feat: 完成端口修改功能

This commit is contained in:
ssongliu 2023-02-02 15:01:37 +08:00 committed by ssongliu
parent aa4cec47d9
commit 1946eb2313
20 changed files with 129 additions and 77 deletions

View File

View File

@ -11,6 +11,7 @@ type SettingRepo struct{}
type ISettingRepo interface { type ISettingRepo interface {
GetList(opts ...DBOption) ([]model.Setting, error) GetList(opts ...DBOption) ([]model.Setting, error)
Get(opts ...DBOption) (model.Setting, error) Get(opts ...DBOption) (model.Setting, error)
Create(key, value string) error
Update(key, value string) error Update(key, value string) error
WithByKey(key string) DBOption WithByKey(key string) DBOption
} }
@ -29,6 +30,14 @@ func (u *SettingRepo) GetList(opts ...DBOption) ([]model.Setting, error) {
return settings, err return settings, err
} }
func (u *SettingRepo) Create(key, value string) error {
setting := &model.Setting{
Key: key,
Value: value,
}
return global.DB.Create(setting).Error
}
func (u *SettingRepo) Get(opts ...DBOption) (model.Setting, error) { func (u *SettingRepo) Get(opts ...DBOption) (model.Setting, error) {
var settings model.Setting var settings model.Setting
db := global.DB.Model(&model.Setting{}) db := global.DB.Model(&model.Setting{})

View File

@ -2,7 +2,6 @@ package service
import ( import (
"encoding/json" "encoding/json"
"errors"
"strconv" "strconv"
"time" "time"
@ -63,15 +62,16 @@ func (u *SettingService) Update(c *gin.Context, key, value string) error {
} }
func (u *SettingService) UpdatePort(port uint) error { func (u *SettingService) UpdatePort(port uint) error {
global.Viper.Set("system.port", port) if err := settingRepo.Update("ServerPort", strconv.Itoa(int(port))); err != nil {
if err := global.Viper.WriteConfig(); err != nil {
return err return err
} }
_ = settingRepo.Update("ServerPort", strconv.Itoa(int(port))) _ = settingRepo.Update("SystemStatus", "Restarting")
stdout, err := cmd.Exec("systemctl restart 1panel.service") go func() {
_, err := cmd.Exec("systemctl restart 1panel.service")
if err != nil { if err != nil {
return errors.New(stdout) global.LOG.Errorf("restart system port failed, err: %v")
} }
}()
return nil return nil
} }

View File

@ -75,18 +75,14 @@ func (u *UpgradeService) Upgrade(version string) error {
originalDir := fmt.Sprintf("%s/%s/original", constant.TmpDir, timeStr) originalDir := fmt.Sprintf("%s/%s/original", constant.TmpDir, timeStr)
downloadPath := fmt.Sprintf("%s/releases/%s/%s.tar.gz", global.CONF.System.AppOss, version, version) downloadPath := fmt.Sprintf("%s/releases/%s/%s.tar.gz", global.CONF.System.AppOss, version, version)
setting, err := settingRepo.Get(settingRepo.WithByKey("SystemVersion")) _ = settingRepo.Update("SystemStatus", "Upgrading")
if err != nil {
return err
}
u.changeStatus(constant.StatusWaiting, nil)
go func() { go func() {
if err := os.MkdirAll(originalDir, os.ModePerm); err != nil { if err := os.MkdirAll(originalDir, os.ModePerm); err != nil {
u.changeStatus(setting.Value, err) global.LOG.Error(err.Error())
return return
} }
if err := fileOp.DownloadFile(downloadPath, filePath); err != nil { if err := fileOp.DownloadFile(downloadPath, filePath); err != nil {
u.changeStatus(setting.Value, fmt.Errorf("download file failed, err: %v", err)) global.LOG.Errorf("download file failed, err: %v", err)
return return
} }
global.LOG.Info("download file from oss successful!") global.LOG.Info("download file from oss successful!")
@ -94,34 +90,35 @@ func (u *UpgradeService) Upgrade(version string) error {
_ = os.Remove(filePath) _ = os.Remove(filePath)
}() }()
if err := fileOp.Decompress(filePath, rootDir, files.TarGz); err != nil { if err := fileOp.Decompress(filePath, rootDir, files.TarGz); err != nil {
u.changeStatus(setting.Value, fmt.Errorf("decompress file failed, err: %v", err)) global.LOG.Errorf("decompress file failed, err: %v", err)
return return
} }
if err := u.handleBackup(fileOp, originalDir); err != nil { if err := u.handleBackup(fileOp, originalDir); err != nil {
u.changeStatus(setting.Value, fmt.Errorf("handle backup original file failed, err: %v", err)) global.LOG.Errorf("handle backup original file failed, err: %v", err)
return return
} }
global.LOG.Info("backup original data successful, now start to upgrade!") global.LOG.Info("backup original data successful, now start to upgrade!")
if err := cpBinary(rootDir+"/1panel", "/usr/local/bin/1panel"); err != nil { if err := cpBinary(rootDir+"/1panel", "/usr/local/bin/1panel"); err != nil {
u.handleRollback(fileOp, originalDir, 1) u.handleRollback(fileOp, originalDir, 1)
u.changeStatus(setting.Value, fmt.Errorf("upgrade 1panel failed, err: %v", err)) global.LOG.Errorf("upgrade 1panel failed, err: %v", err)
return return
} }
if err := cpBinary(rootDir+"/1pctl", "/usr/local/bin/1pctl"); err != nil { if err := cpBinary(rootDir+"/1pctl", "/usr/local/bin/1pctl"); err != nil {
u.handleRollback(fileOp, originalDir, 2) u.handleRollback(fileOp, originalDir, 2)
u.changeStatus(setting.Value, fmt.Errorf("upgrade 1pctl failed, err: %v", err)) global.LOG.Errorf("upgrade 1pctl failed, err: %v", err)
return return
} }
if err := cpBinary(rootDir+"/1panel.service", "/etc/systemd/system/1panel.service"); err != nil { if err := cpBinary(rootDir+"/1panel.service", "/etc/systemd/system/1panel.service"); err != nil {
u.handleRollback(fileOp, originalDir, 3) u.handleRollback(fileOp, originalDir, 3)
u.changeStatus(setting.Value, fmt.Errorf("upgrade 1panel.service failed, err: %v", err)) global.LOG.Errorf("upgrade 1panel.service failed, err: %v", err)
return return
} }
global.LOG.Info("upgrade successful!") global.LOG.Info("upgrade successful!")
u.changeStatus(version, nil) _ = settingRepo.Update("SystemStatus", "Upgrade")
_ = settingRepo.Update("SystemVersion", version)
_, _ = cmd.Exec("systemctl restart 1panel.service") _, _ = cmd.Exec("systemctl restart 1panel.service")
}() }()
return nil return nil
@ -165,12 +162,3 @@ func (u *UpgradeService) handleRollback(fileOp files.FileOp, originalDir string,
global.LOG.Errorf("rollback 1panel failed, err: %v", err) global.LOG.Errorf("rollback 1panel failed, err: %v", err)
} }
} }
func (u *UpgradeService) changeStatus(status string, err error) {
if err != nil {
global.LOG.Error(err.Error())
}
if err := settingRepo.Update("SystemVersion", status); err != nil {
global.LOG.Errorf("update system version failed, err: %v", err)
}
}

