From 8431f49c4703963e780bcff15615e014f3fa29ab Mon Sep 17 00:00:00 2001 From: ssongliu Date: Tue, 8 Nov 2022 14:34:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E7=AB=AF=E5=8F=A3=E4=BF=AE=E6=94=B9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/v1/app.go | 23 ++++++- backend/app/dto/app.go | 7 +++ backend/app/dto/database.go | 1 + backend/app/repo/databse_mysql.go | 4 +- backend/app/service/app.go | 61 ++++++++++++++++++- backend/app/service/database_mysql.go | 2 +- backend/app/service/database_redis.go | 3 +- backend/router/ro_app.go | 1 + frontend/src/api/interface/app.ts | 6 ++ frontend/src/api/interface/database.ts | 1 + frontend/src/api/modules/app.ts | 4 ++ frontend/src/lang/modules/zh.ts | 1 + .../views/database/mysql/setting/index.vue | 11 ++++ .../views/database/redis/setting/index.vue | 38 +++++++++++- 14 files changed, 152 insertions(+), 11 deletions(-) diff --git a/backend/app/api/v1/app.go b/backend/app/api/v1/app.go index 8f465d4a2..7cb8afc0f 100644 --- a/backend/app/api/v1/app.go +++ b/backend/app/api/v1/app.go @@ -1,11 +1,13 @@ package v1 import ( + "strconv" + "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/constant" + "github.com/1Panel-dev/1Panel/backend/global" "github.com/gin-gonic/gin" - "strconv" ) func (b *BaseApi) SearchApp(c *gin.Context) { @@ -180,3 +182,22 @@ func (b *BaseApi) GetUpdateVersions(c *gin.Context) { helper.SuccessWithData(c, versions) } + +func (b *BaseApi) ChangeAppPort(c *gin.Context) { + var req dto.PortUpdate + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + if err := global.VALID.Struct(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + + if err := appService.ChangeAppPort(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + + helper.SuccessWithData(c, nil) +} diff --git a/backend/app/dto/app.go b/backend/app/dto/app.go index f8189bc64..38b1e9689 100644 --- a/backend/app/dto/app.go +++ b/backend/app/dto/app.go @@ -2,6 +2,7 @@ package dto import ( "encoding/json" + "github.com/1Panel-dev/1Panel/backend/app/model" ) @@ -78,6 +79,12 @@ type AppInstallOperate struct { Operate AppOperate `json:"operate" validate:"required"` } +type PortUpdate struct { + Key string `json:"key"` + Name string `json:"name"` + Port int64 `json:"port"` +} + type AppService struct { Label string `json:"label"` Value string `json:"value"` diff --git a/backend/app/dto/database.go b/backend/app/dto/database.go index cba13835b..65843fe59 100644 --- a/backend/app/dto/database.go +++ b/backend/app/dto/database.go @@ -151,6 +151,7 @@ type RedisConfUpdateByFile struct { type RedisConf struct { Name string `json:"name"` + Port int64 `json:"port"` ContainerName string `json:"containerName"` Timeout string `json:"timeout"` Maxclients string `json:"maxclients"` diff --git a/backend/app/repo/databse_mysql.go b/backend/app/repo/databse_mysql.go index 5cbbcc94a..130001532 100644 --- a/backend/app/repo/databse_mysql.go +++ b/backend/app/repo/databse_mysql.go @@ -22,7 +22,7 @@ type IMysqlRepo interface { LoadRunningVersion(keys []string) ([]string, error) LoadBaseInfoByName(name string) (*RootInfo, error) LoadRedisBaseInfo() (*RootInfo, error) - UpdateDatabasePassword(id uint, vars map[string]interface{}) error + UpdateDatabaseInfo(id uint, vars map[string]interface{}) error } func NewIMysqlRepo() IMysqlRepo { @@ -181,7 +181,7 @@ func (u *MysqlRepo) Update(id uint, vars map[string]interface{}) error { return global.DB.Model(&model.DatabaseMysql{}).Where("id = ?", id).Updates(vars).Error } -func (u *MysqlRepo) UpdateDatabasePassword(id uint, vars map[string]interface{}) error { +func (u *MysqlRepo) UpdateDatabaseInfo(id uint, vars map[string]interface{}) error { if err := global.DB.Model(&model.AppInstall{}).Where("id = ?", id).Updates(vars).Error; err != nil { return err } diff --git a/backend/app/service/app.go b/backend/app/service/app.go index 7b43f0f43..c888ad9ca 100644 --- a/backend/app/service/app.go +++ b/backend/app/service/app.go @@ -5,6 +5,12 @@ import ( "encoding/json" "errors" "fmt" + "io/ioutil" + "os" + "path" + "strconv" + "strings" + "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/app/repo" @@ -16,9 +22,6 @@ import ( "github.com/1Panel-dev/1Panel/backend/utils/files" "golang.org/x/net/context" "gopkg.in/yaml.v3" - "os" - "path" - "strings" ) type AppService struct { @@ -197,6 +200,58 @@ func (a AppService) OperateInstall(req dto.AppInstallOperate) error { return appInstallRepo.Save(&install) } +func (a AppService) ChangeAppPort(req dto.PortUpdate) error { + var ( + files []string + newFiles []string + ) + app, err := mysqlRepo.LoadBaseInfoByName(req.Name) + if err != nil { + return err + } + + ComposeDir := fmt.Sprintf("%s/%s/%s", constant.AppInstallDir, req.Key, req.Name) + ComposeFile := fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, req.Key, req.Name) + path := fmt.Sprintf("%s/.env", ComposeDir) + lineBytes, err := ioutil.ReadFile(path) + if err != nil { + return err + } else { + files = strings.Split(string(lineBytes), "\n") + } + for _, line := range files { + if strings.HasPrefix(line, "PANEL_APP_PORT_HTTP=") { + newFiles = append(newFiles, fmt.Sprintf("PANEL_APP_PORT_HTTP=%v", req.Port)) + } else { + newFiles = append(newFiles, line) + } + } + file, err := os.OpenFile(path, os.O_WRONLY, 0666) + if err != nil { + return err + } + defer file.Close() + _, err = file.WriteString(strings.Join(newFiles, "\n")) + if err != nil { + return err + } + + if err := mysqlRepo.UpdateDatabaseInfo(app.ID, map[string]interface{}{ + "env": strings.ReplaceAll(app.Env, strconv.FormatInt(app.Port, 10), strconv.FormatInt(req.Port, 10)), + }); err != nil { + return err + } + stdout, err := compose.Down(ComposeFile) + if err != nil { + return errors.New(stdout) + } + stdout, err = compose.Up(ComposeFile) + if err != nil { + return errors.New(stdout) + } + return nil +} + func (a AppService) Install(name string, appDetailId uint, params map[string]interface{}) error { httpPort, err := checkPort("PANEL_APP_PORT_HTTP", params) diff --git a/backend/app/service/database_mysql.go b/backend/app/service/database_mysql.go index c03f57f16..0832b7eeb 100644 --- a/backend/app/service/database_mysql.go +++ b/backend/app/service/database_mysql.go @@ -224,7 +224,7 @@ func (u *MysqlService) ChangeInfo(info dto.ChangeDBInfo) error { } } } - _ = mysqlRepo.UpdateDatabasePassword(app.ID, map[string]interface{}{ + _ = mysqlRepo.UpdateDatabaseInfo(app.ID, map[string]interface{}{ "param": strings.ReplaceAll(app.Param, app.Password, info.Value), "env": strings.ReplaceAll(app.Env, app.Password, info.Value), }) diff --git a/backend/app/service/database_redis.go b/backend/app/service/database_redis.go index 58623de21..ef3980866 100644 --- a/backend/app/service/database_redis.go +++ b/backend/app/service/database_redis.go @@ -47,7 +47,7 @@ func (u *RedisService) UpdateConf(req dto.RedisConfUpdate) error { if err := configSetStr(redisInfo.ContainerName, redisInfo.Password, "maxclients", req.Maxclients); err != nil { return err } - if err := mysqlRepo.UpdateDatabasePassword(redisInfo.ID, map[string]interface{}{ + if err := mysqlRepo.UpdateDatabaseInfo(redisInfo.ID, map[string]interface{}{ "param": strings.ReplaceAll(redisInfo.Param, redisInfo.Password, req.Requirepass), "env": strings.ReplaceAll(redisInfo.Env, redisInfo.Password, req.Requirepass), }); err != nil { @@ -133,6 +133,7 @@ func (u *RedisService) LoadConf() (*dto.RedisConf, error) { var item dto.RedisConf item.ContainerName = redisInfo.ContainerName item.Name = redisInfo.Name + item.Port = redisInfo.Port if item.Timeout, err = configGetStr(redisInfo.ContainerName, redisInfo.Password, "timeout"); err != nil { return nil, err } diff --git a/backend/router/ro_app.go b/backend/router/ro_app.go index 98cc07641..f81a645aa 100644 --- a/backend/router/ro_app.go +++ b/backend/router/ro_app.go @@ -26,6 +26,7 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) { appRouter.POST("/installed/sync", baseApi.SyncInstalled) appRouter.POST("/installed/backups", baseApi.SearchInstalledBackup) appRouter.POST("/installed/backups/del", baseApi.DeleteAppBackup) + appRouter.POST("/installed/port/change", baseApi.ChangeAppPort) appRouter.GET("/services/:key", baseApi.GetServices) } } diff --git a/frontend/src/api/interface/app.ts b/frontend/src/api/interface/app.ts index f07bc6790..cc5495676 100644 --- a/frontend/src/api/interface/app.ts +++ b/frontend/src/api/interface/app.ts @@ -62,6 +62,12 @@ export namespace App { params: any; } + export interface ChangePort { + key: string; + name: string; + port: number; + } + export interface AppInstalled extends CommonModel { name: string; appId: string; diff --git a/frontend/src/api/interface/database.ts b/frontend/src/api/interface/database.ts index 75eb70c17..ca99184dd 100644 --- a/frontend/src/api/interface/database.ts +++ b/frontend/src/api/interface/database.ts @@ -150,6 +150,7 @@ export namespace Database { } export interface RedisConf { name: string; + port: number; timeout: number; maxclients: number; requirepass: string; diff --git a/frontend/src/api/modules/app.ts b/frontend/src/api/modules/app.ts index 047c5d4e8..5c37e8c76 100644 --- a/frontend/src/api/modules/app.ts +++ b/frontend/src/api/modules/app.ts @@ -22,6 +22,10 @@ export const InstallApp = (install: App.AppInstall) => { return http.post('apps/install', install); }; +export const ChangePort = (params: App.ChangePort) => { + return http.post('apps/installed/port/change', params); +}; + export const GetAppInstalled = (info: ReqPage) => { return http.post>('apps/installed', info); }; diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index f96bed8ad..a5bd26d08 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -171,6 +171,7 @@ export default { baseSetting: '基础设置', remoteConnHelper: 'root 帐号远程连接 mysql 有安全风险,开启需谨慎!', confChange: '配置修改', + portHelper: '该端口为容器对外暴露端口,修改需要单独保存并且重启容器!', currentStatus: '当前状态', runTime: '启动时间', diff --git a/frontend/src/views/database/mysql/setting/index.vue b/frontend/src/views/database/mysql/setting/index.vue index ef937e248..c6ef809b2 100644 --- a/frontend/src/views/database/mysql/setting/index.vue +++ b/frontend/src/views/database/mysql/setting/index.vue @@ -104,6 +104,7 @@ import { updateMysqlConfByFile, updateMysqlDBInfo, } from '@/api/modules/database'; +import { ChangePort } from '@/api/modules/app'; import { Rules } from '@/global/form-rules'; import i18n from '@/lang'; @@ -152,6 +153,16 @@ const onSave = async (formEl: FormInstance | undefined, key: string, val: any) = if (!result) { return; } + if (key === 'port') { + let params = { + key: baseInfo.mysqlKey, + name: mysqlName.value, + port: val, + }; + await ChangePort(params); + ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); + return; + } let changeForm = { id: 0, mysqlName: mysqlName.value, diff --git a/frontend/src/views/database/redis/setting/index.vue b/frontend/src/views/database/redis/setting/index.vue index 09a7f501a..1bc7561d3 100644 --- a/frontend/src/views/database/redis/setting/index.vue +++ b/frontend/src/views/database/redis/setting/index.vue @@ -9,8 +9,15 @@
- - + + + + + {{ $t('database.portHelper') }} @@ -71,6 +78,7 @@ import ConfirmDialog from '@/components/confirm-dialog/index.vue'; import { loadRedisConf, updateRedisConf, updateRedisConfByFile } from '@/api/modules/database'; import i18n from '@/lang'; import { Rules } from '@/global/form-rules'; +import { ChangePort } from '@/api/modules/app'; const extensions = [javascript(), oneDark]; const confShowType = ref('base'); @@ -78,7 +86,7 @@ const confShowType = ref('base'); const restartNow = ref(false); const form = reactive({ name: '', - port: 3306, + port: 6379, requirepass: '', timeout: 0, maxclients: 0, @@ -105,6 +113,29 @@ const onClose = (): void => { settingShow.value = false; }; +const onChangePort = async (formEl: FormInstance | undefined) => { + if (!formEl) return; + const result = await formEl.validateField('port', callback); + if (!result) { + return; + } + let params = { + key: 'redis', + name: form.name, + port: form.port, + }; + await ChangePort(params); + ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); + return; +}; +function callback(error: any) { + if (error) { + return error.message; + } else { + return; + } +} + const onSave = async (formEl: FormInstance | undefined) => { if (confShowType.value === 'all') { onSaveFile(); @@ -149,6 +180,7 @@ const loadform = async () => { form.maxclients = Number(res.data?.maxclients); form.requirepass = res.data?.requirepass; form.maxmemory = Number(res.data?.maxmemory); + form.port = Number(res.data?.port); loadMysqlConf(`/opt/1Panel/data/apps/redis/${form.name}/conf/redis.conf`); };