From fabf33a83bf3810fbd574b4f53e96a0468ecc064 Mon Sep 17 00:00:00 2001 From: CityFun <31820853+zhengkunwang223@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:14:51 +0800 Subject: [PATCH] feat: Ensure compatibility with docker-compose commands. (#9117) --- agent/global/config.go | 11 +++++--- agent/i18n/lang/en.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/zh-Hant.yaml | 1 + agent/i18n/lang/zh.yaml | 1 + agent/init/business/business.go | 15 +++++++++++ agent/utils/common/common.go | 17 ++++++++++++ agent/utils/compose/compose.go | 46 ++++++++++++++++++++++++++++----- 12 files changed, 87 insertions(+), 10 deletions(-) diff --git a/agent/global/config.go b/agent/global/config.go index 8830dfa0f..f2a492510 100644 --- a/agent/global/config.go +++ b/agent/global/config.go @@ -1,9 +1,10 @@ package global type ServerConfig struct { - Base Base `mapstructure:"base"` - RemoteURL RemoteURL `mapstructure:"remote_url"` - Log LogConfig `mapstructure:"log"` + Base Base `mapstructure:"base"` + RemoteURL RemoteURL `mapstructure:"remote_url"` + Log LogConfig `mapstructure:"log"` + DockerConfig DockerConfig } type Base struct { @@ -51,3 +52,7 @@ type LogConfig struct { LogSuffix string `mapstructure:"log_suffix"` MaxBackup int `mapstructure:"max_backup"` } + +type DockerConfig struct { + Command string +} diff --git a/agent/i18n/lang/en.yaml b/agent/i18n/lang/en.yaml index 2007bfc8c..9cb2c3cf2 100644 --- a/agent/i18n/lang/en.yaml +++ b/agent/i18n/lang/en.yaml @@ -92,6 +92,7 @@ ErrCustomApps: 'There is an installed application, please uninstall it first' ErrCustomRuntimes: 'There is an installed runtime environment, please delete it first' 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" #file ErrFileCanNotRead: 'This file does not support preview' diff --git a/agent/i18n/lang/ja.yaml b/agent/i18n/lang/ja.yaml index edb093524..f34fc8fc0 100644 --- a/agent/i18n/lang/ja.yaml +++ b/agent/i18n/lang/ja.yaml @@ -92,6 +92,7 @@ ErrCustomApps: 'インストールされているアプリケーションがあ ErrCustomRuntimes: 'ランタイム環境がインストールされています。まずそれを削除してください' ErrAppVersionDeprecated: "{{ .name }} アプリケーションは現在の 1Panel バージョンと互換性がありません、スキップしました" ErrDockerFailed: "Docker の状態が異常です。サービス状態を確認してください" +ErrDockerComposeCmdNotFound: "Docker Compose コマンドは存在しません。ホストマシンにこのコマンドを先にインストールしてください" #file ErrFileCanNotRead: 'このファイルはプレビューをサポートしていません' diff --git a/agent/i18n/lang/ko.yaml b/agent/i18n/lang/ko.yaml index 9a191d10d..e16f9f156 100644 --- a/agent/i18n/lang/ko.yaml +++ b/agent/i18n/lang/ko.yaml @@ -92,6 +92,7 @@ ErrCustomApps: '설치된 애플리케이션이 있습니다. 먼저 제거해 ErrCustomRuntimes: '설치된 런타임 환경이 있습니다. 먼저 삭제해 주세요' ErrAppVersionDeprecated: "{{ .name }} 응용 프로그램은 현재 1Panel 버전과 호환되지 않아 건너뛰었습니다" ErrDockerFailed: "Docker의 상태가 비정상입니다. 서비스 상태를 확인하세요" +ErrDockerComposeCmdNotFound: "Docker Compose 명령이 없습니다. 호스트 머신에 먼저 이 명령을 설치하세요" #파일 ErrFileCanNotRead: '이 파일은 미리보기를 지원하지 않습니다' diff --git a/agent/i18n/lang/ms.yaml b/agent/i18n/lang/ms.yaml index 34d050eda..eea9fb1cc 100644 --- a/agent/i18n/lang/ms.yaml +++ b/agent/i18n/lang/ms.yaml @@ -92,6 +92,7 @@ ErrCustomApps: 'Ada aplikasi yang dipasang, sila nyahpasangnya dahulu' ErrCustomRuntimes: 'Terdapat persekitaran masa jalan yang dipasang, sila padamkannya dahulu' 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" #fail ErrFileCanNotRead: 'Fail ini tidak menyokong pratonton' diff --git a/agent/i18n/lang/pt-BR.yaml b/agent/i18n/lang/pt-BR.yaml index b078849cf..ce0b7f833 100644 --- a/agent/i18n/lang/pt-BR.yaml +++ b/agent/i18n/lang/pt-BR.yaml @@ -92,6 +92,7 @@ ErrCustomApps: 'Há um aplicativo instalado, desinstale-o primeiro' 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" #arquivo ErrFileCanNotRead: 'Este arquivo não suporta visualização' diff --git a/agent/i18n/lang/ru.yaml b/agent/i18n/lang/ru.yaml index 4006b1869..5e83623a9 100644 --- a/agent/i18n/lang/ru.yaml +++ b/agent/i18n/lang/ru.yaml @@ -92,6 +92,7 @@ ErrCustomApps: 'Установлено приложение. Сначала уд ErrCustomRuntimes: 'Установлена среда выполнения. Сначала удалите ее' ErrAppVersionDeprecated: "Приложение {{ .name }} несовместимо с текущей версией 1Panel, пропущено" ErrDockerFailed: "Состояние Docker аномально, проверьте состояние сервиса" +ErrDockerComposeCmdNotFound: "Команда Docker Compose отсутствует, пожалуйста, установите эту команду на хост-машине сначала" #файл ErrFileCanNotRead: 'Этот файл не поддерживает предварительный просмотр' diff --git a/agent/i18n/lang/zh-Hant.yaml b/agent/i18n/lang/zh-Hant.yaml index 56e535728..44cd262f4 100644 --- a/agent/i18n/lang/zh-Hant.yaml +++ b/agent/i18n/lang/zh-Hant.yaml @@ -91,6 +91,7 @@ ErrCustomApps: '存在已安裝的應用程式,請先解除安裝' ErrCustomRuntimes: '存在已安裝的運作環境,請先刪除' ErrAppVersionDeprecated: "{{ .name }} 應用不適配目前 1Panel 版本,跳過" ErrDockerFailed: "Docker 狀態異常,請檢查服務狀態" +ErrDockerComposeCmdNotFound: "Docker Compose 命令不存在,請先在宿主機安裝此命令" #file ErrFileCanNotRead: '此檔案不支援預覽' diff --git a/agent/i18n/lang/zh.yaml b/agent/i18n/lang/zh.yaml index b92122a08..e011bdc2c 100644 --- a/agent/i18n/lang/zh.yaml +++ b/agent/i18n/lang/zh.yaml @@ -91,6 +91,7 @@ ErrCustomApps: "存在已经安装的应用,请先卸载" ErrCustomRuntimes: "存在已经安装的运行环境,请先删除" ErrAppVersionDeprecated: " {{ .name }} 应用不适配当前 1Panel 版本,跳过" ErrDockerFailed: "Docker 状态异常,请检查服务状态" +ErrDockerComposeCmdNotFound: "Docker Compose 命令不存在,请先在宿主机安装此命令" #file ErrFileCanNotRead: "此文件不支持预览" diff --git a/agent/init/business/business.go b/agent/init/business/business.go index 48d553f4b..2f568a8e3 100644 --- a/agent/init/business/business.go +++ b/agent/init/business/business.go @@ -6,6 +6,7 @@ import ( "github.com/1Panel-dev/1Panel/agent/app/service" "github.com/1Panel-dev/1Panel/agent/constant" "github.com/1Panel-dev/1Panel/agent/global" + "github.com/1Panel-dev/1Panel/agent/utils/common" ) func Init() { @@ -15,6 +16,7 @@ func Init() { go syncSSL() go syncTask() go initAcmeAccount() + go checkDockerCompose() } func syncApp() { @@ -71,3 +73,16 @@ func initAcmeAccount() { } } } + +func checkDockerCompose() { + dockerComposCmd := common.GetDockerComposeCommand() + if dockerComposCmd == "" { + global.LOG.Errorf("Docker Compose command not found, please install Docker Compose Plugin") + return + } + global.CONF.DockerConfig.Command = dockerComposCmd + if err := service.NewISettingService().Update("DockerComposeCommand", dockerComposCmd); err != nil { + global.LOG.Errorf("update docker compose command error: %s", err.Error()) + return + } +} diff --git a/agent/utils/common/common.go b/agent/utils/common/common.go index af21b82f5..887237826 100644 --- a/agent/utils/common/common.go +++ b/agent/utils/common/common.go @@ -6,6 +6,7 @@ import ( "io" mathRand "math/rand" "net" + "os/exec" "reflect" "regexp" "sort" @@ -409,3 +410,19 @@ func GetSystemVersion(versionString string) string { } return "" } + +func isCommandAvailable(name string, args ...string) bool { + execCmd := exec.Command(name, args...) + err := execCmd.Run() + return err == nil +} + +func GetDockerComposeCommand() string { + if isCommandAvailable("docker", "compose", "version") { + return "docker compose" + } + if isCommandAvailable("docker-compose", "version") { + return "docker-compose" + } + return "" +} diff --git a/agent/utils/compose/compose.go b/agent/utils/compose/compose.go index 84b99b5a1..8b62f2dde 100644 --- a/agent/utils/compose/compose.go +++ b/agent/utils/compose/compose.go @@ -1,40 +1,72 @@ package compose import ( + "github.com/1Panel-dev/1Panel/agent/buserr" + "github.com/1Panel-dev/1Panel/agent/global" "github.com/1Panel-dev/1Panel/agent/utils/cmd" + "github.com/1Panel-dev/1Panel/agent/utils/common" "time" ) +func checkCmd() error { + if global.CONF.DockerConfig.Command == "" { + dockerComposCmd := common.GetDockerComposeCommand() + if dockerComposCmd == "" { + return buserr.New("ErrDockerComposeCmdNotFound") + } + global.CONF.DockerConfig.Command = dockerComposCmd + } + return nil +} + func Up(filePath string) (string, error) { - stdout, err := cmd.RunDefaultWithStdoutBashCfAndTimeOut("docker compose -f %s up -d", 20*time.Minute, filePath) + if err := checkCmd(); err != nil { + return "", err + } + stdout, err := cmd.RunDefaultWithStdoutBashCfAndTimeOut(global.CONF.DockerConfig.Command+" -f %s up -d", 20*time.Minute, filePath) return stdout, err } func Down(filePath string) (string, error) { - stdout, err := cmd.RunDefaultWithStdoutBashCf("docker compose -f %s down --remove-orphans", filePath) + if err := checkCmd(); err != nil { + return "", err + } + stdout, err := cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s down --remove-orphans", filePath) return stdout, err } func Stop(filePath string) (string, error) { - stdout, err := cmd.RunDefaultWithStdoutBashCf("docker compose -f %s stop", filePath) + if err := checkCmd(); err != nil { + return "", err + } + stdout, err := cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s stop", filePath) return stdout, err } func Restart(filePath string) (string, error) { - stdout, err := cmd.RunDefaultWithStdoutBashCf("docker compose -f %s restart", filePath) + if err := checkCmd(); err != nil { + return "", err + } + stdout, err := cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s restart", filePath) return stdout, err } func Operate(filePath, operation string) (string, error) { - stdout, err := cmd.RunDefaultWithStdoutBashCf("docker compose -f %s %s", filePath, operation) + if err := checkCmd(); err != nil { + return "", err + } + stdout, err := cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s %s", filePath, operation) return stdout, err } func DownAndUp(filePath string) (string, error) { - stdout, err := cmd.RunDefaultWithStdoutBashCf("docker compose -f %s down", filePath) + if err := checkCmd(); err != nil { + return "", err + } + stdout, err := cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s down", filePath) if err != nil { return stdout, err } - stdout, err = cmd.RunDefaultWithStdoutBashCf("docker compose -f %s up -d", filePath) + stdout, err = cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s up -d", filePath) return stdout, err }