mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	Refactor and improvements for method com.cloud.hypervisor.kvm.resource.LibvirtComputingResource.createVMFromSpec() (#5149)
* Refactor method createVMFromSpec * Add unit tests * Fix test * Extract if block to method for add extra configs to VM Domain XML * Split travis tests trying to isolate which test is causing an error * Override toString() method * Update documentation * Fix checkstyle error (line with trailing spaces) * Change VirtualMachineTO print of object * Add try except to find message error. Remove after test * Fix indent * Trying to understanding why is happening in this code * Refactor method createVMFromSpec * Add unit tests * Fix test * Extract if block to method for add extra configs to VM Domain XML * Split travis tests trying to isolate which test is causing an error * Override toString() method * Update documentation * Fix checkstyle error (line with trailing spaces) * Remove unnecessary comment * Revert travis tests Co-authored-by: SadiJr <17a0db2854@firemailbox.club>
This commit is contained in:
		
							parent
							
								
									eb3acc334b
								
							
						
					
					
						commit
						eff2da2518
					
				| @ -413,4 +413,9 @@ public class VirtualMachineTO { | |||||||
|     public void setDeployAsIsInfo(DeployAsIsInfoTO deployAsIsInfo) { |     public void setDeployAsIsInfo(DeployAsIsInfoTO deployAsIsInfo) { | ||||||
|         this.deployAsIsInfo = deployAsIsInfo; |         this.deployAsIsInfo = deployAsIsInfo; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return String.format("VM {id: \"%s\", name: \"%s\", uuid: \"%s\", type: \"%s\"}", id, name, uuid, type); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -209,6 +209,71 @@ import com.google.common.base.Strings; | |||||||
| public class LibvirtComputingResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer { | public class LibvirtComputingResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer { | ||||||
|     private static final Logger s_logger = Logger.getLogger(LibvirtComputingResource.class); |     private static final Logger s_logger = Logger.getLogger(LibvirtComputingResource.class); | ||||||
| 
 | 
 | ||||||
|  |     private static final String LEGACY = "legacy"; | ||||||
|  |     private static final String SECURE = "secure"; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Machine type. | ||||||
|  |      */ | ||||||
|  |     private static final String PC = "pc"; | ||||||
|  |     private static final String VIRT = "virt"; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Possible devices to add to VM. | ||||||
|  |      */ | ||||||
|  |     private static final String TABLET = "tablet"; | ||||||
|  |     private static final String USB = "usb"; | ||||||
|  |     private static final String MOUSE = "mouse"; | ||||||
|  |     private static final String KEYBOARD = "keyboard"; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Policies used by VM. | ||||||
|  |      */ | ||||||
|  |     private static final String RESTART = "restart"; | ||||||
|  |     private static final String DESTROY = "destroy"; | ||||||
|  | 
 | ||||||
|  |     private static final String KVMCLOCK = "kvmclock"; | ||||||
|  |     private static final String HYPERVCLOCK = "hypervclock"; | ||||||
|  |     private static final String WINDOWS = "Windows"; | ||||||
|  |     private static final String Q35 = "q35"; | ||||||
|  |     private static final String PTY = "pty"; | ||||||
|  |     private static final String VNC = "vnc"; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Acronym of System Management Mode. Perform low-level system management operations while an OS is running. | ||||||
|  |      */ | ||||||
|  |     private static final String SMM = "smm"; | ||||||
|  |     /** | ||||||
|  |      * Acronym of Advanced Configuration and Power Interface.<br> | ||||||
|  |      * Provides an open standard that operating systems can use to discover and configure | ||||||
|  |      * computer hardware components, to perform power management. | ||||||
|  |      */ | ||||||
|  |     private static final String ACPI = "acpi"; | ||||||
|  |     /** | ||||||
|  |      * Acronym of Advanced Programmable Interrupt Controllers.<br> | ||||||
|  |      * With an I/O APIC, operating systems can use more than 16 interrupt requests (IRQs) | ||||||
|  |      * and therefore avoid IRQ sharing for improved reliability. | ||||||
|  |      */ | ||||||
|  |     private static final String APIC = "apic"; | ||||||
|  |     /** | ||||||
|  |      * Acronym of Physical Address Extension. Feature implemented in modern x86 processors.<br> | ||||||
|  |      * PAE extends memory addressing capabilities, allowing more than 4 GB of random access memory (RAM) to be used. | ||||||
|  |      */ | ||||||
|  |     private static final String PAE = "pae"; | ||||||
|  |     /** | ||||||
|  |      * Libvirt supports guest CPU mode since 0.9.10. | ||||||
|  |      */ | ||||||
|  |     private static final int MIN_LIBVIRT_VERSION_FOR_GUEST_CPU_MODE = 9010; | ||||||
|  |     /** | ||||||
|  |      * The CPU tune element provides details of the CPU tunable parameters for the domain.<br> | ||||||
|  |      * It is supported since Libvirt 0.9.0 | ||||||
|  |      */ | ||||||
|  |     private static final int MIN_LIBVIRT_VERSION_FOR_GUEST_CPU_TUNE = 9000; | ||||||
|  |     /** | ||||||
|  |      * Constant that defines ARM64 (aarch64) guest architectures. | ||||||
|  |      */ | ||||||
|  |     private static final String AARCH64 = "aarch64"; | ||||||
|  | 
 | ||||||
|     private String _modifyVlanPath; |     private String _modifyVlanPath; | ||||||
|     private String _versionstringpath; |     private String _versionstringpath; | ||||||
|     private String _patchScriptPath; |     private String _patchScriptPath; | ||||||
| @ -2239,8 +2304,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Creates VM KVM definitions from virtual machine transfer object specifications. | ||||||
|  |      */ | ||||||
|     public LibvirtVMDef createVMFromSpec(final VirtualMachineTO vmTO) { |     public LibvirtVMDef createVMFromSpec(final VirtualMachineTO vmTO) { | ||||||
|         final LibvirtVMDef vm = new LibvirtVMDef(); |         s_logger.debug(String.format("Creating VM from specifications [%s]", vmTO.toString())); | ||||||
|  | 
 | ||||||
|  |         LibvirtVMDef vm = new LibvirtVMDef(); | ||||||
|         vm.setDomainName(vmTO.getName()); |         vm.setDomainName(vmTO.getName()); | ||||||
|         String uuid = vmTO.getUuid(); |         String uuid = vmTO.getUuid(); | ||||||
|         uuid = getUuid(uuid); |         uuid = getUuid(uuid); | ||||||
| @ -2251,215 +2321,311 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv | |||||||
|         Map<String, String> customParams = vmTO.getDetails(); |         Map<String, String> customParams = vmTO.getDetails(); | ||||||
|         boolean isUefiEnabled = false; |         boolean isUefiEnabled = false; | ||||||
|         boolean isSecureBoot = false; |         boolean isSecureBoot = false; | ||||||
|         String bootMode =null; |         String bootMode = null; | ||||||
|  | 
 | ||||||
|         if (MapUtils.isNotEmpty(customParams) && customParams.containsKey(GuestDef.BootType.UEFI.toString())) { |         if (MapUtils.isNotEmpty(customParams) && customParams.containsKey(GuestDef.BootType.UEFI.toString())) { | ||||||
|             isUefiEnabled = true; |             isUefiEnabled = true; | ||||||
|             bootMode = customParams.get(GuestDef.BootType.UEFI.toString()); |             s_logger.debug(String.format("Enabled UEFI for VM UUID [%s].", uuid)); | ||||||
|             if (StringUtils.isNotBlank(bootMode) && "secure".equalsIgnoreCase(bootMode)) { | 
 | ||||||
|  |             if (isSecureMode(customParams.get(GuestDef.BootType.UEFI.toString()))) { | ||||||
|  |                 s_logger.debug(String.format("Enabled Secure Boot for VM UUID [%s].", uuid)); | ||||||
|                 isSecureBoot = true; |                 isSecureBoot = true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Map<String, String> extraConfig = vmTO.getExtraConfig(); |         Map<String, String> extraConfig = vmTO.getExtraConfig(); | ||||||
|         if (dpdkSupport && (!extraConfig.containsKey(DpdkHelper.DPDK_NUMA) || !extraConfig.containsKey(DpdkHelper.DPDK_HUGE_PAGES))) { |         if (dpdkSupport && (!extraConfig.containsKey(DpdkHelper.DPDK_NUMA) || !extraConfig.containsKey(DpdkHelper.DPDK_HUGE_PAGES))) { | ||||||
|             s_logger.info("DPDK is enabled but it needs extra configurations for CPU NUMA and Huge Pages for VM deployment"); |             s_logger.info(String.format("DPDK is enabled for VM [%s], but it needs extra configurations for CPU NUMA and Huge Pages for VM deployment.", vmTO.toString())); | ||||||
|  |         } | ||||||
|  |         configureVM(vmTO, vm, customParams, isUefiEnabled, isSecureBoot, bootMode, extraConfig, uuid); | ||||||
|  |         return vm; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Configures created VM from specification, adding the necessary components to VM. | ||||||
|  |      */ | ||||||
|  |     private void configureVM(VirtualMachineTO vmTO, LibvirtVMDef vm, Map<String, String> customParams, boolean isUefiEnabled, boolean isSecureBoot, String bootMode, | ||||||
|  |             Map<String, String> extraConfig, String uuid) { | ||||||
|  |         s_logger.debug(String.format("Configuring VM with UUID [%s].", uuid)); | ||||||
|  | 
 | ||||||
|  |         GuestDef guest = createGuestFromSpec(vmTO, vm, uuid, customParams); | ||||||
|  |         if (isUefiEnabled) { | ||||||
|  |             configureGuestIfUefiEnabled(isSecureBoot, bootMode, guest); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         final GuestDef guest = new GuestDef(); |         vm.addComp(guest); | ||||||
|  |         vm.addComp(createGuestResourceDef(vmTO)); | ||||||
| 
 | 
 | ||||||
|         if (HypervisorType.LXC == _hypervisorType && VirtualMachine.Type.User == vmTO.getType()) { |         int vcpus = vmTO.getCpus(); | ||||||
|             // LXC domain is only valid for user VMs. Use KVM for system VMs. |         if (!extraConfig.containsKey(DpdkHelper.DPDK_NUMA)) { | ||||||
|             guest.setGuestType(GuestDef.GuestType.LXC); |             vm.addComp(createCpuModeDef(vmTO, vcpus)); | ||||||
|             vm.setHvsType(HypervisorType.LXC.toString().toLowerCase()); |  | ||||||
|         } else { |  | ||||||
|             guest.setGuestType(GuestDef.GuestType.KVM); |  | ||||||
|             vm.setHvsType(HypervisorType.KVM.toString().toLowerCase()); |  | ||||||
|             vm.setLibvirtVersion(_hypervisorLibvirtVersion); |  | ||||||
|             vm.setQemuVersion(_hypervisorQemuVersion); |  | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         if (_hypervisorLibvirtVersion >= MIN_LIBVIRT_VERSION_FOR_GUEST_CPU_TUNE) { | ||||||
|  |             vm.addComp(createCpuTuneDef(vmTO)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         FeaturesDef features = createFeaturesDef(customParams, isUefiEnabled, isSecureBoot); | ||||||
|  |         enlightenWindowsVm(vmTO, features); | ||||||
|  |         vm.addComp(features); | ||||||
|  | 
 | ||||||
|  |         vm.addComp(createTermPolicy()); | ||||||
|  |         vm.addComp(createClockDef(vmTO)); | ||||||
|  |         vm.addComp(createDevicesDef(vmTO, guest, vcpus, isUefiEnabled)); | ||||||
|  | 
 | ||||||
|  |         addExtraConfigsToVM(vmTO, vm, extraConfig); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      *  Adds extra configuration to User VM Domain XML before starting. | ||||||
|  |      */ | ||||||
|  |     private void addExtraConfigsToVM(VirtualMachineTO vmTO, LibvirtVMDef vm, Map<String, String> extraConfig) { | ||||||
|  |         if (MapUtils.isNotEmpty(extraConfig) && VirtualMachine.Type.User.equals(vmTO.getType())) { | ||||||
|  |             s_logger.debug(String.format("Appending extra configuration data [%s] to guest VM [%s] domain XML.", extraConfig, vmTO.toString())); | ||||||
|  |             addExtraConfigComponent(extraConfig, vm); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Adds devices components to VM. | ||||||
|  |      */ | ||||||
|  |     protected DevicesDef createDevicesDef(VirtualMachineTO vmTO, GuestDef guest, int vcpus, boolean isUefiEnabled) { | ||||||
|  |         DevicesDef devices = new DevicesDef(); | ||||||
|  |         devices.setEmulatorPath(_hypervisorPath); | ||||||
|  |         devices.setGuestType(guest.getGuestType()); | ||||||
|  |         devices.addDevice(createSerialDef()); | ||||||
|  | 
 | ||||||
|  |         if (_rngEnable) { | ||||||
|  |             devices.addDevice(createRngDef()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         devices.addDevice(createChannelDef(vmTO)); | ||||||
|  |         devices.addDevice(createWatchDogDef()); | ||||||
|  |         devices.addDevice(createVideoDef()); | ||||||
|  |         devices.addDevice(createConsoleDef()); | ||||||
|  |         devices.addDevice(createGraphicDef(vmTO)); | ||||||
|  |         devices.addDevice(createTabletInputDef()); | ||||||
|  | 
 | ||||||
|  |         if (isGuestAarch64()) { | ||||||
|  |             createArm64UsbDef(devices); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         DiskDef.DiskBus busT = getDiskModelFromVMDetail(vmTO); | ||||||
|  |         if (busT == null) { | ||||||
|  |             busT = getGuestDiskModel(vmTO.getPlatformEmulator(), isUefiEnabled); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (busT == DiskDef.DiskBus.SCSI) { | ||||||
|  |             devices.addDevice(createSCSIDef(vcpus)); | ||||||
|  |         } | ||||||
|  |         return devices; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected WatchDogDef createWatchDogDef() { | ||||||
|  |         return new WatchDogDef(_watchDogAction, _watchDogModel); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected void createArm64UsbDef(DevicesDef devices) { | ||||||
|  |         devices.addDevice(new InputDef(KEYBOARD, USB)); | ||||||
|  |         devices.addDevice(new InputDef(MOUSE, USB)); | ||||||
|  |         devices.addDevice(new LibvirtVMDef.USBDef((short)0, 0, 5, 0, 0)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected InputDef createTabletInputDef() { | ||||||
|  |         return new InputDef(TABLET, USB); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Creates a Libvirt Graphic Definition with the VM's password and VNC address. | ||||||
|  |      */ | ||||||
|  |     protected GraphicDef createGraphicDef(VirtualMachineTO vmTO) { | ||||||
|  |         return new GraphicDef(VNC, (short)0, true, vmTO.getVncAddr(), vmTO.getVncPassword(), null); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Adds a Virtio channel for the Qemu Guest Agent tools. | ||||||
|  |      */ | ||||||
|  |     protected ChannelDef createChannelDef(VirtualMachineTO vmTO) { | ||||||
|  |         File virtIoChannel = Paths.get(_qemuSocketsPath.getPath(), vmTO.getName() + "." + _qemuGuestAgentSocketName).toFile(); | ||||||
|  |         return new ChannelDef(_qemuGuestAgentSocketName, ChannelDef.ChannelType.UNIX, virtIoChannel); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Creates Virtio SCSI controller. <br> | ||||||
|  |      * The respective Virtio SCSI XML definition is generated only if the VM's Disk Bus is of ISCSI. | ||||||
|  |      */ | ||||||
|  |     protected SCSIDef createSCSIDef(int vcpus) { | ||||||
|  |         return new SCSIDef((short)0, 0, 0, 9, 0, vcpus); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected ConsoleDef createConsoleDef() { | ||||||
|  |         return new ConsoleDef(PTY, null, null, (short)0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected VideoDef createVideoDef() { | ||||||
|  |         return new VideoDef(_videoHw, _videoRam); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected RngDef createRngDef() { | ||||||
|  |         return new RngDef(_rngPath, _rngBackendModel, _rngRateBytes, _rngRatePeriod); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected SerialDef createSerialDef() { | ||||||
|  |         return new SerialDef(PTY, null, (short)0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected ClockDef createClockDef(final VirtualMachineTO vmTO) { | ||||||
|  |         ClockDef clock = new ClockDef(); | ||||||
|  |         if (org.apache.commons.lang.StringUtils.startsWith(vmTO.getOs(), WINDOWS)) { | ||||||
|  |             clock.setClockOffset(ClockDef.ClockOffset.LOCALTIME); | ||||||
|  |             clock.setTimer(HYPERVCLOCK, null, null); | ||||||
|  |         } else if ((vmTO.getType() != VirtualMachine.Type.User || isGuestPVEnabled(vmTO.getOs())) && _hypervisorLibvirtVersion >= MIN_LIBVIRT_VERSION_FOR_GUEST_CPU_MODE) { | ||||||
|  |             clock.setTimer(KVMCLOCK, null, null, _noKvmClock); | ||||||
|  |         } | ||||||
|  |         return clock; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected TermPolicy createTermPolicy() { | ||||||
|  |         TermPolicy term = new TermPolicy(); | ||||||
|  |         term.setCrashPolicy(DESTROY); | ||||||
|  |         term.setPowerOffPolicy(DESTROY); | ||||||
|  |         term.setRebootPolicy(RESTART); | ||||||
|  |         return term; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected FeaturesDef createFeaturesDef(Map<String, String> customParams, boolean isUefiEnabled, boolean isSecureBoot) { | ||||||
|  |         FeaturesDef features = new FeaturesDef(); | ||||||
|  |         features.addFeatures(PAE); | ||||||
|  |         features.addFeatures(APIC); | ||||||
|  |         features.addFeatures(ACPI); | ||||||
|  |         if (isUefiEnabled && isSecureBoot) { | ||||||
|  |             features.addFeatures(SMM); | ||||||
|  |         } | ||||||
|  |         return features; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * A 4.0.X/4.1.X management server doesn't send the correct JSON | ||||||
|  |      * command for getMinSpeed, it only sends a 'speed' field.<br> | ||||||
|  |      * So, to create a cpu tune,  if getMinSpeed() returns null we fall back to getSpeed().<br> | ||||||
|  |      * This way a >4.1 agent can work communicate a <=4.1 management server.<br> | ||||||
|  |      * This change is due to the overcommit feature in 4.2. | ||||||
|  |      */ | ||||||
|  |     protected CpuTuneDef createCpuTuneDef(VirtualMachineTO vmTO) { | ||||||
|  |         CpuTuneDef ctd = new CpuTuneDef(); | ||||||
|  |         int shares = vmTO.getCpus() * (vmTO.getMinSpeed() != null ? vmTO.getMinSpeed() : vmTO.getSpeed()); | ||||||
|  |         ctd.setShares(shares); | ||||||
|  |         setQuotaAndPeriod(vmTO, ctd); | ||||||
|  |         return ctd; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private CpuModeDef createCpuModeDef(VirtualMachineTO vmTO, int vcpus) { | ||||||
|  |         final CpuModeDef cmd = new CpuModeDef(); | ||||||
|  |         cmd.setMode(_guestCpuMode); | ||||||
|  |         cmd.setModel(_guestCpuModel); | ||||||
|  |         if (VirtualMachine.Type.User.equals(vmTO.getType())) { | ||||||
|  |             cmd.setFeatures(_cpuFeatures); | ||||||
|  |         } | ||||||
|  |         setCpuTopology(cmd, vcpus, vmTO.getDetails()); | ||||||
|  |         return cmd; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Creates guest resources based in VM specification. | ||||||
|  |      */ | ||||||
|  |     protected GuestResourceDef createGuestResourceDef(VirtualMachineTO vmTO) { | ||||||
|  |         GuestResourceDef grd = new GuestResourceDef(); | ||||||
|  | 
 | ||||||
|  |         grd.setMemorySize(vmTO.getMaxRam() / 1024); | ||||||
|  |         if (vmTO.getMinRam() != vmTO.getMaxRam() && !_noMemBalloon) { | ||||||
|  |             grd.setMemBalloning(true); | ||||||
|  |             grd.setCurrentMem(vmTO.getMinRam() / 1024); | ||||||
|  |         } | ||||||
|  |         grd.setVcpuNum(vmTO.getCpus()); | ||||||
|  |         return grd; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void configureGuestIfUefiEnabled(boolean isSecureBoot, String bootMode, GuestDef guest) { | ||||||
|  |         setGuestLoader(bootMode, SECURE, guest, GuestDef.GUEST_LOADER_SECURE); | ||||||
|  |         setGuestLoader(bootMode, LEGACY, guest, GuestDef.GUEST_LOADER_LEGACY); | ||||||
|  | 
 | ||||||
|  |         if (isUefiPropertieNotNull(GuestDef.GUEST_NVRAM_PATH)) { | ||||||
|  |             guest.setNvram(_uefiProperties.getProperty(GuestDef.GUEST_NVRAM_PATH)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (isSecureBoot && isUefiPropertieNotNull(GuestDef.GUEST_NVRAM_TEMPLATE_SECURE) && SECURE.equalsIgnoreCase(bootMode)) { | ||||||
|  |             guest.setNvramTemplate(_uefiProperties.getProperty(GuestDef.GUEST_NVRAM_TEMPLATE_SECURE)); | ||||||
|  |         } else if (isUefiPropertieNotNull(GuestDef.GUEST_NVRAM_TEMPLATE_LEGACY)) { | ||||||
|  |             guest.setNvramTemplate(_uefiProperties.getProperty(GuestDef.GUEST_NVRAM_TEMPLATE_LEGACY)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void setGuestLoader(String bootMode, String mode, GuestDef guest, String propertie) { | ||||||
|  |         if (isUefiPropertieNotNull(propertie) && mode.equalsIgnoreCase(bootMode)) { | ||||||
|  |             guest.setLoader(_uefiProperties.getProperty(propertie)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private boolean isUefiPropertieNotNull(String propertie) { | ||||||
|  |         return _uefiProperties.getProperty(propertie) != null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private boolean isGuestAarch64() { | ||||||
|  |         return AARCH64.equals(_guestCpuArch); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Creates a guest definition from a VM specification. | ||||||
|  |      */ | ||||||
|  |     protected GuestDef createGuestFromSpec(VirtualMachineTO vmTO, LibvirtVMDef vm, String uuid, Map<String, String> customParams) { | ||||||
|  |         GuestDef guest = new GuestDef(); | ||||||
|  | 
 | ||||||
|  |         configureGuestAndVMHypervisorType(vmTO, vm, guest); | ||||||
|         guest.setGuestArch(_guestCpuArch != null ? _guestCpuArch : vmTO.getArch()); |         guest.setGuestArch(_guestCpuArch != null ? _guestCpuArch : vmTO.getArch()); | ||||||
|         guest.setMachineType(_guestCpuArch != null && _guestCpuArch.equals("aarch64") ? "virt" : "pc"); |         guest.setMachineType(isGuestAarch64() ? VIRT : PC); | ||||||
|         guest.setBootType(GuestDef.BootType.BIOS); |         guest.setBootType(GuestDef.BootType.BIOS); | ||||||
|         if (MapUtils.isNotEmpty(customParams) && customParams.containsKey(GuestDef.BootType.UEFI.toString())) { |         if (MapUtils.isNotEmpty(customParams) && customParams.containsKey(GuestDef.BootType.UEFI.toString())) { | ||||||
|             guest.setBootType(GuestDef.BootType.UEFI); |             guest.setBootType(GuestDef.BootType.UEFI); | ||||||
|             guest.setBootMode(GuestDef.BootMode.LEGACY); |             guest.setBootMode(GuestDef.BootMode.LEGACY); | ||||||
|             guest.setMachineType("q35"); |             guest.setMachineType(Q35); | ||||||
|             if (StringUtils.isNotBlank(customParams.get(GuestDef.BootType.UEFI.toString())) && "secure".equalsIgnoreCase(customParams.get(GuestDef.BootType.UEFI.toString()))) { |             if (SECURE.equalsIgnoreCase(customParams.get(GuestDef.BootType.UEFI.toString()))) { | ||||||
|                 guest.setBootMode(GuestDef.BootMode.SECURE); // setting to secure mode |                 guest.setBootMode(GuestDef.BootMode.SECURE); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         guest.setUuid(uuid); |         guest.setUuid(uuid); | ||||||
|         guest.setBootOrder(GuestDef.BootOrder.CDROM); |         guest.setBootOrder(GuestDef.BootOrder.CDROM); | ||||||
|         guest.setBootOrder(GuestDef.BootOrder.HARDISK); |         guest.setBootOrder(GuestDef.BootOrder.HARDISK); | ||||||
|  |         return guest; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         if (isUefiEnabled) { |     protected void configureGuestAndVMHypervisorType(VirtualMachineTO vmTO, LibvirtVMDef vm, GuestDef guest) { | ||||||
|             if (_uefiProperties.getProperty(GuestDef.GUEST_LOADER_SECURE) != null && "secure".equalsIgnoreCase(bootMode)) { |         if (HypervisorType.LXC == _hypervisorType && VirtualMachine.Type.User.equals(vmTO.getType())) { | ||||||
|                 guest.setLoader(_uefiProperties.getProperty(GuestDef.GUEST_LOADER_SECURE)); |             configureGuestAndUserVMToUseLXC(vm, guest); | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (_uefiProperties.getProperty(GuestDef.GUEST_LOADER_LEGACY) != null && "legacy".equalsIgnoreCase(bootMode)) { |  | ||||||
|                 guest.setLoader(_uefiProperties.getProperty(GuestDef.GUEST_LOADER_LEGACY)); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (_uefiProperties.getProperty(GuestDef.GUEST_NVRAM_PATH) != null) { |  | ||||||
|                 guest.setNvram(_uefiProperties.getProperty(GuestDef.GUEST_NVRAM_PATH)); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (isSecureBoot) { |  | ||||||
|                 if (_uefiProperties.getProperty(GuestDef.GUEST_NVRAM_TEMPLATE_SECURE) != null && "secure".equalsIgnoreCase(bootMode)) { |  | ||||||
|                     guest.setNvramTemplate(_uefiProperties.getProperty(GuestDef.GUEST_NVRAM_TEMPLATE_SECURE)); |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
|                 if (_uefiProperties.getProperty(GuestDef.GUEST_NVRAM_TEMPLATE_LEGACY) != null) { |  | ||||||
|                     guest.setNvramTemplate(_uefiProperties.getProperty(GuestDef.GUEST_NVRAM_TEMPLATE_LEGACY)); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|             vm.addComp(guest); |  | ||||||
| 
 |  | ||||||
|         final GuestResourceDef grd = new GuestResourceDef(); |  | ||||||
| 
 |  | ||||||
|         if (vmTO.getMinRam() != vmTO.getMaxRam() && !_noMemBalloon) { |  | ||||||
|             grd.setMemBalloning(true); |  | ||||||
|             grd.setCurrentMem(vmTO.getMinRam() / 1024); |  | ||||||
|             grd.setMemorySize(vmTO.getMaxRam() / 1024); |  | ||||||
|         } else { |         } else { | ||||||
|             grd.setMemorySize(vmTO.getMaxRam() / 1024); |             configureGuestAndSystemVMToUseKVM(vm, guest); | ||||||
|         } |         } | ||||||
|         final int vcpus = vmTO.getCpus(); |  | ||||||
|         grd.setVcpuNum(vcpus); |  | ||||||
|         vm.addComp(grd); |  | ||||||
| 
 |  | ||||||
|         if (!extraConfig.containsKey(DpdkHelper.DPDK_NUMA)) { |  | ||||||
|             final CpuModeDef cmd = new CpuModeDef(); |  | ||||||
|             cmd.setMode(_guestCpuMode); |  | ||||||
|             cmd.setModel(_guestCpuModel); |  | ||||||
|             if (vmTO.getType() == VirtualMachine.Type.User) { |  | ||||||
|                 cmd.setFeatures(_cpuFeatures); |  | ||||||
|             } |  | ||||||
|             setCpuTopology(cmd, vcpus, vmTO.getDetails()); |  | ||||||
|             vm.addComp(cmd); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (_hypervisorLibvirtVersion >= 9000) { |  | ||||||
|             final CpuTuneDef ctd = new CpuTuneDef(); |  | ||||||
|             /** |  | ||||||
|              A 4.0.X/4.1.X management server doesn't send the correct JSON |  | ||||||
|              command for getMinSpeed, it only sends a 'speed' field. |  | ||||||
| 
 |  | ||||||
|              So if getMinSpeed() returns null we fall back to getSpeed(). |  | ||||||
| 
 |  | ||||||
|              This way a >4.1 agent can work communicate a <=4.1 management server |  | ||||||
| 
 |  | ||||||
|              This change is due to the overcommit feature in 4.2 |  | ||||||
|              */ |  | ||||||
|             if (vmTO.getMinSpeed() != null) { |  | ||||||
|                 ctd.setShares(vmTO.getCpus() * vmTO.getMinSpeed()); |  | ||||||
|             } else { |  | ||||||
|                 ctd.setShares(vmTO.getCpus() * vmTO.getSpeed()); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             setQuotaAndPeriod(vmTO, ctd); |  | ||||||
| 
 |  | ||||||
|             vm.addComp(ctd); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         final FeaturesDef features = new FeaturesDef(); |  | ||||||
|         features.addFeatures("pae"); |  | ||||||
|         features.addFeatures("apic"); |  | ||||||
|         features.addFeatures("acpi"); |  | ||||||
|         if (isUefiEnabled && isSecureMode(customParams.get(GuestDef.BootType.UEFI.toString()))) { |  | ||||||
|             features.addFeatures("smm"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         //KVM hyperv enlightenment features based on OS Type |  | ||||||
|         enlightenWindowsVm(vmTO, features); |  | ||||||
| 
 |  | ||||||
|         vm.addComp(features); |  | ||||||
| 
 |  | ||||||
|         final TermPolicy term = new TermPolicy(); |  | ||||||
|         term.setCrashPolicy("destroy"); |  | ||||||
|         term.setPowerOffPolicy("destroy"); |  | ||||||
|         term.setRebootPolicy("restart"); |  | ||||||
|         vm.addComp(term); |  | ||||||
| 
 |  | ||||||
|         final ClockDef clock = new ClockDef(); |  | ||||||
|         if (vmTO.getOs().startsWith("Windows")) { |  | ||||||
|             clock.setClockOffset(ClockDef.ClockOffset.LOCALTIME); |  | ||||||
|             clock.setTimer("hypervclock", null, null); |  | ||||||
|         } else if (vmTO.getType() != VirtualMachine.Type.User || isGuestPVEnabled(vmTO.getOs())) { |  | ||||||
|             if (_hypervisorLibvirtVersion >= 9 * 1000 + 10) { |  | ||||||
|                 clock.setTimer("kvmclock", null, null, _noKvmClock); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         vm.addComp(clock); |  | ||||||
| 
 |  | ||||||
|         final DevicesDef devices = new DevicesDef(); |  | ||||||
|         devices.setEmulatorPath(_hypervisorPath); |  | ||||||
|         devices.setGuestType(guest.getGuestType()); |  | ||||||
| 
 |  | ||||||
|         final SerialDef serial = new SerialDef("pty", null, (short)0); |  | ||||||
|         devices.addDevice(serial); |  | ||||||
| 
 |  | ||||||
|         if (_rngEnable) { |  | ||||||
|             final RngDef rngDevice = new RngDef(_rngPath, _rngBackendModel, _rngRateBytes, _rngRatePeriod); |  | ||||||
|             devices.addDevice(rngDevice); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         /* Add a VirtIO channel for the Qemu Guest Agent tools */ |  | ||||||
|         File virtIoChannel = Paths.get(_qemuSocketsPath.getPath(), vmTO.getName() + "." + _qemuGuestAgentSocketName).toFile(); |  | ||||||
|         devices.addDevice(new ChannelDef(_qemuGuestAgentSocketName, ChannelDef.ChannelType.UNIX, virtIoChannel)); |  | ||||||
| 
 |  | ||||||
|         devices.addDevice(new WatchDogDef(_watchDogAction, _watchDogModel)); |  | ||||||
| 
 |  | ||||||
|         final VideoDef videoCard = new VideoDef(_videoHw, _videoRam); |  | ||||||
|         devices.addDevice(videoCard); |  | ||||||
| 
 |  | ||||||
|         final ConsoleDef console = new ConsoleDef("pty", null, null, (short)0); |  | ||||||
|         devices.addDevice(console); |  | ||||||
| 
 |  | ||||||
|         //add the VNC port passwd here, get the passwd from the vmInstance. |  | ||||||
|         final String passwd = vmTO.getVncPassword(); |  | ||||||
|         final GraphicDef grap = new GraphicDef("vnc", (short)0, true, vmTO.getVncAddr(), passwd, null); |  | ||||||
|         devices.addDevice(grap); |  | ||||||
| 
 |  | ||||||
|         final InputDef input = new InputDef("tablet", "usb"); |  | ||||||
|         devices.addDevice(input); |  | ||||||
| 
 |  | ||||||
|         // Add an explicit USB devices for ARM64 |  | ||||||
|         if (_guestCpuArch != null && _guestCpuArch.equals("aarch64")) { |  | ||||||
|             devices.addDevice(new InputDef("keyboard", "usb")); |  | ||||||
|             devices.addDevice(new InputDef("mouse", "usb")); |  | ||||||
|             devices.addDevice(new LibvirtVMDef.USBDef((short)0, 0, 5, 0, 0)); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         DiskDef.DiskBus busT = getDiskModelFromVMDetail(vmTO); |  | ||||||
| 
 |  | ||||||
|         if (busT == null) { |  | ||||||
|             busT = getGuestDiskModel(vmTO.getPlatformEmulator(), isUefiEnabled); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // If we're using virtio scsi, then we need to add a virtual scsi controller |  | ||||||
|         if (busT == DiskDef.DiskBus.SCSI) { |  | ||||||
|             final SCSIDef sd = new SCSIDef((short)0, 0, 0, 9, 0, vcpus); |  | ||||||
|             devices.addDevice(sd); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         vm.addComp(devices); |  | ||||||
| 
 |  | ||||||
|         // Add extra configuration to User VM Domain XML before starting |  | ||||||
|         if (vmTO.getType().equals(VirtualMachine.Type.User) && MapUtils.isNotEmpty(extraConfig)) { |  | ||||||
|             s_logger.info("Appending extra configuration data to guest VM domain XML"); |  | ||||||
|             addExtraConfigComponent(extraConfig, vm); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return vm; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Add extra configurations (if any) as a String component to the domain XML |      * KVM domain is only valid for system VMs. Use LXC for user VMs. | ||||||
|  |      */ | ||||||
|  |     private void configureGuestAndSystemVMToUseKVM(LibvirtVMDef vm, GuestDef guest) { | ||||||
|  |         guest.setGuestType(GuestDef.GuestType.KVM); | ||||||
|  |         vm.setHvsType(HypervisorType.KVM.toString().toLowerCase()); | ||||||
|  |         vm.setLibvirtVersion(_hypervisorLibvirtVersion); | ||||||
|  |         vm.setQemuVersion(_hypervisorQemuVersion); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * LXC domain is only valid for user VMs. Use KVM for system VMs. | ||||||
|  |      */ | ||||||
|  |     private void configureGuestAndUserVMToUseLXC(LibvirtVMDef vm, GuestDef guest) { | ||||||
|  |         guest.setGuestType(GuestDef.GuestType.LXC); | ||||||
|  |         vm.setHvsType(HypervisorType.LXC.toString().toLowerCase()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Adds extra configurations (if any) as a String component to the domain XML | ||||||
|      */ |      */ | ||||||
|     protected void addExtraConfigComponent(Map<String, String> extraConfig, LibvirtVMDef vm) { |     protected void addExtraConfigComponent(Map<String, String> extraConfig, LibvirtVMDef vm) { | ||||||
|         if (MapUtils.isNotEmpty(extraConfig)) { |         if (MapUtils.isNotEmpty(extraConfig)) { | ||||||
|  | |||||||
| @ -79,6 +79,7 @@ import org.libvirt.jna.virDomainMemoryStats; | |||||||
| import org.mockito.BDDMockito; | import org.mockito.BDDMockito; | ||||||
| import org.mockito.Mock; | import org.mockito.Mock; | ||||||
| import org.mockito.Mockito; | import org.mockito.Mockito; | ||||||
|  | import org.mockito.Spy; | ||||||
| import org.mockito.invocation.InvocationOnMock; | import org.mockito.invocation.InvocationOnMock; | ||||||
| import org.powermock.api.mockito.PowerMockito; | import org.powermock.api.mockito.PowerMockito; | ||||||
| import org.powermock.core.classloader.annotations.PowerMockIgnore; | import org.powermock.core.classloader.annotations.PowerMockIgnore; | ||||||
| @ -160,11 +161,27 @@ import com.cloud.agent.api.to.VirtualMachineTO; | |||||||
| import com.cloud.agent.api.to.VolumeTO; | import com.cloud.agent.api.to.VolumeTO; | ||||||
| import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; | import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; | ||||||
| import com.cloud.exception.InternalErrorException; | import com.cloud.exception.InternalErrorException; | ||||||
|  | import com.cloud.hypervisor.Hypervisor.HypervisorType; | ||||||
| import com.cloud.hypervisor.kvm.resource.KVMHABase.NfsStoragePool; | import com.cloud.hypervisor.kvm.resource.KVMHABase.NfsStoragePool; | ||||||
| import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef; | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ClockDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ConsoleDef; | ||||||
| import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuTuneDef; | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuTuneDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DevicesDef; | ||||||
| import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.FeaturesDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GraphicDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestDef.GuestType; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestResourceDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InputDef; | ||||||
| import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SCSIDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VideoDef; | ||||||
|  | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef; | ||||||
| import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper; | import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper; | ||||||
| import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper; | import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper; | ||||||
| import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; | import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; | ||||||
| @ -201,6 +218,8 @@ public class LibvirtComputingResourceTest { | |||||||
|     VirtualMachineTO vmTO; |     VirtualMachineTO vmTO; | ||||||
|     @Mock |     @Mock | ||||||
|     LibvirtVMDef vmDef; |     LibvirtVMDef vmDef; | ||||||
|  |     @Spy | ||||||
|  |     private LibvirtComputingResource libvirtComputingResourceSpy = Mockito.spy(LibvirtComputingResource.class); | ||||||
| 
 | 
 | ||||||
|     private final static long HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IOURING = 6003000; |     private final static long HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IOURING = 6003000; | ||||||
|     private final static long HYPERVISOR_QEMU_VERSION_SUPPORTS_IOURING = 5000000; |     private final static long HYPERVISOR_QEMU_VERSION_SUPPORTS_IOURING = 5000000; | ||||||
| @ -217,6 +236,7 @@ public class LibvirtComputingResourceTest { | |||||||
| 
 | 
 | ||||||
|     @Before |     @Before | ||||||
|     public void setup() throws Exception { |     public void setup() throws Exception { | ||||||
|  |         libvirtComputingResourceSpy._qemuSocketsPath = new File("/var/run/qemu"); | ||||||
|         Scanner scanner = new Scanner(memInfo); |         Scanner scanner = new Scanner(memInfo); | ||||||
|         PowerMockito.whenNew(Scanner.class).withAnyArguments().thenReturn(scanner); |         PowerMockito.whenNew(Scanner.class).withAnyArguments().thenReturn(scanner); | ||||||
|     } |     } | ||||||
| @ -243,15 +263,13 @@ public class LibvirtComputingResourceTest { | |||||||
|         final String vncAddr = ""; |         final String vncAddr = ""; | ||||||
|         final String vncPassword = "mySuperSecretPassword"; |         final String vncPassword = "mySuperSecretPassword"; | ||||||
| 
 | 
 | ||||||
|         final LibvirtComputingResource lcr = new LibvirtComputingResource(); |  | ||||||
|         lcr._qemuSocketsPath = new File("/var/run/qemu"); |  | ||||||
| 
 |  | ||||||
|         final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, speed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); |         final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, speed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); | ||||||
|         to.setVncAddr(vncAddr); |         to.setVncAddr(vncAddr); | ||||||
|         to.setArch("x86_64"); |         to.setArch("x86_64"); | ||||||
|         to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); |         to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); | ||||||
|  |         to.setVcpuMaxLimit(cpus + 1); | ||||||
| 
 | 
 | ||||||
|         final LibvirtVMDef vm = lcr.createVMFromSpec(to); |         final LibvirtVMDef vm = libvirtComputingResourceSpy.createVMFromSpec(to); | ||||||
|         vm.setHvsType(hyperVisorType); |         vm.setHvsType(hyperVisorType); | ||||||
| 
 | 
 | ||||||
|         verifyVm(to, vm); |         verifyVm(to, vm); | ||||||
| @ -276,15 +294,13 @@ public class LibvirtComputingResourceTest { | |||||||
|         final String vncAddr = ""; |         final String vncAddr = ""; | ||||||
|         final String vncPassword = "mySuperSecretPassword"; |         final String vncPassword = "mySuperSecretPassword"; | ||||||
| 
 | 
 | ||||||
|         final LibvirtComputingResource lcr = new LibvirtComputingResource(); |  | ||||||
|         lcr._qemuSocketsPath = new File("/var/run/qemu"); |  | ||||||
| 
 |  | ||||||
|         final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); |         final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); | ||||||
|         to.setVncAddr(vncAddr); |         to.setVncAddr(vncAddr); | ||||||
|         to.setArch("x86_64"); |         to.setArch("x86_64"); | ||||||
|         to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); |         to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); | ||||||
|  |         to.setVcpuMaxLimit(cpus + 1); | ||||||
| 
 | 
 | ||||||
|         final LibvirtVMDef vm = lcr.createVMFromSpec(to); |         final LibvirtVMDef vm = libvirtComputingResourceSpy.createVMFromSpec(to); | ||||||
|         vm.setHvsType(hyperVisorType); |         vm.setHvsType(hyperVisorType); | ||||||
| 
 | 
 | ||||||
|         verifyVm(to, vm); |         verifyVm(to, vm); | ||||||
| @ -309,14 +325,11 @@ public class LibvirtComputingResourceTest { | |||||||
|         final String vncAddr = ""; |         final String vncAddr = ""; | ||||||
|         final String vncPassword = "mySuperSecretPassword"; |         final String vncPassword = "mySuperSecretPassword"; | ||||||
| 
 | 
 | ||||||
|         final LibvirtComputingResource lcr = new LibvirtComputingResource(); |  | ||||||
|         lcr._qemuSocketsPath = new File("/var/run/qemu"); |  | ||||||
| 
 |  | ||||||
|         final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); |         final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); | ||||||
|         to.setVncAddr(vncAddr); |         to.setVncAddr(vncAddr); | ||||||
|         to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); |         to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); | ||||||
| 
 | 
 | ||||||
|         final LibvirtVMDef vm = lcr.createVMFromSpec(to); |         LibvirtVMDef vm = libvirtComputingResourceSpy.createVMFromSpec(to); | ||||||
|         vm.setHvsType(hyperVisorType); |         vm.setHvsType(hyperVisorType); | ||||||
| 
 | 
 | ||||||
|         verifyVm(to, vm); |         verifyVm(to, vm); | ||||||
| @ -331,59 +344,388 @@ public class LibvirtComputingResourceTest { | |||||||
|      */ |      */ | ||||||
|     @Test |     @Test | ||||||
|     public void testCreateVMFromSpec() { |     public void testCreateVMFromSpec() { | ||||||
|         final int id = random.nextInt(65534); |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|         final String name = "test-instance-1"; |         final LibvirtVMDef vm = libvirtComputingResourceSpy.createVMFromSpec(to); | ||||||
| 
 |  | ||||||
|         final int cpus = random.nextInt(2) + 1; |  | ||||||
|         final int minSpeed = 1024; |  | ||||||
|         final int maxSpeed = 2048; |  | ||||||
|         final int minRam = 256 * 1024; |  | ||||||
|         final int maxRam = 512 * 1024; |  | ||||||
| 
 |  | ||||||
|         final String os = "Ubuntu"; |  | ||||||
| 
 |  | ||||||
|         final String vncAddr = ""; |  | ||||||
|         final String vncPassword = "mySuperSecretPassword"; |  | ||||||
| 
 |  | ||||||
|         final LibvirtComputingResource lcr = new LibvirtComputingResource(); |  | ||||||
|         lcr._qemuSocketsPath = new File("/var/run/qemu"); |  | ||||||
| 
 |  | ||||||
|         final VirtualMachineTO to = |  | ||||||
|                 new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); |  | ||||||
|         to.setVncAddr(vncAddr); |  | ||||||
|         to.setArch("x86_64"); |  | ||||||
|         to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); |  | ||||||
| 
 |  | ||||||
|         final LibvirtVMDef vm = lcr.createVMFromSpec(to); |  | ||||||
|         vm.setHvsType(hyperVisorType); |         vm.setHvsType(hyperVisorType); | ||||||
| 
 | 
 | ||||||
|         verifyVm(to, vm); |         verifyVm(to, vm); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void verifyVm(final VirtualMachineTO to, final LibvirtVMDef vm) { |     @Test | ||||||
|         final Document domainDoc = parse(vm.toString()); |     public void testCreateGuestFromSpecWithoutCustomParam() { | ||||||
|         assertXpath(domainDoc, "/domain/@type", vm.getHvsType()); |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|         assertXpath(domainDoc, "/domain/name/text()", to.getName()); |         LibvirtVMDef vm = new LibvirtVMDef(); | ||||||
|         assertXpath(domainDoc, "/domain/uuid/text()", to.getUuid()); |         GuestDef guestDef = libvirtComputingResourceSpy.createGuestFromSpec(to, vm, to.getUuid(), null); | ||||||
|         assertXpath(domainDoc, "/domain/description/text()", to.getOs()); |         verifySysInfo(guestDef, "smbios", to.getUuid(), "pc"); | ||||||
|         assertXpath(domainDoc, "/domain/clock/@offset", "utc"); |         Assert.assertEquals(GuestDef.BootType.BIOS, guestDef.getBootType()); | ||||||
|         assertNodeExists(domainDoc, "/domain/features/pae"); |         Assert.assertNull(guestDef.getBootMode()); | ||||||
|         assertNodeExists(domainDoc, "/domain/features/apic"); |     } | ||||||
|         assertNodeExists(domainDoc, "/domain/features/acpi"); |  | ||||||
|         assertXpath(domainDoc, "/domain/devices/serial/@type", "pty"); |  | ||||||
|         assertXpath(domainDoc, "/domain/devices/serial/target/@port", "0"); |  | ||||||
|         assertXpath(domainDoc, "/domain/devices/graphics/@type", "vnc"); |  | ||||||
|         assertXpath(domainDoc, "/domain/devices/graphics/@listen", to.getVncAddr()); |  | ||||||
|         assertXpath(domainDoc, "/domain/devices/graphics/@autoport", "yes"); |  | ||||||
|         assertXpath(domainDoc, "/domain/devices/graphics/@passwd", to.getVncPassword()); |  | ||||||
| 
 | 
 | ||||||
|         assertXpath(domainDoc, "/domain/devices/console/@type", "pty"); |     @Test | ||||||
|         assertXpath(domainDoc, "/domain/devices/console/target/@port", "0"); |     public void testCreateGuestFromSpecWithCustomParamAndUefi() { | ||||||
|         assertXpath(domainDoc, "/domain/devices/input/@type", "tablet"); |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|         assertXpath(domainDoc, "/domain/devices/input/@bus", "usb"); |  | ||||||
| 
 | 
 | ||||||
|         assertNodeExists(domainDoc, "/domain/devices/channel"); |         Map<String, String> extraConfig = new HashMap<>(); | ||||||
|         assertXpath(domainDoc, "/domain/devices/channel/@type", ChannelDef.ChannelType.UNIX.toString()); |         extraConfig.put(GuestDef.BootType.UEFI.toString(), "legacy"); | ||||||
|  | 
 | ||||||
|  |         LibvirtVMDef vm = new LibvirtVMDef(); | ||||||
|  | 
 | ||||||
|  |         GuestDef guestDef = libvirtComputingResourceSpy.createGuestFromSpec(to, vm, to.getUuid(), extraConfig); | ||||||
|  |         verifySysInfo(guestDef, "smbios", to.getUuid(), "q35"); | ||||||
|  |         Assert.assertEquals(GuestDef.BootType.UEFI, guestDef.getBootType()); | ||||||
|  |         Assert.assertEquals(GuestDef.BootMode.LEGACY, guestDef.getBootMode()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateGuestFromSpecWithCustomParamUefiAndSecure() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  | 
 | ||||||
|  |         Map<String, String> extraConfig = new HashMap<>(); | ||||||
|  |         extraConfig.put(GuestDef.BootType.UEFI.toString(), "secure"); | ||||||
|  | 
 | ||||||
|  |         LibvirtVMDef vm = new LibvirtVMDef(); | ||||||
|  | 
 | ||||||
|  |         GuestDef guestDef = libvirtComputingResourceSpy.createGuestFromSpec(to, vm, to.getUuid(), extraConfig); | ||||||
|  |         verifySysInfo(guestDef, "smbios", to.getUuid(), "q35"); | ||||||
|  |         Assert.assertEquals(GuestDef.BootType.UEFI, guestDef.getBootType()); | ||||||
|  |         Assert.assertEquals(GuestDef.BootMode.SECURE, guestDef.getBootMode()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateGuestResourceDef() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  | 
 | ||||||
|  |         GuestResourceDef guestResourceDef = libvirtComputingResourceSpy.createGuestResourceDef(to); | ||||||
|  |         verifyGuestResourceDef(guestResourceDef, to); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateDevicesDef() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  | 
 | ||||||
|  |         GuestDef guest = new GuestDef(); | ||||||
|  |         guest.setGuestType(GuestType.KVM); | ||||||
|  | 
 | ||||||
|  |         DevicesDef devicesDef = libvirtComputingResourceSpy.createDevicesDef(to, guest, to.getCpus() + 1, false); | ||||||
|  |         verifyDevices(devicesDef, to); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateDevicesWithSCSIDisk() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         to.setDetails(new HashMap<>()); | ||||||
|  |         libvirtComputingResourceSpy._guestCpuArch = "aarch64"; | ||||||
|  | 
 | ||||||
|  |         GuestDef guest = new GuestDef(); | ||||||
|  |         guest.setGuestType(GuestType.KVM); | ||||||
|  | 
 | ||||||
|  |         DevicesDef devicesDef = libvirtComputingResourceSpy.createDevicesDef(to, guest, to.getCpus() + 1, false); | ||||||
|  |         verifyDevices(devicesDef, to); | ||||||
|  | 
 | ||||||
|  |         Document domainDoc = parse(devicesDef.toString()); | ||||||
|  |         assertNodeExists(domainDoc, "/devices/controller[@type='scsi']"); | ||||||
|  |         assertNodeExists(domainDoc, "/devices/controller[@model='virtio-scsi']"); | ||||||
|  |         assertNodeExists(domainDoc, "/devices/controller/address[@type='pci']"); | ||||||
|  |         assertNodeExists(domainDoc, "/devices/controller/driver[@queues='" + (to.getCpus() + 1) + "']"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testConfigureGuestAndSystemVMToUseKVM() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         libvirtComputingResourceSpy._hypervisorLibvirtVersion = 100; | ||||||
|  |         libvirtComputingResourceSpy._hypervisorQemuVersion = 10; | ||||||
|  |         LibvirtVMDef vm = new LibvirtVMDef(); | ||||||
|  | 
 | ||||||
|  |         GuestDef guestFromSpec = libvirtComputingResourceSpy.createGuestFromSpec(to, vm, to.getUuid(), null); | ||||||
|  |         Assert.assertEquals(GuestDef.GuestType.KVM, guestFromSpec.getGuestType()); | ||||||
|  |         Assert.assertEquals(HypervisorType.KVM.toString().toLowerCase(), vm.getHvsType()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testConfigureGuestAndUserVMToUseLXC() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         libvirtComputingResourceSpy._hypervisorType = HypervisorType.LXC; | ||||||
|  |         LibvirtVMDef vm = new LibvirtVMDef(); | ||||||
|  | 
 | ||||||
|  |         GuestDef guestFromSpec = libvirtComputingResourceSpy.createGuestFromSpec(to, vm, to.getUuid(), null); | ||||||
|  |         Assert.assertEquals(GuestDef.GuestType.LXC, guestFromSpec.getGuestType()); | ||||||
|  |         Assert.assertEquals(HypervisorType.LXC.toString().toLowerCase(), vm.getHvsType()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateCpuTuneDefWithoutQuotaAndPeriod() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  | 
 | ||||||
|  |         CpuTuneDef cpuTuneDef = libvirtComputingResourceSpy.createCpuTuneDef(to); | ||||||
|  |         Document domainDoc = parse(cpuTuneDef.toString()); | ||||||
|  |         assertXpath(domainDoc, "/cputune/shares/text()", String.valueOf(cpuTuneDef.getShares())); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateCpuTuneDefWithQuotaAndPeriod() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(true); | ||||||
|  |         to.setCpuQuotaPercentage(10.0); | ||||||
|  | 
 | ||||||
|  |         CpuTuneDef cpuTuneDef = libvirtComputingResourceSpy.createCpuTuneDef(to); | ||||||
|  |         Document domainDoc = parse(cpuTuneDef.toString()); | ||||||
|  |         assertXpath(domainDoc, "/cputune/shares/text()", String.valueOf(cpuTuneDef.getShares())); | ||||||
|  |         assertXpath(domainDoc, "/cputune/quota/text()", String.valueOf(cpuTuneDef.getQuota())); | ||||||
|  |         assertXpath(domainDoc, "/cputune/period/text()", String.valueOf(cpuTuneDef.getPeriod())); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateCpuTuneDefWithMinQuota() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(true); | ||||||
|  |         to.setCpuQuotaPercentage(0.01); | ||||||
|  | 
 | ||||||
|  |         CpuTuneDef cpuTuneDef = libvirtComputingResourceSpy.createCpuTuneDef(to); | ||||||
|  |         Document domainDoc = parse(cpuTuneDef.toString()); | ||||||
|  |         assertXpath(domainDoc, "/cputune/shares/text()", String.valueOf(cpuTuneDef.getShares())); | ||||||
|  |         assertXpath(domainDoc, "/cputune/quota/text()", "1000"); | ||||||
|  |         assertXpath(domainDoc, "/cputune/period/text()", String.valueOf(cpuTuneDef.getPeriod())); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateDefaultClockDef() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  | 
 | ||||||
|  |         ClockDef clockDef = libvirtComputingResourceSpy.createClockDef(to); | ||||||
|  |         Document domainDoc = parse(clockDef.toString()); | ||||||
|  | 
 | ||||||
|  |         assertXpath(domainDoc, "/clock/@offset", "utc"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateClockDefWindows() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         to.setOs("Windows"); | ||||||
|  | 
 | ||||||
|  |         ClockDef clockDef = libvirtComputingResourceSpy.createClockDef(to); | ||||||
|  |         Document domainDoc = parse(clockDef.toString()); | ||||||
|  | 
 | ||||||
|  |         assertXpath(domainDoc, "/clock/@offset", "localtime"); | ||||||
|  |         assertXpath(domainDoc, "/clock/timer/@name", "hypervclock"); | ||||||
|  |         assertXpath(domainDoc, "/clock/timer/@present", "yes"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateClockDefKvmclock() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         libvirtComputingResourceSpy._hypervisorLibvirtVersion = 9020; | ||||||
|  | 
 | ||||||
|  |         ClockDef clockDef = libvirtComputingResourceSpy.createClockDef(to); | ||||||
|  |         Document domainDoc = parse(clockDef.toString()); | ||||||
|  | 
 | ||||||
|  |         assertXpath(domainDoc, "/clock/@offset", "utc"); | ||||||
|  |         assertXpath(domainDoc, "/clock/timer/@name", "kvmclock"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateTermPolicy() { | ||||||
|  |         TermPolicy termPolicy = libvirtComputingResourceSpy.createTermPolicy(); | ||||||
|  | 
 | ||||||
|  |         String xml = "<terms>\n" + termPolicy.toString() + "</terms>"; | ||||||
|  |         Document domainDoc = parse(xml); | ||||||
|  | 
 | ||||||
|  |         assertXpath(domainDoc, "/terms/on_reboot/text()", "restart"); | ||||||
|  |         assertXpath(domainDoc, "/terms/on_poweroff/text()", "destroy"); | ||||||
|  |         assertXpath(domainDoc, "/terms/on_crash/text()", "destroy"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateFeaturesDef() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         FeaturesDef featuresDef = libvirtComputingResourceSpy.createFeaturesDef(null, false, false); | ||||||
|  | 
 | ||||||
|  |         String xml = "<domain>" + featuresDef.toString() + "</domain>"; | ||||||
|  |         Document domainDoc = parse(xml); | ||||||
|  | 
 | ||||||
|  |         verifyFeatures(domainDoc); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateFeaturesDefWithUefi() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         HashMap<String, String> extraConfig = new HashMap<>(); | ||||||
|  |         extraConfig.put(GuestDef.BootType.UEFI.toString(), ""); | ||||||
|  | 
 | ||||||
|  |         FeaturesDef featuresDef = libvirtComputingResourceSpy.createFeaturesDef(extraConfig, true, true); | ||||||
|  | 
 | ||||||
|  |         String xml = "<domain>" + featuresDef.toString() + "</domain>"; | ||||||
|  |         Document domainDoc = parse(xml); | ||||||
|  | 
 | ||||||
|  |         verifyFeatures(domainDoc); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateWatchDog() { | ||||||
|  |         WatchDogDef watchDogDef = libvirtComputingResourceSpy.createWatchDogDef(); | ||||||
|  |         verifyWatchDogDevices(parse(watchDogDef.toString()), ""); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateArm64UsbDef() { | ||||||
|  |         DevicesDef devicesDef = new DevicesDef(); | ||||||
|  | 
 | ||||||
|  |         libvirtComputingResourceSpy.createArm64UsbDef(devicesDef); | ||||||
|  |         Document domainDoc = parse(devicesDef.toString()); | ||||||
|  | 
 | ||||||
|  |         assertXpath(domainDoc, "/devices/controller/@type", "usb"); | ||||||
|  |         assertXpath(domainDoc, "/devices/controller/@model", "qemu-xhci"); | ||||||
|  |         assertXpath(domainDoc, "/devices/controller/address/@type", "pci"); | ||||||
|  |         assertNodeExists(domainDoc, "/devices/input[@type='keyboard']"); | ||||||
|  |         assertNodeExists(domainDoc, "/devices/input[@bus='usb']"); | ||||||
|  |         assertNodeExists(domainDoc, "/devices/input[@type='mouse']"); | ||||||
|  |         assertNodeExists(domainDoc, "/devices/input[@bus='usb']"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateInputDef() { | ||||||
|  |         InputDef inputDef = libvirtComputingResourceSpy.createTabletInputDef(); | ||||||
|  |         verifyTabletInputDevice(parse(inputDef.toString()), ""); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateGraphicDef() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         GraphicDef graphicDef = libvirtComputingResourceSpy.createGraphicDef(to); | ||||||
|  |         verifyGraphicsDevices(to, parse(graphicDef.toString()), ""); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateChannelDef() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         ChannelDef channelDef = libvirtComputingResourceSpy.createChannelDef(to); | ||||||
|  |         verifyChannelDevices(to, parse(channelDef.toString()), ""); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateSCSIDef() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  | 
 | ||||||
|  |         SCSIDef scsiDef = libvirtComputingResourceSpy.createSCSIDef(to.getCpus()); | ||||||
|  |         Document domainDoc = parse(scsiDef.toString()); | ||||||
|  |         verifyScsi(to, domainDoc, ""); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateConsoleDef() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         ConsoleDef consoleDef = libvirtComputingResourceSpy.createConsoleDef(); | ||||||
|  |         verifyConsoleDevices(parse(consoleDef.toString()), ""); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateVideoDef() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         libvirtComputingResourceSpy._videoRam = 200; | ||||||
|  |         libvirtComputingResourceSpy._videoHw = "vGPU"; | ||||||
|  | 
 | ||||||
|  |         VideoDef videoDef = libvirtComputingResourceSpy.createVideoDef(); | ||||||
|  |         Document domainDoc = parse(videoDef.toString()); | ||||||
|  |         assertXpath(domainDoc, "/video/model/@type", "vGPU"); | ||||||
|  |         assertXpath(domainDoc, "/video/model/@vram", "200"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateRngDef() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         RngDef rngDef = libvirtComputingResourceSpy.createRngDef(); | ||||||
|  |         Document domainDoc = parse(rngDef.toString()); | ||||||
|  | 
 | ||||||
|  |         assertXpath(domainDoc, "/rng/@model", "virtio"); | ||||||
|  |         assertXpath(domainDoc, "/rng/rate/@period", "1000"); | ||||||
|  |         assertXpath(domainDoc, "/rng/rate/@bytes", "2048"); | ||||||
|  |         assertXpath(domainDoc, "/rng/backend/@model", "random"); | ||||||
|  |         assertXpath(domainDoc, "/rng/backend/text()", "/dev/random"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateSerialDef() { | ||||||
|  |         VirtualMachineTO to = createDefaultVM(false); | ||||||
|  |         SerialDef serialDef = libvirtComputingResourceSpy.createSerialDef(); | ||||||
|  |         verifySerialDevices(parse(serialDef.toString()), ""); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private VirtualMachineTO createDefaultVM(boolean limitCpuUse) { | ||||||
|  |         int id = random.nextInt(65534); | ||||||
|  |         String name = "test-instance-1"; | ||||||
|  | 
 | ||||||
|  |         int cpus = random.nextInt(2) + 1; | ||||||
|  |         int minSpeed = 1024; | ||||||
|  |         int maxSpeed = 2048; | ||||||
|  |         int minRam = 256 * 1024; | ||||||
|  |         int maxRam = 512 * 1024; | ||||||
|  | 
 | ||||||
|  |         String os = "Ubuntu"; | ||||||
|  |         String vncAddr = ""; | ||||||
|  |         String vncPassword = "mySuperSecretPassword"; | ||||||
|  | 
 | ||||||
|  |         final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, limitCpuUse, | ||||||
|  |                 vncPassword); | ||||||
|  |         to.setArch("x86_64"); | ||||||
|  |         to.setVncAddr(vncAddr); | ||||||
|  |         to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); | ||||||
|  |         to.setVcpuMaxLimit(cpus + 1); | ||||||
|  | 
 | ||||||
|  |         return to; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyGuestResourceDef(GuestResourceDef guestResourceDef, VirtualMachineTO to) { | ||||||
|  |         String xml = "<domain>" + guestResourceDef.toString() + "</domain>"; | ||||||
|  |         Document domainDoc = parse(xml); | ||||||
|  | 
 | ||||||
|  |         String minRam = String.valueOf(to.getMinRam() / 1024); | ||||||
|  |         verifyMemory(to, domainDoc, minRam); | ||||||
|  |         assertNodeExists(domainDoc, "/domain/vcpu"); | ||||||
|  |         verifyMemballoonDevices(domainDoc); | ||||||
|  |         verifyVcpu(to, domainDoc); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyVm(VirtualMachineTO to, LibvirtVMDef vm) { | ||||||
|  |         Document domainDoc = parse(vm.toString()); | ||||||
|  |         verifyHeader(domainDoc, vm.getHvsType(), to.getName(), to.getUuid(), to.getOs()); | ||||||
|  |         verifyFeatures(domainDoc); | ||||||
|  |         verifyClock(domainDoc); | ||||||
|  |         verifySerialDevices(domainDoc, "/domain/devices"); | ||||||
|  |         verifyGraphicsDevices(to, domainDoc, "/domain/devices"); | ||||||
|  |         verifyConsoleDevices(domainDoc, "/domain/devices"); | ||||||
|  |         verifyTabletInputDevice(domainDoc, "/domain/devices"); | ||||||
|  |         verifyChannelDevices(to, domainDoc, "/domain/devices"); | ||||||
|  | 
 | ||||||
|  |         String minRam = String.valueOf(to.getMinRam() / 1024); | ||||||
|  |         verifyMemory(to, domainDoc, minRam); | ||||||
|  |         assertNodeExists(domainDoc, "/domain/cpu"); | ||||||
|  | 
 | ||||||
|  |         verifyMemballoonDevices(domainDoc); | ||||||
|  |         verifyVcpu(to, domainDoc); | ||||||
|  |         verifyOsType(domainDoc); | ||||||
|  |         verifyOsBoot(domainDoc); | ||||||
|  |         verifyPoliticOn_(domainDoc); | ||||||
|  |         verifyWatchDogDevices(domainDoc, "/domain/devices"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyMemballoonDevices(Document domainDoc) { | ||||||
|  |         assertXpath(domainDoc, "/domain/devices/memballoon/@model", "virtio"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyVcpu(VirtualMachineTO to, Document domainDoc) { | ||||||
|  |         assertXpath(domainDoc, "/domain/vcpu/text()", String.valueOf(to.getCpus())); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyMemory(VirtualMachineTO to, Document domainDoc, String minRam) { | ||||||
|  |         assertXpath(domainDoc, "/domain/memory/text()", String.valueOf(to.getMaxRam() / 1024)); | ||||||
|  |         assertXpath(domainDoc, "/domain/currentMemory/text()", minRam); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyWatchDogDevices(Document domainDoc, String prefix) { | ||||||
|  |         assertXpath(domainDoc, prefix + "/watchdog/@model", "i6300esb"); | ||||||
|  |         assertXpath(domainDoc, prefix + "/watchdog/@action", "none"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyChannelDevices(VirtualMachineTO to, Document domainDoc, String prefix) { | ||||||
|  |         assertNodeExists(domainDoc, prefix + "/channel"); | ||||||
|  |         assertXpath(domainDoc, prefix + "/channel/@type", ChannelDef.ChannelType.UNIX.toString()); | ||||||
| 
 | 
 | ||||||
|         /* |         /* | ||||||
|            The configure() method of LibvirtComputingResource has not been called, so the default path for the sockets |            The configure() method of LibvirtComputingResource has not been called, so the default path for the sockets | ||||||
| @ -392,28 +734,93 @@ public class LibvirtComputingResourceTest { | |||||||
|            Calling configure is also not possible since that looks for certain files on the system which are not present |            Calling configure is also not possible since that looks for certain files on the system which are not present | ||||||
|            during testing |            during testing | ||||||
|          */ |          */ | ||||||
|         assertXpath(domainDoc, "/domain/devices/channel/source/@path", "/var/run/qemu/" + to.getName() + ".org.qemu.guest_agent.0"); |         assertXpath(domainDoc, prefix + "/channel/source/@path", "/var/run/qemu/" + to.getName() + ".org.qemu.guest_agent.0"); | ||||||
|         assertXpath(domainDoc, "/domain/devices/channel/target/@name", "org.qemu.guest_agent.0"); |         assertXpath(domainDoc, prefix + "/channel/target/@name", "org.qemu.guest_agent.0"); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         assertXpath(domainDoc, "/domain/memory/text()", String.valueOf( to.getMaxRam() / 1024 )); |     private void verifyTabletInputDevice(Document domainDoc, String prefix) { | ||||||
|         assertXpath(domainDoc, "/domain/currentMemory/text()", String.valueOf( to.getMinRam() / 1024 )); |         assertXpath(domainDoc, prefix + "/input/@type", "tablet"); | ||||||
|  |         assertXpath(domainDoc, prefix + "/input/@bus", "usb"); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         assertXpath(domainDoc, "/domain/devices/memballoon/@model", "virtio"); |     private void verifyConsoleDevices(Document domainDoc, String prefix) { | ||||||
|         assertXpath(domainDoc, "/domain/vcpu/text()", String.valueOf(to.getCpus())); |         assertXpath(domainDoc, prefix + "/console/@type", "pty"); | ||||||
|  |         assertXpath(domainDoc, prefix + "/console/target/@port", "0"); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         assertXpath(domainDoc, "/domain/os/type/@machine", "pc"); |     private void verifyScsi(VirtualMachineTO to, Document domainDoc, String prefix) { | ||||||
|         assertXpath(domainDoc, "/domain/os/type/text()", "hvm"); |         assertXpath(domainDoc, prefix + "/controller/@type", "scsi"); | ||||||
|  |         assertXpath(domainDoc, prefix + "/controller/@model", "virtio-scsi"); | ||||||
|  |         assertXpath(domainDoc, prefix + "/controller/address/@type", "pci"); | ||||||
|  |         assertXpath(domainDoc, prefix + "/controller/driver/@queues", String.valueOf(to.getCpus())); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         assertNodeExists(domainDoc, "/domain/cpu"); |     private void verifyClock(Document domainDoc) { | ||||||
|  |         assertXpath(domainDoc, "/domain/clock/@offset", "utc"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyGraphicsDevices(VirtualMachineTO to, Document domainDoc, String prefix) { | ||||||
|  |         assertXpath(domainDoc, prefix + "/graphics/@type", "vnc"); | ||||||
|  |         assertXpath(domainDoc, prefix + "/graphics/@listen", to.getVncAddr()); | ||||||
|  |         assertXpath(domainDoc, prefix + "/graphics/@autoport", "yes"); | ||||||
|  |         assertXpath(domainDoc, prefix + "/graphics/@passwd", to.getVncPassword()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifySerialDevices(Document domainDoc, String prefix) { | ||||||
|  |         assertXpath(domainDoc, prefix + "/serial/@type", "pty"); | ||||||
|  |         assertXpath(domainDoc, prefix + "/serial/target/@port", "0"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyOsBoot(Document domainDoc) { | ||||||
|         assertNodeExists(domainDoc, "/domain/os/boot[@dev='cdrom']"); |         assertNodeExists(domainDoc, "/domain/os/boot[@dev='cdrom']"); | ||||||
|         assertNodeExists(domainDoc, "/domain/os/boot[@dev='hd']"); |         assertNodeExists(domainDoc, "/domain/os/boot[@dev='hd']"); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|  |     private void verifyOsType(Document domainDoc) { | ||||||
|  |         assertXpath(domainDoc, "/domain/os/type/@machine", "pc"); | ||||||
|  |         assertXpath(domainDoc, "/domain/os/type/text()", "hvm"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyPoliticOn_(Document domainDoc) { | ||||||
|         assertXpath(domainDoc, "/domain/on_reboot/text()", "restart"); |         assertXpath(domainDoc, "/domain/on_reboot/text()", "restart"); | ||||||
|         assertXpath(domainDoc, "/domain/on_poweroff/text()", "destroy"); |         assertXpath(domainDoc, "/domain/on_poweroff/text()", "destroy"); | ||||||
|         assertXpath(domainDoc, "/domain/on_crash/text()", "destroy"); |         assertXpath(domainDoc, "/domain/on_crash/text()", "destroy"); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         assertXpath(domainDoc, "/domain/devices/watchdog/@model", "i6300esb"); |     private void verifyFeatures(Document domainDoc) { | ||||||
|         assertXpath(domainDoc, "/domain/devices/watchdog/@action", "none"); |         assertNodeExists(domainDoc, "/domain/features/pae"); | ||||||
|  |         assertNodeExists(domainDoc, "/domain/features/apic"); | ||||||
|  |         assertNodeExists(domainDoc, "/domain/features/acpi"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyHeader(Document domainDoc, String hvsType, String name, String uuid, String os) { | ||||||
|  |         assertXpath(domainDoc, "/domain/@type", hvsType); | ||||||
|  |         assertXpath(domainDoc, "/domain/name/text()", name); | ||||||
|  |         assertXpath(domainDoc, "/domain/uuid/text()", uuid); | ||||||
|  |         assertXpath(domainDoc, "/domain/description/text()", os); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifyDevices(DevicesDef devicesDef, VirtualMachineTO to) { | ||||||
|  |         Document domainDoc = parse(devicesDef.toString()); | ||||||
|  | 
 | ||||||
|  |         verifyWatchDogDevices(domainDoc, "/devices"); | ||||||
|  |         verifyConsoleDevices(domainDoc, "/devices"); | ||||||
|  |         verifySerialDevices(domainDoc, "/devices"); | ||||||
|  |         verifyGraphicsDevices(to, domainDoc, "/devices"); | ||||||
|  |         verifyChannelDevices(to, domainDoc, "/devices"); | ||||||
|  |         verifyTabletInputDevice(domainDoc, "/devices"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void verifySysInfo(GuestDef guestDef, String type, String uuid, String machine) { | ||||||
|  |         // Need put <guestdef> because the string of guestdef generate two root element in XML, raising a error in parse. | ||||||
|  |         String xml = "<guestdef>\n" + guestDef.toString() + "</guestdef>"; | ||||||
|  | 
 | ||||||
|  |         Document domainDoc = parse(xml); | ||||||
|  |         assertXpath(domainDoc, "/guestdef/sysinfo/@type", type); | ||||||
|  |         assertNodeExists(domainDoc, "/guestdef/sysinfo/system/entry[@name='manufacturer']"); | ||||||
|  |         assertNodeExists(domainDoc, "/guestdef/sysinfo/system/entry[@name='product']"); | ||||||
|  |         assertXpath(domainDoc, "/guestdef/sysinfo/system/entry[@name='uuid']/text()", uuid); | ||||||
|  |         assertXpath(domainDoc, "/guestdef/os/type/@machine", machine); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     static Document parse(final String input) { |     static Document parse(final String input) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user