Skip to content

Commit 052ddff

Browse files
author
gitlab
committed
Merge branch 'zsv-ldap@@2' into 'feature-zsv-5.0.0-vm-support-vtpm-and-secuceboot'
<feature>[vm]: add TPM and NvRam restore support for snapshot group See merge request zstackio/zstack!9474
2 parents 67ca4a6 + 7ab9254 commit 052ddff

4 files changed

Lines changed: 146 additions & 0 deletions

File tree

header/src/main/java/org/zstack/header/tpm/entity/TpmSpec.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public class TpmSpec {
99
private String keyProviderUuid;
1010
@APINoSee
1111
private String secretUuid;
12+
private String backupFileUuid;
1213
@APINoSee
1314
private boolean resourceKeyCreatedNew;
1415
@APINoSee
@@ -38,6 +39,14 @@ public void setKeyProviderUuid(String keyProviderUuid) {
3839
this.keyProviderUuid = keyProviderUuid;
3940
}
4041

42+
public String getBackupFileUuid() {
43+
return backupFileUuid;
44+
}
45+
46+
public void setBackupFileUuid(String backupFileUuid) {
47+
this.backupFileUuid = backupFileUuid;
48+
}
49+
4150
public String getSecretUuid() {
4251
return secretUuid;
4352
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.zstack.header.vm.devices;
2+
3+
public class NvRamSpec {
4+
private String backupFileUuid;
5+
6+
public String getBackupFileUuid() {
7+
return backupFileUuid;
8+
}
9+
10+
public void setBackupFileUuid(String backupFileUuid) {
11+
this.backupFileUuid = backupFileUuid;
12+
}
13+
}

header/src/main/java/org/zstack/header/vm/devices/VmDevicesSpec.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public class VmDevicesSpec {
77
* Default value of tpm must be null, because tpm.enable is true by default.
88
*/
99
private TpmSpec tpm;
10+
private NvRamSpec nvRam;
1011

1112
public TpmSpec getTpm() {
1213
return tpm;
@@ -16,6 +17,14 @@ public void setTpm(TpmSpec tpm) {
1617
this.tpm = tpm;
1718
}
1819

20+
public NvRamSpec getNvRam() {
21+
return nvRam;
22+
}
23+
24+
public void setNvRam(NvRamSpec nvRam) {
25+
this.nvRam = nvRam;
26+
}
27+
1928
public static VmDevicesSpec __example__() {
2029
VmDevicesSpec spec = new VmDevicesSpec();
2130
spec.setTpm(TpmSpec.__example__());
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package org.zstack.kvm.tpm;
2+
3+
import org.springframework.beans.factory.annotation.Autowire;
4+
import org.springframework.beans.factory.annotation.Autowired;
5+
import org.springframework.beans.factory.annotation.Configurable;
6+
import org.zstack.compute.vm.VmGlobalConfig;
7+
import org.zstack.core.db.Q;
8+
import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupVO;
9+
import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupVO_;
10+
import org.zstack.header.tpm.entity.TpmSpec;
11+
import org.zstack.header.vm.APICreateVmInstanceFromVolumeSnapshotGroupMsg;
12+
import org.zstack.header.vm.CreateVmInstanceMsg;
13+
import org.zstack.header.vm.additions.VmHostBackupFileVO;
14+
import org.zstack.header.vm.additions.VmHostBackupFileVO_;
15+
import org.zstack.header.vm.additions.VmHostFileType;
16+
import org.zstack.header.vm.devices.NvRamSpec;
17+
import org.zstack.header.vm.devices.VmDevicesSpec;
18+
import org.zstack.resourceconfig.ResourceConfigFacade;
19+
import org.zstack.utils.Utils;
20+
import org.zstack.utils.logging.CLogger;
21+
22+
import java.util.List;
23+
24+
@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE)
25+
public class SnapshotGroupRevertTpmHelper {
26+
private static final CLogger logger = Utils.getLogger(SnapshotGroupRevertTpmHelper.class);
27+
28+
@Autowired
29+
ResourceConfigFacade resourceConfigFacade;
30+
31+
public void setupFromApi(APICreateVmInstanceFromVolumeSnapshotGroupMsg apiMsg, CreateVmInstanceMsg cmsg) {
32+
String snapshotGroupUuid = apiMsg.getVolumeSnapshotGroupUuid();
33+
34+
boolean resetTpm;
35+
if (apiMsg.getResetTpm() != null) {
36+
resetTpm = apiMsg.getResetTpm();
37+
} else {
38+
String vmInstanceUuid = Q.New(VolumeSnapshotGroupVO.class)
39+
.select(VolumeSnapshotGroupVO_.vmInstanceUuid)
40+
.eq(VolumeSnapshotGroupVO_.uuid, snapshotGroupUuid)
41+
.findValue();
42+
resetTpm = resourceConfigFacade.getResourceConfigValue(
43+
VmGlobalConfig.RESET_TPM_AFTER_VM_CLONE, vmInstanceUuid, Boolean.class);
44+
logger.debug(String.format("resetTpm not specified in API, resolved from resource config " +
45+
"RESET_TPM_AFTER_VM_CLONE for vm[uuid:%s]: %s", vmInstanceUuid, resetTpm));
46+
}
47+
48+
List<VmHostBackupFileVO> backupFiles = Q.New(VmHostBackupFileVO.class)
49+
.eq(VmHostBackupFileVO_.resourceUuid, snapshotGroupUuid)
50+
.list();
51+
52+
if (backupFiles.isEmpty()) {
53+
logger.debug(String.format(
54+
"no VmHostBackupFileVO found for volume snapshot group[uuid:%s], skip restoring TPM/NvRam",
55+
snapshotGroupUuid));
56+
return;
57+
}
58+
59+
VmHostBackupFileVO tpmBackupFile = null;
60+
VmHostBackupFileVO nvRamBackupFile = null;
61+
for (VmHostBackupFileVO f : backupFiles) {
62+
if (f.getType() == VmHostFileType.TpmState) {
63+
tpmBackupFile = f;
64+
} else if (f.getType() == VmHostFileType.NvRam) {
65+
nvRamBackupFile = f;
66+
}
67+
}
68+
69+
if (tpmBackupFile == null && nvRamBackupFile == null) {
70+
logger.debug(String.format("no TpmState or NvRam backup file found for volume snapshot group[uuid:%s]",
71+
snapshotGroupUuid));
72+
return;
73+
}
74+
75+
VmDevicesSpec devicesSpec = cmsg.getDevicesSpec();
76+
if (devicesSpec == null) {
77+
devicesSpec = new VmDevicesSpec();
78+
cmsg.setDevicesSpec(devicesSpec);
79+
}
80+
81+
if (tpmBackupFile != null) {
82+
TpmSpec tpmSpec = devicesSpec.getTpm();
83+
if (tpmSpec == null) {
84+
tpmSpec = new TpmSpec();
85+
devicesSpec.setTpm(tpmSpec);
86+
}
87+
tpmSpec.setEnable(true);
88+
89+
if (resetTpm) {
90+
// resetTpm=true: reset secretUuid, generate a new one during VM creation
91+
logger.debug(String.format("resetTpm is true for volume snapshot group[uuid:%s], " +
92+
"will reset secretUuid, tpmBackupFileUuid:%s", snapshotGroupUuid, tpmBackupFile.getUuid()));
93+
} else {
94+
tpmSpec.setBackupFileUuid(tpmBackupFile.getUuid());
95+
// resetTpm=false: should reuse secretUuid + keyProviderUuid recorded in VolumeSnapshotGroup,
96+
// but the recording step is not yet implemented, leave them empty for now
97+
// TODO: retrieve secretUuid and keyProviderUuid from VolumeSnapshotGroup and set them here
98+
logger.warn(String.format("resetTpm is false for volume snapshot group[uuid:%s], " +
99+
"should restore secretUuid and keyProviderUuid but they are not yet recorded in snapshot group, " +
100+
"leaving empty. tpmBackupFileUuid:%s", snapshotGroupUuid, tpmBackupFile.getUuid()));
101+
}
102+
}
103+
104+
if (nvRamBackupFile != null) {
105+
NvRamSpec nvRamSpec = devicesSpec.getNvRam();
106+
if (nvRamSpec == null) {
107+
nvRamSpec = new NvRamSpec();
108+
devicesSpec.setNvRam(nvRamSpec);
109+
}
110+
nvRamSpec.setBackupFileUuid(nvRamBackupFile.getUuid());
111+
logger.debug(String.format("set NvRam restore info for volume snapshot group[uuid:%s], nvRamBackupFileUuid:%s",
112+
snapshotGroupUuid, nvRamBackupFile.getUuid()));
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)