Skip to content
This repository was archived by the owner on Jan 15, 2020. It is now read-only.

Commit fe2a868

Browse files
author
Prachi Damle
committed
Changes to add AffinityGroupprocessor, deployVM changes
1 parent 1aed5bf commit fe2a868

20 files changed

Lines changed: 755 additions & 166 deletions

api/src/com/cloud/event/EventTypes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ public class EventTypes {
386386
public static final String EVENT_AFFINITY_GROUP_DELETE = "AG.DELETE";
387387
public static final String EVENT_AFFINITY_GROUP_ASSIGN = "AG.ASSIGN";
388388
public static final String EVENT_AFFINITY_GROUP_REMOVE = "AG.REMOVE";
389+
public static final String EVENT_VM_AFFINITY_GROUP_UPDATE = "VM.AG.UPDATE";
389390

390391
static {
391392

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.cloud.exception;
2+
3+
import com.cloud.exception.CloudException;
4+
import com.cloud.utils.SerialVersionUID;
5+
6+
public class AffinityConflictException extends CloudException {
7+
8+
private static final long serialVersionUID = SerialVersionUID.AffinityConflictException;
9+
10+
public AffinityConflictException(String message) {
11+
super(message);
12+
}
13+
14+
public AffinityConflictException(String message, Throwable th) {
15+
super(message, th);
16+
}
17+
18+
}

api/src/com/cloud/vm/UserVmService.java

Lines changed: 101 additions & 82 deletions
Large diffs are not rendered by default.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.apache.cloudstack.affinity;
2+
3+
import org.apache.cloudstack.deploy.UserPreferrenceProcessor;
4+
5+
public interface AffinityGroupProcessor extends UserPreferrenceProcessor {
6+
7+
/**
8+
* getType() should return the affinity/anti-affinity group being
9+
* implemented
10+
*
11+
* @return String Affinity/Anti-affinity type
12+
*/
13+
String getType();
14+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.List;
44

55
import com.cloud.exception.ResourceInUseException;
6+
import com.cloud.uservm.UserVm;
67
import com.cloud.utils.Pair;
78

89
public interface AffinityGroupService {
@@ -57,4 +58,6 @@ Pair<List<? extends AffinityGroup>, Integer> listAffinityGroups(Long affinityGro
5758

5859
AffinityGroup getAffinityGroup(Long groupId);
5960

61+
UserVm updateVMAffinityGroups(Long vmId, List<Long> affinityGroupIds);
62+
6063
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@ public class ApiConstants {
473473
public static final String HEALTHCHECK_HEALTHY_THRESHOLD = "healthythreshold";
474474
public static final String HEALTHCHECK_UNHEALTHY_THRESHOLD = "unhealthythreshold";
475475
public static final String HEALTHCHECK_PINGPATH = "pingpath";
476+
public static final String AFFINITY_GROUP_IDS = "affinitygroupids";
477+
public static final String AFFINITY_GROUP_NAMES = "affinitygroupnames";
476478

477479
public enum HostDetails {
478480
all, capacity, events, stats, min;

api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ public String getCommandName() {
8383
@Override
8484
public void execute(){
8585

86-
Pair<List<AffinityGroup>, Integer> result = _affinityGroupService.listAffinityGroups(id, affinityGroupName,
86+
Pair<List<? extends AffinityGroup>, Integer> result = _affinityGroupService.listAffinityGroups(id,
87+
affinityGroupName,
8788
affinityGroupType, virtualMachineId, this.getStartIndex(), this.getPageSizeVal());
8889
if (result != null) {
8990
ListResponse<AffinityGroupResponse> response = new ListResponse<AffinityGroupResponse>();
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.api.command.user.affinitygroup;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
22+
import org.apache.cloudstack.affinity.AffinityGroupResponse;
23+
import org.apache.cloudstack.api.ACL;
24+
import org.apache.cloudstack.api.APICommand;
25+
import org.apache.cloudstack.api.ApiConstants;
26+
import org.apache.cloudstack.api.ApiErrorCode;
27+
import org.apache.cloudstack.api.BaseAsyncCmd;
28+
import org.apache.cloudstack.api.Parameter;
29+
import org.apache.cloudstack.api.ServerApiException;
30+
import org.apache.cloudstack.api.response.UserVmResponse;
31+
import org.apache.log4j.Logger;
32+
33+
import com.cloud.async.AsyncJob;
34+
import com.cloud.event.EventTypes;
35+
import com.cloud.exception.InsufficientCapacityException;
36+
import com.cloud.exception.InvalidParameterValueException;
37+
import com.cloud.exception.ResourceUnavailableException;
38+
import com.cloud.user.Account;
39+
import com.cloud.user.UserContext;
40+
import com.cloud.uservm.UserVm;
41+
42+
43+
@APICommand(name = "updateVMAffinityGroup", description = "Updates the affinity/anti-affinity group associations of a virtual machine. The VM has to be stopped and restarted for the "
44+
+ "new properties to take effect.", responseObject = UserVmResponse.class)
45+
public class UpdateVMAffinityGroupCmd extends BaseAsyncCmd {
46+
public static final Logger s_logger = Logger.getLogger(UpdateVMAffinityGroupCmd.class.getName());
47+
private static final String s_name = "updatevirtualmachineresponse";
48+
49+
/////////////////////////////////////////////////////
50+
//////////////// API parameters /////////////////////
51+
/////////////////////////////////////////////////////
52+
53+
54+
@ACL
55+
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
56+
required=true, description="The ID of the virtual machine")
57+
private Long id;
58+
59+
@ACL
60+
@Parameter(name = ApiConstants.AFFINITY_GROUP_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AffinityGroupResponse.class, description = "comma separated list of affinity groups id that are going to be applied to the virtual machine. "
61+
+ "Should be passed only when vm is created from a zone with Basic Network support."
62+
+ " Mutually exclusive with securitygroupnames parameter")
63+
private List<Long> affinityGroupIdList;
64+
65+
@ACL
66+
@Parameter(name = ApiConstants.AFFINITY_GROUP_NAMES, type = CommandType.LIST, collectionType = CommandType.STRING, entityType = AffinityGroupResponse.class, description = "comma separated list of affinity groups names that are going to be applied to the virtual machine."
67+
+ " Should be passed only when vm is created from a zone with Basic Network support. "
68+
+ "Mutually exclusive with securitygroupids parameter")
69+
private List<String> affinityGroupNameList;
70+
71+
/////////////////////////////////////////////////////
72+
/////////////////// Accessors ///////////////////////
73+
/////////////////////////////////////////////////////
74+
75+
76+
public Long getId() {
77+
return id;
78+
}
79+
80+
81+
public List<Long> getAffinityGroupIdList() {
82+
if (affinityGroupNameList != null && affinityGroupIdList != null) {
83+
throw new InvalidParameterValueException(
84+
"affinitygroupids parameter is mutually exclusive with affinitygroupnames parameter");
85+
}
86+
87+
// transform group names to ids here
88+
if (affinityGroupNameList != null) {
89+
List<Long> affinityGroupIds = new ArrayList<Long>();
90+
for (String groupName : affinityGroupNameList) {
91+
Long groupId = _responseGenerator.getAffinityGroupId(groupName, getEntityOwnerId());
92+
if (groupId == null) {
93+
throw new InvalidParameterValueException("Unable to find group by name " + groupName
94+
+ " for account " + getEntityOwnerId());
95+
} else {
96+
affinityGroupIds.add(groupId);
97+
}
98+
}
99+
return affinityGroupIds;
100+
} else {
101+
return affinityGroupIdList;
102+
}
103+
}
104+
105+
/////////////////////////////////////////////////////
106+
/////////////// API Implementation///////////////////
107+
/////////////////////////////////////////////////////
108+
109+
110+
@Override
111+
public String getCommandName() {
112+
return s_name;
113+
}
114+
115+
public static String getResultObjectName() {
116+
return "virtualmachine";
117+
}
118+
119+
@Override
120+
public long getEntityOwnerId() {
121+
UserVm userVm = _entityMgr.findById(UserVm.class, getId());
122+
if (userVm != null) {
123+
return userVm.getAccountId();
124+
}
125+
126+
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
127+
}
128+
129+
@Override
130+
public void execute() throws ResourceUnavailableException,
131+
InsufficientCapacityException, ServerApiException {
132+
UserContext.current().setEventDetails("Vm Id: "+getId());
133+
UserVm result = _affinityGroupService.updateVMAffinityGroups(getId(), getAffinityGroupIdList());
134+
if (result != null){
135+
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
136+
response.setResponseName(getCommandName());
137+
this.setResponseObject(response);
138+
} else {
139+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update vm's affinity groups");
140+
}
141+
}
142+
143+
@Override
144+
public String getEventType() {
145+
return EventTypes.EVENT_VM_AFFINITY_GROUP_UPDATE;
146+
}
147+
148+
@Override
149+
public String getEventDescription() {
150+
return "updating VM Affinity Group";
151+
}
152+
153+
@Override
154+
public AsyncJob.Type getInstanceType() {
155+
return AsyncJob.Type.AffinityGroup;
156+
}
157+
158+
}

api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.Map;
2626

2727
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
28+
import org.apache.cloudstack.affinity.AffinityGroupResponse;
2829
import org.apache.cloudstack.api.ACL;
2930
import org.apache.cloudstack.api.APICommand;
3031
import org.apache.cloudstack.api.ApiConstants;
@@ -172,6 +173,18 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
172173
@Parameter(name=ApiConstants.START_VM, type=CommandType.BOOLEAN, description="true if network offering supports specifying ip ranges; defaulted to true if not specified")
173174
private Boolean startVm;
174175

176+
@ACL
177+
@Parameter(name = ApiConstants.AFFINITY_GROUP_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AffinityGroupResponse.class, description = "comma separated list of affinity groups id that are going to be applied to the virtual machine. "
178+
+ "Should be passed only when vm is created from a zone with Basic Network support."
179+
+ " Mutually exclusive with securitygroupnames parameter")
180+
private List<Long> affinityGroupIdList;
181+
182+
@ACL
183+
@Parameter(name = ApiConstants.AFFINITY_GROUP_NAMES, type = CommandType.LIST, collectionType = CommandType.STRING, entityType = AffinityGroupResponse.class, description = "comma separated list of affinity groups names that are going to be applied to the virtual machine."
184+
+ " Should be passed only when vm is created from a zone with Basic Network support. "
185+
+ "Mutually exclusive with securitygroupids parameter")
186+
private List<String> affinityGroupNameList;
187+
175188

176189
/////////////////////////////////////////////////////
177190
/////////////////// Accessors ///////////////////////
@@ -321,6 +334,30 @@ public String getIp6Address() {
321334
return ip6Address.toLowerCase();
322335
}
323336

337+
public List<Long> getAffinityGroupIdList() {
338+
if (affinityGroupNameList != null && affinityGroupIdList != null) {
339+
throw new InvalidParameterValueException(
340+
"affinitygroupids parameter is mutually exclusive with affinitygroupnames parameter");
341+
}
342+
343+
// transform group names to ids here
344+
if (affinityGroupNameList != null) {
345+
List<Long> affinityGroupIds = new ArrayList<Long>();
346+
for (String groupName : affinityGroupNameList) {
347+
Long groupId = _responseGenerator.getAffinityGroupId(groupName, getEntityOwnerId());
348+
if (groupId == null) {
349+
throw new InvalidParameterValueException("Unable to find group by name " + groupName
350+
+ " for account " + getEntityOwnerId());
351+
} else {
352+
affinityGroupIds.add(groupId);
353+
}
354+
}
355+
return affinityGroupIds;
356+
} else {
357+
return affinityGroupIdList;
358+
}
359+
}
360+
324361
/////////////////////////////////////////////////////
325362
/////////////// API Implementation///////////////////
326363
/////////////////////////////////////////////////////
@@ -447,18 +484,18 @@ public void create() throws ResourceAllocationException{
447484
throw new InvalidParameterValueException("Can't specify network Ids in Basic zone");
448485
} else {
449486
vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(), owner, name,
450-
displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard);
487+
displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
451488
}
452489
} else {
453490
if (zone.isSecurityGroupEnabled()) {
454491
vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), getSecurityGroupIdList(),
455-
owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard);
492+
owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
456493
} else {
457494
if (getSecurityGroupIdList() != null && !getSecurityGroupIdList().isEmpty()) {
458495
throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone");
459496
}
460497
vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, getNetworkIds(), owner, name, displayName,
461-
diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard);
498+
diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
462499
}
463500
}
464501

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.apache.cloudstack.deploy;
2+
3+
4+
import com.cloud.deploy.DeploymentPlan;
5+
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
6+
import com.cloud.exception.AffinityConflictException;
7+
import com.cloud.utils.component.Adapter;
8+
import com.cloud.vm.VirtualMachine;
9+
import com.cloud.vm.VirtualMachineProfile;
10+
11+
public interface UserPreferrenceProcessor extends Adapter {
12+
13+
/**
14+
* process() is called to apply any user preferences to the deployment plan
15+
* and avoid set for the given VM placement.
16+
*
17+
* @param vm
18+
* virtual machine.
19+
* @param plan
20+
* deployment plan that tells you where it's being deployed to.
21+
* @param avoid
22+
* avoid these data centers, pods, clusters, or hosts.
23+
*/
24+
void process(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid)
25+
throws AffinityConflictException;
26+
27+
}

0 commit comments

Comments
 (0)