mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2025-12-13 21:21:44 +00:00
Add volumeMode dropdown for third-party storage (#197)
Signed-off-by: Andy Lee <andy.lee@suse.com>
This commit is contained in:
parent
374b904191
commit
90c923b480
@ -50,6 +50,7 @@ export const HCI = {
|
|||||||
STORAGE_NETWORK: 'storage-network.settings.harvesterhci.io',
|
STORAGE_NETWORK: 'storage-network.settings.harvesterhci.io',
|
||||||
ADDON_EXPERIMENTAL: 'addon.harvesterhci.io/experimental',
|
ADDON_EXPERIMENTAL: 'addon.harvesterhci.io/experimental',
|
||||||
VOLUME_ERROR: 'longhorn.io/volume-scheduling-error',
|
VOLUME_ERROR: 'longhorn.io/volume-scheduling-error',
|
||||||
|
VOLUME_FOR_VM: 'harvesterhci.io/volumeForVirtualMachine',
|
||||||
KVM_AMD_CPU: 'cpu-feature.node.kubevirt.io/svm',
|
KVM_AMD_CPU: 'cpu-feature.node.kubevirt.io/svm',
|
||||||
KVM_INTEL_CPU: 'cpu-feature.node.kubevirt.io/vmx',
|
KVM_INTEL_CPU: 'cpu-feature.node.kubevirt.io/vmx',
|
||||||
NODE_MANUFACTURER: 'manufacturer',
|
NODE_MANUFACTURER: 'manufacturer',
|
||||||
|
|||||||
@ -7,3 +7,8 @@ export const NETWORK_TYPE = {
|
|||||||
L2VLAN: 'L2VlanNetwork',
|
L2VLAN: 'L2VlanNetwork',
|
||||||
UNTAGGED: 'UntaggedNetwork'
|
UNTAGGED: 'UntaggedNetwork'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const VOLUME_MODE = {
|
||||||
|
BLOCK: 'Block',
|
||||||
|
FILE_SYSTEM: 'Filesystem'
|
||||||
|
};
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import { HCI, VOLUME_SNAPSHOT } from '../types';
|
|||||||
import { LVM_DRIVER } from '../models/harvester/storage.k8s.io.storageclass';
|
import { LVM_DRIVER } from '../models/harvester/storage.k8s.io.storageclass';
|
||||||
import { DATA_ENGINE_V2 } from '../models/harvester/persistentvolumeclaim';
|
import { DATA_ENGINE_V2 } from '../models/harvester/persistentvolumeclaim';
|
||||||
import { GIBIBYTE } from '../utils/unit';
|
import { GIBIBYTE } from '../utils/unit';
|
||||||
|
import { VOLUME_MODE } from '@pkg/harvester/config/types';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'HarvesterVolume',
|
name: 'HarvesterVolume',
|
||||||
@ -73,7 +74,8 @@ export default {
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
if (this.mode === _CREATE) {
|
if (this.mode === _CREATE) {
|
||||||
this.value.spec.volumeMode = 'Block';
|
// default volumeMode to Block
|
||||||
|
this.value.spec.volumeMode = VOLUME_MODE.BLOCK;
|
||||||
this.value.spec.accessModes = ['ReadWriteMany'];
|
this.value.spec.accessModes = ['ReadWriteMany'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +128,10 @@ export default {
|
|||||||
return InterfaceOption;
|
return InterfaceOption;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
volumeModeOptions() {
|
||||||
|
return Object.values(VOLUME_MODE);
|
||||||
|
},
|
||||||
|
|
||||||
imageOption() {
|
imageOption() {
|
||||||
return sortBy(
|
return sortBy(
|
||||||
this.images
|
this.images
|
||||||
@ -179,6 +185,25 @@ export default {
|
|||||||
return this.$store.getters[`${ inStore }/all`](STORAGE_CLASS);
|
return this.$store.getters[`${ inStore }/all`](STORAGE_CLASS);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
isLonghornStorageClass() {
|
||||||
|
const selectedSC = this.storageClasses.find((sc) => sc.name === this.value?.spec?.storageClassName) || {};
|
||||||
|
|
||||||
|
return selectedSC && selectedSC.isLonghorn;
|
||||||
|
},
|
||||||
|
|
||||||
|
showVolumeMode() {
|
||||||
|
// we won't let user choose volumeMode if source = vmimage
|
||||||
|
if (!this.value.thirdPartyStorageFeatureEnabled || this.isVMImage || !!this.value?.spec?.storageClassName === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isLonghornStorageClass) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
storageClassOptions() {
|
storageClassOptions() {
|
||||||
return this.storageClasses.filter((s) => !s.parameters?.backingImage).map((s) => {
|
return this.storageClasses.filter((s) => !s.parameters?.backingImage).map((s) => {
|
||||||
const label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
const label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||||
@ -237,7 +262,43 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
'source'(neu) {
|
||||||
|
if (neu === 'url') {
|
||||||
|
this.setBlockVolumeMode();
|
||||||
|
this.deleteVolumeForVmAnnotation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'value.spec.storageClassName'() {
|
||||||
|
if (this.isLonghornStorageClass) {
|
||||||
|
this.setBlockVolumeMode();
|
||||||
|
this.deleteVolumeForVmAnnotation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'value.spec.volumeMode'(neu) {
|
||||||
|
if (neu === VOLUME_MODE.FILE_SYSTEM) {
|
||||||
|
this.setVolumeForVmAnnotation();
|
||||||
|
} else if (neu === VOLUME_MODE.BLOCK ) {
|
||||||
|
this.deleteVolumeForVmAnnotation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
setBlockVolumeMode() {
|
||||||
|
this.value.spec.volumeMode = VOLUME_MODE.BLOCK;
|
||||||
|
},
|
||||||
|
|
||||||
|
setVolumeForVmAnnotation() {
|
||||||
|
this.value.setAnnotation(HCI_ANNOTATIONS.VOLUME_FOR_VM, 'true');
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteVolumeForVmAnnotation() {
|
||||||
|
if (this.value?.metadata?.annotations?.[HCI_ANNOTATIONS.VOLUME_FOR_VM]) {
|
||||||
|
delete this.value.metadata.annotations[HCI_ANNOTATIONS.VOLUME_FOR_VM];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
getAccessMode() {
|
getAccessMode() {
|
||||||
if (!this.longhornV2LVMSupport) {
|
if (!this.longhornV2LVMSupport) {
|
||||||
return ['ReadWriteMany'];
|
return ['ReadWriteMany'];
|
||||||
@ -359,7 +420,7 @@ export default {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<LabeledSelect
|
<LabeledSelect
|
||||||
v-if="source === 'blank'"
|
v-if="isBlank"
|
||||||
v-model:value="value.spec.storageClassName"
|
v-model:value="value.spec.storageClassName"
|
||||||
:options="storageClassOptions"
|
:options="storageClassOptions"
|
||||||
:label="t('harvester.storage.storageClass.label')"
|
:label="t('harvester.storage.storageClass.label')"
|
||||||
@ -369,6 +430,18 @@ export default {
|
|||||||
@update:value="update"
|
@update:value="update"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<LabeledSelect
|
||||||
|
v-if="showVolumeMode"
|
||||||
|
v-model:value="value.spec.volumeMode"
|
||||||
|
:label="t('harvester.volume.volumeMode')"
|
||||||
|
:options="volumeModeOptions"
|
||||||
|
required
|
||||||
|
:disabled="!isCreate"
|
||||||
|
:mode="mode"
|
||||||
|
class="mb-20"
|
||||||
|
@update:value="update"
|
||||||
|
/>
|
||||||
|
|
||||||
<UnitInput
|
<UnitInput
|
||||||
v-model:value="storage"
|
v-model:value="storage"
|
||||||
:label="t('harvester.volume.size')"
|
:label="t('harvester.volume.size')"
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { PLUGIN_DEVELOPER, DEV } from '@shell/store/prefs';
|
|||||||
import { SOURCE_TYPE } from '../../../config/harvester-map';
|
import { SOURCE_TYPE } from '../../../config/harvester-map';
|
||||||
import { PRODUCT_NAME as HARVESTER_PRODUCT } from '../../../config/harvester';
|
import { PRODUCT_NAME as HARVESTER_PRODUCT } from '../../../config/harvester';
|
||||||
import { HCI } from '../../../types';
|
import { HCI } from '../../../types';
|
||||||
|
import { VOLUME_MODE } from '@pkg/harvester/config/types';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
emits: ['update:value'],
|
emits: ['update:value'],
|
||||||
@ -62,7 +63,7 @@ export default {
|
|||||||
|
|
||||||
customVolumeMode: {
|
customVolumeMode: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'Block'
|
default: VOLUME_MODE.Block
|
||||||
},
|
},
|
||||||
|
|
||||||
customAccessMode: {
|
customAccessMode: {
|
||||||
|
|||||||
@ -791,6 +791,7 @@ harvester:
|
|||||||
datasource: Data Source
|
datasource: Data Source
|
||||||
details: Details
|
details: Details
|
||||||
size: Size
|
size: Size
|
||||||
|
volumeMode: Volume Mode
|
||||||
source: Source
|
source: Source
|
||||||
kind: Kind
|
kind: Kind
|
||||||
sourceOptions:
|
sourceOptions:
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import { HCI } from '../../types';
|
|||||||
import { parseVolumeClaimTemplates } from '../../utils/vm';
|
import { parseVolumeClaimTemplates } from '../../utils/vm';
|
||||||
import impl, { QGA_JSON, USB_TABLET } from './impl';
|
import impl, { QGA_JSON, USB_TABLET } from './impl';
|
||||||
import { GIBIBYTE } from '../../utils/unit';
|
import { GIBIBYTE } from '../../utils/unit';
|
||||||
|
import { VOLUME_MODE } from '@pkg/harvester/config/types';
|
||||||
|
|
||||||
const LONGHORN_V2_DATA_ENGINE = 'longhorn-system/v2-data-engine';
|
const LONGHORN_V2_DATA_ENGINE = 'longhorn-system/v2-data-engine';
|
||||||
|
|
||||||
@ -261,7 +262,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
customVolumeMode() {
|
customVolumeMode() {
|
||||||
return this.storageClassSetting.volumeMode || 'Block';
|
return this.storageClassSetting.volumeMode || VOLUME_MODE.BLOCK;
|
||||||
},
|
},
|
||||||
|
|
||||||
customAccessMode() {
|
customAccessMode() {
|
||||||
@ -463,7 +464,7 @@ export default {
|
|||||||
type,
|
type,
|
||||||
storageClassName: '',
|
storageClassName: '',
|
||||||
image: this.imageId,
|
image: this.imageId,
|
||||||
volumeMode: 'Block',
|
volumeMode: VOLUME_MODE.BLOCK,
|
||||||
isEncrypted,
|
isEncrypted,
|
||||||
volumeBackups,
|
volumeBackups,
|
||||||
});
|
});
|
||||||
@ -522,7 +523,7 @@ export default {
|
|||||||
accessMode = pvcResource?.spec?.accessModes?.[0] || 'ReadWriteMany';
|
accessMode = pvcResource?.spec?.accessModes?.[0] || 'ReadWriteMany';
|
||||||
size = pvcResource?.spec?.resources?.requests?.storage || '10Gi';
|
size = pvcResource?.spec?.resources?.requests?.storage || '10Gi';
|
||||||
storageClassName = pvcResource?.spec?.storageClassName;
|
storageClassName = pvcResource?.spec?.storageClassName;
|
||||||
volumeMode = pvcResource?.spec?.volumeMode || 'Block';
|
volumeMode = pvcResource?.spec?.volumeMode || VOLUME_MODE.BLOCK;
|
||||||
volumeName = pvcResource?.metadata?.name || '';
|
volumeName = pvcResource?.metadata?.name || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -62,6 +62,10 @@ export default class HciStorageClass extends StorageClass {
|
|||||||
return this.parameters?.encrypted === 'true';
|
return this.parameters?.encrypted === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isLonghorn() {
|
||||||
|
return this.provisioner === LONGHORN_DRIVER;
|
||||||
|
}
|
||||||
|
|
||||||
get isLonghornV1() {
|
get isLonghornV1() {
|
||||||
return this.provisioner === LONGHORN_DRIVER && this.longhornVersion === DATA_ENGINE_V1;
|
return this.provisioner === LONGHORN_DRIVER && this.longhornVersion === DATA_ENGINE_V1;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user