Skip to content

Commit 7e3f083

Browse files
committed
Create multiple data volumes using the deployVirtualMachine Api
1 parent 31f89df commit 7e3f083

File tree

14 files changed

+184
-75
lines changed

14 files changed

+184
-75
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import com.cloud.hypervisor.Hypervisor.HypervisorType;
5757
import com.cloud.network.Network.IpAddresses;
5858
import com.cloud.offering.DiskOffering;
59+
import com.cloud.offering.DiskOfferingInfo;
5960
import com.cloud.offering.ServiceOffering;
6061
import com.cloud.storage.StoragePool;
6162
import com.cloud.template.VirtualMachineTemplate;
@@ -218,7 +219,7 @@ void startVirtualMachineForHA(VirtualMachine vm, Map<VirtualMachineProfile.Param
218219
* available.
219220
*/
220221
UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList,
221-
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
222+
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, List<DiskOfferingInfo> dataDiskOfferingsInfo, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
222223
String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
223224
List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
224225
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
@@ -295,7 +296,7 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
295296
* available.
296297
*/
297298
UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
298-
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
299+
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, List<DiskOfferingInfo> dataDiskOfferingsInfo, String group, HypervisorType hypervisor,
299300
HTTPMethod httpmethod, String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
300301
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
301302
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, String vmType) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
@@ -367,7 +368,7 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin
367368
* available.
368369
*/
369370
UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner,
370-
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
371+
String hostName, String displayName, Long diskOfferingId, Long diskSize, List<DiskOfferingInfo> dataDiskOfferingsInfo, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
371372
Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
372373
Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
373374
Map<String, String> templateOvfPropertiesMap, boolean dynamicScalingEnabled, String vmType, Long overrideDiskOfferingId)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ public class ApiConstants {
137137
public static final String MAX_IOPS = "maxiops";
138138
public static final String HYPERVISOR_SNAPSHOT_RESERVE = "hypervisorsnapshotreserve";
139139
public static final String DATACENTER_NAME = "datacentername";
140+
public static final String DATADISKS_DETAILS = "datadisksdetails";
140141
public static final String DATADISK_OFFERING_LIST = "datadiskofferinglist";
141142
public static final String DEFAULT_VALUE = "defaultvalue";
142143
public static final String DELETE_PROTECTION = "deleteprotection";

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

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import com.cloud.network.Network;
7171
import com.cloud.network.Network.IpAddresses;
7272
import com.cloud.offering.DiskOffering;
73+
import com.cloud.offering.DiskOfferingInfo;
7374
import com.cloud.template.VirtualMachineTemplate;
7475
import com.cloud.uservm.UserVm;
7576
import com.cloud.utils.net.Dhcp;
@@ -147,6 +148,13 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
147148
since = "4.4")
148149
private Long rootdisksize;
149150

151+
@Parameter(name = ApiConstants.DATADISKS_DETAILS,
152+
type = CommandType.MAP,
153+
since = "4.21.0",
154+
description = "Disk offering details for creating multiple data volumes. Mutually exclusibe with diskOfferingId." +
155+
" Example: datadisksdetails[0].diskofferingid=1&datadisksdetails[0].size=10&datadisksdetails[0].miniops=100&datadisksdetails[0].maxiops=200")
156+
private Map dataDisksDetails;
157+
150158
@Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "an optional group for the virtual machine")
151159
private String group;
152160

@@ -278,6 +286,8 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
278286
description = "Enable packed virtqueues or not.")
279287
private Boolean nicPackedVirtQueues;
280288

289+
private List<DiskOfferingInfo> dataDiskOfferingsInfo;
290+
281291
/////////////////////////////////////////////////////
282292
/////////////////// Accessors ///////////////////////
283293
/////////////////////////////////////////////////////
@@ -510,6 +520,58 @@ public List<String> getSSHKeyPairNames() {
510520
return sshKeyPairs;
511521
}
512522