View File

@ -1,7 +1,7 @@
package configs package configs
type System struct { type System struct {
Port int `mapstructure:"port"` Port string `mapstructure:"port"`
DbFile string `mapstructure:"db_file"` DbFile string `mapstructure:"db_file"`
DbPath string `mapstructure:"db_path"` DbPath string `mapstructure:"db_path"`
LogPath string `mapstructure:"log_path"` LogPath string `mapstructure:"log_path"`

22
backend/init/hook/hook.go Normal file
View File

@ -0,0 +1,22 @@
package hook
import (
"github.com/1Panel-dev/1Panel/backend/app/repo"
"github.com/1Panel-dev/1Panel/backend/global"
)
func Init() {
settingRepo := repo.NewISettingRepo()
portSetting, err := settingRepo.Get(settingRepo.WithByKey("ServerPort"))
if err != nil {
global.LOG.Errorf("load service port from setting failed, err: %v", err)
}
global.CONF.System.Port = portSetting.Value
if _, err := settingRepo.Get(settingRepo.WithByKey("SystemStatus")); err != nil {
_ = settingRepo.Create("SystemStatus", "Free")
}
if err := settingRepo.Update("SystemStatus", "Free"); err != nil {
global.LOG.Fatalf("init service before start failed, err: %v", "Free")
}
}

View File

@ -99,7 +99,7 @@ var AddTableSetting = &gormigrate.Migration{
if err := tx.Create(&model.Setting{Key: "ExpirationDays", Value: "0"}).Error; err != nil { if err := tx.Create(&model.Setting{Key: "ExpirationDays", Value: "0"}).Error; err != nil {
return err return err
} }
if err := tx.Create(&model.Setting{Key: "ComplexityVerification", Value: "enable"}).Error; err != nil { if err := tx.Create(&model.Setting{Key: "ComplexityVerification", Value: "disable"}).Error; err != nil {
return err return err
} }
if err := tx.Create(&model.Setting{Key: "MFAStatus", Value: "disable"}).Error; err != nil { if err := tx.Create(&model.Setting{Key: "MFAStatus", Value: "disable"}).Error; err != nil {
@ -131,6 +131,9 @@ var AddTableSetting = &gormigrate.Migration{
if err := tx.Create(&model.Setting{Key: "SystemVersion", Value: "v1.0.0"}).Error; err != nil { if err := tx.Create(&model.Setting{Key: "SystemVersion", Value: "v1.0.0"}).Error; err != nil {
return err return err
} }
if err := tx.Create(&model.Setting{Key: "SystemStatus", Value: "Free"}).Error; err != nil {
return err
}
return nil return nil
}, },
} }

View File

@ -10,13 +10,13 @@ import (
func GlobalLoading() gin.HandlerFunc { func GlobalLoading() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
settingRepo := repo.NewISettingRepo() settingRepo := repo.NewISettingRepo()
upgradeSetting, err := settingRepo.Get(settingRepo.WithByKey("SystemVersion")) status, err := settingRepo.Get(settingRepo.WithByKey("SystemStatus"))
if err != nil { if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return return
} }
if upgradeSetting.Value == constant.StatusWaiting { if status.Value != "Free" {
helper.ErrorWithDetail(c, constant.CodeGlobalLoading, "Upgrading", err) helper.ErrorWithDetail(c, constant.CodeGlobalLoading, status.Value, err)
return return
} }
c.Next() c.Next()

View File

@ -15,6 +15,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/global" "github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/init/db" "github.com/1Panel-dev/1Panel/backend/init/db"
"github.com/1Panel-dev/1Panel/backend/init/hook"
"github.com/1Panel-dev/1Panel/backend/init/log" "github.com/1Panel-dev/1Panel/backend/init/log"
"github.com/1Panel-dev/1Panel/backend/init/migration" "github.com/1Panel-dev/1Panel/backend/init/migration"
"github.com/1Panel-dev/1Panel/backend/init/router" "github.com/1Panel-dev/1Panel/backend/init/router"
@ -38,11 +39,12 @@ func Start() {
gin.SetMode("debug") gin.SetMode("debug")
cron.Run() cron.Run()
business.Init() business.Init()
hook.Init()
rootRouter := router.Routers() rootRouter := router.Routers()
address := fmt.Sprintf(":%d", global.CONF.System.Port) address := fmt.Sprintf(":%s", global.CONF.System.Port)
s := initServer(address, rootRouter) s := initServer(address, rootRouter)
global.LOG.Infof("server run success on %d", global.CONF.System.Port) global.LOG.Infof("server run success on %s", global.CONF.System.Port)
if err := s.ListenAndServe(); err != nil { if err := s.ListenAndServe(); err != nil {
global.LOG.Error(err) global.LOG.Error(err)
panic(err) panic(err)

View File

@ -1,5 +1,4 @@
system: system:
port: 9999
db_file: 1Panel.db db_file: 1Panel.db
app_oss: "https://1panel.oss-cn-hangzhou.aliyuncs.com" app_oss: "https://1panel.oss-cn-hangzhou.aliyuncs.com"

View File

@ -29,8 +29,6 @@ declare module 'vue' {
ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
ElCol: typeof import('element-plus/es')['ElCol'] ElCol: typeof import('element-plus/es')['ElCol']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElContainer: typeof import('element-plus/es')['ElContainer'] ElContainer: typeof import('element-plus/es')['ElContainer']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] ElDatePicker: typeof import('element-plus/es')['ElDatePicker']

View File

@ -63,6 +63,7 @@ export default {
}, },
loadingText: { loadingText: {
Upgrading: 'System upgrade, please wait...', Upgrading: 'System upgrade, please wait...',
Restarting: 'System restart, please wait...',
}, },
msg: { msg: {
delete: 'This operation cannot be rolled back. Do you want to continue', delete: 'This operation cannot be rolled back. Do you want to continue',

View File

@ -66,6 +66,7 @@ export default {
}, },
loadingText: { loadingText: {
Upgrading: '系统升级中请稍候...', Upgrading: '系统升级中请稍候...',
Restarting: '系统重启中请稍候...',
}, },
msg: { msg: {
delete: '删除 操作不可回滚是否继续', delete: '删除 操作不可回滚是否继续',

View File

@ -350,6 +350,7 @@ onMounted(() => {
onUnmounted(() => { onUnmounted(() => {
clearInterval(Number(timer)); clearInterval(Number(timer));
timer = null;
}); });
</script> </script>

View File

@ -123,7 +123,7 @@ const initTerm = (formEl: FormInstance | undefined) => {
formEl.validate(async (valid) => { formEl.validate(async (valid) => {
if (!valid) return; if (!valid) return;
let href = window.location.href; let href = window.location.href;
let ipLocal = href.split('//')[1].split(':')[0]; let ipLocal = href.split('//')[1].split('/')[0];
terminalOpen.value = true; terminalOpen.value = true;
let ifm = document.getElementById('terminal-exec') as HTMLInputElement | null; let ifm = document.getElementById('terminal-exec') as HTMLInputElement | null;
term = new Terminal({ term = new Terminal({
@ -141,7 +141,7 @@ const initTerm = (formEl: FormInstance | undefined) => {
if (ifm) { if (ifm) {
term.open(ifm); term.open(ifm);
terminalSocket = new WebSocket( terminalSocket = new WebSocket(
`ws://${ipLocal}:9999/api/v1/containers/exec?containerid=${form.containerID}&cols=${term.cols}&rows=${term.rows}&user=${form.user}&command=${form.command}`, `ws://${ipLocal}/api/v1/containers/exec?containerid=${form.containerID}&cols=${term.cols}&rows=${term.rows}&user=${form.user}&command=${form.command}`,
); );
terminalSocket.onopen = runRealTerminal; terminalSocket.onopen = runRealTerminal;
terminalSocket.onmessage = onWSReceive; terminalSocket.onmessage = onWSReceive;

View File

@ -70,7 +70,7 @@ const closeRealTerminal = (ev: CloseEvent) => {
const initTerm = () => { const initTerm = () => {
let ifm = document.getElementById('terminal-exec') as HTMLInputElement | null; let ifm = document.getElementById('terminal-exec') as HTMLInputElement | null;
let href = window.location.href; let href = window.location.href;
let ipLocal = href.split('//')[1].split(':')[0]; let ipLocal = href.split('//')[1].split('/')[0];
term = new Terminal({ term = new Terminal({
lineHeight: 1.2, lineHeight: 1.2,
fontSize: 12, fontSize: 12,
@ -86,7 +86,7 @@ const initTerm = () => {
if (ifm) { if (ifm) {
term.open(ifm); term.open(ifm);
terminalSocket = new WebSocket( terminalSocket = new WebSocket(
`ws://${ipLocal}:9999/api/v1/databases/redis/exec?cols=${term.cols}&rows=${term.rows}`, `ws://${ipLocal}/api/v1/databases/redis/exec?cols=${term.cols}&rows=${term.rows}`,
); );
terminalSocket.onopen = runRealTerminal; terminalSocket.onopen = runRealTerminal;
terminalSocket.onmessage = onWSReceive; terminalSocket.onmessage = onWSReceive;

View File

@ -56,8 +56,8 @@ const onClose = () => {};
const initProcess = () => { const initProcess = () => {
let href = window.location.href; let href = window.location.href;
let ipLocal = href.split('//')[1].split(':')[0]; let ipLocal = href.split('//')[1].split('/')[0];
processSocket = new WebSocket(`ws://${ipLocal}:9999/api/v1/files/ws`); processSocket = new WebSocket(`ws://${ipLocal}/api/v1/files/ws`);
processSocket.onopen = onOpenProcess; processSocket.onopen = onOpenProcess;
processSocket.onmessage = onMessage; processSocket.onmessage = onMessage;
processSocket.onerror = onerror; processSocket.onerror = onerror;

View File

@ -93,7 +93,7 @@ const initErrorTerm = (errorInfo: string) => {
const initTerm = () => { const initTerm = () => {
let ifm = document.getElementById('terminal-' + terminalID.value) as HTMLInputElement | null; let ifm = document.getElementById('terminal-' + terminalID.value) as HTMLInputElement | null;
let href = window.location.href; let href = window.location.href;
let ipLocal = href.split('//')[1].split(':')[0]; let ipLocal = href.split('//')[1].split('/')[0];
term = new Terminal({ term = new Terminal({
lineHeight: 1.2, lineHeight: 1.2,
fontSize: 12, fontSize: 12,
@ -109,7 +109,7 @@ const initTerm = () => {
if (ifm) { if (ifm) {
term.open(ifm); term.open(ifm);
terminalSocket = new WebSocket( terminalSocket = new WebSocket(
`ws://${ipLocal}:9999/api/v1/terminals?id=${wsID.value}&cols=${term.cols}&rows=${term.rows}`, `ws://${ipLocal}/api/v1/terminals?id=${wsID.value}&cols=${term.cols}&rows=${term.rows}`,
); );
terminalSocket.onopen = runRealTerminal; terminalSocket.onopen = runRealTerminal;
terminalSocket.onmessage = onWSReceive; terminalSocket.onmessage = onWSReceive;

View File

@ -166,7 +166,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'; import { ref, reactive, onMounted, onUnmounted } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import type { ElForm } from 'element-plus'; import type { ElForm } from 'element-plus';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
@ -176,6 +176,8 @@ import { MenuStore } from '@/store/modules/menu';
import i18n from '@/lang'; import i18n from '@/lang';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
let timer: NodeJS.Timer | null = null;
const globalStore = GlobalStore(); const globalStore = GlobalStore();
const menuStore = MenuStore(); const menuStore = MenuStore();
@ -318,6 +320,11 @@ function checkPassword(rule: any, value: any, callback: any) {
onMounted(() => { onMounted(() => {
document.title = globalStore.themeConfig.panelName; document.title = globalStore.themeConfig.panelName;
timer = setInterval(() => {
if (loginForm.captcha === '') {
loginVerify();
}
}, 1000 * 8);
checkStatus(); checkStatus();
document.onkeydown = (e: any) => { document.onkeydown = (e: any) => {
e = window.event || e; e = window.event || e;
@ -327,6 +334,11 @@ onMounted(() => {
} }
}; };
}); });
onUnmounted(() => {
clearInterval(Number(timer));
timer = null;
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -31,6 +31,20 @@
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('setting.panelPort')" :rules="Rules.port" prop="serverPort">
<el-input clearable v-model.number="form.serverPort">
<template #append>
<el-button
@click="onSavePort(panelFormRef, 'ServerPort', form.serverPort)"
icon="Collection"
>
{{ $t('commons.button.save') }}
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('setting.language')" :rules="Rules.requiredSelect" prop="language"> <el-form-item :label="$t('setting.language')" :rules="Rules.requiredSelect" prop="language">
<el-radio-group <el-radio-group
style="width: 100%" style="width: 100%"
@ -84,9 +98,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, reactive, onMounted, computed } from 'vue'; import { ref, reactive, onMounted, computed } from 'vue';
import { ElMessage, ElForm } from 'element-plus'; import { ElMessage, ElForm, ElMessageBox } from 'element-plus';
import LayoutContent from '@/layout/layout-content.vue'; import LayoutContent from '@/layout/layout-content.vue';
import { syncTime, getSettingInfo, updateSetting } from '@/api/modules/setting'; import { syncTime, getSettingInfo, updateSetting, updatePort } from '@/api/modules/setting';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { GlobalStore } from '@/store'; import { GlobalStore } from '@/store';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
@ -179,32 +193,34 @@ const onSave = async (formEl: FormInstance | undefined, key: string, val: any) =
}); });
}; };
// const onSavePort = async (formEl: FormInstance | undefined, key: string, val: any) => { const onSavePort = async (formEl: FormInstance | undefined, key: string, val: any) => {
// if (!formEl) return; if (!formEl) return;
// const result = await formEl.validateField(key.replace(key[0], key[0].toLowerCase()), callback); const result = await formEl.validateField(key.replace(key[0], key[0].toLowerCase()), callback);
// if (!result) { if (!result) {
// return; return;
// } }
// ElMessageBox.confirm(i18n.t('setting.portChangeHelper'), i18n.t('setting.portChange'), { ElMessageBox.confirm(i18n.t('setting.portChangeHelper'), i18n.t('setting.portChange'), {
// confirmButtonText: i18n.t('commons.button.confirm'), confirmButtonText: i18n.t('commons.button.confirm'),
// cancelButtonText: i18n.t('commons.button.cancel'), cancelButtonText: i18n.t('commons.button.cancel'),
// type: 'info', type: 'info',
// }).then(async () => { }).then(async () => {
// loading.value = true; loading.value = true;
// let param = { let param = {
// serverPort: val, serverPort: val,
// }; };
// await updatePort(param) await updatePort(param)
// .then(() => { .then(() => {
// loading.value = false; loading.value = false;
// ElMessage.success(i18n.t('commons.msg.operationSuccess')); ElMessage.success(i18n.t('commons.msg.operationSuccess'));
// search(); let href = window.location.href;
// }) let ip = href.split('//')[1].split(':')[0];
// .catch(() => { window.open(`${href.split('//')[0]}//${ip}:${val}/1panel/login`, '_self');
// loading.value = false; })
// }); .catch(() => {
// }); loading.value = false;
// }; });
});
};
function countdown() { function countdown() {
count.value = TIME_COUNT.value; count.value = TIME_COUNT.value;