diff --git a/pkg/harvester/config/labels-annotations.js b/pkg/harvester/config/labels-annotations.js index 296023f1..83383396 100644 --- a/pkg/harvester/config/labels-annotations.js +++ b/pkg/harvester/config/labels-annotations.js @@ -69,5 +69,6 @@ export const HCI = { DISABLE_LONGHORN_V2_ENGINE: 'node.longhorn.io/disable-v2-data-engine', K8S_ARCH: 'kubernetes.io/arch', IMAGE_DISPLAY_NAME: 'harvesterhci.io/imageDisplayName', - CUSTOM_IP: 'harvesterhci.io/custom-ip' + CUSTOM_IP: 'harvesterhci.io/custom-ip', + IMPORTED_IMAGE: 'migration.harvesterhci.io/imported' }; diff --git a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue index 219cb605..16d7da43 100644 --- a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue +++ b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue @@ -105,8 +105,9 @@ export default { }) .sort((a, b) => (a.creationTimestamp > b.creationTimestamp ? -1 : 1)) .map((image) => ({ - label: this.imageOptionLabel(image), - value: image.id, + label: this.imageOptionLabel(image), + value: image.id, + disabled: image.isImportedImage })); }, diff --git a/pkg/harvester/l10n/en-us.yaml b/pkg/harvester/l10n/en-us.yaml index ba56a61b..5834b711 100644 --- a/pkg/harvester/l10n/en-us.yaml +++ b/pkg/harvester/l10n/en-us.yaml @@ -878,6 +878,8 @@ harvester: uploading: "{name} is uploading, please do not refresh or close the page." checksum: Checksum checksumTip: Validate the image using the SHA512 checksum, if specified. + tooltip: + imported: Created automatically by the vm-import-controller vmTemplate: label: Templates diff --git a/pkg/harvester/list/harvesterhci.io.virtualmachineimage.vue b/pkg/harvester/list/harvesterhci.io.virtualmachineimage.vue index 7f973e61..0654b89d 100644 --- a/pkg/harvester/list/harvesterhci.io.virtualmachineimage.vue +++ b/pkg/harvester/list/harvesterhci.io.virtualmachineimage.vue @@ -90,6 +90,11 @@ export default { v-if="row.isEncrypted" class="icon icon-lock" /> + {{ row.nameDisplay }} diff --git a/pkg/harvester/models/harvesterhci.io.virtualmachineimage.js b/pkg/harvester/models/harvesterhci.io.virtualmachineimage.js index 62679146..27f9b291 100644 --- a/pkg/harvester/models/harvesterhci.io.virtualmachineimage.js +++ b/pkg/harvester/models/harvesterhci.io.virtualmachineimage.js @@ -57,40 +57,42 @@ export default class HciVmImage extends HarvesterResource { const customActions = this.isReady ? [ { - action: 'createFromImage', - enabled: canCreateVM, - icon: 'icon icon-circle-plus', - label: this.t('harvester.action.createVM'), + action: 'createFromImage', + enabled: canCreateVM, + icon: 'icon icon-circle-plus', + label: this.t('harvester.action.createVM'), }, { - action: 'encryptImage', - enabled: this.volumeEncryptionFeatureEnabled && !this.isEncrypted, - icon: 'icon icon-lock', - label: this.t('harvester.action.encryptImage'), + action: 'encryptImage', + enabled: this.volumeEncryptionFeatureEnabled && !this.isEncrypted, + icon: 'icon icon-lock', + label: this.t('harvester.action.encryptImage'), }, { - action: 'decryptImage', - enabled: this.volumeEncryptionFeatureEnabled && this.isEncrypted, - icon: 'icon icon-unlock', - label: this.t('harvester.action.decryptImage'), + action: 'decryptImage', + enabled: this.volumeEncryptionFeatureEnabled && this.isEncrypted, + icon: 'icon icon-unlock', + label: this.t('harvester.action.decryptImage'), }, { - action: 'imageDownload', - enabled: this.links?.download, - icon: 'icon icon-download', - label: this.t('asyncButton.download.action'), + action: 'imageDownload', + enabled: this.links?.download, + icon: 'icon icon-download', + 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) { - filteredOut = out; - } else { - // if the first item is a divider, remove it from the array - filteredOut = out[0]?.divider ? out.slice(1) : out; + return custom ? [custom, { divider: true }, ...filtered] : filtered; } + // 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 [ ...customActions, ...filteredOut @@ -211,6 +213,10 @@ export default class HciVmImage extends HarvesterResource { !!this.spec.securityParameters?.sourceImageNamespace; } + get isImportedImage() { + return (this.metadata?.labels?.[HCI_ANNOTATIONS.IMPORTED_IMAGE]) === 'true'; + } + get displayNameWithNamespace() { return `${ this.metadata.namespace }/${ this.spec.displayName }`; }