523+
public List<DiskOfferingInfo> getDataDiskOfferingsInfo() {
524+
if (this.dataDiskOfferingsInfo != null) {
525+
return this.dataDiskOfferingsInfo;
526+
}
527+
if (dataDisksDetails == null || dataDisksDetails.isEmpty()) {
528+
return null;
529+
}
530+
List<DiskOfferingInfo> diskOfferingInfoList = new ArrayList<>();
531+
Collection dataDisksCollection = dataDisksDetails.values();
532+
Iterator iter = dataDisksCollection.iterator();
533+
while (iter.hasNext()) {
534+
HashMap<String, String> dataDisk = (HashMap<String, String>)iter.next();
535+
String diskOfferingUuid = dataDisk.get(ApiConstants.DISK_OFFERING_ID);
536+
if (diskOfferingUuid == null) {
537+
throw new InvalidParameterValueException("Disk offering id is required for data disk");
538+
}
539+
DiskOffering diskOffering = _entityMgr.findByUuid(DiskOffering.class, diskOfferingUuid);
540+
if (diskOffering == null) {
541+
throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingUuid);
542+
}
543+
if (diskOffering.isComputeOnly()) {
544+
throw new InvalidParameterValueException(String.format("The disk offering id %d provided is directly mapped to a service offering, please provide an individual disk offering", diskOffering.getUuid()));
545+
}
546+
547+
Long size = null;
548+
Long minIops = null;
549+
Long maxIops = null;
550+
if (diskOffering.isCustomized()) {
551+
if (dataDisk.get(ApiConstants.SIZE) == null) {
552+
throw new InvalidParameterValueException("Size is required for custom disk offering");
553+
}
554+
size = Long.parseLong(dataDisk.get(ApiConstants.SIZE));
555+
} else {
556+
size = diskOffering.getDiskSize() / (1024 * 1024 * 1024);
557+
}
558+
if (diskOffering.isCustomizedIops() != null && diskOffering.isCustomizedIops()) {
559+
if (dataDisk.get(ApiConstants.MIN_IOPS) == null) {
560+
throw new InvalidParameterValueException("Min IOPS is required for custom disk offering");
561+
}
562+
if (dataDisk.get(ApiConstants.MAX_IOPS) == null) {
563+
throw new InvalidParameterValueException("Max IOPS is required for custom disk offering");
564+
}
565+
minIops = Long.parseLong(dataDisk.get(ApiConstants.MIN_IOPS));
566+
maxIops = Long.parseLong(dataDisk.get(ApiConstants.MAX_IOPS));
567+
}
568+
DiskOfferingInfo diskOfferingInfo = new DiskOfferingInfo(diskOffering, size, minIops, maxIops);
569+
diskOfferingInfoList.add(diskOfferingInfo);
570+
}
571+
this.dataDiskOfferingsInfo = diskOfferingInfoList;
572+
return dataDiskOfferingsInfo;
573+
}
574+
513575
public Long getHostId() {
514576
return hostId;
515577
}

engine/api/src/main/java/org/apache/cloudstack/engine/service/api/OrchestrationService.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.cloud.exception.InsufficientCapacityException;
3838
import com.cloud.hypervisor.Hypervisor;
3939
import com.cloud.offering.DiskOffering;
40+
import com.cloud.offering.DiskOfferingInfo;
4041
import com.cloud.vm.NicProfile;
4142

4243
@Path("orchestration")
@@ -67,15 +68,17 @@ VirtualMachineEntity createVirtualMachine(@QueryParam("id") String id, @QueryPar
6768
@QueryParam("compute-tags") List<String> computeTags, @QueryParam("root-disk-tags") List<String> rootDiskTags,
6869
@QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan,
6970
@QueryParam("root-disk-size") Long rootDiskSize, @QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap,
70-
@QueryParam("datadisktemplate-diskoffering-map") Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap, @QueryParam("disk-offering-id") Long diskOfferingId, @QueryParam("root-disk-offering-id") Long rootDiskOfferingId) throws InsufficientCapacityException;
71+
@QueryParam("datadisktemplate-diskoffering-map") Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap,
72+
@QueryParam("disk-offering-id") Long diskOfferingId, @QueryParam("root-disk-offering-id") Long rootDiskOfferingId, @QueryParam("data-disks-offering-info") List<DiskOfferingInfo> dataDiskOfferingsInfo) throws InsufficientCapacityException;
7173

7274
@POST
7375
VirtualMachineEntity createVirtualMachineFromScratch(@QueryParam("id") String id, @QueryParam("owner") String owner, @QueryParam("iso-id") String isoId,
7476
@QueryParam("host-name") String hostName, @QueryParam("display-name") String displayName, @QueryParam("hypervisor") String hypervisor,
7577
@QueryParam("os") String os, @QueryParam("cpu") int cpu, @QueryParam("speed") int speed, @QueryParam("ram") long memory, @QueryParam("disk-size") Long diskSize,
7678
@QueryParam("compute-tags") List<String> computeTags, @QueryParam("root-disk-tags") List<String> rootDiskTags,
7779
@QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan,
78-
@QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap, @QueryParam("disk-offering-id") Long diskOfferingId) throws InsufficientCapacityException;
80+
@QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap, @QueryParam("disk-offering-id") Long diskOfferingId,
81+
@QueryParam("data-disks-offering-info") List<DiskOfferingInfo> dataDiskOfferingsInfo) throws InsufficientCapacityException;
7982

