Skip to content

Commit 889045f

Browse files
new plugins: Add non-strict affinity groups (#6845)
1 parent 440d780 commit 889045f

33 files changed

Lines changed: 1397 additions & 9 deletions

File tree

api/src/main/java/com/cloud/deploy/DataCenterDeployment.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
2222

2323
import java.util.ArrayList;
24+
import java.util.HashMap;
2425
import java.util.List;
26+
import java.util.Map;
2527

2628
public class DataCenterDeployment implements DeploymentPlan {
2729
long _dcId;
@@ -35,6 +37,7 @@ public class DataCenterDeployment implements DeploymentPlan {
3537
ReservationContext _context;
3638
List<Long> preferredHostIds = new ArrayList<>();
3739
boolean migrationPlan;
40+
Map<Long, Integer> hostPriorities = new HashMap<>();
3841

3942
public DataCenterDeployment(long dataCenterId) {
4043
this(dataCenterId, null, null, null, null, null);
@@ -124,4 +127,32 @@ public String toString() {
124127
"migrationPlan");
125128
}
126129

130+
@Override
131+
public void adjustHostPriority(Long hostId, HostPriorityAdjustment adjustment) {
132+
Integer currentPriority = hostPriorities.get(hostId);
133+
if (currentPriority == null) {
134+
currentPriority = DEFAULT_HOST_PRIORITY;
135+
} else if (currentPriority.equals(PROHIBITED_HOST_PRIORITY)) {
136+
return;
137+
}
138+
if (HostPriorityAdjustment.HIGHER.equals(adjustment)) {
139+
hostPriorities.put(hostId, currentPriority + ADJUST_HOST_PRIORITY_BY);
140+
} else if (HostPriorityAdjustment.LOWER.equals(adjustment)) {
141+
hostPriorities.put(hostId, currentPriority - ADJUST_HOST_PRIORITY_BY);
142+
} else if (HostPriorityAdjustment.DEFAULT.equals(adjustment)) {
143+
hostPriorities.put(hostId, DEFAULT_HOST_PRIORITY);
144+
} else if (HostPriorityAdjustment.PROHIBIT.equals(adjustment)) {
145+
hostPriorities.put(hostId, PROHIBITED_HOST_PRIORITY);
146+
}
147+
}
148+
149+
@Override
150+
public Map<Long, Integer> getHostPriorities() {
151+
return hostPriorities;
152+
}
153+
154+
@Override
155+
public void setHostPriorities(Map<Long, Integer> priorities) {
156+
this.hostPriorities = priorities;
157+
}
127158
}

api/src/main/java/com/cloud/deploy/DeploymentPlan.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,23 @@
2020
import com.cloud.vm.ReservationContext;
2121

2222
import java.util.List;
23+
import java.util.Map;
2324

2425
/**
2526
*/
2627
public interface DeploymentPlan {
28+
29+
Integer DEFAULT_HOST_PRIORITY = 0;
30+
Integer PROHIBITED_HOST_PRIORITY = Integer.MIN_VALUE;
31+
Integer ADJUST_HOST_PRIORITY_BY = 1;
32+
33+
enum HostPriorityAdjustment {
34+
HIGHER,
35+
DEFAULT,
36+
LOWER,
37+
PROHIBIT
38+
}
39+
2740
// TODO: This interface is not fully developed. It really
2841
// number of parameters to be specified.
2942

@@ -73,4 +86,10 @@ public interface DeploymentPlan {
7386
List<Long> getPreferredHosts();
7487

7588
boolean isMigrationPlan();
89+
90+
void adjustHostPriority(Long hostId, HostPriorityAdjustment priority);
91+
92+
Map<Long, Integer> getHostPriorities();
93+
94+
void setHostPriorities(Map<Long, Integer> priorities);
7695
}

api/src/main/java/com/cloud/vm/VirtualMachineProfile.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public static class Param {
7575
public static final Param BootType = new Param("BootType");
7676
public static final Param BootIntoSetup = new Param("enterHardwareSetup");
7777
public static final Param PreserveNics = new Param("PreserveNics");
78+
public static final Param ConsiderLastHost = new Param("ConsiderLastHost");
7879

7980
private String name;
8081

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ public class ApiConstants {
634634
public static final String PURPOSE = "purpose";
635635
public static final String IS_TAGGED = "istagged";
636636
public static final String INSTANCE_NAME = "instancename";
637+
public static final String CONSIDER_LAST_HOST = "considerlasthost";
637638
public static final String START_VM = "startvm";
638639
public static final String HA_HOST = "hahost";
639640
public static final String CUSTOM_DISK_OFF_MIN_SIZE = "customdiskofferingminsize";

api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ public class StartVMCmd extends BaseAsyncCmd implements UserCmd {
8282
since = "3.0.1")
8383
private Long hostId;
8484

85+
@Parameter(name = ApiConstants.CONSIDER_LAST_HOST,
86+
type = CommandType.BOOLEAN,
87+
description = "True by default, CloudStack will firstly try to start the VM on the last host where it run on before stopping, if destination host is not specified. " +
88+
"If false, CloudStack will not consider the last host and start the VM by normal process.",
89+
since = "4.18.0")
90+
private Boolean considerLastHost;
91+
8592
@Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "Deployment planner to use for vm allocation. Available to ROOT admin only", since = "4.4", authorized = { RoleType.Admin })
8693
private String deploymentPlanner;
8794

@@ -112,6 +119,10 @@ public Boolean getBootIntoSetup() {
112119
return bootIntoSetup;
113120
}
114121

122+
public Boolean getConsiderLastHost() {
123+
return considerLastHost;
124+
}
125+
115126
// ///////////////////////////////////////////////////
116127
// ///////////// API Implementation///////////////////
117128
// ///////////////////////////////////////////////////
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package com.cloud.deploy;
21+
22+
import junit.framework.TestCase;
23+
import org.junit.Assert;
24+
25+
public class DataCenterDeploymentTest extends TestCase {
26+
27+
private long zoneId = 1L;
28+
private long hostId = 2L;
29+
30+
DataCenterDeployment plan = new DataCenterDeployment(zoneId);
31+
32+
private void verifyHostPriority(Integer priority) {
33+
Assert.assertEquals(priority, plan.getHostPriorities().get(hostId));
34+
}
35+
36+
public void testHostPriorities() {
37+
verifyHostPriority(null);
38+
39+
plan.adjustHostPriority(hostId, DeploymentPlan.HostPriorityAdjustment.DEFAULT);
40+
verifyHostPriority(0);
41+
42+
plan.adjustHostPriority(hostId, DeploymentPlan.HostPriorityAdjustment.HIGHER);
43+
verifyHostPriority(1);
44+
45+
plan.adjustHostPriority(hostId, DeploymentPlan.HostPriorityAdjustment.LOWER);
46+
verifyHostPriority(0);
47+
48+
plan.adjustHostPriority(hostId, DeploymentPlan.HostPriorityAdjustment.LOWER);
49+
verifyHostPriority(-1);
50+
51+
plan.adjustHostPriority(hostId, DeploymentPlan.HostPriorityAdjustment.HIGHER);
52+
verifyHostPriority(0);
53+
54+
plan.adjustHostPriority(hostId, DeploymentPlan.HostPriorityAdjustment.HIGHER);
55+
verifyHostPriority(1);
56+
}
57+
}

client/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,16 @@
478478
<artifactId>cloud-plugin-host-affinity</artifactId>
479479
<version>${project.version}</version>
480480
</dependency>
481+
<dependency>
482+
<groupId>org.apache.cloudstack</groupId>
483+
<artifactId>cloud-plugin-non-strict-host-anti-affinity</artifactId>
484+
<version>${project.version}</version>
485+
</dependency>
486+
<dependency>
487+
<groupId>org.apache.cloudstack</groupId>
488+
<artifactId>cloud-plugin-non-strict-host-affinity</artifactId>
489+
<version>${project.version}</version>
490+
</dependency>
481491
<dependency>
482492
<groupId>org.apache.cloudstack</groupId>
483493
<artifactId>cloud-plugin-api-solidfire-intg-test</artifactId>

core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@
248248
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
249249
<property name="orderConfigKey" value="affinity.processors.order" />
250250
<property name="orderConfigDefault"
251-
value="HostAntiAffinityProcessor,ExplicitDedicationProcessor,HostAffinityProcessor" />
251+
value="HostAntiAffinityProcessor,ExplicitDedicationProcessor,HostAffinityProcessor,NonStrictHostAntiAffinityProcessor,NonStrictHostAffinityProcessor" />
252252
<property name="excludeKey" value="affinity.processors.exclude" />
253253
</bean>
254254

engine/components-api/src/main/java/com/cloud/deploy/DeploymentPlanningManager.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@
2020
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
2121
import com.cloud.exception.AffinityConflictException;
2222
import com.cloud.exception.InsufficientServerCapacityException;
23+
import com.cloud.host.Host;
2324
import com.cloud.utils.component.Manager;
2425
import com.cloud.vm.VirtualMachineProfile;
2526
import org.apache.cloudstack.framework.config.ConfigKey;
2627

28+
import java.util.List;
29+
import java.util.Map;
30+
2731
public interface DeploymentPlanningManager extends Manager {
2832

2933

@@ -60,4 +64,6 @@ String finalizeReservation(DeployDestination plannedDestination,
6064
DeploymentPlanner getDeploymentPlannerByName(String plannerName);
6165

6266
void checkForNonDedicatedResources(VirtualMachineProfile vmProfile, DataCenter dc, ExcludeList avoids);
67+
68+
void reorderHostsByPriority(Map<Long, Integer> priorities, List<Host> hosts);
6369
}

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,6 +1412,10 @@ private void logBootModeParameters(Map<VirtualMachineProfile.Param, Object> para
14121412
msgBuf.append(String.format("Boot into Setup: %s ", params.get(VirtualMachineProfile.Param.BootIntoSetup)));
14131413
log = true;
14141414
}
1415+
if (params.get(VirtualMachineProfile.Param.ConsiderLastHost) != null) {
1416+
msgBuf.append(String.format("Consider last host: %s ", params.get(VirtualMachineProfile.Param.ConsiderLastHost)));
1417+
log = true;
1418+
}
14151419
if (log) {
14161420
s_logger.info(msgBuf.toString());
14171421
}

0 commit comments

Comments
 (0)