From b92f22fa757d027431376b25f88b6483bd06f821 Mon Sep 17 00:00:00 2001 From: Yi-Ya Chen Date: Wed, 12 Feb 2025 15:05:07 +0800 Subject: [PATCH] feat: add efi persistent state Signed-off-by: Yi-Ya Chen --- pkg/harvester/config/feature-flags.js | 1 + ...erhci.io.virtualmachinetemplateversion.vue | 13 +++++- .../edit/kubevirt.io.virtualmachine/index.vue | 13 +++++- pkg/harvester/l10n/en-us.yaml | 5 ++- pkg/harvester/mixins/harvester-vm/impl.js | 4 ++ pkg/harvester/mixins/harvester-vm/index.js | 40 +++++++++++++------ ...terhci.io.virtualmachinetemplateversion.js | 4 ++ .../models/kubevirt.io.virtualmachine.js | 4 ++ 8 files changed, 66 insertions(+), 18 deletions(-) diff --git a/pkg/harvester/config/feature-flags.js b/pkg/harvester/config/feature-flags.js index 2cfeb945..ed611205 100644 --- a/pkg/harvester/config/feature-flags.js +++ b/pkg/harvester/config/feature-flags.js @@ -49,6 +49,7 @@ const featuresV142 = [ const featuresV150 = [ ...featuresV142, 'tpmPersistentState', + 'efiPersistentState', 'untaggedNetworkSetting', 'skipSingleReplicaDetachedVol' ]; diff --git a/pkg/harvester/edit/harvesterhci.io.virtualmachinetemplateversion.vue b/pkg/harvester/edit/harvesterhci.io.virtualmachinetemplateversion.vue index 477cac13..97e8aee0 100644 --- a/pkg/harvester/edit/harvesterhci.io.virtualmachinetemplateversion.vue +++ b/pkg/harvester/edit/harvesterhci.io.virtualmachinetemplateversion.vue @@ -478,7 +478,16 @@ export default { v-model:value="efiEnabled" class="check" type="checkbox" - :label="t('harvester.virtualMachine.efiEnabled')" + :label="t('harvester.virtualMachine.advancedOptions.efiEnabled')" + :mode="mode" + /> + + @@ -487,7 +496,7 @@ export default { v-model:value="secureBoot" class="check" type="checkbox" - :label="t('harvester.virtualMachine.secureBoot')" + :label="t('harvester.virtualMachine.advancedOptions.secureBoot')" :mode="mode" /> diff --git a/pkg/harvester/edit/kubevirt.io.virtualmachine/index.vue b/pkg/harvester/edit/kubevirt.io.virtualmachine/index.vue index 8e67f575..e7f2bfd0 100644 --- a/pkg/harvester/edit/kubevirt.io.virtualmachine/index.vue +++ b/pkg/harvester/edit/kubevirt.io.virtualmachine/index.vue @@ -886,7 +886,16 @@ export default { v-model:value="efiEnabled" class="check" type="checkbox" - :label="t('harvester.virtualMachine.efiEnabled')" + :label="t('harvester.virtualMachine.advancedOptions.efiEnabled')" + :mode="mode" + /> + + @@ -895,7 +904,7 @@ export default { v-model:value="secureBoot" class="check" type="checkbox" - :label="t('harvester.virtualMachine.secureBoot')" + :label="t('harvester.virtualMachine.advancedOptions.secureBoot')" :mode="mode" /> diff --git a/pkg/harvester/l10n/en-us.yaml b/pkg/harvester/l10n/en-us.yaml index 40599984..2aae4357 100644 --- a/pkg/harvester/l10n/en-us.yaml +++ b/pkg/harvester/l10n/en-us.yaml @@ -604,11 +604,12 @@ harvester: prefix: You must enable CPU Manager for at least one node in middle: 'host page' suffix: to enable CPU Pinning for VM + efiEnabled: Booting in EFI mode + efiPersistentState: EFI Persistent State + secureBoot: Secure Boot usbTip: Provides an absolute pointer device which often helps with getting a consistent mouse cursor position in VNC. sshTitle: Add Public SSH Key imageTip: An external URL to the .iso, .img, .qcow2 or .raw that the virtual machine should be created from. - efiEnabled: Booting in EFI mode - secureBoot: Secure Boot volume: dragTip: Drag and drop volumes, or use the volume's arrows, to change the boot order. volumeTip: The virtual machine only contains a CD-ROM volume. You may want to add additional disk volumes. diff --git a/pkg/harvester/mixins/harvester-vm/impl.js b/pkg/harvester/mixins/harvester-vm/impl.js index ffb0e56a..b1d6df83 100644 --- a/pkg/harvester/mixins/harvester-vm/impl.js +++ b/pkg/harvester/mixins/harvester-vm/impl.js @@ -144,6 +144,10 @@ export default { return !!spec?.template?.spec?.domain?.devices?.tpm?.persistent; }, + isEFIPersistentStateEnabled(spec) { + return !!spec?.template?.spec?.domain?.firmware?.bootloader?.efi?.persistent; + }, + isSecureBoot(spec) { return !!spec?.template?.spec?.domain?.firmware?.bootloader?.efi?.secureBoot; }, diff --git a/pkg/harvester/mixins/harvester-vm/index.js b/pkg/harvester/mixins/harvester-vm/index.js index 062e57d1..b293951a 100644 --- a/pkg/harvester/mixins/harvester-vm/index.js +++ b/pkg/harvester/mixins/harvester-vm/index.js @@ -165,6 +165,7 @@ export default { efiEnabled: false, tpmEnabled: false, tpmPersistentStateEnabled: false, + efiPersistentStateEnabled: false, secureBoot: false, userDataTemplateId: '', saveUserDataAsClearText: false, @@ -369,6 +370,7 @@ export default { const efiEnabled = this.isEfiEnabled(spec); const tpmEnabled = this.isTpmEnabled(spec); const tpmPersistentStateEnabled = this.isTPMPersistentStateEnabled(spec); + const efiPersistentStateEnabled = this.isEFIPersistentStateEnabled(spec); const secureBoot = this.isSecureBoot(spec); const cpuPinning = this.isCpuPinning(spec); @@ -400,6 +402,7 @@ export default { this['installUSBTablet'] = installUSBTablet; this['efiEnabled'] = efiEnabled; + this['efiPersistentStateEnabled'] = efiPersistentStateEnabled; this['tpmEnabled'] = tpmEnabled; this['tpmPersistentStateEnabled'] = tpmPersistentStateEnabled; this['secureBoot'] = secureBoot; @@ -1386,13 +1389,20 @@ export default { } }, - setBootMethod(boot = { efi: false, secureBoot: false }) { - if (boot.efi && boot.secureBoot) { - set(this.spec.template.spec.domain, 'features.smm.enabled', true); - set(this.spec.template.spec.domain, 'firmware.bootloader.efi.secureBoot', true); - } else if (boot.efi && !boot.secureBoot) { - // set(this.spec.template.spec.domain, 'features.smm.enabled', false); + setBootMethod(boot = { efi: false, secureBoot: false, efiPersistentStateEnabled: false }) { + if (boot.efi) { + set(this.spec.template.spec.domain, 'firmware.bootloader.efi.secureBoot', boot.secureBoot); + set(this.spec.template.spec.domain, 'firmware.bootloader.efi.persistent', boot.efiPersistentStateEnabled); + } else { + delete this.spec.template.spec.domain['firmware']; + delete this.spec.template.spec.domain.features['smm']; + return; + } + + if (boot.secureBoot) { + set(this.spec.template.spec.domain, 'features.smm.enabled', true); + } else { try { delete this.spec.template.spec.domain.features.smm['enabled']; const noKeys = Object.keys(this.spec.template.spec.domain.features.smm).length === 0; @@ -1401,10 +1411,6 @@ export default { delete this.spec.template.spec.domain.features['smm']; } } catch (e) {} - set(this.spec.template.spec.domain, 'firmware.bootloader.efi.secureBoot', false); - } else { - delete this.spec.template.spec.domain['firmware']; - delete this.spec.template.spec.domain.features['smm']; } }, @@ -1540,11 +1546,21 @@ export default { }, efiEnabled(val) { - this.setBootMethod({ efi: val, secureBoot: this.secureBoot }); + this.setBootMethod({ + efi: val, secureBoot: this.secureBoot, efiPersistentStateEnabled: this.efiPersistentStateEnabled + }); }, secureBoot(val) { - this.setBootMethod({ efi: this.efiEnabled, secureBoot: val }); + this.setBootMethod({ + efi: this.efiEnabled, secureBoot: val, efiPersistentStateEnabled: this.efiPersistentStateEnabled + }); + }, + + efiPersistentStateEnabled(val) { + this.setBootMethod({ + efi: this.efiEnabled, secureBoot: this.secureBoot, efiPersistentStateEnabled: val + }); }, cpuPinning(value) { diff --git a/pkg/harvester/models/harvesterhci.io.virtualmachinetemplateversion.js b/pkg/harvester/models/harvesterhci.io.virtualmachinetemplateversion.js index fa385dd0..b2036be2 100644 --- a/pkg/harvester/models/harvesterhci.io.virtualmachinetemplateversion.js +++ b/pkg/harvester/models/harvesterhci.io.virtualmachinetemplateversion.js @@ -280,4 +280,8 @@ export default class HciVmTemplateVersion extends HarvesterResource { get tpmPersistentStateFeatureEnabled() { return this.$rootGetters['harvester-common/getFeatureEnabled']('tpmPersistentState'); } + + get efiPersistentStateFeatureEnabled() { + return this.$rootGetters['harvester-common/getFeatureEnabled']('efiPersistentState'); + } } diff --git a/pkg/harvester/models/kubevirt.io.virtualmachine.js b/pkg/harvester/models/kubevirt.io.virtualmachine.js index 9eea0783..103e32ba 100644 --- a/pkg/harvester/models/kubevirt.io.virtualmachine.js +++ b/pkg/harvester/models/kubevirt.io.virtualmachine.js @@ -1179,6 +1179,10 @@ export default class VirtVm extends HarvesterResource { return this.$rootGetters['harvester-common/getFeatureEnabled']('tpmPersistentState'); } + get efiPersistentStateFeatureEnabled() { + return this.$rootGetters['harvester-common/getFeatureEnabled']('efiPersistentState'); + } + setInstanceLabels(val) { if ( !this.spec?.template?.metadata?.labels ) { set(this, 'spec.template.metadata.labels', {});