feat(ai): share compose preview helpers and translations (#14342)

This commit is contained in:
ssongliu authored and GitHub committed 2026-11-08 17:24:01 +08:00
1 parent c5dfcae38b
commit 5c71dcba19
20 files changed
+158 -14

No files matched your search

+1 -1
View File
@@ -518,7 +518,7 @@ func (a AppService) InstallWithHooks(req request.AppInstallCreate, executeScript
appInstall.ServiceName = serviceName
if !req.SkipComposeCommonConfig {
if err = addDockerComposeCommonParam(composeMap, appInstall.ServiceName, req.AppContainerConfig, req.Params, app.Key); err != nil {
if err = AddDockerComposeCommonParam(composeMap, appInstall.ServiceName, req.AppContainerConfig, req.Params, app.Key); err != nil {
return
}
}
+12
View File
@@ -14,6 +14,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/req_helper"
"github.com/subosito/gotenv"
"gopkg.in/yaml.v3"
)
@@ -87,3 +88,14 @@ func cacheAppDetailCompose(detail *model.AppDetail, content []byte) error {
detail.DockerCompose = string(content)
return nil
}
func LoadAppPackageEnvironment(app model.App, detail model.AppDetail) (map[string]string, error) {
if err := downloadApp(app, detail, nil, nil); err != nil {
return nil, err
}
values, err := gotenv.Read(filepath.Join(app.GetAppResourcePath(), detail.Version, ".env"))
if os.IsNotExist(err) {
return make(map[string]string), nil
}
return values, err
}
+2 -2
View File
@@ -553,7 +553,7 @@ func (a *AppInstallService) UpdateWithBeforeRestart(req request.AppInstalledUpda
}
}
if req.Advanced && !req.SkipComposeCommonConfig {
if err = addDockerComposeCommonParam(composeMap, installed.ServiceName, req.AppContainerConfig, req.Params, installed.App.Key); err != nil {
if err = AddDockerComposeCommonParam(composeMap, installed.ServiceName, req.AppContainerConfig, req.Params, installed.App.Key); err != nil {
return err
}
}
@@ -608,7 +608,7 @@ func (a *AppInstallService) UpdateWithBeforeRestart(req request.AppInstalledUpda
return err
}
backupEnvMaps := maps.Clone(oldEnvMaps)
handleMap(req.Params, oldEnvMaps)
MergeAppEnvironment(req.Params, oldEnvMaps)
paramByte, err := json.Marshal(oldEnvMaps)
if err != nil {
return err
+1 -1
View File
@@ -866,7 +866,7 @@ func renderUpgradeEnv(install *model.AppInstall, original []byte) ([]byte, error
if err := json.Unmarshal([]byte(install.Env), &envs); err != nil {
return nil, err
}
handleMap(envs, params)
MergeAppEnvironment(envs, params)
if install.App.Key == "openlist" {
// The upgrade script updates this too late for the pre-pull phase.
image := "openlistteam/openlist:v" + strings.TrimPrefix(install.Version, "v")
+7 -7
View File
@@ -781,7 +781,7 @@ func getUpgradeCompose(install model.AppInstall, detail model.AppDetail) (string
envs[constant.ContainerName] = install.ContainerName
}
config.Advanced = true
if err := addDockerComposeCommonParam(composeMap, install.ServiceName, config, envs, install.App.Key); err != nil {
if err := AddDockerComposeCommonParam(composeMap, install.ServiceName, config, envs, install.App.Key); err != nil {
return "", err
}
paramByte, err := json.Marshal(envs)
@@ -866,7 +866,7 @@ func coverEnvJsonToStr(envJson string) (string, error) {
envMap := make(map[string]interface{})
_ = json.Unmarshal([]byte(envJson), &envMap)
newEnvMap := make(map[string]string, len(envMap))
handleMap(envMap, newEnvMap)
MergeAppEnvironment(envMap, newEnvMap)
envStr, err := gotenv.Marshal(newEnvMap)
if err != nil {
return "", err
@@ -894,7 +894,7 @@ func checkRequiredAndLimit(app model.App) error {
return nil
}
func handleMap(params map[string]interface{}, envParams map[string]string) {
func MergeAppEnvironment(params map[string]interface{}, envParams map[string]string) {
for k, v := range params {
switch t := v.(type) {
case string:
@@ -912,7 +912,7 @@ func handleMap(params map[string]interface{}, envParams map[string]string) {
}
envParams[k] = strings.Join(strArray, ",")
case map[string]interface{}:
handleMap(t, envParams)
MergeAppEnvironment(t, envParams)
}
}
}
@@ -1059,7 +1059,7 @@ func copyData(task *task.Task, app model.App, appDetail model.AppDetail, appInst
envParams = make(map[string]string)
}
}
handleMap(req.Params, envParams)
MergeAppEnvironment(req.Params, envParams)
if err = env.Write(envParams, envPath); err != nil {
return
}
@@ -1811,7 +1811,7 @@ func updateToolApp(installed *model.AppInstall) {
return
}
envFileMap := make(map[string]string)
handleMap(envMap, envFileMap)
MergeAppEnvironment(envMap, envFileMap)
if err = env.Write(envFileMap, envPath); err != nil {
global.LOG.Errorf("update tool app [%s] error : %s", toolInstall.Name, err.Error())
return
@@ -1831,7 +1831,7 @@ func updateToolApp(installed *model.AppInstall) {
}
}
func addDockerComposeCommonParam(composeMap map[string]interface{}, serviceName string, req request.AppContainerConfig, params map[string]interface{}, appKey string) error {
func AddDockerComposeCommonParam(composeMap map[string]interface{}, serviceName string, req request.AppContainerConfig, params map[string]interface{}, appKey string) error {
services, serviceValid := composeMap["services"].(map[string]interface{})
if !serviceValid {
return buserr.New("ErrFileParse")
+1 -1
View File
@@ -609,7 +609,7 @@ func buildRecoverEnv(appEnv string, backupEnvMap, installedEnvMap map[string]int
backupEnvMap["PANEL_DB_HOST"] = currentHostVal
}
newEnvMap := make(map[string]string, len(backupEnvMap))
handleMap(backupEnvMap, newEnvMap)
MergeAppEnvironment(backupEnvMap, newEnvMap)
mergedEnvContent, err := gotenv.Marshal(newEnvMap)
if err != nil {
return appEnv, "", err
+1 -1
View File
@@ -1391,7 +1391,7 @@ func (r *RuntimeService) UpdatePHPContainer(req request.PHPContainerConfig) erro
return err
}
newMap := make(map[string]string)
handleMap(create.Params, newMap)
MergeAppEnvironment(create.Params, newMap)
maps.Copy(envs, newMap)
envs["PANEL_APP_PORT_HTTP"] = runtime.Port
envStr, err := gotenv.Marshal(envs)
+1 -1
View File
@@ -554,7 +554,7 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
}
newMap := make(map[string]string)
handleMap(create.Params, newMap)
MergeAppEnvironment(create.Params, newMap)
maps.Copy(env, newMap)
envStr, err := gotenv.Marshal(env)
+11
View File
@@ -1147,6 +1147,17 @@ const message = {
serviceAddressHelper:
'Use the container address for container apps and the external address for host or external apps.',
externalAddress: 'External address',
createVllmInstance: 'Create vLLM instance',
previewDeployment: 'Preview deployment configuration',
deploymentOverview: 'Deployment overview',
backToForm: 'Back to edit',
composePreviewHelper:
'Add fields not available in the form here. Change existing settings in the form. Compose edits do not update the form or account synchronization settings.',
envPreviewHelper: 'Environment variables are generated from the form. Return to the form to make changes.',
generateCompose: 'Generate and preview',
saveDeploy: 'Save and deploy',
composeRegenerateHelper:
'The form has changed. Regenerating Compose will overwrite manual edits. Continue?',
deploymentNameHelper:
'Application instance name, used for the installation directory and fixed after creation. Set an alias to change the display name.',
deploymentAliasHelper:
+12
View File
@@ -1150,6 +1150,18 @@ const message = {
serviceAddressHelper:
'Use la dirección del contenedor para sus aplicaciones y la dirección externa para aplicaciones del host o externas.',
externalAddress: 'Dirección externa',
createVllmInstance: 'Crear instancia de vLLM',
previewDeployment: 'Vista previa de la configuración',
deploymentOverview: 'Resumen del despliegue',
backToForm: 'Volver a editar',
composePreviewHelper:
'Añada campos que no estén en el formulario. Modifique los ajustes existentes en el formulario. Editar Compose no actualiza el formulario ni la sincronización de cuentas.',
envPreviewHelper:
'Las variables de entorno se generan a partir del formulario. Vuelva al formulario para modificarlas.',
generateCompose: 'Generar y previsualizar',
saveDeploy: 'Guardar y desplegar',
composeRegenerateHelper:
'El formulario ha cambiado. Regenerar Compose sobrescribirá los cambios manuales. ¿Continuar?',
deploymentNameHelper:
'Nombre de la instancia, usado en el directorio de instalación y fijo tras crearla. Configure un alias para cambiar el nombre mostrado.',
deploymentAliasHelper:
+11
View File
@@ -1128,6 +1128,17 @@ const message = {
serviceAddressHelper:
'برای برنامه‌های کانتینری از آدرس کانتینر و برای برنامه‌های میزبان یا خارجی از آدرس خارجی استفاده کنید.',
externalAddress: 'آدرس خارجی',
createVllmInstance: 'ایجاد نمونه vLLM',
previewDeployment: 'پیش‌نمایش پیکربندی استقرار',
deploymentOverview: 'نمای کلی استقرار',
backToForm: 'بازگشت برای ویرایش',
composePreviewHelper:
'فیلدهای موجود نبودۀ فرم را اضافه کنید. تنظیمات موجود را در فرم تغییر دهید. ویرایش Compose فرم یا تنظیمات همگام‌سازی حساب را تغییر نمی‌دهد.',
envPreviewHelper: 'متغیرهای محیطی از روی فرم تولید می‌شوند. برای تغییر آن‌ها به فرم بازگردید.',
generateCompose: 'تولید و پیش‌نمایش',
saveDeploy: 'ذخیره و استقرار',
composeRegenerateHelper:
'فرم تغییر کرده است. تولید مجدد Compose ویرایش‌های دستی را بازنویسی می‌کند. ادامه می‌دهید؟',
deploymentNameHelper:
'نام نمونهٔ برنامه برای پوشهٔ نصب استفاده می\u200cشود و پس از ایجاد قابل تغییر نیست. برای تغییر نام نمایشی، نام مستعار تعیین کنید.',
deploymentAliasHelper:
+11
View File
@@ -1133,6 +1133,17 @@ const message = {
serviceAddressHelper:
'コンテナ内のアプリにはコンテナアドレスを、ホスト上または外部のアプリには外部アドレスを使用してください。',
externalAddress: '外部アクセスアドレス',
createVllmInstance: 'vLLM インスタンスを作成',
previewDeployment: 'デプロイ設定のプレビュー',
deploymentOverview: 'デプロイ概要',
backToForm: '戻って編集',
composePreviewHelper:
'フォームにない項目を追加できます。既存の設定はフォームで変更してください。Compose の編集はフォームやアカウント同期設定に反映されません。',
envPreviewHelper: '環境変数はフォームから生成されます。変更するにはフォームに戻ってください。',
generateCompose: '設定を生成してプレビュー',
saveDeploy: '保存してデプロイ',
composeRegenerateHelper:
'フォームが変更されています。Compose を再生成すると手動の編集内容が上書きされます。続行しますか?',
deploymentNameHelper:
'アプリのインスタンス名です。インストール先ディレクトリに使用され、作成後は変更できません。表示名を変更するには別名を設定してください。',
deploymentAliasHelper:
+11
View File
@@ -1120,6 +1120,17 @@ const message = {
serviceAPIHelper: '이 서비스는 OpenAI 호환 API를 제공합니다.',
serviceAddressHelper: '컨테이너 앱에는 컨테이너 주소를, 호스트 또는 외부 앱에는 외부 주소를 사용하세요.',
externalAddress: '외부 접속 주소',
createVllmInstance: 'vLLM 인스턴스 생성',
previewDeployment: '배포 설정 미리보기',
deploymentOverview: '배포 개요',
backToForm: '돌아가서 수정',
composePreviewHelper:
'양식에 없는 필드를 추가할 수 있습니다. 기존 설정은 양식에서 변경하세요. Compose 편집은 양식이나 계정 동기화 설정에 반영되지 않습니다.',
envPreviewHelper: '환경 변수는 양식에서 생성됩니다. 수정하려면 양식으로 돌아가세요.',
generateCompose: '설정 생성 및 미리보기',
saveDeploy: '저장 및 배포',
composeRegenerateHelper:
'양식이 변경되었습니다. Compose를 다시 생성하면 수동 편집 내용이 덮어써집니다. 계속할까요?',
deploymentNameHelper:
'앱 인스턴스 이름으로, 설치 디렉터리에 사용되며 생성 후 변경할 수 없습니다. 표시 이름을 바꾸려면 별칭을 설정하세요.',
deploymentAliasHelper:
+10
View File
@@ -1114,6 +1114,16 @@ const message = {
serviceAPIHelper: 'ບໍລິການນີ້ໃຫ້ API ທີ່ເຂົ້າກັນໄດ້ກັບ OpenAI.',
serviceAddressHelper: 'ແອັບໃນຄອນເທນເນີໃຊ້ທີ່ຢູ່ຄອນເທນເນີ; ແອັບໃນໂຮສ ຫຼື ພາຍນອກໃຊ້ທີ່ຢູ່ພາຍນອກ.',
externalAddress: 'ທີ່ຢູ່ພາຍນອກ',
createVllmInstance: 'ສ້າງອິນສະແຕນ vLLM',
previewDeployment: 'ເບິ່ງຕົວຢ່າງການຕັ້ງຄ່າຕິດຕັ້ງ',
deploymentOverview: 'ພາບລວມການຕິດຕັ້ງ',
backToForm: 'ກັບໄປແກ້ໄຂ',
composePreviewHelper:
'ເພີ່ມຟິວທີ່ບໍ່ມີໃນແບບຟອມໄດ້. ແກ້ໄຂຄ່າເດີມໃນແບບຟອມ. ການແກ້ໄຂ Compose ຈະບໍ່ປ່ຽນແບບຟອມ ຫຼື ຄ່າການຊິງຄ໌ບັນຊີ.',
envPreviewHelper: 'ຕົວແປສະພາບແວດລ້ອມຖືກສ້າງຈາກແບບຟອມ. ຫາກຕ້ອງການແກ້ໄຂ ກະລຸນາກັບໄປທີ່ແບບຟອມ.',
generateCompose: 'ສ້າງການຕັ້ງຄ່າແລະເບິ່ງຕົວຢ່າງ',
saveDeploy: 'ບັນທຶກແລະຕິດຕັ້ງ',
composeRegenerateHelper: 'ແບບຟອມຖືກປ່ຽນແລ້ວ. ການສ້າງ Compose ໃໝ່ຈະຂຽນທັບສິ່ງທີ່ແກ້ໄຂດ້ວຍຕົນເອງ. ສືບຕໍ່ບໍ?',
deploymentNameHelper:
'ຊື່ອິນສະແຕນຂອງແອັບ ໃຊ້ສຳລັບໂຟນເດີຕິດຕັ້ງ ແລະ ປ່ຽນບໍ່ໄດ້ຫຼັງສ້າງ. ຕັ້ງຊື່ຫຼິ້ນເພື່ອປ່ຽນຊື່ທີ່ສະແດງ.',
deploymentAliasHelper:
+12
View File
@@ -1159,6 +1159,18 @@ const message = {
serviceAddressHelper:
'Gunakan alamat bekas untuk aplikasi dalam bekas dan alamat luaran untuk aplikasi hos atau luaran.',
externalAddress: 'Alamat luaran',
createVllmInstance: 'Cipta tika vLLM',
previewDeployment: 'Pratonton konfigurasi pelaksanaan',
deploymentOverview: 'Ringkasan pelaksanaan',
backToForm: 'Kembali untuk mengedit',
composePreviewHelper:
'Tambah medan yang tiada dalam borang. Ubah tetapan sedia ada dalam borang. Suntingan Compose tidak mengemas kini borang atau tetapan penyegerakan akaun.',
envPreviewHelper:
'Pemboleh ubah persekitaran dijana daripada borang. Kembali ke borang untuk membuat perubahan.',
generateCompose: 'Jana dan pratonton',
saveDeploy: 'Simpan dan laksanakan',
composeRegenerateHelper:
'Borang telah berubah. Penjanaan semula Compose akan menimpa suntingan manual. Teruskan?',
deploymentNameHelper:
'Nama instans aplikasi, digunakan untuk direktori pemasangan dan tidak boleh diubah selepas penciptaan. Tetapkan alias untuk mengubah nama paparan.',
deploymentAliasHelper:
+12
View File
@@ -1154,6 +1154,18 @@ const message = {
serviceAddressHelper:
'Use o endereço do contêiner para aplicativos em contêineres e o endereço externo para aplicativos do host ou externos.',
externalAddress: 'Endereço externo',
createVllmInstance: 'Criar instância vLLM',
previewDeployment: 'Prévia da configuração de implantação',
deploymentOverview: 'Resumo da implantação',
backToForm: 'Voltar para editar',
composePreviewHelper:
'Adicione campos não disponíveis no formulário. Altere as configurações existentes no formulário. Editar o Compose não atualiza o formulário nem a sincronização de contas.',
envPreviewHelper:
'As variáveis de ambiente são geradas a partir do formulário. Volte ao formulário para alterá-las.',
generateCompose: 'Gerar e visualizar',
saveDeploy: 'Salvar e implantar',
composeRegenerateHelper:
'O formulário foi alterado. Gerar o Compose novamente substituirá as edições manuais. Continuar?',
deploymentNameHelper:
'Nome da instância, usado no diretório de instalação e fixo após a criação. Defina um alias para alterar o nome exibido.',
deploymentAliasHelper:
+11
View File
@@ -1147,6 +1147,17 @@ const message = {
serviceAddressHelper:
'Для приложений в контейнерах используйте адрес контейнера, для приложений на хосте или вне его — внешний адрес.',
externalAddress: 'Внешний адрес',
createVllmInstance: 'Создание экземпляра vLLM',
previewDeployment: 'Просмотр конфигурации развёртывания',
deploymentOverview: 'Обзор развёртывания',
backToForm: 'Вернуться к редактированию',
composePreviewHelper:
'Добавляйте поля, отсутствующие в форме. Существующие настройки меняйте в форме. Правки Compose не обновляют форму или настройки синхронизации аккаунтов.',
envPreviewHelper: 'Переменные окружения создаются на основе формы. Для изменений вернитесь к форме.',
generateCompose: 'Создать и просмотреть',
saveDeploy: 'Сохранить и развернуть',
composeRegenerateHelper:
'Форма изменена. Повторное создание Compose перезапишет ручные правки. Продолжить?',
deploymentNameHelper:
'Имя экземпляра приложения используется для каталога установки и не меняется после создания. Для отображения другого имени задайте псевдоним.',
deploymentAliasHelper:
+11
View File
@@ -1155,6 +1155,17 @@ const message = {
serviceAddressHelper:
'Konteyner uygulamaları için konteyner adresini, ana makine veya harici uygulamalar için harici adresi kullanın.',
externalAddress: 'Harici adres',
createVllmInstance: 'vLLM örneği oluştur',
previewDeployment: 'Dağıtım yapılandırmasını önizle',
deploymentOverview: 'Dağıtım özeti',
backToForm: 'Düzenlemeye dön',
composePreviewHelper:
'Formda bulunmayan alanları ekleyebilirsiniz. Mevcut ayarları formdan değiştirin. Compose düzenlemeleri formu veya hesap eşitleme ayarlarını güncellemez.',
envPreviewHelper: 'Ortam değişkenleri formdan oluşturulur. Değişiklik yapmak için forma dönün.',
generateCompose: 'Oluştur ve önizle',
saveDeploy: 'Kaydet ve dağıt',
composeRegenerateHelper:
'Form değiştirildi. Compose yeniden oluşturulursa elle yapılan düzenlemeler silinir. Devam edilsin mi?',
deploymentNameHelper:
'Uygulama örneğinin adı, kurulum dizininde kullanılır ve oluşturulduktan sonra değiştirilemez. Görünen adı değiştirmek için takma ad belirleyin.',
deploymentAliasHelper:
+10
View File
@@ -1074,6 +1074,16 @@ const message = {
serviceAPIHelper: '此服務提供 OpenAI 相容介面。',
serviceAddressHelper: '容器內應用程式使用容器位址,本機或外部應用程式使用外部位址。',
externalAddress: '外部存取位址',
createVllmInstance: '建立 vLLM 執行個體',
previewDeployment: '預覽部署設定',
deploymentOverview: '部署概覽',
backToForm: '返回修改',
composePreviewHelper:
'可補充表單未提供的欄位。已有設定請返回表單修改;Compose 編輯不會回填表單,也不會更新帳號同步設定。',
envPreviewHelper: '環境變數依表單產生,如需修改請返回表單。',
generateCompose: '產生設定並預覽',
saveDeploy: '儲存並部署',
composeRegenerateHelper: '表單已修改,重新產生 Compose 將覆蓋手動編輯的內容。是否繼續?',
deploymentNameHelper: '應用程式執行個體名稱,用於安裝目錄,建立後無法修改。如需調整顯示名稱,請設定別名。',
deploymentAliasHelper:
'選填,用於清單顯示,可隨時修改;留空時顯示應用程式名稱。僅修改別名不會重新啟動容器。',
+10
View File
@@ -1087,6 +1087,16 @@ const message = {
serviceAPIHelper: '该服务提供 OpenAI 兼容接口。',
serviceAddressHelper: '容器内应用使用容器地址,本机或外部应用使用外部地址。',
externalAddress: '外部访问地址',
createVllmInstance: '创建 vLLM 实例',
previewDeployment: '预览部署配置',
deploymentOverview: '部署概览',
backToForm: '返回修改',
composePreviewHelper:
'可补充表单未提供的字段。已有配置请返回表单修改;Compose 编辑不会回填表单,也不会更新账号同步设置。',
envPreviewHelper: '环境变量根据表单生成,修改请返回表单。',
generateCompose: '生成配置并预览',
saveDeploy: '保存并部署',
composeRegenerateHelper: '表单已修改,重新生成 Compose 将覆盖手动编辑的内容。是否继续?',
deploymentNameHelper: '应用实例名称,用于安装目录,创建后不可修改。需要调整展示名称时,请设置别名。',
deploymentAliasHelper: '选填,用于列表展示,可随时修改;留空时显示应用名称。仅修改别名不会重启容器。',
deploymentContainerNameHelper: 'Docker 容器名称,默认与应用名称相同,可单独设置。修改后会重新创建容器。',