mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Add support for functionality in hypervisor class (#9736)
* Add support for functionality in hypervisor class * Address comments * address comments
This commit is contained in:
parent
f3a474bb9e
commit
52e7b41a54
@ -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);
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user