8083
@POST
8184
NetworkEntity createNetwork(String id, String name, String domainName, String cidr, String gateway);

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,9 +521,11 @@ public void allocate(final String vmInstanceName, final VirtualMachineTemplate t
521521
CallContext volumeContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Volume);
522522
try {
523523
if (dataDiskOfferings != null) {
524+
int diskNumber = 1;
524525
for (final DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings) {
525-
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + persistedVm.getId(), dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(),
526-
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), persistedVm, template, owner, null);
526+
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + persistedVm.getId() + "-" + String.valueOf(diskNumber), dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(),
527+
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), persistedVm, template, owner, Long.valueOf(diskNumber));
528+
diskNumber++;
527529
}
528530
}
529531
if (datadiskTemplateToDiskOfferingMap != null && !datadiskTemplateToDiskOfferingMap.isEmpty()) {

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ public void destroyVolume(String volumeEntity) {
159159
@Override
160160
public VirtualMachineEntity createVirtualMachine(String id, String owner, String templateId, String hostName, String displayName, String hypervisor, int cpu,
161161
int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, List<NicProfile>> networkNicMap, DeploymentPlan plan,
162-
Long rootDiskSize, Map<String, Map<Integer, String>> extraDhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Long dataDiskOfferingId, Long rootDiskOfferingId) throws InsufficientCapacityException {
162+
Long rootDiskSize, Map<String, Map<Integer, String>> extraDhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
163+
Long dataDiskOfferingId, Long rootDiskOfferingId, List<DiskOfferingInfo> dataDiskOfferingsInfo) throws InsufficientCapacityException {
163164

164165
// VirtualMachineEntityImpl vmEntity = new VirtualMachineEntityImpl(id, owner, hostName, displayName, cpu, speed, memory, computeTags, rootDiskTags, networks,
165166
// vmEntityManager);
@@ -241,6 +242,8 @@ public VirtualMachineEntity createVirtualMachine(String id, String owner, String
241242

242243
dataDiskOfferings.add(dataDiskOfferingInfo);
243244
}
245+
} else {
246+
dataDiskOfferings.addAll(dataDiskOfferingsInfo);
244247
}
245248

246249
if (dataDiskTemplateToDiskOfferingMap != null && !dataDiskTemplateToDiskOfferingMap.isEmpty()) {
@@ -264,7 +267,7 @@ public VirtualMachineEntity createVirtualMachine(String id, String owner, String
264267
@Override
265268
public VirtualMachineEntity createVirtualMachineFromScratch(String id, String owner, String isoId, String hostName, String displayName, String hypervisor, String os,
266269
int cpu, int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, List<NicProfile>> networkNicMap, DeploymentPlan plan,
267-
Map<String, Map<Integer, String>> extraDhcpOptionMap, Long diskOfferingId)
270+
Map<String, Map<Integer, String>> extraDhcpOptionMap, Long diskOfferingId, List<DiskOfferingInfo> dataDiskOfferingsInfo)
268271
throws InsufficientCapacityException {
269272

270273
// VirtualMachineEntityImpl vmEntity = new VirtualMachineEntityImpl(id, owner, hostName, displayName, cpu, speed, memory, computeTags, rootDiskTags, networks, vmEntityManager);
@@ -321,7 +324,7 @@ public VirtualMachineEntity createVirtualMachineFromScratch(String id, String ow
321324

322325
HypervisorType hypervisorType = HypervisorType.valueOf(hypervisor);
323326

324-
_itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(isoId)), computeOffering, rootDiskOfferingInfo, new ArrayList<DiskOfferingInfo>(), networkIpMap, plan, hypervisorType, extraDhcpOptionMap, null);
327+
_itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(isoId)), computeOffering, rootDiskOfferingInfo, dataDiskOfferingsInfo, networkIpMap, plan, hypervisorType, extraDhcpOptionMap, null);
325328

326329
return vmEntity;
327330
}

plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,12 +410,12 @@ protected UserVm createKubernetesNode(String joinIp) throws ManagementServerExce
410410
List<Long> securityGroupIds = new ArrayList<>();
411411
securityGroupIds.add(kubernetesCluster.getSecurityGroupId());
412412
nodeVm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, securityGroupIds, owner,
413-
hostName, hostName, null, null, null, Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST,base64UserData, null, null, keypairs,
413+
hostName, hostName, null, null, null, null, Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST,base64UserData, null, null, keypairs,
414414
null, addrs, null, null, null, customParameterMap, null, null, null,
415415
null, true, null, UserVmManager.CKS_NODE);
416416
} else {
417417
nodeVm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, owner,
418-
hostName, hostName, null, null, null,
418+
hostName, hostName, null, null, null, null,
419419
Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, base64UserData, null, null, keypairs,
420420
null, addrs, null, null, null, customParameterMap, null, null, null, null, true, UserVmManager.CKS_NODE, null);
421421
}

0 commit comments

Comments
 (0)