mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-18 13:29:03 +08:00
feat: Add backup status for manual backups (#10377)
This commit is contained in:
parent
c3121fcd38
commit
9a6b51b092
14 changed files with 225 additions and 144 deletions
|
|
@ -99,6 +99,9 @@ type BackupRecords struct {
|
||||||
DownloadAccountID uint `json:"downloadAccountID"`
|
DownloadAccountID uint `json:"downloadAccountID"`
|
||||||
FileDir string `json:"fileDir"`
|
FileDir string `json:"fileDir"`
|
||||||
FileName string `json:"fileName"`
|
FileName string `json:"fileName"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Message string `json:"message"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,5 +27,8 @@ type BackupRecord struct {
|
||||||
FileDir string `json:"fileDir"`
|
FileDir string `json:"fileDir"`
|
||||||
FileName string `json:"fileName"`
|
FileName string `json:"fileName"`
|
||||||
|
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Message string `json:"message"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,35 +45,28 @@ func (u *BackupService) AppBackup(req dto.CommonBackup) (*model.BackupRecord, er
|
||||||
fileName = fmt.Sprintf("%s_%s.tar.gz", req.DetailName, timeNow+common.RandStrAndNum(5))
|
fileName = fmt.Sprintf("%s_%s.tar.gz", req.DetailName, timeNow+common.RandStrAndNum(5))
|
||||||
}
|
}
|
||||||
|
|
||||||
backupApp := func() (*model.BackupRecord, error) {
|
record := &model.BackupRecord{
|
||||||
if err = handleAppBackup(&install, nil, backupDir, fileName, "", req.Secret, req.TaskID); err != nil {
|
Type: "app",
|
||||||
global.LOG.Errorf("backup app %s failed, err: %v", req.DetailName, err)
|
Name: req.Name,
|
||||||
return nil, err
|
DetailName: req.DetailName,
|
||||||
}
|
SourceAccountIDs: "1",
|
||||||
record := &model.BackupRecord{
|
DownloadAccountID: 1,
|
||||||
Type: "app",
|
FileDir: itemDir,
|
||||||
Name: req.Name,
|
FileName: fileName,
|
||||||
DetailName: req.DetailName,
|
TaskID: req.TaskID,
|
||||||
SourceAccountIDs: "1",
|
Status: constant.StatusWaiting,
|
||||||
DownloadAccountID: 1,
|
Description: req.Description,
|
||||||
FileDir: itemDir,
|
}
|
||||||
FileName: fileName,
|
if err := backupRepo.CreateRecord(record); err != nil {
|
||||||
Description: req.Description,
|
global.LOG.Errorf("save backup record failed, err: %v", err)
|
||||||
}
|
return nil, err
|
||||||
if err := backupRepo.CreateRecord(record); err != nil {
|
|
||||||
global.LOG.Errorf("save backup record failed, err: %v", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return record, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.TaskID != "" {
|
if err = handleAppBackup(&install, nil, record.ID, backupDir, fileName, "", req.Secret, req.TaskID); err != nil {
|
||||||
go func() {
|
global.LOG.Errorf("backup app %s failed, err: %v", req.DetailName, err)
|
||||||
_, _ = backupApp()
|
return nil, err
|
||||||
}()
|
|
||||||
} else {
|
|
||||||
return backupApp()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,11 +87,9 @@ func (u *BackupService) AppRecover(req dto.CommonRecover) error {
|
||||||
if _, err := compose.Down(install.GetComposePath()); err != nil {
|
if _, err := compose.Down(install.GetComposePath()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
go func() {
|
if err := handleAppRecover(&install, nil, req.File, false, req.Secret, req.TaskID); err != nil {
|
||||||
if err := handleAppRecover(&install, nil, req.File, false, req.Secret, req.TaskID); err != nil {
|
global.LOG.Errorf("recover app %s failed, err: %v", req.DetailName, err)
|
||||||
global.LOG.Errorf("recover app %s failed, err: %v", req.DetailName, err)
|
}
|
||||||
}
|
|
||||||
}()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +102,7 @@ func backupDatabaseWithTask(parentTask *task.Task, resourceKey, tmpDir, name str
|
||||||
}
|
}
|
||||||
parentTask.LogStart(task.GetTaskName(db.Name, task.TaskBackup, task.TaskScopeDatabase))
|
parentTask.LogStart(task.GetTaskName(db.Name, task.TaskBackup, task.TaskScopeDatabase))
|
||||||
databaseHelper := DatabaseHelper{Database: db.MysqlName, DBType: resourceKey, Name: db.Name}
|
databaseHelper := DatabaseHelper{Database: db.MysqlName, DBType: resourceKey, Name: db.Name}
|
||||||
if err := handleMysqlBackup(databaseHelper, parentTask, tmpDir, fmt.Sprintf("%s.sql.gz", name), ""); err != nil {
|
if err := handleMysqlBackup(databaseHelper, parentTask, 0, tmpDir, fmt.Sprintf("%s.sql.gz", name), ""); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
parentTask.LogSuccess(task.GetTaskName(db.Name, task.TaskBackup, task.TaskScopeDatabase))
|
parentTask.LogSuccess(task.GetTaskName(db.Name, task.TaskBackup, task.TaskScopeDatabase))
|
||||||
|
|
@ -122,7 +113,7 @@ func backupDatabaseWithTask(parentTask *task.Task, resourceKey, tmpDir, name str
|
||||||
}
|
}
|
||||||
parentTask.LogStart(task.GetTaskName(db.Name, task.TaskBackup, task.TaskScopeDatabase))
|
parentTask.LogStart(task.GetTaskName(db.Name, task.TaskBackup, task.TaskScopeDatabase))
|
||||||
databaseHelper := DatabaseHelper{Database: db.PostgresqlName, DBType: resourceKey, Name: db.Name}
|
databaseHelper := DatabaseHelper{Database: db.PostgresqlName, DBType: resourceKey, Name: db.Name}
|
||||||
if err := handlePostgresqlBackup(databaseHelper, parentTask, tmpDir, fmt.Sprintf("%s.sql.gz", name), ""); err != nil {
|
if err := handlePostgresqlBackup(databaseHelper, parentTask, 0, tmpDir, fmt.Sprintf("%s.sql.gz", name), ""); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
parentTask.LogSuccess(task.GetTaskName(db.Name, task.TaskBackup, task.TaskScopeDatabase))
|
parentTask.LogSuccess(task.GetTaskName(db.Name, task.TaskBackup, task.TaskScopeDatabase))
|
||||||
|
|
@ -130,7 +121,7 @@ func backupDatabaseWithTask(parentTask *task.Task, resourceKey, tmpDir, name str
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleAppBackup(install *model.AppInstall, parentTask *task.Task, backupDir, fileName, excludes, secret, taskID string) error {
|
func handleAppBackup(install *model.AppInstall, parentTask *task.Task, recordID uint, backupDir, fileName, excludes, secret, taskID string) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
backupTask *task.Task
|
backupTask *task.Task
|
||||||
|
|
@ -144,11 +135,20 @@ func handleAppBackup(install *model.AppInstall, parentTask *task.Task, backupDir
|
||||||
}
|
}
|
||||||
|
|
||||||
itemHandler := func() error { return doAppBackup(install, backupTask, backupDir, fileName, excludes, secret) }
|
itemHandler := func() error { return doAppBackup(install, backupTask, backupDir, fileName, excludes, secret) }
|
||||||
backupTask.AddSubTask(task.GetTaskName(install.Name, task.TaskBackup, task.TaskScopeApp), func(t *task.Task) error { return itemHandler() }, nil)
|
|
||||||
if parentTask != nil {
|
if parentTask != nil {
|
||||||
return itemHandler()
|
return itemHandler()
|
||||||
}
|
}
|
||||||
return backupTask.Execute()
|
|
||||||
|
backupTask.AddSubTaskWithOps(task.GetTaskName(install.Name, task.TaskBackup, task.TaskScopeApp), func(t *task.Task) error { return itemHandler() }, nil, 3, time.Hour)
|
||||||
|
go func() {
|
||||||
|
if err := backupTask.Execute(); err != nil {
|
||||||
|
backupRepo.UpdateRecordByMap(recordID, map[string]interface{}{"status": constant.StatusFailed, "message": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
backupRepo.UpdateRecordByMap(recordID, map[string]interface{}{"status": constant.StatusSuccess})
|
||||||
|
}()
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleAppRecover(install *model.AppInstall, parentTask *task.Task, recoverFile string, isRollback bool, secret, taskID string) error {
|
func handleAppRecover(install *model.AppInstall, parentTask *task.Task, recoverFile string, isRollback bool, secret, taskID string) error {
|
||||||
|
|
@ -170,7 +170,7 @@ func handleAppRecover(install *model.AppInstall, parentTask *task.Task, recoverF
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
if !isRollback {
|
if !isRollback {
|
||||||
rollbackFile = path.Join(global.Dir.TmpDir, fmt.Sprintf("app/%s_%s.tar.gz", install.Name, time.Now().Format(constant.DateTimeSlimLayout)))
|
rollbackFile = path.Join(global.Dir.TmpDir, fmt.Sprintf("app/%s_%s.tar.gz", install.Name, time.Now().Format(constant.DateTimeSlimLayout)))
|
||||||
if err := handleAppBackup(install, recoverTask, path.Dir(rollbackFile), path.Base(rollbackFile), "", "", taskID); err != nil {
|
if err := handleAppBackup(install, recoverTask, 0, path.Dir(rollbackFile), path.Base(rollbackFile), "", "", taskID); err != nil {
|
||||||
t.Log(fmt.Sprintf("backup app %s for rollback before recover failed, err: %v", install.Name, err))
|
t.Log(fmt.Sprintf("backup app %s for rollback before recover failed, err: %v", install.Name, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -324,12 +324,15 @@ func handleAppRecover(install *model.AppInstall, parentTask *task.Task, recoverF
|
||||||
_ = os.RemoveAll(rollbackFile)
|
_ = os.RemoveAll(rollbackFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recoverTask.AddSubTask(task.GetTaskName(install.Name, task.TaskRecover, task.TaskScopeApp), recoverApp, rollBackApp)
|
|
||||||
if parentTask != nil {
|
if parentTask != nil {
|
||||||
return recoverApp(parentTask)
|
return recoverApp(parentTask)
|
||||||
}
|
}
|
||||||
return recoverTask.Execute()
|
|
||||||
|
recoverTask.AddSubTask(task.GetTaskName(install.Name, task.TaskRecover, task.TaskScopeApp), recoverApp, rollBackApp)
|
||||||
|
go func() {
|
||||||
|
_ = recoverTask.Execute()
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doAppBackup(install *model.AppInstall, parentTask *task.Task, backupDir, fileName, excludes, secret string) error {
|
func doAppBackup(install *model.AppInstall, parentTask *task.Task, backupDir, fileName, excludes, secret string) error {
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,6 @@ func (u *BackupService) MysqlBackup(req dto.CommonBackup) error {
|
||||||
targetDir := path.Join(global.Dir.LocalBackupDir, itemDir)
|
targetDir := path.Join(global.Dir.LocalBackupDir, itemDir)
|
||||||
fileName := fmt.Sprintf("%s_%s.sql.gz", req.DetailName, timeNow+common.RandStrAndNum(5))
|
fileName := fmt.Sprintf("%s_%s.sql.gz", req.DetailName, timeNow+common.RandStrAndNum(5))
|
||||||
|
|
||||||
databaseHelper := DatabaseHelper{Database: req.Name, DBType: req.Type, Name: req.DetailName}
|
|
||||||
if err := handleMysqlBackup(databaseHelper, nil, targetDir, fileName, req.TaskID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
record := &model.BackupRecord{
|
record := &model.BackupRecord{
|
||||||
Type: req.Type,
|
Type: req.Type,
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
|
|
@ -43,19 +38,25 @@ func (u *BackupService) MysqlBackup(req dto.CommonBackup) error {
|
||||||
DownloadAccountID: 1,
|
DownloadAccountID: 1,
|
||||||
FileDir: itemDir,
|
FileDir: itemDir,
|
||||||
FileName: fileName,
|
FileName: fileName,
|
||||||
|
TaskID: req.TaskID,
|
||||||
|
Status: constant.StatusWaiting,
|
||||||
Description: req.Description,
|
Description: req.Description,
|
||||||
}
|
}
|
||||||
if err := backupRepo.CreateRecord(record); err != nil {
|
if err := backupRepo.CreateRecord(record); err != nil {
|
||||||
global.LOG.Errorf("save backup record failed, err: %v", err)
|
global.LOG.Errorf("save backup record failed, err: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
databaseHelper := DatabaseHelper{Database: req.Name, DBType: req.Type, Name: req.DetailName}
|
||||||
|
if err := handleMysqlBackup(databaseHelper, nil, record.ID, targetDir, fileName, req.TaskID); err != nil {
|
||||||
|
backupRepo.UpdateRecordByMap(record.ID, map[string]interface{}{"status": constant.StatusFailed, "message": err.Error()})
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *BackupService) MysqlRecover(req dto.CommonRecover) error {
|
func (u *BackupService) MysqlRecover(req dto.CommonRecover) error {
|
||||||
if err := handleMysqlRecover(req, nil, false, req.TaskID); err != nil {
|
return handleMysqlRecover(req, nil, false, req.TaskID)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *BackupService) MysqlRecoverByUpload(req dto.CommonRecover) error {
|
func (u *BackupService) MysqlRecoverByUpload(req dto.CommonRecover) error {
|
||||||
|
|
@ -64,14 +65,14 @@ func (u *BackupService) MysqlRecoverByUpload(req dto.CommonRecover) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
req.File = recoveFile
|
req.File = recoveFile
|
||||||
|
|
||||||
if err := handleMysqlRecover(req, nil, false, req.TaskID); err != nil {
|
if err := handleMysqlRecover(req, nil, false, req.TaskID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
global.LOG.Info("recover from uploads successful!")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMysqlBackup(db DatabaseHelper, parentTask *task.Task, targetDir, fileName, taskID string) error {
|
func handleMysqlBackup(db DatabaseHelper, parentTask *task.Task, recordID uint, targetDir, fileName, taskID string) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
backupTask *task.Task
|
backupTask *task.Task
|
||||||
|
|
@ -90,11 +91,18 @@ func handleMysqlBackup(db DatabaseHelper, parentTask *task.Task, targetDir, file
|
||||||
}
|
}
|
||||||
|
|
||||||
itemHandler := func() error { return doMysqlBackup(db, targetDir, fileName) }
|
itemHandler := func() error { return doMysqlBackup(db, targetDir, fileName) }
|
||||||
backupTask.AddSubTask(task.GetTaskName(itemName, task.TaskBackup, task.TaskScopeDatabase), func(t *task.Task) error { return itemHandler() }, nil)
|
|
||||||
if parentTask != nil {
|
if parentTask != nil {
|
||||||
return itemHandler()
|
return itemHandler()
|
||||||
}
|
}
|
||||||
return backupTask.Execute()
|
backupTask.AddSubTaskWithOps(task.GetTaskName(itemName, task.TaskBackup, task.TaskScopeDatabase), func(t *task.Task) error { return itemHandler() }, nil, 3, time.Hour)
|
||||||
|
go func() {
|
||||||
|
if err := backupTask.Execute(); err != nil {
|
||||||
|
backupRepo.UpdateRecordByMap(recordID, map[string]interface{}{"status": constant.StatusFailed, "message": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
backupRepo.UpdateRecordByMap(recordID, map[string]interface{}{"status": constant.StatusSuccess})
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMysqlRecover(req dto.CommonRecover, parentTask *task.Task, isRollback bool, taskID string) error {
|
func handleMysqlRecover(req dto.CommonRecover, parentTask *task.Task, isRollback bool, taskID string) error {
|
||||||
|
|
@ -139,8 +147,6 @@ func handleMysqlRecover(req dto.CommonRecover, parentTask *task.Task, isRollback
|
||||||
Format: dbInfo.Format,
|
Format: dbInfo.Format,
|
||||||
TargetDir: path.Dir(rollbackFile),
|
TargetDir: path.Dir(rollbackFile),
|
||||||
FileName: path.Base(rollbackFile),
|
FileName: path.Base(rollbackFile),
|
||||||
|
|
||||||
Timeout: 300,
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("backup mysql db %s for rollback before recover failed, err: %v", req.DetailName, err)
|
return fmt.Errorf("backup mysql db %s for rollback before recover failed, err: %v", req.DetailName, err)
|
||||||
}
|
}
|
||||||
|
|
@ -153,8 +159,6 @@ func handleMysqlRecover(req dto.CommonRecover, parentTask *task.Task, isRollback
|
||||||
Version: version,
|
Version: version,
|
||||||
Format: dbInfo.Format,
|
Format: dbInfo.Format,
|
||||||
SourceFile: rollbackFile,
|
SourceFile: rollbackFile,
|
||||||
|
|
||||||
Timeout: 300,
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
global.LOG.Errorf("rollback mysql db %s from %s failed, err: %v", req.DetailName, rollbackFile, err)
|
global.LOG.Errorf("rollback mysql db %s from %s failed, err: %v", req.DetailName, rollbackFile, err)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -172,8 +176,6 @@ func handleMysqlRecover(req dto.CommonRecover, parentTask *task.Task, isRollback
|
||||||
Version: version,
|
Version: version,
|
||||||
Format: dbInfo.Format,
|
Format: dbInfo.Format,
|
||||||
SourceFile: req.File,
|
SourceFile: req.File,
|
||||||
|
|
||||||
Timeout: 300,
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
global.LOG.Errorf("recover mysql db %s from %s failed, err: %v", req.DetailName, req.File, err)
|
global.LOG.Errorf("recover mysql db %s from %s failed, err: %v", req.DetailName, req.File, err)
|
||||||
return err
|
return err
|
||||||
|
|
@ -181,12 +183,15 @@ func handleMysqlRecover(req dto.CommonRecover, parentTask *task.Task, isRollback
|
||||||
isOk = true
|
isOk = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
itemTask.AddSubTask(i18n.GetMsgByKey("TaskRecover"), recoverDatabase, nil)
|
|
||||||
if parentTask != nil {
|
if parentTask != nil {
|
||||||
return recoverDatabase(parentTask)
|
return recoverDatabase(parentTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
return itemTask.Execute()
|
itemTask.AddSubTaskWithOps(i18n.GetMsgByKey("TaskRecover"), recoverDatabase, nil, 3, time.Hour)
|
||||||
|
go func() {
|
||||||
|
_ = itemTask.Execute()
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doMysqlBackup(db DatabaseHelper, targetDir, fileName string) error {
|
func doMysqlBackup(db DatabaseHelper, targetDir, fileName string) error {
|
||||||
|
|
@ -205,8 +210,6 @@ func doMysqlBackup(db DatabaseHelper, targetDir, fileName string) error {
|
||||||
Format: dbInfo.Format,
|
Format: dbInfo.Format,
|
||||||
TargetDir: targetDir,
|
TargetDir: targetDir,
|
||||||
FileName: fileName,
|
FileName: fileName,
|
||||||
|
|
||||||
Timeout: 300,
|
|
||||||
}
|
}
|
||||||
return cli.Backup(backupInfo)
|
return cli.Backup(backupInfo)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,6 @@ func (u *BackupService) PostgresqlBackup(req dto.CommonBackup) error {
|
||||||
targetDir := path.Join(global.Dir.LocalBackupDir, itemDir)
|
targetDir := path.Join(global.Dir.LocalBackupDir, itemDir)
|
||||||
fileName := fmt.Sprintf("%s_%s.sql.gz", req.DetailName, timeNow+common.RandStrAndNum(5))
|
fileName := fmt.Sprintf("%s_%s.sql.gz", req.DetailName, timeNow+common.RandStrAndNum(5))
|
||||||
|
|
||||||
databaseHelper := DatabaseHelper{Database: req.Name, DBType: req.Type, Name: req.DetailName}
|
|
||||||
if err := handlePostgresqlBackup(databaseHelper, nil, targetDir, fileName, req.TaskID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
record := &model.BackupRecord{
|
record := &model.BackupRecord{
|
||||||
Type: req.Type,
|
Type: req.Type,
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
|
|
@ -42,11 +37,18 @@ func (u *BackupService) PostgresqlBackup(req dto.CommonBackup) error {
|
||||||
DownloadAccountID: 1,
|
DownloadAccountID: 1,
|
||||||
FileDir: itemDir,
|
FileDir: itemDir,
|
||||||
FileName: fileName,
|
FileName: fileName,
|
||||||
|
TaskID: req.TaskID,
|
||||||
|
Status: constant.StatusWaiting,
|
||||||
Description: req.Description,
|
Description: req.Description,
|
||||||
}
|
}
|
||||||
if err := backupRepo.CreateRecord(record); err != nil {
|
if err := backupRepo.CreateRecord(record); err != nil {
|
||||||
global.LOG.Errorf("save backup record failed, err: %v", err)
|
global.LOG.Errorf("save backup record failed, err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
databaseHelper := DatabaseHelper{Database: req.Name, DBType: req.Type, Name: req.DetailName}
|
||||||
|
if err := handlePostgresqlBackup(databaseHelper, nil, record.ID, targetDir, fileName, req.TaskID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (u *BackupService) PostgresqlRecover(req dto.CommonRecover) error {
|
func (u *BackupService) PostgresqlRecover(req dto.CommonRecover) error {
|
||||||
|
|
@ -69,7 +71,7 @@ func (u *BackupService) PostgresqlRecoverByUpload(req dto.CommonRecover) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlePostgresqlBackup(db DatabaseHelper, parentTask *task.Task, targetDir, fileName, taskID string) error {
|
func handlePostgresqlBackup(db DatabaseHelper, parentTask *task.Task, recordID uint, targetDir, fileName, taskID string) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
backupTask *task.Task
|
backupTask *task.Task
|
||||||
|
|
@ -84,11 +86,18 @@ func handlePostgresqlBackup(db DatabaseHelper, parentTask *task.Task, targetDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
itemHandler := func() error { return doPostgresqlgBackup(db, targetDir, fileName) }
|
itemHandler := func() error { return doPostgresqlgBackup(db, targetDir, fileName) }
|
||||||
backupTask.AddSubTask(task.GetTaskName(itemName, task.TaskBackup, task.TaskScopeDatabase), func(task *task.Task) error { return itemHandler() }, nil)
|
|
||||||
if parentTask != nil {
|
if parentTask != nil {
|
||||||
return itemHandler()
|
return itemHandler()
|
||||||
}
|
}
|
||||||
return backupTask.Execute()
|
backupTask.AddSubTaskWithOps(task.GetTaskName(itemName, task.TaskBackup, task.TaskScopeDatabase), func(t *task.Task) error { return itemHandler() }, nil, 3, time.Hour)
|
||||||
|
go func() {
|
||||||
|
if err := backupTask.Execute(); err != nil {
|
||||||
|
backupRepo.UpdateRecordByMap(recordID, map[string]interface{}{"status": constant.StatusFailed, "message": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
backupRepo.UpdateRecordByMap(recordID, map[string]interface{}{"status": constant.StatusSuccess})
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlePostgresqlRecover(req dto.CommonRecover, parentTask *task.Task, isRollback bool) error {
|
func handlePostgresqlRecover(req dto.CommonRecover, parentTask *task.Task, isRollback bool) error {
|
||||||
|
|
@ -163,12 +172,15 @@ func handlePostgresqlRecover(req dto.CommonRecover, parentTask *task.Task, isRol
|
||||||
isOk = true
|
isOk = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
itemTask.AddSubTask(i18n.GetMsgByKey("TaskRecover"), recoverDatabase, nil)
|
|
||||||
if parentTask != nil {
|
if parentTask != nil {
|
||||||
return recoverDatabase(parentTask)
|
return recoverDatabase(parentTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
return itemTask.Execute()
|
itemTask.AddSubTaskWithOps(i18n.GetMsgByKey("TaskRecover"), recoverDatabase, nil, 3, time.Hour)
|
||||||
|
go func() {
|
||||||
|
_ = itemTask.Execute()
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doPostgresqlgBackup(db DatabaseHelper, targetDir, fileName string) error {
|
func doPostgresqlgBackup(db DatabaseHelper, targetDir, fileName string) error {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||||
"github.com/1Panel-dev/1Panel/agent/global"
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
)
|
)
|
||||||
|
|
@ -239,6 +240,9 @@ func (u *BackupRecordService) LoadRecordSize(req dto.SearchForSize) ([]dto.Recor
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, item := range records {
|
for _, item := range records {
|
||||||
|
if item.Status == constant.StatusWaiting {
|
||||||
|
continue
|
||||||
|
}
|
||||||
list = append(list, backupSizeHelper{ID: item.ID, DownloadID: item.DownloadAccountID, FilePath: path.Join(item.FileDir, item.FileName)})
|
list = append(list, backupSizeHelper{ID: item.ID, DownloadID: item.DownloadAccountID, FilePath: path.Join(item.FileDir, item.FileName)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,22 +44,24 @@ func (u *BackupService) RedisBackup(req dto.CommonBackup) error {
|
||||||
}
|
}
|
||||||
itemDir := fmt.Sprintf("database/redis/%s", redisInfo.Name)
|
itemDir := fmt.Sprintf("database/redis/%s", redisInfo.Name)
|
||||||
backupDir := path.Join(global.Dir.LocalBackupDir, itemDir)
|
backupDir := path.Join(global.Dir.LocalBackupDir, itemDir)
|
||||||
if err := handleRedisBackup(redisInfo, nil, backupDir, fileName, req.Secret, req.TaskID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
record := &model.BackupRecord{
|
record := &model.BackupRecord{
|
||||||
Type: "redis",
|
Type: req.Type,
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
SourceAccountIDs: "1",
|
SourceAccountIDs: "1",
|
||||||
DownloadAccountID: 1,
|
DownloadAccountID: 1,
|
||||||
FileDir: itemDir,
|
FileDir: itemDir,
|
||||||
FileName: fileName,
|
FileName: fileName,
|
||||||
|
TaskID: req.TaskID,
|
||||||
|
Status: constant.StatusWaiting,
|
||||||
Description: req.Description,
|
Description: req.Description,
|
||||||
}
|
}
|
||||||
if err := backupRepo.CreateRecord(record); err != nil {
|
if err := backupRepo.CreateRecord(record); err != nil {
|
||||||
global.LOG.Errorf("save backup record failed, err: %v", err)
|
global.LOG.Errorf("save backup record failed, err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := handleRedisBackup(redisInfo, nil, record.ID, backupDir, fileName, req.Secret, req.TaskID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,8 +77,7 @@ func (u *BackupService) RedisRecover(req dto.CommonRecover) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleRedisBackup(redisInfo *repo.RootInfo, parentTask *task.Task, backupDir, fileName, secret, taskID string) error {
|
func handleRedisBackup(redisInfo *repo.RootInfo, parentTask *task.Task, recordID uint, backupDir, fileName, secret, taskID string) error {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
itemTask *task.Task
|
itemTask *task.Task
|
||||||
|
|
@ -128,6 +129,14 @@ func handleRedisBackup(redisInfo *repo.RootInfo, parentTask *task.Task, backupDi
|
||||||
return backupDatabase(parentTask)
|
return backupDatabase(parentTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
itemTask.AddSubTaskWithOps(i18n.GetMsgByKey("TaskBackup"), backupDatabase, nil, 3, time.Hour)
|
||||||
|
go func() {
|
||||||
|
if err := itemTask.Execute(); err != nil {
|
||||||
|
backupRepo.UpdateRecordByMap(recordID, map[string]interface{}{"status": constant.StatusFailed, "message": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
backupRepo.UpdateRecordByMap(recordID, map[string]interface{}{"status": constant.StatusSuccess})
|
||||||
|
}()
|
||||||
return itemTask.Execute()
|
return itemTask.Execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -180,7 +189,7 @@ func handleRedisRecover(redisInfo *repo.RootInfo, parentTask *task.Task, recover
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rollbackFile := path.Join(global.Dir.TmpDir, fmt.Sprintf("database/redis/%s_%s.%s", redisInfo.Name, time.Now().Format(constant.DateTimeSlimLayout), suffix))
|
rollbackFile := path.Join(global.Dir.TmpDir, fmt.Sprintf("database/redis/%s_%s.%s", redisInfo.Name, time.Now().Format(constant.DateTimeSlimLayout), suffix))
|
||||||
if err := handleRedisBackup(redisInfo, nil, path.Dir(rollbackFile), path.Base(rollbackFile), secret, ""); err != nil {
|
if err := handleRedisBackup(redisInfo, nil, 0, path.Dir(rollbackFile), path.Base(rollbackFile), secret, ""); err != nil {
|
||||||
return fmt.Errorf("backup database %s for rollback before recover failed, err: %v", redisInfo.Name, err)
|
return fmt.Errorf("backup database %s for rollback before recover failed, err: %v", redisInfo.Name, err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|
@ -230,5 +239,8 @@ func handleRedisRecover(redisInfo *repo.RootInfo, parentTask *task.Task, recover
|
||||||
return recoverDatabase(parentTask)
|
return recoverDatabase(parentTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
return itemTask.Execute()
|
go func() {
|
||||||
|
_ = itemTask.Execute()
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,26 +38,26 @@ func (u *BackupService) WebsiteBackup(req dto.CommonBackup) error {
|
||||||
backupDir := path.Join(global.Dir.LocalBackupDir, itemDir)
|
backupDir := path.Join(global.Dir.LocalBackupDir, itemDir)
|
||||||
fileName := fmt.Sprintf("%s_%s.tar.gz", website.Alias, timeNow+common.RandStrAndNum(5))
|
fileName := fmt.Sprintf("%s_%s.tar.gz", website.Alias, timeNow+common.RandStrAndNum(5))
|
||||||
|
|
||||||
go func() {
|
record := &model.BackupRecord{
|
||||||
if err = handleWebsiteBackup(&website, nil, backupDir, fileName, "", req.Secret, req.TaskID); err != nil {
|
Type: "website",
|
||||||
global.LOG.Errorf("backup website %s failed, err: %v", website.Alias, err)
|
Name: website.Alias,
|
||||||
return
|
DetailName: website.Alias,
|
||||||
}
|
SourceAccountIDs: "1",
|
||||||
record := &model.BackupRecord{
|
DownloadAccountID: 1,
|
||||||
Type: "website",
|
FileDir: itemDir,
|
||||||
Name: website.Alias,
|
FileName: fileName,
|
||||||
DetailName: website.Alias,
|
TaskID: req.TaskID,
|
||||||
SourceAccountIDs: "1",
|
Status: constant.StatusWaiting,
|
||||||
DownloadAccountID: 1,
|
Description: req.Description,
|
||||||
FileDir: itemDir,
|
}
|
||||||
FileName: fileName,
|
if err = backupRepo.CreateRecord(record); err != nil {
|
||||||
Description: req.Description,
|
global.LOG.Errorf("save backup record failed, err: %v", err)
|
||||||
}
|
return err
|
||||||
if err = backupRepo.CreateRecord(record); err != nil {
|
}
|
||||||
global.LOG.Errorf("save backup record failed, err: %v", err)
|
if err = handleWebsiteBackup(&website, nil, record.ID, backupDir, fileName, "", req.Secret, req.TaskID); err != nil {
|
||||||
return
|
global.LOG.Errorf("backup website %s failed, err: %v", website.Alias, err)
|
||||||
}
|
return err
|
||||||
}()
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,11 +66,9 @@ func (u *BackupService) WebsiteRecover(req dto.CommonRecover) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
go func() {
|
if err := handleWebsiteRecover(&website, req.File, false, req.Secret, req.TaskID); err != nil {
|
||||||
if err := handleWebsiteRecover(&website, req.File, false, req.Secret, req.TaskID); err != nil {
|
global.LOG.Errorf("recover website %s failed, err: %v", website.Alias, err)
|
||||||
global.LOG.Errorf("recover website %s failed, err: %v", website.Alias, err)
|
}
|
||||||
}
|
|
||||||
}()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +81,7 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
||||||
isOk := false
|
isOk := false
|
||||||
if !isRollback {
|
if !isRollback {
|
||||||
rollbackFile := path.Join(global.Dir.TmpDir, fmt.Sprintf("website/%s_%s.tar.gz", website.Alias, time.Now().Format(constant.DateTimeSlimLayout)))
|
rollbackFile := path.Join(global.Dir.TmpDir, fmt.Sprintf("website/%s_%s.tar.gz", website.Alias, time.Now().Format(constant.DateTimeSlimLayout)))
|
||||||
if err := handleWebsiteBackup(website, recoverTask, path.Dir(rollbackFile), path.Base(rollbackFile), "", "", taskID); err != nil {
|
if err := handleWebsiteBackup(website, recoverTask, 0, path.Dir(rollbackFile), path.Base(rollbackFile), "", "", taskID); err != nil {
|
||||||
return fmt.Errorf("backup website %s for rollback before recover failed, err: %v", website.Alias, err)
|
return fmt.Errorf("backup website %s for rollback before recover failed, err: %v", website.Alias, err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|
@ -200,10 +198,14 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
||||||
isOk = true
|
isOk = true
|
||||||
return nil
|
return nil
|
||||||
}, nil)
|
}, nil)
|
||||||
return recoverTask.Execute()
|
|
||||||
|
go func() {
|
||||||
|
_ = recoverTask.Execute()
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleWebsiteBackup(website *model.Website, parentTask *task.Task, backupDir, fileName, excludes, secret, taskID string) error {
|
func handleWebsiteBackup(website *model.Website, parentTask *task.Task, recordID uint, backupDir, fileName, excludes, secret, taskID string) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
backupTask *task.Task
|
backupTask *task.Task
|
||||||
|
|
@ -216,11 +218,18 @@ func handleWebsiteBackup(website *model.Website, parentTask *task.Task, backupDi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
itemHandler := func() error { return doWebsiteBackup(website, backupTask, backupDir, fileName, excludes, secret) }
|
itemHandler := func() error { return doWebsiteBackup(website, backupTask, backupDir, fileName, excludes, secret) }
|
||||||
backupTask.AddSubTask(task.GetTaskName(website.Alias, task.TaskBackup, task.TaskScopeWebsite), func(t *task.Task) error { return itemHandler() }, nil)
|
|
||||||
if parentTask != nil {
|
if parentTask != nil {
|
||||||
return itemHandler()
|
return itemHandler()
|
||||||
}
|
}
|
||||||
return backupTask.Execute()
|
backupTask.AddSubTaskWithOps(task.GetTaskName(website.Alias, task.TaskBackup, task.TaskScopeWebsite), func(t *task.Task) error { return itemHandler() }, nil, 3, time.Hour)
|
||||||
|
go func() {
|
||||||
|
if err := backupTask.Execute(); err != nil {
|
||||||
|
backupRepo.UpdateRecordByMap(recordID, map[string]interface{}{"status": constant.StatusFailed, "message": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
backupRepo.UpdateRecordByMap(recordID, map[string]interface{}{"status": constant.StatusSuccess})
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doWebsiteBackup(website *model.Website, parentTask *task.Task, backupDir, fileName, excludes, secret string) error {
|
func doWebsiteBackup(website *model.Website, parentTask *task.Task, backupDir, fileName, excludes, secret string) error {
|
||||||
|
|
@ -252,7 +261,7 @@ func doWebsiteBackup(website *model.Website, parentTask *task.Task, backupDir, f
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
parentTask.LogStart(task.GetTaskName(app.Name, task.TaskBackup, task.TaskScopeApp))
|
parentTask.LogStart(task.GetTaskName(app.Name, task.TaskBackup, task.TaskScopeApp))
|
||||||
if err = handleAppBackup(&app, parentTask, tmpDir, fmt.Sprintf("%s.app.tar.gz", website.Alias), excludes, "", ""); err != nil {
|
if err = handleAppBackup(&app, parentTask, 0, tmpDir, fmt.Sprintf("%s.app.tar.gz", website.Alias), excludes, "", ""); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
parentTask.LogSuccess(task.GetTaskName(app.Name, task.TaskBackup, task.TaskScopeApp))
|
parentTask.LogSuccess(task.GetTaskName(app.Name, task.TaskBackup, task.TaskScopeApp))
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ const (
|
||||||
TypeImagePush = "image-push"
|
TypeImagePush = "image-push"
|
||||||
TypeImageBuild = "image-build"
|
TypeImageBuild = "image-build"
|
||||||
TypeComposeCreate = "compose-create"
|
TypeComposeCreate = "compose-create"
|
||||||
|
|
||||||
|
InterruptedMsg = "the task was interrupted due to the restart of the 1panel service"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ func Init() {
|
||||||
initGlobalData()
|
initGlobalData()
|
||||||
handleCronjobStatus()
|
handleCronjobStatus()
|
||||||
handleClamStatus()
|
handleClamStatus()
|
||||||
|
handleRecordStatus()
|
||||||
handleSnapStatus()
|
handleSnapStatus()
|
||||||
handleOllamaModelStatus()
|
handleOllamaModelStatus()
|
||||||
|
|
||||||
|
|
@ -44,26 +45,25 @@ func initGlobalData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSnapStatus() {
|
func handleSnapStatus() {
|
||||||
msgFailed := "the task was interrupted due to the restart of the 1panel service"
|
|
||||||
_ = global.DB.Model(&model.Snapshot{}).Where("status = ?", "OnSaveData").
|
_ = global.DB.Model(&model.Snapshot{}).Where("status = ?", "OnSaveData").
|
||||||
Updates(map[string]interface{}{"status": constant.StatusSuccess}).Error
|
Updates(map[string]interface{}{"status": constant.StatusSuccess}).Error
|
||||||
|
|
||||||
_ = global.DB.Model(&model.Snapshot{}).Where("status = ?", constant.StatusWaiting).
|
_ = global.DB.Model(&model.Snapshot{}).Where("status = ?", constant.StatusWaiting).
|
||||||
Updates(map[string]interface{}{
|
Updates(map[string]interface{}{
|
||||||
"status": constant.StatusFailed,
|
"status": constant.StatusFailed,
|
||||||
"message": msgFailed,
|
"message": constant.InterruptedMsg,
|
||||||
}).Error
|
}).Error
|
||||||
|
|
||||||
_ = global.DB.Model(&model.Snapshot{}).Where("recover_status = ?", constant.StatusWaiting).
|
_ = global.DB.Model(&model.Snapshot{}).Where("recover_status = ?", constant.StatusWaiting).
|
||||||
Updates(map[string]interface{}{
|
Updates(map[string]interface{}{
|
||||||
"recover_status": constant.StatusFailed,
|
"recover_status": constant.StatusFailed,
|
||||||
"recover_message": msgFailed,
|
"recover_message": constant.InterruptedMsg,
|
||||||
}).Error
|
}).Error
|
||||||
|
|
||||||
_ = global.DB.Model(&model.Snapshot{}).Where("rollback_status = ?", constant.StatusWaiting).
|
_ = global.DB.Model(&model.Snapshot{}).Where("rollback_status = ?", constant.StatusWaiting).
|
||||||
Updates(map[string]interface{}{
|
Updates(map[string]interface{}{
|
||||||
"rollback_status": constant.StatusFailed,
|
"rollback_status": constant.StatusFailed,
|
||||||
"rollback_message": msgFailed,
|
"rollback_message": constant.InterruptedMsg,
|
||||||
}).Error
|
}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +75,7 @@ func handleCronjobStatus() {
|
||||||
err := global.DB.Model(&model.JobRecords{}).Where("status = ?", constant.StatusWaiting).
|
err := global.DB.Model(&model.JobRecords{}).Where("status = ?", constant.StatusWaiting).
|
||||||
Updates(map[string]interface{}{
|
Updates(map[string]interface{}{
|
||||||
"status": constant.StatusFailed,
|
"status": constant.StatusFailed,
|
||||||
"message": "the task was interrupted due to the restart of the 1panel service",
|
"message": constant.InterruptedMsg,
|
||||||
}).Error
|
}).Error
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -90,26 +90,25 @@ func handleCronjobStatus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleClamStatus() {
|
func handleClamStatus() {
|
||||||
var jobRecords []model.ClamRecord
|
|
||||||
_ = global.DB.Model(&model.Clam{}).Where("is_executing = ?", true).Updates(map[string]interface{}{"is_executing": false}).Error
|
_ = global.DB.Model(&model.Clam{}).Where("is_executing = ?", true).Updates(map[string]interface{}{"is_executing": false}).Error
|
||||||
_ = global.DB.Where("status = ?", constant.StatusWaiting).Find(&jobRecords).Error
|
_ = global.DB.Model(&model.ClamRecord{}).Where("status = ?", constant.StatusWaiting).Updates(map[string]interface{}{
|
||||||
for _, record := range jobRecords {
|
"status": constant.StatusFailed,
|
||||||
err := global.DB.Model(&model.ClamRecord{}).Where("status = ?", constant.StatusWaiting).
|
"message": constant.InterruptedMsg,
|
||||||
Updates(map[string]interface{}{
|
}).Error
|
||||||
"status": constant.StatusFailed,
|
}
|
||||||
"message": "the task was interrupted due to the restart of the 1panel service",
|
|
||||||
}).Error
|
|
||||||
|
|
||||||
if err != nil {
|
func handleRecordStatus() {
|
||||||
global.LOG.Errorf("Failed to update job ID: %v, Error:%v", record.ID, err)
|
_ = global.DB.Model(&model.BackupRecord{}).Where("status = ?", constant.StatusWaiting).Updates(map[string]interface{}{
|
||||||
continue
|
"status": constant.StatusFailed,
|
||||||
}
|
"message": constant.InterruptedMsg,
|
||||||
}
|
}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleOllamaModelStatus() {
|
func handleOllamaModelStatus() {
|
||||||
message := "the task was interrupted due to the restart of the 1panel service"
|
_ = global.DB.Model(&model.OllamaModel{}).Where("status = ?", constant.StatusWaiting).Updates(map[string]interface{}{
|
||||||
_ = global.DB.Model(&model.OllamaModel{}).Where("status = ?", constant.StatusWaiting).Updates(map[string]interface{}{"status": constant.StatusCanceled, "message": message}).Error
|
"status": constant.StatusCanceled,
|
||||||
|
"message": constant.InterruptedMsg,
|
||||||
|
}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleCronJobAlert(cronjob *model.Cronjob) {
|
func handleCronJobAlert(cronjob *model.Cronjob) {
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ func InitAgentDB() {
|
||||||
migrations.UpdateMcpServerAddType,
|
migrations.UpdateMcpServerAddType,
|
||||||
migrations.InitLocalSSHConn,
|
migrations.InitLocalSSHConn,
|
||||||
migrations.InitLocalSSHShow,
|
migrations.InitLocalSSHShow,
|
||||||
|
migrations.InitRecordStatus,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
|
|
||||||
|
|
@ -563,3 +563,16 @@ var InitLocalSSHShow = &gormigrate.Migration{
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var InitRecordStatus = &gormigrate.Migration{
|
||||||
|
ID: "20250910-init-record-status",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
if err := tx.AutoMigrate(&model.BackupRecord{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tx.Model(&model.BackupRecord{}).Where("1 == 1").Updates(map[string]interface{}{"status": constant.StatusSuccess}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -235,9 +235,7 @@ func (r *Local) Backup(info BackupInfo) error {
|
||||||
}
|
}
|
||||||
global.LOG.Infof("start to %s | gzip > %s.gzip", dumpCmd, info.TargetDir+"/"+info.FileName)
|
global.LOG.Infof("start to %s | gzip > %s.gzip", dumpCmd, info.TargetDir+"/"+info.FileName)
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(info.Timeout*uint(time.Second)))
|
cmd := exec.Command("docker", "exec", r.ContainerName, dumpCmd, "--routines", "-uroot", "-p"+r.Password, "--default-character-set="+info.Format, info.Name)
|
||||||
defer cancel()
|
|
||||||
cmd := exec.CommandContext(ctx, "docker", "exec", r.ContainerName, dumpCmd, "--routines", "-uroot", "-p"+r.Password, "--default-character-set="+info.Format, info.Name)
|
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
cmd.Stderr = &stderr
|
cmd.Stderr = &stderr
|
||||||
|
|
||||||
|
|
@ -261,9 +259,7 @@ func (r *Local) Recover(info RecoverInfo) error {
|
||||||
mysqlCli = "mysql"
|
mysqlCli = "mysql"
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(info.Timeout*uint(time.Second)))
|
cmd := exec.Command("docker", "exec", "-i", r.ContainerName, mysqlCli, "-uroot", "-p"+r.Password, "--default-character-set="+info.Format, info.Name)
|
||||||
defer cancel()
|
|
||||||
cmd := exec.CommandContext(ctx, "docker", "exec", "-i", r.ContainerName, mysqlCli, "-uroot", "-p"+r.Password, "--default-character-set="+info.Format, info.Name)
|
|
||||||
if strings.HasSuffix(info.SourceFile, ".gz") {
|
if strings.HasSuffix(info.SourceFile, ".gz") {
|
||||||
gzipFile, err := os.Open(info.SourceFile)
|
gzipFile, err := os.Open(info.SourceFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -33,18 +33,32 @@
|
||||||
<el-button type="primary" plain :disabled="selects.length === 0" @click="onBatchDelete(null)">
|
<el-button type="primary" plain :disabled="selects.length === 0" @click="onBatchDelete(null)">
|
||||||
{{ $t('commons.button.delete') }}
|
{{ $t('commons.button.delete') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
<TableRefresh class="float-right" @search="search()" />
|
||||||
</template>
|
</template>
|
||||||
<el-table-column type="selection" fix />
|
<el-table-column type="selection" :selectable="selectable" fix />
|
||||||
<el-table-column :label="$t('commons.table.name')" prop="fileName" show-overflow-tooltip />
|
<el-table-column :label="$t('commons.table.name')" prop="fileName" show-overflow-tooltip />
|
||||||
<el-table-column :label="$t('file.size')" prop="size" show-overflow-tooltip>
|
<el-table-column min-width="80px" :label="$t('commons.table.status')" prop="status">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div v-if="row.hasLoad">
|
<Status
|
||||||
|
v-if="row.status === 'Waiting'"
|
||||||
|
:status="row.status"
|
||||||
|
@click="openTaskLog(row.taskID)"
|
||||||
|
:msg="row.message"
|
||||||
|
:operate="true"
|
||||||
|
/>
|
||||||
|
<Status v-else :status="row.status" :msg="row.message" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column min-width="80px" :label="$t('file.size')" prop="size" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div v-if="row.hasLoad && (row.status === 'Success' || row.status === 'Failed')">
|
||||||
<span v-if="row.size">
|
<span v-if="row.size">
|
||||||
{{ computeSize(row.size) }}
|
{{ computeSize(row.size) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!row.hasLoad">
|
<div v-else>
|
||||||
<el-button link loading></el-button>
|
<el-button link loading></el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -249,6 +263,10 @@ const openTaskLog = (taskID: string) => {
|
||||||
taskLogRef.value.openWithTaskID(taskID);
|
taskLogRef.value.openWithTaskID(taskID);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function selectable(row) {
|
||||||
|
return row.status !== 'Waiting';
|
||||||
|
}
|
||||||
|
|
||||||
const backup = async (close: boolean) => {
|
const backup = async (close: boolean) => {
|
||||||
const taskID = newUUID();
|
const taskID = newUUID();
|
||||||
let params = {
|
let params = {
|
||||||
|
|
@ -378,6 +396,9 @@ const onBatchDelete = async (row: Backup.RecordInfo | null) => {
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
label: i18n.global.t('commons.button.delete'),
|
label: i18n.global.t('commons.button.delete'),
|
||||||
|
disabled: (row: any) => {
|
||||||
|
return row.status === 'Waiting';
|
||||||
|
},
|
||||||
click: (row: Backup.RecordInfo) => {
|
click: (row: Backup.RecordInfo) => {
|
||||||
onBatchDelete(row);
|
onBatchDelete(row);
|
||||||
},
|
},
|
||||||
|
|
@ -385,7 +406,7 @@ const buttons = [
|
||||||
{
|
{
|
||||||
label: i18n.global.t('commons.button.recover'),
|
label: i18n.global.t('commons.button.recover'),
|
||||||
disabled: (row: any) => {
|
disabled: (row: any) => {
|
||||||
return row.size === 0;
|
return row.size === 0 || row.status === 'Failed';
|
||||||
},
|
},
|
||||||
click: (row: Backup.RecordInfo) => {
|
click: (row: Backup.RecordInfo) => {
|
||||||
onRecover(row);
|
onRecover(row);
|
||||||
|
|
@ -394,7 +415,7 @@ const buttons = [
|
||||||
{
|
{
|
||||||
label: i18n.global.t('commons.button.download'),
|
label: i18n.global.t('commons.button.download'),
|
||||||
disabled: (row: any) => {
|
disabled: (row: any) => {
|
||||||
return row.size === 0;
|
return row.size === 0 || row.status === 'Failed';
|
||||||
},
|
},
|
||||||
click: (row: Backup.RecordInfo) => {
|
click: (row: Backup.RecordInfo) => {
|
||||||
onDownload(row);
|
onDownload(row);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue