mirror of
https://gitee.com/dromara/mayfly-go
synced 2026-01-01 20:26:39 +08:00
feat: 新增linux进程操作
This commit is contained in:
@@ -51,8 +51,8 @@
|
|||||||
|
|
||||||
<el-row type="flex" justify="center">
|
<el-row type="flex" justify="center">
|
||||||
<slot name="btns" :submitDisabled="submitDisabled" :data="form" :submit="submit">
|
<slot name="btns" :submitDisabled="submitDisabled" :data="form" :submit="submit">
|
||||||
<el-button @click="reset" size="mini">重 置</el-button>
|
<el-button @click="reset" size="small">重 置</el-button>
|
||||||
<el-button type="primary" @click="submit" size="mini">保 存</el-button>
|
<el-button type="primary" @click="submit" size="small">保 存</el-button>
|
||||||
</slot>
|
</slot>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
<dynamic-form ref="df" :form-info="formInfo" :form-data="formData" @submitSuccess="submitSuccess">
|
<dynamic-form ref="df" :form-info="formInfo" :form-data="formData" @submitSuccess="submitSuccess">
|
||||||
<template #btns="props">
|
<template #btns="props">
|
||||||
<slot name="btns">
|
<slot name="btns">
|
||||||
<el-button :disabled="props.submitDisabled" type="primary" @click="props.submit" size="mini">保 存</el-button>
|
<el-button :disabled="props.submitDisabled" type="primary" @click="props.submit" size="small">保 存</el-button>
|
||||||
<el-button :disabled="props.submitDisabled" @click="close()" size="mini">取 消</el-button>
|
<el-button :disabled="props.submitDisabled" @click="close()" size="small">取 消</el-button>
|
||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
</dynamic-form>
|
</dynamic-form>
|
||||||
|
|||||||
@@ -152,7 +152,7 @@
|
|||||||
:min="0"
|
:min="0"
|
||||||
:max="9999"
|
:max="9999"
|
||||||
@change="setLocalThemeConfig"
|
@change="setLocalThemeConfig"
|
||||||
size="mini"
|
size="small"
|
||||||
style="width: 90px"
|
style="width: 90px"
|
||||||
>
|
>
|
||||||
</el-input-number>
|
</el-input-number>
|
||||||
@@ -236,7 +236,7 @@
|
|||||||
<div class="layout-breadcrumb-seting-bar-flex-value">
|
<div class="layout-breadcrumb-seting-bar-flex-value">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="getThemeConfig.wartermarkText"
|
v-model="getThemeConfig.wartermarkText"
|
||||||
size="mini"
|
size="small"
|
||||||
style="width: 90px"
|
style="width: 90px"
|
||||||
@input="onWartermarkTextInput($event)"
|
@input="onWartermarkTextInput($event)"
|
||||||
></el-input>
|
></el-input>
|
||||||
@@ -251,7 +251,7 @@
|
|||||||
<el-select
|
<el-select
|
||||||
v-model="getThemeConfig.tagsStyle"
|
v-model="getThemeConfig.tagsStyle"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
size="mini"
|
size="small"
|
||||||
style="width: 90px"
|
style="width: 90px"
|
||||||
@change="setLocalThemeConfig"
|
@change="setLocalThemeConfig"
|
||||||
>
|
>
|
||||||
@@ -268,7 +268,7 @@
|
|||||||
<el-select
|
<el-select
|
||||||
v-model="getThemeConfig.animation"
|
v-model="getThemeConfig.animation"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
size="mini"
|
size="small"
|
||||||
style="width: 90px"
|
style="width: 90px"
|
||||||
@change="setLocalThemeConfig"
|
@change="setLocalThemeConfig"
|
||||||
>
|
>
|
||||||
@@ -284,7 +284,7 @@
|
|||||||
<el-select
|
<el-select
|
||||||
v-model="getThemeConfig.columnsAsideStyle"
|
v-model="getThemeConfig.columnsAsideStyle"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
size="mini"
|
size="small"
|
||||||
style="width: 90px"
|
style="width: 90px"
|
||||||
@change="setLocalThemeConfig"
|
@change="setLocalThemeConfig"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -171,7 +171,6 @@ import { codemirror } from '@/components/codemirror';
|
|||||||
import { getSession } from '@/common/utils/storage';
|
import { getSession } from '@/common/utils/storage';
|
||||||
import enums from './enums';
|
import enums from './enums';
|
||||||
import config from '@/common/config';
|
import config from '@/common/config';
|
||||||
import SvgIcon from '@/components/svgIcon/index.vue';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'FileManage',
|
name: 'FileManage',
|
||||||
|
|||||||
@@ -32,8 +32,8 @@
|
|||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button type="primary" :loading="btnLoading" @click="btnOk" size="mini">确 定</el-button>
|
<el-button type="primary" :loading="btnLoading" @click="btnOk">确 定</el-button>
|
||||||
<el-button @click="cancel()" size="mini">取 消</el-button>
|
<el-button @click="cancel()">取 消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|||||||
@@ -53,17 +53,12 @@
|
|||||||
{{ $filters.dateFormat(scope.row.createTime) }}
|
{{ $filters.dateFormat(scope.row.createTime) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="creator" label="创建者" min-width="55"></el-table-column>
|
<el-table-column prop="creator" label="创建者" min-width="60"></el-table-column>
|
||||||
<!-- <el-table-column prop="updateTime" label="更新时间" min-width="160">
|
|
||||||
<template #default="scope">
|
|
||||||
{{ $filters.dateFormat(scope.row.updateTime) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="modifier" label="修改者" :min-width="55"></el-table-column> -->
|
|
||||||
<el-table-column label="操作" min-width="260" fixed="right">
|
<el-table-column label="操作" min-width="260" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button type="success" @click="serviceManager(scope.row)" plain size="small">脚本</el-button>
|
<el-button type="success" @click="serviceManager(scope.row)" plain size="small">脚本</el-button>
|
||||||
<el-button v-auth="'machine:terminal'" type="primary" @click="showTerminal(scope.row)" plain size="small">终端</el-button>
|
<el-button v-auth="'machine:terminal'" type="primary" @click="showTerminal(scope.row)" plain size="small">终端</el-button>
|
||||||
|
<el-button @click="showProcess(scope.row)" plain size="small">进程</el-button>
|
||||||
<el-button :disabled="!scope.row.hasCli" type="danger" @click="closeCli(scope.row)" plain size="small">关闭连接</el-button>
|
<el-button :disabled="!scope.row.hasCli" type="danger" @click="closeCli(scope.row)" plain size="small">关闭连接</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -91,6 +86,8 @@
|
|||||||
<monitor ref="monitorDialogRef" :machineId="monitorDialog.machineId" />
|
<monitor ref="monitorDialogRef" :machineId="monitorDialog.machineId" />
|
||||||
</el-dialog> -->
|
</el-dialog> -->
|
||||||
|
|
||||||
|
<process-list v-model:visible="processDialog.visible" v-model:machineId="processDialog.machineId" />
|
||||||
|
|
||||||
<service-manage :title="serviceDialog.title" v-model:visible="serviceDialog.visible" v-model:machineId="serviceDialog.machineId" />
|
<service-manage :title="serviceDialog.title" v-model:visible="serviceDialog.visible" v-model:machineId="serviceDialog.machineId" />
|
||||||
|
|
||||||
<file-manage :title="fileDialog.title" v-model:visible="fileDialog.visible" v-model:machineId="fileDialog.machineId" />
|
<file-manage :title="fileDialog.title" v-model:visible="fileDialog.visible" v-model:machineId="fileDialog.machineId" />
|
||||||
@@ -107,11 +104,13 @@ import { projectApi } from '../project/api.ts';
|
|||||||
import ServiceManage from './ServiceManage.vue';
|
import ServiceManage from './ServiceManage.vue';
|
||||||
import FileManage from './FileManage.vue';
|
import FileManage from './FileManage.vue';
|
||||||
import MachineEdit from './MachineEdit.vue';
|
import MachineEdit from './MachineEdit.vue';
|
||||||
|
import ProcessList from './ProcessList.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'MachineList',
|
name: 'MachineList',
|
||||||
components: {
|
components: {
|
||||||
ServiceManage,
|
ServiceManage,
|
||||||
|
ProcessList,
|
||||||
FileManage,
|
FileManage,
|
||||||
MachineEdit,
|
MachineEdit,
|
||||||
},
|
},
|
||||||
@@ -142,6 +141,10 @@ export default defineComponent({
|
|||||||
machineId: 0,
|
machineId: 0,
|
||||||
title: '',
|
title: '',
|
||||||
},
|
},
|
||||||
|
processDialog: {
|
||||||
|
visible: false,
|
||||||
|
machineId: 0,
|
||||||
|
},
|
||||||
fileDialog: {
|
fileDialog: {
|
||||||
visible: false,
|
visible: false,
|
||||||
machineId: 0,
|
machineId: 0,
|
||||||
@@ -256,6 +259,11 @@ export default defineComponent({
|
|||||||
state.data = res;
|
state.data = res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showProcess = (row: any) => {
|
||||||
|
state.processDialog.machineId = row.id;
|
||||||
|
state.processDialog.visible = true;
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
choose,
|
choose,
|
||||||
@@ -266,6 +274,7 @@ export default defineComponent({
|
|||||||
deleteMachine,
|
deleteMachine,
|
||||||
closeCli,
|
closeCli,
|
||||||
serviceManager,
|
serviceManager,
|
||||||
|
showProcess,
|
||||||
submitSuccess,
|
submitSuccess,
|
||||||
fileManage,
|
fileManage,
|
||||||
search,
|
search,
|
||||||
|
|||||||
203
mayfly_go_web/src/views/ops/machine/ProcessList.vue
Normal file
203
mayfly_go_web/src/views/ops/machine/ProcessList.vue
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
<template>
|
||||||
|
<div class="file-manage">
|
||||||
|
<el-dialog title="进程信息" v-model="dialogVisible" :destroy-on-close="true" :show-close="true" :before-close="handleClose" width="65%">
|
||||||
|
<div class="toolbar">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-input size="small" placeholder="进程名" v-model="params.name" plain clearable></el-input>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4" class="ml5">
|
||||||
|
<el-select @change="getProcess" size="small" v-model="params.sortType" placeholder="请选择排序类型">
|
||||||
|
<el-option key="cpu" label="cpu降序" value="1"> </el-option>
|
||||||
|
<el-option key="cpu" label="mem降序" value="2"> </el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4" class="ml5">
|
||||||
|
<el-select @change="getProcess" size="small" v-model="params.count" placeholder="请选择进程个数">
|
||||||
|
<el-option key="10" label="10" value="10"> </el-option>
|
||||||
|
<el-option key="15" label="15" value="15"> </el-option>
|
||||||
|
<el-option key="20" label="20" value="20"> </el-option>
|
||||||
|
<el-option key="25" label="25" value="25"> </el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-button class="ml5" @click="getProcess" type="primary" icon="tickets" size="small" plain>刷新</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="processList" size="small" style="width: 100%" empty-text="获取进程中...">
|
||||||
|
<el-table-column prop="user" label="USER" :min-width="50"> </el-table-column>
|
||||||
|
<el-table-column prop="pid" label="PID" :min-width="50" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="cpu" label="%CPU" :min-width="40"> </el-table-column>
|
||||||
|
<el-table-column prop="mem" label="%MEM" :min-width="42"> </el-table-column>
|
||||||
|
<el-table-column prop="vsz" label="vsz" :min-width="55">
|
||||||
|
<template #header>
|
||||||
|
VSZ
|
||||||
|
<el-tooltip class="box-item" effect="dark" content="虚拟内存" placement="top">
|
||||||
|
<el-icon><question-filled /></el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="rss" :min-width="52">
|
||||||
|
<template #header>
|
||||||
|
RSS
|
||||||
|
<el-tooltip class="box-item" effect="dark" content="固定内存" placement="top">
|
||||||
|
<el-icon><question-filled /></el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="stat" :min-width="50">
|
||||||
|
<template #header>
|
||||||
|
STAT
|
||||||
|
<el-tooltip class="box-item" effect="dark" content="进程状态" placement="top">
|
||||||
|
<el-icon><question-filled /></el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="start" :min-width="50">
|
||||||
|
<template #header>
|
||||||
|
START
|
||||||
|
<el-tooltip class="box-item" effect="dark" content="启动时间" placement="top">
|
||||||
|
<el-icon><question-filled /></el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="time" :min-width="50">
|
||||||
|
<template #header>
|
||||||
|
TIME
|
||||||
|
<el-tooltip class="box-item" effect="dark" content="该进程实际使用CPU运作的时间" placement="top">
|
||||||
|
<el-icon><question-filled /></el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="command" label="command" :min-width="120" show-overflow-tooltip> </el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-popconfirm title="确定终止该进程?" @confirm="confirmKillProcess(scope.row.pid)">
|
||||||
|
<template #reference>
|
||||||
|
<el-button v-auth="'machine:killprocess'" type="danger" icon="delete" size="small" plain>终止</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
<!-- <el-button @click="addFiles(scope.row)" type="danger" icon="delete" size="small" plain>终止</el-button> -->
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { ref, toRefs, reactive, watch, defineComponent } from 'vue';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import { machineApi } from './api';
|
||||||
|
import enums from './enums';
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'ProcessList',
|
||||||
|
components: {},
|
||||||
|
props: {
|
||||||
|
visible: { type: Boolean },
|
||||||
|
machineId: { type: Number },
|
||||||
|
title: { type: String },
|
||||||
|
},
|
||||||
|
setup(props: any, context) {
|
||||||
|
const state = reactive({
|
||||||
|
dialogVisible: false,
|
||||||
|
params: {
|
||||||
|
name: '',
|
||||||
|
sortType: '1',
|
||||||
|
count: '10',
|
||||||
|
id: 0,
|
||||||
|
},
|
||||||
|
processList: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(props, (newValue) => {
|
||||||
|
if (props.machineId) {
|
||||||
|
state.params.id = props.machineId;
|
||||||
|
getProcess();
|
||||||
|
}
|
||||||
|
state.dialogVisible = newValue.visible;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getProcess = async () => {
|
||||||
|
const res = await machineApi.process.request(state.params);
|
||||||
|
// 解析字符串
|
||||||
|
// USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
|
||||||
|
// root 1 0.0 0.0 125632 3352 ? Ss 2019 154:04 /usr/lib/systemd/systemd --system --deserialize 22
|
||||||
|
const psStrings = res.split('\n');
|
||||||
|
const ps = [];
|
||||||
|
for (let i = 1; i < psStrings.length; i++) {
|
||||||
|
const psStr = psStrings[i];
|
||||||
|
const process = psStr.split(/\s+/);
|
||||||
|
if (process.length < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let command = process[10];
|
||||||
|
// 搜索进程时由于使用grep命令,可能会多个bash或grep进程
|
||||||
|
if (state.params.name) {
|
||||||
|
if (command == 'bash' || command == 'grep') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取command,由于command中也有可能存在空格被切割,故重新拼接
|
||||||
|
for (let j = 10; j < process.length - 1; j++) {
|
||||||
|
command += ' ' + process[j + 1];
|
||||||
|
}
|
||||||
|
ps.push({
|
||||||
|
user: process[0],
|
||||||
|
pid: process[1],
|
||||||
|
cpu: process[2],
|
||||||
|
mem: process[3],
|
||||||
|
vsz: kb2Mb(process[4]),
|
||||||
|
rss: kb2Mb(process[5]),
|
||||||
|
stat: process[7],
|
||||||
|
start: process[8],
|
||||||
|
time: process[9],
|
||||||
|
command,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
state.processList = ps as any;
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirmKillProcess = async (pid: any) => {
|
||||||
|
await machineApi.killProcess.request({
|
||||||
|
pid,
|
||||||
|
id: state.params.id,
|
||||||
|
});
|
||||||
|
ElMessage.success('kill success');
|
||||||
|
state.params.name = '';
|
||||||
|
getProcess();
|
||||||
|
};
|
||||||
|
|
||||||
|
const kb2Mb = (kb: string) => {
|
||||||
|
return (parseInt(kb) / 1024).toFixed(2) + 'M';
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭取消按钮触发的事件
|
||||||
|
*/
|
||||||
|
const handleClose = () => {
|
||||||
|
context.emit('update:visible', false);
|
||||||
|
context.emit('update:machineId', null);
|
||||||
|
context.emit('cancel');
|
||||||
|
state.params = {
|
||||||
|
name: '',
|
||||||
|
sortType: '1',
|
||||||
|
count: '10',
|
||||||
|
id: 0,
|
||||||
|
};
|
||||||
|
state.processList = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...toRefs(state),
|
||||||
|
getProcess,
|
||||||
|
confirmKillProcess,
|
||||||
|
enums,
|
||||||
|
handleClose,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -40,11 +40,11 @@
|
|||||||
type="primary"
|
type="primary"
|
||||||
:loading="btnLoading"
|
:loading="btnLoading"
|
||||||
@click="btnOk"
|
@click="btnOk"
|
||||||
size="mini"
|
size="small"
|
||||||
:disabled="submitDisabled"
|
:disabled="submitDisabled"
|
||||||
>保 存</el-button
|
>保 存</el-button
|
||||||
>
|
>
|
||||||
<el-button @click="cancel()" :disabled="submitDisabled" size="mini">关 闭</el-button>
|
<el-button @click="cancel()" :disabled="submitDisabled" size="small">关 闭</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ export const machineApi = {
|
|||||||
list: Api.create("/machines", 'get'),
|
list: Api.create("/machines", 'get'),
|
||||||
info: Api.create("/machines/{id}/sysinfo", 'get'),
|
info: Api.create("/machines/{id}/sysinfo", 'get'),
|
||||||
stats: Api.create("/machines/{id}/stats", 'get'),
|
stats: Api.create("/machines/{id}/stats", 'get'),
|
||||||
|
process: Api.create("/machines/{id}/process", 'get'),
|
||||||
|
// 终止进程
|
||||||
|
killProcess: Api.create("/machines/{id}/process", 'delete'),
|
||||||
closeCli: Api.create("/machines/{id}/close-cli", 'delete'),
|
closeCli: Api.create("/machines/{id}/close-cli", 'delete'),
|
||||||
// 保存按钮
|
// 保存按钮
|
||||||
saveMachine: Api.create("/machines", 'post'),
|
saveMachine: Api.create("/machines", 'post'),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"mayfly-go/base/biz"
|
"mayfly-go/base/biz"
|
||||||
"mayfly-go/base/ctx"
|
"mayfly-go/base/ctx"
|
||||||
"mayfly-go/base/ginx"
|
"mayfly-go/base/ginx"
|
||||||
@@ -72,6 +73,41 @@ func (m *Machine) CloseCli(rc *ctx.ReqCtx) {
|
|||||||
machine.DeleteCli(GetMachineId(rc.GinCtx))
|
machine.DeleteCli(GetMachineId(rc.GinCtx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取进程列表信息
|
||||||
|
func (m *Machine) GetProcess(rc *ctx.ReqCtx) {
|
||||||
|
g := rc.GinCtx
|
||||||
|
cmd := "ps -aux "
|
||||||
|
sortType := g.Query("sortType")
|
||||||
|
if sortType == "2" {
|
||||||
|
cmd += "--sort -pmem "
|
||||||
|
} else {
|
||||||
|
cmd += "--sort -pcpu "
|
||||||
|
}
|
||||||
|
|
||||||
|
pname := g.Query("name")
|
||||||
|
if pname != "" {
|
||||||
|
cmd += fmt.Sprintf("| grep %s ", pname)
|
||||||
|
}
|
||||||
|
|
||||||
|
count := g.Query("count")
|
||||||
|
if count == "" {
|
||||||
|
count = "10"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd += "| head -n " + count
|
||||||
|
res, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx)).Run(cmd)
|
||||||
|
biz.ErrIsNilAppendErr(err, "获取进程信息失败: %s")
|
||||||
|
rc.ResData = res
|
||||||
|
}
|
||||||
|
|
||||||
|
// 终止进程
|
||||||
|
func (m *Machine) KillProcess(rc *ctx.ReqCtx) {
|
||||||
|
pid := rc.GinCtx.Query("pid")
|
||||||
|
biz.NotEmpty(pid, "进程id不能为空")
|
||||||
|
_, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx)).Run("kill -9 " + pid)
|
||||||
|
biz.ErrIsNilAppendErr(err, "终止进程失败: %s")
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Machine) WsSSH(g *gin.Context) {
|
func (m *Machine) WsSSH(g *gin.Context) {
|
||||||
wsConn, err := ws.Upgrader.Upgrade(g.Writer, g.Request, nil)
|
wsConn, err := ws.Upgrader.Upgrade(g.Writer, g.Request, nil)
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|||||||
@@ -20,6 +20,20 @@ func InitMachineRouter(router *gin.RouterGroup) {
|
|||||||
ctx.NewReqCtxWithGin(c).Handle(m.MachineStats)
|
ctx.NewReqCtxWithGin(c).Handle(m.MachineStats)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
machines.GET(":machineId/process", func(c *gin.Context) {
|
||||||
|
ctx.NewReqCtxWithGin(c).Handle(m.GetProcess)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 终止进程
|
||||||
|
killProcessL := ctx.NewLogInfo("终止进程")
|
||||||
|
killProcessP := ctx.NewPermission("machine:killprocess")
|
||||||
|
machines.DELETE(":machineId/process", func(c *gin.Context) {
|
||||||
|
ctx.NewReqCtxWithGin(c).
|
||||||
|
WithLog(killProcessL).
|
||||||
|
WithRequiredPermission(killProcessP).
|
||||||
|
Handle(m.KillProcess)
|
||||||
|
})
|
||||||
|
|
||||||
saveMachine := ctx.NewLogInfo("保存机器信息")
|
saveMachine := ctx.NewLogInfo("保存机器信息")
|
||||||
machines.POST("", func(c *gin.Context) {
|
machines.POST("", func(c *gin.Context) {
|
||||||
ctx.NewReqCtxWithGin(c).
|
ctx.NewReqCtxWithGin(c).
|
||||||
|
|||||||
Reference in New Issue
Block a user