Skip to content

Commit b3a1cb4

Browse files
Allow to configure root disk size via Service Offering (diskoffering of type Service). (#4341)
1 parent 2b220b5 commit b3a1cb4

12 files changed

Lines changed: 345 additions & 40 deletions

File tree

api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ public class CreateServiceOfferingCmd extends BaseCmd {
127127
@Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "details for planner, used to store specific parameters")
128128
private Map details;
129129

130+
@Parameter(name = ApiConstants.ROOT_DISK_SIZE, type = CommandType.LONG, since = "4.15", description = "the Root disk size in GB.")
131+
private Long rootDiskSize;
132+
130133
@Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "bytes read rate of the disk offering")
131134
private Long bytesReadRate;
132135

@@ -324,6 +327,10 @@ public Map<String, String> getDetails() {
324327
return detailsMap;
325328
}
326329

330+
public Long getRootDiskSize() {
331+
return rootDiskSize;
332+
}
333+
327334
public Long getBytesReadRate() {
328335
return bytesReadRate;
329336
}

api/src/main/java/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ public ResizeVolumeCmd(Long id, Long minIops, Long maxIops) {
8787
this.maxIops = maxIops;
8888
}
8989

90+
public ResizeVolumeCmd(Long id, Long minIops, Long maxIops, long diskOfferingId) {
91+
this.id = id;
92+
this.minIops = minIops;
93+
this.maxIops = maxIops;
94+
this.newDiskOfferingId = diskOfferingId;
95+
}
96+
9097
//TODO use the method getId() instead of this one.
9198
public Long getEntityId() {
9299
return id;

api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ public class ServiceOfferingResponse extends BaseResponse {
200200
@Param(description = "the vsphere storage policy tagged to the service offering in case of VMware", since = "4.15")
201201
private String vsphereStoragePolicy;
202202

203+
@SerializedName(ApiConstants.ROOT_DISK_SIZE)
204+
@Param(description = "Root disk size in GB", since = "4.15")
205+
private Long rootDiskSize;
206+
203207
public ServiceOfferingResponse() {
204208
}
205209

@@ -468,4 +472,7 @@ public void setVsphereStoragePolicy(String vsphereStoragePolicy) {
468472
this.vsphereStoragePolicy = vsphereStoragePolicy;
469473
}
470474

475+
public void setRootDiskSize(Long rootDiskSize) {
476+
this.rootDiskSize = rootDiskSize;
477+
}
471478
}

engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ CREATE VIEW `cloud`.`service_offering_view` AS
406406
`disk_offering`.`iops_write_rate_max` AS `iops_write_rate_max`,
407407
`disk_offering`.`iops_write_rate_max_length` AS `iops_write_rate_max_length`,
408408
`disk_offering`.`cache_mode` AS `cache_mode`,
409+
`disk_offering`.`disk_size` AS `root_disk_size`,
409410
`service_offering`.`cpu` AS `cpu`,
410411
`service_offering`.`speed` AS `speed`,
411412
`service_offering`.`ram_size` AS `ram_size`,
@@ -821,7 +822,6 @@ INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_vers
821822
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'solaris11_64Guest', 328, now(), 0);
822823
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'solaris11_64Guest', 328, now(), 0);
823824

824-
825825
-- Add VMware Photon (64 bit) as support guest os
826826
INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (329, UUID(), 7, 'VMware Photon (64 bit)', now());
827827
-- VMware Photon (64 bit) VMWare guest os mapping

