mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-11-29 18:38:32 +08:00
feat SSH 列表支持显示 docker 版本信息
This commit is contained in:
parent
953c5526ce
commit
d12d70c017
@ -46,6 +46,12 @@ max_line_length = off
|
||||
[*.bat]
|
||||
end_of_line = crlf
|
||||
|
||||
[*.sh]
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
max_line_length = off
|
||||
|
||||
[*.{vue,js,ts}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
### 🐣 新增功能
|
||||
|
||||
1. 【server】新增 SSH 列表支持显示 docker 版本信息
|
||||
|
||||
### 🐞 解决BUG、优化功能
|
||||
|
||||
@ -12,6 +13,11 @@
|
||||
3. 【server】优化 web socket 会话关闭显示分类
|
||||
4. 【server】优化 页面滚动条样式
|
||||
5. 【server】优化 编辑关联分发,选择项目下拉框不能显示项目全名称(tooltip)(感谢@LYY)
|
||||
6. 【server】优化 监听页面关闭事件,主动关闭 websocket
|
||||
|
||||
### ⚠️ 注意
|
||||
|
||||
1. 如果自定义过 SSH 监控脚本需要自行同步获取 docker 信息脚本
|
||||
|
||||
------
|
||||
|
||||
|
@ -164,6 +164,10 @@ public class MachineSshModel extends BaseGroupNameModel implements ISshInfo {
|
||||
* java 版本
|
||||
*/
|
||||
private String javaVersion;
|
||||
/**
|
||||
* 服务器中的 docker 信息
|
||||
*/
|
||||
private String dockerInfo;
|
||||
|
||||
public MachineSshModel(String id) {
|
||||
setId(id);
|
||||
|
@ -39,6 +39,7 @@ import cn.hutool.cron.task.Task;
|
||||
import cn.hutool.db.Entity;
|
||||
import cn.hutool.extra.ssh.JschUtil;
|
||||
import cn.keepbx.jpom.Type;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.jcraft.jsch.Session;
|
||||
import lombok.Lombok;
|
||||
@ -295,6 +296,17 @@ public class MachineSshServer extends BaseDbService<MachineSshModel> implements
|
||||
}
|
||||
update.setJavaVersion(this.getFirstValue(map, "java version"));
|
||||
update.setJpomAgentPid(Convert.toInt(this.getFirstValue(map, "jpom agent pid")));
|
||||
//
|
||||
String dockerPath = this.getFirstValue(map, "docker path");
|
||||
String dockerVersion = this.getFirstValue(map, "docker version");
|
||||
if (StrUtil.isAllNotEmpty(dockerVersion, dockerPath)) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("version", dockerVersion);
|
||||
jsonObject.put("path", dockerPath);
|
||||
update.setDockerInfo(jsonObject.toString());
|
||||
} else {
|
||||
update.setDockerInfo(StrUtil.EMPTY);
|
||||
}
|
||||
this.updateById(update);
|
||||
}
|
||||
|
||||
|
@ -72,3 +72,9 @@ df -k | awk 'NR>1' | awk '/^\/dev/{print "disk info:"$1":"$2":"$3}'
|
||||
jpom_agent_pid=$(getPid "${JPOM_AGENT_PID_TAG}")
|
||||
echo "jpom agent pid:$jpom_agent_pid"
|
||||
echo "java version:$(command -v java)"
|
||||
|
||||
docker_path=$(command -v docker)
|
||||
if [[ $docker_path != "" ]]; then
|
||||
echo "docker path:$docker_path"
|
||||
echo "docker version:$(docker -v)"
|
||||
fi
|
||||
|
@ -57,3 +57,4 @@ ADD,PROJECT_INFO,workspaceName,String,50,,工作空间名称,false
|
||||
ADD,SCRIPT_EXECUTE_LOG,workspaceName,String,50,,工作空间名称,false
|
||||
ALTER,REPOSITORY,password,String,255,,登录密码,false
|
||||
ADD,WORKSPACE,group,String,50,,分组,false
|
||||
ADD,MACHINE_SSH_INFO,dockerInfo,String,255,,服务器中的 docker 信息,false
|
||||
|
|
@ -64,6 +64,7 @@ export default {
|
||||
idInc: 0,
|
||||
visibleStartIndex: -1,
|
||||
itemHeight: 24,
|
||||
inited: false,
|
||||
uniqueId: `component_${Math.random().toString(36).substring(2, 15)}`,
|
||||
};
|
||||
},
|
||||
@ -74,10 +75,28 @@ export default {
|
||||
},
|
||||
showList() {
|
||||
const element = document.querySelector(`#${this.uniqueId}`);
|
||||
|
||||
let result = [...this.dataArray];
|
||||
let result;
|
||||
if (this.inited) {
|
||||
result = this.dataArray.length
|
||||
? [...this.dataArray]
|
||||
: [
|
||||
{
|
||||
text: this.defText,
|
||||
id: "0-def",
|
||||
},
|
||||
];
|
||||
} else {
|
||||
// 还没有 dom 对象
|
||||
result = [
|
||||
{
|
||||
text: "loading..................",
|
||||
id: "0-def",
|
||||
},
|
||||
];
|
||||
}
|
||||
let warp = false;
|
||||
if (element) {
|
||||
// 填充空白,避免无内容 页面背景太低
|
||||
const min = Math.ceil(element.clientHeight / this.itemHeight);
|
||||
const le = min - result.length;
|
||||
for (let i = 0; i < le; i++) {
|
||||
@ -89,6 +108,7 @@ export default {
|
||||
}
|
||||
}
|
||||
if (!warp) {
|
||||
// 最后填充一行空白,避免无法看到滚动条
|
||||
result = result.concat([
|
||||
{
|
||||
id: "system-warp-end:1",
|
||||
@ -105,7 +125,15 @@ export default {
|
||||
// set() {},
|
||||
// },
|
||||
},
|
||||
mounted() {},
|
||||
mounted() {
|
||||
const timer = setInterval(() => {
|
||||
const element = document.querySelector(`#${this.uniqueId}`);
|
||||
if (element) {
|
||||
this.inited = true;
|
||||
clearInterval(timer);
|
||||
}
|
||||
}, 200);
|
||||
},
|
||||
methods: {
|
||||
scrollToBottom() {
|
||||
const element = document.querySelector(`#${this.uniqueId}`);
|
||||
@ -122,9 +150,9 @@ export default {
|
||||
return setTimeout(cb, 10);
|
||||
};
|
||||
}
|
||||
var scrollTop = element.scrollTop;
|
||||
var step = function () {
|
||||
var distance = position - scrollTop;
|
||||
let scrollTop = element.scrollTop;
|
||||
const step = function () {
|
||||
const distance = position - scrollTop;
|
||||
scrollTop = scrollTop + distance / 5;
|
||||
if (Math.abs(distance) < 1) {
|
||||
element.scrollTop = position;
|
||||
|
@ -45,6 +45,11 @@ export default {
|
||||
this.initSocket();
|
||||
}, 200);
|
||||
});
|
||||
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
||||
window.onbeforeunload = () => {
|
||||
this.socket?.close();
|
||||
this.dispose();
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.socket?.close();
|
||||
@ -129,7 +134,7 @@ export default {
|
||||
this.sendJson({ data: "resize", cols: this.cols, rows: this.rows, wp: this.wp, hp: this.hp });
|
||||
// 创建心跳,防止掉线
|
||||
this.heart = setInterval(() => {
|
||||
let op = {
|
||||
const op = {
|
||||
data: "jpom-heart",
|
||||
};
|
||||
this.sendJson(op);
|
||||
|
@ -217,23 +217,23 @@ export default {
|
||||
});
|
||||
this.activeTagKey = this.temp.cacheData.useNodeId + "," + this.temp.cacheData.useProjectId;
|
||||
// console.log(cacheData);
|
||||
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
||||
window.onbeforeunload = () => {
|
||||
this.close();
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
Object.keys(this.socketCache).forEach((item) => {
|
||||
clearInterval(this.socketCache[item].heart);
|
||||
});
|
||||
},
|
||||
destroyed() {
|
||||
Object.keys(this.socketCache).forEach((item) => {
|
||||
clearInterval(this.socketCache[item].heart);
|
||||
});
|
||||
this.close();
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
Object.keys(this.socketCache).forEach((item) => {
|
||||
clearInterval(this.socketCache[item].heart);
|
||||
this.socketCache[item].socket?.close();
|
||||
});
|
||||
},
|
||||
initWebSocket(id, url) {
|
||||
let socket;
|
||||
if (!socket || socket.readyState !== socket.OPEN || socket.readyState !== socket.CONNECTING) {
|
||||
socket = new WebSocket(url);
|
||||
}
|
||||
const socket = new WebSocket(url);
|
||||
|
||||
socket.onerror = (err) => {
|
||||
console.error(err);
|
||||
|
@ -61,6 +61,10 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.initWebSocket();
|
||||
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
||||
window.onbeforeunload = () => {
|
||||
this.close();
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.close();
|
||||
|
@ -92,14 +92,19 @@ export default {
|
||||
} else {
|
||||
this.commandParams = [];
|
||||
}
|
||||
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
||||
window.onbeforeunload = () => {
|
||||
this.close();
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.socket) {
|
||||
this.socket.close();
|
||||
}
|
||||
clearInterval(this.heart);
|
||||
this.close();
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.socket?.close();
|
||||
clearInterval(this.heart);
|
||||
},
|
||||
// 初始化
|
||||
initWebSocket() {
|
||||
this.logContext = "";
|
||||
|
@ -105,14 +105,20 @@ export default {
|
||||
mounted() {
|
||||
this.loadProject();
|
||||
this.initWebSocket();
|
||||
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
||||
window.onbeforeunload = () => {
|
||||
this.close();
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.socket) {
|
||||
this.socket.close();
|
||||
}
|
||||
clearInterval(this.heart);
|
||||
this.close();
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.socket?.close();
|
||||
|
||||
clearInterval(this.heart);
|
||||
},
|
||||
// 加载项目
|
||||
loadProject() {
|
||||
const params = {
|
||||
|
@ -67,14 +67,20 @@ export default {
|
||||
mounted() {
|
||||
// this.loadProject();
|
||||
this.initWebSocket();
|
||||
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
||||
window.onbeforeunload = () => {
|
||||
this.close();
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.socket) {
|
||||
this.socket.close();
|
||||
}
|
||||
clearInterval(this.heart);
|
||||
this.close();
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.socket?.close();
|
||||
|
||||
clearInterval(this.heart);
|
||||
},
|
||||
// 初始化
|
||||
initWebSocket() {
|
||||
//this.logContext = "";
|
||||
@ -99,7 +105,7 @@ export default {
|
||||
clearInterval(this.heart);
|
||||
};
|
||||
this.socket.onmessage = (msg) => {
|
||||
this.$refs.logView.appendLine(msg.data);
|
||||
this.$refs.logView?.appendLine(msg.data);
|
||||
|
||||
clearInterval(this.heart);
|
||||
// 创建心跳,防止掉线
|
||||
|
@ -72,8 +72,18 @@ export default {
|
||||
watch: {},
|
||||
created() {
|
||||
this.loadData();
|
||||
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
||||
window.onbeforeunload = () => {
|
||||
this.close();
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.close();
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.socket?.close();
|
||||
},
|
||||
// 加载数据
|
||||
loadData() {
|
||||
this.list = [];
|
||||
|
@ -90,14 +90,20 @@ export default {
|
||||
} else {
|
||||
this.commandParams = [];
|
||||
}
|
||||
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
||||
window.onbeforeunload = () => {
|
||||
this.close();
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.socket) {
|
||||
this.socket.close();
|
||||
}
|
||||
clearInterval(this.heart);
|
||||
this.close();
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.socket?.close();
|
||||
|
||||
clearInterval(this.heart);
|
||||
},
|
||||
// 初始化
|
||||
initWebSocket() {
|
||||
this.logContext = "";
|
||||
|
@ -60,14 +60,29 @@
|
||||
</a-popover>
|
||||
<template slot="nodeId" slot-scope="text, record">
|
||||
<div v-if="record.javaVersion">
|
||||
<a-tooltip v-if="record.jpomAgentPid > 0" placement="topLeft" :title="` ssh 中已经运行了插件端进程ID:${record.jpomAgentPid},java : ${record.javaVersion}`">
|
||||
<a-tag> {{ record.jpomAgentPid }}</a-tag>
|
||||
</a-tooltip>
|
||||
<a-popover title="java信息" v-if="record.jpomAgentPid > 0">
|
||||
<template slot="content">
|
||||
<p>插件端进程ID:{{ record.jpomAgentPid }}</p>
|
||||
<p>java版本:{{ record.javaVersion }}</p>
|
||||
</template>
|
||||
<a-tag color="green"> {{ record.jpomAgentPid }}</a-tag>
|
||||
</a-popover>
|
||||
<a-button v-else size="small" type="primary" @click="install(record)">安装节点</a-button>
|
||||
</div>
|
||||
|
||||
<a-tag color="orange" v-else>no java</a-tag>
|
||||
</template>
|
||||
<template slot="dockerInfo" slot-scope="text, record">
|
||||
<a-popover title="docker信息" v-if="record.dockerInfo">
|
||||
<template slot="content">
|
||||
<p>路径:{{ JSON.parse(record.dockerInfo).path }}</p>
|
||||
<p>版本:{{ JSON.parse(record.dockerInfo).version }}</p>
|
||||
</template>
|
||||
<a-tag color="green">存在</a-tag>
|
||||
</a-popover>
|
||||
|
||||
<a-tag v-else>不存在</a-tag>
|
||||
</template>
|
||||
<template slot="status" slot-scope="text, record">
|
||||
<a-tooltip :title="record.statusMsg">
|
||||
<a-tag :color="record.status === 1 ? 'green' : 'red'">{{ record.status === 1 ? "正常" : "无法连接" }}</a-tag>
|
||||
@ -192,8 +207,8 @@
|
||||
<a-input-number v-model="temp.timeout" :min="1" placeholder="单位秒,最小值 1 秒" style="width: 100%" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="文件后缀" prop="suffix">
|
||||
<template slot="help"
|
||||
>此配置仅对服务端管理生效, 工作空间的 ssh 配置需要单独配置(<span style="color: red">配置方式:SSH列表->操作栏中->关联按钮->对应工作空间->操作栏中->配置按钮</span>)。
|
||||
<template slot="help">
|
||||
此配置仅对服务端管理生效, 工作空间的 ssh 配置需要单独配置(<span style="color: red">配置方式:SSH列表->操作栏中->关联按钮->对应工作空间->操作栏中->配置按钮</span>)。
|
||||
</template>
|
||||
<a-input
|
||||
v-model="temp.allowEditSuffix"
|
||||
@ -413,6 +428,13 @@ export default {
|
||||
width: "80px",
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "docker",
|
||||
dataIndex: "dockerInfo",
|
||||
scopedSlots: { customRender: "dockerInfo" },
|
||||
width: "80px",
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
dataIndex: "createTimeMillis",
|
||||
|
@ -72,11 +72,13 @@ export default {
|
||||
this.introGuide();
|
||||
}, 500);
|
||||
});
|
||||
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
||||
window.onbeforeunload = () => {
|
||||
this.socket?.close();
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.socket) {
|
||||
this.socket.close();
|
||||
}
|
||||
this.socket?.close();
|
||||
},
|
||||
methods: {
|
||||
// 页面引导
|
||||
@ -143,7 +145,7 @@ export default {
|
||||
fileName: node.dataRef.path,
|
||||
};
|
||||
this.temp = node.dataRef;
|
||||
this.$refs.logView.clearLogCache();
|
||||
this.$refs.logView?.clearLogCache();
|
||||
|
||||
this.socket?.close();
|
||||
|
||||
@ -154,7 +156,7 @@ export default {
|
||||
};
|
||||
this.socket.onmessage = (msg) => {
|
||||
// this.logContext += `${msg.data}\r\n`;
|
||||
this.$refs.logView.appendLine(msg.data);
|
||||
this.$refs.logView?.appendLine(msg.data);
|
||||
};
|
||||
this.socket.onerror = (err) => {
|
||||
console.error(err);
|
||||
|
@ -142,13 +142,20 @@ export default {
|
||||
this.getNodeList();
|
||||
this.loadGroupList();
|
||||
this.checkAgentFileVersion();
|
||||
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
|
||||
window.onbeforeunload = () => {
|
||||
this.close();
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.socket && this.socket.close();
|
||||
clearInterval(this.heart);
|
||||
this.socket = null;
|
||||
this.close();
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.socket?.close();
|
||||
clearInterval(this.heart);
|
||||
this.socket = null;
|
||||
},
|
||||
formatDuration,
|
||||
updateList() {
|
||||
this.list = this.list.map((item) => {
|
||||
|
Loading…
Reference in New Issue
Block a user