mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-26 09:22:50 +08:00
feat: Support display and operations for multi-YAML compose startup (#11421)
Refs #11405
This commit is contained in:
parent
74f29e3dc3
commit
5674673c5d
18 changed files with 107 additions and 60 deletions
|
|
@ -15,8 +15,9 @@ type PageContainer struct {
|
|||
}
|
||||
|
||||
type InspectReq struct {
|
||||
ID string `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
ID string `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
Detail string `json:"detail"`
|
||||
}
|
||||
|
||||
type ContainerInfo struct {
|
||||
|
|
@ -284,17 +285,19 @@ type ComposeOperation struct {
|
|||
Path string `json:"path"`
|
||||
Operation string `json:"operation" validate:"required,oneof=up start restart stop down delete"`
|
||||
WithFile bool `json:"withFile"`
|
||||
Force bool `josn:"force"`
|
||||
Force bool `json:"force"`
|
||||
}
|
||||
type ComposeUpdate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Path string `json:"path" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
Env string `json:"env"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Path string `json:"path" validate:"required"`
|
||||
DetailPath string `json:"detailPath"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
Env string `json:"env"`
|
||||
}
|
||||
type ComposeLogClean struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Path string `json:"path" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Path string `json:"path" validate:"required"`
|
||||
DetailPath string `json:"detailPath"`
|
||||
}
|
||||
|
||||
type ContainerLog struct {
|
||||
|
|
|
|||
|
|
@ -19,12 +19,8 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/task"
|
||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
|
|
@ -45,7 +41,9 @@ import (
|
|||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/gin-gonic/gin"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/shirou/gopsutil/v4/cpu"
|
||||
"github.com/shirou/gopsutil/v4/mem"
|
||||
)
|
||||
|
|
@ -362,6 +360,9 @@ func (u *ContainerService) Inspect(req dto.InspectReq) (string, error) {
|
|||
}
|
||||
for _, container := range containers {
|
||||
config := container.Labels[composeConfigLabel]
|
||||
if len(req.Detail) != 0 && strings.Contains(config, req.Detail) {
|
||||
config = req.Detail
|
||||
}
|
||||
workdir := container.Labels[composeWorkdirLabel]
|
||||
if len(config) != 0 && len(workdir) != 0 && strings.Contains(config, workdir) {
|
||||
filePath = config
|
||||
|
|
@ -970,13 +971,20 @@ func collectLogs(done <-chan struct{}, params dto.StreamLog, messageChan chan<-
|
|||
var dockerCmd *exec.Cmd
|
||||
if params.Type == "compose" {
|
||||
dockerComposCmd := common.GetDockerComposeCommand()
|
||||
var yamlFiles []string
|
||||
for _, item := range strings.Split(params.Compose, ",") {
|
||||
if len(item) != 0 {
|
||||
yamlFiles = append(yamlFiles, "-f", item)
|
||||
}
|
||||
}
|
||||
if dockerComposCmd == "docker-compose" {
|
||||
newCmdArgs := append([]string{"-f", params.Compose}, cmdArgs...)
|
||||
newCmdArgs := append(yamlFiles, cmdArgs...)
|
||||
dockerCmd = exec.Command(dockerComposCmd, newCmdArgs...)
|
||||
} else {
|
||||
newCmdArgs := append([]string{"compose", "-f", params.Compose}, cmdArgs...)
|
||||
newCmdArgs := append(append([]string{"compose"}, yamlFiles...), cmdArgs...)
|
||||
dockerCmd = exec.Command("docker", newCmdArgs...)
|
||||
}
|
||||
global.LOG.Debug("Docker command:", dockerCmd.Args)
|
||||
} else {
|
||||
dockerCmd = exec.Command("docker", cmdArgs...)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package service
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
|
@ -24,7 +25,6 @@ import (
|
|||
"github.com/1Panel-dev/1Panel/agent/utils/docker"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
const composeProjectLabel = "com.docker.compose.project"
|
||||
|
|
@ -233,14 +233,15 @@ func (u *ContainerService) ComposeOperation(req dto.ComposeOperation) error {
|
|||
return err
|
||||
}
|
||||
if req.WithFile {
|
||||
_ = os.RemoveAll(path.Dir(req.Path))
|
||||
for _, item := range strings.Split(req.Path, ",") {
|
||||
if len(item) != 0 {
|
||||
_ = os.RemoveAll(path.Dir(item))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ = composeRepo.DeleteRecord(repo.WithByName(req.Name))
|
||||
return nil
|
||||
}
|
||||
if _, err := os.Stat(req.Path); err != nil {
|
||||
return fmt.Errorf("load file with path %s failed, %v", req.Path, err)
|
||||
}
|
||||
if req.Operation == "up" {
|
||||
if stdout, err := compose.Up(req.Path); err != nil {
|
||||
return fmt.Errorf("docker-compose up failed, std: %s, err: %v", stdout, err)
|
||||
|
|
@ -257,11 +258,11 @@ func (u *ContainerService) ComposeUpdate(req dto.ComposeUpdate) error {
|
|||
if cmd.CheckIllegal(req.Name, req.Path) {
|
||||
return buserr.New("ErrCmdIllegal")
|
||||
}
|
||||
oldFile, err := os.ReadFile(req.Path)
|
||||
oldFile, err := os.ReadFile(req.DetailPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("load file with path %s failed, %v", req.Path, err)
|
||||
return fmt.Errorf("load file with path %s failed, %v", req.DetailPath, err)
|
||||
}
|
||||
file, err := os.OpenFile(req.Path, os.O_WRONLY|os.O_TRUNC, 0640)
|
||||
file, err := os.OpenFile(req.DetailPath, os.O_WRONLY|os.O_TRUNC, 0640)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -270,8 +271,8 @@ func (u *ContainerService) ComposeUpdate(req dto.ComposeUpdate) error {
|
|||
_, _ = write.WriteString(req.Content)
|
||||
write.Flush()
|
||||
|
||||
global.LOG.Infof("docker-compose.yml %s has been replaced, now start to docker-compose restart", req.Path)
|
||||
if err := newComposeEnv(req.Path, req.Env); err != nil {
|
||||
global.LOG.Infof("docker-compose.yml %s has been replaced, now start to docker-compose restart", req.DetailPath)
|
||||
if err := newComposeEnv(req.DetailPath, req.Env); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -361,11 +362,8 @@ func (u *ContainerService) loadPath(req *dto.ComposeCreate) error {
|
|||
}
|
||||
|
||||
func removeContainerForCompose(composeName, composePath string) error {
|
||||
if _, err := os.Stat(composePath); err == nil {
|
||||
if stdout, err := compose.Operate(composePath, "down"); err != nil {
|
||||
return errors.New(stdout)
|
||||
}
|
||||
return nil
|
||||
if stdout, err := compose.Operate(composePath, "down"); err != nil {
|
||||
return errors.New(stdout)
|
||||
}
|
||||
var options container.ListOptions
|
||||
options.All = true
|
||||
|
|
@ -405,7 +403,11 @@ func recreateCompose(content, path string) error {
|
|||
|
||||
func loadEnv(list []dto.ComposeInfo) []dto.ComposeInfo {
|
||||
for i := 0; i < len(list); i++ {
|
||||
envFilePath := path.Join(path.Dir(list[i].Path), ".env")
|
||||
tmpPath := list[i].Path
|
||||
if strings.Contains(list[i].Path, ",") {
|
||||
tmpPath = strings.Split(list[i].Path, ",")[0]
|
||||
}
|
||||
envFilePath := path.Join(path.Dir(tmpPath), ".env")
|
||||
file, err := os.ReadFile(envFilePath)
|
||||
if err != nil {
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@ func Up(filePath string) (string, error) {
|
|||
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
|
||||
return cmd.NewCommandMgr(cmd.WithTimeout(20*time.Minute)).RunWithStdoutBashCf("%s %s up -d", global.CONF.DockerConfig.Command, loadFiles(filePath))
|
||||
}
|
||||
|
||||
func UpWithTask(filePath string, task *task.Task) error {
|
||||
|
|
@ -81,54 +80,56 @@ func UpWithTask(filePath string, task *task.Task) error {
|
|||
}
|
||||
}
|
||||
|
||||
dockerCommand := global.CONF.DockerConfig.Command
|
||||
if dockerCommand == "docker-compose" {
|
||||
return cmd.NewCommandMgr(cmd.WithTask(*task)).Run("docker-compose", "-f", filePath, "up", "-d")
|
||||
} else {
|
||||
return cmd.NewCommandMgr(cmd.WithTask(*task)).Run("docker", "compose", "-f", filePath, "up", "-d")
|
||||
}
|
||||
return cmd.NewCommandMgr(cmd.WithTask(*task)).Run("%s %s up -d", global.CONF.DockerConfig.Command, loadFiles(filePath))
|
||||
}
|
||||
|
||||
func Down(filePath string) (string, error) {
|
||||
if err := checkCmd(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashCfAndTimeOut(global.CONF.DockerConfig.Command+" -f %s down --remove-orphans", 20*time.Minute, filePath)
|
||||
return stdout, err
|
||||
return cmd.NewCommandMgr(cmd.WithTimeout(20*time.Minute)).RunWithStdoutBashCf("%s %s down --remove-orphans", global.CONF.DockerConfig.Command, loadFiles(filePath))
|
||||
}
|
||||
|
||||
func Stop(filePath string) (string, error) {
|
||||
if err := checkCmd(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s stop", filePath)
|
||||
return stdout, err
|
||||
return cmd.NewCommandMgr(cmd.WithTimeout(20*time.Minute)).RunWithStdoutBashCf("%s %s stop", global.CONF.DockerConfig.Command, loadFiles(filePath))
|
||||
}
|
||||
|
||||
func Restart(filePath string) (string, error) {
|
||||
if err := checkCmd(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s restart", filePath)
|
||||
return stdout, err
|
||||
return cmd.NewCommandMgr(cmd.WithTimeout(20*time.Minute)).RunWithStdoutBashCf("%s %s restart", global.CONF.DockerConfig.Command, loadFiles(filePath))
|
||||
}
|
||||
|
||||
func Operate(filePath, operation string) (string, error) {
|
||||
if err := checkCmd(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s %s", filePath, operation)
|
||||
return stdout, err
|
||||
return cmd.NewCommandMgr(cmd.WithTimeout(20*time.Minute)).RunWithStdoutBashCf("%s %s %s", global.CONF.DockerConfig.Command, loadFiles(filePath), operation)
|
||||
}
|
||||
|
||||
func DownAndUp(filePath string) (string, error) {
|
||||
if err := checkCmd(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s down", filePath)
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(20 * time.Minute))
|
||||
stdout, err := cmdMgr.RunWithStdoutBashCf("%s %s down", global.CONF.DockerConfig.Command, loadFiles(filePath))
|
||||
if err != nil {
|
||||
return stdout, err
|
||||
}
|
||||
stdout, err = cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s up -d", filePath)
|
||||
stdout, err = cmdMgr.RunWithStdoutBashCf("%s %s up -d", global.CONF.DockerConfig.Command, loadFiles(filePath))
|
||||
return stdout, err
|
||||
}
|
||||
|
||||
func loadFiles(filePath string) string {
|
||||
var fileItem []string
|
||||
for _, item := range strings.Split(filePath, ",") {
|
||||
if len(item) != 0 {
|
||||
fileItem = append(fileItem, fmt.Sprintf("-f %s", item))
|
||||
}
|
||||
}
|
||||
return strings.Join(fileItem, " ")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ export namespace Container {
|
|||
export interface ContainerInspect {
|
||||
id: string;
|
||||
type: string;
|
||||
detail: string;
|
||||
}
|
||||
export interface ContainerPrune {
|
||||
pruneType: string;
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ export const upCompose = (params: Container.ComposeCreate) => {
|
|||
export const testCompose = (params: Container.ComposeCreate) => {
|
||||
return http.post<boolean>(`/containers/compose/test`, params);
|
||||
};
|
||||
export const composeOperator = (params: Container.ComposeOperation) => {
|
||||
export const composeOperate = (params: Container.ComposeOperation) => {
|
||||
return http.post(`/containers/compose/operate`, params);
|
||||
};
|
||||
export const composeUpdate = (params: Container.ComposeUpdate) => {
|
||||
|
|
|
|||
|
|
@ -1017,6 +1017,7 @@ const message = {
|
|||
'If multiple private repositories exist, newlines must be displayed, for example:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
||||
|
||||
compose: 'Compose | Composes',
|
||||
composeFile: 'Compose File',
|
||||
fromChangeHelper: 'Switching the source will clean the current edited content. Do you want to continue?',
|
||||
composePathHelper: 'Configuration file save path: {0}',
|
||||
composeHelper:
|
||||
|
|
|
|||
|
|
@ -1021,7 +1021,9 @@ const message = {
|
|||
'Si hay varios mirrors, deben estar en líneas separadas. Ejemplo:\nhttp://xxxxxx.m.daocloud.io\nhttps://xxxxxx.mirror.aliyuncs.com',
|
||||
registrieHelper:
|
||||
'Si existen varios repositorios privados, deben estar en líneas separadas. Ejemplo:\n172.16.10.111:8081\n172.16.10.112:8081',
|
||||
|
||||
compose: 'Compose | Composes',
|
||||
composeFile: 'Archivo de Orquestación',
|
||||
fromChangeHelper: 'Cambiar la fuente limpiará el contenido actualmente editado. ¿Desea continuar?',
|
||||
composePathHelper: 'Ruta de guardado del archivo de configuración: {0}',
|
||||
composeHelper:
|
||||
|
|
|
|||
|
|
@ -995,6 +995,7 @@ const message = {
|
|||
registrieHelper: '複数のプライベートリポジトリが存在する場合、たとえばnewlinesを表示する必要があります。',
|
||||
|
||||
compose: '構成|作曲',
|
||||
composeFile: 'オーケストレーションファイル',
|
||||
fromChangeHelper: 'ソースを切り替えると、現在の編集されたコンテンツがきれいになります。続けたいですか?',
|
||||
composePathHelper: '構成ファイル保存パス:{0}',
|
||||
composeHelper:
|
||||
|
|
|
|||
|
|
@ -983,6 +983,7 @@ const message = {
|
|||
'개인 레지스트리가 여러 개 있을 경우 각 줄에 하나씩 표시해야 합니다. 예시:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
||||
|
||||
compose: '컴포즈 | 컴포즈들',
|
||||
composeFile: '컴포즈 파일',
|
||||
fromChangeHelper: '소스를 변경하면 현재 편집한 내용이 삭제됩니다. 계속 하시겠습니까?',
|
||||
composePathHelper: '구성 파일 저장 경로: {0}',
|
||||
composeHelper: '1Panel 에디터나 템플릿을 통해 생성된 컴포지션은 {0}/docker/compose 디렉토리에 저장됩니다.',
|
||||
|
|
|
|||
|
|
@ -1012,6 +1012,7 @@ const message = {
|
|||
'Jika terdapat banyak repositori persendirian, baris baru mesti dipaparkan, contohnya:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
||||
|
||||
compose: 'Compose | Compose-compose',
|
||||
composeFile: 'Fail Susunan',
|
||||
fromChangeHelper: 'Menukar sumber akan membersihkan kandungan yang sedang diedit. Adakah anda mahu meneruskan?',
|
||||
composePathHelper: 'Laluan simpan fail konfigurasi: {0}',
|
||||
composeHelper:
|
||||
|
|
|
|||
|
|
@ -1008,6 +1008,7 @@ const message = {
|
|||
'Se houver múltiplos repositórios privados, eles devem ser exibidos em novas linhas, por exemplo:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
||||
|
||||
compose: 'Compose | Composições',
|
||||
composeFile: 'Arquivo de Orquestração',
|
||||
fromChangeHelper: 'Trocar a origem limpará o conteúdo editado atual. Deseja continuar?',
|
||||
composePathHelper: 'Caminho de salvamento do arquivo de configuração: {0}',
|
||||
composeHelper:
|
||||
|
|
|
|||
|
|
@ -1007,6 +1007,7 @@ const message = {
|
|||
'Если существует несколько частных репозиториев, они должны быть разделены новой строкой, например:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
||||
|
||||
compose: 'Compose | Composes',
|
||||
composeFile: 'Файл Оркестрации',
|
||||
fromChangeHelper: 'Переключение источника очистит текущее отредактированное содержимое. Хотите продолжить?',
|
||||
composePathHelper: 'Путь сохранения файла конфигурации: {0}',
|
||||
composeHelper:
|
||||
|
|
|
|||
|
|
@ -1029,6 +1029,7 @@ const message = {
|
|||
'Birden fazla özel depo varsa, yeni satırlar gösterilmelidir, örneğin:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
||||
|
||||
compose: 'Compose | Composelar',
|
||||
composeFile: 'Düzenleme Dosyası',
|
||||
fromChangeHelper:
|
||||
'Kaynağın değiştirilmesi mevcut düzenlenen içeriği temizleyecektir. Devam etmek istiyor musunuz?',
|
||||
composePathHelper: 'Yapılandırma dosyası kaydetme yolu: {0}',
|
||||
|
|
|
|||
|
|
@ -970,6 +970,7 @@ const message = {
|
|||
registrieHelper: '當存在多個私有倉庫時,需要換行顯示,例:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
||||
|
||||
compose: '編排',
|
||||
composeFile: '編排檔案',
|
||||
fromChangeHelper: '切換來源將清空檔前已編輯內容,是否繼續?',
|
||||
composePathHelper: '設定檔儲存路徑: {0}',
|
||||
composeHelper: '通過 1Panel 編輯或者模版建立的編排,將儲存在 {0}/docker/compose 路徑下',
|
||||
|
|
|
|||
|
|
@ -972,6 +972,7 @@ const message = {
|
|||
registrieHelper: '当存在多个私有仓库时,需要换行显示,例:\n172.16.10.111:8081 \n172.16.10.112:8081',
|
||||
|
||||
compose: '编排',
|
||||
composeFile: '编排文件',
|
||||
fromChangeHelper: '切换来源将清空当前已编辑内容,是否继续?',
|
||||
composePathHelper: '配置文件保存路径: {0}',
|
||||
composeHelper: '通过 1Panel 编辑或者模版创建的编排,将保存在 {0}/docker/compose 路径下',
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import { FormInstance } from 'element-plus';
|
|||
import { ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { composeOperator } from '@/api/modules/container';
|
||||
import { composeOperate } from '@/api/modules/container';
|
||||
|
||||
let open = ref(false);
|
||||
let loading = ref(false);
|
||||
|
|
@ -76,7 +76,7 @@ const submit = async () => {
|
|||
withFile: deleteFile.value,
|
||||
force: force.value,
|
||||
};
|
||||
await composeOperator(params)
|
||||
await composeOperate(params)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
|
|
|
|||
|
|
@ -221,10 +221,24 @@
|
|||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-radio-group size="small" class="mt-1 mb-1" v-model="showType">
|
||||
<el-radio-group class="mt-1 mb-1" v-model="showType">
|
||||
<el-radio-button value="compose">{{ $t('container.compose') }}</el-radio-button>
|
||||
<el-radio-button value="log">{{ $t('commons.button.log') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-select
|
||||
class="p-w-300 mt-2 ml-2"
|
||||
v-model="currentYamlPath"
|
||||
@change="inspectCompose(currentCompose.name, currentYamlPath)"
|
||||
v-if="currentCompose.path.indexOf(',') !== -1"
|
||||
>
|
||||
<template #prefix>{{ $t('container.composeFile') }}</template>
|
||||
<el-option
|
||||
v-for="item in currentCompose.path.split(',')"
|
||||
:key="item"
|
||||
:value="item"
|
||||
:label="item.split('/').pop()"
|
||||
/>
|
||||
</el-select>
|
||||
<div v-show="showType === 'compose'">
|
||||
<CodemirrorPro
|
||||
v-model="composeContent"
|
||||
|
|
@ -357,7 +371,7 @@ import TerminalDialog from '@/views/container/container/terminal/index.vue';
|
|||
import ContainerLogDialog from '@/components/log/container-drawer/index.vue';
|
||||
import DeleteDialog from '@/views/container/compose/delete/index.vue';
|
||||
import {
|
||||
composeOperator,
|
||||
composeOperate,
|
||||
composeUpdate,
|
||||
containerItemStats,
|
||||
containerListStats,
|
||||
|
|
@ -381,6 +395,7 @@ const data = ref<any[]>([]);
|
|||
const loading = ref(false);
|
||||
const detailLoading = ref(false);
|
||||
const currentCompose = ref<Container.ComposeInfo | null>(null);
|
||||
const currentYamlPath = ref('');
|
||||
const composeContainers = ref([]);
|
||||
const composeContent = ref('');
|
||||
|
||||
|
|
@ -410,7 +425,7 @@ const form = reactive({
|
|||
path: '',
|
||||
file: '',
|
||||
template: null as number,
|
||||
env: [],
|
||||
env: '',
|
||||
});
|
||||
const rules = reactive({
|
||||
name: [Rules.requiredInput, Rules.composeName],
|
||||
|
|
@ -491,9 +506,14 @@ const loadDetail = async (row: Container.ComposeInfo, withRefresh: boolean) => {
|
|||
isOnCreate.value = false;
|
||||
detailLoading.value = true;
|
||||
currentCompose.value = row;
|
||||
currentYamlPath.value = row.path.indexOf(',') !== -1 ? row.path.split(',')[0] : row.path;
|
||||
env.value = row.env || '';
|
||||
composeContainers.value = row.containers || [];
|
||||
await inspect({ id: currentCompose.value.name, type: 'compose' })
|
||||
inspectCompose(row.name, currentYamlPath.value);
|
||||
};
|
||||
|
||||
const inspectCompose = async (name: string, detailPath: string) => {
|
||||
await inspect({ id: name, type: 'compose', detail: detailPath })
|
||||
.then((res) => {
|
||||
composeContent.value = res.data;
|
||||
detailLoading.value = false;
|
||||
|
|
@ -521,7 +541,7 @@ const onOpenDialog = async () => {
|
|||
form.path = '';
|
||||
form.file = '';
|
||||
form.template = null;
|
||||
form.env = [];
|
||||
form.env = '';
|
||||
loadPath();
|
||||
loadTemplates();
|
||||
};
|
||||
|
|
@ -613,7 +633,7 @@ const handleComposeOperate = async (operation: 'up' | 'stop' | 'restart', row: a
|
|||
withFile: false,
|
||||
force: false,
|
||||
};
|
||||
await composeOperator(params)
|
||||
await composeOperate(params)
|
||||
.then(async () => {
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
await search();
|
||||
|
|
@ -642,6 +662,7 @@ const onSubmitEdit = async () => {
|
|||
const param = {
|
||||
name: currentCompose.value.name,
|
||||
path: currentCompose.value.path,
|
||||
detailPath: currentYamlPath.value,
|
||||
content: composeContent.value,
|
||||
createdBy: currentCompose.value.createdBy,
|
||||
env: env.value || '',
|
||||
|
|
@ -700,7 +721,7 @@ const onInspectContainer = async (item: any) => {
|
|||
if (!item.containerID) {
|
||||
return;
|
||||
}
|
||||
const res = await inspect({ id: item.containerID, type: 'container' });
|
||||
const res = await inspect({ id: item.containerID, type: 'container', detail: '' });
|
||||
containerInspectRef.value!.acceptParams({ data: res.data, ports: item.ports || [] });
|
||||
};
|
||||
const onOpenTerminal = (row: any) => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue