Skip to content

Commit

Permalink
Added support for storpool_qos service (#8755)
Browse files Browse the repository at this point in the history
  • Loading branch information
slavkap committed Aug 29, 2024
1 parent 2a1db67 commit 12d9c26
Show file tree
Hide file tree
Showing 11 changed files with 1,021 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.cloudstack.storage.command.CommandResult;

import com.cloud.host.Host;
import com.cloud.offering.DiskOffering;
import com.cloud.storage.StoragePool;
import com.cloud.storage.Volume;
import com.cloud.storage.Storage.StoragePoolType;
Expand Down Expand Up @@ -199,4 +200,9 @@ default boolean zoneWideVolumesAvailableWithoutClusterMotion() {
default long getVolumeSizeRequiredOnPool(long volumeSize, Long templateSize, boolean isEncryptionRequired) {
return volumeSize;
}
default boolean informStorageForDiskOfferingChange() {
return false;
}

default void updateStorageWithTheNewDiskOffering(Volume volume, DiskOffering newDiskOffering) {}
}
40 changes: 40 additions & 0 deletions plugins/storage/volume/storpool/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,46 @@ corresponding system disk offering.

CloudStack has no way to specify max BW. Do they want to be able to specify max BW only is sufficient.

================================================================================

StorPool provides the ‘storpool_qos’ service ([QoS user guide](https://kb.storpool.com/storpool_misc/qos.html#storpool-qos-user-guide)) that tracks and configures the storage tier for all volumes based on a specifically provided `qc` tag specifying the storage tier for each volume.

To manage the QoS limits with a `qc` tag, you have to add a `qc` tag resource detail to each disk offering to which a tier should be applied, with a key `SP_QOSCLASS` and the value from the configuration file for the `storpool_qos` service:

add resourcedetail resourceid={diskofferingid} details[0].key=SP_QOSCLASS details[0].value={the name of the tier from the config} resourcetype=DiskOffering

To change the tier via CloudStack, you can use the CloudStack API call `changeOfferingForVolume`. The size is required, but the user could use the current volume size. Example:

change offeringforvolume id={The UUID of the Volume} diskofferingid={The UUID of the disk offering} size={The current or a new size for the volume}

Users who were using the offerings to change the StorPool template via the `SP_TEMPLATE` detail, will continue to have this functionality but should use `changeOfferingForVolume` API call instead of:
- `resizeVolume` API call for DATA disk
- `scaleVirtualMachine` API call for ROOT disk


If the disk offering has both `SP_TEMPLATE` and `SP_QOSCLASS` defined, the `SP_QOSCLASS` detail will be prioritised, setting the volume’s QoS using the respective ‘qc’ tag value. In case the QoS for a volume is changed manually, the ‘storpool_qos’ service will automatically reset the QoS limits following the ‘qc’ tag value once per minute.

<h4>Usage</h4>

Creating Disk Offering for each tier.

Go to Service Offerings > Disk Offering > Add disk offering.

Add disk offering detail with API call in CloudStack CLI.

add resourcedetail resourcetype=diskoffering resourceid=$UUID details[0].key=SP_QOSCLASS details[0].value=$Tier Name


Creating VM with QoS

Deploy virtual machine: Go to Compute> Instances> Add Instances.
- For the ROOT volume, choose the option `Override disk offering`. This will set the required `qc` tag from the disk offering (DO) detail.

Creating DATA disk with QoS
- Create volume via GUI/CLI and choose a disk offering which has the required `SP_QOSCLASS` detail

To update the tier of a ROOT/DATA volume go to Storage> Volumes and select the Volume and click on the Change disk offering for the volume in the upper right corner.

## Supported operations for Volume encryption

Supported Virtual machine operations - live migration of VM to another host, virtual machine snapshots (group snapshot without memory), revert VM snapshot, delete VM snapshot
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// 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
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.apache.cloudstack.storage.datastore.api;

import java.io.Serializable;
import java.util.Map;

public class StorPoolVolumeDef implements Serializable {

private static final long serialVersionUID = 1L;
private transient String name;
private Long size;
private Map<String, String> tags;
private String parent;
private Long iops;
private String template;
private String baseOn;
private String rename;
private Boolean shrinkOk;

public StorPoolVolumeDef() {
}

public StorPoolVolumeDef(String name, Long size, Map<String, String> tags, String parent, Long iops, String template,
String baseOn, String rename, Boolean shrinkOk) {
super();
this.name = name;
this.size = size;
this.tags = tags;
this.parent = parent;
this.iops = iops;
this.template = template;
this.baseOn = baseOn;
this.rename = rename;
this.shrinkOk = shrinkOk;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getSize() {
return size;
}
public void setSize(Long size) {
this.size = size;
}
public Map<String, String> getTags() {
return tags;
}
public void setTags(Map<String, String> tags) {
this.tags = tags;
}
public String getParent() {
return parent;
}
public void setParent(String parent) {
this.parent = parent;
}
public Long getIops() {
return iops;
}
public void setIops(Long iops) {
this.iops = iops;
}
public String getTemplate() {
return template;
}
public void setTemplate(String template) {
this.template = template;
}
public String getBaseOn() {
return baseOn;
}
public void setBaseOn(String baseOn) {
this.baseOn = baseOn;
}
public String getRename() {
return rename;
}
public void setRename(String rename) {
this.rename = rename;
}

public Boolean getShrinkOk() {
return shrinkOk;
}

public void setShrinkOk(Boolean shrinkOk) {
this.shrinkOk = shrinkOk;
}
}
Loading

0 comments on commit 12d9c26

Please sign in to comment.