From fcf864156da0b21c57bbc0fd15828aca238d0548 Mon Sep 17 00:00:00 2001 From: CityFun <31820853+zhengkunwang223@users.noreply.github.com> Date: Wed, 15 Oct 2025 17:37:07 +0800 Subject: [PATCH] feat: Optimize image pulling during application installation (#10648) --- agent/app/service/app.go | 12 +++++++++++- agent/app/service/app_utils.go | 8 ++++++-- agent/i18n/lang/en.yaml | 1 + agent/i18n/lang/es-ES.yaml | 1 + agent/i18n/lang/ja.yaml | 1 + agent/i18n/lang/ko.yaml | 1 + agent/i18n/lang/ms.yaml | 1 + agent/i18n/lang/pt-BR.yaml | 1 + agent/i18n/lang/ru.yaml | 1 + agent/i18n/lang/tr.yaml | 1 + agent/i18n/lang/zh-Hant.yaml | 1 + agent/i18n/lang/zh.yaml | 1 + agent/utils/docker/docker.go | 7 +++++++ 13 files changed, 34 insertions(+), 3 deletions(-) diff --git a/agent/app/service/app.go b/agent/app/service/app.go index d465158ae..1324858cc 100644 --- a/agent/app/service/app.go +++ b/agent/app/service/app.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "os" + "path" "path/filepath" "reflect" "strconv" @@ -484,6 +485,15 @@ func (a AppService) Install(req request.AppInstallCreate) (appInstall *model.App req.Params["RESTY_ADD_PACKAGE_BUILDDEPS"] = "" req.Params["RESTY_CONFIG_OPTIONS_MORE"] = "" } + if app.Key == "openresty" && (app.Resource == "remote" || app.Resource == "custom") && common.CompareVersion(appDetail.Version, "1.27") { + if dir, ok := req.Params["WEBSITE_DIR"]; ok { + siteDir := dir.(string) + if siteDir == "" || !strings.HasPrefix(siteDir, "/") { + siteDir = path.Join(global.Dir.DataDir, dir.(string)) + } + req.Params["WEBSITE_DIR"] = siteDir + } + } paramByte, err = json.Marshal(req.Params) if err != nil { return @@ -511,7 +521,7 @@ func (a AppService) Install(req request.AppInstallCreate) (appInstall *model.App return err } if app.Key == "openresty" { - if err = handleSiteDir(app, appDetail, &req, t); err != nil { + if err = handleSiteDir(app, appDetail, req, t); err != nil { return err } if err = handleOpenrestyFile(appInstall); err != nil { diff --git a/agent/app/service/app_utils.go b/agent/app/service/app_utils.go index 51c701601..78577d840 100644 --- a/agent/app/service/app_utils.go +++ b/agent/app/service/app_utils.go @@ -1163,7 +1163,11 @@ func upApp(task *task.Task, appInstall *model.AppInstall, pullImages bool) error appInstall.Message = errMsg + errOur installErr := errors.New(appInstall.Message) task.LogFailedWithErr(i18n.GetMsgByKey("PullImage"), installErr) - return installErr + if exist, _ := dockerCLi.ImageExists(image); !exist { + return installErr + } else { + task.Log(i18n.GetMsgByKey("UseExistImage")) + } } else { task.Log(i18n.GetMsgByKey("PullImageSuccess")) } @@ -1939,7 +1943,7 @@ func getAppTags(appID uint, lang string) ([]response.TagDTO, error) { return res, nil } -func handleSiteDir(app model.App, appDetail model.AppDetail, req *request.AppInstallCreate, t *task.Task) error { +func handleSiteDir(app model.App, appDetail model.AppDetail, req request.AppInstallCreate, t *task.Task) error { if app.Key == "openresty" && (app.Resource == "remote" || app.Resource == "custom") && common.CompareVersion(appDetail.Version, "1.27") { if dir, ok := req.Params["WEBSITE_DIR"]; ok { siteDir := dir.(string) diff --git a/agent/i18n/lang/en.yaml b/agent/i18n/lang/en.yaml index ade79b0da..b42da231c 100644 --- a/agent/i18n/lang/en.yaml +++ b/agent/i18n/lang/en.yaml @@ -95,6 +95,7 @@ ErrCustomRuntimes: 'There is an installed runtime environment, please delete it ErrAppVersionDeprecated: "The {{ .name }} application is not compatible with the current 1Panel version, skipped" ErrDockerFailed: "The state of Docker is abnormal, please check the service status" ErrDockerComposeCmdNotFound: "The Docker Compose command does not exist, please install this command on the host machine first" +UseExistImage: 'Failed to pull image, using existing image' #ssh ExportIP: "Login IP" diff --git a/agent/i18n/lang/es-ES.yaml b/agent/i18n/lang/es-ES.yaml index cbe45001b..2fca2fe29 100644 --- a/agent/i18n/lang/es-ES.yaml +++ b/agent/i18n/lang/es-ES.yaml @@ -95,6 +95,7 @@ ErrCustomRuntimes: 'Hay un entorno de ejecución instalado, elimínelo primero' ErrAppVersionDeprecated: "La aplicación {{ .name }} no es compatible con la versión actual de 1Panel, omitida" ErrDockerFailed: "El estado de Docker es anómalo, revise el servicio" ErrDockerComposeCmdNotFound: "El comando Docker Compose no existe, por favor instálelo primero en el host" +UseExistImage: 'Error al extraer la imagen, usando imagen existente' #ssh ExportIP: "IP de inicio de sesión" diff --git a/agent/i18n/lang/ja.yaml b/agent/i18n/lang/ja.yaml index f7a47e699..68885a5c3 100644 --- a/agent/i18n/lang/ja.yaml +++ b/agent/i18n/lang/ja.yaml @@ -94,6 +94,7 @@ ErrCustomRuntimes: 'ランタイム環境がインストールされています ErrAppVersionDeprecated: "{{ .name }} アプリケーションは現在の 1Panel バージョンと互換性がありません、スキップしました" ErrDockerFailed: "Docker の状態が異常です。サービス状態を確認してください" ErrDockerComposeCmdNotFound: "Docker Compose コマンドは存在しません。ホストマシンにこのコマンドを先にインストールしてください" +UseExistImage: 'イメージのプルに失敗しました、既存のイメージを使用します' #ssh ExportIP: "ログインIP" diff --git a/agent/i18n/lang/ko.yaml b/agent/i18n/lang/ko.yaml index f839ca683..14b89adce 100644 --- a/agent/i18n/lang/ko.yaml +++ b/agent/i18n/lang/ko.yaml @@ -95,6 +95,7 @@ ErrCustomRuntimes: '설치된 런타임 환경이 있습니다. 먼저 삭제해 ErrAppVersionDeprecated: "{{ .name }} 응용 프로그램은 현재 1Panel 버전과 호환되지 않아 건너뛰었습니다" ErrDockerFailed: "Docker의 상태가 비정상입니다. 서비스 상태를 확인하세요" ErrDockerComposeCmdNotFound: "Docker Compose 명령이 없습니다. 호스트 머신에 먼저 이 명령을 설치하세요" +UseExistImage: '이미지 가져오기 실패, 기존 이미지 사용' #ssh ExportIP: "로그인 IP" diff --git a/agent/i18n/lang/ms.yaml b/agent/i18n/lang/ms.yaml index e1418b6f2..bbf4238bd 100644 --- a/agent/i18n/lang/ms.yaml +++ b/agent/i18n/lang/ms.yaml @@ -98,6 +98,7 @@ ErrCustomRuntimes: 'Terdapat persekitaran masa jalan yang dipasang, sila padamka ErrAppVersionDeprecated: "Aplikasi {{ .name }} tidak sesuai dengan versi 1Panel saat ini, dilewati" ErrDockerFailed: "Keadaan Docker tidak normal, sila periksa status perkhidmatan" ErrDockerComposeCmdNotFound: "Perintah Docker Compose tidak wujud, sila pasang perintah ini di mesin tuan terlebih dahulu" +UseExistImage: 'Gagal menarik imej, menggunakan imej sedia ada' #ssh ExportIP: "IP Log Masuk" diff --git a/agent/i18n/lang/pt-BR.yaml b/agent/i18n/lang/pt-BR.yaml index dfbd7e00c..90f1cea01 100644 --- a/agent/i18n/lang/pt-BR.yaml +++ b/agent/i18n/lang/pt-BR.yaml @@ -98,6 +98,7 @@ ErrCustomRuntimes: 'Há um ambiente de execução instalado, exclua-o primeiro' ErrAppVersionDeprecated: "O aplicativo {{ .name }} não é compatível com a versão atual do 1Panel, ignorado" ErrDockerFailed: "O estado do Docker está anormal, verifique o status do serviço" ErrDockerComposeCmdNotFound: "O comando Docker Compose não existe, por favor, instale este comando na máquina host primeiro" +UseExistImage: 'Falha ao puxar a imagem, usando imagem existente' #ssh ExportIP: "IP de Login" diff --git a/agent/i18n/lang/ru.yaml b/agent/i18n/lang/ru.yaml index c7c341228..7dd2c2fd6 100644 --- a/agent/i18n/lang/ru.yaml +++ b/agent/i18n/lang/ru.yaml @@ -98,6 +98,7 @@ ErrCustomRuntimes: 'Установлена среда выполнения. Сн ErrAppVersionDeprecated: "Приложение {{ .name }} несовместимо с текущей версией 1Panel, пропущено" ErrDockerFailed: "Состояние Docker аномально, проверьте состояние сервиса" ErrDockerComposeCmdNotFound: "Команда Docker Compose отсутствует, пожалуйста, установите эту команду на хост-машине сначала" +UseExistImage: 'Не удалось загрузить образ, используется существующий образ' #ssh ExportIP: "IP входа" diff --git a/agent/i18n/lang/tr.yaml b/agent/i18n/lang/tr.yaml index 61b74fd6f..b8caa03c2 100644 --- a/agent/i18n/lang/tr.yaml +++ b/agent/i18n/lang/tr.yaml @@ -98,6 +98,7 @@ ErrCustomRuntimes: 'Yüklü bir çalışma ortamı var, lütfen önce silin' ErrAppVersionDeprecated: "{{ .name }} uygulaması mevcut 1Panel sürümü ile uyumlu değil, atlandı" ErrDockerFailed: "Docker durumu anormal, lütfen servis durumunu kontrol edin" ErrDockerComposeCmdNotFound: "Docker Compose komutu mevcut değil, lütfen önce bu komutu host makinesine yükleyin" +UseExistImage: 'Görüntü çekme başarısız, mevcut görüntü kullanılıyor' #ssh ExportIP: "Giriş IP" diff --git a/agent/i18n/lang/zh-Hant.yaml b/agent/i18n/lang/zh-Hant.yaml index a86c68b9f..e2847526d 100644 --- a/agent/i18n/lang/zh-Hant.yaml +++ b/agent/i18n/lang/zh-Hant.yaml @@ -94,6 +94,7 @@ ErrCustomRuntimes: '存在已安裝的運作環境,請先刪除' ErrAppVersionDeprecated: "{{ .name }} 應用不適配目前 1Panel 版本,跳過" ErrDockerFailed: "Docker 狀態異常,請檢查服務狀態" ErrDockerComposeCmdNotFound: "Docker Compose 指令不存在,請先在宿主機安裝此指令" +UseExistImage: '拉取映像失敗,使用存量映像' #ssh ExportIP: "登入IP" diff --git a/agent/i18n/lang/zh.yaml b/agent/i18n/lang/zh.yaml index 32f80961a..106bb6ab4 100644 --- a/agent/i18n/lang/zh.yaml +++ b/agent/i18n/lang/zh.yaml @@ -94,6 +94,7 @@ ErrCustomRuntimes: "存在已经安装的运行环境,请先删除" ErrAppVersionDeprecated: " {{ .name }} 应用不适配当前 1Panel 版本,跳过" ErrDockerFailed: "Docker 状态异常,请检查服务状态" ErrDockerComposeCmdNotFound: "Docker Compose 命令不存在,请先在宿主机安装此命令" +UseExistImage: "拉取镜像失败,使用存量镜像" #ssh ExportIP: "登录 IP" diff --git a/agent/utils/docker/docker.go b/agent/utils/docker/docker.go index 327380c5c..17dd376b9 100644 --- a/agent/utils/docker/docker.go +++ b/agent/utils/docker/docker.go @@ -115,6 +115,13 @@ func (c Client) DeleteImage(imageID string) error { } return nil } +func (c Client) ImageExists(imageID string) (bool, error) { + _, err := c.cli.ImageInspect(context.Background(), imageID) + if err != nil { + return false, err + } + return true, nil +} func (c Client) GetImageIDByName(imageName string) (string, error) { filter := filters.NewArgs()