mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-11-30 10:58:14 +08:00
项目新增自启动配置、构建新增 webhook、仓库添加验证
This commit is contained in:
parent
4d3b3a7d05
commit
a88fc0dcc4
@ -15,6 +15,8 @@
|
||||
9. 【server】发布命令(SSH发布命令、本地命令)支持变量替换:`#{BUILD_ID}`、`#{BUILD_NAME}`、`#{BUILD_RESULT_FILE}`、`#{BUILD_NUMBER_ID}`
|
||||
10. 【server】新增自动备份全量数据配置 `db.autoBackupIntervalDay` 默认一天备份一次,执行备份时间 凌晨0点或者中午12点
|
||||
11. 【agent】项目的 webhook 新增项目启动成功后通知,并且参数新增 `type` 指包括:`beforeStop`,`start`,`stop`,`beforeRestart`
|
||||
12. 【agent】项目新增自启动配置项,在 agent 启动时候检查对应项目是否启动,未启动执行启动逻辑
|
||||
13. 【server】构建新增 webhook,实时通知构建进度
|
||||
|
||||
### 解决BUG、优化功能
|
||||
|
||||
@ -50,7 +52,7 @@
|
||||
>
|
||||
> 7: 此次升级启动耗时可能需要2分钟以上(耗时根据数据量来决定),请耐心等待和观察控制台日志输出
|
||||
>
|
||||
> 8: 一个节点不要被多个服务端绑定
|
||||
> 8: 一个节点建议不要被多个服务端绑定(可能出现数据工作空间错乱情况)
|
||||
------
|
||||
|
||||
# 2.7.3
|
||||
|
@ -262,14 +262,9 @@ public abstract class AbstractProjectCommander {
|
||||
*/
|
||||
public String restart(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) throws Exception {
|
||||
this.asyncWebHooks(nodeProjectInfoModel, javaCopyItem, "beforeRestart");
|
||||
if (javaCopyItem == null) {
|
||||
if (isRun(nodeProjectInfoModel.getId())) {
|
||||
stop(nodeProjectInfoModel, null);
|
||||
}
|
||||
} else {
|
||||
if (isRun(javaCopyItem.getTagId())) {
|
||||
stop(nodeProjectInfoModel, javaCopyItem);
|
||||
}
|
||||
boolean run = this.isRun(nodeProjectInfoModel, javaCopyItem);
|
||||
if (run) {
|
||||
stop(nodeProjectInfoModel, javaCopyItem);
|
||||
}
|
||||
return start(nodeProjectInfoModel, javaCopyItem);
|
||||
}
|
||||
@ -367,33 +362,23 @@ public abstract class AbstractProjectCommander {
|
||||
return "ok";
|
||||
}
|
||||
|
||||
public String status(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) {
|
||||
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();
|
||||
return this.status(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看状态
|
||||
*
|
||||
* @param tag 运行标识
|
||||
* @return 查询结果
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
public String status(String tag) throws Exception {
|
||||
boolean disableVirtualMachine = AgentExtConfigBean.getInstance().isDisableVirtualMachine();
|
||||
if (disableVirtualMachine) {
|
||||
String jpsStatus = getJpsStatus(tag);
|
||||
if (StrUtil.equals(AbstractProjectCommander.STOP_TAG, jpsStatus) && SystemUtil.getOsInfo().isLinux()) {
|
||||
return getLinuxPsStatus(tag);
|
||||
}
|
||||
return jpsStatus;
|
||||
} else {
|
||||
Integer pid = JvmUtil.getPidByTag(tag);
|
||||
if (pid == null) {
|
||||
String jpsStatus = getJpsStatus(tag);
|
||||
if (StrUtil.equals(AbstractProjectCommander.STOP_TAG, jpsStatus) && SystemUtil.getOsInfo().isLinux()) {
|
||||
return getLinuxPsStatus(tag);
|
||||
}
|
||||
return jpsStatus;
|
||||
}
|
||||
return StrUtil.format("{}:{}", AbstractProjectCommander.RUNNING_TAG, pid);
|
||||
|
||||
protected String status(String tag) {
|
||||
String jpsStatus = getJpsStatus(tag);
|
||||
if (StrUtil.equals(AbstractProjectCommander.STOP_TAG, jpsStatus) && SystemUtil.getOsInfo().isLinux()) {
|
||||
return getLinuxPsStatus(tag);
|
||||
}
|
||||
return jpsStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -403,15 +388,11 @@ public abstract class AbstractProjectCommander {
|
||||
* @return 运行标识
|
||||
*/
|
||||
private String getJpsStatus(String tag) {
|
||||
String execSystemCommand = CommandUtil.execSystemCommand("jps -mv");
|
||||
List<String> list = StrSplitter.splitTrim(execSystemCommand, StrUtil.LF, true);
|
||||
for (String item : list) {
|
||||
if (JvmUtil.checkCommandLineIsJpom(item, tag)) {
|
||||
String[] split = StrUtil.splitToArray(item, StrUtil.SPACE);
|
||||
return StrUtil.format("{}:{}", AbstractProjectCommander.RUNNING_TAG, split[0]);
|
||||
}
|
||||
Integer pid = JvmUtil.getPidByTag(tag);
|
||||
if (pid == null || pid <= 0) {
|
||||
return AbstractProjectCommander.STOP_TAG;
|
||||
}
|
||||
return AbstractProjectCommander.STOP_TAG;
|
||||
return StrUtil.format("{}:{}", AbstractProjectCommander.RUNNING_TAG, pid);
|
||||
}
|
||||
|
||||
|
||||
@ -562,12 +543,23 @@ public abstract class AbstractProjectCommander {
|
||||
/**
|
||||
* 是否正在运行
|
||||
*
|
||||
* @param tag id
|
||||
* @param nodeProjectInfoModel 项目
|
||||
* @return true 正在运行
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
public boolean isRun(String tag) throws Exception {
|
||||
String result = status(tag);
|
||||
public boolean isRun(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) {
|
||||
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();
|
||||
String result = this.status(tag);
|
||||
return result.contains(AbstractProjectCommander.RUNNING_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否正在运行
|
||||
*
|
||||
* @param tag 运行标识
|
||||
* @return true 正在运行
|
||||
*/
|
||||
private boolean isRun(String tag) {
|
||||
String result = this.status(tag);
|
||||
return result.contains(AbstractProjectCommander.RUNNING_TAG);
|
||||
}
|
||||
|
||||
|
@ -26,10 +26,8 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.PatternPool;
|
||||
import cn.hutool.core.lang.RegexPool;
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
@ -79,9 +77,8 @@ public class ManageEditProjectController extends BaseAgentController {
|
||||
* @param projectInfo 项目实体
|
||||
* @param whitelistDirectory 白名单
|
||||
* @param previewData 预检查数据
|
||||
* @return null 检查正常
|
||||
*/
|
||||
private String checkParameter(NodeProjectInfoModel projectInfo, String whitelistDirectory, boolean previewData) {
|
||||
private void checkParameter(NodeProjectInfoModel projectInfo, String whitelistDirectory, boolean previewData) {
|
||||
String id = projectInfo.getId();
|
||||
Assert.state(!StrUtil.isEmptyOrUndefined(id), "项目id不能为空");
|
||||
Assert.state(StringUtil.isGeneral(id, 2, 20), "项目id 长度范围2-20(英文字母 、数字和下划线)");
|
||||
@ -117,7 +114,7 @@ public class ManageEditProjectController extends BaseAgentController {
|
||||
if (outGivingProject) {
|
||||
whitelistDirectoryService.addProjectWhiteList(whitelistDirectory);
|
||||
} else {
|
||||
return JsonMessage.getString(401, "请选择正确的项目路径,或者还没有配置白名单");
|
||||
throw new IllegalArgumentException("请选择正确的项目路径,或者还没有配置白名单");
|
||||
}
|
||||
}
|
||||
String logPath = projectInfo.getLogPath();
|
||||
@ -126,7 +123,7 @@ public class ManageEditProjectController extends BaseAgentController {
|
||||
if (outGivingProject) {
|
||||
whitelistDirectoryService.addProjectWhiteList(logPath);
|
||||
} else {
|
||||
return JsonMessage.getString(401, "请填写的项目日志存储路径,或者还没有配置白名单");
|
||||
throw new IllegalArgumentException("请填写的项目日志存储路径,或者还没有配置白名单");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -162,7 +159,6 @@ public class ManageEditProjectController extends BaseAgentController {
|
||||
} else {
|
||||
projectInfo.setJavaCopyItemList(null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -173,10 +169,8 @@ public class ManageEditProjectController extends BaseAgentController {
|
||||
boolean previewData = Convert.toBool(strPreviewData, false);
|
||||
String whitelistDirectory = projectInfo.getWhitelistDirectory();
|
||||
//
|
||||
String error = checkParameter(projectInfo, whitelistDirectory, previewData);
|
||||
if (error != null) {
|
||||
return error;
|
||||
}
|
||||
this.checkParameter(projectInfo, whitelistDirectory, previewData);
|
||||
|
||||
String id = projectInfo.getId();
|
||||
//
|
||||
String allLib = projectInfo.allLib();
|
||||
@ -205,7 +199,7 @@ public class ManageEditProjectController extends BaseAgentController {
|
||||
}
|
||||
//
|
||||
String token = projectInfo.getToken();
|
||||
if (StrUtil.isNotEmpty(token) && !ReUtil.isMatch(PatternPool.URL_HTTP, token)) {
|
||||
if (StrUtil.isNotEmpty(token)) {
|
||||
Validator.validateMatchRegex(RegexPool.URL_HTTP, token, "WebHooks 地址不合法");
|
||||
}
|
||||
// 判断空格
|
||||
@ -234,7 +228,7 @@ public class ManageEditProjectController extends BaseAgentController {
|
||||
this.checkPath(projectInfo);
|
||||
if (exits == null) {
|
||||
// 检查运行中的tag 是否被占用
|
||||
Assert.state(!AbstractProjectCommander.getInstance().isRun(projectInfo.getId()), "当前项目id已经被正在运行的程序占用");
|
||||
Assert.state(!AbstractProjectCommander.getInstance().isRun(projectInfo, null), "当前项目id已经被正在运行的程序占用");
|
||||
if (previewData) {
|
||||
// 预检查数据
|
||||
return JsonMessage.getString(200, "检查通过");
|
||||
@ -251,6 +245,7 @@ public class ManageEditProjectController extends BaseAgentController {
|
||||
exits.setLogPath(projectInfo.getLogPath());
|
||||
exits.setName(projectInfo.getName());
|
||||
// exits.setGroup(projectInfo.getGroup());
|
||||
exits.setAutoStart(projectInfo.getAutoStart());
|
||||
exits.setMainClass(projectInfo.getMainClass());
|
||||
exits.setLib(projectInfo.getLib());
|
||||
exits.setJvm(projectInfo.getJvm());
|
||||
@ -348,13 +343,15 @@ public class ManageEditProjectController extends BaseAgentController {
|
||||
Assert.notNull(nodeProjectInfoModel, "项目不存在");
|
||||
try {
|
||||
NodeProjectInfoModel.JavaCopyItem copyItem = nodeProjectInfoModel.findCopyItem(copyId);
|
||||
|
||||
if (copyItem == null) {
|
||||
// 运行判断
|
||||
Assert.state(!nodeProjectInfoModel.tryGetStatus(), "不能删除正在运行的项目");
|
||||
|
||||
boolean run = AbstractProjectCommander.getInstance().isRun(nodeProjectInfoModel, null);
|
||||
Assert.state(!run, "不能删除正在运行的项目");
|
||||
projectInfoService.deleteItem(nodeProjectInfoModel.getId());
|
||||
} else {
|
||||
Assert.state(!copyItem.tryGetStatus(), "不能删除正在运行的项目副本");
|
||||
boolean run = AbstractProjectCommander.getInstance().isRun(nodeProjectInfoModel, copyItem);
|
||||
Assert.state(!run, "不能删除正在运行的项目副本");
|
||||
boolean removeCopyItem = nodeProjectInfoModel.removeCopyItem(copyId);
|
||||
Assert.state(removeCopyItem, "删除对应副本集不存在");
|
||||
projectInfoService.updateItem(nodeProjectInfoModel);
|
||||
|
@ -219,9 +219,8 @@ public class ProjectFileControl extends BaseAgentController {
|
||||
if (FileUtil.clean(file)) {
|
||||
return JsonMessage.getString(200, "清除成功");
|
||||
}
|
||||
if (pim.tryGetStatus()) {
|
||||
return JsonMessage.getString(501, "文件被占用,请先停止项目");
|
||||
}
|
||||
boolean run = AbstractProjectCommander.getInstance().isRun(pim, null);
|
||||
Assert.state(!run, "文件被占用,请先停止项目");
|
||||
return JsonMessage.getString(500, "删除失败:" + file.getAbsolutePath());
|
||||
} else {
|
||||
// 删除文件
|
||||
|
@ -22,8 +22,6 @@
|
||||
*/
|
||||
package io.jpom.controller.manage;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
@ -32,6 +30,7 @@ import io.jpom.common.BaseAgentController;
|
||||
import io.jpom.common.commander.AbstractProjectCommander;
|
||||
import io.jpom.model.data.NodeProjectInfoModel;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@ -66,52 +65,17 @@ public class ProjectListController extends BaseAgentController {
|
||||
return JsonMessage.getString(200, "", nodeProjectInfoModel);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 获取所有的分组
|
||||
// *
|
||||
// * @return array
|
||||
// */
|
||||
// @RequestMapping(value = "getProjectGroup", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
// public String getProjectGroup() {
|
||||
// HashSet<String> strings = projectInfoService.getAllGroup();
|
||||
// return JsonMessage.getString(200, "", strings);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 程序项目信息
|
||||
*
|
||||
* @param notStatus 不包含运行状态
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "getProjectInfo", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getProjectInfo(String notStatus) {
|
||||
public String getProjectInfo() {
|
||||
try {
|
||||
boolean status = StrUtil.isEmpty(notStatus);
|
||||
// 查询数据
|
||||
List<NodeProjectInfoModel> nodeProjectInfoModels = projectInfoService.list();
|
||||
// 转换为数据
|
||||
JSONArray array = new JSONArray();
|
||||
for (NodeProjectInfoModel nodeProjectInfoModel : nodeProjectInfoModels) {
|
||||
// if (StrUtil.isNotEmpty(group) && !group.equals(nodeProjectInfoModel.getGroup())) {
|
||||
// continue;
|
||||
// }
|
||||
JSONObject object = nodeProjectInfoModel.toJson();
|
||||
if (status) {
|
||||
object.put("status", nodeProjectInfoModel.tryGetStatus());
|
||||
}
|
||||
array.add(object);
|
||||
}
|
||||
array.sort((oo1, oo2) -> {
|
||||
JSONObject o1 = (JSONObject) oo1;
|
||||
JSONObject o2 = (JSONObject) oo2;
|
||||
String group1 = o1.getString("group");
|
||||
String group2 = o2.getString("group");
|
||||
if (group1 == null || group2 == null) {
|
||||
return -1;
|
||||
}
|
||||
return group1.compareTo(group2);
|
||||
});
|
||||
return JsonMessage.getString(200, "查询成功!", array);
|
||||
return JsonMessage.getString(200, "查询成功!", nodeProjectInfoModels);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error(e.getMessage(), e);
|
||||
return JsonMessage.getString(500, "查询异常:" + e.getMessage());
|
||||
@ -124,20 +88,17 @@ public class ProjectListController extends BaseAgentController {
|
||||
@RequestMapping(value = "project_copy_list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String projectCopyList(String id) {
|
||||
NodeProjectInfoModel nodeProjectInfoModel = projectInfoService.getItem(id);
|
||||
if (nodeProjectInfoModel == null) {
|
||||
return JsonMessage.getString(404, "没有对应项目");
|
||||
}
|
||||
Assert.notNull(nodeProjectInfoModel, "没有对应项目");
|
||||
|
||||
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = nodeProjectInfoModel.getJavaCopyItemList();
|
||||
if (CollUtil.isEmpty(javaCopyItemList)) {
|
||||
return JsonMessage.getString(404, "对应项目没有副本集");
|
||||
}
|
||||
Assert.notEmpty(javaCopyItemList, "对应项目没有副本集");
|
||||
JSONArray array = new JSONArray();
|
||||
for (NodeProjectInfoModel.JavaCopyItem javaCopyItem : javaCopyItemList) {
|
||||
JSONObject object = javaCopyItem.toJson();
|
||||
object.put("status", javaCopyItem.tryGetStatus());
|
||||
boolean run = AbstractProjectCommander.getInstance().isRun(nodeProjectInfoModel, javaCopyItem);
|
||||
object.put("status", run);
|
||||
array.add(object);
|
||||
}
|
||||
|
||||
return JsonMessage.getString(200, "", array);
|
||||
}
|
||||
}
|
||||
|
@ -35,8 +35,8 @@ import io.jpom.common.commander.AbstractProjectCommander;
|
||||
import io.jpom.model.data.NodeProjectInfoModel;
|
||||
import io.jpom.service.manage.ConsoleService;
|
||||
import io.jpom.socket.ConsoleCommandOp;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@ -53,161 +53,154 @@ import java.util.List;
|
||||
@RequestMapping(value = "/manage/")
|
||||
public class ProjectStatusController extends BaseAgentController {
|
||||
|
||||
private final ConsoleService consoleService;
|
||||
private final ConsoleService consoleService;
|
||||
|
||||
public ProjectStatusController(ConsoleService consoleService) {
|
||||
this.consoleService = consoleService;
|
||||
}
|
||||
public ProjectStatusController(ConsoleService consoleService) {
|
||||
this.consoleService = consoleService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取项目的进程id
|
||||
*
|
||||
* @param id 项目id
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "getProjectStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getProjectStatus(@ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确")) String id, String getCopy) {
|
||||
NodeProjectInfoModel nodeProjectInfoModel = tryGetProjectInfoModel();
|
||||
if (nodeProjectInfoModel == null) {
|
||||
return JsonMessage.getString(HttpStatus.NOT_FOUND.value(), "项目id不存在");
|
||||
}
|
||||
int pid = 0;
|
||||
try {
|
||||
pid = AbstractProjectCommander.getInstance().getPid(id);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("获取项目pid 失败", e);
|
||||
}
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("pId", pid);
|
||||
//
|
||||
if (StrUtil.isNotEmpty(getCopy)) {
|
||||
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = nodeProjectInfoModel.getJavaCopyItemList();
|
||||
JSONArray copys = new JSONArray();
|
||||
if (javaCopyItemList != null) {
|
||||
for (NodeProjectInfoModel.JavaCopyItem javaCopyItem : javaCopyItemList) {
|
||||
JSONObject jsonObject1 = new JSONObject();
|
||||
jsonObject1.put("copyId", javaCopyItem.getId());
|
||||
jsonObject1.put("status", javaCopyItem.tryGetStatus());
|
||||
copys.add(jsonObject1);
|
||||
}
|
||||
}
|
||||
jsonObject.put("copys", copys);
|
||||
}
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
/**
|
||||
* 获取项目的进程id
|
||||
*
|
||||
* @param id 项目id
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "getProjectStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getProjectStatus(@ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确")) String id, String getCopy) {
|
||||
NodeProjectInfoModel nodeProjectInfoModel = tryGetProjectInfoModel();
|
||||
Assert.notNull(nodeProjectInfoModel, "项目id不存在");
|
||||
int pid = 0;
|
||||
try {
|
||||
pid = AbstractProjectCommander.getInstance().getPid(id);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("获取项目pid 失败", e);
|
||||
}
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("pId", pid);
|
||||
//
|
||||
if (StrUtil.isNotEmpty(getCopy)) {
|
||||
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = nodeProjectInfoModel.getJavaCopyItemList();
|
||||
JSONArray copys = new JSONArray();
|
||||
if (javaCopyItemList != null) {
|
||||
for (NodeProjectInfoModel.JavaCopyItem javaCopyItem : javaCopyItemList) {
|
||||
JSONObject jsonObject1 = new JSONObject();
|
||||
jsonObject1.put("copyId", javaCopyItem.getId());
|
||||
boolean run = AbstractProjectCommander.getInstance().isRun(nodeProjectInfoModel, javaCopyItem);
|
||||
jsonObject1.put("status", run);
|
||||
copys.add(jsonObject1);
|
||||
}
|
||||
}
|
||||
jsonObject.put("copys", copys);
|
||||
}
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目的运行端口
|
||||
*
|
||||
* @param ids ids
|
||||
* @return obj
|
||||
*/
|
||||
@RequestMapping(value = "getProjectPort", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getProjectPort(String ids) {
|
||||
if (StrUtil.isEmpty(ids)) {
|
||||
return JsonMessage.getString(400, "");
|
||||
}
|
||||
JSONArray jsonArray = JSONArray.parseArray(ids);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
JSONObject itemObj;
|
||||
for (Object object : jsonArray) {
|
||||
String item = object.toString();
|
||||
int pid;
|
||||
try {
|
||||
pid = AbstractProjectCommander.getInstance().getPid(item);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("获取端口错误", e);
|
||||
continue;
|
||||
}
|
||||
if (pid <= 0) {
|
||||
continue;
|
||||
}
|
||||
itemObj = new JSONObject();
|
||||
String port = AbstractProjectCommander.getInstance().getMainPort(pid);
|
||||
itemObj.put("port", port);
|
||||
itemObj.put("pid", pid);
|
||||
jsonObject.put(item, itemObj);
|
||||
}
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
/**
|
||||
* 获取项目的运行端口
|
||||
*
|
||||
* @param ids ids
|
||||
* @return obj
|
||||
*/
|
||||
@RequestMapping(value = "getProjectPort", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getProjectPort(String ids) {
|
||||
Assert.hasText(ids, "没有要获取的信息");
|
||||
JSONArray jsonArray = JSONArray.parseArray(ids);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
JSONObject itemObj;
|
||||
for (Object object : jsonArray) {
|
||||
String item = object.toString();
|
||||
int pid;
|
||||
try {
|
||||
pid = AbstractProjectCommander.getInstance().getPid(item);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("获取端口错误", e);
|
||||
continue;
|
||||
}
|
||||
if (pid <= 0) {
|
||||
continue;
|
||||
}
|
||||
itemObj = new JSONObject();
|
||||
String port = AbstractProjectCommander.getInstance().getMainPort(pid);
|
||||
itemObj.put("port", port);
|
||||
itemObj.put("pid", pid);
|
||||
jsonObject.put(item, itemObj);
|
||||
}
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取项目的运行端口
|
||||
*
|
||||
* @param id 项目id
|
||||
* @param copyIds 副本 ids ["aa","ss"]
|
||||
* @return obj
|
||||
*/
|
||||
@RequestMapping(value = "getProjectCopyPort", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getProjectPort(String id, String copyIds) {
|
||||
if (StrUtil.isEmpty(copyIds) || StrUtil.isEmpty(id)) {
|
||||
return JsonMessage.getString(400, "");
|
||||
}
|
||||
NodeProjectInfoModel nodeProjectInfoModel = getProjectInfoModel();
|
||||
/**
|
||||
* 获取项目的运行端口
|
||||
*
|
||||
* @param id 项目id
|
||||
* @param copyIds 副本 ids ["aa","ss"]
|
||||
* @return obj
|
||||
*/
|
||||
@RequestMapping(value = "getProjectCopyPort", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getProjectPort(String id, String copyIds) {
|
||||
if (StrUtil.isEmpty(copyIds) || StrUtil.isEmpty(id)) {
|
||||
return JsonMessage.getString(400, "");
|
||||
}
|
||||
NodeProjectInfoModel nodeProjectInfoModel = getProjectInfoModel();
|
||||
|
||||
JSONArray jsonArray = JSONArray.parseArray(copyIds);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
JSONObject itemObj;
|
||||
for (Object object : jsonArray) {
|
||||
String item = object.toString();
|
||||
NodeProjectInfoModel.JavaCopyItem copyItem = nodeProjectInfoModel.findCopyItem(item);
|
||||
int pid;
|
||||
try {
|
||||
pid = AbstractProjectCommander.getInstance().getPid(copyItem.getTagId());
|
||||
if (pid <= 0) {
|
||||
continue;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("获取端口错误", e);
|
||||
continue;
|
||||
}
|
||||
itemObj = new JSONObject();
|
||||
String port = AbstractProjectCommander.getInstance().getMainPort(pid);
|
||||
itemObj.put("port", port);
|
||||
itemObj.put("pid", pid);
|
||||
jsonObject.put(item, itemObj);
|
||||
}
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
JSONArray jsonArray = JSONArray.parseArray(copyIds);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
JSONObject itemObj;
|
||||
for (Object object : jsonArray) {
|
||||
String item = object.toString();
|
||||
NodeProjectInfoModel.JavaCopyItem copyItem = nodeProjectInfoModel.findCopyItem(item);
|
||||
int pid;
|
||||
try {
|
||||
pid = AbstractProjectCommander.getInstance().getPid(copyItem.getTagId());
|
||||
if (pid <= 0) {
|
||||
continue;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("获取端口错误", e);
|
||||
continue;
|
||||
}
|
||||
itemObj = new JSONObject();
|
||||
String port = AbstractProjectCommander.getInstance().getMainPort(pid);
|
||||
itemObj.put("port", port);
|
||||
itemObj.put("pid", pid);
|
||||
jsonObject.put(item, itemObj);
|
||||
}
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "restart", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String restart(@ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确")) String id, String copyId) {
|
||||
NodeProjectInfoModel item = projectInfoService.getItem(id);
|
||||
if (item == null) {
|
||||
return JsonMessage.getString(405, "没有找到对应的项目");
|
||||
}
|
||||
NodeProjectInfoModel.JavaCopyItem copyItem = item.findCopyItem(copyId);
|
||||
String tagId = copyItem == null ? item.getId() : copyItem.getTagId();
|
||||
String result;
|
||||
try {
|
||||
result = consoleService.execCommand(ConsoleCommandOp.restart, item, copyItem);
|
||||
boolean status = AbstractProjectCommander.getInstance().isRun(tagId);
|
||||
if (status) {
|
||||
return JsonMessage.getString(200, result);
|
||||
}
|
||||
return JsonMessage.getString(201, "重启项目失败:" + result);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("获取项目pid 失败", e);
|
||||
result = "error:" + e.getMessage();
|
||||
return JsonMessage.getString(500, "重启项目异常:" + result);
|
||||
}
|
||||
}
|
||||
@RequestMapping(value = "restart", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String restart(@ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确")) String id, String copyId) {
|
||||
NodeProjectInfoModel item = projectInfoService.getItem(id);
|
||||
Assert.notNull(item, "没有找到对应的项目");
|
||||
NodeProjectInfoModel.JavaCopyItem copyItem = item.findCopyItem(copyId);
|
||||
|
||||
String result;
|
||||
try {
|
||||
result = consoleService.execCommand(ConsoleCommandOp.restart, item, copyItem);
|
||||
boolean status = AbstractProjectCommander.getInstance().isRun(item, copyItem);
|
||||
if (status) {
|
||||
return JsonMessage.getString(200, result);
|
||||
}
|
||||
return JsonMessage.getString(201, "重启项目失败:" + result);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("获取项目pid 失败", e);
|
||||
result = "error:" + e.getMessage();
|
||||
return JsonMessage.getString(500, "重启项目异常:" + result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "stop", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String stop(@ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确")) String id, String copyId) {
|
||||
NodeProjectInfoModel item = projectInfoService.getItem(id);
|
||||
if (item == null) {
|
||||
return JsonMessage.getString(405, "没有找到对应的项目");
|
||||
}
|
||||
Assert.notNull(item, "没有找到对应的项目");
|
||||
NodeProjectInfoModel.JavaCopyItem copyItem = item.findCopyItem(copyId);
|
||||
String tagId = copyItem == null ? item.getId() : copyItem.getTagId();
|
||||
|
||||
String result;
|
||||
try {
|
||||
result = consoleService.execCommand(ConsoleCommandOp.stop, item, copyItem);
|
||||
boolean status = AbstractProjectCommander.getInstance().isRun(tagId);
|
||||
boolean status = AbstractProjectCommander.getInstance().isRun(item, copyItem);
|
||||
if (!status) {
|
||||
return JsonMessage.getString(200, result);
|
||||
}
|
||||
@ -223,15 +216,12 @@ public class ProjectStatusController extends BaseAgentController {
|
||||
@RequestMapping(value = "start", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String start(@ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确")) String id, String copyId) {
|
||||
NodeProjectInfoModel item = projectInfoService.getItem(id);
|
||||
if (item == null) {
|
||||
return JsonMessage.getString(405, "没有找到对应的项目");
|
||||
}
|
||||
Assert.notNull(item, "没有找到对应的项目");
|
||||
NodeProjectInfoModel.JavaCopyItem copyItem = item.findCopyItem(copyId);
|
||||
String tagId = copyItem == null ? item.getId() : copyItem.getTagId();
|
||||
String result;
|
||||
try {
|
||||
result = consoleService.execCommand(ConsoleCommandOp.start, item, copyItem);
|
||||
boolean status = AbstractProjectCommander.getInstance().isRun(tagId);
|
||||
boolean status = AbstractProjectCommander.getInstance().isRun(item, copyItem);
|
||||
if (status) {
|
||||
return JsonMessage.getString(200, result);
|
||||
}
|
||||
|
@ -27,10 +27,8 @@ import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.request.XssFilter;
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import io.jpom.common.commander.AbstractProjectCommander;
|
||||
import io.jpom.model.BaseJsonModel;
|
||||
import io.jpom.model.BaseModel;
|
||||
import io.jpom.model.RunMode;
|
||||
@ -50,7 +48,7 @@ import java.util.stream.Collectors;
|
||||
* @author jiangzeyin
|
||||
*/
|
||||
public class NodeProjectInfoModel extends BaseModel {
|
||||
// /**
|
||||
// /**
|
||||
// * 分组
|
||||
// */
|
||||
// private String group;
|
||||
@ -115,6 +113,11 @@ public class NodeProjectInfoModel extends BaseModel {
|
||||
|
||||
private String workspaceId;
|
||||
|
||||
/**
|
||||
* 项目自动启动
|
||||
*/
|
||||
private Boolean autoStart;
|
||||
|
||||
public String getWorkspaceId() {
|
||||
return workspaceId;
|
||||
}
|
||||
@ -177,21 +180,6 @@ public class NodeProjectInfoModel extends BaseModel {
|
||||
this.modifyUser = modifyUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目是否正在运行
|
||||
*
|
||||
* @return true 正在运行
|
||||
*/
|
||||
public boolean tryGetStatus() {
|
||||
try {
|
||||
status = AbstractProjectCommander.getInstance().isRun(getId());
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("检查项目状态错误", e);
|
||||
status = false;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(boolean status) {
|
||||
this.status = status;
|
||||
}
|
||||
@ -240,7 +228,16 @@ public class NodeProjectInfoModel extends BaseModel {
|
||||
this.jvm = jvm;
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
public Boolean getAutoStart() {
|
||||
return autoStart;
|
||||
}
|
||||
|
||||
public void setAutoStart(Boolean autoStart) {
|
||||
this.autoStart = autoStart;
|
||||
}
|
||||
|
||||
//
|
||||
// public String getGroup() {
|
||||
// if (StrUtil.isEmpty(group)) {
|
||||
// return "默认";
|
||||
@ -565,20 +562,6 @@ public class NodeProjectInfoModel extends BaseModel {
|
||||
this.modifyTime = modifyTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目是否正在运行
|
||||
*
|
||||
* @return true 正在运行
|
||||
*/
|
||||
public boolean tryGetStatus() {
|
||||
try {
|
||||
return AbstractProjectCommander.getInstance().isRun(getTagId());
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("检查项目状态错误", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String getParendId() {
|
||||
return parendId;
|
||||
}
|
||||
|
@ -38,57 +38,56 @@ import javax.annotation.Resource;
|
||||
*/
|
||||
@Service
|
||||
public class ConsoleService {
|
||||
@Resource
|
||||
private ProjectInfoService projectInfoService;
|
||||
@Resource
|
||||
private ProjectInfoService projectInfoService;
|
||||
|
||||
/**
|
||||
* 执行shell命令
|
||||
*
|
||||
* @param consoleCommandOp 执行的操作
|
||||
* @param nodeProjectInfoModel 项目信息
|
||||
* @param copyItem 副本信息
|
||||
* @return 执行结果
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
public String execCommand(ConsoleCommandOp consoleCommandOp, NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem copyItem) throws Exception {
|
||||
String result;
|
||||
AbstractProjectCommander abstractProjectCommander = AbstractProjectCommander.getInstance();
|
||||
// 执行命令
|
||||
switch (consoleCommandOp) {
|
||||
case restart:
|
||||
result = abstractProjectCommander.restart(nodeProjectInfoModel, copyItem);
|
||||
break;
|
||||
case start:
|
||||
result = abstractProjectCommander.start(nodeProjectInfoModel, copyItem);
|
||||
break;
|
||||
case stop:
|
||||
result = abstractProjectCommander.stop(nodeProjectInfoModel, copyItem);
|
||||
break;
|
||||
case status: {
|
||||
String tag = copyItem == null ? nodeProjectInfoModel.getId() : copyItem.getTagId();
|
||||
result = abstractProjectCommander.status(tag);
|
||||
break;
|
||||
}
|
||||
case top:
|
||||
case showlog:
|
||||
default:
|
||||
throw new IllegalArgumentException(consoleCommandOp + " error");
|
||||
}
|
||||
// 通知日志刷新
|
||||
if (consoleCommandOp == ConsoleCommandOp.start || consoleCommandOp == ConsoleCommandOp.restart) {
|
||||
// 修改 run lib 使用情况
|
||||
NodeProjectInfoModel modify = projectInfoService.getItem(nodeProjectInfoModel.getId());
|
||||
//
|
||||
if (copyItem != null) {
|
||||
NodeProjectInfoModel.JavaCopyItem copyItem1 = modify.findCopyItem(copyItem.getId());
|
||||
copyItem1.setModifyTime(DateUtil.now());
|
||||
}
|
||||
modify.setRunLibDesc(nodeProjectInfoModel.getUseLibDesc());
|
||||
try {
|
||||
projectInfoService.updateItem(modify);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* 执行shell命令
|
||||
*
|
||||
* @param consoleCommandOp 执行的操作
|
||||
* @param nodeProjectInfoModel 项目信息
|
||||
* @param copyItem 副本信息
|
||||
* @return 执行结果
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
public String execCommand(ConsoleCommandOp consoleCommandOp, NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem copyItem) throws Exception {
|
||||
String result;
|
||||
AbstractProjectCommander abstractProjectCommander = AbstractProjectCommander.getInstance();
|
||||
// 执行命令
|
||||
switch (consoleCommandOp) {
|
||||
case restart:
|
||||
result = abstractProjectCommander.restart(nodeProjectInfoModel, copyItem);
|
||||
break;
|
||||
case start:
|
||||
result = abstractProjectCommander.start(nodeProjectInfoModel, copyItem);
|
||||
break;
|
||||
case stop:
|
||||
result = abstractProjectCommander.stop(nodeProjectInfoModel, copyItem);
|
||||
break;
|
||||
case status: {
|
||||
result = abstractProjectCommander.status(nodeProjectInfoModel, copyItem);
|
||||
break;
|
||||
}
|
||||
case top:
|
||||
case showlog:
|
||||
default:
|
||||
throw new IllegalArgumentException(consoleCommandOp + " error");
|
||||
}
|
||||
// 通知日志刷新
|
||||
if (consoleCommandOp == ConsoleCommandOp.start || consoleCommandOp == ConsoleCommandOp.restart) {
|
||||
// 修改 run lib 使用情况
|
||||
NodeProjectInfoModel modify = projectInfoService.getItem(nodeProjectInfoModel.getId());
|
||||
//
|
||||
if (copyItem != null) {
|
||||
NodeProjectInfoModel.JavaCopyItem copyItem1 = modify.findCopyItem(copyItem.getId());
|
||||
copyItem1.setModifyTime(DateUtil.now());
|
||||
}
|
||||
modify.setRunLibDesc(nodeProjectInfoModel.getUseLibDesc());
|
||||
try {
|
||||
projectInfoService.updateItem(modify);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -105,6 +105,8 @@ public class AutoRegSeverNode {
|
||||
serverJson.put("updateTime", DateTime.now().toString());
|
||||
}
|
||||
JsonFileUtil.saveJson(file.getAbsolutePath(), serverJson);
|
||||
} else {
|
||||
DefaultSystemLog.getLog().error("自动注册插件端失败:{}", body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 码之科技工作室
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.jpom.system.init;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.PreLoadClass;
|
||||
import cn.jiangzeyin.common.PreLoadMethod;
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import io.jpom.common.commander.AbstractProjectCommander;
|
||||
import io.jpom.model.data.NodeProjectInfoModel;
|
||||
import io.jpom.service.manage.ProjectInfoService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 自动启动项目
|
||||
*
|
||||
* @author bwcx_jzy
|
||||
* @since 2021/12/10
|
||||
*/
|
||||
@PreLoadClass
|
||||
public class AutoStartProject {
|
||||
|
||||
@PreLoadMethod
|
||||
private static void start() {
|
||||
ProjectInfoService projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
|
||||
List<NodeProjectInfoModel> list = projectInfoService.list();
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
list = list.stream().filter(nodeProjectInfoModel -> nodeProjectInfoModel.getAutoStart() != null && nodeProjectInfoModel.getAutoStart()).collect(Collectors.toList());
|
||||
List<NodeProjectInfoModel> finalList = list;
|
||||
ThreadUtil.execute(() -> {
|
||||
AbstractProjectCommander instance = AbstractProjectCommander.getInstance();
|
||||
for (NodeProjectInfoModel nodeProjectInfoModel : finalList) {
|
||||
try {
|
||||
if (!instance.isRun(nodeProjectInfoModel, null)) {
|
||||
instance.start(nodeProjectInfoModel, null);
|
||||
}
|
||||
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = nodeProjectInfoModel.getJavaCopyItemList();
|
||||
if (javaCopyItemList != null) {
|
||||
for (NodeProjectInfoModel.JavaCopyItem javaCopyItem : javaCopyItemList) {
|
||||
if (!instance.isRun(nodeProjectInfoModel, javaCopyItem)) {
|
||||
instance.start(nodeProjectInfoModel, javaCopyItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().warn("自动启动项目失败:{} {}", nodeProjectInfoModel.getId(), e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -33,6 +33,8 @@ import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import io.jpom.JpomApplication;
|
||||
@ -393,20 +395,27 @@ public class BuildInfoManage extends BaseBuild implements Runnable {
|
||||
for (Map.Entry<String, Supplier<Boolean>> stringSupplierEntry : suppliers.entrySet()) {
|
||||
processName = stringSupplierEntry.getKey();
|
||||
Supplier<Boolean> value = stringSupplierEntry.getValue();
|
||||
//
|
||||
this.asyncWebHooks(processName);
|
||||
Boolean aBoolean = value.get();
|
||||
if (!aBoolean) {
|
||||
// 有条件结束构建流程
|
||||
this.asyncWebHooks("stop", "process", processName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.asyncWebHooks("success");
|
||||
} catch (RuntimeException runtimeException) {
|
||||
Throwable cause = runtimeException.getCause();
|
||||
this.log("构建失败:" + processName, cause == null ? runtimeException : cause);
|
||||
this.asyncWebHooks(processName, "error", runtimeException.getMessage());
|
||||
} catch (Exception e) {
|
||||
this.log("构建失败:" + processName, e);
|
||||
this.asyncWebHooks(processName, "error", e.getMessage());
|
||||
} finally {
|
||||
BUILD_MANAGE_MAP.remove(buildInfoModel.getId());
|
||||
BaseServerController.remove();
|
||||
this.asyncWebHooks("done");
|
||||
}
|
||||
}
|
||||
|
||||
@ -442,4 +451,30 @@ public class BuildInfoManage extends BaseBuild implements Runnable {
|
||||
log("process result " + waitFor);
|
||||
return status[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行 webhooks 通知
|
||||
*
|
||||
* @param type 类型
|
||||
* @param other 其他参数
|
||||
*/
|
||||
private void asyncWebHooks(String type, Object... other) {
|
||||
String webhook = this.buildInfoModel.getWebhook();
|
||||
if (StrUtil.isEmpty(webhook)) {
|
||||
return;
|
||||
}
|
||||
ThreadUtil.execute(() -> {
|
||||
try {
|
||||
HttpRequest httpRequest = HttpUtil.createGet(webhook);
|
||||
httpRequest.form("buildId", this.buildInfoModel.getId());
|
||||
httpRequest.form("buildName", this.buildInfoModel.getName());
|
||||
httpRequest.form("type", type, other);
|
||||
String body = httpRequest.execute().body();
|
||||
DefaultSystemLog.getLog().info(this.buildInfoModel.getName() + ":" + body);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("WebHooks 调用错误", e);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import io.jpom.common.Const;
|
||||
import io.jpom.model.data.BuildInfoModel;
|
||||
import io.jpom.model.data.RepositoryModel;
|
||||
@ -171,7 +172,13 @@ public class BuildUtil {
|
||||
String rsaPath = StrUtil.removePrefix(repositoryModel.getRsaPrv(), URLUtil.FILE_URL_PREFIX);
|
||||
rsaFile = FileUtil.file(rsaPath);
|
||||
} else {
|
||||
rsaFile = BuildUtil.getRepositoryRsaFile(repositoryModel.getId() + Const.ID_RSA);
|
||||
if (StrUtil.isEmpty(repositoryModel.getId())) {
|
||||
rsaFile = FileUtil.file(ConfigBean.getInstance().getTempPath(), Const.SSH_KEY, SecureUtil.sha1(repositoryModel.getGitUrl()) + Const.ID_RSA);
|
||||
} else {
|
||||
rsaFile = BuildUtil.getRepositoryRsaFile(repositoryModel.getId() + Const.ID_RSA);
|
||||
}
|
||||
// 写入
|
||||
FileUtil.writeUtf8String(repositoryModel.getRsaPrv(), rsaFile);
|
||||
}
|
||||
Assert.state(FileUtil.isFile(rsaFile), "仓库密钥文件不存在或者异常,请检查后操作");
|
||||
return rsaFile;
|
||||
|
@ -24,8 +24,9 @@ package io.jpom.controller.build;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.RegexPool;
|
||||
import cn.hutool.core.lang.Tuple;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.jiangzeyin.common.validator.ValidatorConfig;
|
||||
@ -136,7 +137,7 @@ public class BuildInfoController extends BaseServerController {
|
||||
@ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "构建产物目录不能为空,长度1-200", range = "1:200")) String resultDirFile,
|
||||
@ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "构建命令不能为空")) String script,
|
||||
@ValidatorItem(value = ValidatorRule.POSITIVE_INTEGER, msg = "发布方法不正确") int releaseMethod,
|
||||
String branchName, String branchTagName, String group,
|
||||
String branchName, String branchTagName, String webhook,
|
||||
String extraData) {
|
||||
// 根据 repositoryId 查询仓库信息
|
||||
RepositoryModel repositoryModel = repositoryService.getByKey(repositoryId, getRequest());
|
||||
@ -153,13 +154,15 @@ public class BuildInfoController extends BaseServerController {
|
||||
Assert.state(!CommandUtil.checkContainsDel(script), "不能包含删除命令");
|
||||
}
|
||||
// 查询构建信息
|
||||
BuildInfoModel buildInfoModel = buildInfoService.getByKey(id);
|
||||
BuildInfoModel buildInfoModel = buildInfoService.getByKey(id, getRequest());
|
||||
if (null == buildInfoModel) {
|
||||
buildInfoModel = new BuildInfoModel();
|
||||
buildInfoModel.setId(IdUtil.fastSimpleUUID());
|
||||
}
|
||||
// 设置参数
|
||||
buildInfoModel.setGroup(group);
|
||||
if (StrUtil.isNotEmpty(webhook)) {
|
||||
Validator.validateMatchRegex(RegexPool.URL_HTTP, webhook, "WebHooks 地址不合法");
|
||||
}
|
||||
buildInfoModel.setWebhook(webhook);
|
||||
buildInfoModel.setRepositoryId(repositoryId);
|
||||
buildInfoModel.setName(name);
|
||||
buildInfoModel.setBranchName(branchName);
|
||||
@ -177,17 +180,12 @@ public class BuildInfoController extends BaseServerController {
|
||||
|
||||
// 验证发布方式 和 extraData 信息
|
||||
if (releaseMethod1 == BuildReleaseMethod.Project) {
|
||||
String formatProject = formatProject(jsonObject);
|
||||
if (formatProject != null) {
|
||||
return formatProject;
|
||||
}
|
||||
this.formatProject(jsonObject);
|
||||
} else if (releaseMethod1 == BuildReleaseMethod.Ssh) {
|
||||
this.formatSsh(jsonObject);
|
||||
} else if (releaseMethod1 == BuildReleaseMethod.Outgiving) {
|
||||
String releaseMethodDataId = jsonObject.getString("releaseMethodDataId_1");
|
||||
if (StrUtil.isEmpty(releaseMethodDataId)) {
|
||||
return JsonMessage.getString(405, "请选择分发项目");
|
||||
}
|
||||
Assert.hasText(releaseMethodDataId, "请选择分发项目");
|
||||
jsonObject.put("releaseMethodDataId", releaseMethodDataId);
|
||||
} else if (releaseMethod1 == BuildReleaseMethod.LocalCommand) {
|
||||
this.formatLocalCommand(jsonObject);
|
||||
@ -273,14 +271,12 @@ public class BuildInfoController extends BaseServerController {
|
||||
* 当发布方式为【项目】的时候
|
||||
*
|
||||
* @param jsonObject 配置信息
|
||||
* @return null 没有错误信息
|
||||
*/
|
||||
private String formatProject(JSONObject jsonObject) {
|
||||
private void formatProject(JSONObject jsonObject) {
|
||||
String releaseMethodDataId2Node = jsonObject.getString("releaseMethodDataId_2_node");
|
||||
String releaseMethodDataId2Project = jsonObject.getString("releaseMethodDataId_2_project");
|
||||
if (StrUtil.isEmpty(releaseMethodDataId2Node) || StrUtil.isEmpty(releaseMethodDataId2Project)) {
|
||||
return JsonMessage.getString(405, "请选择节点和项目");
|
||||
}
|
||||
|
||||
Assert.state(StrUtil.hasEmpty(releaseMethodDataId2Node, releaseMethodDataId2Project), "请选择节点和项目");
|
||||
jsonObject.put("releaseMethodDataId", String.format("%s:%s", releaseMethodDataId2Node, releaseMethodDataId2Project));
|
||||
//
|
||||
String afterOpt = jsonObject.getString("afterOpt");
|
||||
@ -290,7 +286,6 @@ public class BuildInfoController extends BaseServerController {
|
||||
String clearOld = jsonObject.getString("clearOld");
|
||||
jsonObject.put("afterOpt", afterOpt1.getCode());
|
||||
jsonObject.put("clearOld", Convert.toBool(clearOld, false));
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,30 +103,19 @@ public class RepositoryController extends BaseServerController {
|
||||
@Feature(method = MethodFeature.EDIT)
|
||||
public Object editRepository(RepositoryModel repositoryModelReq) {
|
||||
this.checkInfo(repositoryModelReq);
|
||||
|
||||
if (StrUtil.isEmpty(repositoryModelReq.getId())) {
|
||||
// insert data
|
||||
repositoryService.insert(repositoryModelReq);
|
||||
} else {
|
||||
// update data
|
||||
if (StrUtil.isEmpty(repositoryModelReq.getRsaPrv())) {
|
||||
repositoryModelReq.setRsaPrv(null);
|
||||
}
|
||||
if (StrUtil.isEmpty(repositoryModelReq.getPassword())) {
|
||||
repositoryModelReq.setPassword(null);
|
||||
}
|
||||
repositoryModelReq.setWorkspaceId(repositoryService.getCheckUserWorkspace(getRequest()));
|
||||
repositoryService.updateById(repositoryModelReq);
|
||||
}
|
||||
// 检查 rsa 私钥
|
||||
boolean andUpdateSshKey = checkAndUpdateSshKey(repositoryModelReq);
|
||||
boolean andUpdateSshKey = this.checkAndUpdateSshKey(repositoryModelReq);
|
||||
Assert.state(andUpdateSshKey, "rsa 私钥文件不存在或者有误");
|
||||
|
||||
if (repositoryModelReq.getRepoType() == RepositoryModel.RepoType.Git.getCode()) {
|
||||
RepositoryModel repositoryModel = repositoryService.getByKey(repositoryModelReq.getId(), false);
|
||||
if (repositoryModel != null) {
|
||||
repositoryModelReq.setRsaPrv(StrUtil.emptyToDefault(repositoryModelReq.getRsaPrv(), repositoryModel.getRsaPrv()));
|
||||
repositoryModelReq.setPassword(StrUtil.emptyToDefault(repositoryModelReq.getPassword(), repositoryModel.getPassword()));
|
||||
}
|
||||
// 验证 git 仓库信息
|
||||
try {
|
||||
Tuple tuple = GitUtil.getBranchAndTagList(repositoryModel);
|
||||
Tuple tuple = GitUtil.getBranchAndTagList(repositoryModelReq);
|
||||
} catch (JpomRuntimeException jpomRuntimeException) {
|
||||
throw jpomRuntimeException;
|
||||
} catch (Exception e) {
|
||||
@ -134,6 +123,15 @@ public class RepositoryController extends BaseServerController {
|
||||
return JsonMessage.toJson(500, "无法连接此仓库," + e.getMessage());
|
||||
}
|
||||
}
|
||||
if (StrUtil.isEmpty(repositoryModelReq.getId())) {
|
||||
// insert data
|
||||
repositoryService.insert(repositoryModelReq);
|
||||
} else {
|
||||
// update data
|
||||
repositoryModelReq.setWorkspaceId(repositoryService.getCheckUserWorkspace(getRequest()));
|
||||
repositoryService.updateById(repositoryModelReq);
|
||||
}
|
||||
|
||||
return JsonMessage.toJson(200, "操作成功");
|
||||
}
|
||||
|
||||
@ -183,6 +181,8 @@ public class RepositoryController extends BaseServerController {
|
||||
Validator.validateGeneral(repositoryModelReq.getId(), "错误的ID");
|
||||
entity.set("id", "<> " + repositoryModelReq.getId());
|
||||
}
|
||||
String workspaceId = repositoryService.getCheckUserWorkspace(getRequest());
|
||||
entity.set("workspaceId", workspaceId);
|
||||
entity.set("gitUrl", repositoryModelReq.getGitUrl());
|
||||
Assert.state(!repositoryService.exists(entity), "已经存在对应的仓库信息啦");
|
||||
}
|
||||
@ -196,20 +196,20 @@ public class RepositoryController extends BaseServerController {
|
||||
if (repositoryModelReq.getProtocol() == GitProtocolEnum.SSH.getCode()) {
|
||||
// if rsa key is not empty
|
||||
if (StrUtil.isNotEmpty(repositoryModelReq.getRsaPrv())) {
|
||||
File rsaFile = BuildUtil.getRepositoryRsaFile(repositoryModelReq.getId() + Const.ID_RSA);
|
||||
/**
|
||||
* if rsa key is start with "file:"
|
||||
* copy this file
|
||||
*/
|
||||
if (StrUtil.startWith(repositoryModelReq.getRsaPrv(), URLUtil.FILE_URL_PREFIX)) {
|
||||
String rsaPath = StrUtil.removePrefix(repositoryModelReq.getRsaPrv(), URLUtil.FILE_URL_PREFIX);
|
||||
if (!FileUtil.file(rsaPath).exists()) {
|
||||
if (!FileUtil.exist(rsaPath)) {
|
||||
DefaultSystemLog.getLog().warn("there is no rsa file... {}", rsaPath);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
//File rsaFile = BuildUtil.getRepositoryRsaFile(repositoryModelReq.getId() + Const.ID_RSA);
|
||||
// or else put into file
|
||||
FileUtil.writeUtf8String(repositoryModelReq.getRsaPrv(), rsaFile);
|
||||
//FileUtil.writeUtf8String(repositoryModelReq.getRsaPrv(), rsaFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -232,6 +232,8 @@ public class RepositoryController extends BaseServerController {
|
||||
Assert.state(!exists, "当前仓库被构建关联,不能直接删除");
|
||||
|
||||
repositoryService.delByKey(id, getRequest());
|
||||
File rsaFile = BuildUtil.getRepositoryRsaFile(id + Const.ID_RSA);
|
||||
FileUtil.del(rsaFile);
|
||||
return JsonMessage.getString(200, "删除成功");
|
||||
}
|
||||
}
|
||||
|
@ -357,6 +357,8 @@ public class OutGivingProjectEditController extends BaseServerController {
|
||||
allData.put("jvm", jvm);
|
||||
String args = getParameter(StrUtil.format("{}_args", nodeModel.getId()));
|
||||
allData.put("args", args);
|
||||
String autoStart = getParameter(StrUtil.format("{}_autoStart", nodeModel.getId()));
|
||||
allData.put("autoStart", Convert.toBool(autoStart, false));
|
||||
// 项目副本
|
||||
String javaCopyIds = getParameter(StrUtil.format("{}_javaCopyIds", nodeModel.getId()));
|
||||
allData.put("javaCopyIds", javaCopyIds);
|
||||
|
@ -47,6 +47,7 @@ public class BuildInfoModel extends BaseWorkspaceModel {
|
||||
/**
|
||||
* 分组名称
|
||||
*/
|
||||
@Deprecated
|
||||
private String group;
|
||||
/**
|
||||
* 分支
|
||||
@ -85,6 +86,9 @@ public class BuildInfoModel extends BaseWorkspaceModel {
|
||||
*/
|
||||
private String extraData;
|
||||
|
||||
|
||||
private String webhook;
|
||||
|
||||
public String getRepositoryId() {
|
||||
return repositoryId;
|
||||
}
|
||||
@ -117,6 +121,14 @@ public class BuildInfoModel extends BaseWorkspaceModel {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public String getWebhook() {
|
||||
return webhook;
|
||||
}
|
||||
|
||||
public void setWebhook(String webhook) {
|
||||
this.webhook = webhook;
|
||||
}
|
||||
|
||||
public String getBranchName() {
|
||||
return branchName;
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ public class RepositoryModel extends BaseWorkspaceModel {
|
||||
/**
|
||||
* SSH RSA 公钥
|
||||
*/
|
||||
@Deprecated
|
||||
private String rsaPub;
|
||||
/**
|
||||
* SSH RSA 私钥
|
||||
@ -134,10 +135,12 @@ public class RepositoryModel extends BaseWorkspaceModel {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getRsaPub() {
|
||||
return rsaPub;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setRsaPub(String rsaPub) {
|
||||
this.rsaPub = rsaPub;
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ public class InitDb implements DisposableBean, InitializingBean {
|
||||
"classpath:/bin/h2-db-v1.sql",
|
||||
"classpath:/bin/h2-db-v1.1.sql",
|
||||
"classpath:/bin/h2-db-v2.sql",
|
||||
"classpath:/bin/h2-db-v2.1.sql",
|
||||
"classpath:/bin/h2-db-v3.sql",
|
||||
};
|
||||
// 加载 sql 变更记录,避免重复执行
|
||||
|
4
modules/server/src/main/resources/bin/h2-db-v2.1.sql
Normal file
4
modules/server/src/main/resources/bin/h2-db-v2.1.sql
Normal file
@ -0,0 +1,4 @@
|
||||
-- @author bwcx_jzy
|
||||
|
||||
ALTER TABLE BUILD_INFO
|
||||
ADD IF NOT EXISTS webhook VARCHAR (255) comment 'webhook';
|
@ -71,6 +71,7 @@ export function editBuild(params) {
|
||||
repoType: params.repoType,
|
||||
// 其他参数
|
||||
extraData: params.extraData,
|
||||
webhook: params.webhook,
|
||||
};
|
||||
return axios({
|
||||
url: "/build/edit",
|
||||
|
@ -142,6 +142,7 @@ export function editProject(params, replicaParams) {
|
||||
javaCopyIds: params.javaCopyIds,
|
||||
token: params.token,
|
||||
logPath: params.logPath,
|
||||
autoStart: params.autoStart,
|
||||
...replicaParams,
|
||||
};
|
||||
return axios({
|
||||
|
@ -181,6 +181,22 @@
|
||||
<a-form-model-item v-if="temp.releaseMethod === 2 || temp.releaseMethod === 3" label="清空发布" prop="clearOld">
|
||||
<a-switch v-model="tempExtraData.clearOld" checked-children="是" un-checked-children="否" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item prop="webhook">
|
||||
<template slot="label">
|
||||
WebHooks
|
||||
<a-tooltip v-show="!temp.id">
|
||||
<template slot="title">
|
||||
<ul>
|
||||
<li>构建过程请求对应的地址,开始构建,构建完成,开始发布,发布完成,构建异常,发布异常</li>
|
||||
<li>传人参数有:buildId、buildName、type、error</li>
|
||||
<li>type 的值有:startReady、pull、executeCommand、release、done、stop、success</li>
|
||||
</ul>
|
||||
</template>
|
||||
<a-icon type="question-circle" theme="filled" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input v-model="temp.webhook" placeholder="构建过程请求,非必填,GET请求" />
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</a-modal>
|
||||
<!-- 触发器 -->
|
||||
@ -253,7 +269,7 @@ export default {
|
||||
{ title: "顺序重启(有重启失败将继续)", value: 3 },
|
||||
],
|
||||
columns: [
|
||||
{ title: "名称", dataIndex: "name", width: 150, sorter: true, ellipsis: true, scopedSlots: { customRender: "name" } },
|
||||
{ title: "名称", dataIndex: "name", width: 100, sorter: true, ellipsis: true, scopedSlots: { customRender: "name" } },
|
||||
// { title: "分组", dataIndex: "group", key: "group%", sorter: true, width: 100, ellipsis: true, scopedSlots: { customRender: "group" } },
|
||||
{
|
||||
title: "分支",
|
||||
@ -627,19 +643,27 @@ export default {
|
||||
},
|
||||
// 开始构建
|
||||
handleStartBuild(record) {
|
||||
this.temp = Object.assign(record);
|
||||
startBuild(this.temp.id).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
this.$confirm({
|
||||
title: "系统提示",
|
||||
content: "确定要开始构建 【名称:" + record.name + "】 【分支:" + record.branchName + "】 吗?",
|
||||
okText: "确认",
|
||||
cancelText: "取消",
|
||||
onOk: () => {
|
||||
this.temp = Object.assign(record);
|
||||
startBuild(this.temp.id).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
});
|
||||
this.handleFilter();
|
||||
// 自动打开构建日志
|
||||
this.handleBuildLog({
|
||||
id: this.temp.id,
|
||||
buildId: res.data,
|
||||
});
|
||||
}
|
||||
});
|
||||
this.handleFilter();
|
||||
// 自动打开构建日志
|
||||
this.handleBuildLog({
|
||||
id: this.temp.id,
|
||||
buildId: res.data,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
// 停止构建
|
||||
|
@ -230,15 +230,39 @@
|
||||
</a-form-model-item>
|
||||
<a-collapse v-show="temp.runMode && temp.runMode !== 'File'">
|
||||
<a-collapse-panel v-for="nodeId in temp.nodeIdList" :key="nodeId" :header="nodeId">
|
||||
<a-form-model-item label="WebHooks" prop="token">
|
||||
<a-input v-model="temp[`${nodeId}_token`]" placeholder="关闭程序时自动请求,非必填,GET请求" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="JVM 参数" prop="jvm">
|
||||
<a-textarea v-model="temp[`${nodeId}_jvm`]" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="args 参数" prop="args">
|
||||
<a-textarea v-model="temp[`${nodeId}_args`]" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item prop="autoStart">
|
||||
<template slot="label">
|
||||
自启动
|
||||
<a-tooltip v-show="temp.type !== 'edit'">
|
||||
<template slot="title">插件端启动的时候检查项目状态,如果项目状态是未运行则尝试执行启动项目</template>
|
||||
<a-icon type="question-circle" theme="filled" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-switch v-model="temp[`${nodeId}_autoStart`]" checked-children="开" un-checked-children="关" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item prop="token">
|
||||
<template slot="label">
|
||||
WebHooks
|
||||
<a-tooltip v-show="temp.type !== 'edit'">
|
||||
<template slot="title">
|
||||
<ul>
|
||||
<li>项目启动,停止,重启都将请求对应的地址</li>
|
||||
<li>传人参数有:projectId、projectName、type、copyId、result</li>
|
||||
<li>type 的值有:stop、beforeStop、start、beforeRestart</li>
|
||||
</ul>
|
||||
</template>
|
||||
<a-icon type="question-circle" theme="filled" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input v-model="temp[`${nodeId}_token`]" placeholder="项目启动,停止,重启都将请求对应的地址,非必填,GET请求" />
|
||||
</a-form-model-item>
|
||||
|
||||
<!-- 副本信息 -->
|
||||
<a-row v-for="replica in temp[`${nodeId}_javaCopyItemList`]" :key="replica.id">
|
||||
<a-form-model-item :label="`副本 ${replica.id} JVM 参数`" prop="jvm">
|
||||
@ -641,6 +665,8 @@ export default {
|
||||
this.temp[`${ele.nodeId}_jvm`] = res.data.jvm || "";
|
||||
this.temp[`${ele.nodeId}_token`] = res.data.token || "";
|
||||
this.temp[`${ele.nodeId}_args`] = res.data.args || "";
|
||||
this.temp[`${ele.nodeId}_autoStart`] = res.data.autoStart;
|
||||
|
||||
// 添加 javaCopyItemList
|
||||
this.temp[`${ele.nodeId}_javaCopyItemList`] = res.data.javaCopyItemList || [];
|
||||
this.temp = { ...this.temp };
|
||||
|
@ -46,7 +46,14 @@
|
||||
<a-select-option v-for="project in nodeProjectList" :key="project.id">【{{ project.nodeName }}】{{ project.name }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="报警联系人" prop="notifyUser" class="jpom-notify">
|
||||
<a-form-model-item prop="notifyUser" class="jpom-notify">
|
||||
<template slot="label">
|
||||
报警联系人
|
||||
<a-tooltip v-show="!temp.id">
|
||||
<template slot="title"> 如果这里的报警联系人无法选择,说明这里面的管理员没有设置邮箱,在右上角下拉菜单里面的用户资料里可以设置。 </template>
|
||||
<a-icon type="question-circle" theme="filled" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-transfer
|
||||
:data-source="userList"
|
||||
:lazy="false"
|
||||
|
@ -4,7 +4,6 @@
|
||||
<a-input v-model="listQuery['%name%']" placeholder="监控名称" class="search-input-item" />
|
||||
<a-button type="primary" @click="loadData">搜索</a-button>
|
||||
<a-button type="primary" @click="handleAdd">新增</a-button>
|
||||
|
||||
</div>
|
||||
<!-- 数据表格 -->
|
||||
<a-table :data-source="list" :loading="loading" :columns="columns" :pagination="this.pagination" @change="changePage" bordered :rowKey="(record, index) => index">
|
||||
@ -64,7 +63,14 @@
|
||||
@change="handleMethodFeatureChange"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="报警联系人" prop="notifyUser" class="jpom-monitor-notify">
|
||||
<a-form-model-item prop="notifyUser" class="jpom-monitor-notify">
|
||||
<template slot="label">
|
||||
报警联系人
|
||||
<a-tooltip v-show="!temp.id">
|
||||
<template slot="title"> 如果这里的报警联系人无法选择,说明这里面的管理员没有设置邮箱,在右上角下拉菜单里面的用户资料里可以设置。 </template>
|
||||
<a-icon type="question-circle" theme="filled" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-transfer :data-source="userList" :lazy="false" show-search :filter-option="filterOption" :target-keys="notifyUserKeys" :render="(item) => item.title" @change="handleNotifyUserChange" />
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
@ -267,28 +273,24 @@ export default {
|
||||
if (this.monitorUserKeys.length === 0) {
|
||||
this.$notification.error({
|
||||
message: "请选择监控用户",
|
||||
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.methodFeatureKeys.length === 0) {
|
||||
this.$notification.error({
|
||||
message: "请选择监控操作",
|
||||
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.classFeatureKeys.length === 0) {
|
||||
this.$notification.error({
|
||||
message: "请选择监控的功能",
|
||||
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.notifyUserKeys.length === 0) {
|
||||
this.$notification.error({
|
||||
message: "请选择报警联系人",
|
||||
|
||||
});
|
||||
return false;
|
||||
}
|
||||
@ -303,7 +305,6 @@ export default {
|
||||
// 成功
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
|
||||
});
|
||||
this.$refs["editMonitorForm"].resetFields();
|
||||
this.editOperateMonitorVisible = false;
|
||||
@ -325,7 +326,6 @@ export default {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
|
||||
});
|
||||
this.loadData();
|
||||
}
|
||||
|
@ -203,8 +203,31 @@
|
||||
</template>
|
||||
<a-button type="primary" @click="handleAddReplica">添加副本</a-button>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="WebHooks" prop="token" v-show="temp.runMode && temp.runMode !== 'File'" class="jpom-node-project-token">
|
||||
<a-input v-model="temp.token" placeholder="关闭程序时自动请求,非必填,GET请求" />
|
||||
<a-form-model-item prop="autoStart">
|
||||
<template slot="label">
|
||||
自启动
|
||||
<a-tooltip v-show="temp.type !== 'edit'">
|
||||
<template slot="title">插件端启动的时候检查项目状态,如果项目状态是未运行则尝试执行启动项目</template>
|
||||
<a-icon type="question-circle" theme="filled" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-switch v-model="temp.autoStart" checked-children="开" un-checked-children="关" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item prop="token" v-show="temp.runMode && temp.runMode !== 'File'" class="jpom-node-project-token">
|
||||
<template slot="label">
|
||||
WebHooks
|
||||
<a-tooltip v-show="temp.type !== 'edit'">
|
||||
<template slot="title">
|
||||
<ul>
|
||||
<li>项目启动,停止,重启都将请求对应的地址</li>
|
||||
<li>传人参数有:projectId、projectName、type、copyId、result</li>
|
||||
<li>type 的值有:stop、beforeStop、start、beforeRestart</li>
|
||||
</ul>
|
||||
</template>
|
||||
<a-icon type="question-circle" theme="filled" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input v-model="temp.token" placeholder="项目启动,停止,重启都将请求对应的地址,非必填,GET请求" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item v-show="temp.type === 'edit' && temp.runMode !== 'File'" label="日志路径" prop="log">
|
||||
<a-alert :message="temp.log" type="success" />
|
||||
@ -505,7 +528,6 @@ export default {
|
||||
if (this.temp.outGivingProject) {
|
||||
this.$notification.warning({
|
||||
message: "独立的项目分发请到分发管理中去修改",
|
||||
|
||||
});
|
||||
return;
|
||||
}
|
||||
@ -531,7 +553,6 @@ export default {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
|
||||
});
|
||||
this.$refs["editProjectForm"].resetFields();
|
||||
this.editProjectVisible = false;
|
||||
@ -600,7 +621,6 @@ export default {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
|
||||
});
|
||||
this.loadData();
|
||||
}
|
||||
@ -625,8 +645,7 @@ export default {
|
||||
if (res.code !== 200) {
|
||||
this.$notification.warning({
|
||||
message: res.msg,
|
||||
description: '提示',
|
||||
|
||||
description: "提示",
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -666,7 +685,6 @@ export default {
|
||||
if (this.selectedRows.length == 0) {
|
||||
this.$notification.warning({
|
||||
message: "请选中要启动的项目",
|
||||
|
||||
});
|
||||
}
|
||||
this.selectedRows.forEach((value) => {
|
||||
@ -687,7 +705,6 @@ export default {
|
||||
if (this.selectedRows.length == 0) {
|
||||
this.$notification.warning({
|
||||
message: "请选中要重启的项目",
|
||||
|
||||
});
|
||||
}
|
||||
this.selectedRows.forEach((value) => {
|
||||
@ -707,7 +724,6 @@ export default {
|
||||
if (this.selectedRows.length == 0) {
|
||||
this.$notification.warning({
|
||||
message: "请选中要关闭的项目",
|
||||
|
||||
});
|
||||
}
|
||||
this.selectedRows.forEach((value) => {
|
||||
|
@ -253,7 +253,7 @@ export default {
|
||||
[nodeId]: {
|
||||
...data,
|
||||
type: "uploading",
|
||||
percent: (completeSize / size) * 100,
|
||||
percent: Math.floor((completeSize / size) * 100),
|
||||
},
|
||||
});
|
||||
},
|
||||
|
@ -4,7 +4,7 @@
|
||||
<div ref="filter" class="filter">
|
||||
<a-input class="search-input-item" v-model="listQuery['%name%']" placeholder="仓库名" />
|
||||
<a-input class="search-input-item" v-model="listQuery['%gitUrl%']" placeholder="仓库地址" />
|
||||
<a-select v-model="listQuery.repoType" allowClear placeholder="请选择仓库类型" class="filter-item" @change="handleFilter">
|
||||
<a-select v-model="listQuery.repoType" allowClear placeholder="请选择仓库类型" class="filter-item">
|
||||
<a-select-option :value="'0'">GIT</a-select-option>
|
||||
<a-select-option :value="'1'">SVN</a-select-option>
|
||||
</a-select>
|
||||
@ -110,7 +110,7 @@
|
||||
<a-textarea :auto-size="{ minRows: 3, maxRows: 3 }" v-model="temp.rsaPub" placeholder="公钥,不填将使用默认的 $HOME/.ssh 目录中的配置。支持配置文件目录:file:"></a-textarea>
|
||||
</a-form-model-item>
|
||||
</template>
|
||||
<a-form-model-item v-if="temp.id">
|
||||
<a-form-model-item v-if="temp.id" prop="restHideField">
|
||||
<template slot="label">
|
||||
隐藏字段
|
||||
<a-tooltip>
|
||||
@ -224,10 +224,10 @@ export default {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 筛选
|
||||
handleFilter() {
|
||||
this.loadData();
|
||||
},
|
||||
// // 筛选
|
||||
// handleFilter() {
|
||||
// this.loadData();
|
||||
// },
|
||||
// 添加
|
||||
handleAdd() {
|
||||
this.temp = {
|
||||
@ -258,11 +258,10 @@ export default {
|
||||
// 成功
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
|
||||
});
|
||||
this.$refs["editForm"].resetFields();
|
||||
this.editVisible = false;
|
||||
this.handleFilter();
|
||||
this.loadData();
|
||||
this.$refs["editForm"].resetFields();
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -277,14 +276,13 @@ export default {
|
||||
onOk: () => {
|
||||
const params = {
|
||||
id: record.id,
|
||||
isRealDel: this.isSystem,
|
||||
//isRealDel: this.isSystem,
|
||||
};
|
||||
// 删除
|
||||
deleteRepository(params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
|
||||
});
|
||||
this.loadData();
|
||||
}
|
||||
@ -306,7 +304,6 @@ export default {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
|
||||
});
|
||||
this.loadData();
|
||||
}
|
||||
|
@ -1,52 +1,73 @@
|
||||
// vue.config.js
|
||||
const IP = '127.0.0.1'
|
||||
const IP = "127.0.0.1";
|
||||
const Timestamp = new Date().getTime();
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
module.exports = {
|
||||
// 输出目录
|
||||
outputDir: '../modules/server/src/main/resources/dist',
|
||||
outputDir: "../modules/server/src/main/resources/dist",
|
||||
// 控制静态资源使用相对路径
|
||||
publicPath: './',
|
||||
publicPath: "./",
|
||||
// 代理设置
|
||||
devServer: {
|
||||
port: 3000,
|
||||
proxy: {
|
||||
// websocket
|
||||
'/ssh': {
|
||||
"/ssh": {
|
||||
target: `wss://${IP}:2122`,
|
||||
// true/false: if you want to proxy websockets
|
||||
ws: false,
|
||||
secure: false,
|
||||
},
|
||||
'/tomcat_log': {
|
||||
"/tomcat_log": {
|
||||
target: `wss://${IP}:2122`,
|
||||
// true/false: if you want to proxy websockets
|
||||
ws: false,
|
||||
secure: false,
|
||||
},
|
||||
'/console': {
|
||||
"/console": {
|
||||
target: `wss://${IP}:2122`,
|
||||
// true/false: if you want to proxy websockets
|
||||
ws: false,
|
||||
secure: false,
|
||||
},
|
||||
'/script_run': {
|
||||
"/script_run": {
|
||||
target: `wss://${IP}:2122`,
|
||||
// true/false: if you want to proxy websockets
|
||||
ws: false,
|
||||
secure: false,
|
||||
},
|
||||
// http
|
||||
'/*': {
|
||||
"/*": {
|
||||
target: `http://${IP}:2122`,
|
||||
timeout: 10 * 60 * 1000
|
||||
}
|
||||
timeout: 10 * 60 * 1000,
|
||||
},
|
||||
},
|
||||
},
|
||||
chainWebpack: config => {
|
||||
config.plugin('html')
|
||||
.tap(args => {
|
||||
args[0].title= 'Jpom项目管理系统'
|
||||
args[0].build= new Date().getTime()
|
||||
return args
|
||||
})
|
||||
}
|
||||
}
|
||||
configureWebpack: {
|
||||
// name: name,
|
||||
// 修改打包后的js文件名称
|
||||
output: {
|
||||
// 输出重构 打包编译后的 文件名称 【模块名称.版本号.时间戳】
|
||||
filename: `js/[name].[hash].${Timestamp}.js`,
|
||||
chunkFilename: `js/[name].[hash].${Timestamp}.js`,
|
||||
},
|
||||
// 修改打包后的css文件名称
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({
|
||||
filename: `css/[name].[contenthash].${Timestamp}.css`,
|
||||
}),
|
||||
],
|
||||
// resolve: {
|
||||
// alias: {
|
||||
// "@": resolve("src")
|
||||
// }
|
||||
// }
|
||||
},
|
||||
chainWebpack: (config) => {
|
||||
config.plugin("html").tap((args) => {
|
||||
args[0].title = "Jpom项目管理系统";
|
||||
args[0].build = new Date().getTime();
|
||||
return args;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user