From a8af41c04b9ad12a821be84ab596e9ee6c883965 Mon Sep 17 00:00:00 2001 From: Darrin Husselmann Date: Thu, 18 Feb 2021 12:27:01 +0200 Subject: [PATCH 1/4] Added support for removing unused port groups on VMWare --- .../vmware/manager/VmwareManager.java | 3 ++ .../vmware/manager/VmwareManagerImpl.java | 2 +- .../vmware/resource/VmwareResource.java | 29 ++++++++++++------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java index 8cc328a7a386..104919be38c7 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java @@ -46,6 +46,9 @@ public interface VmwareManager { static final ConfigKey s_vmwareOVAPackageTimeout = new ConfigKey(Integer.class, "vmware.package.ova.timeout", "Advanced", "3600", "Vmware script timeout for ova packaging process", true, ConfigKey.Scope.Global, 1000); + static final ConfigKey s_vmwareCleanupPortGroups = new ConfigKey("Advanced", Boolean.class, "vmware.cleanup.port.groups", "true", + "Remove unused port groups.", true, ConfigKey.Scope.Global); + String composeWorkerName(); String getSystemVMIsoFileNameOnDatastore(); diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index e1e0d6b24ee9..97937d66a513 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -270,7 +270,7 @@ public String getConfigComponentName() { @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs, templateCleanupInterval, s_vmwareSearchExcludeFolder, s_vmwareOVAPackageTimeout}; + return new ConfigKey[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs, templateCleanupInterval, s_vmwareSearchExcludeFolder, s_vmwareOVAPackageTimeout, s_vmwareCleanupPortGroups}; } @Override public boolean configure(String name, Map params) throws ConfigurationException { diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 0248903173ba..02d5cd1537e1 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -48,6 +48,7 @@ import javax.naming.ConfigurationException; import javax.xml.datatype.XMLGregorianCalendar; +import com.cloud.hypervisor.vmware.mo.NetworkMO; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; @@ -5823,16 +5824,24 @@ protected Answer execute(UnregisterNicCommand cmd) { } public void cleanupNetwork(HostMO hostMo, NetworkDetails netDetails) { - // we will no longer cleanup VLAN networks in order to support native VMware HA - /* - * assert(netDetails.getName() != null); try { synchronized(this) { NetworkMO networkMo = new - * NetworkMO(hostMo.getContext(), netDetails.getNetworkMor()); ManagedObjectReference[] vms = - * networkMo.getVMsOnNetwork(); if(vms == null || vms.length == 0) { if(s_logger.isInfoEnabled()) { - * s_logger.info("Cleanup network as it is currently not in use: " + netDetails.getName()); } - * - * hostMo.deletePortGroup(netDetails.getName()); } } } catch(Throwable e) { - * s_logger.warn("Unable to cleanup network due to exception, skip for next time"); } - */ + if (!VmwareManager.s_vmwareCleanupPortGroups.value()){ + return; + } + assert(netDetails.getName() != null); + try { + synchronized(this) { + NetworkMO networkMo = new NetworkMO(hostMo.getContext(), netDetails.getNetworkMor()); + List vms = networkMo.getVMsOnNetwork(); + if(vms == null || vms.size() == 0) { + if(s_logger.isInfoEnabled()) { + s_logger.info("Cleanup network as it is currently not in use: " + netDetails.getName()); + } + hostMo.deletePortGroup(netDetails.getName()); + } + } + } catch(Throwable e) { + s_logger.warn("Unable to cleanup network due to exception, skip for next time"); + } } @Override From b50a3508465b15dd9e1460071d8b5f3e6ef83d34 Mon Sep 17 00:00:00 2001 From: spaceman1984 Date: Fri, 25 Jun 2021 10:27:33 +0200 Subject: [PATCH 2/4] Fixed error handling around unavailable portgroup name --- .../cloud/hypervisor/vmware/resource/VmwareResource.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 02d5cd1537e1..22abf6f7c2cf 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -5827,9 +5827,11 @@ public void cleanupNetwork(HostMO hostMo, NetworkDetails netDetails) { if (!VmwareManager.s_vmwareCleanupPortGroups.value()){ return; } - assert(netDetails.getName() != null); try { synchronized(this) { + if (netDetails.getName() == null) { + throw new CloudRuntimeException("Unspecified port group name, unable to cleanup network"); + } NetworkMO networkMo = new NetworkMO(hostMo.getContext(), netDetails.getNetworkMor()); List vms = networkMo.getVMsOnNetwork(); if(vms == null || vms.size() == 0) { @@ -5840,7 +5842,7 @@ public void cleanupNetwork(HostMO hostMo, NetworkDetails netDetails) { } } } catch(Throwable e) { - s_logger.warn("Unable to cleanup network due to exception, skip for next time"); + s_logger.warn("Unable to cleanup network due to exception.", e); } } From 69fed995c1b6db696a7a4b3c35f1a5e829d7af68 Mon Sep 17 00:00:00 2001 From: Darrin Husselmann Date: Wed, 10 Mar 2021 14:08:45 +0200 Subject: [PATCH 3/4] Review changes, defaulting glovbal var to false, added warning to description, changed if statement. --- .../com/cloud/hypervisor/vmware/manager/VmwareManager.java | 4 ++-- .../com/cloud/hypervisor/vmware/resource/VmwareResource.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java index 104919be38c7..efa8d1dcaa4f 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java @@ -46,8 +46,8 @@ public interface VmwareManager { static final ConfigKey s_vmwareOVAPackageTimeout = new ConfigKey(Integer.class, "vmware.package.ova.timeout", "Advanced", "3600", "Vmware script timeout for ova packaging process", true, ConfigKey.Scope.Global, 1000); - static final ConfigKey s_vmwareCleanupPortGroups = new ConfigKey("Advanced", Boolean.class, "vmware.cleanup.port.groups", "true", - "Remove unused port groups.", true, ConfigKey.Scope.Global); + static final ConfigKey s_vmwareCleanupPortGroups = new ConfigKey("Advanced", Boolean.class, "vmware.cleanup.port.groups", "false", + "Remove unused port groups. WARNING: When set to true, native VMware HA might not work.", true, ConfigKey.Scope.Global); String composeWorkerName(); diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 22abf6f7c2cf..6b3aa3bd6047 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -5834,7 +5834,7 @@ public void cleanupNetwork(HostMO hostMo, NetworkDetails netDetails) { } NetworkMO networkMo = new NetworkMO(hostMo.getContext(), netDetails.getNetworkMor()); List vms = networkMo.getVMsOnNetwork(); - if(vms == null || vms.size() == 0) { + if (CollectionUtils.isEmpty(vms)) { if(s_logger.isInfoEnabled()) { s_logger.info("Cleanup network as it is currently not in use: " + netDetails.getName()); } @@ -5842,7 +5842,7 @@ public void cleanupNetwork(HostMO hostMo, NetworkDetails netDetails) { } } } catch(Throwable e) { - s_logger.warn("Unable to cleanup network due to exception.", e); + s_logger.warn("Unable to cleanup network due to exception: " + e.getMessage()); } } From e0a3f404e12630bf0f9df3aec2bc32a20b5df493 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Mon, 23 Aug 2021 17:11:39 +0530 Subject: [PATCH 4/4] Cleanup unused network port groups on all the hosts. --- .../vmware/manager/VmwareManager.java | 2 +- .../vmware/resource/VmwareResource.java | 49 ++++++++++++++----- .../resource/VmwareStorageProcessor.java | 5 +- .../hypervisor/vmware/mo/DatacenterMO.java | 14 ++++++ 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java index efa8d1dcaa4f..e3fbd1a864f1 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java @@ -47,7 +47,7 @@ public interface VmwareManager { "Vmware script timeout for ova packaging process", true, ConfigKey.Scope.Global, 1000); static final ConfigKey s_vmwareCleanupPortGroups = new ConfigKey("Advanced", Boolean.class, "vmware.cleanup.port.groups", "false", - "Remove unused port groups. WARNING: When set to true, native VMware HA might not work.", true, ConfigKey.Scope.Global); + "When set to true, the unused port groups are removed from VMware hypervisor hosts. WARNING: Native VMware HA might not work when enabled.", true, ConfigKey.Scope.Global); String composeWorkerName(); diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 6b3aa3bd6047..243cd6642bbd 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -5823,27 +5823,54 @@ protected Answer execute(UnregisterNicCommand cmd) { } } - public void cleanupNetwork(HostMO hostMo, NetworkDetails netDetails) { + public void cleanupNetwork(DatacenterMO dcMO, NetworkDetails netDetails) { if (!VmwareManager.s_vmwareCleanupPortGroups.value()){ return; } + try { synchronized(this) { - if (netDetails.getName() == null) { - throw new CloudRuntimeException("Unspecified port group name, unable to cleanup network"); + if (!areVMsOnNetwork(dcMO, netDetails)) { + cleanupPortGroup(dcMO, netDetails.getName()); } - NetworkMO networkMo = new NetworkMO(hostMo.getContext(), netDetails.getNetworkMor()); + } + } catch(Throwable e) { + s_logger.warn("Unable to cleanup network due to exception: " + e.getMessage(), e); + } + } + + private void cleanupPortGroup(DatacenterMO dcMO, String portGroupName) throws Exception { + if (StringUtils.isBlank(portGroupName)) { + s_logger.debug("Unspecified network port group, couldn't cleanup"); + return; + } + + List hosts = dcMO.getAllHostsOnDatacenter(); + if (!CollectionUtils.isEmpty(hosts)) { + for (HostMO host : hosts) { + host.deletePortGroup(portGroupName); + } + } + } + + private boolean areVMsOnNetwork(DatacenterMO dcMO, NetworkDetails netDetails) throws Exception { + if (netDetails == null || netDetails.getName() == null) { + throw new CloudRuntimeException("Unspecified network details / port group, couldn't check VMs on network port group"); + } + + List hosts = dcMO.getAllHostsOnDatacenter(); + if (!CollectionUtils.isEmpty(hosts)) { + for (HostMO host : hosts) { + NetworkMO networkMo = new NetworkMO(host.getContext(), netDetails.getNetworkMor()); List vms = networkMo.getVMsOnNetwork(); - if (CollectionUtils.isEmpty(vms)) { - if(s_logger.isInfoEnabled()) { - s_logger.info("Cleanup network as it is currently not in use: " + netDetails.getName()); - } - hostMo.deletePortGroup(netDetails.getName()); + if (!CollectionUtils.isEmpty(vms)) { + s_logger.debug("Network port group: " + netDetails.getName() + " is in use"); + return true; } } - } catch(Throwable e) { - s_logger.warn("Unable to cleanup network due to exception: " + e.getMessage()); } + + return false; } @Override diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java index 97c328674963..30e0191bb226 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -2650,6 +2650,8 @@ public Answer deleteVolume(DeleteCommand cmd) { DatastoreMO dsMo = new DatastoreMO(context, morDs); ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter(); + DatacenterMO dcMo = new DatacenterMO(context, morDc); + ManagedObjectReference morCluster = hyperHost.getHyperHostCluster(); ClusterMO clusterMo = new ClusterMO(context, morCluster); @@ -2660,7 +2662,6 @@ public Answer deleteVolume(DeleteCommand cmd) { VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(vmName); if (vmMo == null) { // Volume might be on a zone-wide storage pool, look for VM in datacenter - DatacenterMO dcMo = new DatacenterMO(context, morDc); vmMo = dcMo.findVm(vmName); } @@ -2715,7 +2716,7 @@ public Answer deleteVolume(DeleteCommand cmd) { for (NetworkDetails netDetails : networks) { if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) { if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) { - resource.cleanupNetwork(hostMo, netDetails); + resource.cleanupNetwork(dcMo, netDetails); } } } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index af89757d521f..ade82275376e 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.List; +import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; import com.vmware.vim25.CustomFieldStringValue; @@ -172,6 +173,19 @@ public List> getAllVmsOnDatacenter() throws return vms; } + public List getAllHostsOnDatacenter() throws Exception { + List hosts = new ArrayList<>(); + + List ocs = getHostPropertiesOnDatacenterHostFolder(new String[] {"name"}); + if (CollectionUtils.isNotEmpty(ocs)) { + for (ObjectContent oc : ocs) { + hosts.add(new HostMO(getContext(), oc.getObj())); + } + } + + return hosts; + } + public ManagedObjectReference findDatastore(String name) throws Exception { assert (name != null);