1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-31 22:18:07 +08:00

feat: 增加恢复默认配置功能

This commit is contained in:
zhengkunwang223 2022-12-09 17:16:07 +08:00 committed by zhengkunwang223
parent e68a21c2fc
commit 7da97bd663
13 changed files with 142 additions and 10 deletions

View File

@ -183,3 +183,19 @@ func (b *BaseApi) ChangeAppPort(c *gin.Context) {
helper.SuccessWithData(c, nil) helper.SuccessWithData(c, nil)
} }
func (b *BaseApi) GetDefaultConfig(c *gin.Context) {
key := c.Param("key")
if key == "" {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
content, err := appInstallService.GetDefaultConfigByKey(key)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, content)
}

View File

@ -3,12 +3,12 @@ package v1
import ( import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/request"
"github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/constant"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
func (b *BaseApi) GetNginx(c *gin.Context) { func (b *BaseApi) GetNginx(c *gin.Context) {
fileInfo, err := nginxService.GetNginxConfig() fileInfo, err := nginxService.GetNginxConfig()
if err != nil { if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@ -18,7 +18,6 @@ func (b *BaseApi) GetNginx(c *gin.Context) {
} }
func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) { func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) {
var req dto.NginxScopeReq var req dto.NginxScopeReq
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
@ -34,7 +33,6 @@ func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) {
} }
func (b *BaseApi) UpdateNginxConfigBy(c *gin.Context) { func (b *BaseApi) UpdateNginxConfigBy(c *gin.Context) {
var req dto.NginxConfigReq var req dto.NginxConfigReq
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
@ -49,7 +47,6 @@ func (b *BaseApi) UpdateNginxConfigBy(c *gin.Context) {
} }
func (b *BaseApi) GetNginxStatus(c *gin.Context) { func (b *BaseApi) GetNginxStatus(c *gin.Context) {
res, err := nginxService.GetStatus() res, err := nginxService.GetStatus()
if err != nil { if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@ -57,3 +54,17 @@ func (b *BaseApi) GetNginxStatus(c *gin.Context) {
} }
helper.SuccessWithData(c, res) helper.SuccessWithData(c, res)
} }
func (b *BaseApi) UpdateNginxFile(c *gin.Context) {
var req request.NginxConfigFileUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := nginxService.UpdateConfigFile(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}

View File

@ -0,0 +1,7 @@
package request
type NginxConfigFileUpdate struct {
Content string `json:"content" validate:"required"`
FilePath string `json:"filePath" validate:"required"`
Backup bool `json:"backup" validate:"required"`
}

View File

@ -366,6 +366,28 @@ func (a AppInstallService) DeleteCheck(installId uint) ([]dto.AppResource, error
return res, nil return res, nil
} }
func (a AppInstallService) GetDefaultConfigByKey(key string) (string, error) {
appInstall, err := getAppInstallByKey(key)
if err != nil {
return "", err
}
filePath := path.Join(constant.AppResourceDir, appInstall.App.Key, "versions", appInstall.Version, "conf")
if key == "mysql" {
filePath = path.Join(filePath, "my.cnf")
}
if key == "redis" {
filePath = path.Join(filePath, "redis.conf")
}
if key == "nginx" {
filePath = path.Join(filePath, "nginx.conf")
}
contentByte, err := os.ReadFile(filePath)
if err != nil {
return "", err
}
return string(contentByte), nil
}
func syncById(installId uint) error { func syncById(installId uint) error {
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId)) appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
if err != nil { if err != nil {

View File

@ -1,10 +1,13 @@
package service package service
import ( import (
"github.com/1Panel-dev/1Panel/backend/app/request"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os"
"path" "path"
"strings" "strings"
"time"
"github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/constant"
@ -66,3 +69,34 @@ func (n NginxService) GetStatus() (dto.NginxStatus, error) {
status.Waiting = resArray[15] status.Waiting = resArray[15]
return status, nil return status, nil
} }
func (n NginxService) UpdateConfigFile(req request.NginxConfigFileUpdate) error {
fileOp := files.NewFileOp()
if req.Backup {
backupPath := path.Join(path.Dir(req.FilePath), "bak")
if !fileOp.Stat(backupPath) {
if err := fileOp.CreateDir(backupPath, 0755); err != nil {
return err
}
}
newFile := path.Join(backupPath, "nginx.bak"+"-"+time.Now().Format("2006-01-02-15-04-05"))
if err := fileOp.Copy(req.FilePath, backupPath); err != nil {
return err
}
if err := fileOp.Rename(path.Join(backupPath, "nginx.conf"), newFile); err != nil {
return err
}
}
oldContent, err := os.ReadFile(req.FilePath)
if err != nil {
return err
}
if err := fileOp.WriteFile(req.FilePath, strings.NewReader(req.Content), 0644); err != nil {
return err
}
nginxInstall, err := getAppInstallByKey("nginx")
if err != nil {
return err
}
return nginxCheckAndReload(string(oldContent), req.FilePath, nginxInstall.ContainerName)
}

View File

@ -201,7 +201,6 @@ func opNginx(containerName, operate string) error {
} }
func nginxCheckAndReload(oldContent string, filePath string, containerName string) error { func nginxCheckAndReload(oldContent string, filePath string, containerName string) error {
if err := opNginx(containerName, constant.NginxCheck); err != nil { if err := opNginx(containerName, constant.NginxCheck); err != nil {
_ = files.NewFileOp().WriteFile(filePath, strings.NewReader(oldContent), 0644) _ = files.NewFileOp().WriteFile(filePath, strings.NewReader(oldContent), 0644)
return err return err
@ -211,6 +210,5 @@ func nginxCheckAndReload(oldContent string, filePath string, containerName strin
_ = files.NewFileOp().WriteFile(filePath, strings.NewReader(oldContent), 0644) _ = files.NewFileOp().WriteFile(filePath, strings.NewReader(oldContent), 0644)
return err return err
} }
return nil return nil
} }

View File

@ -31,5 +31,6 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) {
appRouter.POST("/installed/backups/del", baseApi.DeleteAppBackup) appRouter.POST("/installed/backups/del", baseApi.DeleteAppBackup)
appRouter.POST("/installed/port/change", baseApi.ChangeAppPort) appRouter.POST("/installed/port/change", baseApi.ChangeAppPort)
appRouter.GET("/services/:key", baseApi.GetServices) appRouter.GET("/services/:key", baseApi.GetServices)
appRouter.GET("/installed/conf/:key", baseApi.GetDefaultConfig)
} }
} }

View File

@ -19,5 +19,6 @@ func (a *NginxRouter) InitNginxRouter(Router *gin.RouterGroup) {
groupRouter.POST("/scope", baseApi.GetNginxConfigByScope) groupRouter.POST("/scope", baseApi.GetNginxConfigByScope)
groupRouter.POST("/update", baseApi.UpdateNginxConfigBy) groupRouter.POST("/update", baseApi.UpdateNginxConfigBy)
groupRouter.GET("/status", baseApi.GetNginxStatus) groupRouter.GET("/status", baseApi.GetNginxStatus)
groupRouter.POST("/file", baseApi.UpdateNginxFile)
} }
} }

