Merge pull request #132 from houhoucoop/feat/issue-7557

feat: add EFI persistent state checkbox in VM advanced tab
This commit is contained in:
Yiya Chen 2025-02-13 18:03:33 +08:00 committed by GitHub
commit a55353fd1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 76 additions and 29 deletions

View File

@ -49,6 +49,7 @@ const featuresV142 = [
const featuresV150 = [
...featuresV142,
'tpmPersistentState',
'efiPersistentState',
'untaggedNetworkSetting',
'skipSingleReplicaDetachedVol'
];

View File

@ -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"
/>
<Checkbox
v-if="value.efiPersistentStateFeatureEnabled && efiEnabled"
v-model:value="efiPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.efiPersistentState')"
: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"
/>
</Tab>

View File

@ -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"
/>
<Checkbox
v-if="value.efiPersistentStateFeatureEnabled && efiEnabled"
v-model:value="efiPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.efiPersistentState')"
: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"
/>

View File

@ -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.

View File

@ -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;
},

View File

@ -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,21 @@ 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);
} 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 +1412,12 @@ export default {
delete this.spec.template.spec.domain.features['smm'];
}
} catch (e) {}
set(this.spec.template.spec.domain, 'firmware.bootloader.efi.secureBoot', false);
}
if (boot.efiPersistentStateEnabled) {
set(this.spec.template.spec.domain, 'firmware.bootloader.efi.persistent', true);
} else {
delete this.spec.template.spec.domain['firmware'];
delete this.spec.template.spec.domain.features['smm'];
delete this.spec.template.spec.domain.firmware.bootloader.efi['persistent'];
}
},
@ -1416,22 +1429,14 @@ export default {
}
},
setTPM(tpmEnabled) {
setTPM({ tpmEnabled = false, tpmPersistentStateEnabled = false } = {}) {
if (tpmEnabled) {
set(this.spec.template.spec.domain.devices, 'tpm', {});
set(this.spec.template.spec.domain.devices, 'tpm', tpmPersistentStateEnabled ? { persistent: true } : {});
} else {
delete this.spec.template.spec.domain.devices['tpm'];
}
},
setTPMPersistentStateEnabled(tpmPersistentStateEnabled) {
if (tpmPersistentStateEnabled) {
set(this.spec.template.spec.domain.devices, 'tpm', { persistent: true });
} else {
set(this.spec.template.spec.domain.devices, 'tpm', {});
}
},
deleteSSHFromUserData(ssh = []) {
const sshAuthorizedKeys = this.getSSHFromUserData(this.userScript);
@ -1540,11 +1545,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) {
@ -1552,11 +1567,11 @@ export default {
},
tpmEnabled(val) {
this.setTPM(val);
this.setTPM({ tpmEnabled: val, tpmPersistentStateEnabled: this.tpmPersistentStateEnabled });
},
tpmPersistentStateEnabled(val) {
this.setTPMPersistentStateEnabled(val);
this.setTPM({ tpmEnabled: this.tpmEnabled, tpmPersistentStateEnabled: val });
},
installAgent: {

View File

@ -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');
}
}

View File

@ -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', {});