feat: 优化应用升级逻辑,拉取镜像失败无需回滚 (#5561)

This commit is contained in:
zhengkunwang 2024-06-25 11:44:45 +08:00 committed by GitHub
parent f6cc0b272c
commit 9121d57e7e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 45 additions and 32 deletions

View file

@ -512,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 {
@ -544,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)
@ -570,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 {
@ -598,32 +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
}
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)
}
upErr = buserr.WithNameAndErr("ErrDockerPullImage", "", err)
} else {
global.LOG.Infof(i18n.GetMsgByKey("PullImageSuccess"))
}
}
}
if out, err := compose.Down(install.GetComposePath()); err != nil {
if out != "" {
upErr = errors.New(out)

View file

@ -1766,7 +1766,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',

View file

@ -1643,7 +1643,7 @@ const message = {
ignoreList: '忽略列表',
appHelper: '部分應用的安裝使用說明請在應用詳情頁查看',
backupApp: '升級前備份應用',
backupAppHelper: '升級失敗可以使用應用備份回滾',
backupAppHelper: '升級失敗會使用備份自動回滾,請在日誌審計-系統日誌中查看失敗原因',
delete: '刪除',
openrestyDeleteHelper: '強制刪除 OpenResty 會刪除所有的網站請確認風險後操作',
downloadLogHelper1: '即將下載 {0} 套用所有日誌是否繼續 ',

View file

@ -1644,7 +1644,7 @@ const message = {
ignoreList: '忽略列表',
appHelper: '部分应用的安装使用说明请在应用详情页查看',
backupApp: '升级前备份应用',
backupAppHelper: '升级失败可以使用应用备份回滚',
backupAppHelper: '升级失败会使用备份自动回滚,请在日志审计-系统日志中查看失败原因',
delete: '删除',
openrestyDeleteHelper: '强制删除 OpenResty 会删除所有的网站请确认风险之后操作',
downloadLogHelper1: '即将下载 {0} 应用所有日志是否继续',

View file

@ -53,7 +53,9 @@
</el-form-item>
<el-form-item prop="backup" v-if="operateReq.operate === 'upgrade'">
<el-checkbox v-model="operateReq.backup" :label="$t('app.backupApp')" />
<span class="input-help">{{ $t('app.backupAppHelper') }}</span>
<span class="input-help">
<el-text type="warning">{{ $t('app.backupAppHelper') }}</el-text>
</span>
</el-form-item>
<el-form-item pro="pullImage" v-if="operateReq.operate === 'upgrade'">
<el-checkbox v-model="operateReq.pullImage" :label="$t('container.forcePull')" size="large" />