server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public ServiceOfferingResponse newServiceOfferingResponse(ServiceOfferingJoinVO
113113
offeringResponse.setObjectName("serviceoffering");
114114
offeringResponse.setIscutomized(offering.isDynamic());
115115
offeringResponse.setCacheMode(offering.getCacheMode());
116+
116117
if (offeringDetails != null && !offeringDetails.isEmpty()) {
117118
String vsphereStoragePolicyId = offeringDetails.get(ApiConstants.STORAGE_POLICY);
118119
if (vsphereStoragePolicyId != null) {
@@ -121,6 +122,9 @@ public ServiceOfferingResponse newServiceOfferingResponse(ServiceOfferingJoinVO
121122
offeringResponse.setVsphereStoragePolicy(vsphereStoragePolicyVO.getName());
122123
}
123124
}
125+
126+
offeringResponse.setRootDiskSize(offering.getRootDiskSize());
127+
124128
return offeringResponse;
125129
}
126130

server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit
190190
@Column(name = "vsphere_storage_policy")
191191
String vsphereStoragePolicy;
192192

193+
@Column(name = "root_disk_size")
194+
private Long rootDiskSize;
195+
193196
public ServiceOfferingJoinVO() {
194197
}
195198

@@ -363,7 +366,6 @@ public Long getIopsWriteRate() {
363366

364367
public Long getIopsWriteRateMaxLength() { return iopsWriteRateMaxLength; }
365368

366-
367369
public boolean isDynamic() {
368370
return cpu == null || speed == null || ramSize == null;
369371
}
@@ -392,4 +394,7 @@ public String getVsphereStoragePolicy() {
392394
return vsphereStoragePolicy;
393395
}
394396

397+
public Long getRootDiskSize() {
398+
return rootDiskSize ;
399+
}
395400
}

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
432432

433433
private static final Set<Provider> VPC_ONLY_PROVIDERS = Sets.newHashSet(Provider.VPCVirtualRouter, Provider.JuniperContrailVpcRouter, Provider.InternalLbVm);
434434

435+
private static final long GiB_TO_BYTES = 1024 * 1024 * 1024;
436+
435437
@Override
436438
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
437439
final String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.key());
@@ -2473,7 +2475,7 @@ public ServiceOffering createServiceOffering(final CreateServiceOfferingCmd cmd)
24732475

