diff --git a/api/src/com/cloud/hypervisor/HypervisorCapabilities.java b/api/src/com/cloud/hypervisor/HypervisorCapabilities.java index d52c36b12f5..aff81b0018d 100644 --- a/api/src/com/cloud/hypervisor/HypervisorCapabilities.java +++ b/api/src/com/cloud/hypervisor/HypervisorCapabilities.java @@ -46,4 +46,10 @@ public interface HypervisorCapabilities extends Identity, InternalIdentity{ * @return the max. data volumes per VM supported by hypervisor */ Integer getMaxDataVolumesLimit(); + + /** + * @return the max. hosts per cluster supported by hypervisor + */ + Integer getMaxHostsPerCluster(); + } diff --git a/core/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java b/core/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java index 56e8e0a734d..b525a2d05d5 100644 --- a/core/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java +++ b/core/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java @@ -59,6 +59,9 @@ public class HypervisorCapabilitiesVO implements HypervisorCapabilities { @Column(name="max_data_volumes_limit") private Integer maxDataVolumesLimit; + @Column(name="max_hosts_per_cluster") + private Integer maxHostsPerCluster; + protected HypervisorCapabilitiesVO() { this.uuid = UUID.randomUUID().toString(); } @@ -157,6 +160,15 @@ public class HypervisorCapabilitiesVO implements HypervisorCapabilities { this.maxDataVolumesLimit = maxDataVolumesLimit; } + @Override + public Integer getMaxHostsPerCluster() { + return maxHostsPerCluster; + } + + public void setMaxHostsPerCluster(Integer maxHostsPerCluster) { + this.maxHostsPerCluster = maxHostsPerCluster; + } + @Override public boolean equals(Object obj) { if (obj instanceof HypervisorCapabilitiesVO) { diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index ddbce661239..84c37473a4a 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -45,6 +45,7 @@ import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.hypervisor.vmware.manager.VmwareManager; import com.cloud.hypervisor.vmware.mo.ClusterMO; import com.cloud.hypervisor.vmware.mo.HostMO; @@ -95,78 +96,69 @@ public class VmwareServerDiscoverer extends DiscovererBase implements CiscoNexusVSMDeviceDao _nexusDao; @Inject NetworkModel _netmgr; - + @Inject + HypervisorCapabilitiesDao _hvCapabilitiesDao; + public VmwareServerDiscoverer() { s_logger.info("VmwareServerDiscoverer is constructed"); } - - @Override - public Map> find(long dcId, - Long podId, Long clusterId, URI url, String username, - String password, List hostTags) throws DiscoveryException { - if (s_logger.isInfoEnabled()) - s_logger.info("Discover host. dc: " + dcId + ", pod: " + podId - + ", cluster: " + clusterId + ", uri host: " - + url.getHost()); + @Override + public Map> find(long dcId, Long podId, Long clusterId, URI url, + String username, String password, List hostTags) throws DiscoveryException { + + if(s_logger.isInfoEnabled()) + s_logger.info("Discover host. dc: " + dcId + ", pod: " + podId + ", cluster: " + clusterId + ", uri host: " + url.getHost()); + + if(podId == null) { + if(s_logger.isInfoEnabled()) + s_logger.info("No pod is assigned, assuming that it is not for vmware and skip it to next discoverer"); + return null; + } + + ClusterVO cluster = _clusterDao.findById(clusterId); + if(cluster == null || cluster.getHypervisorType() != HypervisorType.VMware) { + if(s_logger.isInfoEnabled()) + s_logger.info("invalid cluster id or cluster is not for VMware hypervisors"); + return null; + } + + List hosts = _resourceMgr.listAllHostsInCluster(clusterId); + if (hosts != null && hosts.size() > 0) { + int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(hosts.get(0).getHypervisorType(), hosts.get(0).getHypervisorVersion()); + if (hosts.size() > maxHostsPerCluster) { + String msg = "VMware cluster " + cluster.getName() + " is too big to add new host now. (current configured cluster size: " + maxHostsPerCluster + ")"; + s_logger.error(msg); + throw new DiscoveredWithErrorException(msg); + } + } - if (podId == null) { - if (s_logger.isInfoEnabled()) - s_logger.info("No pod is assigned, assuming that it is not for vmware and skip it to next discoverer"); - return null; - } - - ClusterVO cluster = _clusterDao.findById(clusterId); - if (cluster == null - || cluster.getHypervisorType() != HypervisorType.VMware) { - if (s_logger.isInfoEnabled()) - s_logger.info("invalid cluster id or cluster is not for VMware hypervisors"); - return null; - } - - List hosts = _resourceMgr.listAllHostsInCluster(clusterId); - if (hosts.size() >= _vmwareMgr.getMaxHostsPerCluster()) { - String msg = "VMware cluster " - + cluster.getName() - + " is too big to add new host now. (current configured cluster size: " - + _vmwareMgr.getMaxHostsPerCluster() + ")"; - s_logger.error(msg); - throw new DiscoveredWithErrorException(msg); - } - - String privateTrafficLabel = null; - String publicTrafficLabel = null; - String guestTrafficLabel = null; - Map vsmCredentials = null; - - privateTrafficLabel = _netmgr.getDefaultManagementTrafficLabel(dcId, - HypervisorType.VMware); - if (privateTrafficLabel != null) { - s_logger.info("Detected private network label : " - + privateTrafficLabel); - } - - if (_vmwareMgr.getNexusVSwitchGlobalParameter()) { - DataCenterVO zone = _dcDao.findById(dcId); - NetworkType zoneType = zone.getNetworkType(); - if (zoneType != NetworkType.Basic) { - publicTrafficLabel = _netmgr.getDefaultPublicTrafficLabel(dcId, - HypervisorType.VMware); - if (publicTrafficLabel != null) { - s_logger.info("Detected public network label : " - + publicTrafficLabel); - } - } - // Get physical network label - guestTrafficLabel = _netmgr.getDefaultGuestTrafficLabel(dcId, - HypervisorType.VMware); - if (guestTrafficLabel != null) { - s_logger.info("Detected guest network label : " - + guestTrafficLabel); - } - vsmCredentials = _vmwareMgr - .getNexusVSMCredentialsByClusterId(clusterId); - } + String privateTrafficLabel = null; + String publicTrafficLabel = null; + String guestTrafficLabel = null; + Map vsmCredentials = null; + + privateTrafficLabel = _netmgr.getDefaultManagementTrafficLabel(dcId, HypervisorType.VMware); + if (privateTrafficLabel != null) { + s_logger.info("Detected private network label : " + privateTrafficLabel); + } + + if (_vmwareMgr.getNexusVSwitchGlobalParameter()) { + DataCenterVO zone = _dcDao.findById(dcId); + NetworkType zoneType = zone.getNetworkType(); + if (zoneType != NetworkType.Basic) { + publicTrafficLabel = _netmgr.getDefaultPublicTrafficLabel(dcId, HypervisorType.VMware); + if (publicTrafficLabel != null) { + s_logger.info("Detected public network label : " + publicTrafficLabel); + } + } + // Get physical network label + guestTrafficLabel = _netmgr.getDefaultGuestTrafficLabel(dcId, HypervisorType.VMware); + if (guestTrafficLabel != null) { + s_logger.info("Detected guest network label : " + guestTrafficLabel); + } + vsmCredentials = _vmwareMgr.getNexusVSMCredentialsByClusterId(clusterId); + } VmwareContext context = null; try { diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java index e1ca6ccac03..e219c1cc426 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java @@ -29,10 +29,6 @@ import com.vmware.vim25.ManagedObjectReference; public interface VmwareManager { public final String CONTEXT_STOCK_NAME = "vmwareMgr"; - // this limitation comes from the fact that we are using linked clone on shared VMFS storage, - // we need to limit the size of vCenter cluster, http://en.wikipedia.org/wiki/VMware_VMFS - public final int MAX_HOSTS_PER_CLUSTER = 8; - String composeWorkerName(); String getSystemVMIsoFileNameOnDatastore(); @@ -57,7 +53,6 @@ public interface VmwareManager { Pair getAddiionalVncPortRange(); - int getMaxHostsPerCluster(); int getRouterExtraPublicNics(); boolean beginExclusiveOperation(int timeOutSeconds); 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 88e03f5a220..e6d57426db2 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -58,6 +58,7 @@ import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.hypervisor.vmware.VmwareCleanupMaid; import com.cloud.hypervisor.vmware.mo.DiskControllerType; import com.cloud.hypervisor.vmware.mo.HostFirewallSystemMO; @@ -91,6 +92,7 @@ import com.cloud.utils.ssh.SshHelper; import com.cloud.vm.DomainRouterVO; import com.google.gson.Gson; import com.vmware.apputils.vim25.ServiceUtil; +import com.vmware.vim25.AboutInfo; import com.vmware.vim25.HostConnectSpec; import com.vmware.vim25.ManagedObjectReference; @@ -119,6 +121,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw @Inject ClusterVSMMapDao _vsmMapDao; @Inject ConfigurationDao _configDao; @Inject ConfigurationServer _configServer; + @Inject HypervisorCapabilitiesDao _hvCapabilitiesDao; String _mountParent; StorageLayer _storage; @@ -133,7 +136,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw String _recycleHungWorker = "false"; int _additionalPortRangeStart; int _additionalPortRangeSize; - int _maxHostsPerCluster; int _routerExtraPublicNics = 2; String _cpuOverprovisioningFactor = "1"; @@ -260,7 +262,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw _routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2); - _maxHostsPerCluster = NumbersUtil.parseInt(_configDao.getValue(Config.VmwarePerClusterHostMax.key()), VmwareManager.MAX_HOSTS_PER_CLUSTER); _cpuOverprovisioningFactor = _configDao.getValue(Config.CPUOverprovisioningFactor.key()); if(_cpuOverprovisioningFactor == null || _cpuOverprovisioningFactor.isEmpty()) _cpuOverprovisioningFactor = "1"; @@ -400,10 +401,15 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw ManagedObjectReference[] hosts = (ManagedObjectReference[])serviceContext.getServiceUtil().getDynamicProperty(mor, "host"); assert(hosts != null); - if(hosts.length > _maxHostsPerCluster) { - String msg = "vCenter cluster size is too big (current configured cluster size: " + _maxHostsPerCluster + ")"; - s_logger.error(msg); - throw new DiscoveredWithErrorException(msg); + if (hosts.length > 0) { + AboutInfo about = (AboutInfo)(serviceContext.getServiceUtil().getDynamicProperty(hosts[0], "config.product")); + String version = about.getApiVersion(); + int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(HypervisorType.VMware, version); + if (hosts.length > maxHostsPerCluster) { + String msg = "vCenter cluster size is too big (current configured cluster size: " + maxHostsPerCluster + ")"; + s_logger.error(msg); + throw new DiscoveredWithErrorException(msg); + } } for(ManagedObjectReference morHost: hosts) { @@ -868,11 +874,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw return new Pair(_additionalPortRangeStart, _additionalPortRangeSize); } - @Override - public int getMaxHostsPerCluster() { - return this._maxHostsPerCluster; - } - @Override public int getRouterExtraPublicNics() { return this._routerExtraPublicNics; diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index b22bf4b76f0..abc6a09e4ef 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -258,7 +258,6 @@ public enum Config { VmwareAdditionalVncPortRangeStart("Advanced", ManagementServer.class, Integer.class, "vmware.additional.vnc.portrange.start", "50000", "Start port number of additional VNC port range", null), VmwareAdditionalVncPortRangeSize("Advanced", ManagementServer.class, Integer.class, "vmware.additional.vnc.portrange.size", "1000", "Start port number of additional VNC port range", null), //VmwareGuestNicDeviceType("Advanced", ManagementServer.class, String.class, "vmware.guest.nic.device.type", "E1000", "Ethernet card type used in guest VM, valid values are E1000, PCNet32, Vmxnet2, Vmxnet3", null), - VmwarePerClusterHostMax("Advanced", ManagementServer.class, Integer.class, "vmware.percluster.host.max", "8", "maxmium hosts per vCenter cluster(do not let it grow over 8)", "1-8"), VmwareReserveCpu("Advanced", ManagementServer.class, Boolean.class, "vmware.reserve.cpu", "false", "Specify whether or not to reserve CPU based on CPU overprovisioning factor", null), VmwareReserveMem("Advanced", ManagementServer.class, Boolean.class, "vmware.reserve.mem", "false", "Specify whether or not to reserve memory based on memory overprovisioning factor", null), VmwareRootDiskControllerType("Advanced", ManagementServer.class, String.class, "vmware.root.disk.controller", "ide", "Specify the default disk controller for root volumes, valid values are scsi, ide", null), diff --git a/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java b/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java index 8f4a47584b3..0fe0b535f78 100644 --- a/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java +++ b/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java @@ -31,4 +31,6 @@ public interface HypervisorCapabilitiesDao extends GenericDao HypervisorTypeSearch; protected final SearchBuilder HypervisorTypeAndVersionSearch; - protected final GenericSearchBuilder MaxGuestLimitByHypervisorSearch; - protected final GenericSearchBuilder MaxDataVolumesLimitByHypervisorSearch; private static final String DEFAULT_VERSION = "default"; @@ -52,18 +50,14 @@ public class HypervisorCapabilitiesDaoImpl extends GenericDaoBase sc = MaxGuestLimitByHypervisorSearch.create(); - sc.setParameters("hypervisorType", hypervisorType); - sc.setParameters("hypervisorVersion", hypervisorVersion); - List limitList = customSearch(sc, null); - if(!limitList.isEmpty()){ - result = limitList.get(0); - }else{ - useDefault = true; - } - }else{ - useDefault = true; - } - if(useDefault){ - SearchCriteria sc = MaxGuestLimitByHypervisorSearch.create(); - sc.setParameters("hypervisorType", hypervisorType); - sc.setParameters("hypervisorVersion", DEFAULT_VERSION); - List limitList = customSearch(sc, null); - if(!limitList.isEmpty()){ - result = limitList.get(0); - } - } - if(result == null){ + HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion); + Long limit = result.getMaxGuestsLimit(); + if (limit == null) return defaultLimit; - } - return result; + return limit; } @Override public Integer getMaxDataVolumesLimit(HypervisorType hypervisorType, String hypervisorVersion) { - Integer result = null; - boolean useDefault = false; - if (hypervisorVersion != null) { - SearchCriteria sc = MaxDataVolumesLimitByHypervisorSearch.create(); - sc.setParameters("hypervisorType", hypervisorType); - sc.setParameters("hypervisorVersion", hypervisorVersion); - List limitList = customSearch(sc, null); - if (!limitList.isEmpty()) { - result = limitList.get(0); - } else { - useDefault = true; - } - } else { - useDefault = true; - } - // If data is not available for a specific hypervisor version then use 'default' as the version - if (useDefault) { - SearchCriteria sc = MaxDataVolumesLimitByHypervisorSearch.create(); - sc.setParameters("hypervisorType", hypervisorType); - sc.setParameters("hypervisorVersion", DEFAULT_VERSION); - List limitList = customSearch(sc, null); - if (!limitList.isEmpty()) { - result = limitList.get(0); - } - } - return result; + HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion); + return result.getMaxDataVolumesLimit(); } -} \ No newline at end of file + + @Override + public Integer getMaxHostsPerCluster(HypervisorType hypervisorType, String hypervisorVersion) { + HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion); + return result.getMaxHostsPerCluster(); + } +} diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 11ae26745e8..b4f992d4287 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -1650,6 +1650,7 @@ CREATE TABLE `cloud`.`hypervisor_capabilities` ( `max_guests_limit` bigint unsigned DEFAULT 50, `security_group_enabled` int(1) unsigned DEFAULT 1 COMMENT 'Is security group supported', `max_data_volumes_limit` int unsigned DEFAULT 6 COMMENT 'Max. data volumes per VM supported by hypervisor', + `max_hosts_per_cluster` int unsigned DEFAULT NULL COMMENT 'Max. hosts in cluster supported by hypervisor', PRIMARY KEY (`id`), CONSTRAINT `uc_hypervisor_capabilities__uuid` UNIQUE (`uuid`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; @@ -1661,10 +1662,11 @@ INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', '5.6 SP2', 50, 1); INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_data_volumes_limit) VALUES ('XenServer', '6.0', 50, 1, 13); INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_data_volumes_limit) VALUES ('XenServer', '6.0.2', 50, 1, 13); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', 'default', 128, 0); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', '4.0', 128, 0); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', '4.1', 128, 0); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', '5.0', 128, 0); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_hosts_per_cluster) VALUES ('VMware', 'default', 128, 0, 32); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_hosts_per_cluster) VALUES ('VMware', '4.0', 128, 0, 32); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_hosts_per_cluster) VALUES ('VMware', '4.1', 128, 0, 32); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_hosts_per_cluster) VALUES ('VMware', '5.0', 128, 0, 32); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_hosts_per_cluster) VALUES ('VMware', '5.1', 128, 0, 32); INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('KVM', 'default', 50, 1); INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('Ovm', 'default', 25, 1); INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('Ovm', '2.3', 25, 1);