diff --git a/backend/app/dto/container.go b/backend/app/dto/container.go index 5907fcdc1..cec2f20a2 100644 --- a/backend/app/dto/container.go +++ b/backend/app/dto/container.go @@ -98,6 +98,7 @@ type ContainerStats struct { } type VolumeHelper struct { + Type string `json:"type"` SourceDir string `json:"sourceDir"` ContainerDir string `json:"containerDir"` Mode string `json:"mode"` diff --git a/backend/app/service/container.go b/backend/app/service/container.go index e41decc21..4aa8e2bfc 100644 --- a/backend/app/service/container.go +++ b/backend/app/service/container.go @@ -29,6 +29,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/registry" "github.com/docker/docker/client" @@ -442,7 +443,7 @@ func (u *ContainerService) ContainerInfo(req dto.OperationWithName) (*dto.Contai if oldContainer.HostConfig.Memory != 0 { data.Memory = float64(oldContainer.HostConfig.Memory) / 1024 / 1024 } - data.Volumes = loadVolumeBinds(oldContainer.HostConfig.Binds) + data.Volumes = loadVolumeBinds(oldContainer.Mounts) return &data, nil } @@ -994,10 +995,19 @@ func loadConfigInfo(isCreate bool, req dto.ContainerOperate, oldContainer *types hostConf.MemorySwap = 0 hostConf.PortBindings = portMap hostConf.Binds = []string{} + hostConf.Mounts = []mount.Mount{} config.Volumes = make(map[string]struct{}) for _, volume := range req.Volumes { - config.Volumes[volume.ContainerDir] = struct{}{} - hostConf.Binds = append(hostConf.Binds, fmt.Sprintf("%s:%s:%s", volume.SourceDir, volume.ContainerDir, volume.Mode)) + if volume.Type == "volume" { + hostConf.Mounts = append(hostConf.Mounts, mount.Mount{ + Type: mount.Type(volume.Type), + Source: volume.SourceDir, + Target: volume.ContainerDir, + }) + config.Volumes[volume.ContainerDir] = struct{}{} + } else { + hostConf.Binds = append(hostConf.Binds, fmt.Sprintf("%s:%s:%s", volume.SourceDir, volume.ContainerDir, volume.Mode)) + } } return &config, &hostConf, &networkConf, nil } @@ -1024,40 +1034,21 @@ func reCreateAfterUpdate(name string, client *client.Client, config *container.C global.LOG.Errorf("recreate after container update successful") } -func loadVolumeBinds(binds []string) []dto.VolumeHelper { +func loadVolumeBinds(binds []types.MountPoint) []dto.VolumeHelper { var datas []dto.VolumeHelper for _, bind := range binds { - parts := strings.Split(bind, ":") var volumeItem dto.VolumeHelper - if len(parts) > 3 { - continue + volumeItem.Type = string(bind.Type) + if bind.Type == "volume" { + volumeItem.SourceDir = bind.Name + } else { + volumeItem.SourceDir = bind.Source } - volumeItem.SourceDir = parts[0] - if len(parts) == 1 { - volumeItem.ContainerDir = parts[0] + volumeItem.ContainerDir = bind.Destination + volumeItem.Mode = "ro" + if bind.RW { volumeItem.Mode = "rw" } - if len(parts) == 2 { - switch parts[1] { - case "r", "ro": - volumeItem.ContainerDir = parts[0] - volumeItem.Mode = "ro" - case "rw": - volumeItem.ContainerDir = parts[0] - volumeItem.Mode = "rw" - default: - volumeItem.ContainerDir = parts[1] - volumeItem.Mode = "rw" - } - } - if len(parts) == 3 { - volumeItem.ContainerDir = parts[1] - if parts[2] == "r" { - volumeItem.Mode = "ro" - } else { - volumeItem.Mode = parts[2] - } - } datas = append(datas, volumeItem) } return datas diff --git a/frontend/src/api/interface/container.ts b/frontend/src/api/interface/container.ts index cf99eedf7..3bd63b217 100644 --- a/frontend/src/api/interface/container.ts +++ b/frontend/src/api/interface/container.ts @@ -56,10 +56,10 @@ export namespace Container { protocol: string; } export interface Volume { + type: string; sourceDir: string; containerDir: string; mode: string; - isVolume: boolean; } export interface ContainerInfo { containerID: string; diff --git a/frontend/src/components/log-file/index.vue b/frontend/src/components/log-file/index.vue index 53529d5e1..9d49881b6 100644 --- a/frontend/src/components/log-file/index.vue +++ b/frontend/src/components/log-file/index.vue @@ -98,7 +98,7 @@ const readReq = reactive({ page: 0, pageSize: 2000, }); -const emit = defineEmits(['update:loading', 'update:hasContent']); +const emit = defineEmits(['update:loading', 'update:hasContent', 'update:isReading']); const handleReady = (payload) => { view.value = payload.view; @@ -152,6 +152,7 @@ const stopSignals = [ ]; const getContent = () => { + emit('update:isReading', true); if (!end.value) { readReq.page += 1; } @@ -219,6 +220,7 @@ const onDownload = async () => { }; const onCloseLog = async () => { + emit('update:isReading', false); tailLog.value = false; clearInterval(Number(timer)); timer = null; diff --git a/frontend/src/views/container/compose/create/index.vue b/frontend/src/views/container/compose/create/index.vue index fa0600041..26d98e81c 100644 --- a/frontend/src/views/container/compose/create/index.vue +++ b/frontend/src/views/container/compose/create/index.vue @@ -30,33 +30,27 @@ - - - - - - - - {{ $t('container.composePathHelper', [composeFile]) }} - - - - - - - - - - - - + + + + + + + + + + + + {{ $t('container.composePathHelper', [composeFile]) }} + +
@@ -81,6 +75,7 @@
{{ $t('commons.button.cancel') }} - + {{ $t('commons.button.confirm') }} @@ -124,7 +119,6 @@ const extensions = [javascript(), oneDark]; const showLog = ref(false); const loading = ref(); const mode = ref('edit'); -const onCreating = ref(); const oldFrom = ref('edit'); const drawerVisible = ref(false); const templateOptions = ref(); @@ -132,6 +126,7 @@ const baseDir = ref(); const composeFile = ref(); let timer: NodeJS.Timer | null = null; const logRef = ref(); +const isReading = ref(); const logConfig = reactive({ type: 'compose-create', @@ -164,7 +159,6 @@ const acceptParams = (): void => { form.path = ''; form.file = ''; form.template = null; - onCreating.value = false; loadTemplates(); loadPath(); }; @@ -237,7 +231,6 @@ const onSubmit = async (formEl: FormInstance | undefined) => { .then(async (res) => { loading.value = false; if (res.data) { - onCreating.value = true; mode.value = 'log'; await upCompose(form) .then((res) => { @@ -246,7 +239,6 @@ const onSubmit = async (formEl: FormInstance | undefined) => { }) .catch(() => { loading.value = false; - onCreating.value = false; }); } }) diff --git a/frontend/src/views/container/container/operate/index.vue b/frontend/src/views/container/container/operate/index.vue index fc8cd69a4..2d1b09e37 100644 --- a/frontend/src/views/container/container/operate/index.vue +++ b/frontend/src/views/container/container/operate/index.vue @@ -138,9 +138,9 @@
- - {{ $t('container.volumeOption') }} - {{ $t('container.hostOption') }} + + {{ $t('container.volumeOption') }} + {{ $t('container.hostOption') }} - +
@@ -403,10 +406,10 @@ const goRouter = async () => { const handleVolumesAdd = () => { let item = { + type: 'bind', sourceDir: '', containerDir: '', mode: 'rw', - isVolume: true, }; dialogData.value.rowData!.volumes.push(item); }; @@ -427,18 +430,6 @@ const loadImageOptions = async () => { const loadVolumeOptions = async () => { const res = await listVolume(); volumes.value = res.data; - for (const item of dialogData.value.rowData.volumes) { - let isVolume = false; - for (const v of volumes.value) { - if (item.sourceDir == v.option) { - item.isVolume = true; - break; - } - if (!isVolume) { - item.isVolume = false; - } - } - } }; const loadNetworkOptions = async () => { const res = await listNetwork();