diff --git a/backend/app/service/cronjob_helper.go b/backend/app/service/cronjob_helper.go index 6377ffc8a..a3549af6e 100644 --- a/backend/app/service/cronjob_helper.go +++ b/backend/app/service/cronjob_helper.go @@ -9,6 +9,7 @@ import ( "time" "github.com/1Panel-dev/1Panel/backend/app/model" + "github.com/1Panel-dev/1Panel/backend/app/repo" "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/global" "github.com/1Panel-dev/1Panel/backend/utils/cloud_storage" @@ -68,11 +69,6 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) { } func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Time) (string, error) { - var ( - backupDir string - fileName string - record model.BackupRecord - ) backup, err := backupRepo.Get(commonRepo.WithByID(uint(cronjob.TargetDirID))) if err != nil { return "", err @@ -89,77 +85,57 @@ func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Tim if err != nil { return "", err } - fileName = fmt.Sprintf("db_%s_%s.sql.gz", cronjob.DBName, startTime.Format("20060102150405")) - backupDir = fmt.Sprintf("%s/database/mysql/%s/%s", localDir, app.Name, cronjob.DBName) - if err = handleMysqlBackup(app, backupDir, cronjob.DBName, fileName); err != nil { + if err := u.handleDatabase(*cronjob, app, backup, startTime); err != nil { return "", err } - record.Type = "mysql" - record.Name = app.Name - record.DetailName = cronjob.DBName + if cronjob.DBName != "all" { + if !cronjob.KeepLocal && backup.Type != "LOCAL" { + return fmt.Sprintf("database/mysql/%s/%s/db_%s_%s.sql.gz", app.Name, cronjob.DBName, cronjob.DBName, startTime.Format("20060102150405")), nil + } + return fmt.Sprintf("%s/database/mysql/%s/%s/db_%s_%s.sql.gz", localDir, app.Name, cronjob.DBName, cronjob.DBName, startTime.Format("20060102150405")), nil + } + return "", nil case "website": - fileName = fmt.Sprintf("website_%s_%s.tar.gz", cronjob.Website, startTime.Format("20060102150405")) - backupDir = fmt.Sprintf("%s/website/%s", localDir, cronjob.Website) - website, err := websiteRepo.GetFirst(websiteRepo.WithDomain(cronjob.Website)) - if err != nil { + if err := u.handleWebsite(*cronjob, backup, startTime); err != nil { return "", err } - if err := handleWebsiteBackup(&website, backupDir, fileName); err != nil { - return "", err + if cronjob.DBName != "all" { + if !cronjob.KeepLocal && backup.Type != "LOCAL" { + return fmt.Sprintf("website/%s/website_%s_%s.tar.gz", cronjob.Website, cronjob.Website, startTime.Format("20060102150405")), nil + } + return fmt.Sprintf("%s/website/%s/website_%s_%s.tar.gz", localDir, cronjob.Website, cronjob.Website, startTime.Format("20060102150405")), nil } - record.Type = "website" - record.Name = website.PrimaryDomain + return "", nil default: - fileName = fmt.Sprintf("directory%s_%s.tar.gz", strings.ReplaceAll(cronjob.SourceDir, "/", "_"), startTime.Format("20060102150405")) - backupDir = fmt.Sprintf("%s/%s/%s", localDir, cronjob.Type, cronjob.Name) + fileName := fmt.Sprintf("directory%s_%s.tar.gz", strings.ReplaceAll(cronjob.SourceDir, "/", "_"), startTime.Format("20060102150405")) + backupDir := fmt.Sprintf("%s/%s/%s", localDir, cronjob.Type, cronjob.Name) + itemFileDir := fmt.Sprintf("%s/%s", cronjob.Type, cronjob.Name) global.LOG.Infof("handle tar %s to %s", backupDir, fileName) if err := handleTar(cronjob.SourceDir, backupDir, fileName, cronjob.ExclusionRules); err != nil { return "", err } - } - - itemFileDir := strings.ReplaceAll(backupDir, localDir+"/", "") - if len(record.Name) != 0 { - record.FileName = fileName - record.FileDir = backupDir - record.Source = "LOCAL" - record.BackupType = backup.Type - if !cronjob.KeepLocal && backup.Type != "LOCAL" { - record.Source = backup.Type - record.FileDir = itemFileDir + if backup.Type == "LOCAL" { + u.HandleRmExpired(backup.Type, backupDir, cronjob, nil) + return fmt.Sprintf("%s/%s", backupDir, fileName), nil } - if err := backupRepo.CreateRecord(&record); err != nil { - global.LOG.Errorf("save backup record failed, err: %v", err) + if !cronjob.KeepLocal { + defer func() { + _ = os.RemoveAll(fmt.Sprintf("%s/%s", backupDir, fileName)) + }() + } + client, err := NewIBackupService().NewClient(&backup) + if err != nil { return "", err } + if _, err = client.Upload(backupDir+"/"+fileName, itemFileDir+"/"+fileName); err != nil { + return "", err + } + u.HandleRmExpired(backup.Type, itemFileDir, cronjob, client) + if cronjob.KeepLocal { + u.HandleRmExpired("LOCAL", backupDir, cronjob, client) + } + return fmt.Sprintf("%s/%s/%s", cronjob.Type, cronjob.Name, fileName), nil } - - fullPath := fmt.Sprintf("%s/%s", backupDir, fileName) - if backup.Type != "LOCAL" { - fullPath = fmt.Sprintf("%s/%s", itemFileDir, fileName) - } - if backup.Type == "LOCAL" { - u.HandleRmExpired(backup.Type, backupDir, cronjob, nil) - return fullPath, nil - } - - if !cronjob.KeepLocal { - defer func() { - _ = os.RemoveAll(fmt.Sprintf("%s/%s", backupDir, fileName)) - }() - } - client, err := NewIBackupService().NewClient(&backup) - if err != nil { - return fullPath, err - } - if _, err = client.Upload(backupDir+"/"+fileName, itemFileDir+"/"+fileName); err != nil { - return fullPath, err - } - u.HandleRmExpired(backup.Type, itemFileDir, cronjob, client) - if cronjob.KeepLocal { - u.HandleRmExpired("LOCAL", backupDir, cronjob, client) - } - return fullPath, nil } func (u *CronjobService) HandleDelete(id uint) error { @@ -281,3 +257,137 @@ func handleUnTar(sourceFile, targetDir string) error { } return nil } + +func (u *CronjobService) handleDatabase(cronjob model.Cronjob, app *repo.RootInfo, backup model.BackupAccount, startTime time.Time) error { + localDir, err := loadLocalDir() + if err != nil { + return err + } + var record model.BackupRecord + + record.Type = "mysql" + record.Name = app.Name + record.Source = "LOCAL" + record.BackupType = backup.Type + + var dblist []string + if cronjob.DBName == "all" { + mysqlService := NewIMysqlService() + dblist, err = mysqlService.ListDBName() + if err != nil { + return err + } + } else { + dblist = append(dblist, cronjob.DBName) + } + for _, dbName := range dblist { + backupDir := fmt.Sprintf("%s/database/mysql/%s/%s", localDir, app.Name, dbName) + record.FileName = fmt.Sprintf("db_%s_%s.sql.gz", dbName, startTime.Format("20060102150405")) + if err = handleMysqlBackup(app, backupDir, dbName, record.FileName); err != nil { + return err + } + record.DetailName = dbName + record.FileDir = backupDir + itemFileDir := strings.ReplaceAll(backupDir, localDir+"/", "") + if !cronjob.KeepLocal && backup.Type != "LOCAL" { + record.Source = backup.Type + record.FileDir = itemFileDir + } + if err := saveBackupRecord(record); err != nil { + return err + } + if backup.Type == "LOCAL" { + u.HandleRmExpired(backup.Type, backupDir, &cronjob, nil) + return nil + } + if !cronjob.KeepLocal { + defer func() { + _ = os.RemoveAll(fmt.Sprintf("%s/%s", backupDir, record.FileName)) + }() + } + client, err := NewIBackupService().NewClient(&backup) + if err != nil { + return err + } + if _, err = client.Upload(backupDir+"/"+record.FileName, itemFileDir+"/"+record.FileName); err != nil { + return err + } + u.HandleRmExpired(backup.Type, itemFileDir, &cronjob, client) + if cronjob.KeepLocal { + u.HandleRmExpired("LOCAL", backupDir, &cronjob, client) + } + } + return nil +} + +func (u *CronjobService) handleWebsite(cronjob model.Cronjob, backup model.BackupAccount, startTime time.Time) error { + localDir, err := loadLocalDir() + if err != nil { + return err + } + var record model.BackupRecord + record.Type = "website" + record.Name = cronjob.Website + record.Source = "LOCAL" + record.BackupType = backup.Type + + var weblist []string + if cronjob.Website == "all" { + weblist, err = NewIWebsiteService().GetWebsiteOptions() + if err != nil { + return err + } + } else { + weblist = append(weblist, cronjob.Website) + } + for _, websiteItem := range weblist { + website, err := websiteRepo.GetFirst(websiteRepo.WithDomain(websiteItem)) + if err != nil { + return err + } + backupDir := fmt.Sprintf("%s/website/%s", localDir, website.PrimaryDomain) + record.FileDir = backupDir + itemFileDir := strings.ReplaceAll(backupDir, localDir+"/", "") + if !cronjob.KeepLocal && backup.Type != "LOCAL" { + record.Source = backup.Type + record.FileDir = strings.ReplaceAll(backupDir, localDir+"/", "") + } + record.FileName = fmt.Sprintf("website_%s_%s.tar.gz", website.PrimaryDomain, startTime.Format("20060102150405")) + if err := handleWebsiteBackup(&website, backupDir, record.FileName); err != nil { + return err + } + record.Name = website.PrimaryDomain + if err := saveBackupRecord(record); err != nil { + return err + } + if backup.Type == "LOCAL" { + u.HandleRmExpired(backup.Type, backupDir, &cronjob, nil) + return nil + } + if !cronjob.KeepLocal { + defer func() { + _ = os.RemoveAll(fmt.Sprintf("%s/%s", backupDir, record.FileName)) + }() + } + client, err := NewIBackupService().NewClient(&backup) + if err != nil { + return err + } + if _, err = client.Upload(backupDir+"/"+record.FileName, itemFileDir+"/"+record.FileName); err != nil { + return err + } + u.HandleRmExpired(backup.Type, itemFileDir, &cronjob, client) + if cronjob.KeepLocal { + u.HandleRmExpired("LOCAL", backupDir, &cronjob, client) + } + } + return nil +} + +func saveBackupRecord(record model.BackupRecord) error { + if err := backupRepo.CreateRecord(&record); err != nil { + global.LOG.Errorf("save backup record failed, err: %v", err) + return err + } + return nil +} diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 483f8c722..99e8b58ac 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -586,6 +586,8 @@ const message = { cronSpecHelper: 'Enter the correct execution period', directory: 'Backup directory', sourceDir: 'Backup directory', + allOptionHelper: + 'The current task plan is to back up all {0}. Direct download is not supported at the moment. You can check the backup list of {0} menu.', exclusionRules: 'Exclusive rule', saveLocal: 'Retain local backups (the same as the number of cloud storage copies)', url: 'URL Address', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 1f2b0a5a1..bac5cbe94 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -590,6 +590,7 @@ const message = { cronSpecHelper: '请输入正确的执行周期', directory: '备份目录', sourceDir: '备份目录', + allOptionHelper: '当前计划任务为备份所有 {0},暂不支持直接下载,可在 {0} 备份列表中查看', exclusionRules: '排除规则', saveLocal: '同时保留本地备份(和云存储保留份数一致)', url: 'URL 地址', diff --git a/frontend/src/views/cronjob/operate/index.vue b/frontend/src/views/cronjob/operate/index.vue index 39cc6b45b..f615478db 100644 --- a/frontend/src/views/cronjob/operate/index.vue +++ b/frontend/src/views/cronjob/operate/index.vue @@ -23,7 +23,12 @@ - + @@ -82,6 +87,7 @@ prop="website" > + @@ -89,6 +95,7 @@
+ diff --git a/frontend/src/views/cronjob/record/index.vue b/frontend/src/views/cronjob/record/index.vue index 8179dc43b..de06250f2 100644 --- a/frontend/src/views/cronjob/record/index.vue +++ b/frontend/src/views/cronjob/record/index.vue @@ -152,13 +152,23 @@ - {{ dialogData.rowData!.website }} + + {{ dialogData.rowData!.website }} + + + {{ $t('commons.table.all') }} + - {{ dialogData.rowData!.dbName }} + + {{ dialogData.rowData!.dbName }} + + + {{ $t('commons.table.all') }} +