View File

@ -23,4 +23,10 @@ export namespace Nginx {
writing: string; writing: string;
waiting: string; waiting: string;
} }
export interface NginxFileUpdate {
content: string;
filePath: string;
backup: boolean;
}
} }

View File

@ -69,3 +69,7 @@ export const DelAppBackups = (req: App.AppBackupDelReq) => {
export const GetAppUpdateVersions = (id: number) => { export const GetAppUpdateVersions = (id: number) => {
return http.get<any>(`apps/installed/${id}/versions`); return http.get<any>(`apps/installed/${id}/versions`);
}; };
export const GetAppDefaultConfig = (key: string) => {
return http.get<string>(`apps/installed/conf/${key}`);
};

View File

@ -17,3 +17,7 @@ export const UpdateNginxConfigByScope = (req: Nginx.NginxConfigReq) => {
export const GetNginxStatus = () => { export const GetNginxStatus = () => {
return http.get<Nginx.NginxStatus>(`/nginx/status`); return http.get<Nginx.NginxStatus>(`/nginx/status`);
}; };
export const UpdateNginxConfigFile = (req: Nginx.NginxFileUpdate) => {
return http.post<any>(`/nginx/file`, req);
};

View File

@ -777,6 +777,8 @@ export default {
checkTitle: '提示', checkTitle: '提示',
website: '网站', website: '网站',
database: '数据库', database: '数据库',
defaultConfig: '默认配置',
defaultConfigHelper: '已恢复为默认配置保存后生效',
}, },
website: { website: {
website: '网站', website: '网站',

View File

@ -15,36 +15,53 @@
:readOnly="true" :readOnly="true"
/> />
<div style="margin-top: 10px"> <div style="margin-top: 10px">
<el-button @click="getDefaultConfig()" :loading="loading">
{{ $t('app.defaultConfig') }}
</el-button>
<el-button type="primary" @click="submit()" :loading="loading"> <el-button type="primary" @click="submit()" :loading="loading">
{{ $t('commons.button.save') }} {{ $t('commons.button.save') }}
</el-button> </el-button>
</div> </div>
<el-row>
<el-col :span="4">
<el-alert
v-if="useOld"
style="margin-top: 10px"
:title="$t('app.defaultConfigHelper')"
type="info"
:closable="false"
></el-alert>
</el-col>
</el-row>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { GetNginx } from '@/api/modules/nginx'; import { GetNginx, UpdateNginxConfigFile } from '@/api/modules/nginx';
import { onMounted, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { Codemirror } from 'vue-codemirror'; import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript'; import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark'; import { oneDark } from '@codemirror/theme-one-dark';
import { SaveFileContent } from '@/api/modules/files';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import i18n from '@/lang'; import i18n from '@/lang';
import { GetAppDefaultConfig } from '@/api/modules/app';
const extensions = [javascript(), oneDark]; const extensions = [javascript(), oneDark];
let data = ref(); let data = ref();
let content = ref(''); let content = ref('');
let loading = ref(false); let loading = ref(false);
let useOld = ref(false);
const submit = () => { const submit = () => {
loading.value = true; loading.value = true;
SaveFileContent({ UpdateNginxConfigFile({
path: data.value.path, filePath: data.value.path,
content: content.value, content: content.value,
backup: useOld.value,
}) })
.then(() => { .then(() => {
ElMessage.success(i18n.global.t('commons.msg.updateSuccess')); ElMessage.success(i18n.global.t('commons.msg.updateSuccess'));
getNginx();
}) })
.finally(() => { .finally(() => {
loading.value = false; loading.value = false;
@ -55,6 +72,15 @@ const getNginx = async () => {
const res = await GetNginx(); const res = await GetNginx();
data.value = res.data; data.value = res.data;
content.value = data.value.content; content.value = data.value.content;
useOld.value = false;
};
const getDefaultConfig = async () => {
loading.value = true;
const res = await GetAppDefaultConfig('nginx');
content.value = res.data;
useOld.value = true;
loading.value = false;
}; };
onMounted(() => { onMounted(() => {