Skip to content

Commit 44c11c1

Browse files
vishesh92dhslove
authored andcommitted
Add support for functionality in hypervisor class (apache#9736)
* Add support for functionality in hypervisor class * Address comments * address comments
1 parent 21798e2 commit 44c11c1

File tree

4 files changed

+58
-31
lines changed

4 files changed

+58
-31
lines changed

api/src/main/java/com/cloud/hypervisor/Hypervisor.java

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,57 @@
2020
import org.apache.commons.lang3.StringUtils;
2121

2222
import java.util.LinkedHashMap;
23+
import java.util.List;
2324
import java.util.Locale;
2425
import java.util.Map;
2526
import java.util.Objects;
27+
import java.util.Set;
28+
import java.util.EnumSet;
29+
import java.util.stream.Collectors;
30+
31+
import static com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality.DirectDownloadTemplate;
32+
import static com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality.RootDiskSizeOverride;
33+
import static com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality.VmStorageMigration;
2634

2735
public class Hypervisor {
2836
public static class HypervisorType {
37+
public enum Functionality {
38+
DirectDownloadTemplate,
39+
RootDiskSizeOverride,
40+
VmStorageMigration
41+
}
42+
2943
private static final Map<String, HypervisorType> hypervisorTypeMap = new LinkedHashMap<>();
3044
public static final HypervisorType None = new HypervisorType("None"); //for storage hosts
31-
public static final HypervisorType XenServer = new HypervisorType("XenServer", ImageFormat.VHD);
32-
public static final HypervisorType KVM = new HypervisorType("KVM", ImageFormat.QCOW2);
33-
public static final HypervisorType VMware = new HypervisorType("VMware", ImageFormat.OVA);
45+
public static final HypervisorType XenServer = new HypervisorType("XenServer", ImageFormat.VHD, EnumSet.of(RootDiskSizeOverride, VmStorageMigration));
46+
public static final HypervisorType KVM = new HypervisorType("KVM", ImageFormat.QCOW2, EnumSet.of(DirectDownloadTemplate, RootDiskSizeOverride, VmStorageMigration));
47+
public static final HypervisorType VMware = new HypervisorType("VMware", ImageFormat.OVA, EnumSet.of(RootDiskSizeOverride, VmStorageMigration));
3448
public static final HypervisorType Hyperv = new HypervisorType("Hyperv");
3549
public static final HypervisorType VirtualBox = new HypervisorType("VirtualBox");
3650
public static final HypervisorType Parralels = new HypervisorType("Parralels");
3751
public static final HypervisorType BareMetal = new HypervisorType("BareMetal");
38-
public static final HypervisorType Simulator = new HypervisorType("Simulator");
52+
public static final HypervisorType Simulator = new HypervisorType("Simulator", null, EnumSet.of(RootDiskSizeOverride, VmStorageMigration));
3953
public static final HypervisorType Ovm = new HypervisorType("Ovm", ImageFormat.RAW);
4054
public static final HypervisorType Ovm3 = new HypervisorType("Ovm3", ImageFormat.RAW);
4155
public static final HypervisorType LXC = new HypervisorType("LXC");
42-
public static final HypervisorType Custom = new HypervisorType("Custom");
56+
public static final HypervisorType Custom = new HypervisorType("Custom", null, EnumSet.of(RootDiskSizeOverride));
4357
public static final HypervisorType Any = new HypervisorType("Any"); /*If you don't care about the hypervisor type*/
4458
private final String name;
4559
private final ImageFormat imageFormat;
60+
private final Set<Functionality> supportedFunctionalities;
4661

4762
public HypervisorType(String name) {
48-
this(name, null);
63+
this(name, null, EnumSet.noneOf(Functionality.class));
4964
}
5065

5166
public HypervisorType(String name, ImageFormat imageFormat) {
67+
this(name, imageFormat, EnumSet.noneOf(Functionality.class));
68+
}
69+
70+
public HypervisorType(String name, ImageFormat imageFormat, Set<Functionality> supportedFunctionalities) {
5271
this.name = name;
5372
this.imageFormat = imageFormat;
73+
this.supportedFunctionalities = supportedFunctionalities;
5474
if (name.equals("Parralels")){ // typo in the original code
5575
hypervisorTypeMap.put("parallels", this);
5676
} else {
@@ -81,6 +101,12 @@ public static HypervisorType valueOf(String name) {
81101
return hypervisorType;
82102
}
83103

104+
public static List<HypervisorType> getListOfHypervisorsSupportingFunctionality(Functionality functionality) {
105+
return hypervisorTypeMap.values().stream()
106+
.filter(hypervisor -> hypervisor.supportedFunctionalities.contains(functionality))
107+
.collect(Collectors.toList());
108+
}
109+
84110
/**
85111
* Returns the display name of a hypervisor type in case the custom hypervisor is used,
86112
* using the 'hypervisor.custom.display.name' setting. Otherwise, returns hypervisor name
@@ -102,6 +128,15 @@ public String name() {
102128
return name;
103129
}
104130

131+
/**
132+
* Make this method to be part of the properties of the hypervisor type itself.
133+
*
134+
* @return true if the hypervisor plugin support the specified functionality
135+
*/
136+
public boolean isFunctionalitySupported(Functionality functionality) {
137+
return supportedFunctionalities.contains(functionality);
138+
}
139+
105140
@Override
106141
public int hashCode() {
107142
return Objects.hash(name);

api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,9 @@ protected void validateParameters() {
417417
"Parameter zoneids cannot combine all zones (-1) option with other zones");
418418

419419
String customHypervisor = HypervisorGuru.HypervisorCustomDisplayName.value();
420-
if (isDirectDownload() && !(getHypervisor().equalsIgnoreCase(Hypervisor.HypervisorType.KVM.toString())
420+
if (isDirectDownload() &&
421+
!(Hypervisor.HypervisorType.getType(getHypervisor())
422+
.isFunctionalitySupported(Hypervisor.HypervisorType.Functionality.DirectDownloadTemplate)
421423
|| getHypervisor().equalsIgnoreCase(customHypervisor))) {
422424
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, String.format("Parameter directdownload " +
423425
"is only allowed for KVM or %s templates", customHypervisor));

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// under the License.
1717
package com.cloud.vm;
1818

19+
import static com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality;
1920
import static com.cloud.storage.Volume.IOPS_LIMIT;
2021
import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
2122
import static org.apache.cloudstack.api.ApiConstants.MAX_IOPS;
@@ -718,23 +719,6 @@ public void setKubernetesServiceHelpers(final List<KubernetesServiceHelper> kube
718719
private static final ConfigKey<Boolean> VmDestroyForcestop = new ConfigKey<Boolean>("Advanced", Boolean.class, "vm.destroy.forcestop", "false",
719720
"On destroy, force-stop takes this value ", true);
720721

721-
public static final List<HypervisorType> VM_STORAGE_MIGRATION_SUPPORTING_HYPERVISORS = new ArrayList<>(Arrays.asList(
722-
HypervisorType.KVM,
723-
HypervisorType.VMware,
724-
HypervisorType.XenServer,
725-
HypervisorType.Simulator
726-
));
727-
728-
protected static final List<HypervisorType> ROOT_DISK_SIZE_OVERRIDE_SUPPORTING_HYPERVISORS = Arrays.asList(
729-
HypervisorType.KVM,
730-
HypervisorType.XenServer,
731-
HypervisorType.VMware,
732-
HypervisorType.Simulator,
733-
HypervisorType.Custom
734-
);
735-
736-
private static final List<HypervisorType> HYPERVISORS_THAT_CAN_DO_STORAGE_MIGRATION_ON_NON_USER_VMS = Arrays.asList(HypervisorType.KVM, HypervisorType.VMware);
737-
738722
@Override
739723
public UserVmVO getVirtualMachine(long vmId) {
740724
return _vmDao.findById(vmId);
@@ -4667,7 +4651,7 @@ protected long configureCustomRootDiskSize(Map<String, String> customParameters,
46674651
* @throws InvalidParameterValueException if the hypervisor does not support rootdisksize override
46684652
*/
46694653
protected void verifyIfHypervisorSupportsRootdiskSizeOverride(HypervisorType hypervisorType) {
4670-
if (!ROOT_DISK_SIZE_OVERRIDE_SUPPORTING_HYPERVISORS.contains(hypervisorType)) {
4654+
if (!hypervisorType.isFunctionalitySupported(Functionality.RootDiskSizeOverride)) {
46714655
throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support rootdisksize override");
46724656
}
46734657
}
@@ -6718,9 +6702,12 @@ private VMInstanceVO preVmStorageMigrationCheck(Long vmId) {
67186702
}
67196703

67206704
HypervisorType hypervisorType = vm.getHypervisorType();
6721-
if (vm.getType() != VirtualMachine.Type.User && !HYPERVISORS_THAT_CAN_DO_STORAGE_MIGRATION_ON_NON_USER_VMS.contains(hypervisorType)) {
6722-
throw new InvalidParameterValueException(String.format("Unable to migrate storage of non-user VMs for hypervisor [%s]. Operation only supported for the following"
6723-
+ " hypervisors: [%s].", hypervisorType, HYPERVISORS_THAT_CAN_DO_STORAGE_MIGRATION_ON_NON_USER_VMS));
6705+
List<HypervisorType> supportedHypervisorsForNonUserVMStorageMigration = HypervisorType.getListOfHypervisorsSupportingFunctionality(Functionality.VmStorageMigration)
6706+
.stream().filter(hypervisor -> !hypervisor.equals(HypervisorType.XenServer)).collect(Collectors.toList());
6707+
if (vm.getType() != VirtualMachine.Type.User && !supportedHypervisorsForNonUserVMStorageMigration.contains(hypervisorType)) {
6708+
throw new InvalidParameterValueException(String.format(
6709+
"Unable to migrate storage of non-user VMs for hypervisor [%s]. Operation only supported for the following hypervisors: [%s].",
6710+
hypervisorType, supportedHypervisorsForNonUserVMStorageMigration));
67246711
}
67256712

67266713
List<VolumeVO> vols = _volsDao.findByInstance(vm.getId());
@@ -7430,8 +7417,11 @@ public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinatio
74307417
throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
74317418
}
74327419

7433-
if (!VM_STORAGE_MIGRATION_SUPPORTING_HYPERVISORS.contains(vm.getHypervisorType())) {
7434-
throw new InvalidParameterValueException(String.format("Unsupported hypervisor: %s for VM migration, we support XenServer/VMware/KVM only", vm.getHypervisorType()));
7420+
if (!vm.getHypervisorType().isFunctionalitySupported(Functionality.VmStorageMigration)) {
7421+
throw new InvalidParameterValueException(
7422+
String.format("Unsupported hypervisor: %s for VM migration, we support [%s] only",
7423+
vm.getHypervisorType(),
7424+
HypervisorType.getListOfHypervisorsSupportingFunctionality(Functionality.VmStorageMigration)));
74357425
}
74367426

74377427
if (_vmSnapshotDao.findByVm(vmId).size() > 0) {

server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ public void verifyIfHypervisorSupportRootdiskSizeOverrideTest() {
636636
int expectedExceptionCounter = hypervisorTypeArray.length - 5;
637637

638638
for(int i = 0; i < hypervisorTypeArray.length; i++) {
639-
if (UserVmManagerImpl.ROOT_DISK_SIZE_OVERRIDE_SUPPORTING_HYPERVISORS.contains(hypervisorTypeArray[i])) {
639+
if (hypervisorTypeArray[i].isFunctionalitySupported(Hypervisor.HypervisorType.Functionality.RootDiskSizeOverride)) {
640640
userVmManagerImpl.verifyIfHypervisorSupportsRootdiskSizeOverride(hypervisorTypeArray[i]);
641641
} else {
642642
try {

0 commit comments

Comments
 (0)