Skip to content

Commit 192bab5

Browse files
Address the rest of the DRS anti-affinity review
- a skipped migration is CANCELLED, not FAILED. Nothing went wrong; the plan went out of date. FAILED was indistinguishable from a migration that genuinely broke, and left no record of why - record an event when one is skipped, so it is visible rather than a silent no-op in an otherwise successful plan - the processors also cover dedicated resources and DPDK, so the refusal message no longer claims every skip is about an affinity group - hoist the third copy of getVmIdVmMap into AffinityProcessorBase Signed-off-by: Brad House <bhouse@nexthop.ai>
1 parent b7ed756 commit 192bab5

5 files changed

Lines changed: 33 additions & 23 deletions

File tree

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
import com.cloud.vm.VirtualMachineProfile;
2626

2727
import java.util.Collections;
28+
import java.util.HashMap;
2829
import java.util.List;
30+
import java.util.Map;
2931

3032
public class AffinityProcessorBase extends AdapterBase implements AffinityGroupProcessor {
3133

@@ -41,6 +43,23 @@ public void process(VirtualMachineProfile vm, DeploymentPlan plan, ExcludeList a
4143

4244
}
4345

46+
47+
/**
48+
* Indexes placements supplied by the caller. Callers such as DRS build a plan of several moves
49+
* in memory and persist it only at the end, so during planning the database still shows the old
50+
* host for every VM the plan has already moved.
51+
*/
52+
protected Map<Long, VirtualMachine> getVmIdVmMap(List<VirtualMachine> vmList) {
53+
Map<Long, VirtualMachine> vmIdVmMap = new HashMap<>();
54+
if (vmList == null) {
55+
return vmIdVmMap;
56+
}
57+
for (VirtualMachine vm : vmList) {
58+
vmIdVmMap.put(vm.getId(), vm);
59+
}
60+
return vmIdVmMap;
61+
}
62+
4463
@Override
4564
public String getType() {
4665
return _type;

plugins/affinity-group-processors/host-anti-affinity/src/main/java/org/apache/cloudstack/affinity/HostAntiAffinityProcessor.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import java.util.Arrays;
2020
import java.util.Collections;
21-
import java.util.HashMap;
2221
import java.util.List;
2322
import java.util.Map;
2423
import java.util.stream.Collectors;
@@ -133,14 +132,6 @@ protected void processAffinityGroup(AffinityGroupVMMapVO vmGroupMapping, Exclude
133132
}
134133
}
135134

136-
protected Map<Long, VirtualMachine> getVmIdVmMap(List<VirtualMachine> vmList) {
137-
Map<Long, VirtualMachine> vmIdVmMap = new HashMap<>();
138-
for (VirtualMachine vm : vmList) {
139-
vmIdVmMap.put(vm.getId(), vm);
140-
}
141-
return vmIdVmMap;
142-
}
143-
144135
protected void avoidHostOfVmInAffinityGroup(ExcludeList avoid, VMInstanceVO groupVM) {
145136
if (groupVM.getHostId() != null) {
146137
avoid.addHost(groupVM.getHostId());

plugins/affinity-group-processors/non-strict-host-affinity/src/main/java/org/apache/cloudstack/affinity/NonStrictHostAffinityProcessor.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import java.util.Arrays;
2020
import java.util.Collections;
21-
import java.util.HashMap;
2221
import java.util.List;
2322
import java.util.Map;
2423

@@ -113,14 +112,6 @@ protected void processAffinityGroup(AffinityGroupVMMapVO vmGroupMapping, Deploym
113112
}
114113
}
115114

116-
protected Map<Long, VirtualMachine> getVmIdVmMap(List<VirtualMachine> vmList) {
117-
Map<Long, VirtualMachine> vmIdVmMap = new HashMap<>();
118-
for (VirtualMachine vm : vmList) {
119-
vmIdVmMap.put(vm.getId(), vm);
120-
}
121-
return vmIdVmMap;
122-
}
123-
124115
protected void processVmInAffinityGroup(DeploymentPlan plan, VMInstanceVO groupVM) {
125116
if (groupVM.getHostId() != null) {
126117
Integer priority = adjustHostPriority(plan, groupVM.getHostId());

server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -795,13 +795,16 @@ void processPlans() {
795795
* the DRS plan to be executed
796796
*/
797797
/**
798-
* Checks a planned migration against the affinity rules as they stand now.
798+
* Checks a planned migration against the placement rules as they stand now.
799799
*
800800
* A plan is generated once and executed later, so state can have moved on: VMs may have been
801801
* created, migrated or destroyed in between. Anti-affinity in particular is only meaningful
802802
* against current placements, and nothing downstream re-checks it - migrateVirtualMachine does
803803
* not enforce affinity groups.
804804
*
805+
* The processors also cover dedicated resources and DPDK, so a refusal is not necessarily about
806+
* an affinity group.
807+
*
805808
* @param vm
806809
* the VM the plan wants to move
807810
* @param destHost
@@ -863,10 +866,16 @@ void executeDrsPlan(ClusterDrsPlanVO plan) {
863866
}
864867

865868
if (destinationViolatesAffinity(vm, host, dispatched, dispatchedSourceHosts)) {
866-
logger.warn("Skipping DRS migration of vm {} to host {}: it no longer satisfies the affinity " +
867-
"rules for that VM. The plan was generated against older state.", vm, host);
868-
migration.setStatus(JobInfo.Status.FAILED);
869+
String reason = String.format("Skipped DRS migration of %s to %s: the destination no longer "
870+
+ "satisfies the placement rules for that VM. The plan was generated against older "
871+
+ "state.", vm, host);
872+
logger.warn(reason);
873+
// cancelled rather than failed: nothing went wrong, the plan went out of date
874+
migration.setStatus(JobInfo.Status.CANCELLED);
869875
drsPlanMigrationDao.update(migration.getId(), migration);
876+
ActionEventUtils.onCompletedActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM,
877+
EventVO.LEVEL_WARN, EventTypes.EVENT_CLUSTER_DRS, false, reason,
878+
plan.getClusterId(), ApiCommandResourceType.Cluster.toString(), plan.getEventId());
870879
continue;
871880
}
872881

server/src/test/java/org/apache/cloudstack/cluster/ClusterDrsServiceImplTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ public void testExecuteDrsPlanSkipsMigrationThatViolatesAffinity() {
11101110

11111111
clusterDrsService.executeDrsPlan(plan);
11121112

1113-
Mockito.verify(migration).setStatus(JobInfo.Status.FAILED);
1113+
Mockito.verify(migration).setStatus(JobInfo.Status.CANCELLED);
11141114
Mockito.verify(clusterDrsService, Mockito.never())
11151115
.createMigrateVMAsyncJob(Mockito.any(), Mockito.any(), Mockito.anyLong());
11161116
}

0 commit comments

Comments
 (0)