修复运维管理的一些bug

pull/302/head
Elune 2019-12-21 21:30:45 +08:00
parent d32216d513
commit fac8e2f51e
6 changed files with 66 additions and 25 deletions

View File

@ -176,7 +176,7 @@ recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within the same "printed page" as the copyright notice for easier identification within
third-party archives. third-party archives.
Copyright 2018 Elune Copyright 2018 Zheng Jie
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@ -97,7 +97,7 @@ public class DatabaseController {
public ResponseEntity<Object> upload(@RequestBody MultipartFile file, HttpServletRequest request)throws Exception{ public ResponseEntity<Object> upload(@RequestBody MultipartFile file, HttpServletRequest request)throws Exception{
String id = request.getParameter("id"); String id = request.getParameter("id");
DatabaseDto database = databaseService.findById(id); DatabaseDto database = databaseService.findById(id);
String fileName = ""; String fileName;
if(database != null){ if(database != null){
fileName = file.getOriginalFilename(); fileName = file.getOriginalFilename();
File executeFile = new File(fileSavePath+fileName); File executeFile = new File(fileSavePath+fileName);

View File

@ -15,9 +15,12 @@ public class DeployHistoryQueryCriteria{
/** /**
* *
*/ */
@Query(blurry = "appName,ip,deployUser,deployId") @Query(blurry = "appName,ip,deployUser")
private String blurry; private String blurry;
@Query
private Long deployId;
@Query(type = Query.Type.BETWEEN) @Query(type = Query.Type.BETWEEN)
private List<Timestamp> deployDate; private List<Timestamp> deployDate;
} }

View File

@ -1,5 +1,6 @@
package me.zhengjie.modules.mnt.service.impl; package me.zhengjie.modules.mnt.service.impl;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.mnt.domain.App; import me.zhengjie.modules.mnt.domain.App;
import me.zhengjie.modules.mnt.repository.AppRepository; import me.zhengjie.modules.mnt.repository.AppRepository;
import me.zhengjie.modules.mnt.service.AppService; import me.zhengjie.modules.mnt.service.AppService;
@ -57,18 +58,34 @@ public class AppServiceImpl implements AppService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public AppDto create(App resources) { public AppDto create(App resources) {
verification(resources);
return appMapper.toDto(appRepository.save(resources)); return appMapper.toDto(appRepository.save(resources));
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void update(App resources) { public void update(App resources) {
verification(resources);
App app = appRepository.findById(resources.getId()).orElseGet(App::new); App app = appRepository.findById(resources.getId()).orElseGet(App::new);
ValidationUtil.isNull(app.getId(),"App","id",resources.getId()); ValidationUtil.isNull(app.getId(),"App","id",resources.getId());
app.copy(resources); app.copy(resources);
appRepository.save(app); appRepository.save(app);
} }
private void verification(App resources){
String opt = "/opt";
String home = "/home";
if (!(resources.getUploadPath().startsWith(opt) || resources.getUploadPath().startsWith(home))) {
throw new BadRequestException("文件只能上传在opt目录或者home目录 ");
}
if (!(resources.getDeployPath().startsWith(opt) || resources.getDeployPath().startsWith(home))) {
throw new BadRequestException("文件只能部署在opt目录或者home目录 ");
}
if (!(resources.getBackupPath().startsWith(opt) || resources.getBackupPath().startsWith(home))) {
throw new BadRequestException("文件只能备份在opt目录或者home目录 ");
}
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void delete(Set<Long> ids) { public void delete(Set<Long> ids) {

View File

@ -130,13 +130,15 @@ public class DeployServiceImpl implements DeployService {
//判断是否第一次部署 //判断是否第一次部署
boolean flag = checkFile(executeShellUtil, app); boolean flag = checkFile(executeShellUtil, app);
//第一步要确认服务器上有这个目录 //第一步要确认服务器上有这个目录
executeShellUtil.execute("mkdir -p " + uploadPath); executeShellUtil.execute("mkdir -p " + app.getUploadPath());
executeShellUtil.execute("mkdir -p " + app.getBackupPath());
executeShellUtil.execute("mkdir -p " + app.getDeployPath());
//上传文件 //上传文件
msg = String.format("登陆到服务器:%s", ip); msg = String.format("登陆到服务器:%s", ip);
ScpClientUtil scpClientUtil = getScpClientUtil(ip); ScpClientUtil scpClientUtil = getScpClientUtil(ip);
log.info(msg); log.info(msg);
sendMsg(msg, MsgType.INFO); sendMsg(msg, MsgType.INFO);
msg = String.format("上传文件到服务器:%s<br>目录:%s下", ip, uploadPath); msg = String.format("上传文件到服务器:%s<br>目录:%s下,请稍等...", ip, uploadPath);
sendMsg(msg, MsgType.INFO); sendMsg(msg, MsgType.INFO);
scpClientUtil.putFile(fileSavePath, uploadPath); scpClientUtil.putFile(fileSavePath, uploadPath);
if (flag) { if (flag) {
@ -151,13 +153,19 @@ public class DeployServiceImpl implements DeployService {
//部署文件,并启动应用 //部署文件,并启动应用
String deployScript = app.getDeployScript(); String deployScript = app.getDeployScript();
executeShellUtil.execute(deployScript); executeShellUtil.execute(deployScript);
sleep(3);
sendMsg("启动应用", MsgType.INFO); sendMsg("应用部署中,请耐心等待部署结果,或者稍后手动查看部署状态", MsgType.INFO);
String startScript = app.getStartScript(); int i = 0;
executeShellUtil.execute(startScript); boolean result = false;
//只有过5秒才能知道到底是不是启动成功了。 // 由于启动应用需要时间所以需要循环获取状态如果超过30次则认为是启动失败
sleep(5); while (i++ < 30){
boolean result = checkIsRunningStatus(port, executeShellUtil); result = checkIsRunningStatus(port, executeShellUtil);
if(result){
break;
}
// 休眠6秒
sleep(6);
}
sb.append("服务器:").append(deployDTO.getName()).append("<br>应用:").append(app.getName()); sb.append("服务器:").append(deployDTO.getName()).append("<br>应用:").append(app.getName());
sendResultMsg(result, sb); sendResultMsg(result, sb);
executeShellUtil.close(); executeShellUtil.close();
@ -253,7 +261,7 @@ public class DeployServiceImpl implements DeployService {
private boolean checkFile(ExecuteShellUtil executeShellUtil, AppDto appDTO) { private boolean checkFile(ExecuteShellUtil executeShellUtil, AppDto appDTO) {
String result = executeShellUtil.executeForResult("find " + appDTO.getDeployPath() + " -name " + appDTO.getName()); String result = executeShellUtil.executeForResult("find " + appDTO.getDeployPath() + " -name " + appDTO.getName());
return result.indexOf("/tcp:")>0; return result.indexOf(appDTO.getName())>0;
} }
/** /**
@ -273,9 +281,19 @@ public class DeployServiceImpl implements DeployService {
sb.append("服务器:").append(deploy.getName()).append("<br>应用:").append(app.getName()); sb.append("服务器:").append(deploy.getName()).append("<br>应用:").append(app.getName());
sendMsg("下发启动命令", MsgType.INFO); sendMsg("下发启动命令", MsgType.INFO);
executeShellUtil.execute(app.getStartScript()); executeShellUtil.execute(app.getStartScript());
//停止3秒防止应用没有启动完成
sleep(3); sleep(3);
boolean result = checkIsRunningStatus(app.getPort(), executeShellUtil); sendMsg("应用启动中,请耐心等待启动结果,或者稍后手动查看运行状态", MsgType.INFO);
int i = 0;
boolean result = false;
// 由于启动应用需要时间所以需要循环获取状态如果超过30次则认为是启动失败
while (i++ < 30){
result = checkIsRunningStatus(app.getPort(), executeShellUtil);
if(result){
break;
}
// 休眠6秒
sleep(6);
}
sendResultMsg(result, sb); sendResultMsg(result, sb);
log.info(sb.toString()); log.info(sb.toString());
executeShellUtil.close(); executeShellUtil.close();
@ -343,21 +361,24 @@ public class DeployServiceImpl implements DeployService {
stopApp(app.getPort(), executeShellUtil); stopApp(app.getPort(), executeShellUtil);
//删除原来应用 //删除原来应用
sendMsg("删除应用", MsgType.INFO); sendMsg("删除应用", MsgType.INFO);
//考虑到系统安全性,必须限制下操作目录
String path = "/opt";
if (!deployPath.startsWith(path)) {
throw new BadRequestException("部署路径必须在opt目录下" + deployPath);
}
executeShellUtil.execute("rm -rf " + deployPath + FILE_SEPARATOR + resources.getAppName()); executeShellUtil.execute("rm -rf " + deployPath + FILE_SEPARATOR + resources.getAppName());
//还原应用 //还原应用
sendMsg("还原应用", MsgType.INFO); sendMsg("还原应用", MsgType.INFO);
executeShellUtil.execute("cp -r " + backupPath + "/. " + deployPath); executeShellUtil.execute("cp -r " + backupPath + "/. " + deployPath);
sendMsg("启动应用", MsgType.INFO); sendMsg("启动应用", MsgType.INFO);
executeShellUtil.execute(app.getStartScript()); executeShellUtil.execute(app.getStartScript());
//只有过5秒才能知道到底是不是启动成功了。 sendMsg("应用启动中,请耐心等待启动结果,或者稍后手动查看启动状态", MsgType.INFO);
sleep(5); int i = 0;
boolean result = checkIsRunningStatus(app.getPort(), executeShellUtil); boolean result = false;
// 由于启动应用需要时间所以需要循环获取状态如果超过30次则认为是启动失败
while (i++ < 30){
result = checkIsRunningStatus(app.getPort(), executeShellUtil);
if(result){
break;
}
// 休眠6秒
sleep(6);
}
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("服务器:").append(ip).append("<br>应用:").append(resources.getAppName()); sb.append("服务器:").append(ip).append("<br>应用:").append(resources.getAppName());
sendResultMsg(result, sb); sendResultMsg(result, sb);

View File

@ -155,7 +155,7 @@ public class SqlUtils {
public static String executeFile(String jdbcUrl, String userName, String password, File sqlFile) { public static String executeFile(String jdbcUrl, String userName, String password, File sqlFile) {
Connection connection = getConnection(jdbcUrl, userName, password); Connection connection = getConnection(jdbcUrl, userName, password);
try { try {
batchExecute(connection, readSqlList( sqlFile)); batchExecute(connection, readSqlList(sqlFile));
} catch (Exception e) { } catch (Exception e) {
log.error("sql脚本执行发生异常:{}",e.getMessage()); log.error("sql脚本执行发生异常:{}",e.getMessage());
return e.getMessage(); return e.getMessage();