Changes to add AffinityGroupprocessor, deployVM changes

This commit is contained in:
Prachi Damle 2013-03-13 13:57:47 -07:00
parent 1aed5bf9c2
commit fe2a86871f
20 changed files with 755 additions and 166 deletions

View File

@ -386,6 +386,7 @@ public class EventTypes {
public static final String EVENT_AFFINITY_GROUP_DELETE = "AG.DELETE";
public static final String EVENT_AFFINITY_GROUP_ASSIGN = "AG.ASSIGN";
public static final String EVENT_AFFINITY_GROUP_REMOVE = "AG.REMOVE";
public static final String EVENT_VM_AFFINITY_GROUP_UPDATE = "VM.AG.UPDATE";
static {

View File

@ -0,0 +1,18 @@
package com.cloud.exception;
import com.cloud.exception.CloudException;
import com.cloud.utils.SerialVersionUID;
public class AffinityConflictException extends CloudException {
private static final long serialVersionUID = SerialVersionUID.AffinityConflictException;
public AffinityConflictException(String message) {
super(message);
}
public AffinityConflictException(String message, Throwable th) {
super(message, th);
}
}

View File

@ -26,9 +26,6 @@ import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
import org.apache.cloudstack.api.command.user.vm.*;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
import com.cloud.dc.DataCenter;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
@ -42,7 +39,6 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.Network.IpAddresses;
import com.cloud.offering.ServiceOffering;
import com.cloud.storage.StoragePool;
import com.cloud.storage.Volume;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.uservm.UserVm;
@ -123,7 +119,8 @@ public interface UserVmService {
/**
* Creates a Basic Zone User VM in the database and returns the VM to the caller.
* Creates a Basic Zone User VM in the database and returns the VM to the
* caller.
*
* @param zone
* - availability zone for the virtual machine
@ -132,61 +129,69 @@ public interface UserVmService {
* @param template
* - the template for the virtual machine
* @param securityGroupIdList
* - comma separated list of security groups id that going to be applied to the virtual machine
* - comma separated list of security groups id that going to be
* applied to the virtual machine
* @param hostName
* - host name for the virtual machine
* @param displayName
* - an optional user generated name for the virtual machine
* @param diskOfferingId
* - the ID of the disk offering for the virtual machine. If the template is of ISO format, the
* diskOfferingId is
* for the root disk volume. Otherwise this parameter is used to indicate the offering for the data disk
* volume.
* If the templateId parameter passed is from a Template object, the diskOfferingId refers to a DATA Disk
* Volume
* created. If the templateId parameter passed is from an ISO object, the diskOfferingId refers to a ROOT
* Disk
* Volume created
* - the ID of the disk offering for the virtual machine. If the
* template is of ISO format, the diskOfferingId is for the root
* disk volume. Otherwise this parameter is used to indicate the
* offering for the data disk volume. If the templateId parameter
* passed is from a Template object, the diskOfferingId refers to
* a DATA Disk Volume created. If the templateId parameter passed
* is from an ISO object, the diskOfferingId refers to a ROOT
* Disk Volume created
* @param diskSize
* - the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId
* - the arbitrary size for the DATADISK volume. Mutually
* exclusive with diskOfferingId
* @param group
* - an optional group for the virtual machine
* @param hypervisor
* - the hypervisor on which to deploy the virtual machine
* @param userData
* - an optional binary data that can be sent to the virtual machine upon a successful deployment. This
* binary
* data must be base64 encoded before adding it to the request. Currently only HTTP GET is supported.
* Using HTTP
* GET (via querystring), you can send up to 2KB of data after base64 encoding
* - an optional binary data that can be sent to the virtual
* machine upon a successful deployment. This binary data must be
* base64 encoded before adding it to the request. Currently only
* HTTP GET is supported. Using HTTP GET (via querystring), you
* can send up to 2KB of data after base64 encoding
* @param sshKeyPair
* - name of the ssh key pair used to login to the virtual machine
* - name of the ssh key pair used to login to the virtual
* machine
* @param requestedIps
* TODO
* @param defaultIp
* TODO
* @param affinityGroupIdList
* @param accountName
* - an optional account for the virtual machine. Must be used with domainId
* - an optional account for the virtual machine. Must be used
* with domainId
* @param domainId
* - an optional domainId for the virtual machine. If the account parameter is used, domainId must also
* be used
* - an optional domainId for the virtual machine. If the account
* parameter is used, domainId must also be used
* @return UserVm object if successful.
*
* @throws InsufficientCapacityException
* if there is insufficient capacity to deploy the VM.
* @throws ConcurrentOperationException
* if there are multiple users working on the same VM or in the same environment.
* if there are multiple users working on the same VM or in the
* same environment.
* @throws ResourceUnavailableException
* if the resources required to deploy the VM is not currently available.
* if the resources required to deploy the VM is not currently
* available.
* @throws InsufficientResourcesException
*/
UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList, Account owner, String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, String keyboard)
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp,
String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
/**
* Creates a User VM in Advanced Zone (Security Group feature is enabled) in the database and returns the VM to the
* caller.
* Creates a User VM in Advanced Zone (Security Group feature is enabled) in
* the database and returns the VM to the caller.
*
* @param zone
* - availability zone for the virtual machine
@ -197,62 +202,68 @@ public interface UserVmService {
* @param networkIdList
* - list of network ids used by virtual machine
* @param securityGroupIdList
* - comma separated list of security groups id that going to be applied to the virtual machine
* - comma separated list of security groups id that going to be
* applied to the virtual machine
* @param hostName
* - host name for the virtual machine
* @param displayName
* - an optional user generated name for the virtual machine
* @param diskOfferingId
* - the ID of the disk offering for the virtual machine. If the template is of ISO format, the
* diskOfferingId is
* for the root disk volume. Otherwise this parameter is used to indicate the offering for the data disk
* volume.
* If the templateId parameter passed is from a Template object, the diskOfferingId refers to a DATA Disk
* Volume
* created. If the templateId parameter passed is from an ISO object, the diskOfferingId refers to a ROOT
* Disk
* Volume created
* - the ID of the disk offering for the virtual machine. If the
* template is of ISO format, the diskOfferingId is for the root
* disk volume. Otherwise this parameter is used to indicate the
* offering for the data disk volume. If the templateId parameter
* passed is from a Template object, the diskOfferingId refers to
* a DATA Disk Volume created. If the templateId parameter passed
* is from an ISO object, the diskOfferingId refers to a ROOT
* Disk Volume created
* @param diskSize
* - the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId
* - the arbitrary size for the DATADISK volume. Mutually
* exclusive with diskOfferingId
* @param group
* - an optional group for the virtual machine
* @param hypervisor
* - the hypervisor on which to deploy the virtual machine
* @param userData
* - an optional binary data that can be sent to the virtual machine upon a successful deployment. This
* binary
* data must be base64 encoded before adding it to the request. Currently only HTTP GET is supported.
* Using HTTP
* GET (via querystring), you can send up to 2KB of data after base64 encoding
* - an optional binary data that can be sent to the virtual
* machine upon a successful deployment. This binary data must be
* base64 encoded before adding it to the request. Currently only
* HTTP GET is supported. Using HTTP GET (via querystring), you
* can send up to 2KB of data after base64 encoding
* @param sshKeyPair
* - name of the ssh key pair used to login to the virtual machine
* - name of the ssh key pair used to login to the virtual
* machine
* @param requestedIps
* TODO
* @param defaultIps
* TODO
* @param affinityGroupIdList
* @param accountName
* - an optional account for the virtual machine. Must be used with domainId
* - an optional account for the virtual machine. Must be used
* with domainId
* @param domainId
* - an optional domainId for the virtual machine. If the account parameter is used, domainId must also
* be used
* - an optional domainId for the virtual machine. If the account
* parameter is used, domainId must also be used
* @return UserVm object if successful.
*
* @throws InsufficientCapacityException
* if there is insufficient capacity to deploy the VM.
* @throws ConcurrentOperationException
* if there are multiple users working on the same VM or in the same environment.
* if there are multiple users working on the same VM or in the
* same environment.
* @throws ResourceUnavailableException
* if the resources required to deploy the VM is not currently available.
* if the resources required to deploy the VM is not currently
* available.
* @throws InsufficientResourcesException
*/
UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, List<Long> securityGroupIdList,
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard)
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
/**
* Creates a User VM in Advanced Zone (Security Group feature is disabled) in the database and returns the VM to the
* caller.
* Creates a User VM in Advanced Zone (Security Group feature is disabled)
* in the database and returns the VM to the caller.
*
* @param zone
* - availability zone for the virtual machine
@ -267,49 +278,57 @@ public interface UserVmService {
* @param displayName
* - an optional user generated name for the virtual machine
* @param diskOfferingId
* - the ID of the disk offering for the virtual machine. If the template is of ISO format, the
* diskOfferingId is
* for the root disk volume. Otherwise this parameter is used to indicate the offering for the data disk
* volume.
* If the templateId parameter passed is from a Template object, the diskOfferingId refers to a DATA Disk
* Volume
* created. If the templateId parameter passed is from an ISO object, the diskOfferingId refers to a ROOT
* Disk
* Volume created
* - the ID of the disk offering for the virtual machine. If the
* template is of ISO format, the diskOfferingId is for the root
* disk volume. Otherwise this parameter is used to indicate the
* offering for the data disk volume. If the templateId parameter
* passed is from a Template object, the diskOfferingId refers to
* a DATA Disk Volume created. If the templateId parameter passed
* is from an ISO object, the diskOfferingId refers to a ROOT
* Disk Volume created
* @param diskSize
* - the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId
* - the arbitrary size for the DATADISK volume. Mutually
* exclusive with diskOfferingId
* @param group
* - an optional group for the virtual machine
* @param hypervisor
* - the hypervisor on which to deploy the virtual machine
* @param userData
* - an optional binary data that can be sent to the virtual machine upon a successful deployment. This
* binary
* data must be base64 encoded before adding it to the request. Currently only HTTP GET is supported.
* Using HTTP
* GET (via querystring), you can send up to 2KB of data after base64 encoding
* - an optional binary data that can be sent to the virtual
* machine upon a successful deployment. This binary data must be
* base64 encoded before adding it to the request. Currently only
* HTTP GET is supported. Using HTTP GET (via querystring), you
* can send up to 2KB of data after base64 encoding
* @param sshKeyPair
* - name of the ssh key pair used to login to the virtual machine
* - name of the ssh key pair used to login to the virtual
* machine
* @param requestedIps
* TODO
* @param defaultIps TODO
* @param defaultIps
* TODO
* @param affinityGroupIdList
* @param accountName
* - an optional account for the virtual machine. Must be used with domainId
* - an optional account for the virtual machine. Must be used
* with domainId
* @param domainId
* - an optional domainId for the virtual machine. If the account parameter is used, domainId must also
* be used
* - an optional domainId for the virtual machine. If the account
* parameter is used, domainId must also be used
* @return UserVm object if successful.
*
* @throws InsufficientCapacityException
* if there is insufficient capacity to deploy the VM.
* @throws ConcurrentOperationException
* if there are multiple users working on the same VM or in the same environment.
* if there are multiple users working on the same VM or in the
* same environment.
* @throws ResourceUnavailableException
* if the resources required to deploy the VM is not currently available.
* if the resources required to deploy the VM is not currently
* available.
* @throws InsufficientResourcesException
*/
UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner, String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, String keyboard)
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps,
String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
/**

View File

@ -0,0 +1,14 @@
package org.apache.cloudstack.affinity;
import org.apache.cloudstack.deploy.UserPreferrenceProcessor;
public interface AffinityGroupProcessor extends UserPreferrenceProcessor {
/**
* getType() should return the affinity/anti-affinity group being
* implemented
*
* @return String Affinity/Anti-affinity type
*/
String getType();
}

