1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 00:09:16 +08:00

feat: Supervisor 增加修改配置功能 (#1818)

This commit is contained in:
zhengkunwang 2023-08-03 15:23:32 +08:00 committed by GitHub
parent b0320a4ebc
commit 0f6e14d2f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 181 additions and 42 deletions

1
.gitignore vendored
View File

@ -34,3 +34,4 @@ quick_start.sh
cmd/server/web/.DS_Store
cmd/server/.DS_Store
cmd/server/fileList.txt
.fileList.txt

View File

@ -163,12 +163,29 @@ func (h *HostToolService) CreateToolConfig(req request.HostToolCreate) error {
if err = cfg.SaveTo(req.ConfigPath); err != nil {
return err
}
if err = settingRepo.Create(constant.SupervisorConfigPath, req.ConfigPath); err != nil {
return err
serviceNameSet, _ := settingRepo.Get(settingRepo.WithByKey(constant.SupervisorServiceName))
if serviceNameSet.ID != 0 {
if err = settingRepo.Update(constant.SupervisorServiceName, req.ServiceName); err != nil {
return err
}
} else {
if err = settingRepo.Create(constant.SupervisorServiceName, req.ServiceName); err != nil {
return err
}
}
if err = settingRepo.Create(constant.SupervisorServiceName, req.ServiceName); err != nil {
return err
configPathSet, _ := settingRepo.Get(settingRepo.WithByKey(constant.SupervisorConfigPath))
if configPathSet.ID != 0 {
if err = settingRepo.Update(constant.SupervisorConfigPath, req.ConfigPath); err != nil {
return err
}
} else {
if err = settingRepo.Create(constant.SupervisorConfigPath, req.ConfigPath); err != nil {
return err
}
}
go func() {
if err = systemctl.Restart(req.ServiceName); err != nil {
global.LOG.Errorf("[init] restart %s failed err %s", req.ServiceName, err.Error())

View File

@ -1672,6 +1672,8 @@ const message = {
uptime: 'running time',
notStartWarn: 'Supervisor is not started, please start it first',
serviceName: 'Service name',
initHelper:
'The initialization process will modify the configuration file, causing all existing processes to stop, please confirm the risk in advance',
},
},
};

View File

@ -1588,6 +1588,7 @@ const message = {
uptime: '運行時長',
notStartWarn: 'Supervisor 未啟動請先啟動',
serviceName: '服務名稱',
initHelper: '尚未初始化 Supervisor 請先初始化',
},
},
};

View File

@ -1590,6 +1590,7 @@ const message = {
uptime: '运行时长',
notStartWarn: '当前未开启 Supervisor 请先启动',
serviceName: '服务名称',
initHelper: '尚未初始化 Supervisor 请先初始化',
},
},
};

View File

@ -0,0 +1,79 @@
<template>
<el-row v-loading="loading">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" :offset="1">
<el-form ref="initForm" label-position="top" :model="data" label-width="100px" :rules="rules">
<el-form-item :label="$t('tool.supervisor.primaryConfig')" prop="configPath">
<el-input v-model.trim="data.configPath"></el-input>
</el-form-item>
<el-form-item :label="$t('tool.supervisor.serviceName')" prop="serviceName">
<el-input v-model.trim="data.serviceName"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit(initForm)" :disabled="loading">
{{ $t('commons.button.confirm') }}
</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</template>
<script lang="ts" setup>
import { HostTool } from '@/api/interface/host-tool';
import { GetSupervisorStatus, InitSupervisor } from '@/api/modules/host-tool';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
import { FormInstance } from 'element-plus';
import { onMounted, ref } from 'vue';
const loading = ref(false);
const initForm = ref<FormInstance>();
const rules = ref({
configPath: [Rules.requiredInput],
serviceName: [Rules.requiredInput],
});
const data = ref({
isExist: false,
version: '',
status: 'running',
init: false,
configPath: '',
ctlExist: false,
serviceName: '',
});
const getStatus = async () => {
try {
loading.value = true;
const res = await GetSupervisorStatus();
data.value = res.data.config as HostTool.Supersivor;
} catch (error) {}
loading.value = false;
};
const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid) => {
if (!valid) {
return;
}
loading.value = true;
InitSupervisor({
type: 'supervisord',
configPath: data.value.configPath,
serviceName: data.value.serviceName,
})
.then(() => {
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
})
.finally(() => {
loading.value = false;
});
});
};
onMounted(() => {
getStatus();
});
</script>

