|
3 | 3 | import org.springframework.beans.factory.annotation.Autowired; |
4 | 4 | import org.zstack.compute.legacy.ComputeLegacyGlobalProperty; |
5 | 5 | import org.zstack.compute.vm.VmGlobalConfig; |
| 6 | +import org.zstack.compute.vm.VmSystemTags; |
6 | 7 | import org.zstack.compute.vm.devices.VmTpmManager; |
7 | 8 | import org.zstack.core.Platform; |
8 | 9 | import org.zstack.core.cloudbus.CloudBus; |
|
24 | 25 | import org.zstack.header.identity.AccountResourceRefVO; |
25 | 26 | import org.zstack.header.identity.AccountResourceRefVO_; |
26 | 27 | import org.zstack.header.message.MessageReply; |
| 28 | +import org.zstack.header.tpm.entity.TpmVO; |
| 29 | +import org.zstack.header.tpm.entity.TpmVO_; |
27 | 30 | import org.zstack.header.vm.DiskAO; |
28 | 31 | import org.zstack.header.vm.PreVmInstantiateResourceExtensionPoint; |
29 | 32 | import org.zstack.header.vm.VmInstanceDestroyExtensionPoint; |
30 | 33 | import org.zstack.header.vm.VmInstanceInventory; |
31 | 34 | import org.zstack.header.vm.VmInstanceSpec; |
32 | 35 | import org.zstack.header.vm.VmInstantiateResourceException; |
| 36 | +import org.zstack.header.vm.VmMigrationType; |
| 37 | +import org.zstack.header.vm.VmPreMigrationExtensionPoint; |
33 | 38 | import org.zstack.header.vm.additions.VmHostBackupFileVO; |
34 | 39 | import org.zstack.header.vm.additions.VmHostBackupFileVO_; |
35 | 40 | import org.zstack.header.vm.additions.VmHostFileContentFormat; |
|
72 | 77 | import java.util.Map; |
73 | 78 | import java.util.Objects; |
74 | 79 |
|
| 80 | +import static org.zstack.compute.vm.VmGlobalConfig.ENABLE_UEFI_SECURE_BOOT; |
75 | 81 | import static org.zstack.core.Platform.operr; |
| 82 | +import static org.zstack.header.vm.VmMigrationType.HostMigration; |
76 | 83 | import static org.zstack.kvm.KVMConstant.*; |
| 84 | +import static org.zstack.utils.CollectionDSL.list; |
77 | 85 | import static org.zstack.utils.CollectionUtils.findOneOrNull; |
78 | 86 | import static org.zstack.utils.CollectionUtils.transform; |
79 | 87 |
|
80 | 88 | public class KvmSecureBootExtensions implements KVMStartVmExtensionPoint, |
81 | 89 | PreVmInstantiateResourceExtensionPoint, |
82 | | - VmInstanceDestroyExtensionPoint { |
| 90 | + VmInstanceDestroyExtensionPoint, |
| 91 | + VmPreMigrationExtensionPoint { |
83 | 92 | private static final CLogger logger = Utils.getLogger(KvmSecureBootExtensions.class); |
84 | 93 |
|
85 | 94 | @Autowired |
@@ -160,6 +169,61 @@ private void prepareNvRamToStartVmCmd(KVMAgentCommands.StartVmCmd cmd, DiskAO nv |
160 | 169 | } |
161 | 170 | } |
162 | 171 |
|
| 172 | + @Override |
| 173 | + public void preVmMigration(VmInstanceInventory vm, VmMigrationType type, String dstHostUuid, Completion completion) { |
| 174 | + if (HostMigration != type) { |
| 175 | + completion.success(); |
| 176 | + return; |
| 177 | + } |
| 178 | + |
| 179 | + String tpmUuid = Q.New(TpmVO.class) |
| 180 | + .eq(TpmVO_.vmInstanceUuid, vm.getUuid()) |
| 181 | + .select(TpmVO_.uuid) |
| 182 | + .findValue(); |
| 183 | + boolean needRegisterNvRam = tpmUuid != null; |
| 184 | + if (!needRegisterNvRam) { |
| 185 | + String bootMode = VmSystemTags.BOOT_MODE.getTokenByResourceUuid(vm.getUuid(), VmSystemTags.BOOT_MODE_TOKEN); |
| 186 | + if (isUefiBootMode(bootMode)) { |
| 187 | + ResourceConfig resourceConfig = resourceConfigFacade.getResourceConfig(ENABLE_UEFI_SECURE_BOOT.getIdentity()); |
| 188 | + needRegisterNvRam = resourceConfig.getResourceConfigValue(vm.getUuid(), Boolean.class) == Boolean.TRUE; |
| 189 | + } |
| 190 | + |
| 191 | + if (!needRegisterNvRam) { |
| 192 | + completion.success(); |
| 193 | + return; |
| 194 | + } |
| 195 | + } |
| 196 | + |
| 197 | + SimpleFlowChain.of("prepare-nvram-before-vm-" + vm.getUuid() + "-migrate") |
| 198 | + .then("prepare-nvram-folder-on-dest-host", trigger -> { |
| 199 | + VmHostFileTO to = new VmHostFileTO(); |
| 200 | + to.setPath(buildNvramFilePath(vm.getUuid())); |
| 201 | + to.setType(VmHostFileType.NvRam.toString()); |
| 202 | + to.setFileFormat(VmHostFileTO.FORMAT_PREPARE_ONLY); |
| 203 | + |
| 204 | + RewriteVmHostFilesContext context = new RewriteVmHostFilesContext(); |
| 205 | + context.hostUuid = dstHostUuid; |
| 206 | + context.hostFiles = list(to); |
| 207 | + |
| 208 | + rewriteVmHostFiles(context, new Completion(trigger) { |
| 209 | + @Override |
| 210 | + public void success() { |
| 211 | + trigger.next(); |
| 212 | + } |
| 213 | + |
| 214 | + @Override |
| 215 | + public void fail(ErrorCode errorCode) { |
| 216 | + trigger.fail(errorCode); |
| 217 | + } |
| 218 | + }); |
| 219 | + }) |
| 220 | + // TpmState folder is not needed to prepare |
| 221 | + .propagateExceptionTo(completion) |
| 222 | + .done(completion::success) |
| 223 | + .error(completion::fail) |
| 224 | + .start(); |
| 225 | + } |
| 226 | + |
163 | 227 | public static class SyncVmHostFilesFromHostContext { |
164 | 228 | public String hostUuid; |
165 | 229 | public String vmUuid; |
|
0 commit comments