From 6632809e88095410c66d29255828b59902360db1 Mon Sep 17 00:00:00 2001 From: Pavan Aravapalli Date: Tue, 25 Nov 2025 03:28:07 +0530 Subject: [PATCH] Added support to remove CloudStack metadata (zone, pod, cluster, host details) from Libvirt XML for KVM VMs after an unmanage operation, controlled by the global config vm.unmanage.libvirt.metadata.cleanup [default: true] --- .../java/com/cloud/agent/api/to/VirtualMachineTO.java | 5 +++++ .../org/apache/cloudstack/vm/UnmanagedVMsManager.java | 8 ++++++++ .../java/com/cloud/agent/api/UnmanageInstanceCommand.java | 7 +++++++ .../main/java/com/cloud/vm/VirtualMachineManagerImpl.java | 2 ++ .../hypervisor/kvm/resource/LibvirtComputingResource.java | 3 ++- .../wrapper/LibvirtUnmanageInstanceCommandWrapper.java | 3 +++ .../org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java | 3 ++- 7 files changed, 29 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java index e26cc1e9f02..bdde2a3fbb6 100644 --- a/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java +++ b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java @@ -90,6 +90,7 @@ public class VirtualMachineTO { private String metadataManufacturer; private String metadataProductName; private VirtualMachineMetadataTO metadata; + private boolean excludeMetadata; public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader, String os, boolean enableHA, boolean limitCpuUse, String vncPassword) { @@ -503,6 +504,10 @@ public class VirtualMachineTO { this.metadata = metadata; } + public boolean isExcludeMetadata() { return excludeMetadata; } + + public void setExcludeMetadata(boolean excludeMetadata) { this.excludeMetadata = excludeMetadata;} + @Override public String toString() { return String.format("VM {id: \"%s\", name: \"%s\", uuid: \"%s\", type: \"%s\"}", id, name, uuid, type); diff --git a/api/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManager.java b/api/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManager.java index b6233b9c270..235c3299f65 100644 --- a/api/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManager.java +++ b/api/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManager.java @@ -69,6 +69,14 @@ public interface UnmanagedVMsManager extends VmImportService, UnmanageVMService, true, ConfigKey.Scope.Global, null); + ConfigKey VmUnmanageLibvirtMetadataCleanup = new ConfigKey<>(Boolean.class, + "vm.unmanage.libvirt.metadata.cleanup", + "Advanced", + "true", + "Specifies whether metadata should be cleaned up when a VM is unmanaged, applicable to the KVM hypervisor.", + true, + ConfigKey.Scope.Global, + null); static boolean isSupported(Hypervisor.HypervisorType hypervisorType) { return hypervisorType == VMware || hypervisorType == KVM; diff --git a/core/src/main/java/com/cloud/agent/api/UnmanageInstanceCommand.java b/core/src/main/java/com/cloud/agent/api/UnmanageInstanceCommand.java index dd504b9ea26..e5540c2e80d 100644 --- a/core/src/main/java/com/cloud/agent/api/UnmanageInstanceCommand.java +++ b/core/src/main/java/com/cloud/agent/api/UnmanageInstanceCommand.java @@ -28,6 +28,7 @@ public class UnmanageInstanceCommand extends Command { boolean executeInSequence = false; VirtualMachineTO vm; boolean isConfigDriveAttached; + boolean isLibvirtMetadataCleanUpEnabled; @Override public boolean executeInSequence() { @@ -58,4 +59,10 @@ public class UnmanageInstanceCommand extends Command { public void setConfigDriveAttached(boolean configDriveAttached) { isConfigDriveAttached = configDriveAttached; } + + public boolean isLibvirtMetadataCleanupEnabled() {return isLibvirtMetadataCleanUpEnabled;} + + public void setLibvirtMetadataCleanup(boolean libvirtMetadataCleanUp) { + isLibvirtMetadataCleanUpEnabled = libvirtMetadataCleanUp; + } } diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index b3e672e2c17..ebd02b59836 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -2091,6 +2091,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac unmanageInstanceCommand = new UnmanageInstanceCommand(vmName); unmanageInstanceCommand.setConfigDriveAttached(vmInstanceDetailsDao.findDetail(vm.getId(), VmDetailConstants.CONFIG_DRIVE_LOCATION) != null); } + boolean isEnabled = UnmanagedVMsManager.VmUnmanageLibvirtMetadataCleanup.value(); + unmanageInstanceCommand.setLibvirtMetadataCleanup(isEnabled); logger.debug("Selected host ID: {} to persist domain XML for Instance: {}.", agentHostId, vmName); try { diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index fbfe3ef20eb..74b318587ba 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -3014,7 +3014,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv vm.addComp(createDevicesDef(vmTO, guest, vcpus, isUefiEnabled)); MetadataDef metaDef; - if ((metaDef = createMetadataDef(vmTO)) != null) { + boolean excludeMetadata = vmTO.isExcludeMetadata(); + if (!excludeMetadata && (metaDef = createMetadataDef(vmTO)) != null) { vm.addComp(metaDef); } diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnmanageInstanceCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnmanageInstanceCommandWrapper.java index 33ad274b8d1..2d4344b1adf 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnmanageInstanceCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnmanageInstanceCommandWrapper.java @@ -67,6 +67,9 @@ public final class LibvirtUnmanageInstanceCommandWrapper extends CommandWrapper< public Answer execute(final UnmanageInstanceCommand command, final LibvirtComputingResource libvirtComputingResource) { String instanceName = command.getInstanceName(); VirtualMachineTO vmSpec = command.getVm(); + if (command.isLibvirtMetadataCleanupEnabled()) { + vmSpec.setExcludeMetadata(true); + } final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper(); logger.debug("Attempting to unmanage KVM instance: {}", instanceName); Domain dom = null; diff --git a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java index 13fa2608016..3145a028203 100644 --- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java @@ -3037,7 +3037,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager { ThreadsOnMSToImportVMwareVMFiles, ThreadsOnKVMHostToImportVMwareVMFiles, ConvertVmwareInstanceToKvmExtraParamsAllowed, - ConvertVmwareInstanceToKvmExtraParamsAllowedList + ConvertVmwareInstanceToKvmExtraParamsAllowedList, + VmUnmanageLibvirtMetadataCleanup }; } }