View File

@ -7,10 +7,14 @@
<el-button type="primary" :plain="activeName !== '2'" @click="changeTab('2')">
{{ $t('website.log') }}
</el-button>
<el-button type="primary" :plain="activeName !== '3'" @click="changeTab('3')">
{{ $t('website.basic') }}
</el-button>
</template>
<template #main>
<Source v-if="activeName === '1'"></Source>
<Log v-if="activeName === '2'"></Log>
<Basic v-if="activeName === '3'"></Basic>
</template>
</LayoutContent>
</template>
@ -19,6 +23,7 @@
import { ref } from 'vue';
import Source from './source/index.vue';
import Log from './log/index.vue';
import Basic from './basic/index.vue';
const activeName = ref('1');

View File

@ -1,7 +1,7 @@
<template>
<div>
<ToolRouter />
<el-card v-if="!isRunningSuperVisor && maskShow" class="mask-prompt">
<el-card v-if="showStopped" class="mask-prompt">
<span>{{ $t('tool.supervisor.notStartWarn') }}</span>
</el-card>
<LayoutContent :title="$t('tool.supervisor.list')" v-loading="loading">
@ -9,18 +9,17 @@
<SuperVisorStatus
@setting="setting"
v-model:loading="loading"
@is-exist="isExist"
@is-running="isRunning"
@get-status="getStatus"
v-model:mask-show="maskShow"
/>
</template>
<template v-if="isExistSuperVisor && !setSuperVisor" #toolbar>
<template v-if="showTable" #toolbar>
<el-button type="primary" @click="openCreate">
{{ $t('commons.button.create') + $t('tool.supervisor.list') }}
</el-button>
</template>
<template #main v-if="isExistSuperVisor && !setSuperVisor">
<ComplexTable :data="data" :class="{ mask: !isRunningSuperVisor }">
<template #main v-if="showTable">
<ComplexTable :data="data" :class="{ mask: !supervisorStatus.isRunning }">
<el-table-column :label="$t('commons.table.name')" fix prop="name"></el-table-column>
<el-table-column :label="$t('tool.supervisor.command')" prop="command"></el-table-column>
<el-table-column :label="$t('tool.supervisor.dir')" prop="dir"></el-table-column>
@ -86,24 +85,44 @@ const globalStore = GlobalStore();
const loading = ref(false);
const setSuperVisor = ref(false);
const isExistSuperVisor = ref(false);
const isRunningSuperVisor = ref(true);
const createRef = ref();
const fileRef = ref();
const data = ref();
const maskShow = ref(true);
const supervisorStatus = ref({
maskShow: true,
isExist: false,
isRunning: false,
init: true,
});
const setting = () => {
setSuperVisor.value = true;
};
const isExist = (isExist: boolean) => {
isExistSuperVisor.value = isExist;
const getStatus = (status: any) => {
supervisorStatus.value = status;
};
const isRunning = (running: boolean) => {
isRunningSuperVisor.value = running;
};
const showStopped = computed((): boolean => {
if (supervisorStatus.value.init || setSuperVisor.value) {
return false;
}
if (supervisorStatus.value.isExist && !supervisorStatus.value.isRunning && maskShow.value) {
return true;
}
return false;
});
const showTable = computed((): boolean => {
if (supervisorStatus.value.init || setSuperVisor.value || !supervisorStatus.value.isExist) {
return false;
}
if (supervisorStatus.value.isExist && !setSuperVisor.value) {
return true;
}
return true;
});
const openCreate = () => {
createRef.value.acceptParams();
@ -113,7 +132,6 @@ const search = async () => {
loading.value = true;
try {
const res = await GetSupervisorProcess();
console.log(res);
data.value = res.data;
} catch (error) {}
loading.value = false;

View File

@ -6,7 +6,7 @@
<el-tag effect="dark" type="success">{{ 'Supervisor' }}</el-tag>
<Status class="status-content" :key="data.status" :status="data.status"></Status>
<el-tag class="status-content">{{ $t('app.version') }}:{{ data.version }}</el-tag>
<span class="buttons">
<span class="buttons" v-if="!data.init">
<el-button type="primary" v-if="data.status != 'running'" link @click="onOperate('start')">
{{ $t('app.start') }}
</el-button>
@ -18,25 +18,30 @@
{{ $t('app.restart') }}
</el-button>
<el-divider direction="vertical" />
<el-button
type="primary"
link
:disabled="data.status !== 'running' || !data.ctlExist"
@click="setting"
>
<el-button type="primary" link @click="setting">
{{ $t('commons.button.set') }}
</el-button>
</span>
<span class="buttons" v-else>
<el-button type="primary" link @click="init">
{{ $t('commons.button.init') }}
</el-button>
</span>
</div>
</el-card>
</div>
<LayoutContent :title="$t('tool.supervisor.list')" :divider="true" v-if="!data.isExist || !data.ctlExist">
<LayoutContent
:title="$t('tool.supervisor.list')"
:divider="true"
v-if="!data.isExist || !data.ctlExist || data.init"
>
<template #main>
<div class="app-warn">
<div>
<span v-if="!data.isExist">{{ $t('tool.supervisor.notSupport') }}</span>
<span v-if="!data.ctlExist">{{ $t('tool.supervisor.notSupportCrl') }}</span>
<span @click="toDoc()">
<span v-else-if="!data.ctlExist">{{ $t('tool.supervisor.notSupportCrl') }}</span>
<span v-else-if="data.init">{{ $t('tool.supervisor.initHelper') }}</span>
<span @click="toDoc()" v-if="!data.isExist || !data.ctlExist">
<el-icon><Position /></el-icon>
{{ $t('firewall.quickJump') }}
</span>
@ -75,14 +80,18 @@ const data = ref({
serviceName: '',
});
const em = defineEmits(['setting', 'isExist', 'isRunning', 'update:loading', 'update:maskShow']);
const em = defineEmits(['setting', 'getStatus', 'update:loading', 'update:maskShow']);
const setting = () => {
em('setting', false);
em('setting', true);
};
const toDoc = async () => {
window.open('https://1panel.cn/docs/user_manual/hosts/firewall/', '_blank');
window.open('https://1panel.cn/docs/user_manual/hosts/supervisor/', '_blank');
};
const init = async () => {
initRef.value.acceptParams(data.value.configPath, data.value.serviceName);
};
const onOperate = async (operation: string) => {
@ -120,15 +129,13 @@ const getStatus = async () => {
em('update:loading', true);
const res = await GetSupervisorStatus();
data.value = res.data.config as HostTool.Supersivor;
em('isRunning', data.value.status === 'running');
if (!data.value.isExist || !data.value.ctlExist) {
em('isExist', false);
} else {
em('isExist', true);
}
if (data.value.init) {
initRef.value.acceptParams(data.value.configPath, data.value.serviceName);
}
const status = {
isExist: data.value.isExist && data.value.ctlExist,
isRunning: data.value.status === 'running',
init: data.value.init,
};
em('getStatus', status);
} catch (error) {}
em('update:loading', false);
};

View File

@ -1,7 +1,7 @@
<template>
<el-drawer :close-on-click-modal="false" v-model="open" size="30%" :show-close="false">
<el-drawer :close-on-click-modal="false" v-model="open" size="30%">
<template #header>
<span>{{ $t('commons.button.init') }}</span>
<DrawerHeader :header="$t('commons.button.init')" :back="handleClose" />
</template>
<el-row v-loading="loading">
<el-col :span="22" :offset="1">
@ -23,6 +23,9 @@
</el-row>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose()" :disabled="loading">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button type="primary" @click="submit(initForm)" :disabled="loading">
{{ $t('commons.button.confirm') }}
</el-button>
@ -59,6 +62,11 @@ const acceptParams = (primaryConfig: string, serviceName: string) => {
open.value = true;
};
const handleClose = () => {
open.value = false;
em('close', false);
};
const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid) => {