View File

@ -3,6 +3,7 @@ package org.apache.cloudstack.affinity;
import java.util.List;
import com.cloud.exception.ResourceInUseException;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
public interface AffinityGroupService {
@ -57,4 +58,6 @@ public interface AffinityGroupService {
AffinityGroup getAffinityGroup(Long groupId);
UserVm updateVMAffinityGroups(Long vmId, List<Long> affinityGroupIds);
}

View File

@ -473,6 +473,8 @@ public class ApiConstants {
public static final String HEALTHCHECK_HEALTHY_THRESHOLD = "healthythreshold";
public static final String HEALTHCHECK_UNHEALTHY_THRESHOLD = "unhealthythreshold";
public static final String HEALTHCHECK_PINGPATH = "pingpath";
public static final String AFFINITY_GROUP_IDS = "affinitygroupids";
public static final String AFFINITY_GROUP_NAMES = "affinitygroupnames";
public enum HostDetails {
all, capacity, events, stats, min;

View File

@ -83,7 +83,8 @@ public class ListAffinityGroupsCmd extends BaseListCmd {
@Override
public void execute(){
Pair<List<AffinityGroup>, Integer> result = _affinityGroupService.listAffinityGroups(id, affinityGroupName,
Pair<List<? extends AffinityGroup>, Integer> result = _affinityGroupService.listAffinityGroups(id,
affinityGroupName,
affinityGroupType, virtualMachineId, this.getStartIndex(), this.getPageSizeVal());
if (result != null) {
ListResponse<AffinityGroupResponse> response = new ListResponse<AffinityGroupResponse>();

View File

@ -0,0 +1,158 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.user.affinitygroup;
import java.util.ArrayList;
import java.util.List;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.log4j.Logger;
import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
@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 "
+ "new properties to take effect.", responseObject = UserVmResponse.class)
public class UpdateVMAffinityGroupCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(UpdateVMAffinityGroupCmd.class.getName());
private static final String s_name = "updatevirtualmachineresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@ACL
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
required=true, description="The ID of the virtual machine")
private Long id;
@ACL
@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. "
+ "Should be passed only when vm is created from a zone with Basic Network support."
+ " Mutually exclusive with securitygroupnames parameter")
private List<Long> affinityGroupIdList;
@ACL
@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."
+ " Should be passed only when vm is created from a zone with Basic Network support. "
+ "Mutually exclusive with securitygroupids parameter")
private List<String> affinityGroupNameList;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
public List<Long> getAffinityGroupIdList() {
if (affinityGroupNameList != null && affinityGroupIdList != null) {
throw new InvalidParameterValueException(
"affinitygroupids parameter is mutually exclusive with affinitygroupnames parameter");
}
// transform group names to ids here
if (affinityGroupNameList != null) {
List<Long> affinityGroupIds = new ArrayList<Long>();
for (String groupName : affinityGroupNameList) {
Long groupId = _responseGenerator.getAffinityGroupId(groupName, getEntityOwnerId());
if (groupId == null) {
throw new InvalidParameterValueException("Unable to find group by name " + groupName
+ " for account " + getEntityOwnerId());
} else {
affinityGroupIds.add(groupId);
}
}
return affinityGroupIds;
} else {
return affinityGroupIdList;
}
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
public static String getResultObjectName() {
return "virtualmachine";
}
@Override
public long getEntityOwnerId() {
UserVm userVm = _entityMgr.findById(UserVm.class, getId());
if (userVm != null) {
return userVm.getAccountId();
}
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}
@Override
public void execute() throws ResourceUnavailableException,
InsufficientCapacityException, ServerApiException {
UserContext.current().setEventDetails("Vm Id: "+getId());
UserVm result = _affinityGroupService.updateVMAffinityGroups(getId(), getAffinityGroupIdList());
if (result != null){
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update vm's affinity groups");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_VM_AFFINITY_GROUP_UPDATE;
}
@Override
public String getEventDescription() {
return "updating VM Affinity Group";
}
@Override
public AsyncJob.Type getInstanceType() {
return AsyncJob.Type.AffinityGroup;
}
}

View File

@ -25,6 +25,7 @@ import java.util.List;
import java.util.Map;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
@ -172,6 +173,18 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
@Parameter(name=ApiConstants.START_VM, type=CommandType.BOOLEAN, description="true if network offering supports specifying ip ranges; defaulted to true if not specified")
private Boolean startVm;
@ACL
@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. "
+ "Should be passed only when vm is created from a zone with Basic Network support."
+ " Mutually exclusive with securitygroupnames parameter")
private List<Long> affinityGroupIdList;
@ACL
@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."
+ " Should be passed only when vm is created from a zone with Basic Network support. "
+ "Mutually exclusive with securitygroupids parameter")
private List<String> affinityGroupNameList;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@ -321,6 +334,30 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
return ip6Address.toLowerCase();
}
public List<Long> getAffinityGroupIdList() {
if (affinityGroupNameList != null && affinityGroupIdList != null) {
throw new InvalidParameterValueException(
"affinitygroupids parameter is mutually exclusive with affinitygroupnames parameter");
}
// transform group names to ids here
if (affinityGroupNameList != null) {
List<Long> affinityGroupIds = new ArrayList<Long>();
for (String groupName : affinityGroupNameList) {
Long groupId = _responseGenerator.getAffinityGroupId(groupName, getEntityOwnerId());
if (groupId == null) {
throw new InvalidParameterValueException("Unable to find group by name " + groupName
+ " for account " + getEntityOwnerId());
} else {
affinityGroupIds.add(groupId);
}
}
return affinityGroupIds;
} else {
return affinityGroupIdList;
}
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@ -447,18 +484,18 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
throw new InvalidParameterValueException("Can't specify network Ids in Basic zone");
} else {
vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(), owner, name,
displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard);
displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
}
} else {
if (zone.isSecurityGroupEnabled()) {
vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), getSecurityGroupIdList(),
owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard);
owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
} else {
if (getSecurityGroupIdList() != null && !getSecurityGroupIdList().isEmpty()) {
throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone");
}
vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, getNetworkIds(), owner, name, displayName,
diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard);
diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
}
}

