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

fix: 快照删除增加备份文件删除选项 (#5237)

Refs #4962
This commit is contained in:
ssongliu 2024-05-31 17:31:19 +08:00 committed by GitHub
parent a02f160adf
commit e044d92075
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 88 additions and 25 deletions

View File

@ -168,13 +168,13 @@ func (b *BaseApi) RollbackSnapshot(c *gin.Context) {
// @Summary Delete system backup // @Summary Delete system backup
// @Description 删除系统快照 // @Description 删除系统快照
// @Accept json // @Accept json
// @Param request body dto.BatchDeleteReq true "request" // @Param request body dto.SnapshotBatchDelete true "request"
// @Success 200 // @Success 200
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Router /settings/snapshot/del [post] // @Router /settings/snapshot/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"删除系统快照 [name]","formatEN":"Delete system backup [name]"} // @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"删除系统快照 [name]","formatEN":"Delete system backup [name]"}
func (b *BaseApi) DeleteSnapshot(c *gin.Context) { func (b *BaseApi) DeleteSnapshot(c *gin.Context) {
var req dto.BatchDeleteReq var req dto.SnapshotBatchDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil { if err := helper.CheckBindAndValidate(&req, c); err != nil {
return return
} }

View File

@ -122,6 +122,10 @@ type SnapshotRecover struct {
ReDownload bool `json:"reDownload"` ReDownload bool `json:"reDownload"`
ID uint `json:"id" validate:"required"` ID uint `json:"id" validate:"required"`
} }
type SnapshotBatchDelete struct {
DeleteWithFile bool `json:"deleteWithFile"`
Ids []uint `json:"ids" validate:"required"`
}
type SnapshotImport struct { type SnapshotImport struct {
From string `json:"from"` From string `json:"from"`
Names []string `json:"names"` Names []string `json:"names"`

View File

@ -32,7 +32,7 @@ type ISnapshotService interface {
SnapshotRecover(req dto.SnapshotRecover) error SnapshotRecover(req dto.SnapshotRecover) error
SnapshotRollback(req dto.SnapshotRecover) error SnapshotRollback(req dto.SnapshotRecover) error
SnapshotImport(req dto.SnapshotImport) error SnapshotImport(req dto.SnapshotImport) error
Delete(req dto.BatchDeleteReq) error Delete(req dto.SnapshotBatchDelete) error
LoadSnapShotStatus(id uint) (*dto.SnapshotStatus, error) LoadSnapShotStatus(id uint) (*dto.SnapshotStatus, error)
@ -323,25 +323,23 @@ func (u *SnapshotService) HandleSnapshot(isCronjob bool, logPath string, req dto
return snap.Name, nil return snap.Name, nil
} }
func (u *SnapshotService) Delete(req dto.BatchDeleteReq) error { func (u *SnapshotService) Delete(req dto.SnapshotBatchDelete) error {
backups, _ := snapshotRepo.GetList(commonRepo.WithIdsIn(req.Ids)) snaps, _ := snapshotRepo.GetList(commonRepo.WithIdsIn(req.Ids))
localDir, err := loadLocalDir() for _, snap := range snaps {
targetAccounts, err := loadClientMap(snap.From)
if err != nil { if err != nil {
return err return err
} }
for _, snap := range backups { for _, item := range targetAccounts {
itemFile := path.Join(localDir, "system", snap.Name) global.LOG.Debugf("remove snapshot file %s.tar.gz from %s", snap.Name, item.backType)
_ = os.RemoveAll(itemFile) _, _ = item.client.Delete(path.Join(item.backupPath, "system_snapshot", snap.Name+".tar.gz"))
}
itemTarFile := path.Join(global.CONF.System.TmpDir, "system", snap.Name+".tar.gz")
_ = os.Remove(itemTarFile)
_ = snapshotRepo.DeleteStatus(snap.ID) _ = snapshotRepo.DeleteStatus(snap.ID)
} if err := snapshotRepo.Delete(commonRepo.WithByID(snap.ID)); err != nil {
if err := snapshotRepo.Delete(commonRepo.WithIdsIn(req.Ids)); err != nil {
return err return err
} }
}
return nil return nil
} }

View File

@ -10501,7 +10501,7 @@ const docTemplate = `{
"in": "body", "in": "body",
"required": true, "required": true,
"schema": { "schema": {
"$ref": "#/definitions/dto.BatchDeleteReq" "$ref": "#/definitions/dto.SnapshotBatchDelete"
} }
} }
], ],
@ -18607,6 +18607,23 @@ const docTemplate = `{
} }
} }
}, },
"dto.SnapshotBatchDelete": {
"type": "object",
"required": [
"ids"
],
"properties": {
"deleteWithFile": {
"type": "boolean"
},
"ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"dto.SnapshotCreate": { "dto.SnapshotCreate": {
"type": "object", "type": "object",
"required": [ "required": [

View File

@ -10494,7 +10494,7 @@
"in": "body", "in": "body",
"required": true, "required": true,
"schema": { "schema": {
"$ref": "#/definitions/dto.BatchDeleteReq" "$ref": "#/definitions/dto.SnapshotBatchDelete"
} }
} }
], ],
@ -18600,6 +18600,23 @@
} }
} }
}, },
"dto.SnapshotBatchDelete": {
"type": "object",
"required": [
"ids"
],
"properties": {
"deleteWithFile": {
"type": "boolean"
},
"ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"dto.SnapshotCreate": { "dto.SnapshotCreate": {
"type": "object", "type": "object",
"required": [ "required": [

View File

@ -2744,6 +2744,17 @@ definitions:
required: required:
- key - key
type: object type: object
dto.SnapshotBatchDelete:
properties:
deleteWithFile:
type: boolean
ids:
items:
type: integer
type: array
required:
- ids
type: object
dto.SnapshotCreate: dto.SnapshotCreate:
properties: properties:
defaultDownload: defaultDownload:
@ -11846,7 +11857,7 @@ paths:
name: request name: request
required: true required: true
schema: schema:
$ref: '#/definitions/dto.BatchDeleteReq' $ref: '#/definitions/dto.SnapshotBatchDelete'
responses: responses:
"200": "200":
description: OK description: OK

View File

@ -183,7 +183,7 @@ export const snapshotImport = (param: Setting.SnapshotImport) => {
export const updateSnapshotDescription = (param: DescriptionUpdate) => { export const updateSnapshotDescription = (param: DescriptionUpdate) => {
return http.post(`/settings/snapshot/description/update`, param); return http.post(`/settings/snapshot/description/update`, param);
}; };
export const snapshotDelete = (param: { ids: number[] }) => { export const snapshotDelete = (param: { ids: number[]; deleteWithFile: boolean }) => {
return http.post(`/settings/snapshot/del`, param); return http.post(`/settings/snapshot/del`, param);
}; };
export const snapshotRecover = (param: Setting.SnapshotRecover) => { export const snapshotRecover = (param: Setting.SnapshotRecover) => {

View File

@ -1472,6 +1472,8 @@ const message = {
'Backup files not in the current backup list, please try downloading from the file directory and importing for backup.', 'Backup files not in the current backup list, please try downloading from the file directory and importing for backup.',
snapshot: 'Snapshot', snapshot: 'Snapshot',
deleteHelper:
'All backup files for the snapshot, including those in the third-party backup account, will be deleted.',
status: 'Snapshot status', status: 'Snapshot status',
ignoreRule: 'Ignore Rule', ignoreRule: 'Ignore Rule',
ignoreHelper: ignoreHelper:

View File

@ -1298,6 +1298,7 @@ const message = {
backupJump: '未在當前備份列表中的備份檔案請嘗試從檔案目錄中下載後導入備份', backupJump: '未在當前備份列表中的備份檔案請嘗試從檔案目錄中下載後導入備份',
snapshot: '快照', snapshot: '快照',
deleteHelper: '將刪除該快照的所有備份文件包括第三方備份賬號中的文件',
status: '快照狀態', status: '快照狀態',
ignoreRule: '排除規則', ignoreRule: '排除規則',
ignoreHelper: '快照時將使用該規則對 1Panel 數據目錄進行壓縮備份請謹慎修改', ignoreHelper: '快照時將使用該規則對 1Panel 數據目錄進行壓縮備份請謹慎修改',

View File

@ -1299,6 +1299,7 @@ const message = {
backupJump: '未在当前备份列表中的备份文件请尝试从文件目录中下载后导入备份', backupJump: '未在当前备份列表中的备份文件请尝试从文件目录中下载后导入备份',
snapshot: '快照', snapshot: '快照',
deleteHelper: '将删除该快照的所有备份文件包括第三方备份账号中的文件',
ignoreRule: '排除规则', ignoreRule: '排除规则',
ignoreHelper: '快照时将使用该规则对 1Panel 数据目录进行压缩备份请谨慎修改', ignoreHelper: '快照时将使用该规则对 1Panel 数据目录进行压缩备份请谨慎修改',
ignoreHelper1: '一行一个 \n*.log\n/opt/1panel/cache', ignoreHelper1: '一行一个 \n*.log\n/opt/1panel/cache',

View File

@ -164,7 +164,18 @@
</template> </template>
</el-drawer> </el-drawer>
<OpDialog ref="opRef" @search="search" /> <OpDialog ref="opRef" @search="search">
<template #content>
<el-form class="mt-4 mb-1" ref="deleteForm" label-position="left">
<el-form-item>
<el-checkbox v-model="cleanData" :label="$t('cronjob.cleanData')" />
<span class="input-help">
{{ $t('setting.deleteHelper') }}
</span>
</el-form-item>
</el-form>
</template>
</OpDialog>
<SnapStatus ref="snapStatusRef" @search="search" /> <SnapStatus ref="snapStatusRef" @search="search" />
<IgnoreRule ref="ignoreRef" /> <IgnoreRule ref="ignoreRef" />
</div> </div>
@ -221,6 +232,7 @@ let snapInfo = reactive<Setting.SnapshotCreate>({
fromAccounts: [], fromAccounts: [],
description: '', description: '',
}); });
const cleanData = ref();
const drawerVisible = ref<boolean>(false); const drawerVisible = ref<boolean>(false);
@ -332,7 +344,7 @@ const batchDelete = async (row: Setting.SnapshotInfo | null) => {
i18n.global.t('commons.button.delete'), i18n.global.t('commons.button.delete'),
]), ]),
api: snapshotDelete, api: snapshotDelete,
params: { ids: ids }, params: { ids: ids, deleteWithFile: cleanData.value },
}); });
}; };