diff --git a/backend/app/service/app_utils.go b/backend/app/service/app_utils.go index 8afe96ff3..dd06c8737 100644 --- a/backend/app/service/app_utils.go +++ b/backend/app/service/app_utils.go @@ -14,6 +14,7 @@ import ( "regexp" "strconv" "strings" + "time" "github.com/docker/docker/api/types" @@ -511,6 +512,7 @@ func upgradeInstall(req request.AppInstallUpgrade) error { var ( upErr error backupFile string + preErr error ) global.LOG.Infof(i18n.GetMsgWithName("UpgradeAppStart", install.Name, nil)) if req.Backup { @@ -543,18 +545,27 @@ func upgradeInstall(req request.AppInstallUpgrade) error { _ = appInstallRepo.Save(context.Background(), &existInstall) } } + if preErr != nil { + global.LOG.Infof(i18n.GetMsgWithName("ErrAppUpgrade", install.Name, preErr)) + existInstall, _ := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallID)) + if existInstall.ID > 0 { + existInstall.Status = constant.UpgradeErr + existInstall.Message = preErr.Error() + _ = appInstallRepo.Save(context.Background(), &existInstall) + } + } }() fileOp := files.NewFileOp() detailDir := path.Join(constant.ResourceDir, "apps", install.App.Resource, install.App.Key, detail.Version) if install.App.Resource == constant.AppResourceRemote { - if upErr = downloadApp(install.App, detail, &install); upErr != nil { + if preErr = downloadApp(install.App, detail, &install); preErr != nil { return } if detail.DockerCompose == "" { composeDetail, err := fileOp.GetContent(path.Join(detailDir, "docker-compose.yml")) if err != nil { - upErr = err + preErr = err return } detail.DockerCompose = string(composeDetail) @@ -569,6 +580,32 @@ func upgradeInstall(req request.AppInstallUpgrade) error { detailDir = path.Join(constant.ResourceDir, "apps", "local", strings.TrimPrefix(install.App.Key, "local"), detail.Version) } + content, err := fileOp.GetContent(install.GetEnvPath()) + if err != nil { + preErr = err + return + } + if req.PullImage { + projectName := strings.ToLower(install.Name) + images, err := composeV2.GetDockerComposeImages(projectName, content, []byte(detail.DockerCompose)) + if err != nil { + preErr = err + return + } + for _, image := range images { + global.LOG.Infof(i18n.GetMsgWithName("PullImageStart", image, nil)) + if out, err := cmd.ExecWithTimeOut("docker pull "+image, 20*time.Minute); err != nil { + if out != "" { + err = errors.New(out) + } + preErr = buserr.WithNameAndErr("ErrDockerPullImage", "", err) + return + } else { + global.LOG.Infof(i18n.GetMsgByKey("PullImageSuccess")) + } + } + } + command := exec.Command("/bin/bash", "-c", fmt.Sprintf("cp -rn %s/* %s || true", detailDir, install.GetPath())) stdout, _ := command.CombinedOutput() if stdout != nil { @@ -597,36 +634,6 @@ func upgradeInstall(req request.AppInstallUpgrade) error { install.Version = detail.Version install.AppDetailId = req.DetailID - content, err := fileOp.GetContent(install.GetEnvPath()) - if err != nil { - upErr = err - return - } - - if req.PullImage { - projectName := strings.ToLower(install.Name) - images, err := composeV2.GetDockerComposeImages(projectName, content, []byte(detail.DockerCompose)) - if err != nil { - upErr = err - return - } - dockerCli, err := composeV2.NewClient() - if err != nil { - upErr = err - return - } - defer dockerCli.Close() - 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) diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 6565e8c87..bb6843abc 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -1738,7 +1738,8 @@ const message = { ignoreList: 'ignore list', appHelper: 'Please view the installation instructions of some applications on the application details page', backupApp: 'Backup application before upgrade', - backupAppHelper: 'If the upgrade fails, you can use the application backup to roll back', + backupAppHelper: + 'If the upgrade fails, the backup will be automatically rolled back. Please check the failure reason in the log audit-system log', delete: 'Delete', openrestyDeleteHelper: 'Forcibly deleting OpenResty will delete all websites, please confirm the risk before operation', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index 992dc3797..aebfa8130 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -1617,7 +1617,7 @@ const message = { ignoreList: '忽略列表', appHelper: '部分應用的安裝使用說明請在應用詳情頁查看', backupApp: '升級前備份應用', - backupAppHelper: '升級失敗可以使用應用備份回滾', + backupAppHelper: '升級失敗會使用備份自動回滾,請在日誌審計-系統日誌中查看失敗原因', delete: '刪除', openrestyDeleteHelper: '強制刪除 OpenResty 會刪除所有的網站,請確認風險後操作', downloadLogHelper1: '即將下載 {0} 套用所有日誌,是否繼續? ', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 3c159479f..66d7b96bd 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1617,7 +1617,7 @@ const message = { ignoreList: '忽略列表', appHelper: '部分应用的安装使用说明请在应用详情页查看', backupApp: '升级前备份应用', - backupAppHelper: '升级失败可以使用应用备份回滚', + backupAppHelper: '升级失败会使用备份自动回滚,请在日志审计-系统日志中查看失败原因', delete: '删除', openrestyDeleteHelper: '强制删除 OpenResty 会删除所有的网站,请确认风险之后操作', downloadLogHelper1: '即将下载 {0} 应用所有日志,是否继续?', diff --git a/frontend/src/views/app-store/installed/upgrade/index.vue b/frontend/src/views/app-store/installed/upgrade/index.vue index 400a050f6..b1c0af9fd 100644 --- a/frontend/src/views/app-store/installed/upgrade/index.vue +++ b/frontend/src/views/app-store/installed/upgrade/index.vue @@ -53,7 +53,9 @@ - {{ $t('app.backupAppHelper') }} + + {{ $t('app.backupAppHelper') }} +