diff --git a/backend/app/api/v1/backup.go b/backend/app/api/v1/backup.go index 54a78dc13..ae358bf92 100644 --- a/backend/app/api/v1/backup.go +++ b/backend/app/api/v1/backup.go @@ -323,7 +323,7 @@ func (b *BaseApi) Backup(c *gin.Context) { switch req.Type { case "app": - if err := backupService.AppBackup(req); err != nil { + if _, err := backupService.AppBackup(req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } diff --git a/backend/app/api/v1/file.go b/backend/app/api/v1/file.go index 88fb43e1b..1075df6ae 100644 --- a/backend/app/api/v1/file.go +++ b/backend/app/api/v1/file.go @@ -318,7 +318,7 @@ func (b *BaseApi) UploadFiles(c *gin.Context) { } dir := path.Dir(paths[0]) - info, err := os.Stat(dir) + _, err = os.Stat(dir) if err != nil && os.IsNotExist(err) { mode, err := files.GetParentMode(dir) if err != nil { @@ -330,7 +330,7 @@ func (b *BaseApi) UploadFiles(c *gin.Context) { return } } - info, err = os.Stat(dir) + info, err := os.Stat(dir) if err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return diff --git a/backend/app/service/app_utils.go b/backend/app/service/app_utils.go index d7e02ad8c..246e044ba 100644 --- a/backend/app/service/app_utils.go +++ b/backend/app/service/app_utils.go @@ -450,23 +450,40 @@ func upgradeInstall(installID uint, detailID uint, backup, pullImage bool) error install.Status = constant.Upgrading go func() { + var ( + upErr error + backupFile string + ) + global.LOG.Infof(i18n.GetMsgByKey("UpgradeAppStart")) if backup { - if err = NewIBackupService().AppBackup(dto.CommonBackup{Name: install.App.Key, DetailName: install.Name}); err != nil { - global.LOG.Errorf(i18n.GetMsgWithMap("ErrAppBackup", map[string]interface{}{"name": install.Name, "err": err.Error()})) + backupRecord, err := NewIBackupService().AppBackup(dto.CommonBackup{Name: install.App.Key, DetailName: install.Name}) + if err == nil { + localDir, err := loadLocalDir() + if err == nil { + backupFile = path.Join(localDir, backupRecord.FileDir, backupRecord.FileName) + } else { + global.LOG.Errorf(i18n.GetMsgWithName("ErrAppBackup", install.Name, err)) + } + } else { + global.LOG.Errorf(i18n.GetMsgWithName("ErrAppBackup", install.Name, err)) } } - var upErr error defer func() { if upErr != nil { + global.LOG.Infof(i18n.GetMsgWithName("ErrAppUpgrade", install.Name, upErr)) if backup { - if err := NewIBackupService().AppRecover(dto.CommonRecover{Name: install.App.Key, DetailName: install.Name, Type: "app", Source: constant.ResourceLocal}); err != nil { + global.LOG.Infof(i18n.GetMsgWithName("AppRecover", install.Name, nil)) + if err := NewIBackupService().AppRecover(dto.CommonRecover{Name: install.App.Key, DetailName: install.Name, Type: "app", Source: constant.ResourceLocal, File: backupFile}); err != nil { global.LOG.Errorf("recover app [%s] [%s] failed %v", install.App.Key, install.Name, err) } } - install.Status = constant.UpgradeErr - install.Message = upErr.Error() - _ = appInstallRepo.Save(context.Background(), &install) + existInstall, _ := appInstallRepo.GetFirst(commonRepo.WithByID(installID)) + if existInstall.ID > 0 { + existInstall.Status = constant.UpgradeErr + existInstall.Message = upErr.Error() + _ = appInstallRepo.Save(context.Background(), &existInstall) + } } }() @@ -546,13 +563,15 @@ func upgradeInstall(installID uint, detailID uint, backup, pullImage bool) error if upErr = addDockerComposeCommonParam(composeMap, install.ServiceName, config, envs); upErr != nil { return } - paramByte, upErr := json.Marshal(envs) - if upErr != nil { + paramByte, err := json.Marshal(envs) + if err != nil { + upErr = err return } install.Env = string(paramByte) - composeByte, upErr := yaml.Marshal(composeMap) - if upErr != nil { + composeByte, err := yaml.Marshal(composeMap) + if err != nil { + upErr = err return } @@ -560,23 +579,6 @@ func upgradeInstall(installID uint, detailID uint, backup, pullImage bool) error install.Version = detail.Version install.AppDetailId = detailID - if out, err := compose.Down(install.GetComposePath()); err != nil { - if out != "" { - upErr = errors.New(out) - return - } - return - } - envParams := make(map[string]string, len(envs)) - handleMap(envs, envParams) - if err = env.Write(envParams, install.GetEnvPath()); err != nil { - return - } - - if err = runScript(&install, "upgrade"); err != nil { - return - } - content, err := fileOp.GetContent(install.GetEnvPath()) if err != nil { upErr = err @@ -595,13 +597,34 @@ func upgradeInstall(installID uint, detailID uint, backup, pullImage bool) error return } for _, image := range images { + global.LOG.Infof(i18n.GetMsgWithName("PullImageStart", image, nil)) if err = dockerCli.PullImage(image, true); err != nil { upErr = buserr.WithNameAndErr("ErrDockerPullImage", "", err) return + } else { + global.LOG.Infof(i18n.GetMsgByKey("PullImageSuccess")) } } } + if out, err := compose.Down(install.GetComposePath()); err != nil { + if out != "" { + upErr = errors.New(out) + return + } + upErr = err + return + } + envParams := make(map[string]string, len(envs)) + handleMap(envs, envParams) + if upErr = env.Write(envParams, install.GetEnvPath()); upErr != nil { + return + } + + if upErr = runScript(&install, "upgrade"); upErr != nil { + return + } + if upErr = fileOp.WriteFile(install.GetComposePath(), strings.NewReader(install.DockerCompose), 0775); upErr != nil { return } @@ -615,6 +638,7 @@ func upgradeInstall(installID uint, detailID uint, backup, pullImage bool) error } install.Status = constant.Running _ = appInstallRepo.Save(context.Background(), &install) + global.LOG.Infof(i18n.GetMsgWithName("UpgradeAppSuccess", install.Name, nil)) }() return appInstallRepo.Save(context.Background(), &install) diff --git a/backend/app/service/backup.go b/backend/app/service/backup.go index 060421cc2..7a1a1f878 100644 --- a/backend/app/service/backup.go +++ b/backend/app/service/backup.go @@ -55,7 +55,7 @@ type IBackupService interface { WebsiteBackup(db dto.CommonBackup) error WebsiteRecover(req dto.CommonRecover) error - AppBackup(db dto.CommonBackup) error + AppBackup(db dto.CommonBackup) (*model.BackupRecord, error) AppRecover(req dto.CommonRecover) error Run() diff --git a/backend/app/service/backup_app.go b/backend/app/service/backup_app.go index 1b7941593..891f3ef60 100644 --- a/backend/app/service/backup_app.go +++ b/backend/app/service/backup_app.go @@ -22,18 +22,18 @@ import ( "github.com/pkg/errors" ) -func (u *BackupService) AppBackup(req dto.CommonBackup) error { +func (u *BackupService) AppBackup(req dto.CommonBackup) (*model.BackupRecord, error) { localDir, err := loadLocalDir() if err != nil { - return err + return nil, err } app, err := appRepo.GetFirst(appRepo.WithKey(req.Name)) if err != nil { - return err + return nil, err } install, err := appInstallRepo.GetFirst(commonRepo.WithByName(req.DetailName), appInstallRepo.WithAppId(app.ID)) if err != nil { - return err + return nil, err } timeNow := time.Now().Format("20060102150405") itemDir := fmt.Sprintf("app/%s/%s", req.Name, req.DetailName) @@ -41,7 +41,7 @@ func (u *BackupService) AppBackup(req dto.CommonBackup) error { fileName := fmt.Sprintf("%s_%s.tar.gz", req.DetailName, timeNow+common.RandStrAndNum(5)) if err := handleAppBackup(&install, backupDir, fileName); err != nil { - return err + return nil, err } record := &model.BackupRecord{ @@ -56,9 +56,9 @@ func (u *BackupService) AppBackup(req dto.CommonBackup) error { if err := backupRepo.CreateRecord(record); err != nil { global.LOG.Errorf("save backup record failed, err: %v", err) - return err + return nil, err } - return nil + return record, nil } func (u *BackupService) AppRecover(req dto.CommonRecover) error { diff --git a/backend/i18n/i18n.go b/backend/i18n/i18n.go index 0a42bf487..b1cc34468 100644 --- a/backend/i18n/i18n.go +++ b/backend/i18n/i18n.go @@ -31,6 +31,27 @@ func GetMsgWithMap(key string, maps map[string]interface{}) string { } } +func GetMsgWithName(key string, name string, err error) string { + var ( + content string + dataMap = make(map[string]interface{}) + ) + dataMap["name"] = name + if err != nil { + dataMap["err"] = err.Error() + } + content, _ = global.I18n.Localize(&i18n.LocalizeConfig{ + MessageID: key, + TemplateData: dataMap, + }) + content = strings.ReplaceAll(content, "", "") + if content == "" { + return key + } else { + return content + } +} + func GetErrMsg(key string, maps map[string]interface{}) string { var content string if maps == nil { diff --git a/backend/i18n/lang/en.yaml b/backend/i18n/lang/en.yaml index fa087184a..866f71d02 100644 --- a/backend/i18n/lang/en.yaml +++ b/backend/i18n/lang/en.yaml @@ -61,6 +61,12 @@ AppStoreIsSyncing: 'The App Store is syncing, please try again later' ErrGetCompose: "Failed to obtain docker-compose.yml file! {{ .detail }}" ErrAppWarn: "Abnormal status, please check the log" ErrAppParamKey: "Parameter {{ .name }} field exception" +ErrAppUpgrade: "Failed to upgrade application {{ .name }} {{ .err }}" +AppRecover: "App {{ .name }} rolled back " +PullImageStart: "Start pulling image {{ .name }}" +PullImageSuccess: "Image pulled successfully" +UpgradeAppStart: "Start upgrading application {{ .name }}" +UpgradeAppSuccess: "App {{ .name }} upgraded successfully" #file ErrFileCanNotRead: "File can not read" diff --git a/backend/i18n/lang/zh-Hant.yaml b/backend/i18n/lang/zh-Hant.yaml index 3a6f77866..48a7bf074 100644 --- a/backend/i18n/lang/zh-Hant.yaml +++ b/backend/i18n/lang/zh-Hant.yaml @@ -62,6 +62,12 @@ AppStoreIsSyncing: '應用程式商店正在同步中,請稍後再試' ErrGetCompose: "docker-compose.yml 檔案取得失敗!{{ .detail }}" ErrAppWarn: "狀態異常,請查看日誌" ErrAppParamKey: "參數 {{ .name }} 欄位異常" +ErrAppUpgrade: "應用程式 {{ .name }} 升級失敗 {{ .err }}" +AppRecover: "應用程式 {{ .name }} 回滾 " +PullImageStart: "開始拉取鏡像 {{ .name }}" +PullImageSuccess: "鏡像拉取成功" +UpgradeAppStart: "開始升級應用程式 {{ .name }}" +UpgradeAppSuccess: "應用程式 {{ .name }} 升級成功" #file ErrFileCanNotRead: "此文件不支持預覽" diff --git a/backend/i18n/lang/zh.yaml b/backend/i18n/lang/zh.yaml index 7f7db7261..caf8b4656 100644 --- a/backend/i18n/lang/zh.yaml +++ b/backend/i18n/lang/zh.yaml @@ -61,6 +61,12 @@ AppStoreIsSyncing: '应用商店正在同步中,请稍后再试' ErrGetCompose: "docker-compose.yml 文件获取失败!{{ .detail }}" ErrAppWarn: "状态异常,请查看日志" ErrAppParamKey: "参数 {{ .name }} 字段异常" +ErrAppUpgrade: "应用 {{ .name }} 升级失败 {{ .err }}" +AppRecover: "应用 {{ .name }} 回滚 " +PullImageStart: "开始拉取镜像 {{ .name }}" +PullImageSuccess: "镜像拉取成功" +UpgradeAppStart: "开始升级应用 {{ .name }}" +UpgradeAppSuccess: "应用 {{ .name }} 升级成功" #file ErrFileCanNotRead: "此文件不支持预览"