CLOUDSTACK-4757. Deploy Virtual Machine - If datadisk templates are specified using parameter 'datadisktemplatetodiskofferinglist', then create virtual machine with additional volumes attached
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ad8033f9 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ad8033f9 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ad8033f9 Branch: refs/heads/multiple-disk-ova Commit: ad8033f9807ca06f36ee85750a697fa9b4f284c7 Parents: 5db1bca Author: Likitha Shetty <likitha.she...@citrix.com> Authored: Mon Mar 10 19:40:05 2014 +0530 Committer: Likitha Shetty <likitha.she...@citrix.com> Committed: Fri May 2 17:51:52 2014 +0530 ---------------------------------------------------------------------- api/src/com/cloud/vm/DiskProfile.java | 4 ++ api/src/com/cloud/vm/UserVmService.java | 22 +++++++-- .../org/apache/cloudstack/api/ApiConstants.java | 1 + .../cloudstack/api/ResponseGenerator.java | 2 + .../api/command/user/vm/DeployVMCmd.java | 41 +++++++++++++++-- .../src/com/cloud/vm/VirtualMachineManager.java | 4 +- .../service/VolumeOrchestrationService.java | 5 ++- .../service/api/OrchestrationService.java | 4 +- .../com/cloud/vm/VirtualMachineManagerImpl.java | 27 ++++++++--- .../engine/orchestration/CloudOrchestrator.java | 19 ++++++-- .../orchestration/VolumeOrchestrator.java | 8 +++- .../resource/VmwareStorageProcessor.java | 6 ++- server/src/com/cloud/api/ApiResponseHelper.java | 5 +++ .../cloud/network/as/AutoScaleManagerImpl.java | 6 +-- server/src/com/cloud/vm/UserVmManagerImpl.java | 47 +++++++++++++++----- 15 files changed, 166 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/api/src/com/cloud/vm/DiskProfile.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/vm/DiskProfile.java b/api/src/com/cloud/vm/DiskProfile.java index a37f7aa..d909774 100644 --- a/api/src/com/cloud/vm/DiskProfile.java +++ b/api/src/com/cloud/vm/DiskProfile.java @@ -139,6 +139,10 @@ public class DiskProfile { return templateId; } + public void setTemplateId(Long templateId) { + this.templateId = templateId; + } + /** * @return disk offering id that the disk is based on. */ http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/api/src/com/cloud/vm/UserVmService.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index af4e1d3..c4bca71 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -50,6 +50,7 @@ import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network.IpAddresses; +import com.cloud.offering.DiskOffering; import com.cloud.offering.ServiceOffering; import com.cloud.storage.StoragePool; import com.cloud.template.VirtualMachineTemplate; @@ -185,6 +186,11 @@ public interface UserVmService { * @param memory * @param cpuNumber * @param customId + * @param dataDiskTemplateToDiskOfferingMap + * - Datadisk template to Disk offering Map + * an optional parameter that creates additional data disks for the virtual machine + * For each of the templates in the map, a data disk will be created from the corresponding + * disk offering obtained from the map * @return UserVm object if successful. * * @throws InsufficientCapacityException @@ -199,7 +205,7 @@ public interface UserVmService { 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, HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard, - List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId) throws InsufficientCapacityException, + List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -258,6 +264,11 @@ public interface UserVmService { * @param memory * @param cpuNumber * @param customId + * @param dataDiskTemplateToDiskOfferingMap + * - Datadisk template to Disk offering Map + * an optional parameter that creates additional data disks for the virtual machine + * For each of the templates in the map, a data disk will be created from the corresponding + * disk offering obtained from the map * @return UserVm object if successful. * * @throws InsufficientCapacityException @@ -272,7 +283,7 @@ public interface UserVmService { 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, HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, - List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId) throws InsufficientCapacityException, + List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; /** @@ -329,6 +340,11 @@ public interface UserVmService { * @param memory * @param cpuNumber * @param customId + * @param dataDiskTemplateToDiskOfferingMap + * - Datadisk template to Disk offering Map + * an optional parameter that creates additional data disks for the virtual machine + * For each of the templates in the map, a data disk will be created from the corresponding + * disk offering obtained from the map * @return UserVm object if successful. * * @throws InsufficientCapacityException @@ -343,7 +359,7 @@ public interface UserVmService { 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, HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList, - Map<String, String> customParameters, String customId) + Map<String, String> customParameters, String customId, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/api/src/org/apache/cloudstack/api/ApiConstants.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index a3faca7..7ece5d9 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -67,6 +67,7 @@ public class ApiConstants { public static final String MIN_IOPS = "miniops"; public static final String MAX_IOPS = "maxiops"; public static final String HYPERVISOR_SNAPSHOT_RESERVE = "hypervisorsnapshotreserve"; + public static final String DATADISKTEMPLATE_TO_DISKOFFERING_LIST = "datadisktemplatetodiskofferinglist"; public static final String DESCRIPTION = "description"; public static final String DESTINATION_ZONE_ID = "destzoneid"; public static final String DETAILS = "details"; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/api/src/org/apache/cloudstack/api/ResponseGenerator.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index 10fb6df..3cb656d 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -281,6 +281,8 @@ public interface ResponseGenerator { Host findHostById(Long hostId); + DiskOffering findDiskOfferingById(Long diskOfferingId); + VpnUsersResponse createVpnUserResponse(VpnUser user); RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java index 0adc57b..c59cea2 100755 --- a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java @@ -190,6 +190,10 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { @Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "Deployment planner to use for vm allocation. Available to ROOT admin only", since = "4.4", authorized = { RoleType.Admin }) private String deploymentPlanner; + @Parameter(name = ApiConstants.DATADISKTEMPLATE_TO_DISKOFFERING_LIST, type = CommandType.MAP, since = "4.4", description = "datadisk template to disk-offering mapping;" + + " an optional parameter used to create additional data disks from datadisk templates; can't be specified with diskOfferingId parameter") + private Map dataDiskTemplateToDiskOfferingList; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -393,6 +397,37 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { } } + public Map<Long, DiskOffering> getDataDiskTemplateToDiskOfferingMap() { + if (diskOfferingId != null && dataDiskTemplateToDiskOfferingList != null) { + throw new InvalidParameterValueException("diskofferingid paramter can't be specified along with datadisktemplatetodiskofferinglist parameter"); + } + HashMap<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap = new HashMap<Long, DiskOffering>(); + if (dataDiskTemplateToDiskOfferingList != null && !dataDiskTemplateToDiskOfferingList.isEmpty()) { + Collection dataDiskTemplatesCollection = dataDiskTemplateToDiskOfferingList.values(); + Iterator iter = dataDiskTemplatesCollection.iterator(); + while (iter.hasNext()) { + HashMap<String, String> dataDiskTemplates = (HashMap<String, String>)iter.next(); + Long dataDiskTemplateId; + DiskOffering dataDiskOffering = null; + VirtualMachineTemplate dataDiskTemplate= _entityMgr.findByUuid(VirtualMachineTemplate.class, dataDiskTemplates.get("datadisktemplateid")); + if (dataDiskTemplate == null) { + dataDiskTemplate = _entityMgr.findById(VirtualMachineTemplate.class, dataDiskTemplates.get("datadisktemplateid")); + if (dataDiskTemplate == null) + throw new InvalidParameterValueException("Unable to translate and find entity with datadisktemplateid " + dataDiskTemplates.get("datadisktemplateid")); + } + dataDiskTemplateId = dataDiskTemplate.getId(); + dataDiskOffering = _entityMgr.findByUuid(DiskOffering.class, dataDiskTemplates.get("diskofferingid")); + if (dataDiskOffering == null) { + dataDiskOffering = _entityMgr.findById(DiskOffering.class, dataDiskTemplates.get("diskofferingid")); + if (dataDiskOffering == null) + throw new InvalidParameterValueException("Unable to translate and find entity with diskofferingId " + dataDiskTemplates.get("diskofferingid")); + } + dataDiskTemplateToDiskOfferingMap.put(dataDiskTemplateId, dataDiskOffering); + } + } + return dataDiskTemplateToDiskOfferingMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -585,13 +620,13 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { } else { vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(), owner, name, displayName, diskOfferingId, size, group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm, keyboard, getAffinityGroupIdList(), - getDetails(), getCustomId()); + getDetails(), getCustomId(), getDataDiskTemplateToDiskOfferingMap()); } } else { if (zone.isSecurityGroupEnabled()) { vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), getSecurityGroupIdList(), owner, name, displayName, diskOfferingId, size, group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm, keyboard, - getAffinityGroupIdList(), getDetails(), getCustomId()); + getAffinityGroupIdList(), getDetails(), getCustomId(), getDataDiskTemplateToDiskOfferingMap()); } else { if (getSecurityGroupIdList() != null && !getSecurityGroupIdList().isEmpty()) { @@ -599,7 +634,7 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd { } vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, getNetworkIds(), owner, name, displayName, diskOfferingId, size, group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm, keyboard, getAffinityGroupIdList(), getDetails(), - getCustomId()); + getCustomId(), getDataDiskTemplateToDiskOfferingMap()); } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/engine/api/src/com/cloud/vm/VirtualMachineManager.java ---------------------------------------------------------------------- diff --git a/engine/api/src/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/com/cloud/vm/VirtualMachineManager.java index f070210..a1c3809 100644 --- a/engine/api/src/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/com/cloud/vm/VirtualMachineManager.java @@ -36,6 +36,7 @@ import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network; +import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOfferingInfo; import com.cloud.offering.ServiceOffering; import com.cloud.storage.StoragePool; @@ -73,11 +74,12 @@ public interface VirtualMachineManager extends Manager { * @param auxiliaryNetworks additional networks to attach the VMs to. * @param plan How to deploy the VM. * @param hyperType Hypervisor type + * @param datadiskTemplateToDiskOfferingMap data disks to be created from datadisk templates and attached to the VM * @throws InsufficientCapacityException If there are insufficient capacity to deploy this vm. */ void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering, DiskOfferingInfo rootDiskOfferingInfo, List<DiskOfferingInfo> dataDiskOfferings, LinkedHashMap<? extends Network, List<? extends NicProfile>> auxiliaryNetworks, DeploymentPlan plan, - HypervisorType hyperType) throws InsufficientCapacityException; + HypervisorType hyperType, Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap) throws InsufficientCapacityException; void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering, LinkedHashMap<? extends Network, List<? extends NicProfile>> networkProfiles, DeploymentPlan plan, HypervisorType hyperType) throws InsufficientCapacityException; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java ---------------------------------------------------------------------- diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java index df0b5e8..90625f7 100644 --- a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java +++ b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java @@ -23,6 +23,7 @@ import java.util.Set; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.framework.config.ConfigKey; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.dc.DataCenter; @@ -45,7 +46,6 @@ import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; -import org.apache.cloudstack.framework.config.ConfigKey; /** * VolumeOrchestrationService is a PURE orchestration service on CloudStack @@ -87,7 +87,8 @@ public interface VolumeOrchestrationService { void destroyVolume(Volume volume); - DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner); + DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, + Account owner, Long deviceId); VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, VolumeInfo volume, HypervisorType rootDiskHyperType, StoragePool storagePool) throws NoTransitionException; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/engine/api/src/org/apache/cloudstack/engine/service/api/OrchestrationService.java ---------------------------------------------------------------------- diff --git a/engine/api/src/org/apache/cloudstack/engine/service/api/OrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/service/api/OrchestrationService.java index 93f969f..b259808 100755 --- a/engine/api/src/org/apache/cloudstack/engine/service/api/OrchestrationService.java +++ b/engine/api/src/org/apache/cloudstack/engine/service/api/OrchestrationService.java @@ -36,6 +36,7 @@ import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.InsufficientCapacityException; import com.cloud.hypervisor.Hypervisor; +import com.cloud.offering.DiskOffering; import com.cloud.vm.NicProfile; @Path("orchestration") @@ -56,6 +57,7 @@ public interface OrchestrationService { * @param rootDiskTags tags for the root disk * @param networks networks that this VM should join * @param rootDiskSize size the root disk in case of templates. + * @param dataDiskTemplateDiskOfferingMap disk offerings in case of data disk templates * @return VirtualMachineEntity */ @POST @@ -65,7 +67,7 @@ public interface OrchestrationService { @QueryParam("cpu") int cpu, @QueryParam("speed") int speed, @QueryParam("ram") long memory, @QueryParam("disk-size") Long diskSize, @QueryParam("compute-tags") List<String> computeTags, @QueryParam("root-disk-tags") List<String> rootDiskTags, @QueryParam("network-nic-map") Map<String, NicProfile> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan, - @QueryParam("root-disk-size") Long rootDiskSize) throws InsufficientCapacityException; + @QueryParam("root-disk-size") Long rootDiskSize, @QueryParam("datadisktemplate-diskoffering-map") Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap) throws InsufficientCapacityException; @POST VirtualMachineEntity createVirtualMachineFromScratch(@QueryParam("id") String id, @QueryParam("owner") String owner, @QueryParam("iso-id") String isoId, http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java ---------------------------------------------------------------------- diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index e15d287..0b07026 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -29,6 +29,7 @@ import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.TimeZone; import java.util.UUID; @@ -40,6 +41,8 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; + import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -68,7 +71,6 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.cloudstack.utils.identity.ManagementServerNode; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; @@ -152,6 +154,7 @@ import com.cloud.network.NetworkModel; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.rules.RulesManager; +import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOfferingInfo; import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; @@ -161,6 +164,7 @@ import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StoragePool; +import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; @@ -374,7 +378,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @DB public void allocate(String vmInstanceName, final VirtualMachineTemplate template, ServiceOffering serviceOffering, final DiskOfferingInfo rootDiskOfferingInfo, final List<DiskOfferingInfo> dataDiskOfferings, - final LinkedHashMap<? extends Network, List<? extends NicProfile>> auxiliaryNetworks, DeploymentPlan plan, HypervisorType hyperType) + final LinkedHashMap<? extends Network, List<? extends NicProfile>> auxiliaryNetworks, DeploymentPlan plan, HypervisorType hyperType, + final Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap) throws InsufficientCapacityException { VMInstanceVO vm = _vmDao.findVMByInstanceName(vmInstanceName); @@ -412,7 +417,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (template.getFormat() == ImageFormat.ISO) { volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(), - rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vmFinal, template, owner); + rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vmFinal, template, owner, null); } else if (template.getFormat() == ImageFormat.BAREMETAL) { // Do nothing } else { @@ -423,7 +428,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (dataDiskOfferings != null) { for (DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings) { volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId(), dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(), - dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), vmFinal, template, owner); + dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), vmFinal, template, owner, null); + } + } + + if (datadiskTemplateToDiskOfferingMap != null && !datadiskTemplateToDiskOfferingMap.isEmpty()) { + int diskNumber = 1; + for (Entry<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap : datadiskTemplateToDiskOfferingMap.entrySet()) { + DiskOffering diskOffering = dataDiskTemplateToDiskOfferingMap.getValue(); + long diskOfferingSize = diskOffering.getDiskSize() / (1024 * 1024 * 1024); + VMTemplateVO dataDiskTemplate = _templateDao.findById(dataDiskTemplateToDiskOfferingMap.getKey()); + volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId() + "-" + String.valueOf(diskNumber), diskOffering, diskOfferingSize, null, null, + vmFinal, dataDiskTemplate, owner, Long.valueOf(diskNumber)); + diskNumber++; } } } @@ -437,7 +454,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering, LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, DeploymentPlan plan, HypervisorType hyperType) throws InsufficientCapacityException { - allocate(vmInstanceName, template, serviceOffering, new DiskOfferingInfo(serviceOffering), new ArrayList<DiskOfferingInfo>(), networks, plan, hyperType); + allocate(vmInstanceName, template, serviceOffering, new DiskOfferingInfo(serviceOffering), new ArrayList<DiskOfferingInfo>(), networks, plan, hyperType, null); } private VirtualMachineGuru getVmGuru(VirtualMachine vm) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java ---------------------------------------------------------------------- diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java index 2b49954..994bd92 100755 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java @@ -24,6 +24,7 @@ import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import javax.inject.Inject; @@ -45,6 +46,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; +import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOfferingInfo; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; @@ -155,7 +157,7 @@ public class CloudOrchestrator implements OrchestrationService { @Override public VirtualMachineEntity createVirtualMachine(String id, String owner, String templateId, String hostName, String displayName, String hypervisor, int cpu, int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, NicProfile> networkNicMap, DeploymentPlan plan, - Long rootDiskSize) throws InsufficientCapacityException { + Long rootDiskSize, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException { // VirtualMachineEntityImpl vmEntity = new VirtualMachineEntityImpl(id, owner, hostName, displayName, cpu, speed, memory, computeTags, rootDiskTags, networks, // vmEntityManager); @@ -233,8 +235,19 @@ public class CloudOrchestrator implements OrchestrationService { dataDiskOfferings.add(dataDiskOfferingInfo); } + if (dataDiskTemplateToDiskOfferingMap != null && !dataDiskTemplateToDiskOfferingMap.isEmpty()) { + for (Entry<Long, DiskOffering> datadiskTemplateToDiskOffering : dataDiskTemplateToDiskOfferingMap.entrySet()) { + DiskOffering diskOffering = datadiskTemplateToDiskOffering.getValue(); + if (diskOffering == null) { + throw new InvalidParameterValueException("Unable to find disk offering " + vm.getDiskOfferingId()); + } + if (diskOffering.getDiskSize() == 0) { // Custom disk offering is not supported for volumes created from datadisk templates + throw new InvalidParameterValueException("Disk offering " + diskOffering + " requires size parameter."); + } + } + } _itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(templateId)), computeOffering, rootDiskOfferingInfo, dataDiskOfferings, networkIpMap, plan, - hypervisorType); + hypervisorType, dataDiskTemplateToDiskOfferingMap); return vmEntity; } @@ -299,7 +312,7 @@ public class CloudOrchestrator implements OrchestrationService { HypervisorType hypervisorType = HypervisorType.valueOf(hypervisor); - _itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(isoId)), computeOffering, rootDiskOfferingInfo, new ArrayList<DiskOfferingInfo>(), networkIpMap, plan, hypervisorType); + _itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(isoId)), computeOffering, rootDiskOfferingInfo, new ArrayList<DiskOfferingInfo>(), networkIpMap, plan, hypervisorType, null); return vmEntity; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java ---------------------------------------------------------------------- diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index 6256e25..f453f6b 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -583,7 +583,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati } @Override - public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner) { + public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner, Long deviceId) { if (size == null) { size = offering.getDiskSize(); } else { @@ -608,13 +608,17 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati vol.setInstanceId(vm.getId()); } - if (type.equals(Type.ROOT)) { + if (deviceId != null) { + vol.setDeviceId(deviceId); + } else if (type.equals(Type.ROOT)) { vol.setDeviceId(0l); } else { vol.setDeviceId(1l); } if (template.getFormat() == ImageFormat.ISO) { vol.setIsoId(template.getId()); + } else if(template.getTemplateType().equals(Storage.TemplateType.DATADISK)) { + vol.setTemplateId(template.getId()); } // display flag matters only for the User vms if (vm.getType() == VirtualMachine.Type.User) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index ff893b2..131fe0a 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -456,7 +456,7 @@ public class VmwareStorageProcessor implements StorageProcessor { vmMo = new ClusterMO(context, morCluster).findVmOnHyperHost(vmdkName); assert (vmMo != null); - vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0); // TO-DO: Support for base template containing multiple disks + vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0); s_logger.info("Move volume out of volume-wrapper VM "); String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.VMWARE, !_fullCloneFlag); String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, !_fullCloneFlag); @@ -471,7 +471,9 @@ public class VmwareStorageProcessor implements StorageProcessor { vmMo.destroy(); String srcFile = dsMo.getDatastorePath(vmdkName, true); - dsMo.deleteFile(srcFile, dcMo.getMor(), true); + if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) { + dsMo.deleteFolder(srcFile, dcMo.getMor()); + } } // restoreVM - move the new ROOT disk into corresponding VM folder String vmInternalCSName = volume.getVmName(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/server/src/com/cloud/api/ApiResponseHelper.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 250f5a9..6d78d62 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1259,6 +1259,11 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override + public DiskOfferingVO findDiskOfferingById(Long diskOfferingId) { + return ApiDBUtils.findDiskOfferingById(diskOfferingId); + } + + @Override public VpnUsersResponse createVpnUserResponse(VpnUser vpnUser) { VpnUsersResponse vpnResponse = new VpnUsersResponse(); vpnResponse.setId(vpnUser.getUuid()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/server/src/com/cloud/network/as/AutoScaleManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java index 09c6694..044eee5 100644 --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -1331,18 +1331,18 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null, - null, true, null, null, null, null); + null, true, null, null, null, null, null); } else { if (zone.isSecurityGroupEnabled()) { vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, null, null, owner, "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, - null, null, true, null, null, null, null); + null, null, true, null, null, null, null, null); } else { vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), - null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null, addrs, true, null, null, null, null); + null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null, addrs, true, null, null, null, null, null); } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad8033f9/server/src/com/cloud/vm/UserVmManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 3d262b7..9a0d2a1 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -183,6 +183,7 @@ import com.cloud.network.security.dao.SecurityGroupDao; import com.cloud.network.security.dao.SecurityGroupVMMapDao; import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offering.ServiceOffering; @@ -2274,7 +2275,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir 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, HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList, - Map<String, String> customParametes, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, + Map<String, String> customParametes, String customId, Map<Long, DiskOffering> datadiskTemplateToDiskOfferringMap) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -2318,7 +2319,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod, - userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParametes, customId); + userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParametes, customId, datadiskTemplateToDiskOfferringMap); } @@ -2327,7 +2328,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir 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, HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, - List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId) throws InsufficientCapacityException, ConcurrentOperationException, + List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<Long, DiskOffering> datadiskTemplateToDiskOfferringMap) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -2425,7 +2426,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod, - userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParameters, customId); + userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParameters, customId, datadiskTemplateToDiskOfferringMap); } @Override @@ -2433,7 +2434,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir 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, HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayvm, String keyboard, List<Long> affinityGroupIdList, - Map<String, String> customParametrs, String customId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, + Map<String, String> customParametrs, String customId, Map<Long, DiskOffering> datadiskTemplateToDiskOfferringMap) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); @@ -2517,7 +2518,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, httpmethod, userData, - sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, customParametrs, customId); + sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, customParametrs, customId, datadiskTemplateToDiskOfferringMap); } public void checkNameForRFCCompliance(String name) { @@ -2531,7 +2532,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate tmplt, String hostName, String displayName, Account owner, Long diskOfferingId, Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, HTTPMethod httpmethod, String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean isDisplayVm, String keyboard, - List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId) throws InsufficientCapacityException, ResourceUnavailableException, + List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferringMap) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException { _accountMgr.checkAccess(caller, null, owner); @@ -2602,6 +2603,32 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso || diskOfferingId == null ? 1 : 2)); _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, size); + if (dataDiskTemplateToDiskOfferringMap != null && !dataDiskTemplateToDiskOfferringMap.isEmpty()) { + for (Entry<Long, DiskOffering> datadiskTemplateToDiskOffering : dataDiskTemplateToDiskOfferringMap.entrySet()) { + VMTemplateVO dataDiskTemplate = _templateDao.findById(datadiskTemplateToDiskOffering.getKey()); + DiskOffering dataDiskOffering = datadiskTemplateToDiskOffering.getValue(); + + if (dataDiskTemplate == null || (!dataDiskTemplate.getTemplateType().equals(TemplateType.DATADISK)) && + (dataDiskTemplate.getState().equals(VirtualMachineTemplate.State.Active))) { + throw new InvalidParameterValueException("Invalid template id specified for Datadisk template" + datadiskTemplateToDiskOffering.getKey()); + } + if (!dataDiskTemplate.getParentTemplateId().equals(template.getId())) { + throw new InvalidParameterValueException("Invalid Datadisk template. Specified Datadisk template " + datadiskTemplateToDiskOffering.getKey() + + " doesn't belong to template " + template.getId()); + } + if (dataDiskOffering == null) { + throw new InvalidParameterValueException("Invalid disk offering id specified" + datadiskTemplateToDiskOffering.getValue()); + } + _templateDao.loadDetails(dataDiskTemplate); + if (dataDiskOffering.isCustomized()) { + throw new InvalidParameterValueException("Invalid disk offering id specified" + datadiskTemplateToDiskOffering.getValue() + ". Custom Disk offerings are not" + + " supported for Datadisk templates"); + } + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, 1); + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, dataDiskOffering.getDiskSize()); + } + } + // verify security group ids if (securityGroupIdList != null) { for (Long securityGroupId : securityGroupIdList) { @@ -2785,7 +2812,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } UserVmVO vm = commitUserVm(zone, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, hypervisor, caller, isDisplayVm, keyboard, accountId, - offering, isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters); + offering, isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters, dataDiskTemplateToDiskOfferringMap); // Assign instance to the group try { @@ -2845,7 +2872,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir final Long diskOfferingId, final Long diskSize, final String userData, final HypervisorType hypervisor, final Account caller, final Boolean isDisplayVm, final String keyboard, final long accountId, final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap<String, NicProfile> networkNicMap, final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, - final Map<String, String> customParameters) throws InsufficientCapacityException { + final Map<String, String> customParameters, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException { return Transaction.execute(new TransactionCallbackWithException<UserVmVO, InsufficientCapacityException>() { @Override public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException { @@ -2954,7 +2981,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir networkNicMap, plan); } else { _orchSrvc.createVirtualMachine(vm.getUuid(), Long.toString(owner.getAccountId()), Long.toString(template.getId()), hostName, displayName, hypervisor.name(), - offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan, rootDiskSize); + offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan, rootDiskSize, dataDiskTemplateToDiskOfferingMap); } if (s_logger.isDebugEnabled()) {