Skip to content

Commit 6610889

Browse files
author
Prachi Damle
committed
CLOUDSTACK-2155 Anti-Affinity -When Vm deployment is done in parallel , anti-affinity rule is not honored.
Changes to check if the destination found does not conflict with any vm reservation
1 parent c79b827 commit 6610889

24 files changed

Lines changed: 138 additions & 31 deletions

api/src/org/apache/cloudstack/affinity/AffinityGroupProcessor.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// under the License.
1717
package org.apache.cloudstack.affinity;
1818

19+
import com.cloud.deploy.DeployDestination;
1920
import com.cloud.deploy.DeploymentPlan;
2021
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
2122
import com.cloud.exception.AffinityConflictException;
@@ -46,4 +47,16 @@ void process(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan
4647
* @return String Affinity/Anti-affinity type
4748
*/
4849
String getType();
50+
51+
/**
52+
* check() is called to see if the planned destination fits the group
53+
* requirements
54+
*
55+
* @param vm
56+
* virtual machine.
57+
* @param plannedDestination
58+
* deployment destination where VM is planned to be deployed
59+
*/
60+
boolean check(VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination plannedDestination)
61+
throws AffinityConflictException;
4962
}

api/src/org/apache/cloudstack/affinity/AffinityProcessorBase.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// under the License.
1717
package org.apache.cloudstack.affinity;
1818

19+
import com.cloud.deploy.DeployDestination;
1920
import com.cloud.deploy.DeploymentPlan;
2021
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
2122
import com.cloud.exception.AffinityConflictException;
@@ -41,4 +42,10 @@ public String getType() {
4142
public void setType(String type) {
4243
_type = type;
4344
}
45+
46+
@Override
47+
public boolean check(VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination plannedDestination)
48+
throws AffinityConflictException {
49+
return true;
50+
}
4451
}

engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
// under the License.
1717
package org.apache.cloudstack.engine.cloud.entity.api;
1818

19-
import java.util.ArrayList;
2019
import java.util.HashMap;
2120
import java.util.List;
2221
import java.util.Map;
@@ -181,38 +180,49 @@ public String reserveVirtualMachine(VMEntityVO vmEntityVO, String plannerToUse,
181180

182181
}
183182

184-
DeployDestination dest;
185-
try {
186-
dest = _dpMgr.planDeployment(vmProfile, plan, exclude);
187-
} catch (AffinityConflictException e) {
188-
throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict");
189-
}
183+
while (true) {
184+
DeployDestination dest = null;
185+
try {
186+
dest = _dpMgr.planDeployment(vmProfile, plan, exclude);
187+
} catch (AffinityConflictException e) {
188+
throw new CloudRuntimeException(
189+
"Unable to create deployment, affinity rules associted to the VM conflict");
190+
}
191+
192+
if (dest != null) {
193+
if (_dpMgr.finalizeReservation(dest, vmProfile, plan, exclude)) {
194+
// save destination with VMEntityVO
195+
VMReservationVO vmReservation = new VMReservationVO(vm.getId(), dest.getDataCenter().getId(), dest
196+
.getPod().getId(), dest.getCluster().getId(), dest.getHost().getId());
197+
Map<Long, Long> volumeReservationMap = new HashMap<Long, Long>();
198+
199+
if (vm.getHypervisorType() != HypervisorType.BareMetal) {
200+
for (Volume vo : dest.getStorageForDisks().keySet()) {
201+
volumeReservationMap.put(vo.getId(), dest.getStorageForDisks().get(vo).getId());
202+
}
203+
vmReservation.setVolumeReservation(volumeReservationMap);
204+
}
190205

191-
if (dest != null) {
192-
//save destination with VMEntityVO
193-
VMReservationVO vmReservation = new VMReservationVO(vm.getId(), dest.getDataCenter().getId(), dest.getPod().getId(), dest.getCluster().getId(), dest.getHost().getId());
194-
Map<Long,Long> volumeReservationMap = new HashMap<Long,Long>();
206+
vmEntityVO.setVmReservation(vmReservation);
207+
_vmEntityDao.persist(vmEntityVO);
195208

196-
if (vm.getHypervisorType() != HypervisorType.BareMetal) {
197-
for(Volume vo : dest.getStorageForDisks().keySet()){
198-
volumeReservationMap.put(vo.getId(), dest.getStorageForDisks().get(vo).getId());
209+
return vmReservation.getUuid();
210+
} else {
211+
try {
212+
Thread.sleep(10000);
213+
} catch (final InterruptedException e) {
214+
}
215+
continue;
199216
}
200-
vmReservation.setVolumeReservation(volumeReservationMap);
217+
} else if (planChangedByReadyVolume) {
218+
// we could not reserve in the Volume's cluster - let the deploy
219+
// call retry it.
220+
return UUID.randomUUID().toString();
221+
} else {
222+
throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile,
223+
DataCenter.class, plan.getDataCenterId(), areAffinityGroupsAssociated(vmProfile));
201224
}
202-
203-
vmEntityVO.setVmReservation(vmReservation);
204-
_vmEntityDao.persist(vmEntityVO);
205-
206-
return vmReservation.getUuid();
207-
} else if (planChangedByReadyVolume) {
208-
// we could not reserve in the Volume's cluster - let the deploy
209-
// call retry it.
210-
return UUID.randomUUID().toString();
211-
}else{
212-
throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile,
213-
DataCenter.class, plan.getDataCenterId(), areAffinityGroupsAssociated(vmProfile));
214225
}
215-
216226
}
217227

218228
@Override

engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMComputeTagVO.java renamed to engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMComputeTagVO.java

File renamed without changes.

engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java renamed to engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// to you under the Apache License, Version 2.0 (the
66
// "License"); you may not use this file except in compliance
77
// with the License. You may obtain a copy of the License at
8-
//
8+
//
99
// http://www.apache.org/licenses/LICENSE-2.0
1010
//
1111
// Unless required by applicable law or agreed to in writing,
@@ -181,10 +181,10 @@ public class VMEntityVO implements VirtualMachine, FiniteStateObject<State, Virt
181181

182182
@Column(name="disk_offering_id")
183183
protected Long diskOfferingId;
184-
184+
185185
@Transient
186186
private VMReservationVO vmReservation;
187-
187+
188188

189189
public VMEntityVO(long id,
190190
long serviceOfferingId,

engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMNetworkMapVO.java renamed to engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMNetworkMapVO.java

File renamed without changes.

engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMReservationVO.java renamed to engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMReservationVO.java

File renamed without changes.

engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMRootDiskTagVO.java renamed to engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMRootDiskTagVO.java

File renamed without changes.

engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/db/VolumeReservationVO.java renamed to engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VolumeReservationVO.java

File renamed without changes.

engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDao.java renamed to engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDao.java

File renamed without changes.

0 commit comments

Comments
 (0)