mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2025-12-13 13:11:43 +00:00
chore: disable vmstate-persistence and longhorn-static StorageClasses (#377)
* chore: disable vmstate-persistence and longhorn-static StorageClasses Signed-off-by: Nick Chung <nick.chung@suse.com> * chore: allow internal storage class deletions in image and volumn Signed-off-by: Nick Chung <nick.chung@suse.com> * chore: remove deletion tooltips in image and volume pages Signed-off-by: Nick Chung <nick.chung@suse.com> * chore: rollback style changes of image and volume lists Signed-off-by: Nick Chung <nick.chung@suse.com> --------- Signed-off-by: Nick Chung <nick.chung@suse.com>
This commit is contained in:
parent
193d4536e3
commit
b775ce5f50
@ -17,4 +17,9 @@ export const VOLUME_MODE = {
|
||||
export const NETWORK_PROTOCOL = {
|
||||
IPv4: 'IPv4',
|
||||
IPv6: 'IPv6',
|
||||
}
|
||||
|
||||
export const INTERNAL_STORAGE_CLASS = {
|
||||
VMSTATE_PERSISTENCE: 'vmstate-persistence',
|
||||
LONGHORN_STATIC: 'longhorn-static',
|
||||
};
|
||||
|
||||
@ -10,6 +10,7 @@ import { LabeledInput } from '@components/Form/LabeledInput';
|
||||
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
||||
import { NAMESPACE, STORAGE_CLASS } from '@shell/config/types';
|
||||
import { allHash } from '@shell/utils/promise';
|
||||
import { isInternalStorageClass } from '../utils/storage-class';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterExportImageDialog',
|
||||
@ -105,11 +106,17 @@ export default {
|
||||
}
|
||||
|
||||
const options = storages.filter((s) => !s.parameters?.backingImage).map((s) => {
|
||||
const label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
let label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
const isInternal = isInternalStorageClass(s.metadata?.name);
|
||||
|
||||
if (isInternal) {
|
||||
label += ` (${ this.t('harvester.storage.internal.label') })`;
|
||||
}
|
||||
|
||||
return {
|
||||
label,
|
||||
value: s.name,
|
||||
value: s.name,
|
||||
disabled: isInternal,
|
||||
};
|
||||
}) || [];
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ import { VM_IMAGE_FILE_FORMAT } from '../validators/vm-image';
|
||||
import { OS } from '../mixins/harvester-vm';
|
||||
import { HCI } from '../types';
|
||||
import { LVM_DRIVER } from '../models/harvester/storage.k8s.io.storageclass';
|
||||
import { isInternalStorageClass } from '../utils/storage-class';
|
||||
|
||||
const ENCRYPT = 'encrypt';
|
||||
const DECRYPT = 'decrypt';
|
||||
@ -168,11 +169,18 @@ export default {
|
||||
|
||||
return filteredStorages
|
||||
.map((s) => {
|
||||
const label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
let label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
let disabled = false;
|
||||
|
||||
if (isInternalStorageClass(s.name)) {
|
||||
label += ` (${ this.t('harvester.storage.internal.label') })`;
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
return {
|
||||
label,
|
||||
value: s.name,
|
||||
disabled
|
||||
};
|
||||
}) || [];
|
||||
},
|
||||
|
||||
@ -23,6 +23,7 @@ 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';
|
||||
import { isInternalStorageClass } from '../utils/storage-class';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterVolume',
|
||||
@ -206,11 +207,18 @@ export default {
|
||||
|
||||
storageClassOptions() {
|
||||
return this.storageClasses.filter((s) => !s.parameters?.backingImage).map((s) => {
|
||||
const label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
let label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
let disabled = false;
|
||||
|
||||
if (isInternalStorageClass(s.name)) {
|
||||
label += ` (${ this.t('harvester.storage.internal.label') })`;
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
return {
|
||||
label,
|
||||
value: s.name,
|
||||
disabled
|
||||
};
|
||||
}) || [];
|
||||
},
|
||||
|
||||
@ -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 { isInternalStorageClass } from '../../../../utils/storage-class';
|
||||
import { VOLUME_MODE } from '@pkg/harvester/config/types';
|
||||
|
||||
export default {
|
||||
@ -118,11 +119,18 @@ export default {
|
||||
|
||||
storageClassOptions() {
|
||||
return this.storageClasses.filter((s) => !s.parameters?.backingImage).map((s) => {
|
||||
const label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
let label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
let disabled = false;
|
||||
|
||||
if (isInternalStorageClass(s.name)) {
|
||||
label += ` (${ this.t('harvester.storage.internal.label') })`;
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
return {
|
||||
label,
|
||||
value: s.name,
|
||||
disabled
|
||||
};
|
||||
}) || [];
|
||||
},
|
||||
|
||||
@ -1369,6 +1369,10 @@ harvester:
|
||||
allowedTopologies:
|
||||
title: Allowed Topologies
|
||||
tooltip: Allowed Topologies helps scheduling virtual machines on hosts which match all of below expressions.
|
||||
internal:
|
||||
label: Internal Storage Class
|
||||
cannotDeleteTooltip: Internal storage class volumes cannot be deleted
|
||||
cannotDeleteOrDefaultTooltip: Internal storage classes cannot be deleted or set as default
|
||||
|
||||
vlanConfig:
|
||||
title: Network Configuration
|
||||
|
||||
@ -83,6 +83,34 @@ export default {
|
||||
:rows="rows"
|
||||
:schema="schema"
|
||||
:headers="headers"
|
||||
/>
|
||||
>
|
||||
<template #cell:name="{ row }">
|
||||
<td>
|
||||
<div>
|
||||
<router-link
|
||||
v-if="row?.detailLocation"
|
||||
:to="row.detailLocation"
|
||||
>
|
||||
{{ row.nameDisplay }}
|
||||
<i
|
||||
v-if="row.isInternalStorageClass && typeof row.isInternalStorageClass === 'function' ? row.isInternalStorageClass() : false"
|
||||
v-clean-tooltip="t('harvester.storage.internal.cannotDeleteOrDefaultTooltip')"
|
||||
class="icon icon-info text-info"
|
||||
style="margin-left: 0.4em;"
|
||||
/>
|
||||
</router-link>
|
||||
<span v-else>
|
||||
{{ row.nameDisplay }}
|
||||
<i
|
||||
v-if="row.isInternalStorageClass && typeof row.isInternalStorageClass === 'function' ? row.isInternalStorageClass() : false"
|
||||
v-clean-tooltip="t('harvester.storage.internal.cannotDeleteOrDefaultTooltip')"
|
||||
class="icon icon-info text-info"
|
||||
style="margin-left: 0.4em;"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</template>
|
||||
</ResourceTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -3,6 +3,8 @@ import ResourceTable from '@shell/components/ResourceTable';
|
||||
import { Banner } from '@components/Banner';
|
||||
import { defaultTableSortGenerationFn } from '@shell/components/ResourceTable.vue';
|
||||
import FilterLabel from '../components/FilterLabel';
|
||||
import { HCI as HCI_ANNOTATIONS } from '../config/labels-annotations';
|
||||
import { isInternalStorageClass } from '../utils/storage-class';
|
||||
|
||||
export default {
|
||||
name: 'ListHarvesterImage',
|
||||
@ -53,6 +55,13 @@ export default {
|
||||
|
||||
return base;
|
||||
},
|
||||
|
||||
isInternalStorageClass(row) {
|
||||
const name = row?.spec?.targetStorageClassName ||
|
||||
row?.metadata?.annotations?.[HCI_ANNOTATIONS.STORAGE_CLASS];
|
||||
|
||||
return isInternalStorageClass(name);
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -8,6 +8,7 @@ import { STATE, AGE, NAME, NAMESPACE } from '@shell/config/table-headers';
|
||||
import HarvesterVolumeState from '../formatters/HarvesterVolumeState';
|
||||
import { allSettled } from '../utils/promise';
|
||||
import { HCI, VOLUME_SNAPSHOT } from '../types';
|
||||
import { INTERNAL_STORAGE_CLASS } from '../config/types';
|
||||
|
||||
const schema = {
|
||||
id: HCI.VOLUME,
|
||||
@ -130,6 +131,10 @@ export default {
|
||||
|
||||
getVMName(row) {
|
||||
return row.attachVM?.metadata?.name || '';
|
||||
},
|
||||
|
||||
isInternalStorageClass(storageClassName) {
|
||||
return this.$store.getters['type-map/labelFor'](INTERNAL_STORAGE_CLASS, storageClassName);
|
||||
}
|
||||
},
|
||||
|
||||
@ -170,7 +175,7 @@ export default {
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
<template #col:name="{row}">
|
||||
<template #col:name="{ row }">
|
||||
<td>
|
||||
<span>
|
||||
<router-link
|
||||
|
||||
@ -4,6 +4,7 @@ import { HCI } from '../../types';
|
||||
import { PRODUCT_NAME as HARVESTER_PRODUCT } from '../../config/harvester';
|
||||
import { LONGHORN_DRIVER } from '@shell/config/types';
|
||||
import { DATA_ENGINE_V1, DATA_ENGINE_V2 } from '../../models/harvester/persistentvolumeclaim';
|
||||
import { isInternalStorageClass } from '../../utils/storage-class';
|
||||
|
||||
export const LVM_DRIVER = 'lvm.driver.harvesterhci.io';
|
||||
|
||||
@ -85,4 +86,22 @@ export default class HciStorageClass extends StorageClass {
|
||||
get thirdPartyStorageFeatureEnabled() {
|
||||
return this.$rootGetters['harvester-common/getFeatureEnabled']('thirdPartyStorage');
|
||||
}
|
||||
|
||||
isInternalStorageClass() {
|
||||
return isInternalStorageClass(this.metadata?.name);
|
||||
}
|
||||
|
||||
get availableActions() {
|
||||
let out = super.availableActions || [];
|
||||
|
||||
out = out.map((action) => {
|
||||
if ((action.action === 'setDefault' || action.action === 'setAsDefault' || action.action === 'promptRemove') && this.isInternalStorageClass()) {
|
||||
return { ...action, enabled: false };
|
||||
}
|
||||
|
||||
return action;
|
||||
});
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
6
pkg/harvester/utils/storage-class.js
Normal file
6
pkg/harvester/utils/storage-class.js
Normal file
@ -0,0 +1,6 @@
|
||||
import { INTERNAL_STORAGE_CLASS } from '../config/types';
|
||||
|
||||
export function isInternalStorageClass(name) {
|
||||
return name === INTERNAL_STORAGE_CLASS.VMSTATE_PERSISTENCE ||
|
||||
name === INTERNAL_STORAGE_CLASS.LONGHORN_STATIC;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user