diff --git a/backend/app/service/container_volume.go b/backend/app/service/container_volume.go index f6259c855..50a6f50e5 100644 --- a/backend/app/service/container_volume.go +++ b/backend/app/service/container_volume.go @@ -2,11 +2,13 @@ package service import ( "context" + "fmt" "sort" "strings" "time" "github.com/1Panel-dev/1Panel/backend/app/dto" + "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/utils/docker" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" @@ -104,14 +106,28 @@ func (u *ContainerService) CreateVolume(req dto.VolumeCreat) error { if err != nil { return err } + var array []filters.KeyValuePair + array = append(array, filters.Arg("name", req.Name)) + vos, _ := client.VolumeList(context.TODO(), filters.NewArgs(array...)) + if len(vos.Volumes) != 0 { + for _, v := range vos.Volumes { + if v.Name == req.Name { + return constant.ErrRecordExist + } + } + } options := volume.VolumeCreateBody{ Name: req.Name, Driver: req.Driver, DriverOpts: stringsToMap(req.Options), Labels: stringsToMap(req.Labels), } - if _, err := client.VolumeCreate(context.TODO(), options); err != nil { + stat, err := client.VolumeCreate(context.TODO(), options) + if err != nil { return err } + // if len(stat.CreatedAt) != 0 { + fmt.Println(stat) + // } return nil } diff --git a/frontend/src/views/container/compose/create/index.vue b/frontend/src/views/container/compose/create/index.vue index 9f84af934..d7fa46864 100644 --- a/frontend/src/views/container/compose/create/index.vue +++ b/frontend/src/views/container/compose/create/index.vue @@ -7,9 +7,6 @@ - - - {{ $t('commons.button.edit') }} @@ -27,6 +24,12 @@ + + + + + {{ $t('container.composePathHelper', [composeFile]) }} + { if (value.indexOf('docker-compose.yml') === -1) { @@ -102,7 +108,7 @@ const form = reactive({ template: null as number, }); const rules = reactive({ - name: [Rules.requiredInput, Rules.name], + name: [Rules.requiredInput, Rules.imageName], path: [Rules.requiredSelect, { validator: varifyPath, trigger: 'change', required: true }], }); @@ -121,6 +127,7 @@ const acceptParams = (): void => { form.path = ''; form.file = ''; loadTemplates(); + loadPath(); }; const emit = defineEmits<{ (e: 'search'): void }>(); @@ -128,6 +135,16 @@ const handleClose = () => { drawerVisiable.value = false; }; +const loadPath = async () => { + const pathRes = await loadBaseDir(); + baseDir.value = pathRes.data; + changePath(); +}; + +const changePath = async () => { + composeFile.value = baseDir.value + '/docker/compose/' + form.name + '/docker-compose.yml'; +}; + type FormInstance = InstanceType; const formRef = ref(); diff --git a/frontend/src/views/container/compose/detail/index.vue b/frontend/src/views/container/compose/detail/index.vue index 231e05270..dcef1d5a7 100644 --- a/frontend/src/views/container/compose/detail/index.vue +++ b/frontend/src/views/container/compose/detail/index.vue @@ -210,6 +210,20 @@ const checkStatus = (operation: string) => { } } return false; + case 'pause': + for (const item of selects.value) { + if (item.state === 'paused' || item.state === 'exited') { + return true; + } + } + return false; + case 'unpause': + for (const item of selects.value) { + if (item.state !== 'paused') { + return true; + } + } + return false; } }; diff --git a/frontend/src/views/container/container/create/index.vue b/frontend/src/views/container/container/create/index.vue index 15d45b488..c7e0e364d 100644 --- a/frontend/src/views/container/container/create/index.vue +++ b/frontend/src/views/container/container/create/index.vue @@ -208,7 +208,7 @@ import { ElForm } from 'element-plus'; import DrawerHeader from '@/components/drawer-header/index.vue'; import { listImage, listVolume, createContainer } from '@/api/modules/container'; import { Container } from '@/api/interface/container'; -import { MsgSuccess } from '@/utils/message'; +import { MsgError, MsgSuccess } from '@/utils/message'; const loading = ref(false); @@ -292,6 +292,14 @@ const loadVolumeOptions = async () => { volumes.value = res.data; }; const onSubmit = async (formEl: FormInstance | undefined) => { + if (form.volumes.length !== 0) { + for (const item of form.volumes) { + if (!item.containerDir || !item.sourceDir) { + MsgError(i18n.global.t('container.volumeHelper')); + return; + } + } + } if (!formEl) return; formEl.validate(async (valid) => { if (!valid) return; diff --git a/frontend/src/views/container/volume/create/index.vue b/frontend/src/views/container/volume/create/index.vue index ffec58001..d31c900b1 100644 --- a/frontend/src/views/container/volume/create/index.vue +++ b/frontend/src/views/container/volume/create/index.vue @@ -75,6 +75,11 @@ const form = reactive({ }); const acceptParams = (): void => { + form.name = ''; + form.labels = []; + form.labelStr = ''; + form.options = []; + form.optionStr = ''; drawerVisiable.value = true; }; const emit = defineEmits<{ (e: 'search'): void }>(); @@ -84,7 +89,7 @@ const handleClose = () => { }; const rules = reactive({ - name: [Rules.requiredInput, Rules.name], + name: [Rules.requiredInput, Rules.volumeName], driver: [Rules.requiredSelect], });