From f7821b41f792637a129fb851045c704f665dfe80 Mon Sep 17 00:00:00 2001 From: Zhang Wenhao Date: Mon, 13 Apr 2026 18:25:03 +0800 Subject: [PATCH] [header]: add Tpm cascade extensions Resolves: ZSV-11799 Related: ZSV-11310 Change-Id: I69656261626e6c73636874707076726378706d68 --- .../vm/devices/TpmCascadeExtension.java | 141 +++++++++++++++++ .../VmHostBackupFileCascadeExtension.java | 148 ++++++++++++++++++ .../devices/VmHostFileCascadeExtension.java | 143 +++++++++++++++++ conf/springConfigXml/VmInstanceManager.xml | 21 +++ ...{RemoveTpmMsg.java => TpmDeletionMsg.java} | 8 +- ...oveTpmReply.java => TpmDeletionReply.java} | 2 +- .../VmHostBackupFileDeletionMsg.java | 15 ++ .../VmHostBackupFileDeletionReply.java | 6 + .../vm/additions/VmHostFileDeletionMsg.java | 15 ++ .../vm/additions/VmHostFileDeletionReply.java | 6 + .../zstack/kvm/efi/KvmSecureBootManager.java | 20 +++ .../org/zstack/kvm/tpm/KvmTpmExtensions.java | 5 +- .../org/zstack/kvm/tpm/KvmTpmManager.java | 19 ++- 13 files changed, 534 insertions(+), 15 deletions(-) create mode 100644 compute/src/main/java/org/zstack/compute/vm/devices/TpmCascadeExtension.java create mode 100644 compute/src/main/java/org/zstack/compute/vm/devices/VmHostBackupFileCascadeExtension.java create mode 100644 compute/src/main/java/org/zstack/compute/vm/devices/VmHostFileCascadeExtension.java rename header/src/main/java/org/zstack/header/tpm/message/{RemoveTpmMsg.java => TpmDeletionMsg.java} (73%) rename header/src/main/java/org/zstack/header/tpm/message/{RemoveTpmReply.java => TpmDeletionReply.java} (62%) create mode 100644 header/src/main/java/org/zstack/header/vm/additions/VmHostBackupFileDeletionMsg.java create mode 100644 header/src/main/java/org/zstack/header/vm/additions/VmHostBackupFileDeletionReply.java create mode 100644 header/src/main/java/org/zstack/header/vm/additions/VmHostFileDeletionMsg.java create mode 100644 header/src/main/java/org/zstack/header/vm/additions/VmHostFileDeletionReply.java diff --git a/compute/src/main/java/org/zstack/compute/vm/devices/TpmCascadeExtension.java b/compute/src/main/java/org/zstack/compute/vm/devices/TpmCascadeExtension.java new file mode 100644 index 00000000000..2dded6e9125 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/devices/TpmCascadeExtension.java @@ -0,0 +1,141 @@ +package org.zstack.compute.vm.devices; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cascade.AbstractAsyncCascadeExtension; +import org.zstack.core.cascade.CascadeAction; +import org.zstack.core.cascade.CascadeConstant; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.core.Completion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.message.MessageReply; +import org.zstack.header.tpm.entity.TpmVO; +import org.zstack.header.tpm.entity.TpmVO_; +import org.zstack.header.tpm.message.TpmDeletionMsg; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.List; + +import static org.zstack.core.Platform.operr; +import static org.zstack.header.tpm.TpmConstants.SERVICE_ID; +import static org.zstack.utils.CollectionDSL.list; +import static org.zstack.utils.CollectionUtils.transformAndRemoveNull; + +public class TpmCascadeExtension extends AbstractAsyncCascadeExtension { + private static final CLogger logger = Utils.getLogger(TpmCascadeExtension.class); + + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + + private static final String NAME = TpmVO.class.getSimpleName(); + + @Override + public void asyncCascade(CascadeAction action, Completion completion) { + if (action.isActionCode(CascadeConstant.DELETION_CHECK_CODE)) { + handleDeletionCheck(action, completion); + } else if (action.isActionCode(CascadeConstant.DELETION_DELETE_CODE, CascadeConstant.DELETION_FORCE_DELETE_CODE)) { + handleDeletion(action, completion); + } else if (action.isActionCode(CascadeConstant.DELETION_CLEANUP_CODE)) { + handleDeletionCleanup(action, completion); + } else { + completion.success(); + } + } + + private List tpmFromAction(CascadeAction action) { + if (VmInstanceVO.class.getSimpleName().equals(action.getParentIssuer())) { + List vmInventories = action.getParentIssuerContext(); + List vmUuidList = transformAndRemoveNull(vmInventories, VmInstanceInventory::getUuid); + + if (vmUuidList.isEmpty()) { + return null; + } + return Q.New(TpmVO.class) + .in(TpmVO_.vmInstanceUuid, vmUuidList) + .list(); + } else if (NAME.equals(action.getParentIssuer())) { + return action.getParentIssuerContext(); + } + + return null; + } + + private void handleDeletionCheck(CascadeAction action, Completion completion) { + completion.success(); + } + + private void handleDeletion(CascadeAction action, Completion completion) { + final List tpmList = tpmFromAction(action); + if (CollectionUtils.isEmpty(tpmList)) { + completion.success(); + return; + } + + new While<>(tpmList).each((tpm, whileCompletion) -> { + TpmDeletionMsg msg = new TpmDeletionMsg(); + msg.setTpmUuid(tpm.getUuid()); + msg.setVmInstanceUuid(tpm.getVmInstanceUuid()); + msg.setForceDelete(true); + bus.makeTargetServiceIdByResourceUuid(msg, SERVICE_ID, msg.getTpmUuid()); + bus.send(msg, new CloudBusCallBack(whileCompletion) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + logger.debug(String.format("deleted Tpm[uuid:%s] from VM[uuid:%s]", + tpm.getUuid(), tpm.getVmInstanceUuid())); + } else { + whileCompletion.addError(reply.getError()); + whileCompletion.allDone(); + } + whileCompletion.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.isEmpty()) { + completion.fail(operr("failed to delete Tpm from VM[uuid:%s]", tpmList.get(0).getVmInstanceUuid()) + .withCause(errorCodeList)); + return; + } + completion.success(); + } + }); + } + + private void handleDeletionCleanup(CascadeAction action, Completion completion) { + completion.success(); + } + + @Override + public List getEdgeNames() { + return list(VmInstanceVO.class.getSimpleName()); + } + + @Override + public String getCascadeResourceName() { + return NAME; + } + + @Override + public CascadeAction createActionForChildResource(CascadeAction action) { + if (CascadeConstant.DELETION_CODES.contains(action.getActionCode())) { + List ctx = tpmFromAction(action); + if (ctx != null) { + return action.copy().setParentIssuer(NAME).setParentIssuerContext(ctx); + } + } + + return null; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/devices/VmHostBackupFileCascadeExtension.java b/compute/src/main/java/org/zstack/compute/vm/devices/VmHostBackupFileCascadeExtension.java new file mode 100644 index 00000000000..ed2690d20a4 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/devices/VmHostBackupFileCascadeExtension.java @@ -0,0 +1,148 @@ +package org.zstack.compute.vm.devices; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cascade.AbstractAsyncCascadeExtension; +import org.zstack.core.cascade.CascadeAction; +import org.zstack.core.cascade.CascadeConstant; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.core.Completion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.message.MessageReply; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.additions.VmHostBackupFileDeletionMsg; +import org.zstack.header.vm.additions.VmHostBackupFileVO; +import org.zstack.header.vm.additions.VmHostBackupFileVO_; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.List; + +import static org.zstack.core.Platform.operr; +import static org.zstack.utils.CollectionDSL.list; +import static org.zstack.utils.CollectionUtils.transformAndRemoveNull; + +public class VmHostBackupFileCascadeExtension extends AbstractAsyncCascadeExtension { + private static final CLogger logger = Utils.getLogger(VmHostBackupFileCascadeExtension.class); + + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + + private static final String NAME = VmHostBackupFileVO.class.getSimpleName(); + + @Override + public void asyncCascade(CascadeAction action, Completion completion) { + if (action.isActionCode(CascadeConstant.DELETION_CHECK_CODE)) { + handleDeletionCheck(action, completion); + } else if (action.isActionCode(CascadeConstant.DELETION_DELETE_CODE, CascadeConstant.DELETION_FORCE_DELETE_CODE)) { + handleDeletion(action, completion); + } else if (action.isActionCode(CascadeConstant.DELETION_CLEANUP_CODE)) { + handleDeletionCleanup(action, completion); + } else { + completion.success(); + } + } + + private List voFromAction(CascadeAction action) { + if (VmInstanceVO.class.getSimpleName().equals(action.getParentIssuer())) { + List vmInventories = action.getParentIssuerContext(); + List vmUuidList = transformAndRemoveNull(vmInventories, VmInstanceInventory::getUuid); + + if (vmUuidList.isEmpty()) { + return null; + } + return Q.New(VmHostBackupFileVO.class) + .in(VmHostBackupFileVO_.resourceUuid, vmUuidList) + .list(); + } + // Note: VolumeSnapshotGroupVO has no cascade extension! + // skip: else if (VolumeSnapshotGroupVO.class.getSimpleName().equals(action.getParentIssuer())) + else if (NAME.equals(action.getParentIssuer())) { + return action.getParentIssuerContext(); + } + + return null; + } + + private void handleDeletionCheck(CascadeAction action, Completion completion) { + completion.success(); + } + + private void handleDeletion(CascadeAction action, Completion completion) { + final List voList = voFromAction(action); + if (CollectionUtils.isEmpty(voList)) { + completion.success(); + return; + } + + new While<>(voList).each((vo, whileCompletion) -> { + VmHostBackupFileDeletionMsg msg = new VmHostBackupFileDeletionMsg(); + msg.setUuid(vo.getUuid()); + msg.setForceDelete(true); + bus.makeLocalServiceId(msg, VmInstanceConstant.SECURE_BOOT_SERVICE_ID); + bus.send(msg, new CloudBusCallBack(whileCompletion) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + logger.debug(String.format("deleted VmHostBackupFile[uuid:%s] from resource[uuid:%s]", + vo.getUuid(), vo.getResourceUuid())); + } else { + whileCompletion.addError(reply.getError()); + whileCompletion.allDone(); + } + whileCompletion.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.isEmpty()) { + completion.fail(operr("failed to delete VmHostBackupFile from resource[uuid:%s]", voList.get(0).getResourceUuid()) + .withCause(errorCodeList)); + return; + } + completion.success(); + } + }); + } + + private void handleDeletionCleanup(CascadeAction action, Completion completion) { + completion.success(); + } + + @Override + public List getEdgeNames() { + return list( + VmInstanceVO.class.getSimpleName() + + // Note: VolumeSnapshotGroupVO has no cascade extension! + // skip: VolumeSnapshotGroupVO.class.getName() + ); + } + + @Override + public String getCascadeResourceName() { + return NAME; + } + + @Override + public CascadeAction createActionForChildResource(CascadeAction action) { + if (CascadeConstant.DELETION_CODES.contains(action.getActionCode())) { + List ctx = voFromAction(action); + if (ctx != null) { + return action.copy().setParentIssuer(NAME).setParentIssuerContext(ctx); + } + } + + return null; + } +} \ No newline at end of file diff --git a/compute/src/main/java/org/zstack/compute/vm/devices/VmHostFileCascadeExtension.java b/compute/src/main/java/org/zstack/compute/vm/devices/VmHostFileCascadeExtension.java new file mode 100644 index 00000000000..76e6c8b356f --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/devices/VmHostFileCascadeExtension.java @@ -0,0 +1,143 @@ +package org.zstack.compute.vm.devices; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cascade.AbstractAsyncCascadeExtension; +import org.zstack.core.cascade.CascadeAction; +import org.zstack.core.cascade.CascadeConstant; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.core.Completion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.message.MessageReply; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.additions.VmHostFileDeletionMsg; +import org.zstack.header.vm.additions.VmHostFileVO; +import org.zstack.header.vm.additions.VmHostFileVO_; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.List; + +import static org.zstack.core.Platform.operr; +import static org.zstack.utils.CollectionDSL.list; +import static org.zstack.utils.CollectionUtils.transformAndRemoveNull; + +public class VmHostFileCascadeExtension extends AbstractAsyncCascadeExtension { + private static final CLogger logger = Utils.getLogger(VmHostFileCascadeExtension.class); + + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + + private static final String NAME = VmHostFileVO.class.getSimpleName(); + + @Override + public void asyncCascade(CascadeAction action, Completion completion) { + if (action.isActionCode(CascadeConstant.DELETION_CHECK_CODE)) { + handleDeletionCheck(action, completion); + } else if (action.isActionCode(CascadeConstant.DELETION_DELETE_CODE, CascadeConstant.DELETION_FORCE_DELETE_CODE)) { + handleDeletion(action, completion); + } else if (action.isActionCode(CascadeConstant.DELETION_CLEANUP_CODE)) { + handleDeletionCleanup(action, completion); + } else { + completion.success(); + } + } + + private List voFromAction(CascadeAction action) { + if (VmInstanceVO.class.getSimpleName().equals(action.getParentIssuer())) { + List vmInventories = action.getParentIssuerContext(); + List vmUuidList = transformAndRemoveNull(vmInventories, VmInstanceInventory::getUuid); + + if (vmUuidList.isEmpty()) { + return null; + } + return Q.New(VmHostFileVO.class) + .in(VmHostFileVO_.vmInstanceUuid, vmUuidList) + .list(); + } else if (NAME.equals(action.getParentIssuer())) { + return action.getParentIssuerContext(); + } + + return null; + } + + private void handleDeletionCheck(CascadeAction action, Completion completion) { + completion.success(); + } + + private void handleDeletion(CascadeAction action, Completion completion) { + final List voList = voFromAction(action); + if (CollectionUtils.isEmpty(voList)) { + completion.success(); + return; + } + + new While<>(voList).each((vo, whileCompletion) -> { + VmHostFileDeletionMsg msg = new VmHostFileDeletionMsg(); + msg.setUuid(vo.getUuid()); + msg.setForceDelete(true); + bus.makeLocalServiceId(msg, VmInstanceConstant.SECURE_BOOT_SERVICE_ID); + bus.send(msg, new CloudBusCallBack(whileCompletion) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + logger.debug(String.format("deleted VmHostFile[uuid:%s] from VM[uuid:%s]", + vo.getUuid(), vo.getVmInstanceUuid())); + } else { + whileCompletion.addError(reply.getError()); + whileCompletion.allDone(); + } + whileCompletion.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.isEmpty()) { + completion.fail(operr("failed to delete VmHostFile from VM[uuid:%s]", voList.get(0).getVmInstanceUuid()) + .withCause(errorCodeList)); + return; + } + completion.success(); + } + }); + } + + private void handleDeletionCleanup(CascadeAction action, Completion completion) { + completion.success(); + } + + @Override + public List getEdgeNames() { + // Note: host delete -> VmHostFileVO should not be delete: + // TPM/NvRam is too important and should not be deleted so easily. + // And hostUuid will not be updated -> host is not reachable. it is by design. + return list(VmInstanceVO.class.getSimpleName()); + } + + @Override + public String getCascadeResourceName() { + return NAME; + } + + @Override + public CascadeAction createActionForChildResource(CascadeAction action) { + if (CascadeConstant.DELETION_CODES.contains(action.getActionCode())) { + List ctx = voFromAction(action); + if (ctx != null) { + return action.copy().setParentIssuer(NAME).setParentIssuerContext(ctx); + } + } + + return null; + } +} \ No newline at end of file diff --git a/conf/springConfigXml/VmInstanceManager.xml b/conf/springConfigXml/VmInstanceManager.xml index 1b284284d29..5810a203d11 100755 --- a/conf/springConfigXml/VmInstanceManager.xml +++ b/conf/springConfigXml/VmInstanceManager.xml @@ -290,6 +290,27 @@ + + + + + + + + + + + + + + + + + + diff --git a/header/src/main/java/org/zstack/header/tpm/message/RemoveTpmMsg.java b/header/src/main/java/org/zstack/header/tpm/message/TpmDeletionMsg.java similarity index 73% rename from header/src/main/java/org/zstack/header/tpm/message/RemoveTpmMsg.java rename to header/src/main/java/org/zstack/header/tpm/message/TpmDeletionMsg.java index c68e16bc8d5..a11a998c992 100644 --- a/header/src/main/java/org/zstack/header/tpm/message/RemoveTpmMsg.java +++ b/header/src/main/java/org/zstack/header/tpm/message/TpmDeletionMsg.java @@ -1,9 +1,9 @@ package org.zstack.header.tpm.message; -import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.message.DeletionMessage; import org.zstack.header.tpm.api.APIRemoveTpmMsg; -public class RemoveTpmMsg extends NeedReplyMessage { +public class TpmDeletionMsg extends DeletionMessage { private String tpmUuid; private String vmInstanceUuid; @@ -23,8 +23,8 @@ public void setVmInstanceUuid(String vmInstanceUuid) { this.vmInstanceUuid = vmInstanceUuid; } - public static RemoveTpmMsg valueOf(APIRemoveTpmMsg api) { - RemoveTpmMsg msg = new RemoveTpmMsg(); + public static TpmDeletionMsg valueOf(APIRemoveTpmMsg api) { + TpmDeletionMsg msg = new TpmDeletionMsg(); msg.setTpmUuid(api.getTpmUuid()); msg.setVmInstanceUuid(api.getVmInstanceUuid()); return msg; diff --git a/header/src/main/java/org/zstack/header/tpm/message/RemoveTpmReply.java b/header/src/main/java/org/zstack/header/tpm/message/TpmDeletionReply.java similarity index 62% rename from header/src/main/java/org/zstack/header/tpm/message/RemoveTpmReply.java rename to header/src/main/java/org/zstack/header/tpm/message/TpmDeletionReply.java index ad2e3b13292..39e05dc7a24 100644 --- a/header/src/main/java/org/zstack/header/tpm/message/RemoveTpmReply.java +++ b/header/src/main/java/org/zstack/header/tpm/message/TpmDeletionReply.java @@ -2,5 +2,5 @@ import org.zstack.header.message.MessageReply; -public class RemoveTpmReply extends MessageReply { +public class TpmDeletionReply extends MessageReply { } diff --git a/header/src/main/java/org/zstack/header/vm/additions/VmHostBackupFileDeletionMsg.java b/header/src/main/java/org/zstack/header/vm/additions/VmHostBackupFileDeletionMsg.java new file mode 100644 index 00000000000..b386cc8ecf6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/additions/VmHostBackupFileDeletionMsg.java @@ -0,0 +1,15 @@ +package org.zstack.header.vm.additions; + +import org.zstack.header.message.DeletionMessage; + +public class VmHostBackupFileDeletionMsg extends DeletionMessage { + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/additions/VmHostBackupFileDeletionReply.java b/header/src/main/java/org/zstack/header/vm/additions/VmHostBackupFileDeletionReply.java new file mode 100644 index 00000000000..b87c233c4c1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/additions/VmHostBackupFileDeletionReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.vm.additions; + +import org.zstack.header.message.MessageReply; + +public class VmHostBackupFileDeletionReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/vm/additions/VmHostFileDeletionMsg.java b/header/src/main/java/org/zstack/header/vm/additions/VmHostFileDeletionMsg.java new file mode 100644 index 00000000000..0b4a7499ad1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/additions/VmHostFileDeletionMsg.java @@ -0,0 +1,15 @@ +package org.zstack.header.vm.additions; + +import org.zstack.header.message.DeletionMessage; + +public class VmHostFileDeletionMsg extends DeletionMessage { + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/additions/VmHostFileDeletionReply.java b/header/src/main/java/org/zstack/header/vm/additions/VmHostFileDeletionReply.java new file mode 100644 index 00000000000..56f22079798 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/additions/VmHostFileDeletionReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.vm.additions; + +import org.zstack.header.message.MessageReply; + +public class VmHostFileDeletionReply extends MessageReply { +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java b/plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java index 5a62cc6dc6d..4884d89a5cc 100644 --- a/plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootManager.java @@ -34,11 +34,15 @@ import org.zstack.header.vm.VmInstanceVO_; import org.zstack.header.vm.additions.RestoreVmHostFileMsg; import org.zstack.header.vm.additions.RestoreVmHostFileReply; +import org.zstack.header.vm.additions.VmHostBackupFileDeletionMsg; +import org.zstack.header.vm.additions.VmHostBackupFileDeletionReply; import org.zstack.header.vm.additions.VmHostBackupFileVO; import org.zstack.header.vm.additions.VmHostBackupFileVO_; import org.zstack.header.vm.additions.VmHostFileContentFormat; import org.zstack.header.vm.additions.VmHostFileContentVO; import org.zstack.header.vm.additions.VmHostFileContentVO_; +import org.zstack.header.vm.additions.VmHostFileDeletionMsg; +import org.zstack.header.vm.additions.VmHostFileDeletionReply; import org.zstack.header.vm.additions.VmHostFileOperation; import org.zstack.header.vm.additions.VmHostFileType; import org.zstack.header.vm.additions.VmHostFileVO; @@ -258,6 +262,10 @@ public void handleMessage(Message msg) { handle((RestoreVmHostFileMsg) msg); } else if (msg instanceof BackupVmHostFileOnHypervisorMsg) { handle((BackupVmHostFileOnHypervisorMsg) msg); + } else if (msg instanceof VmHostFileDeletionMsg) { + handle((VmHostFileDeletionMsg) msg); + } else if (msg instanceof VmHostBackupFileDeletionMsg) { + handle((VmHostBackupFileDeletionMsg) msg); } else { bus.dealWithUnknownMessage(msg); } @@ -1064,4 +1072,16 @@ public void fail(ErrorCode errorCode) { } }); } + + private void handle(VmHostFileDeletionMsg msg) { + VmHostFileDeletionReply reply = new VmHostFileDeletionReply(); + databaseFacade.removeByPrimaryKey(msg.getUuid(), VmHostFileVO.class); + bus.reply(msg, reply); + } + + private void handle(VmHostBackupFileDeletionMsg msg) { + VmHostBackupFileDeletionReply reply = new VmHostBackupFileDeletionReply(); + databaseFacade.removeByPrimaryKey(msg.getUuid(), VmHostBackupFileVO.class); + bus.reply(msg, reply); + } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmExtensions.java b/plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmExtensions.java index eaa846aeb5c..86774d075fa 100644 --- a/plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmExtensions.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmExtensions.java @@ -40,7 +40,7 @@ import org.zstack.header.vm.VmAfterExpungeExtensionPoint; import org.zstack.header.vm.VmInstanceMigrateExtensionPoint; import org.zstack.header.secret.SecretHostDefineReply; -import org.zstack.header.tpm.message.RemoveTpmMsg; +import org.zstack.header.tpm.message.TpmDeletionMsg; import org.zstack.header.vm.PreVmInstantiateResourceExtensionPoint; import org.zstack.header.vm.VmInstanceInventory; import org.zstack.header.vm.VmInstanceSpec; @@ -519,9 +519,10 @@ public void vmJustBeforeDeleteFromDb(VmInstanceInventory inv) { deleteHostSecretBestEffort(hostUuid, inv.getUuid(), keyVersion, "vm-just-before-delete-from-db"); } - RemoveTpmMsg removeMsg = new RemoveTpmMsg(); + TpmDeletionMsg removeMsg = new TpmDeletionMsg(); removeMsg.setVmInstanceUuid(inv.getUuid()); removeMsg.setTpmUuid(tpmUuid); + removeMsg.setForceDelete(true); bus.makeTargetServiceIdByResourceUuid(removeMsg, SERVICE_ID, removeMsg.getTpmUuid()); MessageReply reply = bus.call(removeMsg); if (!reply.isSuccess()) { diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmManager.java b/plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmManager.java index 7b8da96fc97..00faea34236 100644 --- a/plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmManager.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmManager.java @@ -27,6 +27,7 @@ import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.host.HostConstant; +import org.zstack.header.message.APIDeleteMessage; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; @@ -44,8 +45,8 @@ import org.zstack.header.tpm.entity.TpmVO_; import org.zstack.header.tpm.message.AddTpmMsg; import org.zstack.header.tpm.message.AddTpmReply; -import org.zstack.header.tpm.message.RemoveTpmMsg; -import org.zstack.header.tpm.message.RemoveTpmReply; +import org.zstack.header.tpm.message.TpmDeletionMsg; +import org.zstack.header.tpm.message.TpmDeletionReply; import org.zstack.header.vm.VmInstanceVO; import org.zstack.header.vm.VmInstanceVO_; import org.zstack.header.vm.additions.ResetVmTpmMsg; @@ -138,8 +139,8 @@ public void handleMessage(Message msg) { private void handleLocalMessage(Message msg) { if (msg instanceof AddTpmMsg) { handle((AddTpmMsg) msg); - } else if (msg instanceof RemoveTpmMsg) { - handle((RemoveTpmMsg) msg); + } else if (msg instanceof TpmDeletionMsg) { + handle((TpmDeletionMsg) msg); } else if (msg instanceof CloneVmTpmMsg) { handle((CloneVmTpmMsg) msg); } else if (msg instanceof ResetVmTpmMsg) { @@ -272,8 +273,8 @@ private void addTpmToVm(AddTpmToVmContext context, Completion completion) { .start(); } - private void handle(RemoveTpmMsg msg) { - RemoveTpmReply reply = new RemoveTpmReply(); + private void handle(TpmDeletionMsg msg) { + TpmDeletionReply reply = new TpmDeletionReply(); threadFacade.chainSubmit(new ChainTask(msg) { @Override public void run(SyncTaskChain chain) { @@ -316,10 +317,11 @@ static class RemoveTpmFromVmContext { List hostFiles; - static RemoveTpmFromVmContext valueOf(RemoveTpmMsg msg) { + static RemoveTpmFromVmContext valueOf(TpmDeletionMsg msg) { RemoveTpmFromVmContext context = new RemoveTpmFromVmContext(); context.vmInstanceUuid = msg.getVmInstanceUuid(); context.tpmUuid = msg.getTpmUuid(); + context.force = msg.isForceDelete(); return context; } } @@ -911,7 +913,8 @@ public void run(MessageReply reply) { private void handle(APIRemoveTpmMsg msg) { APIRemoveTpmEvent event = new APIRemoveTpmEvent(msg.getId()); - RemoveTpmMsg inner = RemoveTpmMsg.valueOf(msg); + TpmDeletionMsg inner = TpmDeletionMsg.valueOf(msg); + inner.setForceDelete(APIDeleteMessage.DeletionMode.Enforcing.equals(msg.getDeletionMode())); bus.makeTargetServiceIdByResourceUuid(inner, SERVICE_ID, msg.getTpmUuid()); bus.send(inner, new CloudBusCallBack(msg) { @Override