diff --git a/api/src/com/cloud/api/commands/DeployVMCmd.java b/api/src/com/cloud/api/commands/DeployVMCmd.java index b22e5ed922d..c9a8a8169e6 100644 --- a/api/src/com/cloud/api/commands/DeployVMCmd.java +++ b/api/src/com/cloud/api/commands/DeployVMCmd.java @@ -36,10 +36,8 @@ import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.offering.ServiceOffering; import com.cloud.template.VirtualMachineTemplate; @@ -50,7 +48,7 @@ import com.cloud.uservm.UserVm; @Implementation(description="Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", responseObject=UserVmResponse.class) public class DeployVMCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(DeployVMCmd.class.getName()); - + private static final String s_name = "deployvirtualmachineresponse"; ///////////////////////////////////////////////////// @@ -59,37 +57,37 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="availability zone for the virtual machine") private Long zoneId; - + @Parameter(name=ApiConstants.SERVICE_OFFERING_ID, type=CommandType.LONG, required=true, description="the ID of the service offering for the virtual machine") private Long serviceOfferingId; - + @Parameter(name=ApiConstants.TEMPLATE_ID, type=CommandType.LONG, required=true, description="the ID of the template for the virtual machine") private Long templateId; - + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="host name for the virtual machine") private String name; - + @Parameter(name=ApiConstants.DISPLAY_NAME, type=CommandType.STRING, description="an optional user generated name for the virtual machine") private String displayName; - + //Owner information @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for the virtual machine. Must be used with domainId.") private String accountName; - + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used.") private Long domainId; - + //Network information @Parameter(name=ApiConstants.NETWORK_IDS, type=CommandType.LIST, collectionType=CommandType.LONG, description="list of network ids used by virtual machine") private List networkIds; - + @Parameter(name=ApiConstants.SECURITY_GROUP_IDS, type=CommandType.LIST, collectionType=CommandType.LONG, description="comma separated list of security groups id that going to be applied to the virtual machine. Should be passed only when vm is created from a zone with Basic Network support") private List securityGroupIdList; //DataDisk information @Parameter(name=ApiConstants.DISK_OFFERING_ID, type=CommandType.LONG, description="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.") private Long diskOfferingId; - + @Parameter(name=ApiConstants.SIZE, type=CommandType.LONG, description="the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId") private Long size; @@ -98,16 +96,16 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, description="the hypervisor on which to deploy the virtual machine") private String hypervisor; - + @Parameter(name=ApiConstants.USER_DATA, type=CommandType.STRING, description="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.") private String userData; @Parameter(name=ApiConstants.SSH_KEYPAIR, type=CommandType.STRING, description="name of the ssh key pair used to login to the virtual machine", includeInApiDoc=false) private String sshKeyPairName; - + @Parameter(name=ApiConstants.HOST_ID, type=CommandType.LONG, description="destination Host ID to deploy the VM to - parameter available for root admin only") private Long hostId; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -173,15 +171,15 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { public String getName() { return name; } - + public String getSSHKeyPairName() { - return sshKeyPairName; + return sshKeyPairName; } public Long getHostId() { return hostId; } - + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -190,11 +188,11 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { public String getCommandName() { return s_name; } - + public static String getResultObjectName() { return "virtualmachine"; } - + @Override public long getEntityOwnerId() { Account account = UserContext.current().getCaller(); @@ -223,33 +221,33 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { public String getCreateEventType() { return EventTypes.EVENT_VM_CREATE; } - + @Override public String getCreateEventDescription() { return "creating Vm"; } - + @Override public String getEventDescription() { return "starting Vm. Vm Id: "+getEntityId(); } - + @Override public AsyncJob.Type getInstanceType() { - return AsyncJob.Type.VirtualMachine; + return AsyncJob.Type.VirtualMachine; } - + @Override public void execute(){ UserVm result; try { UserContext.current().setEventDetails("Vm Id: "+getEntityId()); if (getHypervisor() == HypervisorType.BareMetal) { - result = _bareMetalVmService.startVirtualMachine(this); + result = _bareMetalVmService.startVirtualMachine(this); } else { - result = _userVmService.startVirtualMachine(this); + result = _userVmService.startVirtualMachine(this); } - + if (result != null) { UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0); response.setResponseName(getCommandName()); @@ -267,7 +265,7 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { s_logger.info(ex); s_logger.trace(ex); throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); - } + } } @Override @@ -278,62 +276,50 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { if (owner == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); } - + DataCenter zone = _configService.getZone(zoneId); if (zone == null) { throw new InvalidParameterValueException("Unable to find zone by id=" + zoneId); } - + ServiceOffering serviceOffering = _configService.getServiceOffering(serviceOfferingId); if (serviceOffering == null) { throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId); } - + VirtualMachineTemplate template = _templateService.getTemplate(templateId); // Make sure a valid template ID was specified if (template == null) { throw new InvalidParameterValueException("Unable to use template " + templateId); } - - Host destinationHost = null; - if(getHostId() != null){ - Account account = UserContext.current().getCaller(); - if(!_accountService.isRootAdmin(account.getType())){ - throw new PermissionDeniedException("Parameter hostid can only be specified by a Root Admin, permission denied"); - } - destinationHost = _resourceService.getHost(getHostId()); - if (destinationHost == null) { - throw new InvalidParameterValueException("Unable to find the host to deploy the VM, host id=" + getHostId()); - } + + UserVm vm = null; + if (getHypervisor() == HypervisorType.BareMetal) { + vm = _bareMetalVmService.createVirtualMachine(this); + } else { + if (zone.getNetworkType() == NetworkType.Basic) { + if (getNetworkIds() != null) { + throw new InvalidParameterValueException("Can't specify network Ids in Basic zone"); + } else { + vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, securityGroupIdList, owner, name, + displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName); + } + } else { + if (zone.isSecurityGroupEnabled()) { + vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), securityGroupIdList, + owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName); + } else { + if (securityGroupIdList != null && !securityGroupIdList.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); + } + } } - - UserVm vm = null; - if (getHypervisor() == HypervisorType.BareMetal) { - vm = _bareMetalVmService.createVirtualMachine(this); - } else { - if (zone.getNetworkType() == NetworkType.Basic) { - if (getNetworkIds() != null) { - throw new InvalidParameterValueException("Can't specify network Ids in Basic zone"); - } else { - vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, securityGroupIdList, owner, name, - displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, destinationHost); - } - } else { - if (zone.isSecurityGroupEnabled()) { - vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), securityGroupIdList, - owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, destinationHost); - } else { - if (securityGroupIdList != null && !securityGroupIdList.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, destinationHost); - } - } - } - - if (vm != null) { - setEntityId(vm.getId()); + + if (vm != null) { + setEntityId(vm.getId()); } else { throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to deploy vm"); } diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index 340b82fb20b..83b783c093e 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -105,7 +105,7 @@ public interface UserVmService { Volume detachVolumeFromVM(DetachVolumeCmd cmmd); UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, ExecutionException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, - ResourceAllocationException; + ResourceAllocationException; UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException; @@ -170,8 +170,6 @@ public interface UserVmService { * 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 - * @param Host - * destinationHost to deploy the VM * * @return UserVm object if successful. * @@ -184,8 +182,8 @@ public interface UserVmService { * @throws InsufficientResourcesException */ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List securityGroupIdList, Account owner, String hostName, - String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Host destinationHost) - throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; + String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair) + 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. @@ -226,8 +224,6 @@ public interface UserVmService { * 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 - * @param Host - * destinationHost to deploy the VM * * @return UserVm object if successful. * @@ -240,8 +236,8 @@ public interface UserVmService { * @throws InsufficientResourcesException */ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, List securityGroupIdList, - Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Host destinationHost) - throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; + Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair) + 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. @@ -280,8 +276,6 @@ public interface UserVmService { * 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 - * @param Host - * destinationHost to deploy the VM * * @return UserVm object if successful. * @@ -294,8 +288,8 @@ public interface UserVmService { * @throws InsufficientResourcesException */ UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, Account owner, String hostName, - String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Host destinationHost) - throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; + String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair) + throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** * Starts the virtual machine created from createVirtualMachine. @@ -352,7 +346,7 @@ public interface UserVmService { HypervisorType getHypervisorTypeOfUserVM(long vmid); UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, - ResourceAllocationException; + ResourceAllocationException; UserVm getUserVm(long vmId); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index b24da40c397..88e0410ddc1 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1964,7 +1964,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Override public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List securityGroupIdList, Account owner, - String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Host destinationHost) + String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = UserContext.current().getCaller(); @@ -1983,13 +1983,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, - caller, destinationHost); + caller); } @Override public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, - String sshKeyPair, Host destinationHost) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, + String sshKeyPair) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = UserContext.current().getCaller(); @@ -2057,12 +2057,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, - caller, destinationHost); + caller); } @Override public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List networkIdList, Account owner, String hostName, - String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Host destinationHost) + String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = UserContext.current().getCaller(); @@ -2176,23 +2176,17 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } } - return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, userData, sshKeyPair, hypervisor, caller, - destinationHost); + return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, userData, sshKeyPair, hypervisor, caller); } @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 networkList, List securityGroupIdList, String group, String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, - Host destinationHost) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException { + Long diskSize, List networkList, List securityGroupIdList, String group, String userData, String sshKeyPair, HypervisorType hypervisor, Account caller) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException { _accountMgr.checkAccess(caller, owner); long accountId = owner.getId(); - if (destinationHost != null && !_accountMgr.isRootAdmin(caller.getType())) { - throw new PermissionDeniedException("Destination Host can only be specified by a Root Admin, permission denied"); - } - if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getId()); } @@ -2292,13 +2286,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager _accountMgr.checkAccess(caller, template); - DataCenterDeployment plan = null; - if (destinationHost != null) { - s_logger.debug("Destination Host to deploy the VM is specified, adding it to the deployment plan"); - plan = new DataCenterDeployment(zone.getId(), destinationHost.getPodId(), destinationHost.getClusterId(), destinationHost.getId(), null); - } else { - plan = new DataCenterDeployment(zone.getId()); - } + DataCenterDeployment plan = new DataCenterDeployment(zone.getId()); s_logger.debug("Allocating in the DB for vm"); @@ -2409,6 +2397,18 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager protected UserVm startVirtualMachine(DeployVMCmd cmd, Map additonalParams) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { + + Host destinationHost = null; + if(cmd.getHostId() != null){ + Account account = UserContext.current().getCaller(); + if(!_accountService.isRootAdmin(account.getType())){ + throw new PermissionDeniedException("Parameter hostid can only be specified by a Root Admin, permission denied"); + } + destinationHost = _hostDao.findById(cmd.getHostId()); + if (destinationHost == null) { + throw new InvalidParameterValueException("Unable to find the host to deploy the VM, host id=" + cmd.getHostId()); + } + } long vmId = cmd.getEntityId(); UserVmVO vm = _vmDao.findById(vmId); _vmDao.loadDetails(vm); @@ -2448,7 +2448,14 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager params.putAll(additonalParams); } params.put(VirtualMachineProfile.Param.VmPassword, password); - vm = _itMgr.start(vm, params, caller, owner); + + DataCenterDeployment plan = null; + if (destinationHost != null) { + s_logger.debug("Destination Host to deploy the VM is specified, specifying a deployment plan to deploy the VM"); + plan = new DataCenterDeployment(vm.getDataCenterId(), destinationHost.getPodId(), destinationHost.getClusterId(), destinationHost.getId(), null); + } + + vm = _itMgr.start(vm, params, caller, owner, plan); } finally { updateVmStateForFailedVmCreation(vm.getId()); } diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java index 9c6c86aa2ac..0cea78bb45a 100644 --- a/server/src/com/cloud/vm/VirtualMachineManager.java +++ b/server/src/com/cloud/vm/VirtualMachineManager.java @@ -44,7 +44,7 @@ import com.cloud.utils.component.Manager; * Manages allocating resources to vms. */ public interface VirtualMachineManager extends Manager { - + T allocate(T vm, VMTemplateVO template, ServiceOfferingVO serviceOffering, @@ -55,7 +55,7 @@ public interface VirtualMachineManager extends Manager { DeploymentPlan plan, HypervisorType hyperType, Account owner) throws InsufficientCapacityException; - + T allocate(T vm, VMTemplateVO template, ServiceOfferingVO serviceOffering, @@ -65,7 +65,7 @@ public interface VirtualMachineManager extends Manager { DeploymentPlan plan, HypervisorType hyperType, Account owner) throws InsufficientCapacityException; - + T allocate(T vm, VMTemplateVO template, ServiceOfferingVO serviceOffering, @@ -73,34 +73,38 @@ public interface VirtualMachineManager extends Manager { DeploymentPlan plan, HypervisorType hyperType, Account owner) throws InsufficientCapacityException; - + T start(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException; - + + T start(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) throws InsufficientCapacityException, ResourceUnavailableException; + boolean stop(T vm, User caller, Account account) throws ResourceUnavailableException; - + boolean expunge(T vm, User caller, Account account) throws ResourceUnavailableException; - + void registerGuru(VirtualMachine.Type type, VirtualMachineGuru guru); - boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId); - + boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId); + T advanceStart(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; - - boolean advanceStop(T vm, boolean forced, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException; - - boolean advanceExpunge(T vm, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException; - - boolean remove(T vm, User caller, Account account); - - boolean destroy(T vm, User caller, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException; - - boolean migrateAway(VirtualMachine.Type type, long vmid, long hostId) throws InsufficientServerCapacityException, VirtualMachineMigrationException; - - T migrate(T vm, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException; - - T reboot(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException; - - T advanceReboot(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; - - VMInstanceVO findById(VirtualMachine.Type type, long vmId); + + T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; + + boolean advanceStop(T vm, boolean forced, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException; + + boolean advanceExpunge(T vm, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException; + + boolean remove(T vm, User caller, Account account); + + boolean destroy(T vm, User caller, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException; + + boolean migrateAway(VirtualMachine.Type type, long vmid, long hostId) throws InsufficientServerCapacityException, VirtualMachineMigrationException; + + T migrate(T vm, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException; + + T reboot(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException; + + T advanceReboot(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; + + VMInstanceVO findById(VirtualMachine.Type type, long vmId); } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 1237415e103..0972e3aec7f 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -251,10 +251,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene if (plan.getPodId() != null) { vm.setPodId(plan.getPodId()); } - if (plan.getHostId() != null) { - vm.setHostId(plan.getHostId()); - } - assert (plan.getPoolId() == null) : "We currently don't support pool preset yet"; + assert (plan.getClusterId() == null && plan.getPoolId() == null) : "We currently don't support cluster and pool preset yet"; @SuppressWarnings("unchecked") VirtualMachineGuru guru = (VirtualMachineGuru) _vmGurus.get(vm.getType()); @@ -435,8 +432,12 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene @Override public T start(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException { + return start(vm, params, caller, account, null); + } + @Override + public T start(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) throws InsufficientCapacityException, ResourceUnavailableException { try { - return advanceStart(vm, params, caller, account); + return advanceStart(vm, params, caller, account, planToDeploy); } catch (ConcurrentOperationException e) { throw new CloudRuntimeException("Unable to start a VM due to concurrent operation", e); } @@ -477,7 +478,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene @DB protected Ternary changeToStartState(VirtualMachineGuru vmGuru, T vm, User caller, Account account) - throws ConcurrentOperationException { + throws ConcurrentOperationException { long vmId = vm.getId(); ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Starting, vm.getType(), vm.getId()); @@ -549,7 +550,13 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene @Override public T advanceStart(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { + ConcurrentOperationException, ResourceUnavailableException { + return advanceStart(vm, params, caller, account, null); + } + + @Override + public T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { long vmId = vm.getId(); VirtualMachineGuru vmGuru; if (vm.getHypervisorType() == HypervisorType.BareMetal) { @@ -573,6 +580,12 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodId(), null, null, null); + if(planToDeploy != null){ + if (s_logger.isDebugEnabled()) { + s_logger.debug("advanceStart: DeploymentPlan is provided, using that plan to deploy"); + } + plan = (DataCenterDeployment)planToDeploy; + } HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); boolean canRetry = true; @@ -600,7 +613,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene Long rootVolClusterId = pool.getClusterId(); plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId()); if (s_logger.isDebugEnabled()) { - s_logger.debug(vol + " is ready, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId + " , and clusterId: " + rootVolClusterId); + s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId + " , and clusterId: " + rootVolClusterId); } } } @@ -722,7 +735,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } } finally { if (startedVm == null && canRetry) { - // decrement only for user VM's and newly created VM + // decrement only for user VM's and newly created VM if (vm.getType().equals(VirtualMachine.Type.User) && (vm.getLastHostId() == null)) { _accountMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm); } @@ -995,7 +1008,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene @Override public T migrate(T vm, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, - VirtualMachineMigrationException { + VirtualMachineMigrationException { s_logger.info("Migrating " + vm + " to " + dest); long dstHostId = dest.getHost().getId(); @@ -1264,7 +1277,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene @Override public T advanceReboot(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { + ConcurrentOperationException, ResourceUnavailableException { T rebootedVm = null; DataCenter dc = _configMgr.getZone(vm.getDataCenterId());