This is an automated email from the ASF dual-hosted git repository.
rohit pushed a commit to branch 4.20
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.20 by this push:
new 52e7b41a54e Add support for functionality in hypervisor class (#9736)
52e7b41a54e is described below
commit 52e7b41a54ee107166421bf14c9d8606c86a9511
Author: Vishesh <[email protected]>
AuthorDate: Tue Dec 3 12:20:59 2024 +0530
Add support for functionality in hypervisor class (#9736)
* Add support for functionality in hypervisor class
* Address comments
* address comments
---
.../main/java/com/cloud/hypervisor/Hypervisor.java | 47 +++++++++++++++++++---
.../command/user/template/RegisterTemplateCmd.java | 4 +-
.../main/java/com/cloud/vm/UserVmManagerImpl.java | 36 ++++++-----------
.../java/com/cloud/vm/UserVmManagerImplTest.java | 2 +-
4 files changed, 58 insertions(+), 31 deletions(-)
diff --git a/api/src/main/java/com/cloud/hypervisor/Hypervisor.java
b/api/src/main/java/com/cloud/hypervisor/Hypervisor.java
index e1108b34a83..27ffef1c370 100644
--- a/api/src/main/java/com/cloud/hypervisor/Hypervisor.java
+++ b/api/src/main/java/com/cloud/hypervisor/Hypervisor.java
@@ -20,37 +20,57 @@ import com.cloud.storage.Storage.ImageFormat;
import org.apache.commons.lang3.StringUtils;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
+import java.util.EnumSet;
+import java.util.stream.Collectors;
+
+import static
com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality.DirectDownloadTemplate;
+import static
com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality.RootDiskSizeOverride;
+import static
com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality.VmStorageMigration;
public class Hypervisor {
public static class HypervisorType {
+ public enum Functionality {
+ DirectDownloadTemplate,
+ RootDiskSizeOverride,
+ VmStorageMigration
+ }
+
private static final Map<String, HypervisorType> hypervisorTypeMap =
new LinkedHashMap<>();
public static final HypervisorType None = new HypervisorType("None");
//for storage hosts
- public static final HypervisorType XenServer = new
HypervisorType("XenServer", ImageFormat.VHD);
- public static final HypervisorType KVM = new HypervisorType("KVM",
ImageFormat.QCOW2);
- public static final HypervisorType VMware = new
HypervisorType("VMware", ImageFormat.OVA);
+ public static final HypervisorType XenServer = new
HypervisorType("XenServer", ImageFormat.VHD, EnumSet.of(RootDiskSizeOverride,
VmStorageMigration));
+ public static final HypervisorType KVM = new HypervisorType("KVM",
ImageFormat.QCOW2, EnumSet.of(DirectDownloadTemplate, RootDiskSizeOverride,
VmStorageMigration));
+ public static final HypervisorType VMware = new
HypervisorType("VMware", ImageFormat.OVA, EnumSet.of(RootDiskSizeOverride,
VmStorageMigration));
public static final HypervisorType Hyperv = new
HypervisorType("Hyperv");
public static final HypervisorType VirtualBox = new
HypervisorType("VirtualBox");
public static final HypervisorType Parralels = new
HypervisorType("Parralels");
public static final HypervisorType BareMetal = new
HypervisorType("BareMetal");
- public static final HypervisorType Simulator = new
HypervisorType("Simulator");
+ public static final HypervisorType Simulator = new
HypervisorType("Simulator", null, EnumSet.of(RootDiskSizeOverride,
VmStorageMigration));
public static final HypervisorType Ovm = new HypervisorType("Ovm",
ImageFormat.RAW);
public static final HypervisorType Ovm3 = new HypervisorType("Ovm3",
ImageFormat.RAW);
public static final HypervisorType LXC = new HypervisorType("LXC");
- public static final HypervisorType Custom = new
HypervisorType("Custom");
+ public static final HypervisorType Custom = new
HypervisorType("Custom", null, EnumSet.of(RootDiskSizeOverride));
public static final HypervisorType Any = new HypervisorType("Any");
/*If you don't care about the hypervisor type*/
private final String name;
private final ImageFormat imageFormat;
+ private final Set<Functionality> supportedFunctionalities;
public HypervisorType(String name) {
- this(name, null);
+ this(name, null, EnumSet.noneOf(Functionality.class));
}
public HypervisorType(String name, ImageFormat imageFormat) {
+ this(name, imageFormat, EnumSet.noneOf(Functionality.class));
+ }
+
+ public HypervisorType(String name, ImageFormat imageFormat,
Set<Functionality> supportedFunctionalities) {
this.name = name;
this.imageFormat = imageFormat;
+ this.supportedFunctionalities = supportedFunctionalities;
if (name.equals("Parralels")){ // typo in the original code
hypervisorTypeMap.put("parallels", this);
} else {
@@ -81,6 +101,12 @@ public class Hypervisor {
return hypervisorType;
}
+ public static List<HypervisorType>
getListOfHypervisorsSupportingFunctionality(Functionality functionality) {
+ return hypervisorTypeMap.values().stream()
+ .filter(hypervisor ->
hypervisor.supportedFunctionalities.contains(functionality))
+ .collect(Collectors.toList());
+ }
+
/**
* Returns the display name of a hypervisor type in case the custom
hypervisor is used,
* using the 'hypervisor.custom.display.name' setting. Otherwise,
returns hypervisor name
@@ -102,6 +128,15 @@ public class Hypervisor {
return name;
}
+ /**
+ * Make this method to be part of the properties of the hypervisor
type itself.
+ *
+ * @return true if the hypervisor plugin support the specified
functionality
+ */
+ public boolean isFunctionalitySupported(Functionality functionality) {
+ return supportedFunctionalities.contains(functionality);
+ }
+
@Override
public int hashCode() {
return Objects.hash(name);
diff --git
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
index a7826dedcd0..1f968b869b9 100644
---
a/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
+++
b/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
@@ -362,7 +362,9 @@ public class RegisterTemplateCmd extends BaseCmd implements
UserCmd {
"Parameter zoneids cannot combine all zones (-1) option
with other zones");
String customHypervisor =
HypervisorGuru.HypervisorCustomDisplayName.value();
- if (isDirectDownload() &&
!(getHypervisor().equalsIgnoreCase(Hypervisor.HypervisorType.KVM.toString())
+ if (isDirectDownload() &&
+ !(Hypervisor.HypervisorType.getType(getHypervisor())
+
.isFunctionalitySupported(Hypervisor.HypervisorType.Functionality.DirectDownloadTemplate)
|| getHypervisor().equalsIgnoreCase(customHypervisor))) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
String.format("Parameter directdownload " +
"is only allowed for KVM or %s templates",
customHypervisor));
diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
index 219feeef5a9..04b64dd80a3 100644
--- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
@@ -16,6 +16,7 @@
// under the License.
package com.cloud.vm;
+import static com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality;
import static com.cloud.storage.Volume.IOPS_LIMIT;
import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
import static org.apache.cloudstack.api.ApiConstants.MAX_IOPS;
@@ -679,23 +680,6 @@ public class UserVmManagerImpl extends ManagerBase
implements UserVmManager, Vir
private static final ConfigKey<Boolean> VmDestroyForcestop = new
ConfigKey<Boolean>("Advanced", Boolean.class, "vm.destroy.forcestop", "false",
"On destroy, force-stop takes this value ", true);
- public static final List<HypervisorType>
VM_STORAGE_MIGRATION_SUPPORTING_HYPERVISORS = new ArrayList<>(Arrays.asList(
- HypervisorType.KVM,
- HypervisorType.VMware,
- HypervisorType.XenServer,
- HypervisorType.Simulator
- ));
-
- protected static final List<HypervisorType>
ROOT_DISK_SIZE_OVERRIDE_SUPPORTING_HYPERVISORS = Arrays.asList(
- HypervisorType.KVM,
- HypervisorType.XenServer,
- HypervisorType.VMware,
- HypervisorType.Simulator,
- HypervisorType.Custom
- );
-
- private static final List<HypervisorType>
HYPERVISORS_THAT_CAN_DO_STORAGE_MIGRATION_ON_NON_USER_VMS =
Arrays.asList(HypervisorType.KVM, HypervisorType.VMware);
-
@Override
public UserVmVO getVirtualMachine(long vmId) {
return _vmDao.findById(vmId);
@@ -4563,7 +4547,7 @@ public class UserVmManagerImpl extends ManagerBase
implements UserVmManager, Vir
* @throws InvalidParameterValueException if the hypervisor does not
support rootdisksize override
*/
protected void
verifyIfHypervisorSupportsRootdiskSizeOverride(HypervisorType hypervisorType) {
- if
(!ROOT_DISK_SIZE_OVERRIDE_SUPPORTING_HYPERVISORS.contains(hypervisorType)) {
+ if
(!hypervisorType.isFunctionalitySupported(Functionality.RootDiskSizeOverride)) {
throw new InvalidParameterValueException("Hypervisor " +
hypervisorType + " does not support rootdisksize override");
}
}
@@ -6606,9 +6590,12 @@ public class UserVmManagerImpl extends ManagerBase
implements UserVmManager, Vir
}
HypervisorType hypervisorType = vm.getHypervisorType();
- if (vm.getType() != VirtualMachine.Type.User &&
!HYPERVISORS_THAT_CAN_DO_STORAGE_MIGRATION_ON_NON_USER_VMS.contains(hypervisorType))
{
- throw new InvalidParameterValueException(String.format("Unable to
migrate storage of non-user VMs for hypervisor [%s]. Operation only supported
for the following"
- + " hypervisors: [%s].", hypervisorType,
HYPERVISORS_THAT_CAN_DO_STORAGE_MIGRATION_ON_NON_USER_VMS));
+ List<HypervisorType> supportedHypervisorsForNonUserVMStorageMigration
=
HypervisorType.getListOfHypervisorsSupportingFunctionality(Functionality.VmStorageMigration)
+ .stream().filter(hypervisor ->
!hypervisor.equals(HypervisorType.XenServer)).collect(Collectors.toList());
+ if (vm.getType() != VirtualMachine.Type.User &&
!supportedHypervisorsForNonUserVMStorageMigration.contains(hypervisorType)) {
+ throw new InvalidParameterValueException(String.format(
+ "Unable to migrate storage of non-user VMs for hypervisor
[%s]. Operation only supported for the following hypervisors: [%s].",
+ hypervisorType,
supportedHypervisorsForNonUserVMStorageMigration));
}
List<VolumeVO> vols = _volsDao.findByInstance(vm.getId());
@@ -7318,8 +7305,11 @@ public class UserVmManagerImpl extends ManagerBase
implements UserVmManager, Vir
throw new InvalidParameterValueException("Live Migration of GPU
enabled VM is not supported");
}
- if
(!VM_STORAGE_MIGRATION_SUPPORTING_HYPERVISORS.contains(vm.getHypervisorType()))
{
- throw new
InvalidParameterValueException(String.format("Unsupported hypervisor: %s for VM
migration, we support XenServer/VMware/KVM only", vm.getHypervisorType()));
+ if
(!vm.getHypervisorType().isFunctionalitySupported(Functionality.VmStorageMigration))
{
+ throw new InvalidParameterValueException(
+ String.format("Unsupported hypervisor: %s for VM
migration, we support [%s] only",
+ vm.getHypervisorType(),
+
HypervisorType.getListOfHypervisorsSupportingFunctionality(Functionality.VmStorageMigration)));
}
if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
diff --git a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
index 8316c57d67d..d49dcd0f00c 100644
--- a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
+++ b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
@@ -635,7 +635,7 @@ public class UserVmManagerImplTest {
int expectedExceptionCounter = hypervisorTypeArray.length - 5;
for(int i = 0; i < hypervisorTypeArray.length; i++) {
- if
(UserVmManagerImpl.ROOT_DISK_SIZE_OVERRIDE_SUPPORTING_HYPERVISORS.contains(hypervisorTypeArray[i]))
{
+ if
(hypervisorTypeArray[i].isFunctionalitySupported(Hypervisor.HypervisorType.Functionality.RootDiskSizeOverride))
{
userVmManagerImpl.verifyIfHypervisorSupportsRootdiskSizeOverride(hypervisorTypeArray[i]);
} else {
try {