Skip to content

Commit eba186a

Browse files
storage: New Dell EMC PowerFlex Plugin (formerly ScaleIO, VxFlexOS) (#4304)
Added support for PowerFlex/ScaleIO (v3.5 onwards) storage pool as a primary storage in CloudStack (for KVM hypervisor) and enabled VM/Volume operations on that pool (using pool tag). Please find more details in the FS here: https://cwiki.apache.org/confluence/x/cDl4CQ Documentation PR: apache/cloudstack-documentation#169 This enables support for PowerFlex/ScaleIO (v3.5 onwards) storage pool as a primary storage in CloudStack Other improvements addressed in addition to PowerFlex/ScaleIO support: - Added support for config drives in host cache for KVM => Changed configuration "vm.configdrive.primarypool.enabled" scope from Global to Zone level => Introduced new zone level configuration "vm.configdrive.force.host.cache.use" (default: false) to force host cache for config drives => Introduced new zone level configuration "vm.configdrive.use.host.cache.on.unsupported.pool" (default: true) to use host cache for config drives when storage pool doesn't support config drive => Added new parameter "host.cache.location" (default: /var/cache/cloud) in KVM agent.properties for specifying the host cache path and create config drives on the "/config" directory on the host cache path => Maintain the config drive location and use it when required on any config drive operation (migrate, delete) - Detect virtual size from the template URL while registering direct download qcow2 (of KVM hypervisor) templates - Updated full deployment destination for preparing the network(s) on VM start - Propagate the direct download certificates uploaded to the newly added KVM hosts - Discover the template size for direct download templates using any available host from the zones specified on template registration => When zones are not specified while registering template, template size discovery is performed using any available host, which is picked up randomly from one of the available zones - Release the VM resources when VM is sync-ed to Stopped state on PowerReportMissing (after graceful period) - Retry VM deployment/start when the host cannot grant access to volume/template - Mark never-used or downloaded templates as Destroyed on deletion, without sending any DeleteCommand => Do not trigger any DeleteCommand for never-used or downloaded templates as these doesn't exist and cannot be deleted from the datastore - Check the router filesystem is writable or not, before performing health checks => Introduce a new test "filesystem.writable.test" to check the filesystem is writable or not => The router health checks keeps the config info at "/var/cache/cloud" and updates the monitor results at "/root" for health checks, both are different partitions. So, test at both the locations. => Added new script: "filesystem_writable_check.py" at /opt/cloud/bin/ to check the filesystem is writable or not - Fixed NPE issue, template is null for DATA disks. Copy template to target storage for ROOT disk (with template id), skip DATA disk(s) * Addressed some issues for few operations on PowerFlex storage pool. - Updated migration volume operation to sync the status and wait for migration to complete. - Updated VM Snapshot naming, for uniqueness in ScaleIO volume name when more than one volume exists in the VM. - Added sync lock while spooling managed storage template before volume creation from the template (non-direct download). - Updated resize volume error message string. - Blocked the below operations on PowerFlex storage pool: -> Extract Volume -> Create Snapshot for VMSnapshot * Added the PowerFlex/ScaleIO client connection pool to manage the ScaleIO gateway clients, which uses a single gateway client per Powerflex/ScaleIO storage pool and renews it when the session token expires. - The token is valid for 8 hours from the time it was created, unless there has been no activity for 10 minutes. Reference: https://cpsdocs.dellemc.com/bundle/PF_REST_API_RG/page/GUID-92430F19-9F44-42B6-B898-87D5307AE59B.html Other fixes included: - Fail the VM deployment when the host specified in the deployVirtualMachine cmd is not in the right state (i.e. either Resource State is not Enabled or Status is not Up) - Use the physical file size of the template to check the free space availability on the host, while downloading the direct download templates. - Perform basic tests (for connectivity and file system) on router before updating the health check config data => Validate the basic tests (connectivity and file system check) on router => Cleanup the health check results when router is destroyed * Updated PowerFlex/ScaleIO storage plugin version to 4.16.0.0 * UI Changes to support storage plugin for PowerFlex/ScaleIO storage pool. - PowerFlex pool URL generated from the UI inputs(Gateway, Username, Password, Storage Pool) when adding "PowerFlex" Primary Storage - Updated protocol to "custom" for PowerFlex provider - Allow VM Snapshot for stopped VM on KVM hypervisor and PowerFlex/ScaleIO storage pool and Minor improvements in PowerFlex/ScaleIO storage plugin code * Added support for PowerFlex/ScaleIO volume migration across different PowerFlex storage instances. - findStoragePoolsForMigration API returns PowerFlex pool(s) of different instance as suitable pool(s), for volume(s) on PowerFlex storage pool. - Volume(s) with snapshots are not allowed to migrate to different PowerFlex instance. - Volume(s) of running VM are not allowed to migrate to other PowerFlex storage pools. - Volume migration from PowerFlex pool to Non-PowerFlex pool, and vice versa are not supported. * Fixed change service offering smoke tests in test_service_offerings.py, test_vm_snapshots.py * Added the PowerFlex/ScaleIO volume/snapshot name to the paths of respective CloudStack resources (Templates, Volumes, Snapshots and VM Snapshots) * Added new response parameter “supportsStorageSnapshot” (true/false) to volume response, and Updated UI to hide the async backup option while taking snapshot for volume(s) with storage snapshot support. * Fix to remove the duplicate zone wide pools listed while finding storage pools for migration * Updated PowerFlex/ScaleIO volume migration checks and rollback migration on failure * Fixed the PowerFlex/ScaleIO volume name inconsistency issue in the volume path after migration, due to rename failure
1 parent 9088573 commit eba186a

File tree

161 files changed

+10221
-577
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

161 files changed

+10221
-577
lines changed

agent/conf/agent.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ hypervisor.type=kvm
143143
# This parameter specifies a directory on the host local storage for temporary storing direct download templates
144144
#direct.download.temporary.download.location=/var/lib/libvirt/images
145145

146+
# This parameter specifies a directory on the host local storage for creating and hosting the config drives
147+
#host.cache.location=/var/cache/cloud
148+
146149
# set the rolling maintenance hook scripts directory
147150
#rolling.maintenance.hooks.dir=/etc/cloudstack/agent/hooks.d
148151

api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Map;
2121
import java.util.HashMap;
2222

23+
import com.cloud.network.element.NetworkElement;
2324
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
2425
import com.cloud.vm.VirtualMachine;
2526
import com.cloud.vm.VirtualMachine.Type;
@@ -73,6 +74,7 @@ public class VirtualMachineTO {
7374
String configDriveLabel = null;
7475
String configDriveIsoRootFolder = null;
7576
String configDriveIsoFile = null;
77+
NetworkElement.Location configDriveLocation = NetworkElement.Location.SECONDARY;
7678

7779
Double cpuQuotaPercentage = null;
7880

@@ -349,6 +351,18 @@ public void setConfigDriveIsoFile(String configDriveIsoFile) {
349351
this.configDriveIsoFile = configDriveIsoFile;
350352
}
351353

354+
public boolean isConfigDriveOnHostCache() {
355+
return (this.configDriveLocation == NetworkElement.Location.HOST);
356+
}
357+
358+
public NetworkElement.Location getConfigDriveLocation() {
359+
return configDriveLocation;
360+
}
361+
362+
public void setConfigDriveLocation(NetworkElement.Location configDriveLocation) {
363+
this.configDriveLocation = configDriveLocation;
364+
}
365+
352366
public Map<String, String> getGuestOsDetails() {
353367
return guestOsDetails;
354368
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.exception;
18+
19+
import com.cloud.utils.SerialVersionUID;
20+
21+
/**
22+
* If the cause is due to storage pool not accessible on host, calling
23+
* problem with.
24+
*
25+
*/
26+
public class StorageAccessException extends RuntimeException {
27+
private static final long serialVersionUID = SerialVersionUID.StorageAccessException;
28+
29+
public StorageAccessException(String message) {
30+
super(message);
31+
}
32+
}

api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.cloud.exception.ResourceUnavailableException;
2727
import com.cloud.network.router.VirtualRouter;
2828
import com.cloud.user.Account;
29+
import com.cloud.utils.Pair;
2930

3031
public interface VirtualNetworkApplianceService {
3132
/**
@@ -73,5 +74,5 @@ public interface VirtualNetworkApplianceService {
7374
* @param routerId id of the router
7475
* @return
7576
*/
76-
boolean performRouterHealthChecks(long routerId);
77+
Pair<Boolean, String> performRouterHealthChecks(long routerId);
7778
}

api/src/main/java/com/cloud/network/element/NetworkElement.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
*/
4040
public interface NetworkElement extends Adapter {
4141

42+
enum Location {
43+
SECONDARY, PRIMARY, HOST
44+
}
45+
4246
Map<Service, Map<Capability, String>> getCapabilities();
4347

4448
/**

api/src/main/java/com/cloud/storage/Storage.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ public static enum StoragePoolType {
135135
OCFS2(true, false),
136136
SMB(true, false),
137137
Gluster(true, false),
138+
PowerFlex(true, true), // Dell EMC PowerFlex/ScaleIO (formerly VxFlexOS)
138139
ManagedNFS(true, false),
139140
DatastoreCluster(true, true); // for VMware, to abstract pool of clusters
140141

api/src/main/java/com/cloud/storage/Volume.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
import com.cloud.utils.fsm.StateObject;
3030

3131
public interface Volume extends ControlledEntity, Identity, InternalIdentity, BasedOn, StateObject<Volume.State>, Displayable {
32+
33+
// Managed storage volume parameters (specified in the compute/disk offering for PowerFlex)
34+
String BANDWIDTH_LIMIT_IN_MBPS = "bandwidthLimitInMbps";
35+
String IOPS_LIMIT = "iopsLimit";
36+
3237
enum Type {
3338
UNKNOWN, ROOT, SWAP, DATADISK, ISO
3439
};
@@ -79,6 +84,7 @@ public String getDescription() {
7984
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Creating, Event.OperationSucceeded, Ready, null));
8085
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Creating, Event.DestroyRequested, Destroy, null));
8186
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Creating, Event.CreateRequested, Creating, null));
87+
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Ready, Event.CreateRequested, Creating, null));
8288
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Ready, Event.ResizeRequested, Resizing, null));
8389
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Resizing, Event.OperationSucceeded, Ready, Arrays.asList(new StateMachine2.Transition.Impact[]{StateMachine2.Transition.Impact.USAGE})));
8490
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Resizing, Event.OperationFailed, Ready, null));

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
import java.util.Map;
2121

2222
import com.cloud.agent.api.to.DiskTO;
23+
import com.cloud.host.Host;
2324
import com.cloud.hypervisor.Hypervisor.HypervisorType;
25+
import com.cloud.network.element.NetworkElement;
2426
import com.cloud.offering.ServiceOffering;
2527
import com.cloud.template.VirtualMachineTemplate;
2628
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
@@ -54,6 +56,10 @@ public interface VirtualMachineProfile {
5456

5557
void setConfigDriveIsoFile(String isoFile);
5658

59+
NetworkElement.Location getConfigDriveLocation();
60+
61+
void setConfigDriveLocation(NetworkElement.Location location);
62+
5763
public static class Param {
5864

5965
public static final Param VmPassword = new Param("VmPassword");
@@ -100,6 +106,10 @@ public boolean equals(Object obj) {
100106
}
101107
}
102108

109+
Long getHostId();
110+
111+
void setHost(Host host);
112+
103113
String getHostName();
104114

105115
String getInstanceName();

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public interface VmDetailConstants {
5656
String PASSWORD = "password";
5757
String ENCRYPTED_PASSWORD = "Encrypted.Password";
5858

59+
String CONFIG_DRIVE_LOCATION = "configDriveLocation";
60+
5961
// VM import with nic, disk and custom params for custom compute offering
6062
String NIC = "nic";
6163
String NETWORK = "network";

api/src/main/java/org/apache/cloudstack/alert/AlertService.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
// under the License.
1717
package org.apache.cloudstack.alert;
1818

19-
import com.cloud.capacity.Capacity;
20-
import com.cloud.exception.InvalidParameterValueException;
21-
2219
import java.util.HashSet;
2320
import java.util.Set;
2421

22+
import com.cloud.capacity.Capacity;
23+
import com.cloud.exception.InvalidParameterValueException;
24+
2525
public interface AlertService {
2626
public static class AlertType {
2727
private static Set<AlertType> defaultAlertTypes = new HashSet<AlertType>();
@@ -69,6 +69,7 @@ private AlertType(short type, String name, boolean isDefault) {
6969
public static final AlertType ALERT_TYPE_OOBM_AUTH_ERROR = new AlertType((short)29, "ALERT.OOBM.AUTHERROR", true);
7070
public static final AlertType ALERT_TYPE_HA_ACTION = new AlertType((short)30, "ALERT.HA.ACTION", true);
7171
public static final AlertType ALERT_TYPE_CA_CERT = new AlertType((short)31, "ALERT.CA.CERT", true);
72+
public static final AlertType ALERT_TYPE_VM_SNAPSHOT = new AlertType((short)32, "ALERT.VM.SNAPSHOT", true);
7273

7374
public short getType() {
7475
return type;

0 commit comments

Comments
 (0)