From 0f177c2b501fb14aecb8cb43e31491d404e2fd4e Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 8 May 2025 14:37:04 +0530 Subject: [PATCH 1/3] xenserver: destroy halted vm on expunge Addresses https://github.com/apache/cloudstack/pull/9175#issuecomment-2834546887 Signed-off-by: Abhishek Kumar --- .../com/cloud/hypervisor/XenServerGuru.java | 9 ++ .../CitrixCleanupVMCommandWrapper.java | 82 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/XenServerGuru.java index 9de6ba8ab4f7..98b778817b94 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/XenServerGuru.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/XenServerGuru.java @@ -35,6 +35,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; +import com.cloud.agent.api.CleanupVMCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; @@ -236,4 +237,12 @@ public String getConfigComponentName() { public ConfigKey[] getConfigKeys() { return new ConfigKey[] {MaxNumberOfVCPUSPerVM}; } + + @Override + public List finalizeExpunge(VirtualMachine vm) { + List commands = new ArrayList<>(); + final CleanupVMCommand cleanupVMCommand = new CleanupVMCommand(vm.getInstanceName(), true); + commands.add(cleanupVMCommand); + return commands; + } } diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java new file mode 100644 index 000000000000..d5675044a4dd --- /dev/null +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java @@ -0,0 +1,82 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package com.cloud.hypervisor.xenserver.resource.wrapper.xenbase; + +import java.util.Iterator; +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CleanupVMCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.VM; + +@ResourceWrapper(handles = CleanupVMCommand.class) +public class CitrixCleanupVMCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixCleanupVMCommandWrapper.class); + + @Override + public Answer execute(final CleanupVMCommand command, final CitrixResourceBase citrixResourceBase) { + if (!citrixResourceBase.isDestroyHaltedVms()) { + s_logger.debug(String.format("Cleanup VM is not needed for host with version %s", + citrixResourceBase.getHost().getProductVersion())); + return new Answer(command); + } + final String vmName = command.getVmName(); + try { + final Connection conn = citrixResourceBase.getConnection(); + final Set vms = VM.getByNameLabel(conn, vmName); + if (vms.isEmpty()) { + return new Answer(command, false, "VM does not exist"); + } + // destroy vm which is in HALTED state on this host + final Iterator iter = vms.iterator(); + while (iter.hasNext()) { + final VM vm = iter.next(); + final VM.Record vmr = vm.getRecord(conn); + if (!Types.VmPowerState.HALTED.equals(vmr.powerState)) { + final String msg = String.format("VM %s is not in %s state", vmName, Types.VmPowerState.HALTED); + s_logger.error(msg); + return new Answer(command, false, msg); + } + if (citrixResourceBase.isRefNull(vmr.residentOn)) { + continue; + } + if (vmr.residentOn.getUuid(conn).equals(citrixResourceBase.getHost().getUuid())) { + continue; + } + iter.remove(); + } + for (final VM vm : vms) { + citrixResourceBase.destroyVm(vm, conn, true); + } + + } catch (final Exception e) { + final String msg = String.format("Clean up VM %s fail due to %s", vmName, e); + s_logger.error(msg, e); + return new Answer(command, false, e.getMessage()); + } + return new Answer(command); + } +} From bb60c8852bd10783e77580e50232e5fc77c1f3d4 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 9 May 2025 11:47:12 +0530 Subject: [PATCH 2/3] Update plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java --- .../resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java index d5675044a4dd..cc617a6756b1 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java @@ -48,7 +48,7 @@ public Answer execute(final CleanupVMCommand command, final CitrixResourceBase c final Connection conn = citrixResourceBase.getConnection(); final Set vms = VM.getByNameLabel(conn, vmName); if (vms.isEmpty()) { - return new Answer(command, false, "VM does not exist"); + return new Answer(command, true, "VM does not exist"); } // destroy vm which is in HALTED state on this host final Iterator iter = vms.iterator(); From 93686c73b902eddde74f57cab55be3d61b829325 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 9 May 2025 20:01:19 +0530 Subject: [PATCH 3/3] fix condition :facepalm Signed-off-by: Abhishek Kumar --- .../resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java index cc617a6756b1..3b0408379efd 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupVMCommandWrapper.java @@ -38,7 +38,7 @@ public class CitrixCleanupVMCommandWrapper extends CommandWrapper