View File

@ -0,0 +1,27 @@
package org.apache.cloudstack.deploy;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.exception.AffinityConflictException;
import com.cloud.utils.component.Adapter;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
public interface UserPreferrenceProcessor extends Adapter {
/**
* process() is called to apply any user preferences to the deployment plan
* and avoid set for the given VM placement.
*
* @param vm
* virtual machine.
* @param plan
* deployment plan that tells you where it's being deployed to.
* @param avoid
* avoid these data centers, pods, clusters, or hosts.
*/
void process(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid)
throws AffinityConflictException;
}

View File

@ -0,0 +1,29 @@
package com.cloud.deploy;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.exception.AffinityConflictException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.utils.component.Manager;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
public interface DeploymentPlanningManager extends Manager {
/**
* Manages vm deployment stages: First Process Affinity/Anti-affinity - Call
* the chain of AffinityGroupProcessor adapters to set deploymentplan scope
* and exclude list Secondly, Call DeploymentPlanner - to use heuristics to
* find the best spot to place the vm/volume. Planner will drill down to the
* write set of clusters to look for placement based on various heuristics.
* Lastly, Call Allocators - Given a cluster, allocators matches the
* requirements to capabilities of the physical resource (host, storage
* pool).
*
* @throws AffinityConflictException
*
*
*
*/
DeployDestination planDeployment(VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan,
ExcludeList avoids) throws InsufficientServerCapacityException, AffinityConflictException;
}

