diff --git a/api/src/main/java/com/cloud/offering/DiskOffering.java b/api/src/main/java/com/cloud/offering/DiskOffering.java index 581d32d572a..98ba6c0f46d 100644 --- a/api/src/main/java/com/cloud/offering/DiskOffering.java +++ b/api/src/main/java/com/cloud/offering/DiskOffering.java @@ -99,18 +99,53 @@ public interface DiskOffering extends InfrastructureEntity, Identity, InternalId Long getBytesReadRate(); + void setBytesReadRateMax(Long bytesReadRateMax); + + Long getBytesReadRateMax(); + + void setBytesReadRateMaxLength(Long bytesReadRateMaxLength); + + Long getBytesReadRateMaxLength(); + + void setBytesWriteRate(Long bytesWriteRate); Long getBytesWriteRate(); + void setBytesWriteRateMax(Long bytesWriteMax); + + Long getBytesWriteRateMax(); + + void setBytesWriteRateMaxLength(Long bytesWriteMaxLength); + + Long getBytesWriteRateMaxLength(); + + void setIopsReadRate(Long iopsReadRate); Long getIopsReadRate(); + void setIopsReadRateMax(Long iopsReadRateMax); + + Long getIopsReadRateMax(); + + void setIopsReadRateMaxLength(Long iopsReadRateMaxLength); + + Long getIopsReadRateMaxLength(); + void setIopsWriteRate(Long iopsWriteRate); Long getIopsWriteRate(); + void setIopsWriteRateMax(Long iopsWriteRateMax); + + Long getIopsWriteRateMax(); + + + void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength); + + Long getIopsWriteRateMaxLength(); + void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve); Integer getHypervisorSnapshotReserve(); diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index d519e4408e6..0c1f2b11f32 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -37,7 +37,11 @@ public class ApiConstants { public static final String BIND_DN = "binddn"; public static final String BIND_PASSWORD = "bindpass"; public static final String BYTES_READ_RATE = "bytesreadrate"; + public static final String BYTES_READ_RATE_MAX = "bytesreadratemax"; + public static final String BYTES_READ_RATE_MAX_LENGTH = "bytesreadratemaxlength"; public static final String BYTES_WRITE_RATE = "byteswriterate"; + public static final String BYTES_WRITE_RATE_MAX = "byteswriteratemax"; + public static final String BYTES_WRITE_RATE_MAX_LENGTH = "byteswriteratemaxlength"; public static final String BYPASS_VLAN_OVERLAP_CHECK = "bypassvlanoverlapcheck"; public static final String CATEGORY = "category"; public static final String CAN_REVERT = "canrevert"; @@ -162,7 +166,11 @@ public class ApiConstants { public static final String INTERVAL_TYPE = "intervaltype"; public static final String LOCATION_TYPE = "locationtype"; public static final String IOPS_READ_RATE = "iopsreadrate"; + public static final String IOPS_READ_RATE_MAX = "iopsreadratemax"; + public static final String IOPS_READ_RATE_MAX_LENGTH = "iopsreadratemaxlength"; public static final String IOPS_WRITE_RATE = "iopswriterate"; + public static final String IOPS_WRITE_RATE_MAX = "iopswriteratemax"; + public static final String IOPS_WRITE_RATE_MAX_LENGTH = "iopswriteratemaxlength"; public static final String IP_ADDRESS = "ipaddress"; public static final String IP6_ADDRESS = "ip6address"; public static final String IP_ADDRESS_ID = "ipaddressid"; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java index 747da053be6..469f714d028 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java @@ -80,15 +80,41 @@ public class CreateDiskOfferingCmd extends BaseCmd { @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "bytes read rate of the disk offering") private Long bytesReadRate; + + @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes read rate of the disk offering") + private Long bytesReadRateMax; + + @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst") + private Long bytesReadRateMaxLength; + @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, required = false, description = "bytes write rate of the disk offering") private Long bytesWriteRate; + @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes write rate of the disk offering") + private Long bytesWriteRateMax; + + + @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst") + private Long bytesWriteRateMaxLength; + @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, required = false, description = "io requests read rate of the disk offering") private Long iopsReadRate; + @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst requests read rate of the disk offering") + private Long iopsReadRateMax; + + @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst") + private Long iopsReadRateMaxLength; + @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, required = false, description = "io requests write rate of the disk offering") private Long iopsWriteRate; + @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst io requests write rate of the disk offering") + private Long iopsWriteRateMax; + + @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst") + private Long iopsWriteRateMaxLength; + @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "whether disk offering iops is custom or not") private Boolean customizedIops; @@ -148,18 +174,50 @@ public class CreateDiskOfferingCmd extends BaseCmd { return bytesReadRate; } + public Long getBytesReadRateMax() { + return bytesReadRateMax; + } + + public Long getBytesReadRateMaxLength() { + return bytesReadRateMaxLength; + } + public Long getBytesWriteRate() { return bytesWriteRate; } + public Long getBytesWriteRateMax() { + return bytesWriteRateMax; + } + + public Long getBytesWriteRateMaxLength() { + return bytesWriteRateMaxLength; + } + public Long getIopsReadRate() { return iopsReadRate; } + public Long getIopsReadRateMax() { + return iopsReadRateMax; + } + + public Long getIopsReadRateMaxLength() { + return iopsReadRateMaxLength; + } + public Long getIopsWriteRate() { return iopsWriteRate; } + public Long getIopsWriteRateMax() { + return iopsWriteRateMax; + } + + public Long getIopsWriteRateMaxLength() { + return iopsWriteRateMaxLength; + } + public String getStorageType() { return storageType; } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java index eaa8d875036..ed87ad86c40 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java @@ -113,15 +113,39 @@ public class CreateServiceOfferingCmd extends BaseCmd { @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "bytes read rate of the disk offering") private Long bytesReadRate; + @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes read rate of the disk offering") + private Long bytesReadRateMax; + + @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst") + private Long bytesReadRateMaxLength; + @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, required = false, description = "bytes write rate of the disk offering") private Long bytesWriteRate; + @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes write rate of the disk offering") + private Long bytesWriteRateMax; + + @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst") + private Long bytesWriteRateMaxLength; + @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, required = false, description = "io requests read rate of the disk offering") private Long iopsReadRate; + @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst requests read rate of the disk offering") + private Long iopsReadRateMax; + + @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst") + private Long iopsReadRateMaxLength; + @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, required = false, description = "io requests write rate of the disk offering") private Long iopsWriteRate; + @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst io requests write rate of the disk offering") + private Long iopsWriteRateMax; + + @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst") + private Long iopsWriteRateMaxLength; + @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "whether compute offering iops is custom or not", since = "4.4") private Boolean customizedIops; @@ -232,18 +256,50 @@ public class CreateServiceOfferingCmd extends BaseCmd { return bytesReadRate; } + public Long getBytesReadRateMax() { + return bytesReadRateMax; + } + + public Long getBytesReadRateMaxLength() { + return bytesReadRateMaxLength; + } + public Long getBytesWriteRate() { return bytesWriteRate; } + public Long getBytesWriteRateMax() { + return bytesWriteRateMax; + } + + public Long getBytesWriteRateMaxLength() { + return bytesWriteRateMaxLength; + } + public Long getIopsReadRate() { return iopsReadRate; } + public Long getIopsReadRateMax() { + return iopsReadRateMax; + } + + public Long getIopsReadRateMaxLength() { + return iopsReadRateMaxLength; + } + public Long getIopsWriteRate() { return iopsWriteRate; } + public Long getIopsWriteRateMax() { + return iopsWriteRateMax; + } + + public Long getIopsWriteRateMaxLength() { + return iopsWriteRateMaxLength; + } + public Boolean isCustomizedIops() { return customizedIops; } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/DiskOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/DiskOfferingResponse.java index f579119483b..5f22c91488e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/DiskOfferingResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/DiskOfferingResponse.java @@ -92,18 +92,50 @@ public class DiskOfferingResponse extends BaseResponse { @Param(description = "bytes read rate of the disk offering") private Long bytesReadRate; + @SerializedName("diskBytesReadRateMax") + @Param(description = "burst bytes read rate of the disk offering") + private Long bytesReadRateMax; + + @SerializedName("diskBytesReadRateMaxLength") + @Param(description = "length (in seconds) of the burst") + private Long bytesReadRateMaxLength; + @SerializedName("diskBytesWriteRate") @Param(description = "bytes write rate of the disk offering") private Long bytesWriteRate; + @SerializedName("diskBytesWriteRateMax") + @Param(description = "burst bytes write rate of the disk offering") + private Long bytesWriteRateMax; + + @SerializedName("diskBytesWriteRateMaxLength") + @Param(description = "length (in seconds) of the burst") + private Long bytesWriteRateMaxLength; + @SerializedName("diskIopsReadRate") @Param(description = "io requests read rate of the disk offering") private Long iopsReadRate; + @SerializedName("diskIopsReadRateMax") + @Param(description = "burst io requests read rate of the disk offering") + private Long iopsReadRateMax; + + @SerializedName("diskIopsReadRateMaxLength") + @Param(description = "length (in second) of the burst") + private Long iopsReadRateMaxLength; + @SerializedName("diskIopsWriteRate") @Param(description = "io requests write rate of the disk offering") private Long iopsWriteRate; + @SerializedName("diskIopsWriteRateMax") + @Param(description = "burst io requests write rate of the disk offering") + private Long iopsWriteRateMax; + + @SerializedName("diskIopsWriteRateMaxLength") + @Param(description = "length (in seconds) of the burst") + private Long iopsWriteRateMaxLength; + @SerializedName("cacheMode") @Param(description = "the cache mode to use for this disk offering. none, writeback or writethrough", since = "4.4") private String cacheMode; @@ -253,15 +285,47 @@ public class DiskOfferingResponse extends BaseResponse { this.bytesReadRate = bytesReadRate; } + public void setBytesReadRateMax(Long bytesReadRateMax) { + this.bytesReadRateMax = bytesReadRateMax; + } + + public void setBytesReadRateMaxLength(Long bytesReadRateMaxLength) { + this.bytesReadRateMaxLength = bytesReadRateMaxLength; + } + public void setBytesWriteRate(Long bytesWriteRate) { this.bytesWriteRate = bytesWriteRate; } + public void setBytesWriteRateMax(Long bytesWriteRateMax) { + this.bytesWriteRateMax = bytesWriteRateMax; + } + + public void setBytesWriteRateMaxLength(Long bytesWriteRateMaxLength) { + this.bytesWriteRateMaxLength = bytesWriteRateMaxLength; + } + public void setIopsReadRate(Long iopsReadRate) { this.iopsReadRate = iopsReadRate; } + public void setIopsReadRateMax(Long iopsReadRateMax) { + this.iopsReadRateMax = iopsReadRateMax; + } + + public void setIopsReadRateMaxLength(Long iopsReadRateMaxLength) { + this.iopsReadRateMaxLength = iopsReadRateMaxLength; + } + public void setIopsWriteRate(Long iopsWriteRate) { this.iopsWriteRate = iopsWriteRate; } + + public void setIopsWriteRateMax(Long iopsWriteRateMax) { + this.iopsWriteRateMax = iopsWriteRateMax; + } + + public void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength) { + this.iopsWriteRateMaxLength = iopsWriteRateMaxLength; + } } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java index f66d2f82fee..51b5c1f6db8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java @@ -129,18 +129,50 @@ public class ServiceOfferingResponse extends BaseResponse { @Param(description = "bytes read rate of the service offering") private Long bytesReadRate; + @SerializedName("diskBytesReadRateMax") + @Param(description = "burst bytes read rate of the disk offering") + private Long bytesReadRateMax; + + @SerializedName("diskBytesReadRateMaxLength") + @Param(description = "length (in seconds) of the burst") + private Long bytesReadRateMaxLength; + @SerializedName("diskBytesWriteRate") @Param(description = "bytes write rate of the service offering") private Long bytesWriteRate; + @SerializedName("diskBytesWriteRateMax") + @Param(description = "burst bytes write rate of the disk offering") + private Long bytesWriteRateMax; + + @SerializedName("diskBytesWriteRateMaxLength") + @Param(description = "length (in seconds) of the burst") + private Long bytesWriteRateMaxLength; + @SerializedName("diskIopsReadRate") @Param(description = "io requests read rate of the service offering") private Long iopsReadRate; + @SerializedName("diskIopsReadRateMax") + @Param(description = "burst io requests read rate of the disk offering") + private Long iopsReadRateMax; + + @SerializedName("diskIopsReadRateMaxLength") + @Param(description = "length (in second) of the burst") + private Long iopsReadRateMaxLength; + @SerializedName("diskIopsWriteRate") @Param(description = "io requests write rate of the service offering") private Long iopsWriteRate; + @SerializedName("diskIopsWriteRateMax") + @Param(description = "burst io requests write rate of the disk offering") + private Long iopsWriteRateMax; + + @SerializedName("diskIopsWriteRateMaxLength") + @Param(description = "length (in seconds) of the burst") + private Long iopsWriteRateMaxLength; + @SerializedName(ApiConstants.DEPLOYMENT_PLANNER) @Param(description = "deployment strategy used to deploy VM.") private String deploymentPlanner; @@ -356,18 +388,34 @@ public class ServiceOfferingResponse extends BaseResponse { this.bytesReadRate = bytesReadRate; } + public void setBytesReadRateMax(Long bytesReadRateMax) { this.bytesReadRateMax = bytesReadRateMax; } + + public void setBytesReadRateMaxLength(Long bytesReadRateMaxLength) { this.bytesReadRateMaxLength = bytesReadRateMaxLength; } + public void setBytesWriteRate(Long bytesWriteRate) { this.bytesWriteRate = bytesWriteRate; } + public void setBytesWriteRateMax(Long bytesWriteRateMax) { this.bytesWriteRateMax = bytesWriteRateMax; } + + public void setBytesWriteRateMaxLength(Long bytesWriteRateMaxLength) { this.bytesWriteRateMaxLength = bytesWriteRateMaxLength; } + public void setIopsReadRate(Long iopsReadRate) { this.iopsReadRate = iopsReadRate; } + public void setIopsReadRateMax(Long iopsReadRateMax) { this.iopsReadRateMax = iopsReadRateMax; } + + public void setIopsReadRateMaxLength(Long iopsReadRateMaxLength) { this.iopsReadRateMaxLength = iopsReadRateMaxLength; } + public void setIopsWriteRate(Long iopsWriteRate) { this.iopsWriteRate = iopsWriteRate; } + public void setIopsWriteRateMax(Long iopsWriteRateMax) { this.iopsWriteRateMax = iopsWriteRateMax; } + + public void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength) { this.iopsWriteRateMaxLength = iopsWriteRateMaxLength; } + public void setDetails(Map details) { this.details = details; } diff --git a/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java index 509cc3a1be9..2d240c4ad40 100644 --- a/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -46,9 +46,17 @@ public class VolumeObjectTO implements DataTO { private Long deviceId; private Long bytesReadRate; + private Long bytesReadRateMax; + private Long bytesReadRateMaxLength; private Long bytesWriteRate; + private Long bytesWriteRateMax; + private Long bytesWriteRateMaxLength; private Long iopsReadRate; + private Long iopsReadRateMax; + private Long iopsReadRateMaxLength; private Long iopsWriteRate; + private Long iopsWriteRateMax; + private Long iopsWriteRateMaxLength; private DiskCacheMode cacheMode; private Hypervisor.HypervisorType hypervisorType; @@ -75,9 +83,17 @@ public class VolumeObjectTO implements DataTO { format = volume.getFormat(); provisioningType = volume.getProvisioningType(); bytesReadRate = volume.getBytesReadRate(); + bytesReadRateMax = volume.getBytesReadRateMax(); + bytesReadRateMaxLength = volume.getBytesReadRateMaxLength(); bytesWriteRate = volume.getBytesWriteRate(); + bytesWriteRateMax = volume.getBytesWriteRateMax(); + bytesWriteRateMaxLength = volume.getBytesWriteRateMaxLength(); iopsReadRate = volume.getIopsReadRate(); + iopsReadRateMax = volume.getIopsReadRateMax(); + iopsReadRateMaxLength = volume.getIopsReadRateMaxLength(); iopsWriteRate = volume.getIopsWriteRate(); + iopsWriteRateMax = volume.getIopsWriteRateMax(); + iopsWriteRateMaxLength = volume.getIopsWriteRateMaxLength(); cacheMode = volume.getCacheMode(); hypervisorType = volume.getHypervisorType(); setDeviceId(volume.getDeviceId()); @@ -213,6 +229,14 @@ public class VolumeObjectTO implements DataTO { return bytesReadRate; } + public Long getBytesReadRateMax() { return bytesReadRateMax; } + + public void setBytesReadRateMax(Long bytesReadRateMax) { this.bytesReadRateMax = bytesReadRateMax; } + + public Long getBytesReadRateMaxLength() { return bytesReadRateMaxLength; } + + public void setBytesReadRateMaxLength(Long bytesReadRateMaxLength) { this.bytesReadRateMaxLength = bytesReadRateMaxLength; } + public void setBytesWriteRate(Long bytesWriteRate) { this.bytesWriteRate = bytesWriteRate; } @@ -221,6 +245,14 @@ public class VolumeObjectTO implements DataTO { return bytesWriteRate; } + public Long getBytesWriteRateMax() { return bytesWriteRateMax; } + + public void setBytesWriteRateMax(Long bytesWriteRateMax) { this.bytesWriteRateMax = bytesWriteRateMax; } + + public Long getBytesWriteRateMaxLength() { return bytesWriteRateMaxLength; } + + public void setBytesWriteRateMaxLength(Long bytesWriteRateMaxLength) { this.bytesWriteRateMaxLength = bytesWriteRateMaxLength; } + public void setIopsReadRate(Long iopsReadRate) { this.iopsReadRate = iopsReadRate; } @@ -229,6 +261,14 @@ public class VolumeObjectTO implements DataTO { return iopsReadRate; } + public Long getIopsReadRateMax() { return iopsReadRateMax; } + + public void setIopsReadRateMax(Long iopsReadRateMax) { this.iopsReadRateMax = iopsReadRateMax; } + + public Long getIopsReadRateMaxLength() { return iopsReadRateMaxLength; } + + public void setIopsReadRateMaxLength(Long iopsReadRateMaxLength) { this.iopsReadRateMaxLength = iopsReadRateMaxLength; } + public void setIopsWriteRate(Long iopsWriteRate) { this.iopsWriteRate = iopsWriteRate; } @@ -237,6 +277,14 @@ public class VolumeObjectTO implements DataTO { return iopsWriteRate; } + public Long getIopsWriteRateMax() { return iopsWriteRateMax; } + + public void setIopsWriteRateMax(Long iopsWriteRateMax) { this.iopsWriteRateMax = iopsWriteRateMax; } + + public Long getIopsWriteRateMaxLength() { return iopsWriteRateMaxLength; } + + public void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength) { this.iopsWriteRateMaxLength = iopsWriteRateMaxLength; } + public Long getDeviceId() { return deviceId; } diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java index e27b7516868..67942728021 100644 --- a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java +++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java @@ -48,11 +48,27 @@ public interface VolumeInfo extends DataObject, Volume { Long getBytesReadRate(); + Long getBytesReadRateMax(); + + Long getBytesReadRateMaxLength(); + Long getBytesWriteRate(); + Long getBytesWriteRateMax(); + + Long getBytesWriteRateMaxLength(); + Long getIopsReadRate(); + Long getIopsReadRateMax(); + + Long getIopsReadRateMaxLength(); + Long getIopsWriteRate(); + Long getIopsWriteRateMax(); + + Long getIopsWriteRateMaxLength(); + DiskCacheMode getCacheMode(); } diff --git a/engine/schema/src/main/java/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/main/java/com/cloud/storage/DiskOfferingVO.java index 5c898016917..e8e91ea3781 100644 --- a/engine/schema/src/main/java/com/cloud/storage/DiskOfferingVO.java +++ b/engine/schema/src/main/java/com/cloud/storage/DiskOfferingVO.java @@ -106,16 +106,41 @@ public class DiskOfferingVO implements DiskOffering { int sortKey; @Column(name = "bytes_read_rate") - Long bytesReadRate; + private Long bytesReadRate; + + @Column(name = "bytes_read_rate_max") + private Long bytesReadRateMax; + + @Column(name = "bytes_read_rate_max_length") + private Long bytesReadRateMaxLength; @Column(name = "bytes_write_rate") - Long bytesWriteRate; + private Long bytesWriteRate; + + @Column(name = "bytes_write_rate_max") + private Long bytesWriteRateMax; + + @Column(name = "bytes_write_rate_max_length") + private Long bytesWriteRateMaxLength; @Column(name = "iops_read_rate") - Long iopsReadRate; + private Long iopsReadRate; + + @Column(name = "iops_read_rate_max") + private Long iopsReadRateMax; + + @Column(name = "iops_read_rate_max_length") + private Long iopsReadRateMaxLength; @Column(name = "iops_write_rate") - Long iopsWriteRate; + private Long iopsWriteRate; + + @Column(name = "iops_write_rate_max") + private Long iopsWriteRateMax; + + @Column(name = "iops_write_rate_max_length") + private Long iopsWriteRateMaxLength; + @Column(name = "cache_mode", updatable = true, nullable = false) @Enumerated(value = EnumType.STRING) @@ -472,9 +497,9 @@ public class DiskOfferingVO implements DiskOffering { } @Override - public Long getBytesReadRate() { - return bytesReadRate; - } + public Long getBytesReadRate() { return bytesReadRate; } + + @Override public void setBytesWriteRate(Long bytesWriteRate) { @@ -486,6 +511,44 @@ public class DiskOfferingVO implements DiskOffering { return bytesWriteRate; } + @Override + public Long getBytesWriteRateMax() { + return bytesWriteRateMax; + } + + public void setBytesWriteRateMax(Long bytesWriteRateMax) { + this.bytesWriteRateMax = bytesWriteRateMax; + } + + @Override + public Long getBytesWriteRateMaxLength() { + return bytesWriteRateMaxLength; + } + + public void setBytesWriteRateMaxLength(Long bytesWriteRateMaxLength) { + this.bytesWriteRateMaxLength = bytesWriteRateMaxLength; + } + + @Override + public Long getBytesReadRateMax() { + return bytesReadRateMax; + } + + @Override + public void setBytesReadRateMax(Long bytesReadRateMax) { + this.bytesReadRateMax = bytesReadRateMax; + } + + @Override + public Long getBytesReadRateMaxLength() { + return bytesReadRateMaxLength; + } + + @Override + public void setBytesReadRateMaxLength(Long bytesReadRateMaxLength) { + this.bytesReadRateMaxLength = bytesReadRateMaxLength; + } + @Override public void setIopsReadRate(Long iopsReadRate) { this.iopsReadRate = iopsReadRate; @@ -496,6 +559,26 @@ public class DiskOfferingVO implements DiskOffering { return iopsReadRate; } + @Override + public Long getIopsReadRateMax() { + return iopsReadRateMax; + } + + @Override + public void setIopsReadRateMax(Long iopsReadRateMax) { + this.iopsReadRateMax = iopsReadRateMax; + } + + @Override + public Long getIopsReadRateMaxLength() { + return iopsReadRateMaxLength; + } + + @Override + public void setIopsReadRateMaxLength(Long iopsReadRateMaxLength) { + this.iopsReadRateMaxLength = iopsReadRateMaxLength; + } + @Override public void setIopsWriteRate(Long iopsWriteRate) { this.iopsWriteRate = iopsWriteRate; @@ -506,6 +589,26 @@ public class DiskOfferingVO implements DiskOffering { return iopsWriteRate; } + @Override + public Long getIopsWriteRateMax() { + return iopsWriteRateMax; + } + + @Override + public void setIopsWriteRateMax(Long iopsWriteRateMax) { + this.iopsWriteRateMax = iopsWriteRateMax; + } + + @Override + public Long getIopsWriteRateMaxLength() { + return iopsWriteRateMaxLength; + } + + @Override + public void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength) { + this.iopsWriteRateMaxLength = iopsWriteRateMaxLength; + } + @Override public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) { this.hypervisorSnapshotReserve = hypervisorSnapshotReserve; diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41120to41200.sql b/engine/schema/src/main/resources/META-INF/db/schema-41120to41200.sql index cf11d8f16b1..3a99c541001 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41120to41200.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41120to41200.sql @@ -37,7 +37,7 @@ INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, UPDATE `cloud`.`async_job` SET `removed` = now() WHERE `removed` IS NULL; -- PR#1448 update description of 'execute.in.sequence.network.element.commands' parameter to reflect an unused command that has been removed. The removed class command is 'UserDataCommand'. -update `cloud`.`configuration` set description = 'If set to true, DhcpEntryCommand, SavePasswordCommand, VmDataCommand will be synchronized on the agent side. If set to false, these commands become asynchronous. Default value is false.' where name = 'execute.in.sequence.network.element.commands'; +update `cloud`.`configuration` set description = 'If set to true, DhcpEntryCommand, SavePasswordCommand, VmDataCommand will be synchronized on the agent side. If set to false, these commands become asynchronous. Default value is false.' where name = 'execute.in.sequence.network.element.commands'; INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Storage', 'DEFAULT', 'StorageManager', 'kvm.storage.offline.migration.wait', '10800', 'Timeout in seconds for offline (non-live) storage migration to complete on KVM', '10800', null, 'Global', 0); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Storage', 'DEFAULT', 'StorageManager', 'kvm.storage.online.migration.wait', '10800', 'Timeout in seconds for online (live) storage migration to complete on KVM (migrateVirtualMachineWithVolume)', '10800', null, 'Global', 0); @@ -50,5 +50,113 @@ INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervi -- changed fingerprint type to TEXT, it avoids db exception when creating the certificate issue #3123 ALTER TABLE `cloud`.`sslcerts` MODIFY `fingerprint` TEXT; +-- add KVM / qemu io bursting options PR 3133 +alter table `cloud`.`disk_offering` add `bytes_read_rate_max` bigint(20) default null after `bytes_read_rate`; +alter table `cloud`.`disk_offering` add `bytes_read_rate_max_length` bigint(20) default null after `bytes_read_rate_max`; +alter table `cloud`.`disk_offering` add `bytes_write_rate_max` bigint(20) default null after `bytes_write_rate`; +alter table `cloud`.`disk_offering` add `bytes_write_rate_max_length` bigint(20) default null after `bytes_write_rate_max`; +alter table `cloud`.`disk_offering` add `iops_read_rate_max` bigint(20) default null after `iops_read_rate`; +alter table `cloud`.`disk_offering` add `iops_read_rate_max_length` bigint(20) default null after `iops_read_rate_max`; +alter table `cloud`.`disk_offering` add `iops_write_rate_max` bigint(20) default null after `iops_write_rate`; +alter table `cloud`.`disk_offering` add `iops_write_rate_max_length` bigint(20) default null after `iops_write_rate_max`; + +ALTER VIEW `cloud`.`disk_offering_view` AS + SELECT + `disk_offering`.`id` AS `id`, + `disk_offering`.`uuid` AS `uuid`, + `disk_offering`.`name` AS `name`, + `disk_offering`.`display_text` AS `display_text`, + `disk_offering`.`provisioning_type` AS `provisioning_type`, + `disk_offering`.`disk_size` AS `disk_size`, + `disk_offering`.`min_iops` AS `min_iops`, + `disk_offering`.`max_iops` AS `max_iops`, + `disk_offering`.`created` AS `created`, + `disk_offering`.`tags` AS `tags`, + `disk_offering`.`customized` AS `customized`, + `disk_offering`.`customized_iops` AS `customized_iops`, + `disk_offering`.`removed` AS `removed`, + `disk_offering`.`use_local_storage` AS `use_local_storage`, + `disk_offering`.`system_use` AS `system_use`, + `disk_offering`.`hv_ss_reserve` AS `hv_ss_reserve`, + `disk_offering`.`bytes_read_rate` AS `bytes_read_rate`, + `disk_offering`.`bytes_read_rate_max` AS `bytes_read_rate_max`, + `disk_offering`.`bytes_read_rate_max_length` AS `bytes_read_rate_max_length`, + `disk_offering`.`bytes_write_rate` AS `bytes_write_rate`, + `disk_offering`.`bytes_write_rate_max` AS `bytes_write_rate_max`, + `disk_offering`.`bytes_write_rate_max_length` AS `bytes_write_rate_max_length`, + `disk_offering`.`iops_read_rate` AS `iops_read_rate`, + `disk_offering`.`iops_read_rate_max` AS `iops_read_rate_max`, + `disk_offering`.`iops_read_rate_max_length` AS `iops_read_rate_max_length`, + `disk_offering`.`iops_write_rate` AS `iops_write_rate`, + `disk_offering`.`iops_write_rate_max` AS `iops_write_rate_max`, + `disk_offering`.`iops_write_rate_max_length` AS `iops_write_rate_max_length`, + `disk_offering`.`cache_mode` AS `cache_mode`, + `disk_offering`.`sort_key` AS `sort_key`, + `disk_offering`.`type` AS `type`, + `disk_offering`.`display_offering` AS `display_offering`, + `domain`.`id` AS `domain_id`, + `domain`.`uuid` AS `domain_uuid`, + `domain`.`name` AS `domain_name`, + `domain`.`path` AS `domain_path` + FROM + (`disk_offering` + LEFT JOIN `domain` ON ((`disk_offering`.`domain_id` = `domain`.`id`))) + WHERE + (`disk_offering`.`state` = 'ACTIVE'); + + +ALTER VIEW `cloud`.`service_offering_view` AS + SELECT + `service_offering`.`id` AS `id`, + `disk_offering`.`uuid` AS `uuid`, + `disk_offering`.`name` AS `name`, + `disk_offering`.`display_text` AS `display_text`, + `disk_offering`.`provisioning_type` AS `provisioning_type`, + `disk_offering`.`created` AS `created`, + `disk_offering`.`tags` AS `tags`, + `disk_offering`.`removed` AS `removed`, + `disk_offering`.`use_local_storage` AS `use_local_storage`, + `disk_offering`.`system_use` AS `system_use`, + `disk_offering`.`customized_iops` AS `customized_iops`, + `disk_offering`.`min_iops` AS `min_iops`, + `disk_offering`.`max_iops` AS `max_iops`, + `disk_offering`.`hv_ss_reserve` AS `hv_ss_reserve`, + `disk_offering`.`bytes_read_rate` AS `bytes_read_rate`, + `disk_offering`.`bytes_read_rate_max` AS `bytes_read_rate_max`, + `disk_offering`.`bytes_read_rate_max_length` AS `bytes_read_rate_max_length`, + `disk_offering`.`bytes_write_rate` AS `bytes_write_rate`, + `disk_offering`.`bytes_write_rate_max` AS `bytes_write_rate_max`, + `disk_offering`.`bytes_write_rate_max_length` AS `bytes_write_rate_max_length`, + `disk_offering`.`iops_read_rate` AS `iops_read_rate`, + `disk_offering`.`iops_read_rate_max` AS `iops_read_rate_max`, + `disk_offering`.`iops_read_rate_max_length` AS `iops_read_rate_max_length`, + `disk_offering`.`iops_write_rate` AS `iops_write_rate`, + `disk_offering`.`iops_write_rate_max` AS `iops_write_rate_max`, + `disk_offering`.`iops_write_rate_max_length` AS `iops_write_rate_max_length`, + `disk_offering`.`cache_mode` AS `cache_mode`, + `service_offering`.`cpu` AS `cpu`, + `service_offering`.`speed` AS `speed`, + `service_offering`.`ram_size` AS `ram_size`, + `service_offering`.`nw_rate` AS `nw_rate`, + `service_offering`.`mc_rate` AS `mc_rate`, + `service_offering`.`ha_enabled` AS `ha_enabled`, + `service_offering`.`limit_cpu_use` AS `limit_cpu_use`, + `service_offering`.`host_tag` AS `host_tag`, + `service_offering`.`default_use` AS `default_use`, + `service_offering`.`vm_type` AS `vm_type`, + `service_offering`.`sort_key` AS `sort_key`, + `service_offering`.`is_volatile` AS `is_volatile`, + `service_offering`.`deployment_planner` AS `deployment_planner`, + `domain`.`id` AS `domain_id`, + `domain`.`uuid` AS `domain_uuid`, + `domain`.`name` AS `domain_name`, + `domain`.`path` AS `domain_path` + FROM + ((`service_offering` + JOIN `disk_offering` ON ((`service_offering`.`id` = `disk_offering`.`id`))) + LEFT JOIN `domain` ON ((`disk_offering`.`domain_id` = `domain`.`id`))) + WHERE + (`disk_offering`.`state` = 'Active'); + -- PR#2578 New column for listManagementServers API call -ALTER TABLE `mshost` ADD COLUMN `uuid` varchar(40) AFTER `name`; +ALTER TABLE `mshost` ADD COLUMN `uuid` varchar(40) AFTER `name`; \ No newline at end of file diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java index ed9b39823f2..85d95240617 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -207,6 +207,24 @@ public class VolumeObject implements VolumeInfo { return null; } + @Override + public Long getBytesReadRateMax() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getBytesReadRateMax(); + } + return null; + } + + @Override + public Long getBytesReadRateMaxLength() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getBytesReadRateMaxLength(); + } + return null; + } + @Override public Long getBytesWriteRate() { DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); @@ -216,6 +234,24 @@ public class VolumeObject implements VolumeInfo { return null; } + @Override + public Long getBytesWriteRateMax() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getBytesWriteRateMax(); + } + return null; + } + + @Override + public Long getBytesWriteRateMaxLength() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getBytesWriteRateMaxLength(); + } + return null; + } + @Override public Long getIopsReadRate() { DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); @@ -225,6 +261,24 @@ public class VolumeObject implements VolumeInfo { return null; } + @Override + public Long getIopsReadRateMax() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getIopsReadRateMax(); + } + return null; + } + + @Override + public Long getIopsReadRateMaxLength() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getIopsReadRateMaxLength(); + } + return null; + } + @Override public Long getIopsWriteRate() { DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); @@ -234,6 +288,24 @@ public class VolumeObject implements VolumeInfo { return null; } + @Override + public Long getIopsWriteRateMax() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getIopsWriteRateMax(); + } + return null; + } + + @Override + public Long getIopsWriteRateMaxLength() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getIopsWriteRateMaxLength(); + } + return null; + } + @Override public DiskCacheMode getCacheMode() { DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 2e799b1b713..c07b2d93435 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -2384,18 +2384,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (data instanceof VolumeObjectTO) { final VolumeObjectTO volumeObjectTO = (VolumeObjectTO)data; disk.setSerial(diskUuidToSerial(volumeObjectTO.getUuid())); - if (volumeObjectTO.getBytesReadRate() != null && volumeObjectTO.getBytesReadRate() > 0) { - disk.setBytesReadRate(volumeObjectTO.getBytesReadRate()); - } - if (volumeObjectTO.getBytesWriteRate() != null && volumeObjectTO.getBytesWriteRate() > 0) { - disk.setBytesWriteRate(volumeObjectTO.getBytesWriteRate()); - } - if (volumeObjectTO.getIopsReadRate() != null && volumeObjectTO.getIopsReadRate() > 0) { - disk.setIopsReadRate(volumeObjectTO.getIopsReadRate()); - } - if (volumeObjectTO.getIopsWriteRate() != null && volumeObjectTO.getIopsWriteRate() > 0) { - disk.setIopsWriteRate(volumeObjectTO.getIopsWriteRate()); - } + setBurstProperties(volumeObjectTO, disk); + if (volumeObjectTO.getCacheMode() != null) { disk.setCacheMode(DiskDef.DiskCacheMode.valueOf(volumeObjectTO.getCacheMode().toString().toUpperCase())); } @@ -2446,6 +2436,45 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } + private void setBurstProperties(final VolumeObjectTO volumeObjectTO, final DiskDef disk ) { + if (volumeObjectTO.getBytesReadRate() != null && volumeObjectTO.getBytesReadRate() > 0) { + disk.setBytesReadRate(volumeObjectTO.getBytesReadRate()); + } + if (volumeObjectTO.getBytesReadRateMax() != null && volumeObjectTO.getBytesReadRateMax() > 0) { + disk.setBytesReadRateMax(volumeObjectTO.getBytesReadRateMax()); + } + if (volumeObjectTO.getBytesReadRateMaxLength() != null && volumeObjectTO.getBytesReadRateMaxLength() > 0) { + disk.setBytesReadRateMaxLength(volumeObjectTO.getBytesReadRateMaxLength()); + } + if (volumeObjectTO.getBytesWriteRate() != null && volumeObjectTO.getBytesWriteRate() > 0) { + disk.setBytesWriteRate(volumeObjectTO.getBytesWriteRate()); + } + if (volumeObjectTO.getBytesWriteRateMax() != null && volumeObjectTO.getBytesWriteRateMax() > 0) { + disk.setBytesWriteRateMax(volumeObjectTO.getBytesWriteRateMax()); + } + if (volumeObjectTO.getBytesWriteRateMaxLength() != null && volumeObjectTO.getBytesWriteRateMaxLength() > 0) { + disk.setBytesWriteRateMaxLength(volumeObjectTO.getBytesWriteRateMaxLength()); + } + if (volumeObjectTO.getIopsReadRate() != null && volumeObjectTO.getIopsReadRate() > 0) { + disk.setIopsReadRate(volumeObjectTO.getIopsReadRate()); + } + if (volumeObjectTO.getIopsReadRateMax() != null && volumeObjectTO.getIopsReadRateMax() > 0) { + disk.setIopsReadRateMax(volumeObjectTO.getIopsReadRateMax()); + } + if (volumeObjectTO.getIopsReadRateMaxLength() != null && volumeObjectTO.getIopsReadRateMaxLength() > 0) { + disk.setIopsReadRateMaxLength(volumeObjectTO.getIopsReadRateMaxLength()); + } + if (volumeObjectTO.getIopsWriteRate() != null && volumeObjectTO.getIopsWriteRate() > 0) { + disk.setIopsWriteRate(volumeObjectTO.getIopsWriteRate()); + } + if (volumeObjectTO.getIopsWriteRateMax() != null && volumeObjectTO.getIopsWriteRateMax() > 0) { + disk.setIopsWriteRateMax(volumeObjectTO.getIopsWriteRateMax()); + } + if (volumeObjectTO.getIopsWriteRateMaxLength() != null && volumeObjectTO.getIopsWriteRateMaxLength() > 0) { + disk.setIopsWriteRateMaxLength(volumeObjectTO.getIopsWriteRateMaxLength()); + } + } + private void createVif(final LibvirtVMDef vm, final NicTO nic, final String nicAdapter, Map extraConfig) throws InternalErrorException, LibvirtException { if (nic.getType().equals(TrafficType.Guest) && nic.getBroadcastType().equals(BroadcastDomainType.Vsp)) { @@ -2520,7 +2549,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv public synchronized String attachOrDetachDisk(final Connect conn, final boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, - final int devId, final Long bytesReadRate, final Long bytesWriteRate, final Long iopsReadRate, final Long iopsWriteRate, final String cacheMode) throws LibvirtException, InternalErrorException { + final int devId, final Long bytesReadRate, final Long bytesReadRateMax, final Long bytesReadRateMaxLength, final Long bytesWriteRate, final Long bytesWriteRateMax, final Long bytesWriteRateMaxLength, final Long iopsReadRate, final Long iopsReadRateMax, final Long iopsReadRateMaxLength, final Long iopsWriteRate, final Long iopsWriteRateMax, final Long iopsWriteRateMaxLength, final String cacheMode) throws LibvirtException, InternalErrorException { List disks = null; Domain dm = null; DiskDef diskdef = null; @@ -2573,15 +2602,36 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (bytesReadRate != null && bytesReadRate > 0) { diskdef.setBytesReadRate(bytesReadRate); } + if (bytesReadRateMax != null && bytesReadRateMax > 0) { + diskdef.setBytesReadRateMax(bytesReadRateMax); + } + if (bytesReadRateMaxLength != null && bytesReadRateMaxLength > 0) { + diskdef.setBytesReadRateMaxLength(bytesReadRateMaxLength); + } if (bytesWriteRate != null && bytesWriteRate > 0) { diskdef.setBytesWriteRate(bytesWriteRate); } + if (bytesWriteRateMax != null && bytesWriteRateMax > 0) { + diskdef.setBytesWriteRateMax(bytesWriteRateMax); + } + if (bytesWriteRateMaxLength != null && bytesWriteRateMaxLength > 0) { + diskdef.setBytesWriteRateMaxLength(bytesWriteRateMaxLength); + } if (iopsReadRate != null && iopsReadRate > 0) { diskdef.setIopsReadRate(iopsReadRate); } + if (iopsReadRateMax != null && iopsReadRateMax > 0) { + diskdef.setIopsReadRateMax(iopsReadRateMax); + } + if (iopsReadRateMaxLength != null && iopsReadRateMaxLength > 0) { + diskdef.setIopsReadRateMaxLength(iopsReadRateMaxLength); + } if (iopsWriteRate != null && iopsWriteRate > 0) { diskdef.setIopsWriteRate(iopsWriteRate); } + if (iopsWriteRateMax != null && iopsWriteRateMax > 0) { + diskdef.setIopsWriteRateMax(iopsWriteRateMax); + } if (cacheMode != null) { diskdef.setCacheMode(DiskDef.DiskCacheMode.valueOf(cacheMode.toUpperCase())); diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java index d4ca44b093d..97963fd2317 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java @@ -133,21 +133,61 @@ public class LibvirtDomainXMLParser { Long bytesReadRate = Long.parseLong(bytesReadRateStr); def.setBytesReadRate(bytesReadRate); } + String bytesReadRateMaxStr = getTagValue("read_bytes_sec_max", (Element)iotune.item(0)); + if (bytesReadRateMaxStr != null) { + Long bytesReadRateMax = Long.parseLong(bytesReadRateMaxStr); + def.setBytesReadRateMax(bytesReadRateMax); + } + String bytesReadRateMaxLengthStr = getTagValue("read_bytes_sec_max_length", (Element)iotune.item(0)); + if (bytesReadRateMaxLengthStr != null) { + Long bytesReadRateMaxLength = Long.parseLong(bytesReadRateMaxLengthStr); + def.setBytesReadRateMaxLength(bytesReadRateMaxLength); + } String bytesWriteRateStr = getTagValue("write_bytes_sec", (Element)iotune.item(0)); if (bytesWriteRateStr != null) { Long bytesWriteRate = Long.parseLong(bytesWriteRateStr); def.setBytesWriteRate(bytesWriteRate); } + String bytesWriteRateMaxStr = getTagValue("write_bytes_sec_max", (Element)iotune.item(0)); + if (bytesWriteRateMaxStr != null) { + Long bytesWriteRateMax = Long.parseLong(bytesWriteRateMaxStr); + def.setBytesWriteRateMax(bytesWriteRateMax); + } + String bytesWriteRateMaxLengthStr = getTagValue("write_bytes_sec_max_length", (Element)iotune.item(0)); + if (bytesWriteRateMaxLengthStr != null) { + Long bytesWriteRateMaxLength = Long.parseLong(bytesWriteRateMaxLengthStr); + def.setBytesWriteRateMaxLength(bytesWriteRateMaxLength); + } String iopsReadRateStr = getTagValue("read_iops_sec", (Element)iotune.item(0)); if (iopsReadRateStr != null) { Long iopsReadRate = Long.parseLong(iopsReadRateStr); def.setIopsReadRate(iopsReadRate); } + String iopsReadRateMaxStr = getTagValue("read_iops_sec_max", (Element)iotune.item(0)); + if (iopsReadRateMaxStr != null) { + Long iopsReadRateMax = Long.parseLong(iopsReadRateMaxStr); + def.setIopsReadRateMax(iopsReadRateMax); + } + String iopsReadRateMaxLengthStr = getTagValue("read_iops_sec_max_length", (Element)iotune.item(0)); + if (iopsReadRateMaxLengthStr != null) { + Long iopsReadRateMaxLength = Long.parseLong(iopsReadRateMaxLengthStr); + def.setIopsReadRateMaxLength(iopsReadRateMaxLength); + } String iopsWriteRateStr = getTagValue("write_iops_sec", (Element)iotune.item(0)); if (iopsWriteRateStr != null) { Long iopsWriteRate = Long.parseLong(iopsWriteRateStr); def.setIopsWriteRate(iopsWriteRate); } + String iopsWriteRateMaxStr = getTagValue("write_iops_sec_max", (Element)iotune.item(0)); + if (iopsWriteRateMaxStr != null) { + Long iopsWriteRateMax = Long.parseLong(iopsWriteRateMaxStr); + def.setIopsWriteRateMax(iopsWriteRateMax); + } + String iopsWriteRateMaxLengthStr = getTagValue("write_iops_sec_max_length", (Element)iotune.item(0)); + if (iopsWriteRateMaxLengthStr != null) { + Long iopsWriteRateMaxLength = Long.parseLong(iopsWriteRateMaxLengthStr); + def.setIopsWriteRateMaxLength(iopsWriteRateMaxLength); + } } diskDefs.add(def); diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index 1f1c3a051a1..4f7732b9a3d 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -581,9 +581,17 @@ public class LibvirtVMDef { private boolean _shareable = false; private boolean _deferAttach = false; private Long _bytesReadRate; + private Long _bytesReadRateMax; + private Long _bytesReadRateMaxLength; private Long _bytesWriteRate; + private Long _bytesWriteRateMax; + private Long _bytesWriteRateMaxLength; private Long _iopsReadRate; + private Long _iopsReadRateMax; + private Long _iopsReadRateMaxLength; private Long _iopsWriteRate; + private Long _iopsWriteRateMax; + private Long _iopsWriteRateMaxLength; private DiskCacheMode _diskCacheMode; private String _serial; private boolean qemuDriver = true; @@ -784,18 +792,50 @@ public class LibvirtVMDef { _bytesReadRate = bytesReadRate; } + public void setBytesReadRateMax(Long bytesReadRateMax) { + _bytesReadRateMax = bytesReadRateMax; + } + + public void setBytesReadRateMaxLength(Long bytesReadRateLength) { + _bytesReadRateMaxLength = bytesReadRateLength; + } + public void setBytesWriteRate(Long bytesWriteRate) { _bytesWriteRate = bytesWriteRate; } + public void setBytesWriteRateMax(Long bytesWriteRateMax) { + _bytesWriteRateMax = bytesWriteRateMax; + } + + public void setBytesWriteRateMaxLength(Long bytesWriteRateMaxLength) { + _bytesWriteRateMaxLength = bytesWriteRateMaxLength; + } + public void setIopsReadRate(Long iopsReadRate) { _iopsReadRate = iopsReadRate; } + public void setIopsReadRateMax(Long iopsReadRateMax) { + _iopsReadRateMax = iopsReadRateMax; + } + + public void setIopsReadRateMaxLength(Long iopsReadRateMaxLength) { + _iopsReadRateMaxLength = iopsReadRateMaxLength; + } + public void setIopsWriteRate(Long iopsWriteRate) { _iopsWriteRate = iopsWriteRate; } + public void setIopsWriteRateMax(Long iopsWriteRateMax) { + _iopsWriteRateMax = iopsWriteRateMax; + } + + public void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength) { + _iopsWriteRateMaxLength = iopsWriteRateMaxLength; + } + public void setCacheMode(DiskCacheMode cacheMode) { _diskCacheMode = cacheMode; } @@ -891,6 +931,31 @@ public class LibvirtVMDef { diskBuilder.append("" + _iopsReadRate + "\n"); if ((_iopsWriteRate != null) && (_iopsWriteRate > 0)) diskBuilder.append("" + _iopsWriteRate + "\n"); + if (s_qemuVersion >= 2004000) { + if (_bytesReadRateMax != null && _bytesReadRateMax > 0 ) { + diskBuilder.append("" + _bytesReadRateMax + "\n"); + } + if (_bytesWriteRateMax != null && _bytesWriteRateMax > 0) { + diskBuilder.append("" + _bytesWriteRateMax + "\n"); + } + if (_iopsReadRateMax != null && _iopsReadRateMax > 0) + diskBuilder.append("" + _iopsReadRateMax + "\n"); + if (_iopsWriteRateMax != null && _iopsWriteRateMax > 0) + diskBuilder.append("" + _iopsWriteRateMax + "\n"); + } + if (s_qemuVersion >= 2006000) { + if (_bytesReadRateMaxLength != null && _bytesReadRateMaxLength > 0) { + diskBuilder.append("" + _bytesReadRateMaxLength + "\n"); + } + if (_bytesWriteRateMaxLength != null && _bytesWriteRateMaxLength > 0) { + diskBuilder.append("" + _bytesWriteRateMaxLength + "\n"); + } + if (_iopsReadRateMaxLength != null && _iopsReadRateMaxLength > 0) + diskBuilder.append("" + _iopsReadRateMaxLength + "\n"); + if (_iopsWriteRateMaxLength != null && _iopsWriteRateMaxLength > 0) + diskBuilder.append("" + _iopsWriteRateMaxLength + "\n"); + } + diskBuilder.append("\n"); } diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index e7e0ea26b60..83a7a12d22b 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -1167,7 +1167,10 @@ public class KVMStorageProcessor implements StorageProcessor { } protected synchronized String attachOrDetachDisk(final Connect conn, final boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final int devId, final String serial, - final Long bytesReadRate, final Long bytesWriteRate, final Long iopsReadRate, final Long iopsWriteRate) throws LibvirtException, InternalErrorException { + final Long bytesReadRate, final Long bytesReadRateMax, final Long bytesReadRateMaxLength, + final Long bytesWriteRate, final Long bytesWriteRateMax, final Long bytesWriteRateMaxLength, + final Long iopsReadRate, final Long iopsReadRateMax, final Long iopsReadRateMaxLength, + final Long iopsWriteRate, final Long iopsWriteRateMax, final Long iopsWriteRateMaxLength) throws LibvirtException, InternalErrorException { List disks = null; Domain dm = null; DiskDef diskdef = null; @@ -1244,15 +1247,39 @@ public class KVMStorageProcessor implements StorageProcessor { if ((bytesReadRate != null) && (bytesReadRate > 0)) { diskdef.setBytesReadRate(bytesReadRate); } + if ((bytesReadRateMax != null) && (bytesReadRateMax > 0)) { + diskdef.setBytesReadRateMax(bytesReadRateMax); + } + if ((bytesReadRateMaxLength != null) && (bytesReadRateMaxLength > 0)) { + diskdef.setBytesReadRateMaxLength(bytesReadRateMaxLength); + } if ((bytesWriteRate != null) && (bytesWriteRate > 0)) { diskdef.setBytesWriteRate(bytesWriteRate); } + if ((bytesWriteRateMax != null) && (bytesWriteRateMax > 0)) { + diskdef.setBytesWriteRateMax(bytesWriteRateMax); + } + if ((bytesWriteRateMaxLength != null) && (bytesWriteRateMaxLength > 0)) { + diskdef.setBytesWriteRateMaxLength(bytesWriteRateMaxLength); + } if ((iopsReadRate != null) && (iopsReadRate > 0)) { diskdef.setIopsReadRate(iopsReadRate); } + if ((iopsReadRateMax != null) && (iopsReadRateMax > 0)) { + diskdef.setIopsReadRateMax(iopsReadRateMax); + } + if ((iopsReadRateMaxLength != null) && (iopsReadRateMaxLength > 0)) { + diskdef.setIopsReadRateMaxLength(iopsReadRateMaxLength); + } if ((iopsWriteRate != null) && (iopsWriteRate > 0)) { diskdef.setIopsWriteRate(iopsWriteRate); } + if ((iopsWriteRateMax != null) && (iopsWriteRateMax > 0)) { + diskdef.setIopsWriteRateMax(iopsWriteRateMax); + } + if ((iopsWriteRateMaxLength != null) && (iopsWriteRateMaxLength > 0)) { + diskdef.setIopsWriteRateMaxLength(iopsWriteRateMaxLength); + } } final String xml = diskdef.toString(); @@ -1278,7 +1305,11 @@ public class KVMStorageProcessor implements StorageProcessor { final KVMPhysicalDisk phyDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath()); - attachOrDetachDisk(conn, true, vmName, phyDisk, disk.getDiskSeq().intValue(), serial, vol.getBytesReadRate(), vol.getBytesWriteRate(), vol.getIopsReadRate(), vol.getIopsWriteRate()); + attachOrDetachDisk(conn, true, vmName, phyDisk, disk.getDiskSeq().intValue(), serial, + vol.getBytesReadRate(), vol.getBytesReadRateMax(), vol.getBytesReadRateMaxLength(), + vol.getBytesWriteRate(), vol.getBytesWriteRateMax(), vol.getBytesWriteRateMaxLength(), + vol.getIopsReadRate(), vol.getIopsReadRateMax(), vol.getIopsReadRateMaxLength(), + vol.getIopsWriteRate(), vol.getIopsWriteRateMax(), vol.getIopsWriteRateMaxLength()); return new AttachAnswer(disk); } catch (final LibvirtException e) { @@ -1303,7 +1334,11 @@ public class KVMStorageProcessor implements StorageProcessor { final KVMPhysicalDisk phyDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath()); - attachOrDetachDisk(conn, false, vmName, phyDisk, disk.getDiskSeq().intValue(), serial, vol.getBytesReadRate(), vol.getBytesWriteRate(), vol.getIopsReadRate(), vol.getIopsWriteRate()); + attachOrDetachDisk(conn, false, vmName, phyDisk, disk.getDiskSeq().intValue(), serial, + vol.getBytesReadRate(), vol.getBytesReadRateMax(), vol.getBytesReadRateMaxLength(), + vol.getBytesWriteRate(), vol.getBytesWriteRateMax(), vol.getBytesWriteRateMaxLength(), + vol.getIopsReadRate(), vol.getIopsReadRateMax(), vol.getIopsReadRateMaxLength(), + vol.getIopsWriteRate(), vol.getIopsWriteRateMax(), vol.getIopsWriteRateMaxLength()); storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath()); diff --git a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java index e127ed350e2..414bc04892f 100644 --- a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java +++ b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java @@ -135,6 +135,59 @@ public class LibvirtVMDefTest extends TestCase { assertEquals(xmlDef, expectedXml); } + public void testDiskDefWithBurst() { + String filePath = "/var/lib/libvirt/images/disk.qcow2"; + String diskLabel = "vda"; + + DiskDef disk = new DiskDef(); + DiskDef.DiskBus bus = DiskDef.DiskBus.VIRTIO; + DiskDef.DiskFmtType type = DiskDef.DiskFmtType.QCOW2; + disk.defFileBasedDisk(filePath, diskLabel, bus, type); + + + Long iopsReadRate = 500L; + Long iopsReadRateMax = 2000L; + Long iopsReadRateMaxLength = 120L; + Long iopsWriteRate = 501L; + Long iopsWriteRateMax = 2001L; + Long iopsWriteRateMaxLength = 121L; + Long bytesReadRate = 1000L; + Long bytesReadRateMax = 2500L; + Long bytesReadRateMaxLength = 122L; + Long bytesWriteRate = 1001L; + Long bytesWriteRateMax = 2501L; + Long bytesWriteRateMaxLength = 123L; + + + disk.setIopsReadRate(iopsReadRate); + disk.setIopsReadRateMax(iopsReadRateMax); + disk.setIopsReadRateMaxLength(iopsReadRateMaxLength); + disk.setIopsWriteRate(iopsWriteRate); + disk.setIopsWriteRateMax(iopsWriteRateMax); + disk.setIopsWriteRateMaxLength(iopsWriteRateMaxLength); + disk.setBytesReadRate(bytesReadRate); + disk.setBytesReadRateMax(bytesReadRateMax); + disk.setBytesReadRateMaxLength(bytesReadRateMaxLength); + disk.setBytesWriteRate(bytesWriteRate); + disk.setBytesWriteRateMax(bytesWriteRateMax); + disk.setBytesWriteRateMaxLength(bytesWriteRateMaxLength); + + LibvirtVMDef.setGlobalQemuVersion(2006000L); + LibvirtVMDef.setGlobalLibvirtVersion(9008L); + + String xmlDef = disk.toString(); + String expectedXml = "\n\n" + + "\n\n" + + "\n"+bytesReadRate+"\n"+bytesWriteRate+"\n" + + ""+iopsReadRate+"\n"+iopsWriteRate+"\n" + + ""+bytesReadRateMax+"\n"+bytesWriteRateMax+"\n" + + ""+iopsReadRateMax+"\n"+iopsWriteRateMax+"\n" + + ""+bytesReadRateMaxLength+"\n"+bytesWriteRateMaxLength+"\n" + + ""+iopsReadRateMaxLength+"\n"+iopsWriteRateMaxLength+"\n\n\n"; + + assertEquals(xmlDef, expectedXml); + } + public void testHypervEnlightDef() { LibvirtVMDef.FeaturesDef featuresDef = new LibvirtVMDef.FeaturesDef(); LibvirtVMDef.HyperVEnlightenmentFeatureDef hyperVEnlightenmentFeatureDef = new LibvirtVMDef.HyperVEnlightenmentFeatureDef(); diff --git a/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java index 9ca44872fec..b46fbd0deb6 100644 --- a/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java @@ -73,9 +73,17 @@ public class DiskOfferingJoinDaoImpl extends GenericDaoBase details, final Boolean isCustomizedIops, Long minIops, Long maxIops, - Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate, final Integer hypervisorSnapshotReserve) { + Long bytesReadRate, Long bytesReadRateMax, Long bytesReadRateMaxLength, + Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength, + Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength, + Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength, + final Integer hypervisorSnapshotReserve) { // Check if user exists in the system final User user = _userDao.findById(userId); @@ -2368,38 +2376,29 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati limitResourceUse, volatileVm, displayText, typedProvisioningType, localStorageRequired, false, tags, isSystem, vmType, domainId, hostTag, deploymentPlanner); - if (isCustomizedIops != null) { - bytesReadRate = null; - bytesWriteRate = null; - iopsReadRate = null; - iopsWriteRate = null; - - if (isCustomizedIops) { + if (Boolean.TRUE.equals(isCustomizedIops)) { minIops = null; maxIops = null; + } else { + if (minIops == null && maxIops == null) { + minIops = 0L; + maxIops = 0L; } else { - if (minIops == null && maxIops == null) { - minIops = 0L; + if (minIops == null || minIops <= 0) { + throw new InvalidParameterValueException("The min IOPS must be greater than 0."); + } + + if (maxIops == null) { maxIops = 0L; - } else { - if (minIops == null || minIops <= 0) { - throw new InvalidParameterValueException("The min IOPS must be greater than 0."); - } + } - if (maxIops == null) { - maxIops = 0L; - } - - if (minIops > maxIops) { - throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS."); - } + if (minIops > maxIops) { + throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS."); } } - } else { - minIops = null; - maxIops = null; } + offering.setCustomizedIops(isCustomizedIops); offering.setMinIops(minIops); offering.setMaxIops(maxIops); @@ -2407,15 +2406,39 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (bytesReadRate != null && bytesReadRate > 0) { offering.setBytesReadRate(bytesReadRate); } + if (bytesReadRateMax != null && bytesReadRateMax > 0) { + offering.setBytesReadRateMax(bytesReadRateMax); + } + if (bytesReadRateMaxLength != null && bytesReadRateMaxLength > 0) { + offering.setBytesReadRateMaxLength(bytesReadRateMaxLength); + } if (bytesWriteRate != null && bytesWriteRate > 0) { offering.setBytesWriteRate(bytesWriteRate); } + if (bytesWriteRateMax != null && bytesWriteRateMax > 0) { + offering.setBytesWriteRateMax(bytesWriteRateMax); + } + if (bytesWriteRateMaxLength != null && bytesWriteRateMaxLength > 0) { + offering.setBytesWriteRateMaxLength(bytesWriteRateMaxLength); + } if (iopsReadRate != null && iopsReadRate > 0) { offering.setIopsReadRate(iopsReadRate); } + if (iopsReadRateMax != null && iopsReadRateMax > 0) { + offering.setIopsReadRateMax(iopsReadRateMax); + } + if (iopsReadRateMaxLength != null && iopsReadRateMaxLength > 0) { + offering.setIopsReadRateMaxLength(iopsReadRateMaxLength); + } if (iopsWriteRate != null && iopsWriteRate > 0) { offering.setIopsWriteRate(iopsWriteRate); } + if (iopsWriteRateMax != null && iopsWriteRateMax > 0) { + offering.setIopsWriteRateMax(iopsWriteRateMax); + } + if (iopsWriteRateMaxLength != null && iopsWriteRateMaxLength > 0) { + offering.setIopsWriteRateMaxLength(iopsWriteRateMaxLength); + } if (hypervisorSnapshotReserve != null && hypervisorSnapshotReserve < 0) { throw new InvalidParameterValueException("If provided, Hypervisor Snapshot Reserve must be greater than or equal to 0."); @@ -2553,7 +2576,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati protected DiskOfferingVO createDiskOffering(final Long userId, final Long domainId, final String name, final String description, final String provisioningType, final Long numGibibytes, String tags, boolean isCustomized, final boolean localStorageRequired, final boolean isDisplayOfferingEnabled, final Boolean isCustomizedIops, Long minIops, Long maxIops, - Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate, + Long bytesReadRate, Long bytesReadRateMax, Long bytesReadRateMaxLength, + Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength, + Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength, + Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength, final Integer hypervisorSnapshotReserve) { long diskSize = 0;// special case for custom disk offerings if (numGibibytes != null && numGibibytes <= 0) { @@ -2571,38 +2597,29 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati isCustomized = true; } - if (isCustomizedIops != null) { - bytesReadRate = null; - bytesWriteRate = null; - iopsReadRate = null; - iopsWriteRate = null; - - if (isCustomizedIops) { - minIops = null; - maxIops = null; - } else { - if (minIops == null && maxIops == null) { - minIops = 0L; - maxIops = 0L; - } else { - if (minIops == null || minIops <= 0) { - throw new InvalidParameterValueException("The min IOPS must be greater than 0."); - } - - if (maxIops == null) { - maxIops = 0L; - } - - if (minIops > maxIops) { - throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS."); - } - } - } - } else { + if (Boolean.TRUE.equals(isCustomizedIops)) { minIops = null; maxIops = null; + } else { + if (minIops == null && maxIops == null) { + minIops = 0L; + maxIops = 0L; + } else { + if (minIops == null || minIops <= 0) { + throw new InvalidParameterValueException("The min IOPS must be greater than 0."); + } + + if (maxIops == null) { + maxIops = 0L; + } + + if (minIops > maxIops) { + throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS."); + } + } } + // Check if user exists in the system final User user = _userDao.findById(userId); if (user == null || user.getRemoved() != null) { @@ -2632,15 +2649,39 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (bytesReadRate != null && bytesReadRate > 0) { newDiskOffering.setBytesReadRate(bytesReadRate); } + if (bytesReadRateMax != null && bytesReadRateMax > 0) { + newDiskOffering.setBytesReadRateMax(bytesReadRateMax); + } + if (bytesReadRateMaxLength != null && bytesReadRateMaxLength > 0) { + newDiskOffering.setBytesReadRateMaxLength(bytesReadRateMaxLength); + } if (bytesWriteRate != null && bytesWriteRate > 0) { newDiskOffering.setBytesWriteRate(bytesWriteRate); } + if (bytesWriteRateMax != null && bytesWriteRateMax > 0) { + newDiskOffering.setBytesWriteRateMax(bytesWriteRateMax); + } + if (bytesWriteRateMaxLength != null && bytesWriteRateMaxLength > 0) { + newDiskOffering.setBytesWriteRateMaxLength(bytesWriteRateMaxLength); + } if (iopsReadRate != null && iopsReadRate > 0) { newDiskOffering.setIopsReadRate(iopsReadRate); } + if (iopsReadRateMax != null && iopsReadRateMax > 0) { + newDiskOffering.setIopsReadRateMax(iopsReadRateMax); + } + if (iopsReadRateMaxLength != null && iopsReadRateMaxLength > 0) { + newDiskOffering.setIopsReadRateMaxLength(iopsReadRateMaxLength); + } if (iopsWriteRate != null && iopsWriteRate > 0) { newDiskOffering.setIopsWriteRate(iopsWriteRate); } + if (iopsWriteRateMax != null && iopsWriteRateMax > 0) { + newDiskOffering.setIopsWriteRateMax(iopsWriteRateMax); + } + if (iopsWriteRateMaxLength != null && iopsWriteRateMaxLength > 0) { + newDiskOffering.setIopsWriteRateMaxLength(iopsWriteRateMaxLength); + } if (hypervisorSnapshotReserve != null && hypervisorSnapshotReserve < 0) { throw new InvalidParameterValueException("If provided, Hypervisor Snapshot Reserve must be greater than or equal to 0."); @@ -2698,15 +2739,25 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati final Long minIops = cmd.getMinIops(); final Long maxIops = cmd.getMaxIops(); final Long bytesReadRate = cmd.getBytesReadRate(); + final Long bytesReadRateMax = cmd.getBytesReadRateMax(); + final Long bytesReadRateMaxLength = cmd.getBytesReadRateMaxLength(); final Long bytesWriteRate = cmd.getBytesWriteRate(); + final Long bytesWriteRateMax = cmd.getBytesWriteRateMax(); + final Long bytesWriteRateMaxLength = cmd.getBytesWriteRateMaxLength(); final Long iopsReadRate = cmd.getIopsReadRate(); + final Long iopsReadRateMax = cmd.getIopsReadRateMax(); + final Long iopsReadRateMaxLength = cmd.getIopsReadRateMaxLength(); final Long iopsWriteRate = cmd.getIopsWriteRate(); + final Long iopsWriteRateMax = cmd.getIopsWriteRateMax(); + final Long iopsWriteRateMaxLength = cmd.getIopsWriteRateMaxLength(); final Integer hypervisorSnapshotReserve = cmd.getHypervisorSnapshotReserve(); final Long userId = CallContext.current().getCallingUserId(); return createDiskOffering(userId, domainId, name, description, provisioningType, numGibibytes, tags, isCustomized, localStorageRequired, isDisplayOfferingEnabled, isCustomizedIops, minIops, - maxIops, bytesReadRate, bytesWriteRate, iopsReadRate, iopsWriteRate, hypervisorSnapshotReserve); + maxIops, bytesReadRate, bytesReadRateMax, bytesReadRateMaxLength, bytesWriteRate, bytesWriteRateMax, bytesWriteRateMaxLength, + iopsReadRate, iopsReadRateMax, iopsReadRateMaxLength, iopsWriteRate, iopsWriteRateMax, iopsWriteRateMaxLength, + hypervisorSnapshotReserve); } @Override diff --git a/test/integration/smoke/test_disk_offerings.py b/test/integration/smoke/test_disk_offerings.py index fed0690c69a..af7ba6a2ccc 100644 --- a/test/integration/smoke/test_disk_offerings.py +++ b/test/integration/smoke/test_disk_offerings.py @@ -5,9 +5,9 @@ # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -171,6 +171,58 @@ class TestCreateDiskOffering(cloudstackTestCase): ) return + @attr(hypervisor="kvm") + @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "simulator", "smoke"]) + def test_05_create_burst_type_disk_offering(self): + """Test to create a disk offering with io bursting enabled""" + + # Validate the following: + # 1. createDiskOfferings should return valid info for new offering with io burst settings + # 2. The Cloud Database contains the valid information + + burstBits = {} + for key in self.services["ioburst"]: + if str(key).startswith("bytes") or str(key).startswith("iops"): + burstBits[key] = self.services["ioburst"][key] + + disk_offering = DiskOffering.create( + self.apiclient, + self.services["ioburst"], + None, + False, + None, + **burstBits + ) + self.cleanup.append(disk_offering) + + self.debug("Created Disk offering with ID: %s" % disk_offering.id) + + list_disk_response = list_disk_offering( + self.apiclient, + id=disk_offering.id + ) + self.assertEqual( + isinstance(list_disk_response, list), + True, + "Check list response returns a valid list" + ) + self.assertNotEqual( + len(list_disk_response), + 0, + "Check Disk offering is created" + ) + disk_response = list_disk_response[0] + + for key in burstBits: + k = str(key) + mapped = 'disk' + k[:1].upper() + k[1:] + self.assertEqual( + disk_response[mapped], + self.services["ioburst"][key], + "Check " + str(key) + " in createServiceOffering" + ) + return + class TestDiskOfferings(cloudstackTestCase): def setUp(self): @@ -193,7 +245,7 @@ class TestDiskOfferings(cloudstackTestCase): testClient = super(TestDiskOfferings, cls).getClsTestClient() cls.apiclient = cls.testClient.getApiClient() cls.services = cls.testClient.getParsedTestDataConfig() - + cls.disk_offering_1 = DiskOffering.create( cls.apiclient, cls.services["disk_offering"] @@ -227,9 +279,9 @@ class TestDiskOfferings(cloudstackTestCase): random_displaytext = random_gen() random_name = random_gen() - self.debug("Updating Disk offering with ID: %s" % + self.debug("Updating Disk offering with ID: %s" % self.disk_offering_1.id) - + cmd = updateDiskOffering.updateDiskOfferingCmd() cmd.id = self.disk_offering_1.id cmd.displaytext = random_displaytext @@ -276,7 +328,7 @@ class TestDiskOfferings(cloudstackTestCase): """ self.disk_offering_2.delete(self.apiclient) - self.debug("Deleted Disk offering with ID: %s" % + self.debug("Deleted Disk offering with ID: %s" % self.disk_offering_2.id) list_disk_response = list_disk_offering( self.apiclient, diff --git a/test/integration/smoke/test_service_offerings.py b/test/integration/smoke/test_service_offerings.py index 9d4650b88a3..61d83b90282 100644 --- a/test/integration/smoke/test_service_offerings.py +++ b/test/integration/smoke/test_service_offerings.py @@ -129,6 +129,73 @@ class TestCreateServiceOffering(cloudstackTestCase): "Check name in createServiceOffering" ) return + @attr( + tags=[ + "advanced", + "advancedns", + "smoke", + "basic", + "eip", + "sg"], + required_hardware="false") + def test_02_create_iops_offering(self): + """Test to create service io burst offering""" + + # Validate the following: + # 1. createServiceOfferings should return a valid information + # for newly created offering + # 2. The Cloud Database contains the valid information + + + + svcs = self.services["service_offerings"]["tiny"] + kws = {} + + for key in self.services["ioburst"]: + if str(key).startswith("bytes") or str(key).startswith("iops"): + kws[key] = self.services["ioburst"][key] + else: + svcs[key] = self.services["ioburst"][key] + + service_offering = ServiceOffering.create( + self.apiclient, + svcs, + None, + None, + **kws + ) + self.cleanup.append(service_offering) + + self.debug( + "Created service offering with ID: %s" % + service_offering.id) + + list_service_response = list_service_offering( + self.apiclient, + id=service_offering.id + ) + self.assertEqual( + isinstance(list_service_response, list), + True, + "Check list response returns a valid list" + ) + + self.assertNotEqual( + len(list_service_response), + 0, + "Check Service offering is created" + ) + + for key in kws: + k = str(key) + mapped = 'disk' + k[:1].upper() + k[1:] + self.assertEqual( + list_service_response[0][mapped], + kws[key], + "Check " + str(key) + " => " + str(mapped) + " in createServiceOffering" + ) + + return class TestServiceOfferings(cloudstackTestCase): diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py index 7c5ce5c503f..929741b7b0d 100644 --- a/tools/marvin/marvin/config/test_data.py +++ b/tools/marvin/marvin/config/test_data.py @@ -1239,6 +1239,24 @@ test_data = { "disksize": 1, # in GB "provisioningtype": "fat" }, + "ioburst": { + "name": "io burst disk offering", + "displaytext": "io burst disk offering", + "disksize": 1, + "provisioningtype": "sparse", + "bytesReadRate": 500, + "bytesReadRateMax": 2000, + "bytesReadRateMaxLength": 120, + "bytesWriteRate": 501, + "bytesWriteRateMax": 2001, + "bytesWriteRateMaxLength": 121, + "iopsReadRate": 1000, + "iopsReadRateMax": 2500, + "iopsReadRateMaxLength": 122, + "iopsWriteRate": 1001, + "iopsWriteRateMax": 2501, + "iopsWriteRateMaxLength": 123 + }, "sparse_disk_offering": { "displaytext": "Sparse", "name": "Sparse", diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index 178eabe60d1..29e61f94bb3 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -2219,7 +2219,7 @@ class DiskOffering: self.__dict__.update(items) @classmethod - def create(cls, apiclient, services, tags=None, custom=False, domainid=None): + def create(cls, apiclient, services, tags=None, custom=False, domainid=None, **kwargs): """Create Disk offering""" cmd = createDiskOffering.createDiskOfferingCmd() cmd.displaytext = services["displaytext"] @@ -2258,6 +2258,7 @@ class DiskOffering: if "provisioningtype" in services: cmd.provisioningtype = services["provisioningtype"] + [setattr(cmd, k, v) for k, v in kwargs.items()] return DiskOffering(apiclient.createDiskOffering(cmd).__dict__) def delete(self, apiclient):