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 org.apache.commons.lang3.StringUtils; | ||||||
| 
 | 
 | ||||||
| import java.util.LinkedHashMap; | import java.util.LinkedHashMap; | ||||||
|  | import java.util.List; | ||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.Objects; | 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 class Hypervisor { | ||||||
|     public static class HypervisorType { |     public static class HypervisorType { | ||||||
|  |         public enum Functionality { | ||||||
|  |             DirectDownloadTemplate, | ||||||
|  |             RootDiskSizeOverride, | ||||||
|  |             VmStorageMigration | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         private static final Map<String, HypervisorType> hypervisorTypeMap = new LinkedHashMap<>(); |         private static final Map<String, HypervisorType> hypervisorTypeMap = new LinkedHashMap<>(); | ||||||
|         public static final HypervisorType None = new HypervisorType("None"); //for storage hosts |         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 XenServer = new HypervisorType("XenServer", ImageFormat.VHD, EnumSet.of(RootDiskSizeOverride, VmStorageMigration)); | ||||||
|         public static final HypervisorType KVM = new HypervisorType("KVM", ImageFormat.QCOW2); |         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); |         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 Hyperv = new HypervisorType("Hyperv"); | ||||||
|         public static final HypervisorType VirtualBox = new HypervisorType("VirtualBox"); |         public static final HypervisorType VirtualBox = new HypervisorType("VirtualBox"); | ||||||
|         public static final HypervisorType Parralels = new HypervisorType("Parralels"); |         public static final HypervisorType Parralels = new HypervisorType("Parralels"); | ||||||
|         public static final HypervisorType BareMetal = new HypervisorType("BareMetal"); |         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 Ovm = new HypervisorType("Ovm", ImageFormat.RAW); | ||||||
|         public static final HypervisorType Ovm3 = new HypervisorType("Ovm3", ImageFormat.RAW); |         public static final HypervisorType Ovm3 = new HypervisorType("Ovm3", ImageFormat.RAW); | ||||||
|         public static final HypervisorType LXC = new HypervisorType("LXC"); |         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*/ |         public static final HypervisorType Any = new HypervisorType("Any"); /*If you don't care about the hypervisor type*/ | ||||||
|         private final String name; |         private final String name; | ||||||
|         private final ImageFormat imageFormat; |         private final ImageFormat imageFormat; | ||||||
|  |         private final Set<Functionality> supportedFunctionalities; | ||||||
| 
 | 
 | ||||||
|         public HypervisorType(String name) { |         public HypervisorType(String name) { | ||||||
|             this(name, null); |             this(name, null, EnumSet.noneOf(Functionality.class)); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public HypervisorType(String name, ImageFormat imageFormat) { |         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.name = name; | ||||||
|             this.imageFormat = imageFormat; |             this.imageFormat = imageFormat; | ||||||
|  |             this.supportedFunctionalities = supportedFunctionalities; | ||||||
|             if (name.equals("Parralels")){ // typo in the original code |             if (name.equals("Parralels")){ // typo in the original code | ||||||
|                 hypervisorTypeMap.put("parallels", this); |                 hypervisorTypeMap.put("parallels", this); | ||||||
|             } else { |             } else { | ||||||
| @ -81,6 +101,12 @@ public class Hypervisor { | |||||||
|             return hypervisorType; |             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, |          * 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 |          * using the 'hypervisor.custom.display.name' setting. Otherwise, returns hypervisor name | ||||||
| @ -102,6 +128,15 @@ public class Hypervisor { | |||||||
|             return name; |             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 |         @Override | ||||||
|         public int hashCode() { |         public int hashCode() { | ||||||
|             return Objects.hash(name); |             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"); |                     "Parameter zoneids cannot combine all zones (-1) option with other zones"); | ||||||
| 
 | 
 | ||||||
|         String customHypervisor = HypervisorGuru.HypervisorCustomDisplayName.value(); |         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))) { |                 || getHypervisor().equalsIgnoreCase(customHypervisor))) { | ||||||
|             throw new ServerApiException(ApiErrorCode.PARAM_ERROR, String.format("Parameter directdownload " + |             throw new ServerApiException(ApiErrorCode.PARAM_ERROR, String.format("Parameter directdownload " + | ||||||
|                     "is only allowed for KVM or %s templates", customHypervisor)); |                     "is only allowed for KVM or %s templates", customHypervisor)); | ||||||
|  | |||||||
| @ -16,6 +16,7 @@ | |||||||
| // under the License. | // under the License. | ||||||
| package com.cloud.vm; | package com.cloud.vm; | ||||||
| 
 | 
 | ||||||
|  | import static com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality; | ||||||
| import static com.cloud.storage.Volume.IOPS_LIMIT; | import static com.cloud.storage.Volume.IOPS_LIMIT; | ||||||
| import static com.cloud.utils.NumbersUtil.toHumanReadableSize; | import static com.cloud.utils.NumbersUtil.toHumanReadableSize; | ||||||
| import static org.apache.cloudstack.api.ApiConstants.MAX_IOPS; | 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", |     private static final ConfigKey<Boolean> VmDestroyForcestop = new ConfigKey<Boolean>("Advanced", Boolean.class, "vm.destroy.forcestop", "false", | ||||||
|             "On destroy, force-stop takes this value ", true); |             "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 |     @Override | ||||||
|     public UserVmVO getVirtualMachine(long vmId) { |     public UserVmVO getVirtualMachine(long vmId) { | ||||||
|         return _vmDao.findById(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 |      * @throws InvalidParameterValueException if the hypervisor does not support rootdisksize override | ||||||
|      */ |      */ | ||||||
|     protected void verifyIfHypervisorSupportsRootdiskSizeOverride(HypervisorType hypervisorType) { |     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"); |             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(); |         HypervisorType hypervisorType = vm.getHypervisorType(); | ||||||
|         if (vm.getType() != VirtualMachine.Type.User && !HYPERVISORS_THAT_CAN_DO_STORAGE_MIGRATION_ON_NON_USER_VMS.contains(hypervisorType)) { |         List<HypervisorType> supportedHypervisorsForNonUserVMStorageMigration = HypervisorType.getListOfHypervisorsSupportingFunctionality(Functionality.VmStorageMigration) | ||||||
|             throw new InvalidParameterValueException(String.format("Unable to migrate storage of non-user VMs for hypervisor [%s]. Operation only supported for the following" |                 .stream().filter(hypervisor -> !hypervisor.equals(HypervisorType.XenServer)).collect(Collectors.toList()); | ||||||
|                     + " hypervisors: [%s].", hypervisorType, HYPERVISORS_THAT_CAN_DO_STORAGE_MIGRATION_ON_NON_USER_VMS)); |         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()); |         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"); |             throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (!VM_STORAGE_MIGRATION_SUPPORTING_HYPERVISORS.contains(vm.getHypervisorType())) { |         if (!vm.getHypervisorType().isFunctionalitySupported(Functionality.VmStorageMigration)) { | ||||||
|             throw new InvalidParameterValueException(String.format("Unsupported hypervisor: %s for VM migration, we support XenServer/VMware/KVM only", vm.getHypervisorType())); |             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) { |         if (_vmSnapshotDao.findByVm(vmId).size() > 0) { | ||||||
|  | |||||||
| @ -635,7 +635,7 @@ public class UserVmManagerImplTest { | |||||||
|         int expectedExceptionCounter = hypervisorTypeArray.length - 5; |         int expectedExceptionCounter = hypervisorTypeArray.length - 5; | ||||||
| 
 | 
 | ||||||
|         for(int i = 0; i < hypervisorTypeArray.length; i++) { |         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]); |                 userVmManagerImpl.verifyIfHypervisorSupportsRootdiskSizeOverride(hypervisorTypeArray[i]); | ||||||
|             } else { |             } else { | ||||||
|                 try { |                 try { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user