View File

@ -0,0 +1,80 @@
package com.cloud.deploy;
import java.util.List;
import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.log4j.Logger;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.exception.AffinityConflictException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
@Local(value = { DeploymentPlanningManager.class })
public class DeploymentPlanningManagerImpl extends ManagerBase implements DeploymentPlanningManager, Manager {
private static final Logger s_logger = Logger.getLogger(DeploymentPlanningManagerImpl.class);
@Inject
protected UserVmDao _vmDao;
@Inject
protected VMInstanceDao _vmInstanceDao;
@Inject
protected AffinityGroupDao _affinityGroupDao;
@Inject
protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
@Inject
protected List<DeploymentPlanner> _planners;
@Inject
protected List<AffinityGroupProcessor> _affinityProcessors;
@Override
public DeployDestination planDeployment(VirtualMachineProfile<? extends VirtualMachine> vmProfile,
DeploymentPlan plan, ExcludeList avoids) throws InsufficientServerCapacityException,
AffinityConflictException {
// call affinitygroup chain
VirtualMachine vm = vmProfile.getVirtualMachine();
long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
if (vmGroupCount > 0) {
for (AffinityGroupProcessor processor : _affinityProcessors) {
processor.process(vmProfile, plan, avoids);
}
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: "
+ avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid());
}
// call planners
DeployDestination dest = null;
for (DeploymentPlanner planner : _planners) {
if (planner.canHandle(vmProfile, plan, avoids)) {
dest = planner.plan(vmProfile, plan, avoids);
} else {
continue;
}
if (dest != null) {
avoids.addHost(dest.getHost().getId());
break;
}
}
return dest;
}
}

