mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-02 20:08:40 +08:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
5ba189e575
@ -2,5 +2,5 @@
|
||||
"tag_name": "v2.7.2",
|
||||
"agentUrl": "https://jpom-releases.oss-cn-hangzhou.aliyuncs.com/agent-2.7.2-release.zip",
|
||||
"serverUrl": "https://jpom-releases.oss-cn-hangzhou.aliyuncs.com/server-2.7.2-release.zip",
|
||||
"changelog": "https://gitee.com/dromara/Jpom/raw/master/CHANGELOG.md"
|
||||
"changelogUrl": "https://gitee.com/dromara/Jpom/raw/master/CHANGELOG.md"
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public class JpomAgentApplication {
|
||||
// 拦截器
|
||||
.addInterceptor(AuthorizeInterceptor.class)
|
||||
// 添加 参数 url 解码
|
||||
.addHandlerMethodArgumentResolver(UrlDecodeHandlerMethodArgumentResolver.class)
|
||||
// .addHandlerMethodArgumentResolver(UrlDecodeHandlerMethodArgumentResolver.class)
|
||||
.run(args);
|
||||
}
|
||||
|
||||
|
@ -41,24 +41,24 @@ import java.lang.reflect.Field;
|
||||
*/
|
||||
public class UrlDecodeHandlerMethodArgumentResolver extends DefaultHandlerMethodArgumentResolver {
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
|
||||
Object argument = super.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
|
||||
if (argument instanceof String) {
|
||||
// 解码
|
||||
return URLUtil.decode(argument.toString());
|
||||
} else if (argument instanceof BaseJsonModel) {
|
||||
// 解码对象属性
|
||||
Field[] fields = ReflectUtil.getFields(argument.getClass());
|
||||
for (Field field : fields) {
|
||||
Class<?> type = field.getType();
|
||||
if (type == String.class) {
|
||||
String fieldValue = (String) ReflectUtil.getFieldValue(argument, field);
|
||||
fieldValue = URLUtil.decode(fieldValue);
|
||||
ReflectUtil.setFieldValue(argument, field, fieldValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return argument;
|
||||
}
|
||||
// @Override
|
||||
// public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
|
||||
// Object argument = super.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
|
||||
// if (argument instanceof String) {
|
||||
// // 解码
|
||||
// return URLUtil.decode(argument.toString());
|
||||
// } else if (argument instanceof BaseJsonModel) {
|
||||
// // 解码对象属性
|
||||
// Field[] fields = ReflectUtil.getFields(argument.getClass());
|
||||
// for (Field field : fields) {
|
||||
// Class<?> type = field.getType();
|
||||
// if (type == String.class) {
|
||||
// String fieldValue = (String) ReflectUtil.getFieldValue(argument, field);
|
||||
// fieldValue = URLUtil.decode(fieldValue);
|
||||
// ReflectUtil.setFieldValue(argument, field, fieldValue);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return argument;
|
||||
// }
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ import io.jpom.common.JpomManifest;
|
||||
import io.jpom.common.RemoteVersion;
|
||||
import io.jpom.common.Type;
|
||||
import io.jpom.system.AgentConfigBean;
|
||||
import io.jpom.system.ConfigBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@ -109,4 +110,16 @@ public class SystemUpdateController extends BaseAgentController {
|
||||
RemoteVersion remoteVersion = RemoteVersion.loadRemoteInfo();
|
||||
return JsonMessage.getString(200, "", remoteVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程下载升级
|
||||
*
|
||||
* @return json
|
||||
* @see RemoteVersion
|
||||
*/
|
||||
@PostMapping(value = "remote_upgrade.json", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String upgrade() throws IOException {
|
||||
RemoteVersion.upgrade(ConfigBean.getInstance().getTempPath().getAbsolutePath());
|
||||
return JsonMessage.getString(200, "升级中大约需要30秒");
|
||||
}
|
||||
}
|
||||
|
@ -74,11 +74,9 @@ public class UploadFileModel extends BaseModel {
|
||||
this.completeSize += data.length;
|
||||
File file = new File(this.getFilePath());
|
||||
FileUtil.mkParentDirs(file);
|
||||
try {
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(file, true);
|
||||
try(FileOutputStream fileOutputStream = new FileOutputStream(file, true)) {
|
||||
fileOutputStream.write(data);
|
||||
fileOutputStream.flush();
|
||||
fileOutputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -23,3 +23,4 @@ preload:
|
||||
# 强制去掉空格
|
||||
request:
|
||||
trimAll: true
|
||||
urlDecode: true
|
||||
|
@ -137,7 +137,7 @@ public class JpomManifest {
|
||||
String timeStamp = attributes.getValue("Jpom-Timestamp");
|
||||
timeStamp = parseJpomTime(timeStamp);
|
||||
String mainClass = attributes.getValue(Attributes.Name.MAIN_CLASS);
|
||||
return new Tuple(version, timeStamp, mainClass);
|
||||
return new Tuple(version, timeStamp, mainClass, jarFile);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -81,11 +81,14 @@ public class RemoteVersion {
|
||||
* 服务端下载地址
|
||||
*/
|
||||
private String serverUrl;
|
||||
/**
|
||||
* 更新日志 (远程url)
|
||||
*/
|
||||
private String changelogUrl;
|
||||
/**
|
||||
* 更新日志
|
||||
*/
|
||||
private String changelog;
|
||||
|
||||
/**
|
||||
* 上次获取时间
|
||||
*/
|
||||
@ -144,6 +147,14 @@ public class RemoteVersion {
|
||||
this.lastTime = lastTime;
|
||||
}
|
||||
|
||||
public String getChangelogUrl() {
|
||||
return changelogUrl;
|
||||
}
|
||||
|
||||
public void setChangelogUrl(String changelogUrl) {
|
||||
this.changelogUrl = changelogUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSONObject.toJSONString(this);
|
||||
@ -218,7 +229,7 @@ public class RemoteVersion {
|
||||
tagName = StrUtil.removePrefixIgnoreCase(tagName, "v");
|
||||
remoteVersion.setUpgrade(StrUtil.compareVersion(version, tagName) < 0);
|
||||
} else {
|
||||
remoteVersion.setUpgrade(false);
|
||||
remoteVersion.setUpgrade(true);
|
||||
}
|
||||
// 检查是否存在下载地址
|
||||
Type type = instance.getType();
|
||||
@ -226,6 +237,12 @@ public class RemoteVersion {
|
||||
if (StrUtil.isEmpty(remoteUrl)) {
|
||||
remoteVersion.setUpgrade(false);
|
||||
}
|
||||
// 获取 changelog
|
||||
String changelogUrl = remoteVersion.getChangelogUrl();
|
||||
if (StrUtil.isNotEmpty(changelogUrl)) {
|
||||
String body = HttpUtil.createGet(changelogUrl).execute().body();
|
||||
remoteVersion.setChangelog(body);
|
||||
}
|
||||
//
|
||||
FileUtil.writeUtf8String(remoteVersion.toString(), getFile());
|
||||
}
|
||||
@ -262,6 +279,31 @@ public class RemoteVersion {
|
||||
return remoteVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载
|
||||
*
|
||||
* @param savePath 下载文件保存路径
|
||||
* @param type 类型
|
||||
* @return 保存的全路径
|
||||
* @throws IOException 异常
|
||||
*/
|
||||
public static Tuple download(String savePath, Type type) throws IOException {
|
||||
RemoteVersion remoteVersion = loadRemoteInfo();
|
||||
Assert.notNull(remoteVersion, "没有可用的新版本升级:-1");
|
||||
Assert.state(remoteVersion.getUpgrade() != null && remoteVersion.getUpgrade(), "没有可用的新版本升级");
|
||||
// 检查是否存在下载地址
|
||||
String remoteUrl = type.getRemoteUrl(remoteVersion);
|
||||
Assert.hasText(remoteUrl, "存在新版本,下载地址不可用");
|
||||
// 下载
|
||||
File downloadFileFromUrl = HttpUtil.downloadFileFromUrl(remoteUrl, savePath);
|
||||
// 解析压缩包
|
||||
File file = JpomManifest.zipFileFind(FileUtil.getAbsolutePath(downloadFileFromUrl), type, savePath);
|
||||
// 检查
|
||||
JsonMessage<Tuple> error = JpomManifest.checkJpomJar(FileUtil.getAbsolutePath(file), type.getApplicationClass());
|
||||
Assert.state(error.getCode() == HttpStatus.HTTP_OK, error.getMsg());
|
||||
return error.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 升级
|
||||
*
|
||||
@ -269,23 +311,12 @@ public class RemoteVersion {
|
||||
* @throws IOException 异常
|
||||
*/
|
||||
public static void upgrade(String savePath) throws IOException {
|
||||
RemoteVersion remoteVersion = loadRemoteInfo();
|
||||
Assert.notNull(remoteVersion, "没有可用的新版本升级:-1");
|
||||
Assert.state(remoteVersion.getUpgrade() != null && remoteVersion.getUpgrade(), "没有可用的新版本升级");
|
||||
// 检查是否存在下载地址
|
||||
Type type = JpomManifest.getInstance().getType();
|
||||
String remoteUrl = type.getRemoteUrl(remoteVersion);
|
||||
Assert.hasText(remoteUrl, "存在新版本,下载地址不可用");
|
||||
// 下载
|
||||
File versionFile = HttpUtil.downloadFileFromUrl(remoteUrl, savePath);
|
||||
// 解析压缩包
|
||||
File file = JpomManifest.zipFileFind(FileUtil.getAbsolutePath(versionFile), type, savePath);
|
||||
Tuple data = download(savePath, type);
|
||||
File file = data.get(3);
|
||||
// 基础检查
|
||||
String path = FileUtil.getAbsolutePath(file);
|
||||
JsonMessage<Tuple> error = JpomManifest.checkJpomJar(path, type.getApplicationClass());
|
||||
Assert.state(error.getCode() == HttpStatus.HTTP_OK, error.getMsg());
|
||||
//
|
||||
Tuple data = error.getData();
|
||||
String version = data.get(0);
|
||||
JpomManifest.releaseJar(path, version);
|
||||
//
|
||||
|
@ -208,6 +208,10 @@ public enum NodeUrl {
|
||||
* 更新系统jar包
|
||||
*/
|
||||
CHECK_VERSION("/system/check_version.json"),
|
||||
/**
|
||||
* 远程升级
|
||||
*/
|
||||
REMOTE_UPGRADE("/system/remote_upgrade.json"),
|
||||
CHANGE_LOG("/system/change_log"),
|
||||
|
||||
/**
|
||||
|
@ -1,49 +1,29 @@
|
||||
package io.jpom.controller.node;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.Tuple;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.jiangzeyin.controller.multipart.MultipartFileBuilder;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.jpom.common.BaseServerController;
|
||||
import io.jpom.common.JpomManifest;
|
||||
import io.jpom.common.Type;
|
||||
import io.jpom.common.forward.NodeForward;
|
||||
import io.jpom.common.forward.NodeUrl;
|
||||
import io.jpom.common.interceptor.OptLog;
|
||||
import io.jpom.model.AgentFileModel;
|
||||
import io.jpom.model.data.NodeModel;
|
||||
import io.jpom.model.log.UserOperateLogV1;
|
||||
import io.jpom.permission.SystemPermission;
|
||||
import io.jpom.plugin.ClassFeature;
|
||||
import io.jpom.plugin.Feature;
|
||||
import io.jpom.plugin.MethodFeature;
|
||||
import io.jpom.service.node.AgentFileService;
|
||||
import io.jpom.service.node.ssh.SshService;
|
||||
import io.jpom.system.ServerConfigBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* 节点管理
|
||||
@ -56,10 +36,6 @@ import java.util.zip.ZipFile;
|
||||
@Feature(cls = ClassFeature.NODE)
|
||||
public class NodeIndexController extends BaseServerController {
|
||||
|
||||
@Resource
|
||||
private SshService sshService;
|
||||
@Resource
|
||||
private AgentFileService agentFileService;
|
||||
|
||||
private List<NodeModel> listByGroup(String group) {
|
||||
List<NodeModel> nodeModels = nodeService.list();
|
||||
@ -110,7 +86,7 @@ public class NodeIndexController extends BaseServerController {
|
||||
|
||||
/**
|
||||
* @param status 节点状态获取
|
||||
* @return
|
||||
* @return json
|
||||
* @author Hotstrip
|
||||
* load node project list
|
||||
* 加载节点项目列表
|
||||
@ -128,50 +104,5 @@ public class NodeIndexController extends BaseServerController {
|
||||
return JsonMessage.getString(200, "success", nodeModels);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "upload_agent", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
@OptLog(UserOperateLogV1.OptType.UpdateSys)
|
||||
@SystemPermission
|
||||
public String uploadAgent() throws IOException {
|
||||
String saveDir = ServerConfigBean.getInstance().getAgentPath().getAbsolutePath();
|
||||
MultipartFileBuilder multipartFileBuilder = createMultipart();
|
||||
multipartFileBuilder
|
||||
.setFileExt("jar", "zip")
|
||||
.addFieldName("file")
|
||||
.setUseOriginalFilename(true)
|
||||
.setSavePath(saveDir);
|
||||
String path = multipartFileBuilder.save();
|
||||
// 解析压缩包
|
||||
File file = JpomManifest.zipFileFind(path, Type.Agent, saveDir);
|
||||
path = FileUtil.getAbsolutePath(file);
|
||||
// 基础检查
|
||||
JsonMessage<Tuple> error = JpomManifest.checkJpomJar(path, Type.Agent.getApplicationClass(), false);
|
||||
if (error.getCode() != HttpStatus.HTTP_OK) {
|
||||
FileUtil.del(path);
|
||||
return error.toString();
|
||||
}
|
||||
// 保存Agent文件
|
||||
String id = Type.Agent.name().toLowerCase();
|
||||
|
||||
AgentFileModel agentFileModel = agentFileService.getItem(id);
|
||||
if (agentFileModel == null) {
|
||||
agentFileModel = new AgentFileModel();
|
||||
agentFileModel.setId(id);
|
||||
agentFileService.addItem(agentFileModel);
|
||||
}
|
||||
agentFileModel.setName(file.getName());
|
||||
agentFileModel.setSize(file.length());
|
||||
agentFileModel.setSavePath(path);
|
||||
//
|
||||
Tuple data = error.getData();
|
||||
agentFileModel.setVersion(data.get(0));
|
||||
agentFileModel.setTimeStamp(data.get(1));
|
||||
agentFileService.updateItem(agentFileModel);
|
||||
// 删除历史包 @author jzy 2021-08-03
|
||||
List<File> files = FileUtil.loopFiles(saveDir, pathname -> !FileUtil.equals(pathname, file));
|
||||
for (File file1 : files) {
|
||||
FileUtil.del(file1);
|
||||
}
|
||||
return JsonMessage.getString(200, "上传成功");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,106 @@
|
||||
package io.jpom.controller.node;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.Tuple;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.jiangzeyin.controller.multipart.MultipartFileBuilder;
|
||||
import io.jpom.common.BaseServerController;
|
||||
import io.jpom.common.JpomManifest;
|
||||
import io.jpom.common.RemoteVersion;
|
||||
import io.jpom.common.Type;
|
||||
import io.jpom.common.interceptor.OptLog;
|
||||
import io.jpom.model.AgentFileModel;
|
||||
import io.jpom.model.log.UserOperateLogV1;
|
||||
import io.jpom.permission.SystemPermission;
|
||||
import io.jpom.service.node.AgentFileService;
|
||||
import io.jpom.system.ConfigBean;
|
||||
import io.jpom.system.ServerConfigBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author bwcx_jzy
|
||||
* @since 2021/11/29
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(value = "/node")
|
||||
public class NodeUpdateController extends BaseServerController {
|
||||
|
||||
private final AgentFileService agentFileService;
|
||||
|
||||
public NodeUpdateController(AgentFileService agentFileService) {
|
||||
this.agentFileService = agentFileService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程下载
|
||||
*
|
||||
* @return json
|
||||
* @see RemoteVersion
|
||||
*/
|
||||
@GetMapping(value = "download_remote.json", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String downloadRemote() throws IOException {
|
||||
Tuple download = RemoteVersion.download(ConfigBean.getInstance().getTempPath().getAbsolutePath(), Type.Agent);
|
||||
// 保存文件
|
||||
this.saveAgentFile(download);
|
||||
return JsonMessage.getString(200, "下载成功");
|
||||
}
|
||||
|
||||
@RequestMapping(value = "upload_agent", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
@OptLog(UserOperateLogV1.OptType.UpdateSys)
|
||||
@SystemPermission
|
||||
public String uploadAgent() throws IOException {
|
||||
String saveDir = ServerConfigBean.getInstance().getAgentPath().getAbsolutePath();
|
||||
MultipartFileBuilder multipartFileBuilder = createMultipart();
|
||||
multipartFileBuilder
|
||||
.setFileExt("jar", "zip")
|
||||
.addFieldName("file")
|
||||
.setUseOriginalFilename(true)
|
||||
.setSavePath(saveDir);
|
||||
String path = multipartFileBuilder.save();
|
||||
// 解析压缩包
|
||||
File file = JpomManifest.zipFileFind(path, Type.Agent, saveDir);
|
||||
path = FileUtil.getAbsolutePath(file);
|
||||
// 基础检查
|
||||
JsonMessage<Tuple> error = JpomManifest.checkJpomJar(path, Type.Agent.getApplicationClass(), false);
|
||||
if (error.getCode() != HttpStatus.HTTP_OK) {
|
||||
FileUtil.del(path);
|
||||
return error.toString();
|
||||
}
|
||||
// 保存文件
|
||||
this.saveAgentFile(error.getData());
|
||||
return JsonMessage.getString(200, "上传成功");
|
||||
}
|
||||
|
||||
private void saveAgentFile(Tuple data) {
|
||||
File file = data.get(3);
|
||||
// 保存Agent文件
|
||||
String id = Type.Agent.name().toLowerCase();
|
||||
|
||||
AgentFileModel agentFileModel = agentFileService.getItem(id);
|
||||
if (agentFileModel == null) {
|
||||
agentFileModel = new AgentFileModel();
|
||||
agentFileModel.setId(id);
|
||||
agentFileService.addItem(agentFileModel);
|
||||
}
|
||||
agentFileModel.setName(file.getName());
|
||||
agentFileModel.setSize(file.length());
|
||||
agentFileModel.setSavePath(FileUtil.getAbsolutePath(file));
|
||||
//
|
||||
agentFileModel.setVersion(data.get(0));
|
||||
agentFileModel.setTimeStamp(data.get(1));
|
||||
agentFileService.updateItem(agentFileModel);
|
||||
// 删除历史包 @author jzy 2021-08-03
|
||||
String saveDir = ServerConfigBean.getInstance().getAgentPath().getAbsolutePath();
|
||||
List<File> files = FileUtil.loopFiles(saveDir, pathname -> !FileUtil.equals(pathname, file));
|
||||
for (File file1 : files) {
|
||||
FileUtil.del(file1);
|
||||
}
|
||||
}
|
||||
}
|
@ -44,6 +44,7 @@ import io.jpom.common.interceptor.OptLog;
|
||||
import io.jpom.model.data.NodeModel;
|
||||
import io.jpom.model.log.UserOperateLogV1;
|
||||
import io.jpom.permission.SystemPermission;
|
||||
import io.jpom.system.ConfigBean;
|
||||
import io.jpom.system.ServerConfigBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -79,6 +80,11 @@ public class SystemUpdateController extends BaseServerController {
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新日志
|
||||
*
|
||||
* @return changelog md
|
||||
*/
|
||||
@PostMapping(value = "change_log", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String changeLog() {
|
||||
NodeModel nodeModel = tryGetNode();
|
||||
@ -144,4 +150,20 @@ public class SystemUpdateController extends BaseServerController {
|
||||
RemoteVersion remoteVersion = RemoteVersion.loadRemoteInfo();
|
||||
return JsonMessage.getString(200, "", remoteVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程下载升级
|
||||
*
|
||||
* @return json
|
||||
* @see RemoteVersion
|
||||
*/
|
||||
@GetMapping(value = "remote_upgrade.json", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String upgrade() throws IOException {
|
||||
NodeModel nodeModel = tryGetNode();
|
||||
if (nodeModel != null) {
|
||||
return NodeForward.request(getNode(), getRequest(), NodeUrl.REMOTE_UPGRADE).toString();
|
||||
}
|
||||
RemoteVersion.upgrade(ConfigBean.getInstance().getTempPath().getAbsolutePath());
|
||||
return JsonMessage.getString(200, "升级中大约需要30秒");
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +1,49 @@
|
||||
import axios from './config';
|
||||
import axios from "./config";
|
||||
|
||||
// 分组
|
||||
export function getNodeGroupList() {
|
||||
return axios({
|
||||
url: '/node/list_group.json',
|
||||
method: 'get'
|
||||
})
|
||||
url: "/node/list_group.json",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
// node 列表
|
||||
export function getNodeList(params) {
|
||||
return axios({
|
||||
url: '/node/list_data.json',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
url: "/node/list_data.json",
|
||||
method: "get",
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
// 节点和版本信息
|
||||
export function getNodeListWithVersion(params) {
|
||||
return axios({
|
||||
url: '/node/list_data_with_version',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
url: "/node/list_data_with_version",
|
||||
method: "get",
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
// node 状态
|
||||
export function getNodeStatus(nodeId) {
|
||||
return axios({
|
||||
url: '/node/node_status',
|
||||
method: 'post',
|
||||
data: {nodeId}
|
||||
})
|
||||
url: "/node/node_status",
|
||||
method: "post",
|
||||
data: { nodeId },
|
||||
});
|
||||
}
|
||||
|
||||
// 节点 + 项目列表
|
||||
export function getNodeProjectList(params) {
|
||||
return axios({
|
||||
url: '/node/node_project_list',
|
||||
method: 'post',
|
||||
url: "/node/node_project_list",
|
||||
method: "post",
|
||||
params: params,
|
||||
timeout: 0
|
||||
})
|
||||
timeout: 0,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 编辑 node
|
||||
* @param {
|
||||
@ -60,7 +59,7 @@ export function getNodeProjectList(params) {
|
||||
* loginName: 用户名,
|
||||
* loginPwd: 密码,
|
||||
* type: 操作类型 add || update
|
||||
* } params
|
||||
* } params
|
||||
*/
|
||||
export function editNode(params) {
|
||||
const data = {
|
||||
@ -75,46 +74,46 @@ export function editNode(params) {
|
||||
openStatus: params.openStatus,
|
||||
loginName: params.loginName,
|
||||
loginPwd: params.loginPwd,
|
||||
type: params.type
|
||||
}
|
||||
type: params.type,
|
||||
};
|
||||
return axios({
|
||||
url: '/node/save.json',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
url: "/node/save.json",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除 node
|
||||
export function deleteNode(id) {
|
||||
return axios({
|
||||
url: '/node/del.json',
|
||||
method: 'post',
|
||||
data: {id}
|
||||
})
|
||||
url: "/node/del.json",
|
||||
method: "post",
|
||||
data: { id },
|
||||
});
|
||||
}
|
||||
|
||||
// 节点 top 命令
|
||||
export function getNodeTop(nodeId) {
|
||||
return axios({
|
||||
url: '/node/getTop',
|
||||
method: 'post',
|
||||
data: {nodeId},
|
||||
url: "/node/getTop",
|
||||
method: "post",
|
||||
data: { nodeId },
|
||||
headers: {
|
||||
loading: 'no'
|
||||
}
|
||||
})
|
||||
loading: "no",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 获取进程列表
|
||||
export function getProcessList(nodeId) {
|
||||
return axios({
|
||||
url: '/node/processList',
|
||||
method: 'post',
|
||||
data: {nodeId},
|
||||
url: "/node/processList",
|
||||
method: "post",
|
||||
data: { nodeId },
|
||||
headers: {
|
||||
loading: 'no'
|
||||
}
|
||||
})
|
||||
loading: "no",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,10 +122,10 @@ export function getProcessList(nodeId) {
|
||||
*/
|
||||
export function killPid(params) {
|
||||
return axios({
|
||||
url: '/node/kill.json',
|
||||
method: 'post',
|
||||
data: params
|
||||
})
|
||||
url: "/node/kill.json",
|
||||
method: "post",
|
||||
data: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,18 +133,16 @@ export function killPid(params) {
|
||||
* @param {
|
||||
* nodeId: 节点 ID,
|
||||
* time: 时间段,格式:yyyy-MM-dd HH:mm:ss ~ yyyy-MM-dd HH:mm:ss
|
||||
* } params
|
||||
* } params
|
||||
*/
|
||||
export function nodeMonitorData(params) {
|
||||
return axios({
|
||||
url: '/node/nodeMonitor_data.json',
|
||||
method: 'post',
|
||||
data: params
|
||||
})
|
||||
url: "/node/nodeMonitor_data.json",
|
||||
method: "post",
|
||||
data: params,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 上传升级文件
|
||||
* @param {
|
||||
@ -155,13 +152,21 @@ export function nodeMonitorData(params) {
|
||||
*/
|
||||
export function uploadAgentFile(formData) {
|
||||
return axios({
|
||||
url: '/node/upload_agent',
|
||||
url: "/node/upload_agent",
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data;charset=UTF-8'
|
||||
"Content-Type": "multipart/form-data;charset=UTF-8",
|
||||
},
|
||||
method: 'post',
|
||||
method: "post",
|
||||
// 0 表示无超时时间
|
||||
timeout: 0,
|
||||
data: formData
|
||||
})
|
||||
}
|
||||
data: formData,
|
||||
});
|
||||
}
|
||||
|
||||
export function downloadRemote() {
|
||||
return axios({
|
||||
url: "/node/download_remote.json",
|
||||
method: "get",
|
||||
data: {},
|
||||
});
|
||||
}
|
||||
|
@ -220,3 +220,16 @@ export function checkVersion(nodeId) {
|
||||
data: { nodeId },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程升级
|
||||
*@param {String} nodeId 节点 ID
|
||||
*/
|
||||
export function remoteUpgrade(nodeId) {
|
||||
return axios({
|
||||
url: "/system/remote_upgrade.json",
|
||||
method: "get",
|
||||
headers: {},
|
||||
data: { nodeId },
|
||||
});
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
<a-timeline-item>
|
||||
<span class="layui-elem-quote">当前版本号:{{ temp.version }} </span>
|
||||
<template v-if="temp.upgrade !== undefined">
|
||||
<a-tag v-if="temp.upgrade" color="pink">新版本:{{ temp.newVersion }} </a-tag>
|
||||
<a-tag v-if="temp.upgrade" color="pink" @click="upgrageVerion">新版本:{{ temp.newVersion }} </a-tag>
|
||||
<a-tag v-else color="orange" @click="checkVersion">
|
||||
<a-icon type="rocket" />
|
||||
</a-tag>
|
||||
@ -37,7 +37,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { systemInfo, uploadUpgradeFile, changelog, checkVersion } from "@/api/system";
|
||||
import { systemInfo, uploadUpgradeFile, changelog, checkVersion, remoteUpgrade } from "@/api/system";
|
||||
import MarkdownItVue from "markdown-it-vue";
|
||||
import "markdown-it-vue/dist/markdown-it-vue.css";
|
||||
export default {
|
||||
@ -81,13 +81,15 @@ export default {
|
||||
if (res.code === 200) {
|
||||
this.temp = res.data?.manifest;
|
||||
//
|
||||
// res.data.
|
||||
this.showVersion(false, res.data?.remoteVersion);
|
||||
|
||||
changelog(this.nodeId).then((resLog) => {
|
||||
this.changelog = resLog.data;
|
||||
//
|
||||
// res.data.
|
||||
this.showVersion(false, res.data?.remoteVersion);
|
||||
});
|
||||
}
|
||||
});
|
||||
changelog(this.nodeId).then((res) => {
|
||||
this.changelog = res.data;
|
||||
});
|
||||
},
|
||||
// 处理文件移除
|
||||
handleRemove(file) {
|
||||
@ -165,6 +167,7 @@ export default {
|
||||
}
|
||||
this.temp.upgrade = data.upgrade;
|
||||
this.temp.newVersion = data.tagName;
|
||||
this.changelog = data.changelog;
|
||||
if (tip) {
|
||||
this.$notification.success({
|
||||
message: this.temp.upgrade ? "检测到新版本 " + data.tagName : "没有检查到最新版",
|
||||
@ -172,6 +175,29 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
// 升级
|
||||
upgrageVerion() {
|
||||
this.$confirm({
|
||||
title: "系统提示",
|
||||
content: "启动要升级到最新版本吗?",
|
||||
okText: "确认",
|
||||
cancelText: "取消",
|
||||
onOk: () => {
|
||||
// 重新发布
|
||||
this.spinning = true;
|
||||
remoteUpgrade(this.nodeId).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
duration: 2,
|
||||
});
|
||||
this.checkUpgradeVersion();
|
||||
this.spinning = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -212,6 +212,7 @@ export default {
|
||||
},
|
||||
// 新增
|
||||
handleAdd() {
|
||||
this.temp = {};
|
||||
this.editMonitorVisible = true;
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
|
@ -9,7 +9,10 @@
|
||||
<a-button type="primary" @click="batchUpdate">批量更新</a-button>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="title">Agent最新版本:{{ agentVersion | version }}</div>
|
||||
<div class="title">
|
||||
Agent版本:{{ agentVersion | version }}
|
||||
<a-tag v-if="temp.upgrade" color="pink" @click="downloadRemoteEvent">新版本:{{ temp.newVersion }} </a-tag>
|
||||
</div>
|
||||
<div class="version">打包时间:{{ agentTimeStamp | version }}</div>
|
||||
<div class="action">
|
||||
<a-upload name="file" accept=".jar,.zip" action="" :showUploadList="false" :multiple="false" :before-upload="beforeUpload">
|
||||
@ -42,7 +45,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getNodeGroupList, uploadAgentFile } from "@/api/node";
|
||||
import { getNodeGroupList, uploadAgentFile, downloadRemote } from "@/api/node";
|
||||
import { systemInfo } from "@/api/system";
|
||||
import { mapGetters } from "vuex";
|
||||
|
||||
export default {
|
||||
@ -76,6 +80,7 @@ export default {
|
||||
nodeVersion: {},
|
||||
nodeStatus: {},
|
||||
tableSelections: [],
|
||||
temp: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -138,6 +143,17 @@ export default {
|
||||
init() {
|
||||
this.getNodeList();
|
||||
this.getAgentVersion();
|
||||
// 获取是否有新版本
|
||||
systemInfo().then((res) => {
|
||||
if (res.code === 200) {
|
||||
let remoteVersion = res.data?.remoteVersion;
|
||||
if (remoteVersion) {
|
||||
//
|
||||
this.temp.upgrade = remoteVersion.upgrade;
|
||||
this.temp.newVersion = remoteVersion.tagName;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
loadGroupList() {
|
||||
getNodeGroupList().then(({ code, data }) => {
|
||||
@ -244,6 +260,17 @@ export default {
|
||||
});
|
||||
return false;
|
||||
},
|
||||
// 下载远程最新文件
|
||||
downloadRemoteEvent() {
|
||||
downloadRemote().then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({ message: res.msg });
|
||||
this.getAgentVersion();
|
||||
} else {
|
||||
this.$notification.error({ message: res.msg });
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@ -258,12 +285,12 @@ export default {
|
||||
|
||||
|
||||
.header {
|
||||
height 60px
|
||||
display flex
|
||||
align-items center
|
||||
height 60px;
|
||||
display flex;
|
||||
align-items center;
|
||||
|
||||
> div {
|
||||
width 50%
|
||||
// width 50%;
|
||||
}
|
||||
|
||||
.left {
|
||||
@ -276,7 +303,8 @@ export default {
|
||||
.right {
|
||||
display flex
|
||||
justify-content flex-end
|
||||
align-items center
|
||||
align-items center;
|
||||
flex: 1;
|
||||
|
||||
> div {
|
||||
padding: 0 10px
|
||||
|
@ -1,4 +1,5 @@
|
||||
<template>
|
||||
<!-- 已经独立出公共组件 -->
|
||||
<upgrade></upgrade>
|
||||
</template>
|
||||
<script>
|
||||
|
Loading…
Reference in New Issue
Block a user