From 9343813ace09bc3ba409c300745fa307ebf31cbd Mon Sep 17 00:00:00 2001 From: Andy Lee Date: Wed, 19 Mar 2025 17:42:02 +0800 Subject: [PATCH] Add volum mode options in create VM volume tab (#209) * add volume mode option for non-longhorn volume Signed-off-by: Andy Lee * fix default storage class in create VM page Signed-off-by: Andy Lee --------- Signed-off-by: Andy Lee --- .../VirtualMachineVolume/index.vue | 9 ++- .../VirtualMachineVolume/type/volume.vue | 72 +++++++++++++++++-- pkg/harvester/mixins/harvester-vm/index.js | 6 -- 3 files changed, 75 insertions(+), 12 deletions(-) diff --git a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/index.vue b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/index.vue index 29888929..fe9c725e 100644 --- a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/index.vue +++ b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/index.vue @@ -7,8 +7,7 @@ import UnitInput from '@shell/components/form/UnitInput'; import { LabeledInput } from '@components/Form/LabeledInput'; import LabeledSelect from '@shell/components/form/LabeledSelect'; import ModalWithCard from '@shell/components/ModalWithCard'; - -import { PVC } from '@shell/config/types'; +import { PVC, STORAGE_CLASS } from '@shell/config/types'; import { clone } from '@shell/utils/object'; import { ucFirst, randomStr } from '@shell/utils/string'; import { removeObject } from '@shell/utils/array'; @@ -117,6 +116,12 @@ export default { return this.mode === _CREATE; }, + defaultStorageClass() { + const defaultStorage = this.$store.getters['harvester/all'](STORAGE_CLASS).find((sc) => sc.isDefault); + + return defaultStorage; + }, + showVolumeTip() { const imageName = this.getImageDisplayName(this.rows[0]?.image); diff --git a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/volume.vue b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/volume.vue index e5e9d186..1a370d63 100644 --- a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/volume.vue +++ b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/volume.vue @@ -13,6 +13,7 @@ import { ucFirst } from '@shell/utils/string'; import { LVM_DRIVER } from '../../../../models/harvester/storage.k8s.io.storageclass'; import { DATA_ENGINE_V2 } from '../../../../models/harvester/persistentvolumeclaim'; import { GIBIBYTE } from '../../../../utils/unit'; +import { VOLUME_MODE } from '@pkg/harvester/config/types'; export default { name: 'HarvesterEditVolume', @@ -71,6 +72,10 @@ export default { return this.$store.getters['harvester-common/getFeatureEnabled']('longhornV2LVMSupport'); }, + thirdPartyStorageClassEnabled() { + return this.$store.getters['harvester-common/getFeatureEnabled']('thirdPartyStorage'); + }, + encryptionValue() { return ucFirst(String(this.value.isEncrypted)); }, @@ -91,6 +96,18 @@ export default { return allPVCs.find((P) => P.id === `${ this.namespace }/${ this.value.volumeName }`); }, + showVolumeMode() { + if (!this.thirdPartyStorageClassEnabled || !!this.value?.storageClassName === false) { + return false; + } + + if (this.isLonghornStorageClass) { + return false; + } + + return true; + }, + isDisabled() { return !this.value.newCreateId && this.isEdit && this.isVirtualType; }, @@ -112,7 +129,17 @@ export default { isLonghornV2() { return this.value.pvc?.isLonghornV2 || this.value.pvc?.storageClass?.isLonghornV2; - } + }, + + isLonghornStorageClass() { + const selectedSC = this.storageClasses.find((sc) => sc.name === this.value?.storageClassName) || {}; + + return selectedSC && selectedSC.isLonghorn; + }, + + volumeModeOptions() { + return Object.values(VOLUME_MODE); + }, }, watch: { @@ -120,6 +147,8 @@ export default { immediate: true, handler(neu) { this.value.accessMode = this.getAccessMode(neu); + this.value.volumeMode = this.getVolumeMode(neu, this.value.volumeMode); + this.update(); } }, @@ -151,6 +180,20 @@ export default { }, methods: { + getVolumeMode(storageClassName, originalVolumeMode) { + if (!this.thirdPartyStorageClassEnabled) { + return VOLUME_MODE.BLOCK; + } + const storageClass = this.storageClasses.find((sc) => sc.name === storageClassName); + + // longhorn v1, v2 use block volumeMode + if (storageClass && storageClass.isLonghorn) { + return VOLUME_MODE.BLOCK; + } + + return originalVolumeMode; + }, + getAccessMode(storageClassName) { if (!this.longhornV2LVMSupport) { return 'ReadWriteMany'; @@ -286,6 +329,29 @@ export default { /> +
+ + + +
+ +
-
-
O.isDefault); - - return defaultStorage; - }, - storageClassSetting() { try { const storageClassValue = this.$store.getters[`${ this.inStore }/all`](HCI.SETTING).find( (O) => O.id === HCI_SETTING.DEFAULT_STORAGE_CLASS)?.value;