View File

@ -35,6 +35,9 @@ import javax.naming.ConfigurationException;
import com.cloud.api.ApiDBUtils;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.affinity.AffinityGroupVO;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
import org.apache.cloudstack.api.command.user.vm.*;
@ -378,6 +381,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
@Inject
protected VMSnapshotManager _vmSnapshotMgr;
@Inject
AffinityGroupVMMapDao _affinityGroupVMMapDao;
@Inject
AffinityGroupDao _affinityGroupDao;
@Inject
List<DeployPlannerSelector> plannerSelectors;
@ -1916,7 +1924,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
@Override
public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList, Account owner,
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, String keyboard)
String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps,
String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
Account caller = UserContext.current().getCaller();
@ -1966,13 +1977,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
}
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId,
diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, keyboard);
diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller,
requestedIps, defaultIps, keyboard, affinityGroupIdList);
}
@Override
public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData,
String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, String keyboard) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException,
String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
StorageUnavailableException,
ResourceAllocationException {
Account caller = UserContext.current().getCaller();
@ -2079,12 +2094,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
}
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId,
diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, keyboard);
diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller,
requestedIps, defaultIps, keyboard, affinityGroupIdList);
}
@Override
public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner, String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, String keyboard)
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps,
String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
Account caller = UserContext.current().getCaller();
@ -2192,7 +2210,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
}
}
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, keyboard);
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId,
diskSize, networkList, null, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps,
keyboard, affinityGroupIdList);
}
@ -2205,7 +2225,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
@DB @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true)
protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, String hostName, String displayName, Account owner, Long diskOfferingId,
Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, String keyboard)
Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, String userData,
String sshKeyPair, HypervisorType hypervisor, Account caller, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException {
_accountMgr.checkAccess(caller, null, true, owner);
@ -2261,6 +2283,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
}
}
// check that the affinity groups exist
for (Long affinityGroupId : affinityGroupIdList) {
AffinityGroupVO ag = _affinityGroupDao.findById(affinityGroupId);
if (ag == null) {
throw new InvalidParameterValueException("Unable to find affinity group by id " + affinityGroupId);
}
}
if (template.getHypervisorType() != null && template.getHypervisorType() != HypervisorType.BareMetal) {
// check if we have available pools for vm deployment
long availablePools = _storagePoolDao.countPoolsByStatus(StoragePoolStatus.Up);
@ -2552,6 +2582,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
_securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList);
_affinityGroupVMMapDao.updateMap(vm.getId(), affinityGroupIdList);
return vm;
}

