1717package com .cloud .deploy ;
1818
1919import java .util .ArrayList ;
20+ import java .util .Collections ;
21+ import java .util .Comparator ;
2022import java .util .HashMap ;
2123import java .util .List ;
2224import java .util .Map ;
4446import com .cloud .dc .dao .DataCenterDao ;
4547import com .cloud .dc .dao .HostPodDao ;
4648import com .cloud .exception .InsufficientServerCapacityException ;
49+ import com .cloud .gpu .GPU ;
50+ import com .cloud .gpu .dao .HostGpuGroupsDao ;
51+ import com .cloud .host .Host ;
4752import com .cloud .host .dao .HostDao ;
53+ import com .cloud .host .dao .HostTagsDao ;
4854import com .cloud .hypervisor .Hypervisor .HypervisorType ;
4955import com .cloud .offering .ServiceOffering ;
56+ import com .cloud .service .dao .ServiceOfferingDetailsDao ;
5057import com .cloud .storage .StorageManager ;
5158import com .cloud .storage .dao .DiskOfferingDao ;
5259import com .cloud .storage .dao .GuestOSCategoryDao ;
@@ -102,9 +109,16 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPla
102109 DataStoreManager dataStoreMgr ;
103110 @ Inject
104111 protected ClusterDetailsDao _clusterDetailsDao ;
112+ @ Inject
113+ protected ServiceOfferingDetailsDao _serviceOfferingDetailsDao ;
114+ @ Inject
115+ protected HostGpuGroupsDao _hostGpuGroupsDao ;
116+ @ Inject
117+ protected HostTagsDao _hostTagsDao ;
105118
106119 protected String _allocationAlgorithm = "random" ;
107120 protected String _globalDeploymentPlanner = "FirstFitPlanner" ;
121+ protected String [] _implicitHostTags ;
108122
109123 @ Override
110124 public List <Long > orderClusters (VirtualMachineProfile vmProfile , DeploymentPlan plan , ExcludeList avoid ) throws InsufficientServerCapacityException {
@@ -131,7 +145,6 @@ public List<Long> orderClusters(VirtualMachineProfile vmProfile, DeploymentPlan
131145 clusterList .add (clusterIdSpecified );
132146 removeClustersCrossingThreshold (clusterList , avoid , vmProfile , plan );
133147 }
134- return clusterList ;
135148 } else {
136149 s_logger .debug ("The specified cluster cannot be found, returning." );
137150 avoid .addCluster (plan .getClusterId ());
@@ -152,7 +165,6 @@ public List<Long> orderClusters(VirtualMachineProfile vmProfile, DeploymentPlan
152165 avoid .addPod (plan .getPodId ());
153166 }
154167 }
155- return clusterList ;
156168 } else {
157169 s_logger .debug ("The specified Pod cannot be found, returning." );
158170 avoid .addPod (plan .getPodId ());
@@ -164,13 +176,39 @@ public List<Long> orderClusters(VirtualMachineProfile vmProfile, DeploymentPlan
164176 boolean applyAllocationAtPods = Boolean .parseBoolean (_configDao .getValue (Config .ApplyAllocationAlgorithmToPods .key ()));
165177 if (applyAllocationAtPods ) {
166178 //start scan at all pods under this zone.
167- return scanPodsForDestination (vmProfile , plan , avoid );
179+ clusterList = scanPodsForDestination (vmProfile , plan , avoid );
168180 } else {
169181 //start scan at clusters under this zone.
170- return scanClustersForDestinationInZoneOrPod (plan .getDataCenterId (), true , vmProfile , plan , avoid );
182+ clusterList = scanClustersForDestinationInZoneOrPod (plan .getDataCenterId (), true , vmProfile , plan , avoid );
183+ }
184+ }
185+
186+ if (clusterList != null && !clusterList .isEmpty ()) {
187+ ServiceOffering offering = vmProfile .getServiceOffering ();
188+ // In case of non-GPU VMs, protect GPU enabled Hosts and prefer VM deployment on non-GPU Hosts.
189+ if ((_serviceOfferingDetailsDao .findDetail (offering .getId (), GPU .Keys .vgpuType .toString ()) == null ) && !(_hostGpuGroupsDao .listHostIds ().isEmpty ())) {
190+ int requiredCpu = offering .getCpu () * offering .getSpeed ();
191+ long requiredRam = offering .getRamSize () * 1024L * 1024L ;
192+ reorderClustersBasedOnImplicitTags (clusterList , requiredCpu , requiredRam );
171193 }
172194 }
195+ return clusterList ;
196+ }
173197
198+ private void reorderClustersBasedOnImplicitTags (List <Long > clusterList , int requiredCpu , long requiredRam ) {
199+ final HashMap <Long , Long > UniqueTagsInClusterMap = new HashMap <Long , Long >();
200+ for (Long clusterId : clusterList ) {
201+ List <Long > hostList = _capacityDao .listHostsWithEnoughCapacity (requiredCpu , requiredRam , clusterId , Host .Type .Routing .toString ());
202+ UniqueTagsInClusterMap .put (clusterId , new Long (_hostTagsDao .getDistinctImplicitHostTags (hostList , _implicitHostTags ).size ()));
203+ }
204+ Collections .sort (clusterList , new Comparator <Long >() {
205+ @ Override
206+ public int compare (Long o1 , Long o2 ) {
207+ Long t1 = UniqueTagsInClusterMap .get (o1 );
208+ Long t2 = UniqueTagsInClusterMap .get (o2 );
209+ return t1 .compareTo (t2 );
210+ }
211+ });
174212 }
175213
176214 private List <Long > scanPodsForDestination (VirtualMachineProfile vmProfile , DeploymentPlan plan , ExcludeList avoid ) {
@@ -504,6 +542,10 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
504542 super .configure (name , params );
505543 _allocationAlgorithm = _configDao .getValue (Config .VmAllocationAlgorithm .key ());
506544 _globalDeploymentPlanner = _configDao .getValue (Config .VmDeploymentPlanner .key ());
545+ String configValue ;
546+ if ((configValue = _configDao .getValue (Config .ImplicitHostTags .key ())) != null ) {
547+ _implicitHostTags = configValue .trim ().split ("\\ s*,\\ s*" );
548+ }
507549 return true ;
508550 }
509551
0 commit comments