diff --git a/engine/schema/src/com/cloud/host/dao/HostDao.java b/engine/schema/src/com/cloud/host/dao/HostDao.java index bd484825c812..a9dfb63f6473 100644 --- a/engine/schema/src/com/cloud/host/dao/HostDao.java +++ b/engine/schema/src/com/cloud/host/dao/HostDao.java @@ -71,6 +71,8 @@ public interface HostDao extends GenericDao, StateDao findHypervisorHostInCluster(long clusterId); + HostVO findOlderHypervisorHostInCluster(long clusterId); + /** * @param type * @param clusterId diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java index 8342f1fcf773..698b4e385766 100644 --- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java +++ b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java @@ -1081,6 +1081,23 @@ public List findHypervisorHostInCluster(long clusterId) { return listBy(sc); } + @Override + public HostVO findOlderHypervisorHostInCluster(long clusterId) { + SearchCriteria sc = TypeClusterStatusSearch.create(); + sc.setParameters("type", Host.Type.Routing); + sc.setParameters("cluster", clusterId); + sc.setParameters("status", Status.Up); + sc.setParameters("resourceState", ResourceState.Enabled); + Filter orderByFilter = new Filter(HostVO.class, "created", true, null, null); + + List hosts = search(sc, orderByFilter, null, false); + if (hosts != null && hosts.size() > 0) { + return hosts.get(0); + } + + return null; + } + @Override public List listAllHosts(long zoneId) { SearchCriteria sc = HostIdSearch.create(); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 575801fa6034..f902430cba39 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -21,6 +21,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.net.URLDecoder; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.HashMap; @@ -71,6 +72,8 @@ import com.cloud.exception.DiscoveryException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceInUseException; +import com.cloud.host.dao.HostDao; +import com.cloud.host.HostVO; import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -120,6 +123,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; import com.cloud.utils.ssh.SshHelper; +import com.cloud.utils.UriUtils; import com.cloud.vm.DomainRouterVO; public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService { @@ -138,6 +142,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw @Inject private NetworkModel _netMgr; @Inject + private HostDao _hostDao; + @Inject private ClusterDao _clusterDao; @Inject private ClusterDetailsDao _clusterDetailsDao; @@ -374,6 +380,29 @@ private void prepareHost(HostMO hostMo, String privateTrafficLabel) throws Excep } } + private HostMO getOlderHostInCluster(Long clusterId, VmwareContext serviceContext) throws Exception { + HostVO host = _hostDao.findOlderHypervisorHostInCluster(clusterId); + if (host == null) { + return null; + } + + ManagedObjectReference morSrcHost = HypervisorHostHelper.getHypervisorHostMorFromGuid(host.getGuid()); + if (morSrcHost == null) { + Map clusterDetails = _clusterDetailsDao.findDetails(clusterId); + if (clusterDetails.get("url") == null) { + return null; + } + + URI uriForHost = new URI(UriUtils.encodeURIComponent(clusterDetails.get("url") + "/" + host.getName())); + morSrcHost = serviceContext.getHostMorByPath(URLDecoder.decode(uriForHost.getPath(), "UTF-8")); + if (morSrcHost == null) { + return null; + } + } + + return new HostMO(serviceContext, morSrcHost); + } + @Override public List addHostToPodCluster(VmwareContext serviceContext, long dcId, Long podId, Long clusterId, String hostInventoryPath) throws Exception { @@ -426,6 +455,11 @@ public List addHostToPodCluster(VmwareContext serviceCon // For ESX host, we need to enable host firewall to allow VNC access HostMO hostMo = new HostMO(serviceContext, mor); prepareHost(hostMo, privateTrafficLabel); + HostMO olderHostMo = getOlderHostInCluster(clusterId, serviceContext); + if (olderHostMo != null) { + hostMo.copyPortGroupsFromHost(olderHostMo); + } + returnedHostList.add(mor); return returnedHostList; } else { diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java index d8fa7f355db1..249def0b6966 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java @@ -48,6 +48,7 @@ import com.vmware.vim25.HostNetworkTrafficShapingPolicy; import com.vmware.vim25.HostOpaqueNetworkInfo; import com.vmware.vim25.HostPortGroup; +import com.vmware.vim25.HostPortGroupPort; import com.vmware.vim25.HostPortGroupSpec; import com.vmware.vim25.HostRuntimeInfo; import com.vmware.vim25.HostSystemConnectionState; @@ -127,6 +128,43 @@ public HostPortGroupSpec getHostPortGroupSpec(String portGroupName) throws Excep return null; } + public List getHostPortGroupSpecs() throws Exception { + HostNetworkInfo hostNetInfo = getHostNetworkInfo(); + if (hostNetInfo == null) { + return null; + } + + List portGroups = hostNetInfo.getPortgroup(); + if (portGroups == null) { + return null; + } + + List portGroupSpecs = new ArrayList(); + for (HostPortGroup portGroup : portGroups) { + if (!isVMKernelPort(portGroup)) { + portGroupSpecs.add(portGroup.getSpec()); + } + } + + return portGroupSpecs; + } + + private boolean isVMKernelPort(HostPortGroup portGroup) { + assert (portGroup != null); + List ports = portGroup.getPort(); + if (ports == null) { + return false; + } + + for (HostPortGroupPort port : ports) { + if (port.getType().equalsIgnoreCase("host")) { + return true; + } + } + + return false; + } + @Override public String getHyperHostName() throws Exception { return getName(); @@ -1110,4 +1148,39 @@ public String getNetworkName(String netMorVal) throws Exception { } return networkName; } + + public void createPortGroup(HostPortGroupSpec spec) throws Exception { + if (spec == null) { + return; + } + + synchronized (_mor.getValue().intern()) { + HostNetworkSystemMO hostNetMo = getHostNetworkSystemMO(); + if (hostNetMo == null) { + return; + } + + ManagedObjectReference morNetwork = getNetworkMor(spec.getName()); + if (morNetwork == null) { + hostNetMo.addPortGroup(spec); + } + } + } + + public void copyPortGroupsFromHost(HostMO srcHost) throws Exception { + if (srcHost == null) { + return; + } + + List portGroupSpecs = srcHost.getHostPortGroupSpecs(); + if (portGroupSpecs == null || portGroupSpecs.isEmpty()) { + s_logger.debug("No port groups in the host: " + srcHost.getName()); + return; + } + + for (HostPortGroupSpec spec : portGroupSpecs) { + s_logger.debug("Creating port group: " + spec.getName() + " in the host: " + getName()); + createPortGroup(spec); + } + } } diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java index fc27d1f8e430..74e21d89c94d 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java @@ -1571,6 +1571,30 @@ public void action(Long param) { } } + public static ManagedObjectReference getHypervisorHostMorFromGuid(String guid) { + if (guid == null) { + return null; + } + + String[] tokens = guid.split("@"); + if (tokens == null || tokens.length != 2) { + s_logger.error("Invalid content in host guid"); + return null; + } + + String[] hostTokens = tokens[0].split(":"); + if (hostTokens == null || hostTokens.length != 2) { + s_logger.error("Invalid content in host guid"); + return null; + } + + ManagedObjectReference morHyperHost = new ManagedObjectReference(); + morHyperHost.setType(hostTokens[0]); + morHyperHost.setValue(hostTokens[1]); + + return morHyperHost; + } + public static String getScsiController(Pair controllerInfo, String recommendedController) { String rootDiskController = controllerInfo.first(); String dataDiskController = controllerInfo.second();