View File

@ -68,7 +68,9 @@ import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.deploy.DeploymentPlanningManager;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.AffinityConflictException;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.ConnectionException;
@ -239,6 +241,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
@Inject
VolumeManager volumeMgr;
@Inject
DeploymentPlanningManager _dpMgr;
Map<VirtualMachine.Type, VirtualMachineGuru<? extends VMInstanceVO>> _vmGurus = new HashMap<VirtualMachine.Type, VirtualMachineGuru<? extends VMInstanceVO>>();
protected StateMachine2<State, VirtualMachine.Event, VirtualMachine> _stateMachine;
@ -695,17 +700,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
VirtualMachineProfileImpl<T> vmProfile = new VirtualMachineProfileImpl<T>(vm, template, offering, account, params);
DeployDestination dest = null;
for (DeploymentPlanner planner : _planners) {
if (planner.canHandle(vmProfile, plan, avoids)) {
dest = planner.plan(vmProfile, plan, avoids);
} else {
continue;
}
if (dest != null) {
avoids.addHost(dest.getHost().getId());
journal.record("Deployment found ", vmProfile, dest);
break;
}
try {
dest = _dpMgr.planDeployment(vmProfile, plan, avoids);
} catch (AffinityConflictException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
if (dest == null) {

View File

@ -1,6 +1,5 @@
package org.apache.cloudstack.affinity;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -13,36 +12,34 @@ import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.log4j.Logger;
import com.cloud.api.query.vo.SecurityGroupJoinVO;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.security.SecurityGroupManager;
import com.cloud.network.security.SecurityGroupRuleVO;
import com.cloud.network.security.SecurityGroupVMMapVO;
import com.cloud.network.security.SecurityGroupVO;
import com.cloud.network.security.SecurityGroup;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.JoinBuilder.JoinType;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.fsm.StateListener;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.UserVmDao;
@Local(value = { AffinityGroupService.class })
public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGroupService, Manager {
public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGroupService, Manager,
StateListener<State, VirtualMachine.Event, VirtualMachine> {
public static final Logger s_logger = Logger.getLogger(AffinityGroupServiceImpl.class);
private String _name;
@ -221,4 +218,56 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
return _affinityGroupDao.findById(groupId);
}
@Override
public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo,
boolean status, Object opaque) {
return true;
}
@Override
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo,
boolean status, Object opaque) {
if (!status) {
return false;
}
if ((newState == State.Expunging)) {
// cleanup all affinity groups associated to the Expunged VM
SearchCriteria<AffinityGroupVMMapVO> sc = _affinityGroupVMMapDao.createSearchCriteria();
sc.addAnd("instanceId", SearchCriteria.Op.EQ, vo.getId());
_affinityGroupVMMapDao.expunge(sc);
}
return true;
}
@Override
public UserVm updateVMAffinityGroups(Long vmId, List<Long> affinityGroupIds) {
// Verify input parameters
UserVmVO vmInstance = _userVmDao.findById(vmId);
if (vmInstance == null) {
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
}
// Check that the VM is stopped
if (!vmInstance.getState().equals(State.Stopped)) {
s_logger.warn("Unable to update affinity groups of the virtual machine " + vmInstance.toString()
+ " in state " + vmInstance.getState());
throw new InvalidParameterValueException("Unable update affinity groups of the virtual machine "
+ vmInstance.toString() + " " + "in state " + vmInstance.getState()
+ "; make sure the virtual machine is stopped and not in an error state before updating.");
}
// check that the affinity groups exist
for (Long affinityGroupId : affinityGroupIds) {
AffinityGroupVO ag = _affinityGroupDao.findById(affinityGroupId);
if (ag == null) {
throw new InvalidParameterValueException("Unable to find affinity group by id " + affinityGroupId);
}
}
_affinityGroupVMMapDao.updateMap(vmId, affinityGroupIds);
// APIResponseHelper will pull out the updated affinitygroups.
return vmInstance;
}
}

View File

@ -0,0 +1,66 @@
package org.apache.cloudstack.affinity;
import java.util.List;
import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.log4j.Logger;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.exception.AffinityConflictException;
import com.cloud.utils.component.AdapterBase;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
@Local(value = AffinityGroupProcessor.class)
public class HostAntiAffinityProcessor extends AdapterBase implements AffinityGroupProcessor {
private static final Logger s_logger = Logger.getLogger(HostAntiAffinityProcessor.class);
@Inject
protected UserVmDao _vmDao;
@Inject
protected VMInstanceDao _vmInstanceDao;
@Inject
protected AffinityGroupDao _affinityGroupDao;
@Inject
protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
@Override
public void process(VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan,
ExcludeList avoid)
throws AffinityConflictException {
VirtualMachine vm = vmProfile.getVirtualMachine();
AffinityGroupVMMapVO vmGroupMapping = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), getType());
if (vmGroupMapping != null) {
AffinityGroupVO group = _affinityGroupDao.findById(vmGroupMapping.getAffinityGroupId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Processing affinity group " + group.getName() + " for VM Id: " + vm.getId());
}
List<Long> groupVMIds = _affinityGroupVMMapDao.listVmIdsByAffinityGroup(group.getId());
for (Long groupVMId : groupVMIds) {
VMInstanceVO groupVM = _vmInstanceDao.findById(groupVMId);
if (groupVM != null && !groupVM.isRemoved() && groupVM.getHostId() != null) {
avoid.addHost(groupVM.getHostId());
}
}
}
}
@Override
public String getType() {
return "HostAntiAffinity";
}
}

