fix: Fix the issue of abnormal task logs when website restoration fails (#10609)

This commit is contained in:
ssongliu 2025-10-11 22:07:58 +08:00 committed by GitHub
parent 1f53b64b08
commit 7afe9ac878
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 58 additions and 43 deletions

View file

@ -308,6 +308,10 @@ func handleAppRecover(install *model.AppInstall, parentTask *task.Task, recoverF
return nil return nil
} }
if parentTask != nil {
return recoverApp(parentTask)
}
rollBackApp := func(t *task.Task) { rollBackApp := func(t *task.Task) {
if isRollback { if isRollback {
return return
@ -324,10 +328,6 @@ func handleAppRecover(install *model.AppInstall, parentTask *task.Task, recoverF
_ = os.RemoveAll(rollbackFile) _ = os.RemoveAll(rollbackFile)
} }
} }
if parentTask != nil {
return recoverApp(parentTask)
}
recoverTask.AddSubTask(task.GetTaskName(install.Name, task.TaskRecover, task.TaskScopeBackup), recoverApp, rollBackApp) recoverTask.AddSubTask(task.GetTaskName(install.Name, task.TaskRecover, task.TaskScopeBackup), recoverApp, rollBackApp)
go func() { go func() {
_ = recoverTask.Execute() _ = recoverTask.Execute()

View file

@ -66,38 +66,34 @@ func (u *BackupService) WebsiteRecover(req dto.CommonRecover) error {
if err != nil { if err != nil {
return err return err
} }
if err := handleWebsiteRecover(&website, req.File, false, req.Secret, req.TaskID); err != nil { if err := handleWebsiteRecover(&website, nil, 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
} }
func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback bool, secret, taskID string) error { func handleWebsiteRecover(website *model.Website, parentTask *task.Task, recoverFile string, isRollback bool, secret, taskID string) error {
recoverTask, err := task.NewTaskWithOps(website.PrimaryDomain, task.TaskRecover, task.TaskScopeBackup, taskID, website.ID) var (
if err != nil { err error
return err recoverTask *task.Task
isOk = false
rollbackFile string
)
recoverTask = parentTask
if parentTask == nil {
recoverTask, err = task.NewTaskWithOps(website.PrimaryDomain, task.TaskRecover, task.TaskScopeBackup, taskID, website.ID)
if err != nil {
return err
}
} }
recoverTask.AddSubTask(task.GetTaskName(website.PrimaryDomain, task.TaskRecover, task.TaskScopeBackup), func(t *task.Task) error { recoverWebsite := func(t *task.Task) error {
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, 0, 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() {
if !isOk {
t.LogStart(i18n.GetMsgByKey("Rollback"))
if err := handleWebsiteRecover(website, rollbackFile, true, "", taskID); err != nil {
t.LogFailedWithErr(i18n.GetMsgByKey("Rollback"), err)
return
}
t.LogSuccess(i18n.GetMsgByKey("Rollback"))
_ = os.RemoveAll(rollbackFile)
} else {
_ = os.RemoveAll(rollbackFile)
}
}()
} }
fileOp := files.NewFileOp() fileOp := files.NewFileOp()
tmpPath := strings.ReplaceAll(recoverFile, ".tar.gz", "") tmpPath := strings.ReplaceAll(recoverFile, ".tar.gz", "")
t.Log(i18n.GetWithName("DeCompressFile", recoverFile)) t.Log(i18n.GetWithName("DeCompressFile", recoverFile))
@ -149,12 +145,10 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
taskName := task.GetTaskName(app.Name, task.TaskRecover, task.TaskScopeApp) taskName := task.GetTaskName(app.Name, task.TaskRecover, task.TaskScopeApp)
t.LogStart(taskName) t.LogStart(taskName)
if err := handleAppRecover(&app, recoverTask, fmt.Sprintf("%s/%s.app.tar.gz", tmpPath, website.Alias), true, "", ""); err != nil { if err := handleAppRecover(&app, recoverTask, fmt.Sprintf("%s/%s.app.tar.gz", tmpPath, website.Alias), true, "", ""); err != nil {
t.LogFailedWithErr(taskName, err)
return err return err
} }
t.LogSuccess(taskName) t.LogSuccess(taskName)
if _, err = compose.DownAndUp(fmt.Sprintf("%s/%s/%s/docker-compose.yml", global.Dir.AppInstallDir, app.App.Key, app.Name)); err != nil { if _, err = compose.DownAndUp(fmt.Sprintf("%s/%s/%s/docker-compose.yml", global.Dir.AppInstallDir, app.App.Key, app.Name)); err != nil {
t.LogFailedWithErr("Run", err)
return err return err
} }
case constant.Runtime: case constant.Runtime:
@ -165,7 +159,6 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
taskName := task.GetTaskName(runtime.Name, task.TaskRecover, task.TaskScopeRuntime) taskName := task.GetTaskName(runtime.Name, task.TaskRecover, task.TaskScopeRuntime)
t.LogStart(taskName) t.LogStart(taskName)
if err := handleRuntimeRecover(runtime, fmt.Sprintf("%s/%s.runtime.tar.gz", tmpPath, website.Alias), true, ""); err != nil { if err := handleRuntimeRecover(runtime, fmt.Sprintf("%s/%s.runtime.tar.gz", tmpPath, website.Alias), true, ""); err != nil {
t.LogFailedWithErr(taskName, err)
return err return err
} }
t.LogSuccess(taskName) t.LogSuccess(taskName)
@ -184,7 +177,6 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
taskName := i18n.GetMsgByKey("TaskRecover") + i18n.GetMsgByKey("websiteDir") taskName := i18n.GetMsgByKey("TaskRecover") + i18n.GetMsgByKey("websiteDir")
t.Log(taskName) t.Log(taskName)
if err = fileOp.TarGzExtractPro(fmt.Sprintf("%s/%s.web.tar.gz", tmpPath, website.Alias), GetOpenrestyDir(SitesRootDir), ""); err != nil { if err = fileOp.TarGzExtractPro(fmt.Sprintf("%s/%s.web.tar.gz", tmpPath, website.Alias), GetOpenrestyDir(SitesRootDir), ""); err != nil {
t.LogFailedWithErr(taskName, err)
return err return err
} }
stdout, err := cmd.RunDefaultWithStdoutBashCf("docker exec -i %s nginx -s reload", nginxInfo.ContainerName) stdout, err := cmd.RunDefaultWithStdoutBashCf("docker exec -i %s nginx -s reload", nginxInfo.ContainerName)
@ -197,8 +189,29 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
} }
isOk = true isOk = true
return nil return nil
}, nil) }
if parentTask != nil {
return recoverWebsite(parentTask)
}
rollBackWebsite := func(t *task.Task) {
if isRollback {
return
}
if !isOk {
t.Log(i18n.GetMsgByKey("RecoverFailedStartRollBack"))
if err := handleWebsiteRecover(website, t, rollbackFile, true, "", ""); err != nil {
t.LogFailedWithErr(i18n.GetMsgByKey("Rollback"), err)
return
}
t.LogSuccess(i18n.GetMsgByKey("Rollback"))
_ = os.RemoveAll(rollbackFile)
} else {
_ = os.RemoveAll(rollbackFile)
}
}
recoverTask.AddSubTask(task.GetTaskName(website.PrimaryDomain, task.TaskRecover, task.TaskScopeBackup), recoverWebsite, rollBackWebsite)
go func() { go func() {
_ = recoverTask.Execute() _ = recoverTask.Execute()
}() }()

View file

@ -38,6 +38,7 @@ func (u *CronjobService) handleApp(cronjob model.Cronjob, startTime time.Time, t
retry := 0 retry := 0
taskItem.AddSubTaskWithOps(task.GetTaskName(app.Name, task.TaskBackup, task.TaskScopeCronjob), func(task *task.Task) error { taskItem.AddSubTaskWithOps(task.GetTaskName(app.Name, task.TaskBackup, task.TaskScopeCronjob), func(task *task.Task) error {
var record model.BackupRecord var record model.BackupRecord
record.Status = constant.StatusSuccess
record.From = "cronjob" record.From = "cronjob"
record.Type = "app" record.Type = "app"
record.CronjobID = cronjob.ID record.CronjobID = cronjob.ID
@ -95,6 +96,7 @@ func (u *CronjobService) handleWebsite(cronjob model.Cronjob, startTime time.Tim
retry := 0 retry := 0
taskItem.AddSubTaskWithOps(task.GetTaskName(web.Alias, task.TaskBackup, task.TaskScopeCronjob), func(task *task.Task) error { taskItem.AddSubTaskWithOps(task.GetTaskName(web.Alias, task.TaskBackup, task.TaskScopeCronjob), func(task *task.Task) error {
var record model.BackupRecord var record model.BackupRecord
record.Status = constant.StatusSuccess
record.From = "cronjob" record.From = "cronjob"
record.Type = "website" record.Type = "website"
record.CronjobID = cronjob.ID record.CronjobID = cronjob.ID
@ -154,6 +156,7 @@ func (u *CronjobService) handleDatabase(cronjob model.Cronjob, startTime time.Ti
itemName := fmt.Sprintf("%s[%s] - %s", dbInfo.Database, dbInfo.DBType, dbInfo.Name) itemName := fmt.Sprintf("%s[%s] - %s", dbInfo.Database, dbInfo.DBType, dbInfo.Name)
taskItem.AddSubTaskWithOps(task.GetTaskName(itemName, task.TaskBackup, task.TaskScopeCronjob), func(task *task.Task) error { taskItem.AddSubTaskWithOps(task.GetTaskName(itemName, task.TaskBackup, task.TaskScopeCronjob), func(task *task.Task) error {
var record model.BackupRecord var record model.BackupRecord
record.Status = constant.StatusSuccess
record.From = "cronjob" record.From = "cronjob"
record.Type = dbInfo.DBType record.Type = dbInfo.DBType
record.CronjobID = cronjob.ID record.CronjobID = cronjob.ID
@ -238,6 +241,7 @@ func (u *CronjobService) handleDirectory(cronjob model.Cronjob, startTime time.T
} }
} }
var record model.BackupRecord var record model.BackupRecord
record.Status = constant.StatusSuccess
record.From = "cronjob" record.From = "cronjob"
record.Type = "directory" record.Type = "directory"
record.CronjobID = cronjob.ID record.CronjobID = cronjob.ID
@ -273,6 +277,7 @@ func (u *CronjobService) handleSystemLog(cronjob model.Cronjob, startTime time.T
return err return err
} }
var record model.BackupRecord var record model.BackupRecord
record.Status = constant.StatusSuccess
record.From = "cronjob" record.From = "cronjob"
record.Type = "log" record.Type = "log"
record.CronjobID = cronjob.ID record.CronjobID = cronjob.ID
@ -301,6 +306,7 @@ func (u *CronjobService) handleSnapshot(cronjob model.Cronjob, jobRecord model.J
return errors.New(i18n.GetMsgWithDetail("LoadBackupFailed", accountMap[fmt.Sprintf("%d", cronjob.DownloadAccountID)].message)) return errors.New(i18n.GetMsgWithDetail("LoadBackupFailed", accountMap[fmt.Sprintf("%d", cronjob.DownloadAccountID)].message))
} }
var record model.BackupRecord var record model.BackupRecord
record.Status = constant.StatusSuccess
record.From = "cronjob" record.From = "cronjob"
record.Type = "snapshot" record.Type = "snapshot"
record.CronjobID = cronjob.ID record.CronjobID = cronjob.ID

View file

@ -218,6 +218,7 @@ func (u *CronjobService) handleCutWebsiteLog(cronjob *model.Cronjob, startTime t
for _, website := range websites { for _, website := range websites {
taskItem.Log(website.Alias) taskItem.Log(website.Alias)
var record model.BackupRecord var record model.BackupRecord
record.Status = constant.StatusSuccess
record.From = "cronjob" record.From = "cronjob"
record.Type = "cut-website-log" record.Type = "cut-website-log"
record.CronjobID = cronjob.ID record.CronjobID = cronjob.ID

View file

@ -90,7 +90,7 @@ const (
TaskScopeContainer = "Container" TaskScopeContainer = "Container"
TaskScopeCompose = "Compose" TaskScopeCompose = "Compose"
TaskScopeImage = "Image" TaskScopeImage = "Image"
TaskScopeBackup = "Backup " TaskScopeBackup = "Backup"
TaskScopeRuntimeExtension = "RuntimeExtension" TaskScopeRuntimeExtension = "RuntimeExtension"
TaskScopeCustomAppstore = "CustomAppstore" TaskScopeCustomAppstore = "CustomAppstore"
TaskScopeTamper = "Tamper" TaskScopeTamper = "Tamper"
@ -161,7 +161,9 @@ func ReNewTaskWithOps(resourceName, operate, scope, taskID string, resourceID ui
return ReNewTask(GetTaskName(resourceName, operate, scope), operate, scope, taskID, resourceID) return ReNewTask(GetTaskName(resourceName, operate, scope), operate, scope, taskID, resourceID)
} }
func ReNewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task, error) { func ReNewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task, error) {
if taskID == "" { taskRepo := repo.NewITaskRepo()
taskItem, _ := taskRepo.GetFirst(taskRepo.WithByID(taskID))
if taskItem.ID == "" {
return NewTask(name, operate, taskScope, taskID, resourceID) return NewTask(name, operate, taskScope, taskID, resourceID)
} }
logDir := path.Join(global.Dir.TaskDir, taskScope) logDir := path.Join(global.Dir.TaskDir, taskScope)
@ -177,17 +179,10 @@ func ReNewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task,
} }
writer := bufio.NewWriter(file) writer := bufio.NewWriter(file)
logger := log.New(file, "", log.LstdFlags) logger := log.New(file, "", log.LstdFlags)
taskModel := &model.Task{ logger.Print("\n --------------------------------------------------- \n")
ID: taskID, taskItem.Status = constant.StatusExecuting
Name: name, task := &Task{Name: name, logFile: file, Logger: logger, taskRepo: taskRepo, Task: &taskItem, Writer: writer}
Type: taskScope, task.updateTask(&taskItem)
LogFile: logPath,
Status: constant.StatusExecuting,
ResourceID: resourceID,
Operate: operate,
}
taskRepo := repo.NewITaskRepo()
task := &Task{Name: name, logFile: file, Logger: logger, taskRepo: taskRepo, Task: taskModel, Writer: writer}
return task, nil return task, nil
} }