24742476
return createServiceOffering(userId, cmd.isSystem(), vmType, cmd.getServiceOfferingName(), cpuNumber, memory, cpuSpeed, cmd.getDisplayText(),
24752477
cmd.getProvisioningType(), localStorageRequired, offerHA, limitCpuUse, volatileVm, cmd.getTags(), cmd.getDomainIds(), cmd.getZoneIds(), cmd.getHostTag(),
2476-
cmd.getNetworkRate(), cmd.getDeploymentPlanner(), details, isCustomizedIops, cmd.getMinIops(), cmd.getMaxIops(),
2478+
cmd.getNetworkRate(), cmd.getDeploymentPlanner(), details, cmd.getRootDiskSize(), isCustomizedIops, cmd.getMinIops(), cmd.getMaxIops(),
24772479
cmd.getBytesReadRate(), cmd.getBytesReadRateMax(), cmd.getBytesReadRateMaxLength(),
24782480
cmd.getBytesWriteRate(), cmd.getBytesWriteRateMax(), cmd.getBytesWriteRateMaxLength(),
24792481
cmd.getIopsReadRate(), cmd.getIopsReadRateMax(), cmd.getIopsReadRateMaxLength(),
@@ -2484,7 +2486,7 @@ public ServiceOffering createServiceOffering(final CreateServiceOfferingCmd cmd)
24842486
protected ServiceOfferingVO createServiceOffering(final long userId, final boolean isSystem, final VirtualMachine.Type vmType,
24852487
final String name, final Integer cpu, final Integer ramSize, final Integer speed, final String displayText, final String provisioningType, final boolean localStorageRequired,
24862488
final boolean offerHA, final boolean limitResourceUse, final boolean volatileVm, String tags, final List<Long> domainIds, List<Long> zoneIds, final String hostTag,
2487-
final Integer networkRate, final String deploymentPlanner, final Map<String, String> details, final Boolean isCustomizedIops, Long minIops, Long maxIops,
2489+
final Integer networkRate, final String deploymentPlanner, final Map<String, String> details, Long rootDiskSizeInGiB, final Boolean isCustomizedIops, Long minIops, Long maxIops,
24882490
Long bytesReadRate, Long bytesReadRateMax, Long bytesReadRateMaxLength,
24892491
Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength,
24902492
Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength,
@@ -2545,6 +2547,12 @@ protected ServiceOfferingVO createServiceOffering(final long userId, final boole
25452547
}
25462548
}
25472549

2550+
if (rootDiskSizeInGiB != null && rootDiskSizeInGiB <= 0L) {
2551+
throw new InvalidParameterValueException(String.format("The Root disk size is of %s GB but it must be greater than 0.", rootDiskSizeInGiB));
2552+
} else if (rootDiskSizeInGiB != null) {
2553+
long rootDiskSizeInBytes = rootDiskSizeInGiB * GiB_TO_BYTES;
2554+
offering.setDiskSize(rootDiskSizeInBytes);
2555+
}
25482556

25492557
offering.setCustomizedIops(isCustomizedIops);
25502558
offering.setMinIops(minIops);

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep
894894
DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
895895
DiskOfferingVO newDiskOffering = null;
896896

897-
if (cmd.getNewDiskOfferingId() != null && volume.getDiskOfferingId() != cmd.getNewDiskOfferingId()) {
897+
if (cmd.getNewDiskOfferingId() != null) {
898898
newDiskOffering = _diskOfferingDao.findById(cmd.getNewDiskOfferingId());
899899
}
900900

@@ -913,6 +913,12 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep
913913

914914
// if we are to use the existing disk offering
915915
if (newDiskOffering == null) {
916+
if (volume.getVolumeType().equals(Volume.Type.ROOT) && diskOffering.getDiskSize() > 0) {
917+
throw new InvalidParameterValueException(
918+
"Failed to resize Root volume. The service offering of this Volume has been configured with a root disk size; "
919+
+ "on such case a Root Volume can only be resized when changing to another Service Offering with a Root disk size. "
920+
+ "For more details please check out the Official Resizing Volumes documentation.");
921+
}
916922
newSize = cmd.getSize();
917923
newHypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve();
918924

@@ -958,10 +964,6 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep
958964
throw new InvalidParameterValueException("Requested disk offering has been removed.");
959965
}
960966

961-
if (!DiskOfferingVO.Type.Disk.equals(newDiskOffering.getType())) {
962-
throw new InvalidParameterValueException("Requested disk offering type is invalid.");
963-
}
964-
965967
if (diskOffering.getTags() != null) {
966968
if (!StringUtils.areTagsEqual(diskOffering.getTags(), newDiskOffering.getTags())) {
967969
throw new InvalidParameterValueException("The tags on the new and old disk offerings must match.");
@@ -972,7 +974,9 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep
972974

973975
_configMgr.checkDiskOfferingAccess(_accountMgr.getActiveAccountById(volume.getAccountId()), newDiskOffering, _dcDao.findById(volume.getDataCenterId()));
974976

975-
if (newDiskOffering.isCustomized()) {
977+
if (newDiskOffering.getDiskSize() > 0 && DiskOfferingVO.Type.Service.equals(newDiskOffering.getType())) {
978+
newSize = newDiskOffering.getDiskSize();
979+
} else if (newDiskOffering.isCustomized()) {
976980
newSize = cmd.getSize();
977981

978982
if (newSize == null) {
@@ -989,9 +993,9 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep
989993
newSize = newDiskOffering.getDiskSize();
990994
}
991995

992-
if (!volume.getSize().equals(newSize) && !volume.getVolumeType().equals(Volume.Type.DATADISK)) {
993-
throw new InvalidParameterValueException("Only data volumes can be resized via a new disk offering.");
994-
}
996+
Long instanceId = volume.getInstanceId();
997+
VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(instanceId);
998+
checkIfVolumeIsRootAndVmIsRunning(newSize, volume, vmInstanceVO);
995999

9961000
if (newDiskOffering.isCustomizedIops() != null && newDiskOffering.isCustomizedIops()) {
9971001
newMinIops = cmd.getMinIops() != null ? cmd.getMinIops() : volume.getMinIops();
@@ -1140,6 +1144,13 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep
11401144
shrinkOk);
11411145
}
11421146

1147+
private void checkIfVolumeIsRootAndVmIsRunning(Long newSize, VolumeVO volume, VMInstanceVO vmInstanceVO) {
1148+
if (!volume.getSize().equals(newSize) && volume.getVolumeType().equals(Volume.Type.ROOT) && !State.Stopped.equals(vmInstanceVO.getState())) {
1149+
throw new InvalidParameterValueException(String.format("Cannot resize ROOT volume [%s] when VM is not on Stopped State. VM %s is in state %.", volume.getName(), vmInstanceVO
1150+
.getInstanceName(), vmInstanceVO.getState()));
1151+
}
1152+
}
1153+
11431154
private void validateIops(Long minIops, Long maxIops) {
11441155
if ((minIops == null && maxIops != null) || (minIops != null && maxIops == null)) {
11451156
throw new InvalidParameterValueException("Either 'miniops' and 'maxiops' must both be provided or neither must be provided.");

0 commit comments

Comments
 (0)