View File

@ -40,4 +40,8 @@ public interface AffinityGroupVMMapDao extends GenericDao<AffinityGroupVMMapVO,
long countAffinityGroupsForVm(long instanceId);
int deleteVM(long instanceId);
AffinityGroupVMMapVO findByVmIdType(long instanceId, String type);
void updateMap(Long vmId, List<Long> affinityGroupIds);
}

View File

@ -19,17 +19,22 @@ package org.apache.cloudstack.affinity.dao;
import java.util.List;
import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
import org.apache.cloudstack.affinity.AffinityGroupVO;
import org.springframework.stereotype.Component;
import com.cloud.host.HostTagVO;
import com.cloud.utils.Pair;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.JoinBuilder.JoinType;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.Transaction;
@Component
@Local(value = { AffinityGroupVMMapDao.class })
@ -40,6 +45,10 @@ public class AffinityGroupVMMapDaoImpl extends GenericDaoBase<AffinityGroupVMMap
protected GenericSearchBuilder<AffinityGroupVMMapVO, Long> CountSGForVm;
private GenericSearchBuilder<AffinityGroupVMMapVO, Long> ListVmIdByAffinityGroup;
private SearchBuilder<AffinityGroupVMMapVO> ListByAffinityGroup;
private SearchBuilder<AffinityGroupVMMapVO> ListByVmIdType;
@Inject
protected AffinityGroupDao _affinityGroupDao;
protected AffinityGroupVMMapDaoImpl() {
ListVmIdByAffinityGroup = createSearchBuilder(Long.class);
@ -62,6 +71,14 @@ public class AffinityGroupVMMapDaoImpl extends GenericDaoBase<AffinityGroupVMMap
ListByVmIdGroupId.and("affinityGroupId", ListByVmIdGroupId.entity().getAffinityGroupId(), SearchCriteria.Op.EQ);
ListByVmIdGroupId.done();
ListByVmIdType = createSearchBuilder();
ListByVmIdType.and("instanceId", ListByVmIdType.entity().getInstanceId(), SearchCriteria.Op.EQ);
SearchBuilder<AffinityGroupVO> groupSearch = _affinityGroupDao.createSearchBuilder();
groupSearch.and("type", groupSearch.entity().getType(), SearchCriteria.Op.EQ);
ListByVmIdType.join("groupSearch", groupSearch, ListByVmIdType.entity().getAffinityGroupId(), groupSearch
.entity().getId(), JoinType.INNER);
ListByVmIdType.done();
CountSGForVm = createSearchBuilder(Long.class);
CountSGForVm.select(null, Func.COUNT, null);
CountSGForVm.and("vmId", CountSGForVm.entity().getInstanceId(), SearchCriteria.Op.EQ);
@ -117,4 +134,30 @@ public class AffinityGroupVMMapDaoImpl extends GenericDaoBase<AffinityGroupVMMap
sc.setParameters("vmId", instanceId);
return customSearch(sc, null).get(0);
}
@Override
public AffinityGroupVMMapVO findByVmIdType(long instanceId, String type) {
SearchCriteria<AffinityGroupVMMapVO> sc = ListByVmIdType.create();
sc.setParameters("instanceId", instanceId);
sc.setJoinParameters("groupSearch", "type", type);
return customSearch(sc, null).get(0);
}
@Override
public void updateMap(Long vmId, List<Long> affinityGroupIds) {
Transaction txn = Transaction.currentTxn();
txn.start();
SearchCriteria<AffinityGroupVMMapVO> sc = createSearchCriteria();
sc.addAnd("instanceId", SearchCriteria.Op.EQ, vmId);
expunge(sc);
for (Long groupId : affinityGroupIds) {
AffinityGroupVMMapVO vo = new AffinityGroupVMMapVO(groupId, vmId);
persist(vo);
}
txn.commit();
}
}

View File

@ -330,7 +330,9 @@ public class MockUserVmManagerImpl extends ManagerBase implements UserVmManager,
@Override
public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList, Account owner,
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIp, String keyboard) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException,
IpAddresses defaultIp,
String keyboard, List<Long> affinityGroupIdList) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException,
ResourceAllocationException {
// TODO Auto-generated method stub
return null;
@ -339,7 +341,9 @@ public class MockUserVmManagerImpl extends ManagerBase implements UserVmManager,
@Override
public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData,
String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, String keyboard) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
StorageUnavailableException, ResourceAllocationException {
// TODO Auto-generated method stub
return null;
@ -348,7 +352,9 @@ public class MockUserVmManagerImpl extends ManagerBase implements UserVmManager,
@Override
public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner, String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps,
String keyboard) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
String keyboard, List<Long> affinityGroupIdList) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException,
ResourceAllocationException {
// TODO Auto-generated method stub
return null;
}

View File

@ -61,4 +61,5 @@ public interface SerialVersionUID {
public static final long CloudExecutionException = Base | 0x27;
public static final long CallFailedException = Base | 0x28;
public static final long UnableDeleteHostException = Base | 0x29;
public static final long AffinityConflictException = Base | 0x2a;
}