feat: disable vm images (#376) (#380)

(cherry picked from commit 85a06feb918784752025addcb04844920999694d)

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
Co-authored-by: Yiya Chen <yiya.chen@suse.com>
This commit is contained in:
mergify[bot] 2025-07-08 17:10:14 +08:00 committed by GitHub
parent 264d65cc6d
commit 8044e74102
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 40 additions and 25 deletions

View File

@ -69,5 +69,6 @@ export const HCI = {
DISABLE_LONGHORN_V2_ENGINE: 'node.longhorn.io/disable-v2-data-engine', DISABLE_LONGHORN_V2_ENGINE: 'node.longhorn.io/disable-v2-data-engine',
K8S_ARCH: 'kubernetes.io/arch', K8S_ARCH: 'kubernetes.io/arch',
IMAGE_DISPLAY_NAME: 'harvesterhci.io/imageDisplayName', IMAGE_DISPLAY_NAME: 'harvesterhci.io/imageDisplayName',
CUSTOM_IP: 'harvesterhci.io/custom-ip' CUSTOM_IP: 'harvesterhci.io/custom-ip',
IMPORTED_IMAGE: 'migration.harvesterhci.io/imported'
}; };

View File

@ -105,8 +105,9 @@ export default {
}) })
.sort((a, b) => (a.creationTimestamp > b.creationTimestamp ? -1 : 1)) .sort((a, b) => (a.creationTimestamp > b.creationTimestamp ? -1 : 1))
.map((image) => ({ .map((image) => ({
label: this.imageOptionLabel(image), label: this.imageOptionLabel(image),
value: image.id, value: image.id,
disabled: image.isImportedImage
})); }));
}, },

View File

@ -878,6 +878,8 @@ harvester:
uploading: "{name} is uploading, please do not refresh or close the page." uploading: "{name} is uploading, please do not refresh or close the page."
checksum: Checksum checksum: Checksum
checksumTip: Validate the image using the SHA512 checksum, if specified. checksumTip: Validate the image using the SHA512 checksum, if specified.
tooltip:
imported: Created automatically by the vm-import-controller
vmTemplate: vmTemplate:
label: Templates label: Templates

View File

@ -90,6 +90,11 @@ export default {
v-if="row.isEncrypted" v-if="row.isEncrypted"
class="icon icon-lock" class="icon icon-lock"
/> />
<i
v-if="row.isImportedImage"
v-clean-tooltip="t('harvester.image.tooltip.imported')"
class="icon icon-info"
/>
</router-link> </router-link>
<span v-else> <span v-else>
{{ row.nameDisplay }} {{ row.nameDisplay }}

View File

@ -57,40 +57,42 @@ export default class HciVmImage extends HarvesterResource {
const customActions = this.isReady ? [ const customActions = this.isReady ? [
{ {
action: 'createFromImage', action: 'createFromImage',
enabled: canCreateVM, enabled: canCreateVM,
icon: 'icon icon-circle-plus', icon: 'icon icon-circle-plus',
label: this.t('harvester.action.createVM'), label: this.t('harvester.action.createVM'),
}, },
{ {
action: 'encryptImage', action: 'encryptImage',
enabled: this.volumeEncryptionFeatureEnabled && !this.isEncrypted, enabled: this.volumeEncryptionFeatureEnabled && !this.isEncrypted,
icon: 'icon icon-lock', icon: 'icon icon-lock',
label: this.t('harvester.action.encryptImage'), label: this.t('harvester.action.encryptImage'),
}, },
{ {
action: 'decryptImage', action: 'decryptImage',
enabled: this.volumeEncryptionFeatureEnabled && this.isEncrypted, enabled: this.volumeEncryptionFeatureEnabled && this.isEncrypted,
icon: 'icon icon-unlock', icon: 'icon icon-unlock',
label: this.t('harvester.action.decryptImage'), label: this.t('harvester.action.decryptImage'),
}, },
{ {
action: 'imageDownload', action: 'imageDownload',
enabled: this.links?.download, enabled: this.links?.download,
icon: 'icon icon-download', icon: 'icon icon-download',
label: this.t('asyncButton.download.action'), label: this.t('asyncButton.download.action'),
} }
] : []; ] : [];
let filteredOut; // imported image only allow download, download yaml and delete actions
if (this.isImportedImage) {
const custom = customActions.find((a) => a.action === 'imageDownload');
const filtered = out.filter(({ action }) => ['download', 'promptRemove'].includes(action));
if (customActions.length > 0) { return custom ? [custom, { divider: true }, ...filtered] : filtered;
filteredOut = out;
} else {
// if the first item is a divider, remove it from the array
filteredOut = out[0]?.divider ? out.slice(1) : out;
} }
// if the first item is a divider, remove it from the array
const filteredOut = customActions.length > 0 ? out : (out[0]?.divider ? out.slice(1) : out);
return [ return [
...customActions, ...customActions,
...filteredOut ...filteredOut
@ -211,6 +213,10 @@ export default class HciVmImage extends HarvesterResource {
!!this.spec.securityParameters?.sourceImageNamespace; !!this.spec.securityParameters?.sourceImageNamespace;
} }
get isImportedImage() {
return (this.metadata?.labels?.[HCI_ANNOTATIONS.IMPORTED_IMAGE]) === 'true';
}
get displayNameWithNamespace() { get displayNameWithNamespace() {
return `${ this.metadata.namespace }/${ this.spec.displayName }`; return `${ this.metadata.namespace }/${ this.spec.displayName }`;
} }