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;
|
||||||
}
|
}
|
||||||
|
|
||||||
final GuestDef guest = new GuestDef();
|
/**
|
||||||
|
* 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));
|
||||||
|
|
||||||
if (HypervisorType.LXC == _hypervisorType && VirtualMachine.Type.User == vmTO.getType()) {
|
GuestDef guest = createGuestFromSpec(vmTO, vm, uuid, customParams);
|
||||||
// LXC domain is only valid for user VMs. Use KVM for system VMs.
|
if (isUefiEnabled) {
|
||||||
guest.setGuestType(GuestDef.GuestType.LXC);
|
configureGuestIfUefiEnabled(isSecureBoot, bootMode, guest);
|
||||||
vm.setHvsType(HypervisorType.LXC.toString().toLowerCase());
|
|
||||||
} else {
|
|
||||||
guest.setGuestType(GuestDef.GuestType.KVM);
|
|
||||||
vm.setHvsType(HypervisorType.KVM.toString().toLowerCase());
|
|
||||||
vm.setLibvirtVersion(_hypervisorLibvirtVersion);
|
|
||||||
vm.setQemuVersion(_hypervisorQemuVersion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm.addComp(guest);
|
||||||
|
vm.addComp(createGuestResourceDef(vmTO));
|
||||||
|
|
||||||
|
int vcpus = vmTO.getCpus();
|
||||||
|
if (!extraConfig.containsKey(DpdkHelper.DPDK_NUMA)) {
|
||||||
|
vm.addComp(createCpuModeDef(vmTO, vcpus));
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
|
||||||
if (_uefiProperties.getProperty(GuestDef.GUEST_LOADER_SECURE) != null && "secure".equalsIgnoreCase(bootMode)) {
|
|
||||||
guest.setLoader(_uefiProperties.getProperty(GuestDef.GUEST_LOADER_SECURE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_uefiProperties.getProperty(GuestDef.GUEST_LOADER_LEGACY) != null && "legacy".equalsIgnoreCase(bootMode)) {
|
protected void configureGuestAndVMHypervisorType(VirtualMachineTO vmTO, LibvirtVMDef vm, GuestDef guest) {
|
||||||
guest.setLoader(_uefiProperties.getProperty(GuestDef.GUEST_LOADER_LEGACY));
|
if (HypervisorType.LXC == _hypervisorType && VirtualMachine.Type.User.equals(vmTO.getType())) {
|
||||||
}
|
configureGuestAndUserVMToUseLXC(vm, guest);
|
||||||
|
|
||||||
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 {
|
} else {
|
||||||
if (_uefiProperties.getProperty(GuestDef.GUEST_NVRAM_TEMPLATE_LEGACY) != null) {
|
configureGuestAndSystemVMToUseKVM(vm, guest);
|
||||||
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 {
|
|
||||||
grd.setMemorySize(vmTO.getMaxRam() / 1024);
|
|
||||||
}
|
|
||||||
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
|
* KVM domain is only valid for system VMs. Use LXC for user VMs.
|
||||||
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) {
|
private void configureGuestAndSystemVMToUseKVM(LibvirtVMDef vm, GuestDef guest) {
|
||||||
ctd.setShares(vmTO.getCpus() * vmTO.getMinSpeed());
|
guest.setGuestType(GuestDef.GuestType.KVM);
|
||||||
} else {
|
vm.setHvsType(HypervisorType.KVM.toString().toLowerCase());
|
||||||
ctd.setShares(vmTO.getCpus() * vmTO.getSpeed());
|
vm.setLibvirtVersion(_hypervisorLibvirtVersion);
|
||||||
}
|
vm.setQemuVersion(_hypervisorQemuVersion);
|
||||||
|
|
||||||
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
|
* 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