Skip to content

Commit 55a86de

Browse files
author
gitlab
committed
Merge branch 'zsv-ldap@@2' into 'feature-zsv-5.0.0-vm-support-vtpm-and-secuceboot'
<feature>[compute]: persist resource key when creating VM See merge request zstackio/zstack!9366
2 parents 9142bf3 + 2029138 commit 55a86de

11 files changed

Lines changed: 223 additions & 29 deletions

File tree

compute/src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,16 +1214,22 @@ public void setup() {
12141214

12151215
flow(new Flow() {
12161216
String __name__ = "call-after-persist-vm-extensions";
1217+
List<VmInstanceCreateExtensionPoint> done = new ArrayList<>();
1218+
12171219
@Override
12181220
public void run(FlowTrigger trigger, Map data) {
1219-
pluginRgty.getExtensionList(VmInstanceCreateExtensionPoint.class).forEach(
1220-
extensionPoint -> extensionPoint.afterPersistVmInstanceVO(finalVo, msg));
1221+
for (VmInstanceCreateExtensionPoint extension : pluginRgty.getExtensionList(VmInstanceCreateExtensionPoint.class)) {
1222+
done.add(extension);
1223+
extension.afterPersistVmInstanceVO(finalVo, msg);
1224+
}
12211225
trigger.next();
12221226
}
12231227

12241228
@Override
12251229
public void rollback(FlowRollback trigger, Map data) {
1226-
// do nothing
1230+
Collections.reverse(done);
1231+
CollectionUtils.safeForEach(done,
1232+
extension -> extension.afterRollbackPersistVmInstanceVO(finalVo, msg));
12271233
trigger.rollback();
12281234
}
12291235
});
@@ -1315,7 +1321,7 @@ public void run(FlowTrigger trigger, Map data) {
13151321
smsg.setRootDiskOfferingUuid(rootDisk.getDiskOfferingUuid());
13161322
} else if (rootDisk.getSize() > 0) {
13171323
dvo = new DiskOfferingVO();
1318-
dvo.setUuid(Platform.getUuid());
1324+
dvo.setUuid(getUuid());
13191325
dvo.setAccountUuid(msg.getAccountUuid());
13201326
dvo.setDiskSize(rootDisk.getSize());
13211327
dvo.setName("for-create-vm-" + finalVo.getUuid());
@@ -1381,7 +1387,7 @@ public void rollback(FlowRollback chain, Map data) {
13811387
}
13821388
DestroyVmInstanceMsg dmsg = new DestroyVmInstanceMsg();
13831389
dmsg.setVmInstanceUuid(finalVo.getUuid());
1384-
dmsg.setDeletionPolicy(VmInstanceDeletionPolicyManager.VmInstanceDeletionPolicy.Direct);
1390+
dmsg.setDeletionPolicy(VmInstanceDeletionPolicy.Direct);
13851391
bus.makeTargetServiceIdByResourceUuid(dmsg, VmInstanceConstant.SERVICE_ID, finalVo.getUuid());
13861392
bus.send(dmsg, new CloudBusCallBack(null) {
13871393
@Override

plugin/kvm/src/main/java/org/zstack/kvm/tpm/DummyTpmEncryptedResourceKeyBackend.java renamed to compute/src/main/java/org/zstack/compute/vm/devices/DummyTpmEncryptedResourceKeyBackend.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.zstack.kvm.tpm;
1+
package org.zstack.compute.vm.devices;
22

33
import org.zstack.header.core.Completion;
44
import org.zstack.utils.Utils;
@@ -7,6 +7,22 @@
77
public class DummyTpmEncryptedResourceKeyBackend implements TpmEncryptedResourceKeyBackend {
88
private static final CLogger logger = Utils.getLogger(DummyTpmEncryptedResourceKeyBackend.class);
99

10+
@Override
11+
public void attachKeyProviderToTpm(String tpmUuid, String keyProviderUuid) {
12+
logger.debug("ignore attach key provider to TPM request for TPM uuid " + tpmUuid +
13+
" and key provider uuid " + keyProviderUuid);
14+
}
15+
16+
@Override
17+
public void detachKeyProviderFromTpm(String tpmUuid) {
18+
logger.debug("ignore detach key provider from TPM request for TPM uuid " + tpmUuid);
19+
}
20+
21+
@Override
22+
public String findKeyProviderUuidByTpm(String tpmUuid) {
23+
return null;
24+
}
25+
1026
@Override
1127
public void cloneEncryptedResourceKey(CloneEncryptedResourceKeyContext context, Completion completion) {
1228
// do nothing

plugin/kvm/src/main/java/org/zstack/kvm/tpm/TpmEncryptedResourceKeyBackend.java renamed to compute/src/main/java/org/zstack/compute/vm/devices/TpmEncryptedResourceKeyBackend.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.zstack.kvm.tpm;
1+
package org.zstack.compute.vm.devices;
22

33
import org.zstack.header.core.Completion;
44

@@ -7,6 +7,24 @@
77
* and other tasks in VM TPM cloning scenarios.
88
*/
99
public interface TpmEncryptedResourceKeyBackend {
10+
11+
/**
12+
* Build relationship from {@link org.zstack.header.tpm.entity.TpmVO} to EncryptedResourceKeyRefVO
13+
* Non-async call.
14+
*/
15+
void attachKeyProviderToTpm(String tpmUuid, String keyProviderUuid);
16+
17+
/**
18+
* Clean relationship from {@link org.zstack.header.tpm.entity.TpmVO} to EncryptedResourceKeyRefVO
19+
* Non-async call.
20+
*/
21+
void detachKeyProviderFromTpm(String tpmUuid);
22+
23+
/**
24+
* maybe null (when crypto module is not installed)
25+
*/
26+
String findKeyProviderUuidByTpm(String tpmUuid);
27+
1028
static class CloneEncryptedResourceKeyContext {
1129
public String srcTpmUuid;
1230
public String dstTpmUuid;

compute/src/main/java/org/zstack/compute/vm/devices/VmTpmExtensions.java

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.zstack.compute.vm.BuildVmSpecExtensionPoint;
55
import org.zstack.compute.vm.VmSystemTags;
66
import org.zstack.core.db.Q;
7+
import org.zstack.core.db.SQLBatch;
78
import org.zstack.header.tpm.entity.TpmSpec;
89
import org.zstack.header.tpm.entity.TpmVO;
910
import org.zstack.header.tpm.entity.TpmVO_;
@@ -25,6 +26,8 @@ public class VmTpmExtensions implements VmInstanceCreateExtensionPoint,
2526
private VmTpmManager vmTpmManager;
2627
@Autowired
2728
private ResourceConfigFacade resourceConfigFacade;
29+
@Autowired
30+
private TpmEncryptedResourceKeyBackend resourceKeyBackend;
2831

2932
@Override
3033
public void preCreateVmInstance(CreateVmInstanceMsg msg) {
@@ -38,17 +41,49 @@ public void afterPersistVmInstanceVO(VmInstanceVO vo, CreateVmInstanceMsg msg) {
3841
return;
3942
}
4043

41-
vmTpmManager.persistTpmVO(null, vo.getUuid());
44+
new SQLBatch() {
45+
@Override
46+
protected void scripts() {
47+
final TpmVO tpm = vmTpmManager.persistTpmVO(null, vo.getUuid());
48+
final String keyProviderUuid = spec.getTpm().getKeyProviderUuid();
49+
if (keyProviderUuid != null) {
50+
resourceKeyBackend.attachKeyProviderToTpm(tpm.getUuid(), keyProviderUuid);
51+
}
52+
}
53+
}.execute();
54+
}
55+
56+
@Override
57+
public void afterRollbackPersistVmInstanceVO(VmInstanceVO vo, CreateVmInstanceMsg msg) {
58+
String tpmUuid = Q.New(TpmVO.class)
59+
.eq(TpmVO_.vmInstanceUuid, vo.getUuid())
60+
.select(TpmVO_.uuid)
61+
.findValue();
62+
if (tpmUuid == null) {
63+
return;
64+
}
65+
66+
new SQLBatch() {
67+
@Override
68+
protected void scripts() {
69+
try {
70+
resourceKeyBackend.detachKeyProviderFromTpm(tpmUuid);
71+
} finally {
72+
vmTpmManager.deleteTpmVO(tpmUuid);
73+
}
74+
}
75+
}.execute();
4276
}
4377

4478
@Override
4579
public void afterBuildVmSpec(VmInstanceSpec spec) {
4680
String vmUuid = spec.getVmInventory().getUuid();
4781

48-
boolean tpmExists = Q.New(TpmVO.class)
82+
String tpmUuid = Q.New(TpmVO.class)
4983
.eq(TpmVO_.vmInstanceUuid, vmUuid)
50-
.isExists();
51-
boolean needRegisterNvRam = tpmExists;
84+
.select(TpmVO_.uuid)
85+
.findValue();
86+
boolean needRegisterNvRam = tpmUuid != null;
5287
if (!needRegisterNvRam) {
5388
String bootMode = VmSystemTags.BOOT_MODE.getTokenByResourceUuid(vmUuid, VmSystemTags.BOOT_MODE_TOKEN);
5489
if (vmTpmManager.isUefiBootMode(bootMode)) {
@@ -64,12 +99,13 @@ public void afterBuildVmSpec(VmInstanceSpec spec) {
6499
spec.setNvRamSpec(nvRamSpec);
65100
}
66101

67-
if (tpmExists && (spec.getDevicesSpec() == null || spec.getDevicesSpec().getTpm() == null)) {
102+
if (tpmUuid != null && (spec.getDevicesSpec() == null || spec.getDevicesSpec().getTpm() == null)) {
68103
VmDevicesSpec devicesSpec = spec.getDevicesSpec() == null ? new VmDevicesSpec() : spec.getDevicesSpec();
69104
spec.setDevicesSpec(devicesSpec);
70105

71106
devicesSpec.setTpm(new TpmSpec());
72107
devicesSpec.getTpm().setEnable(true);
108+
devicesSpec.getTpm().setKeyProviderUuid(resourceKeyBackend.findKeyProviderUuidByTpm(tpmUuid));
73109
}
74110
}
75111
}

compute/src/main/java/org/zstack/compute/vm/devices/VmTpmManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ public TpmVO persistTpmVO(String tpmUuid, String vmUuid) {
3838
return tpm;
3939
}
4040

41+
public void deleteTpmVO(String tpmUuid) {
42+
databaseFacade.removeByPrimaryKey(tpmUuid, TpmVO.class);
43+
}
44+
4145
/**
4246
* @param bootMode boot mode, null is Legacy
4347
*/

conf/errorCodes/keyProvider.xml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<error>
2+
<prefix>KP</prefix>
3+
4+
<code>
5+
<id>1000</id>
6+
<description>ok</description>
7+
</code>
8+
9+
<code>
10+
<id>1001</id>
11+
<description>invalid content</description>
12+
</code>
13+
14+
<code>
15+
<id>1002</id>
16+
<description>internal error</description>
17+
</code>
18+
19+
<code>
20+
<id>1500</id>
21+
<description>backend unavailable</description>
22+
</code>
23+
24+
<code>
25+
<id>1506</id>
26+
<description>socket not found</description>
27+
</code>
28+
29+
<code>
30+
<id>1507</id>
31+
<description>socket not socket</description>
32+
</code>
33+
34+
<code>
35+
<id>1700</id>
36+
<description>kmip connect failed</description>
37+
</code>
38+
39+
<code>
40+
<id>1701</id>
41+
<description>kmip timeout</description>
42+
</code>
43+
44+
<code>
45+
<id>1702</id>
46+
<description>kmip tls handshake failed</description>
47+
</code>
48+
49+
<code>
50+
<id>1703</id>
51+
<description>kmip cert invalid</description>
52+
</code>
53+
54+
<code>
55+
<id>1704</id>
56+
<description>kmip operation failed</description>
57+
</code>
58+
59+
<code>
60+
<id>1600</id>
61+
<description>root key sha256 mismatch</description>
62+
</code>
63+
64+
<code>
65+
<id>1601</id>
66+
<description>root key sha256 file missing</description>
67+
</code>
68+
69+
<code>
70+
<id>1602</id>
71+
<description>zip data required</description>
72+
</code>
73+
74+
<code>
75+
<id>1603</id>
76+
<description>checksum mismatch</description>
77+
</code>
78+
79+
<code>
80+
<id>1604</id>
81+
<description>password invalid</description>
82+
</code>
83+
84+
<code>
85+
<id>1605</id>
86+
<description>root key extension missing</description>
87+
</code>
88+
89+
<code>
90+
<id>1900</id>
91+
<description>name duplicate</description>
92+
</code>
93+
94+
<code>
95+
<id>1901</id>
96+
<description>uuid duplicate</description>
97+
</code>
98+
99+
<code>
100+
<id>2000</id>
101+
<description>TPM related errors</description>
102+
</code>
103+
104+
<code>
105+
<id>2101</id>
106+
<description>TPM already attached key provider</description>
107+
</code>
108+
</error>

conf/springConfigXml/Kvm.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,4 @@
273273
<zstack:extension interface="org.zstack.header.vm.VmInstanceDestroyExtensionPoint" />
274274
</zstack:plugin>
275275
</bean>
276-
277-
<bean id="DummyTpmEncryptedResourceKeyBackend" class="org.zstack.kvm.tpm.DummyTpmEncryptedResourceKeyBackend"/>
278276
</beans>

conf/springConfigXml/VmInstanceManager.xml

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -283,16 +283,18 @@
283283

284284
<bean id="VmTpmManager" class="org.zstack.compute.vm.devices.VmTpmManager"/>
285285

286-
<bean id="VmTpmExtensions" class="org.zstack.compute.vm.devices.VmTpmExtensions">
287-
<zstack:plugin>
288-
<zstack:extension interface="org.zstack.header.vm.VmInstanceCreateExtensionPoint" />
289-
<zstack:extension interface="org.zstack.compute.vm.BuildVmSpecExtensionPoint" />
290-
</zstack:plugin>
291-
</bean>
292-
293-
<bean id="VmTpmRekeyAssociation" class="org.zstack.compute.vm.devices.VmTpmRekeyAssociation">
294-
<zstack:plugin>
295-
<zstack:extension interface="org.zstack.header.keyprovider.KeyProviderRekeyAssociationExtensionPoint" />
296-
</zstack:plugin>
297-
</bean>
298-
</beans>
286+
<bean id="VmTpmExtensions" class="org.zstack.compute.vm.devices.VmTpmExtensions">
287+
<zstack:plugin>
288+
<zstack:extension interface="org.zstack.header.vm.VmInstanceCreateExtensionPoint" />
289+
<zstack:extension interface="org.zstack.compute.vm.BuildVmSpecExtensionPoint" />
290+
</zstack:plugin>
291+
</bean>
292+
293+
<bean id="VmTpmRekeyAssociation" class="org.zstack.compute.vm.devices.VmTpmRekeyAssociation">
294+
<zstack:plugin>
295+
<zstack:extension interface="org.zstack.header.keyprovider.KeyProviderRekeyAssociationExtensionPoint" />
296+
</zstack:plugin>
297+
</bean>
298+
299+
<bean id="DummyTpmEncryptedResourceKeyBackend" class="org.zstack.compute.vm.devices.DummyTpmEncryptedResourceKeyBackend"/>
300+
</beans>

header/src/main/java/org/zstack/header/vm/VmInstanceCreateExtensionPoint.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,11 @@ public interface VmInstanceCreateExtensionPoint {
99
void preCreateVmInstance(CreateVmInstanceMsg msg);
1010

1111
default void afterPersistVmInstanceVO(VmInstanceVO vo, CreateVmInstanceMsg msg) {}
12+
13+
/**
14+
* Invoked when VM creation rolls back after
15+
* {`@link` `#afterPersistVmInstanceVO`(VmInstanceVO, CreateVmInstanceMsg)} so extensions can
16+
* clean up any state created in that hook. Implementations should be idempotent.
17+
*/
18+
default void afterRollbackPersistVmInstanceVO(VmInstanceVO vo, CreateVmInstanceMsg msg) {}
1219
}

plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.zstack.kvm.tpm;
22

33
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.zstack.compute.vm.devices.TpmEncryptedResourceKeyBackend;
45
import org.zstack.compute.vm.devices.VmTpmManager;
56
import org.zstack.core.asyncbatch.While;
67
import org.zstack.core.cloudbus.CloudBus;

0 commit comments

Comments
 (0)