mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 07:57:21 +08:00
feat: 备份优化
This commit is contained in:
@@ -77,12 +77,22 @@ func (r *backupRepo) List(typ biz.BackupType) ([]*types.BackupFile, error) {
|
||||
// target 目标名称
|
||||
// account 备份账号ID
|
||||
func (r *backupRepo) Create(ctx context.Context, typ biz.BackupType, target string, account uint) error {
|
||||
// 取备份账号,0 为本地备份
|
||||
backupAccount := new(biz.BackupAccount)
|
||||
if err := r.db.First(backupAccount, account).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New(r.t.Get("backup account not found"))
|
||||
if account != 0 {
|
||||
if err := r.db.First(backupAccount, account).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New(r.t.Get("backup account not found"))
|
||||
}
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
backupAccount = &biz.BackupAccount{
|
||||
Type: biz.BackupAccountTypeLocal,
|
||||
Info: types.BackupAccountInfo{
|
||||
Path: r.GetDefaultPath(typ),
|
||||
},
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := r.getStorage(*backupAccount)
|
||||
|
||||
@@ -66,26 +66,26 @@ func (r *cronRepo) Create(ctx context.Context, req *request.CronCreate) error {
|
||||
script = fmt.Sprintf(`#!/bin/bash
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
|
||||
|
||||
acepanel backup website -n '%s' -p '%s'
|
||||
acepanel backup clear -t website -f '%s' -s '%d' -p '%s'
|
||||
`, req.Target, req.BackupPath, req.Target, req.Save, req.BackupPath)
|
||||
acepanel backup website -n '%s' -a '%d'
|
||||
acepanel backup clear -t website -f '%s' -s '%d' -a '%d'
|
||||
`, req.Target, req.BackupAccount, req.Target, req.Save, req.BackupAccount)
|
||||
}
|
||||
if req.BackupType == "mysql" || req.BackupType == "postgres" {
|
||||
script = fmt.Sprintf(`#!/bin/bash
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
|
||||
|
||||
acepanel backup database -t '%s' -n '%s' -p '%s'
|
||||
acepanel backup clear -t '%s' -f '%s' -s '%d' -p '%s'
|
||||
`, req.BackupType, req.Target, req.BackupPath, req.BackupType, req.Target, req.Save, req.BackupPath)
|
||||
acepanel backup database -t '%s' -n '%s' -a '%d'
|
||||
acepanel backup clear -t '%s' -f '%s' -s '%d' -a '%d'
|
||||
`, req.BackupType, req.Target, req.BackupAccount, req.BackupType, req.Target, req.Save, req.BackupAccount)
|
||||
}
|
||||
}
|
||||
if req.Type == "cutoff" {
|
||||
script = fmt.Sprintf(`#!/bin/bash
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
|
||||
|
||||
acepanel cutoff website -n '%s' -p '%s'
|
||||
acepanel cutoff clear -t website -n '%s' -s '%d' -p '%s'
|
||||
`, req.Target, req.BackupPath, req.Target, req.Save, req.BackupPath)
|
||||
acepanel cutoff website -n '%s'
|
||||
acepanel cutoff clear -t website -n '%s' -s '%d'
|
||||
`, req.Target, req.Target, req.Save)
|
||||
}
|
||||
if req.Type == "shell" {
|
||||
script = req.Script
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package request
|
||||
|
||||
type CronCreate struct {
|
||||
Name string `form:"name" json:"name" validate:"required|notExists:crons,name"`
|
||||
Type string `form:"type" json:"type" validate:"required"`
|
||||
Time string `form:"time" json:"time" validate:"required|cron"`
|
||||
Script string `form:"script" json:"script"`
|
||||
BackupType string `form:"backup_type" json:"backup_type" validate:"requiredIf:Type,backup"`
|
||||
BackupPath string `form:"backup_path" json:"backup_path"`
|
||||
Target string `form:"target" json:"target" validate:"requiredIf:Type,backup,cutoff"`
|
||||
Save int `form:"save" json:"save" validate:"required"`
|
||||
Name string `form:"name" json:"name" validate:"required|notExists:crons,name"`
|
||||
Type string `form:"type" json:"type" validate:"required"`
|
||||
Time string `form:"time" json:"time" validate:"required|cron"`
|
||||
Script string `form:"script" json:"script"`
|
||||
BackupType string `form:"backup_type" json:"backup_type" validate:"requiredIf:Type,backup"`
|
||||
BackupAccount uint `form:"backup_account" json:"backup_account"`
|
||||
Target string `form:"target" json:"target" validate:"requiredIf:Type,backup,cutoff"`
|
||||
Save int `form:"save" json:"save" validate:"required"`
|
||||
}
|
||||
|
||||
type CronUpdate struct {
|
||||
|
||||
@@ -652,7 +652,6 @@ func (s *CliService) BackupPanel(ctx context.Context, cmd *cli.Command) error {
|
||||
}
|
||||
|
||||
func (s *CliService) BackupClear(ctx context.Context, cmd *cli.Command) error {
|
||||
path := s.backupRepo.GetDefaultPath(biz.BackupType(cmd.String("type")))
|
||||
|
||||
fmt.Println(s.hr)
|
||||
fmt.Println(s.t.Get("★ Start cleaning [%s]", time.Now().Format(time.DateTime)))
|
||||
@@ -661,11 +660,12 @@ func (s *CliService) BackupClear(ctx context.Context, cmd *cli.Command) error {
|
||||
fmt.Println(s.t.Get("|-Cleaning target: %s", cmd.String("file")))
|
||||
fmt.Println(s.t.Get("|-Keep count: %d", cmd.Int("save")))
|
||||
|
||||
if cmd.String("account") != "" {
|
||||
if cmd.Uint("account") != 0 {
|
||||
if err := s.backupRepo.ClearAccountExpired(cmd.Uint("account"), biz.BackupType(cmd.String("type")), cmd.String("file"), cmd.Int("save")); err != nil {
|
||||
return errors.New(s.t.Get("Cleaning failed: %v", err))
|
||||
}
|
||||
} else {
|
||||
path := s.backupRepo.GetDefaultPath(biz.BackupType(cmd.String("type")))
|
||||
if err := s.backupRepo.ClearExpired(path, cmd.String("file"), cmd.Int("save")); err != nil {
|
||||
return errors.New(s.t.Get("Cleaning failed: %v", err))
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import app from '@/api/panel/app'
|
||||
import backupAccount from '@/api/panel/backupAccount'
|
||||
import cron from '@/api/panel/cron'
|
||||
import home from '@/api/panel/home'
|
||||
import website from '@/api/panel/website'
|
||||
@@ -17,12 +18,13 @@ const createModel = ref({
|
||||
target: '',
|
||||
save: 1,
|
||||
backup_type: 'website',
|
||||
backup_path: '',
|
||||
backup_account: 0,
|
||||
script: $gettext('# Enter your script content here'),
|
||||
time: '* * * * *'
|
||||
})
|
||||
|
||||
const websites = ref<any>([])
|
||||
const accounts = ref<any[]>([])
|
||||
|
||||
const { data: installedEnvironment } = useRequest(home.installedEnvironment, {
|
||||
initialData: {
|
||||
@@ -64,6 +66,30 @@ watch(createModel, (value) => {
|
||||
}
|
||||
})
|
||||
|
||||
const generateTaskName = () => {
|
||||
const type = createModel.value.type
|
||||
const target = createModel.value.target
|
||||
|
||||
if (type === 'backup') {
|
||||
const backupTypeMap: Record<string, string> = {
|
||||
website: $gettext('Backup Website'),
|
||||
mysql: $gettext('Backup MySQL'),
|
||||
postgres: $gettext('Backup PostgreSQL')
|
||||
}
|
||||
const prefix = backupTypeMap[createModel.value.backup_type] || $gettext('Backup')
|
||||
createModel.value.name = target ? `${prefix} - ${target}` : prefix
|
||||
} else if (type === 'cutoff') {
|
||||
createModel.value.name = target ? `${$gettext('Log Rotation')} - ${target}` : $gettext('Log Rotation')
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [createModel.value.type, createModel.value.backup_type, createModel.value.target],
|
||||
() => {
|
||||
generateTaskName()
|
||||
}
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
useRequest(app.isInstalled('nginx')).onSuccess(({ data }) => {
|
||||
if (data) {
|
||||
@@ -78,6 +104,15 @@ onMounted(() => {
|
||||
})
|
||||
}
|
||||
})
|
||||
useRequest(backupAccount.list(1, 10000)).onSuccess(({ data }: { data: any }) => {
|
||||
for (const item of data.items) {
|
||||
accounts.value.push({
|
||||
label: item.name,
|
||||
value: item.id
|
||||
})
|
||||
}
|
||||
createModel.value.backup_account = accounts.value[0]?.value || 0
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -143,10 +178,11 @@ onMounted(() => {
|
||||
>
|
||||
<n-input v-model:value="createModel.target" :placeholder="$gettext('Database Name')" />
|
||||
</n-form-item>
|
||||
<n-form-item v-if="createModel.type === 'backup'" :label="$gettext('Save Directory')">
|
||||
<n-input
|
||||
v-model:value="createModel.backup_path"
|
||||
:placeholder="$gettext('Save Directory')"
|
||||
<n-form-item v-if="createModel.type === 'backup'" :label="$gettext('Backup Account')">
|
||||
<n-select
|
||||
v-model:value="createModel.backup_account"
|
||||
:options="accounts"
|
||||
:placeholder="$gettext('Select backup account')"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item v-if="createModel.type !== 'shell'" :label="$gettext('Retention Count')">
|
||||
|
||||
Reference in New Issue
Block a user