Merge pull request #120 from harvester/mergify/bp/release-harvester-v1.5/pr-117

feat: add support for persistent TPM in VMs (backport #117)
This commit is contained in:
Andy Lee 2025-02-11 10:36:45 +08:00 committed by GitHub
commit 26d85a7760
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 50 additions and 2 deletions

View File

@ -47,7 +47,8 @@ const featuresV142 = [
// TODO: add v1.5.0 official release note // TODO: add v1.5.0 official release note
const featuresV150 = [ const featuresV150 = [
...featuresV142 ...featuresV142,
'tpmPersistentState'
]; ];
export const RELEASE_FEATURES = { export const RELEASE_FEATURES = {

View File

@ -465,6 +465,15 @@ export default {
:mode="mode" :mode="mode"
/> />
<Checkbox
v-if="value.tpmPersistentStateFeatureEnabled && tpmEnabled"
v-model:value="tpmPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.tpmPersistentState')"
:mode="mode"
/>
<Checkbox <Checkbox
v-model:value="efiEnabled" v-model:value="efiEnabled"
class="check" class="check"

View File

@ -873,6 +873,15 @@ export default {
:mode="mode" :mode="mode"
/> />
<Checkbox
v-if="value.tpmPersistentStateFeatureEnabled && tpmEnabled"
v-model:value="tpmPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.tpmPersistentState')"
:mode="mode"
/>
<Checkbox <Checkbox
v-model:value="efiEnabled" v-model:value="efiEnabled"
class="check" class="check"
@ -889,6 +898,7 @@ export default {
:label="t('harvester.virtualMachine.secureBoot')" :label="t('harvester.virtualMachine.secureBoot')"
:mode="mode" :mode="mode"
/> />
<Banner <Banner
v-if="showCpuPinningBanner" v-if="showCpuPinningBanner"
color="warning" color="warning"

View File

@ -594,6 +594,7 @@ harvester:
enableUsb: Enable USB Tablet enableUsb: Enable USB Tablet
advancedOptions: advancedOptions:
tpm: Enable TPM tpm: Enable TPM
tpmPersistentState: TPM Persistent State
cpuManager: cpuManager:
prefix: You must enable CPU Manager for at least one node in prefix: You must enable CPU Manager for at least one node in
middle: 'host page' middle: 'host page'

View File

@ -137,7 +137,11 @@ export default {
}, },
isTpmEnabled(spec) { isTpmEnabled(spec) {
return !!spec?.template?.spec?.domain?.devices?.tpm ; return !!spec?.template?.spec?.domain?.devices?.tpm;
},
isTPMPersistentStateEnabled(spec) {
return !!spec?.template?.spec?.domain?.devices?.tpm?.persistent;
}, },
isSecureBoot(spec) { isSecureBoot(spec) {

View File

@ -164,6 +164,7 @@ export default {
accessCredentials: [], accessCredentials: [],
efiEnabled: false, efiEnabled: false,
tpmEnabled: false, tpmEnabled: false,
tpmPersistentStateEnabled: false,
secureBoot: false, secureBoot: false,
userDataTemplateId: '', userDataTemplateId: '',
saveUserDataAsClearText: false, saveUserDataAsClearText: false,
@ -367,6 +368,7 @@ export default {
const installAgent = this.hasInstallAgent(userData, osType, true); const installAgent = this.hasInstallAgent(userData, osType, true);
const efiEnabled = this.isEfiEnabled(spec); const efiEnabled = this.isEfiEnabled(spec);
const tpmEnabled = this.isTpmEnabled(spec); const tpmEnabled = this.isTpmEnabled(spec);
const tpmPersistentStateEnabled = this.isTPMPersistentStateEnabled(spec);
const secureBoot = this.isSecureBoot(spec); const secureBoot = this.isSecureBoot(spec);
const cpuPinning = this.isCpuPinning(spec); const cpuPinning = this.isCpuPinning(spec);
@ -399,6 +401,7 @@ export default {
this['installUSBTablet'] = installUSBTablet; this['installUSBTablet'] = installUSBTablet;
this['efiEnabled'] = efiEnabled; this['efiEnabled'] = efiEnabled;
this['tpmEnabled'] = tpmEnabled; this['tpmEnabled'] = tpmEnabled;
this['tpmPersistentStateEnabled'] = tpmPersistentStateEnabled;
this['secureBoot'] = secureBoot; this['secureBoot'] = secureBoot;
this['cpuPinning'] = cpuPinning; this['cpuPinning'] = cpuPinning;
@ -1421,6 +1424,14 @@ export default {
} }
}, },
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 = []) { deleteSSHFromUserData(ssh = []) {
const sshAuthorizedKeys = this.getSSHFromUserData(this.userScript); const sshAuthorizedKeys = this.getSSHFromUserData(this.userScript);
@ -1544,6 +1555,10 @@ export default {
this.setTPM(val); this.setTPM(val);
}, },
tpmPersistentStateEnabled(val) {
this.setTPMPersistentStateEnabled(val);
},
installAgent: { installAgent: {
/** /**
* rules * rules

View File

@ -276,4 +276,8 @@ export default class HciVmTemplateVersion extends HarvesterResource {
this.spec.vm.spec.template.metadata['labels'] = { ...wasIgnored, ...val }; this.spec.vm.spec.template.metadata['labels'] = { ...wasIgnored, ...val };
} }
get tpmPersistentStateFeatureEnabled() {
return this.$rootGetters['harvester-common/getFeatureEnabled']('tpmPersistentState');
}
} }

View File

@ -1175,6 +1175,10 @@ export default class VirtVm extends HarvesterResource {
return this.$rootGetters['harvester-common/getFeatureEnabled']('volumeEncryption'); return this.$rootGetters['harvester-common/getFeatureEnabled']('volumeEncryption');
} }
get tpmPersistentStateFeatureEnabled() {
return this.$rootGetters['harvester-common/getFeatureEnabled']('tpmPersistentState');
}
setInstanceLabels(val) { setInstanceLabels(val) {
if ( !this.spec?.template?.metadata?.labels ) { if ( !this.spec?.template?.metadata?.labels ) {
set(this, 'spec.template.metadata.labels', {}); set(this, 'spec.template.metadata.labels', {});