From 24d4ebdce0a3c022c7ae7c90139235bb4c8dad67 Mon Sep 17 00:00:00 2001 From: Manuel Bentele Date: Thu, 25 Mar 2021 11:25:18 +0100 Subject: [qemu] Add filtering/transformation of config files and VM management --- .../vmchooser/plugins/qemu/run-virt.include | 7 +- core/modules/qemu/runvirt-plugin-qemu/.gitignore | 17 +- core/modules/qemu/runvirt-plugin-qemu/pom.xml | 8 + .../org/openslx/runvirt/configuration/Filter.java | 28 + .../runvirt/configuration/FilterException.java | 14 + .../runvirt/configuration/FilterFunction.java | 12 + .../runvirt/configuration/FilterGeneric.java | 9 + .../runvirt/configuration/FilterManager.java | 80 ++ .../runvirt/configuration/FilterSpecific.java | 18 + .../java/org/openslx/runvirt/plugin/qemu/App.java | 121 +++ .../runvirt/plugin/qemu/cmdln/CommandLineArgs.java | 43 +- .../qemu/configuration/FilterGenericCpu.java | 26 + .../FilterGenericDiskCdromDevices.java | 54 ++ .../FilterGenericDiskFloppyDevices.java | 50 ++ .../FilterGenericDiskStorageDevices.java | 49 + .../FilterGenericFileSystemDevices.java | 64 ++ .../FilterGenericInterfaceDevices.java | 48 + .../qemu/configuration/FilterGenericMemory.java | 28 + .../qemu/configuration/FilterGenericName.java | 23 + .../FilterGenericParallelDevices.java | 58 ++ .../qemu/configuration/FilterGenericUuid.java | 22 + .../FilterSpecificQemuArchitecture.java | 199 +++++ .../FilterSpecificQemuNvidiaGpuPassthrough.java | 26 + .../FilterSpecificQemuSerialDevices.java | 69 ++ .../qemu/virtualization/LibvirtHypervisorQemu.java | 39 + .../runvirt/virtualization/LibvirtHypervisor.java | 99 +++ .../virtualization/LibvirtHypervisorException.java | 14 + .../virtualization/LibvirtVirtualMachine.java | 81 ++ .../LibvirtVirtualMachineException.java | 14 + .../org/openslx/runvirt/plugin/qemu/AppTest.java | 8 +- .../plugin/qemu/cmdln/CommandLineArgsTest.java | 109 ++- .../qemu/configuration/FilterGenericCpuTest.java | 34 + .../FilterGenericDiskStorageDevicesTest.java | 61 ++ .../configuration/FilterGenericMemoryTest.java | 35 + .../qemu/configuration/FilterGenericNameTest.java | 30 + .../qemu/configuration/FilterGenericUuidTest.java | 28 + .../qemu/configuration/FilterTestResources.java | 17 + .../plugin/qemu/configuration/FilterTestUtils.java | 112 +++ .../libvirt/xml/qemu-kvm_capabilities_default.xml | 986 +++++++++++++++++++++ .../xml/qemu-kvm_default-ubuntu-20-04-vm.xml | 164 ++++ 40 files changed, 2877 insertions(+), 27 deletions(-) create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/Filter.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterException.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterFunction.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterGeneric.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterManager.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterSpecific.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericCpu.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskCdromDevices.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskFloppyDevices.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskStorageDevices.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericFileSystemDevices.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericInterfaceDevices.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericMemory.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericName.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericParallelDevices.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericUuid.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuArchitecture.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuNvidiaGpuPassthrough.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuSerialDevices.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/virtualization/LibvirtHypervisorQemu.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtHypervisor.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtHypervisorException.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtVirtualMachine.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtVirtualMachineException.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericCpuTest.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskStorageDevicesTest.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericMemoryTest.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericNameTest.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericUuidTest.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterTestResources.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterTestUtils.java create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/test/resources/libvirt/xml/qemu-kvm_capabilities_default.xml create mode 100644 core/modules/qemu/runvirt-plugin-qemu/src/test/resources/libvirt/xml/qemu-kvm_default-ubuntu-20-04-vm.xml diff --git a/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemu/run-virt.include b/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemu/run-virt.include index 5b320bcc..90a00c6e 100644 --- a/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemu/run-virt.include +++ b/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemu/run-virt.include @@ -19,7 +19,7 @@ declare -rg QEMU_PLUGIN_DIR="$(dirname "${BASH_SOURCE[0]}")" declare -rg QEMU_INCLUDE_DIR="${QEMU_PLUGIN_DIR}/includes" -# Define which features the VMware plugin supports +# Define which features the QEMU plugin supports declare -rg PLUGIN_FEATURES="firewall printer usb slxfloppy sound netshares" run_plugin() { @@ -45,5 +45,8 @@ run_plugin() { isset CDROM_1 && VIRTCMDOPTS+=( "-vmcdrom1" "${CDROM_1}" ) isset SERIAL0 && VIRTCMDOPTS+=( "-vmserial0" "${SERIAL0}" ) isset PARALLEL0 && VIRTCMDOPTS+=( "-vmparallel0" "${PARALLEL0}" ) - isset SOUND_DEV && VIRTCMDOPTS+=( "-vmsound0" "${SOUND_DEV}" ) + isset HOME_SHARE_PATH && VIRTCMDOPTS+=( "-vmfssrc0" "${HOME_SHARE_PATH}" ) + isset HOME_SHARE_NAME && VIRTCMDOPTS+=( "-vmfstgt0" "${HOME_SHARE_NAME}" ) + isset COMMON_SHARE_PATH && VIRTCMDOPTS+=( "-vmfssrc1" "${COMMON_SHARE_PATH}" ) + isset COMMON_SHARE_NAME && VIRTCMDOPTS+=( "-vmfstgt1" "${COMMON_SHARE_NAME}" ) } diff --git a/core/modules/qemu/runvirt-plugin-qemu/.gitignore b/core/modules/qemu/runvirt-plugin-qemu/.gitignore index 49b2bfee..6090294a 100644 --- a/core/modules/qemu/runvirt-plugin-qemu/.gitignore +++ b/core/modules/qemu/runvirt-plugin-qemu/.gitignore @@ -1,3 +1,14 @@ -/target/ -.classpath -.settings/ +/testing +/.settings +/.project +/.classpath +/target +/gen-java +*~ +!src/ +!test/ +*.swp + +# Ignore IntelliJ Project Files +/.idea +*.iml diff --git a/core/modules/qemu/runvirt-plugin-qemu/pom.xml b/core/modules/qemu/runvirt-plugin-qemu/pom.xml index 27f33991..197f3df3 100644 --- a/core/modules/qemu/runvirt-plugin-qemu/pom.xml +++ b/core/modules/qemu/runvirt-plugin-qemu/pom.xml @@ -154,5 +154,13 @@ 3.0.0 + + + ${basedir}/src/test/resources + + libvirt/xml/* + + + diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/Filter.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/Filter.java new file mode 100644 index 00000000..3fb594a2 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/Filter.java @@ -0,0 +1,28 @@ +package org.openslx.runvirt.configuration; + +public abstract class Filter implements FilterFunction +{ + private final String name; + private boolean enabled; + + public Filter( String name ) + { + this.name = name; + this.setEnabled( true ); + } + + public String getName() + { + return this.name; + } + + public boolean isEnabled() + { + return this.enabled; + } + + public void setEnabled( boolean enabled ) + { + this.enabled = enabled; + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterException.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterException.java new file mode 100644 index 00000000..8969d1a2 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterException.java @@ -0,0 +1,14 @@ +package org.openslx.runvirt.configuration; + +public class FilterException extends Exception +{ + /** + * Version for serialization. + */ + private static final long serialVersionUID = 7293420658901349154L; + + public FilterException( String errorMsg ) + { + super( errorMsg ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterFunction.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterFunction.java new file mode 100644 index 00000000..1d716201 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterFunction.java @@ -0,0 +1,12 @@ +package org.openslx.runvirt.configuration; + +@FunctionalInterface +public interface FilterFunction +{ + public void filter( T config, R args ) throws FilterException; + + public default void apply( T config, R args ) throws FilterException + { + this.filter( config, args ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterGeneric.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterGeneric.java new file mode 100644 index 00000000..e66c8f21 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterGeneric.java @@ -0,0 +1,9 @@ +package org.openslx.runvirt.configuration; + +public abstract class FilterGeneric extends Filter +{ + public FilterGeneric( String name ) + { + super( name ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterManager.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterManager.java new file mode 100644 index 00000000..a97ad6d1 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterManager.java @@ -0,0 +1,80 @@ +package org.openslx.runvirt.configuration; + +import java.util.ArrayList; + +public final class FilterManager +{ + private ArrayList> filters; + private T config; + private R args; + + public FilterManager( T config, R args ) + { + this.filters = new ArrayList>(); + this.config = config; + this.args = args; + } + + public void register( Filter filter ) + { + this.register( filter, true ); + } + + public void register( Filter filter, boolean enabled ) + { + filter.setEnabled( enabled ); + this.filters.add( filter ); + } + + public void register( String name, FilterFunction filterFunction ) + { + this.register( name, filterFunction, true ); + } + + public void register( String name, FilterFunction filterFunction, boolean enabled ) + { + final Filter filter = new Filter( name ) { + @Override + public void filter( T document, R args ) throws FilterException + { + filterFunction.apply( document, args ); + } + }; + + filter.setEnabled( enabled ); + this.filters.add( filter ); + } + + public void filterAll() throws FilterException + { + for ( Filter filter : this.filters ) { + try { + filter.apply( this.config, this.args ); + } catch ( FilterException e ) { + final String errorMsg = new String( + "Error in configuration filter '" + filter.getName() + "':" + e.getLocalizedMessage() ); + throw new FilterException( errorMsg ); + } + } + } + + private String showFilters() + { + String filterSummary = new String(); + final int maxFilterNumCharacters = ( this.filters.size() + 1 ) / 10; + + for ( int i = 0; i < this.filters.size(); i++ ) { + final Filter filter = this.filters.get( i ); + final String paddedNumber = String.format( "%-" + maxFilterNumCharacters + "s", i + 1 ); + filterSummary += paddedNumber + ": " + filter.getName() + System.lineSeparator(); + } + + return filterSummary; + } + + @Override + public String toString() + { + return this.showFilters(); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterSpecific.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterSpecific.java new file mode 100644 index 00000000..8cff83bd --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/configuration/FilterSpecific.java @@ -0,0 +1,18 @@ +package org.openslx.runvirt.configuration; + +public abstract class FilterSpecific extends Filter +{ + private final H hypervisor; + + public FilterSpecific( String name, H hypervisor ) + { + super( name ); + + this.hypervisor = hypervisor; + } + + public H getHypervisor() + { + return this.hypervisor; + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/App.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/App.java index 8a70be33..bf76ebf2 100644 --- a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/App.java +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/App.java @@ -1,11 +1,38 @@ package org.openslx.runvirt.plugin.qemu; +import java.io.File; + import org.apache.log4j.BasicConfigurator; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.xml.LibvirtXmlDocumentException; +import org.openslx.libvirt.xml.LibvirtXmlSerializationException; +import org.openslx.libvirt.xml.LibvirtXmlValidationException; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterManager; import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs.CmdLnOption; import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgsException; +import org.openslx.runvirt.plugin.qemu.configuration.FilterGenericCpu; +import org.openslx.runvirt.plugin.qemu.configuration.FilterGenericDiskCdromDevices; +import org.openslx.runvirt.plugin.qemu.configuration.FilterGenericDiskFloppyDevices; +import org.openslx.runvirt.plugin.qemu.configuration.FilterGenericDiskStorageDevices; +import org.openslx.runvirt.plugin.qemu.configuration.FilterGenericFileSystemDevices; +import org.openslx.runvirt.plugin.qemu.configuration.FilterGenericInterfaceDevices; +import org.openslx.runvirt.plugin.qemu.configuration.FilterGenericMemory; +import org.openslx.runvirt.plugin.qemu.configuration.FilterGenericName; +import org.openslx.runvirt.plugin.qemu.configuration.FilterGenericParallelDevices; +import org.openslx.runvirt.plugin.qemu.configuration.FilterSpecificQemuSerialDevices; +import org.openslx.runvirt.plugin.qemu.configuration.FilterGenericUuid; +import org.openslx.runvirt.plugin.qemu.configuration.FilterSpecificQemuArchitecture; +import org.openslx.runvirt.plugin.qemu.configuration.FilterSpecificQemuNvidiaGpuPassthrough; +import org.openslx.runvirt.plugin.qemu.virtualization.LibvirtHypervisorQemu; +import org.openslx.runvirt.plugin.qemu.virtualization.LibvirtHypervisorQemu.QemuSessionType; +import org.openslx.runvirt.virtualization.LibvirtHypervisor; +import org.openslx.runvirt.virtualization.LibvirtHypervisorException; +import org.openslx.runvirt.virtualization.LibvirtVirtualMachine; +import org.openslx.runvirt.virtualization.LibvirtVirtualMachineException; /** * Run-virt QEMU plugin (command line tool) to finalize a Libvirt domain XML configuration. @@ -65,6 +92,100 @@ public class App // print command line arguments for debugging purposes App.printCmdLnArgs( cmdLn ); + // create connection to the QEMU hypervisor via Libvirt + LibvirtHypervisor hypervisor = null; + try { + hypervisor = new LibvirtHypervisorQemu( QemuSessionType.LOCAL_USER_SESSION ); + } catch ( LibvirtHypervisorException e ) { + LOGGER.error( "Failed to connect to the QEMU virtualizer (Libvirt daemon): " + e.getLocalizedMessage() ); + System.exit( 2 ); + } + + // read Libvirt XML domain configuration template + final String xmlInputFileName = cmdLn.getVmCfgInpFileName(); + Domain config = null; + try { + final File xmlInputFile = new File( xmlInputFileName ); + config = new Domain( xmlInputFile ); + } catch ( LibvirtXmlDocumentException | LibvirtXmlSerializationException | LibvirtXmlValidationException e ) { + LOGGER.error( "Failed to read VM input configuration file: " + e.getLocalizedMessage() ); + hypervisor.close(); + System.exit( 3 ); + } + + // create filter manager to finalize VM configuration + final FilterManager filterManager; + filterManager = new FilterManager( config, cmdLn ); + + // register necessary filters to finalize configuration template + filterManager.register( new FilterGenericName(), true ); + filterManager.register( new FilterGenericUuid(), true ); + filterManager.register( new FilterGenericCpu(), true ); + filterManager.register( new FilterGenericMemory(), true ); + filterManager.register( new FilterGenericDiskStorageDevices(), true ); + filterManager.register( new FilterGenericDiskCdromDevices(), true ); + filterManager.register( new FilterGenericDiskFloppyDevices(), true ); + filterManager.register( new FilterGenericInterfaceDevices(), true ); + filterManager.register( new FilterGenericParallelDevices(), true ); + filterManager.register( new FilterGenericFileSystemDevices(), true ); + + // register QEMU specific filters to finalize configuration template + if ( hypervisor instanceof LibvirtHypervisorQemu ) { + final LibvirtHypervisorQemu hypervisorQemu = LibvirtHypervisorQemu.class.cast( hypervisor ); + + filterManager.register( new FilterSpecificQemuArchitecture( hypervisorQemu ), true ); + filterManager.register( new FilterSpecificQemuSerialDevices( hypervisorQemu ), true ); + filterManager.register( new FilterSpecificQemuNvidiaGpuPassthrough( hypervisorQemu ), false ); + } + + // finalize Libvirt VM configuration template + try { + filterManager.filterAll(); + } catch ( FilterException e ) { + LOGGER.error( "Failed to finalize VM configuration file: " + e.getLocalizedMessage() ); + hypervisor.close(); + System.exit( 4 ); + } + + // write finalized configuration to file if output file is specified + final String xmlOutputFileName = cmdLn.getVmCfgOutFileName(); + if ( xmlOutputFileName != null && !xmlOutputFileName.isEmpty() ) { + try { + final File xmlOutputFile = new File( xmlOutputFileName ); + config.toXml( xmlOutputFile ); + } catch ( LibvirtXmlSerializationException e ) { + LOGGER.error( "Failed to write VM output configuration file: " + e.getLocalizedMessage() ); + hypervisor.close(); + System.exit( 5 ); + } + } + + // define QEMU VM from finalized configuration + LibvirtVirtualMachine vm = null; + try { + vm = hypervisor.registerVm( config ); + } catch ( LibvirtHypervisorException e ) { + LOGGER.error( "Failed to define VM from configuration file: " + e.getLocalizedMessage() ); + hypervisor.close(); + System.exit( 6 ); + } + + try { + vm.start(); + } catch ( LibvirtVirtualMachineException e ) { + LOGGER.error( "Failed to start defined VM: " + e.getLocalizedMessage() ); + try { + hypervisor.deregisterVm( vm ); + } catch ( LibvirtHypervisorException | LibvirtVirtualMachineException e1 ) { + LOGGER.error( "Failed to undefine VM: " + e.getLocalizedMessage() ); + } + hypervisor.close(); + System.exit( 7 ); + } + + // close connection and let VM be running + hypervisor.close(); + // return with successful exit code System.exit( 0 ); } diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/cmdln/CommandLineArgs.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/cmdln/CommandLineArgs.java index 13b8c0e2..7e1a7a22 100644 --- a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/cmdln/CommandLineArgs.java +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/cmdln/CommandLineArgs.java @@ -289,13 +289,43 @@ public class CommandLineArgs } /** - * Returns the argument of the command line option {@link CmdLnOption#VM_AUDIO0}. + * Returns the argument of the command line option {@link CmdLnOption#VM_FSSRC0}. * - * @return argument of the command line option {@link CmdLnOption#VM_AUDIO0}. + * @return argument of the command line option {@link CmdLnOption#VM_FSSRC0}. */ - public String getVmModelSoundCard0() + public String getVmFsSrc0() { - return this.getArgument( CmdLnOption.VM_AUDIO0 ); + return this.getArgument( CmdLnOption.VM_FSSRC0 ); + } + + /** + * Returns the argument of the command line option {@link CmdLnOption#VM_FSTGT0}. + * + * @return argument of the command line option {@link CmdLnOption#VM_FSTGT0}. + */ + public String getVmFsTgt0() + { + return this.getArgument( CmdLnOption.VM_FSTGT0 ); + } + + /** + * Returns the argument of the command line option {@link CmdLnOption#VM_FSSRC1}. + * + * @return argument of the command line option {@link CmdLnOption#VM_FSSRC1}. + */ + public String getVmFsSrc1() + { + return this.getArgument( CmdLnOption.VM_FSSRC1 ); + } + + /** + * Returns the argument of the command line option {@link CmdLnOption#VM_FSTGT1}. + * + * @return argument of the command line option {@link CmdLnOption#VM_FSTGT1}. + */ + public String getVmFsTgt1() + { + return this.getArgument( CmdLnOption.VM_FSTGT1 ); } /** @@ -324,7 +354,10 @@ public class CommandLineArgs VM_PARALLEL0( 'p', "vmparallel0", true, "Device for the first parallel port interface" ), VM_SERIAL0 ( 'q', "vmserial0", true, "Device for the first serial port interface" ), VM_MAC0 ( 'a', "vmmac0", true, "MAC address for the first network interface" ), - VM_AUDIO0 ( 'x', "vmaudio0", true, "Hardware model for the first sound card" ); + VM_FSSRC0 ( 't', "vmfssrc0", true, "Source directory for first file system passthrough (shared folder)" ), + VM_FSTGT0 ( 'u', "vmfstgt0", true, "Target directory for first file system passthrough (shared folder)" ), + VM_FSSRC1 ( 'v', "vmfssrc1", true, "Source directory for second file system passthrough (shared folder)" ), + VM_FSTGT1 ( 'w', "vmfstgt1", true, "Target directory for second file system passthrough (shared folder)" ); // @formatter:on /** diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericCpu.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericCpu.java new file mode 100644 index 00000000..1fbcd568 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericCpu.java @@ -0,0 +1,26 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.Domain.CpuCheck; +import org.openslx.libvirt.domain.Domain.CpuMode; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterGeneric; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; + +public class FilterGenericCpu extends FilterGeneric +{ + private static final String FILTER_NAME = "CPU [number of cores, mode, ...]"; + + public FilterGenericCpu() + { + super( FilterGenericCpu.FILTER_NAME ); + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + config.setVCpu( args.getVmNumCpus() ); + config.setCpuMode( CpuMode.HOST_PASSTHROUGH ); + config.setCpuCheck( CpuCheck.PARTIAL ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskCdromDevices.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskCdromDevices.java new file mode 100644 index 00000000..a17f3a8b --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskCdromDevices.java @@ -0,0 +1,54 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import java.util.ArrayList; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.device.Disk.StorageType; +import org.openslx.libvirt.domain.device.DiskCdrom; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterGeneric; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; +import org.openslx.vm.QemuMetaData; +import org.openslx.vm.QemuMetaDataUtils; + +public class FilterGenericDiskCdromDevices extends FilterGeneric +{ + private static final String FILTER_NAME = "Disk CDROM devices"; + + public FilterGenericDiskCdromDevices() + { + super( FilterGenericDiskCdromDevices.FILTER_NAME ); + } + + private void filterDiskCdromDevice( Domain config, String fileName, int index ) throws FilterException + { + final ArrayList devices = config.getDiskCdromDevices(); + final DiskCdrom disk = QemuMetaDataUtils.getArrayIndex( devices, index ); + + if ( disk != null ) { + if ( fileName == null ) { + // do not remove disk CDROM drive, but set local physical drive as input source + disk.setStorage( StorageType.BLOCK, QemuMetaData.CDROM_DEFAULT_PHYSICAL_DRIVE ); + } else if ( fileName.equals( "" ) ) { + // remove storage source if empty string is specified to emulate an empty CDROM drive + disk.removeStorage(); + } else { + // set disk image file as storage source of the disk CDROM drive + disk.setStorage( StorageType.FILE, fileName ); + } + } + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + this.filterDiskCdromDevice( config, args.getVmDiskFileNameCdrom0(), 0 ); + this.filterDiskCdromDevice( config, args.getVmDiskFileNameCdrom1(), 1 ); + + // remove all additional disk CDROM devices + final ArrayList devices = config.getDiskCdromDevices(); + for ( int i = 2; i < devices.size(); i++ ) { + devices.get( i ).remove(); + } + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskFloppyDevices.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskFloppyDevices.java new file mode 100644 index 00000000..106e499e --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskFloppyDevices.java @@ -0,0 +1,50 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import java.util.ArrayList; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.device.Disk.StorageType; +import org.openslx.libvirt.domain.device.DiskFloppy; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterGeneric; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; +import org.openslx.vm.QemuMetaDataUtils; + +public class FilterGenericDiskFloppyDevices extends FilterGeneric +{ + private static final String FILTER_NAME = "Disk floppy devices"; + + public FilterGenericDiskFloppyDevices() + { + super( FilterGenericDiskFloppyDevices.FILTER_NAME ); + } + + private void filterDiskFloppyDevice( Domain config, String fileName, int index ) throws FilterException + { + final ArrayList devices = config.getDiskFloppyDevices(); + final DiskFloppy disk = QemuMetaDataUtils.getArrayIndex( devices, index ); + + if ( disk != null ) { + if ( fileName == null ) { + // remove disk floppy device if disk image file name is not set + disk.remove(); + } else { + // set image file of disk storage if disk floppy device is available + disk.setStorage( StorageType.FILE, fileName ); + } + } + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + this.filterDiskFloppyDevice( config, args.getVmDiskFileNameFloppy0(), 0 ); + this.filterDiskFloppyDevice( config, args.getVmDiskFileNameFloppy1(), 1 ); + + // remove all additional disk storage devices + final ArrayList devices = config.getDiskFloppyDevices(); + for ( int i = 2; i < devices.size(); i++ ) { + devices.get( i ).remove(); + } + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskStorageDevices.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskStorageDevices.java new file mode 100644 index 00000000..0dcfddf9 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskStorageDevices.java @@ -0,0 +1,49 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import java.util.ArrayList; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.device.Disk.StorageType; +import org.openslx.libvirt.domain.device.DiskStorage; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterGeneric; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; +import org.openslx.vm.QemuMetaDataUtils; + +public class FilterGenericDiskStorageDevices extends FilterGeneric +{ + private static final String FILTER_NAME = "Disk storage devices [HDD, SSD, ...]"; + + public FilterGenericDiskStorageDevices() + { + super( FilterGenericDiskStorageDevices.FILTER_NAME ); + } + + private void filterDiskStorageDevice( Domain config, String fileName, int index ) throws FilterException + { + final ArrayList devices = config.getDiskStorageDevices(); + final DiskStorage disk = QemuMetaDataUtils.getArrayIndex( devices, index ); + + if ( disk != null ) { + if ( fileName == null ) { + // remove disk storage device if disk image file name is not set + disk.remove(); + } else { + // set image file of disk storage if disk storage device is available + disk.setStorage( StorageType.FILE, fileName ); + } + } + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + this.filterDiskStorageDevice( config, args.getVmDiskFileNameHDD0(), 0 ); + + // remove all additional disk storage devices + final ArrayList devices = config.getDiskStorageDevices(); + for ( int i = 1; i < devices.size(); i++ ) { + devices.get( i ).remove(); + } + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericFileSystemDevices.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericFileSystemDevices.java new file mode 100644 index 00000000..1d06474f --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericFileSystemDevices.java @@ -0,0 +1,64 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import java.util.ArrayList; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.device.FileSystem; +import org.openslx.libvirt.domain.device.FileSystem.AccessMode; +import org.openslx.libvirt.domain.device.FileSystem.Type; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterGeneric; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; +import org.openslx.vm.QemuMetaDataUtils; + +public class FilterGenericFileSystemDevices extends FilterGeneric +{ + private static final String FILTER_NAME = "File system devices"; + + public FilterGenericFileSystemDevices() + { + super( FilterGenericFileSystemDevices.FILTER_NAME ); + } + + private void filterFileSystemDevice( Domain config, String source, String target, int index ) throws FilterException + { + final ArrayList devices = config.getFileSystemDevices(); + final FileSystem fileSystem = QemuMetaDataUtils.getArrayIndex( devices, index ); + + if ( fileSystem == null ) { + // check if file system device source directory is specified + if ( source != null && target != null ) { + // file system device does not exist, so create new file system device + final FileSystem newFileSystem = config.addFileSystemDevice(); + newFileSystem.setType( Type.MOUNT ); + newFileSystem.setAccessMode( AccessMode.MAPPED ); + newFileSystem.setSource( source ); + newFileSystem.setTarget( target ); + } + } else { + if ( source == null || target == null ) { + // remove file system device since device source or target is not specified + fileSystem.remove(); + } else { + // change type, access mode, source and target of existing file system device + fileSystem.setType( Type.MOUNT ); + fileSystem.setAccessMode( AccessMode.MAPPED ); + fileSystem.setSource( source ); + fileSystem.setTarget( target ); + } + } + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + this.filterFileSystemDevice( config, args.getVmFsSrc0(), args.getVmFsTgt0(), 0 ); + this.filterFileSystemDevice( config, args.getVmFsSrc1(), args.getVmFsTgt1(), 1 ); + + // remove all additional file system devices + final ArrayList devices = config.getFileSystemDevices(); + for ( int i = 1; i < devices.size(); i++ ) { + devices.get( i ).remove(); + } + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericInterfaceDevices.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericInterfaceDevices.java new file mode 100644 index 00000000..ea2782ba --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericInterfaceDevices.java @@ -0,0 +1,48 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import java.util.ArrayList; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.device.Interface; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterGeneric; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; +import org.openslx.vm.QemuMetaDataUtils; + +public class FilterGenericInterfaceDevices extends FilterGeneric +{ + private static final String FILTER_NAME = "Network interface devices"; + + public FilterGenericInterfaceDevices() + { + super( FilterGenericInterfaceDevices.FILTER_NAME ); + } + + private void filterInterfaceDevice( Domain config, String macAddress, int index ) throws FilterException + { + final ArrayList devices = config.getInterfaceDevices(); + final Interface device = QemuMetaDataUtils.getArrayIndex( devices, index ); + + if ( device != null ) { + if ( macAddress == null ) { + // remove network interface device if MAC address is not set + device.remove(); + } else { + // set MAC address of network interface device if network interface device is available + device.setMacAddress( macAddress ); + } + } + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + this.filterInterfaceDevice( config, args.getVmMacAddress0(), 0 ); + + // remove all additional disk storage devices + final ArrayList devices = config.getInterfaceDevices(); + for ( int i = 1; i < devices.size(); i++ ) { + devices.get( i ).remove(); + } + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericMemory.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericMemory.java new file mode 100644 index 00000000..d8d901d4 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericMemory.java @@ -0,0 +1,28 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import java.math.BigInteger; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.DomainUtils; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterGeneric; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; + +public class FilterGenericMemory extends FilterGeneric +{ + private static final String FILTER_NAME = "Memory [normal, current (balloning)]"; + + public FilterGenericMemory() + { + super( FilterGenericMemory.FILTER_NAME ); + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + BigInteger memory = DomainUtils.decodeMemory( args.getVmMemory(), "MiB" ); + + config.setMemory( memory ); + config.setCurrentMemory( memory ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericName.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericName.java new file mode 100644 index 00000000..00644b23 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericName.java @@ -0,0 +1,23 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterGeneric; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; + +public class FilterGenericName extends FilterGeneric +{ + private static final String FILTER_NAME = "Name [(display) name]"; + + public FilterGenericName() + { + super( FilterGenericName.FILTER_NAME ); + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + config.setName( args.getVmName() ); + config.setTitle( args.getVmDisplayName() ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericParallelDevices.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericParallelDevices.java new file mode 100644 index 00000000..458f69cb --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericParallelDevices.java @@ -0,0 +1,58 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import java.util.ArrayList; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.device.Parallel; +import org.openslx.libvirt.domain.device.Parallel.Type; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterGeneric; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; +import org.openslx.vm.QemuMetaDataUtils; + +public class FilterGenericParallelDevices extends FilterGeneric +{ + private static final String FILTER_NAME = "Parallel devices"; + + public FilterGenericParallelDevices() + { + super( FilterGenericParallelDevices.FILTER_NAME ); + } + + private void filterParallelDevice( Domain config, String fileName, int index ) throws FilterException + { + final ArrayList devices = config.getParallelDevices(); + final Parallel device = QemuMetaDataUtils.getArrayIndex( devices, index ); + + if ( device == null ) { + // check if device file name is specified + if ( fileName != null ) { + // parallel port device does not exist, so create new parallel port device + final Parallel newDevice = config.addParallelDevice(); + newDevice.setType( Type.DEV ); + newDevice.setSource( fileName ); + } + } else { + if ( fileName == null ) { + // remove device since device file is not specified + device.remove(); + } else { + // change type and source of existing parallel port device + device.setType( Type.DEV ); + device.setSource( fileName ); + } + } + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + this.filterParallelDevice( config, args.getVmDeviceSerial0(), 0 ); + + // remove all additional parallel devices + final ArrayList devices = config.getParallelDevices(); + for ( int i = 1; i < devices.size(); i++ ) { + devices.get( i ).remove(); + } + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericUuid.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericUuid.java new file mode 100644 index 00000000..f10a32b7 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericUuid.java @@ -0,0 +1,22 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterGeneric; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; + +public class FilterGenericUuid extends FilterGeneric +{ + private static final String FILTER_NAME = "UUID"; + + public FilterGenericUuid() + { + super( FilterGenericUuid.FILTER_NAME ); + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + config.setUuid( args.getVmUuid() ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuArchitecture.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuArchitecture.java new file mode 100644 index 00000000..0466b5e9 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuArchitecture.java @@ -0,0 +1,199 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import java.util.ArrayList; +import java.util.List; + +import org.openslx.libvirt.capabilities.Capabilities; +import org.openslx.libvirt.capabilities.guest.Guest; +import org.openslx.libvirt.capabilities.guest.Machine; +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.Domain.OsType; +import org.openslx.libvirt.domain.Domain.Type; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterSpecific; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; +import org.openslx.runvirt.plugin.qemu.virtualization.LibvirtHypervisorQemu; +import org.openslx.runvirt.virtualization.LibvirtHypervisorException; + +public class FilterSpecificQemuArchitecture extends FilterSpecific +{ + private static final String FILTER_NAME = "QEMU Architecture [CPU architecture, machine type, ...]"; + + // used as instance of an singelton, always use getCapabilities to retrieve caps instance + private Capabilities capabilities = null; + + public FilterSpecificQemuArchitecture( LibvirtHypervisorQemu hypervisor ) + { + super( FilterSpecificQemuArchitecture.FILTER_NAME, hypervisor ); + } + + private Capabilities getCapabilities() throws FilterException + { + // retrieve capabilities from QEMU hypervisor only once + if ( this.capabilities == null ) { + try { + this.capabilities = this.getHypervisor().getCapabilites(); + } catch ( LibvirtHypervisorException e ) { + final String errorMsg = new String( + "Failed to get host capabilities from QEMU virtualizer: " + e.getLocalizedMessage() ); + throw new FilterException( errorMsg ); + } + } + + return this.capabilities; + } + + private Guest getTargetGuestFromArchName( String architectureName ) throws FilterException + { + final List guests = this.getCapabilities().getGuests(); + Guest targetGuest = null; + + if ( architectureName == null ) { + return targetGuest; + } + + for ( Guest guest : guests ) { + final String guestArchitectureName = guest.getArchName(); + if ( architectureName.equals( guestArchitectureName ) ) { + targetGuest = guest; + break; + } + } + + return targetGuest; + } + + private Machine getTargetMachineFromGuest( Guest guest, String machineName ) throws FilterException + { + final List machines = guest.getArchMachines(); + Machine targetMachine = null; + + if ( machineName == null ) { + return targetMachine; + } + + for ( Machine machine : machines ) { + if ( machineName.equals( machine.getName() ) ) { + targetMachine = machine; + break; + } + } + + return targetMachine; + } + + private List getCanonicalNamesFromTargetMachines( Guest guest ) throws FilterException + { + final List machines = guest.getArchMachines(); + final List canonicalNames = new ArrayList(); + + for ( Machine machine : machines ) { + final String canonicalName = machine.getCanonicalMachine(); + if ( canonicalName != null ) { + canonicalNames.add( canonicalName ); + } + } + + return canonicalNames; + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + // get source architecture, machine- and OS type + final String sourceArchitectureName = config.getOsArch(); + final String sourceMachine = config.getOsMachine(); + final OsType sourceOsType = config.getOsType(); + final Type sourceDomainType = config.getType(); + + // check if source architecture is supported by one of the hypervisor's guests + Guest targetGuest = null; + if ( sourceArchitectureName == null ) { + final String errorMsg = new String( "Source architecture is not specified!" ); + throw new FilterException( errorMsg ); + } else { + targetGuest = this.getTargetGuestFromArchName( sourceArchitectureName ); + if ( targetGuest == null ) { + final String errorMsg = new String( "Source architecture is not supported by the virtualizer!" ); + throw new FilterException( errorMsg ); + } + } + + // check if source machine is supported by the hypervisor + Machine targetMachine = null; + if ( sourceMachine == null ) { + final String errorMsg = new String( "Source machine type is not specified!" ); + throw new FilterException( errorMsg ); + } else { + // get all possible machine type for supported source architecture + targetMachine = this.getTargetMachineFromGuest( targetGuest, sourceMachine ); + + if ( targetMachine == null ) { + // source machine is not directly supported by the hypervisor + // check if up- or downgraded version of the chipset is supported by the hypervisor + List targetMachineCanonicalNames = this.getCanonicalNamesFromTargetMachines( targetGuest ); + + // retrieve overwrite chipset name from canonical machine names + String sourceMachineOverwrite = null; + for ( String targetMachineCanonicalName : targetMachineCanonicalNames ) { + if ( sourceMachine.contains( targetMachineCanonicalName ) ) { + sourceMachineOverwrite = targetMachineCanonicalName; + break; + } + } + + // if overwrite available, patch the machine type + if ( sourceMachineOverwrite != null ) { + config.setOsMachine( sourceMachineOverwrite ); + } else { + final String errorMsg = new String( "Source machine type is not supported by the virtualizer!" ); + throw new FilterException( errorMsg ); + } + } + } + + // check if source OS type is supported by the hypervisor's architecture + if ( sourceOsType == null ) { + final String errorMsg = new String( "OS type is not specified!" ); + throw new FilterException( errorMsg ); + } else { + if ( !sourceOsType.toString().equals( targetGuest.getOsType().toString() ) ) { + final String errorMsg = new String( "OS type is not supported by the virtualizer!" ); + throw new FilterException( errorMsg ); + } + } + + // check if source domain type is supported by the hypervisor's architecture + Type targetDomainType = null; + if ( sourceDomainType == null ) { + final String errorMsg = new String( "Source domain type is not specified!" ); + throw new FilterException( errorMsg ); + } else { + final List targetDomains = targetGuest.getArchDomains(); + + // retrieve supported domain type + for ( org.openslx.libvirt.capabilities.guest.Domain domain : targetDomains ) { + final Type domainType = domain.getType(); + if ( domainType == sourceDomainType ) { + targetDomainType = domainType; + break; + } + } + + // check supported domain type + if ( targetDomainType == null ) { + final String errorMsg = new String( "Source domain type is not supported by the virtualizer!" ); + throw new FilterException( errorMsg ); + } + } + + // patch path of QEMU emulator binary + final String archEmulator = targetGuest.getArchEmulator(); + if ( archEmulator == null ) { + final String errorMsg = new String( "Emulation of source architecture is not supported by the virtualizer!" ); + throw new FilterException( errorMsg ); + } else { + config.setDevicesEmulator( targetGuest.getArchEmulator() ); + } + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuNvidiaGpuPassthrough.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuNvidiaGpuPassthrough.java new file mode 100644 index 00000000..913eeb5a --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuNvidiaGpuPassthrough.java @@ -0,0 +1,26 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterSpecific; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; +import org.openslx.runvirt.plugin.qemu.virtualization.LibvirtHypervisorQemu; + +public class FilterSpecificQemuNvidiaGpuPassthrough extends FilterSpecific +{ + private static final String FILTER_NAME = "QEMU GPU passthrough [Nvidia]"; + + public FilterSpecificQemuNvidiaGpuPassthrough( LibvirtHypervisorQemu hypervisor ) + { + super( FilterSpecificQemuNvidiaGpuPassthrough.FILTER_NAME, hypervisor ); + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + // check if IOMMU support is available on the host + + // TODO: implement Nvidia hypervisor shadowing + // call this filter at the end, since -> override of software graphics to 'none' necessary + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuSerialDevices.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuSerialDevices.java new file mode 100644 index 00000000..258027b8 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/FilterSpecificQemuSerialDevices.java @@ -0,0 +1,69 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import java.util.ArrayList; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.device.Serial.Type; +import org.openslx.libvirt.domain.device.Serial; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.configuration.FilterSpecific; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; +import org.openslx.runvirt.plugin.qemu.virtualization.LibvirtHypervisorQemu; +import org.openslx.vm.QemuMetaDataUtils; + +public class FilterSpecificQemuSerialDevices extends FilterSpecific +{ + private static final String FILTER_NAME = "Serial devices"; + + public FilterSpecificQemuSerialDevices( LibvirtHypervisorQemu hypervisor ) + { + super( FilterSpecificQemuSerialDevices.FILTER_NAME, hypervisor ); + } + + private ArrayList getSerialDevDevices( Domain config ) + { + final ArrayList devices = config.getSerialDevices(); + final Predicate byDeviceTypeDev = device -> device.getType() == Type.DEV; + + return devices.stream().filter( byDeviceTypeDev ).collect( Collectors.toCollection( ArrayList::new ) ); + } + + private void filterSerialDevice( Domain config, String fileName, int index ) throws FilterException + { + final ArrayList devices = this.getSerialDevDevices( config ); + final Serial device = QemuMetaDataUtils.getArrayIndex( devices, index ); + + if ( device == null ) { + // check if device file name is specified + if ( fileName != null ) { + // serial port device is not available, so create new serial port device + final Serial newDevice = config.addSerialDevice(); + newDevice.setType( Type.DEV ); + newDevice.setSource( fileName ); + } + } else { + if ( fileName == null ) { + // remove serial port device if device file name is not set + device.remove(); + } else { + // set type and source of existing serial port device + device.setType( Type.DEV ); + device.setSource( fileName ); + } + } + } + + @Override + public void filter( Domain config, CommandLineArgs args ) throws FilterException + { + this.filterSerialDevice( config, args.getVmDeviceSerial0(), 0 ); + + // remove all additional serial devices + final ArrayList devices = this.getSerialDevDevices( config ); + for ( int i = 1; i < devices.size(); i++ ) { + devices.get( i ).remove(); + } + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/virtualization/LibvirtHypervisorQemu.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/virtualization/LibvirtHypervisorQemu.java new file mode 100644 index 00000000..260c3f4e --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/virtualization/LibvirtHypervisorQemu.java @@ -0,0 +1,39 @@ +package org.openslx.runvirt.plugin.qemu.virtualization; + +import org.openslx.runvirt.virtualization.LibvirtHypervisor; +import org.openslx.runvirt.virtualization.LibvirtHypervisorException; + +public class LibvirtHypervisorQemu extends LibvirtHypervisor +{ + public LibvirtHypervisorQemu( QemuSessionType type ) throws LibvirtHypervisorException + { + super( type.getConnectionUri() ); + } + + public enum QemuSessionType + { + // @formatter:off + LOCAL_SYSTEM_SESSION( "qemu:///system" ), + LOCAL_USER_SESSION ( "qemu:///session" ); + // @formatter:on + + private final String connectionUri; + + QemuSessionType( String connectionUri ) + { + this.connectionUri = connectionUri; + } + + public String getConnectionUri() + { + return this.connectionUri; + } + + // TODO: + // Implement capabilities -> get host architecture => decision whether to emulate or use KVM? -> change domain of XML + // fill in given HDD file, CDROM, ... + // GPU-Passthrough: patch XML with hypervisor disable bit, ..., to get Nvidia driver working + // Add hostdev für GPU passthrough -> add PCI ID arguments to cmdln parser + // + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtHypervisor.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtHypervisor.java new file mode 100644 index 00000000..345900ab --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtHypervisor.java @@ -0,0 +1,99 @@ +package org.openslx.runvirt.virtualization; + +import java.io.Closeable; + +import org.libvirt.Connect; +import org.libvirt.LibvirtException; +import org.openslx.libvirt.capabilities.Capabilities; +import org.openslx.libvirt.xml.LibvirtXmlDocumentException; +import org.openslx.libvirt.xml.LibvirtXmlSerializationException; +import org.openslx.libvirt.xml.LibvirtXmlValidationException; + +public abstract class LibvirtHypervisor implements Closeable +{ + protected Connect hypervisor = null; + + public LibvirtHypervisor( String connectionUri ) throws LibvirtHypervisorException + { + this.connect( connectionUri ); + } + + protected void connect( String connectionUri ) throws LibvirtHypervisorException + { + try { + this.hypervisor = new Connect( connectionUri ); + } catch ( LibvirtException e ) { + throw new LibvirtHypervisorException( e.getLocalizedMessage() ); + } + } + + public Capabilities getCapabilites() throws LibvirtHypervisorException + { + Capabilities hypervisorCapabilities = null; + + try { + final String hypervisorCapabilitiesString = this.hypervisor.getCapabilities(); + hypervisorCapabilities = new Capabilities( hypervisorCapabilitiesString ); + } catch ( LibvirtException | LibvirtXmlDocumentException | LibvirtXmlSerializationException + | LibvirtXmlValidationException e ) { + throw new LibvirtHypervisorException( e.getLocalizedMessage() ); + } + + return hypervisorCapabilities; + } + + public int getVersion() throws LibvirtHypervisorException + { + int hypervisorVersion = 0; + + try { + final long hypervisorVersionLong = this.hypervisor.getVersion(); + hypervisorVersion = Long.valueOf( hypervisorVersionLong ).intValue(); + } catch ( LibvirtException e ) { + throw new LibvirtHypervisorException( e.getLocalizedMessage() ); + } + + return hypervisorVersion; + } + + public LibvirtVirtualMachine registerVm( org.openslx.libvirt.domain.Domain vmConfiguration ) + throws LibvirtHypervisorException + { + final String xmlVmConfiguration = vmConfiguration.toString(); + org.libvirt.Domain libvirtDomain = null; + + try { + libvirtDomain = this.hypervisor.domainDefineXML( xmlVmConfiguration ); + } catch ( LibvirtException e ) { + throw new LibvirtHypervisorException( e.getLocalizedMessage() ); + } + + return new LibvirtVirtualMachine( libvirtDomain ); + } + + public void deregisterVm( LibvirtVirtualMachine vm ) + throws LibvirtHypervisorException, LibvirtVirtualMachineException + { + // stop virtual machine if machine is running + if ( vm.isRunning() ) { + vm.stop(); + } + + // deregister and remove virtual machine from hypervisor + try { + vm.getLibvirtDomain().undefine(); + } catch ( LibvirtException e ) { + throw new LibvirtHypervisorException( e.getLocalizedMessage() ); + } + } + + @Override + public void close() + { + try { + this.hypervisor.close(); + } catch ( LibvirtException e ) { + e.printStackTrace(); + } + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtHypervisorException.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtHypervisorException.java new file mode 100644 index 00000000..acf640e1 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtHypervisorException.java @@ -0,0 +1,14 @@ +package org.openslx.runvirt.virtualization; + +public class LibvirtHypervisorException extends Exception +{ + /** + * Version for serialization. + */ + private static final long serialVersionUID = -3631452625806770209L; + + LibvirtHypervisorException( String errorMsg ) + { + super( errorMsg ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtVirtualMachine.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtVirtualMachine.java new file mode 100644 index 00000000..781bd938 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtVirtualMachine.java @@ -0,0 +1,81 @@ +package org.openslx.runvirt.virtualization; + +import org.libvirt.Domain; +import org.libvirt.LibvirtException; + +public class LibvirtVirtualMachine +{ + private Domain domain; + + LibvirtVirtualMachine( Domain vm ) + { + this.domain = vm; + } + + public Domain getLibvirtDomain() + { + return this.domain; + } + + public boolean isRunning() throws LibvirtVirtualMachineException + { + int state = 0; + + try { + state = this.domain.isActive(); + } catch ( LibvirtException e ) { + throw new LibvirtVirtualMachineException( e.getLocalizedMessage() ); + } + + return ( state == 0 ) ? false : true; + } + + public void start() throws LibvirtVirtualMachineException + { + if ( !this.isRunning() ) { + try { + this.domain.create(); + } catch ( LibvirtException e ) { + throw new LibvirtVirtualMachineException( e.getLocalizedMessage() ); + } + } + } + + public void stop() throws LibvirtVirtualMachineException + { + if ( this.isRunning() ) { + try { + this.domain.shutdown(); + } catch ( LibvirtException e ) { + throw new LibvirtVirtualMachineException( e.getLocalizedMessage() ); + } + } + } + + public void suspend() throws LibvirtVirtualMachineException + { + try { + this.domain.suspend(); + } catch ( LibvirtException e ) { + throw new LibvirtVirtualMachineException( e.getLocalizedMessage() ); + } + } + + public void resume() throws LibvirtVirtualMachineException + { + try { + this.domain.resume(); + } catch ( LibvirtException e ) { + throw new LibvirtVirtualMachineException( e.getLocalizedMessage() ); + } + } + + public void reboot() throws LibvirtVirtualMachineException + { + try { + this.domain.reboot( 0 ); + } catch ( LibvirtException e ) { + throw new LibvirtVirtualMachineException( e.getLocalizedMessage() ); + } + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtVirtualMachineException.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtVirtualMachineException.java new file mode 100644 index 00000000..4e8ee1ba --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtVirtualMachineException.java @@ -0,0 +1,14 @@ +package org.openslx.runvirt.virtualization; + +public class LibvirtVirtualMachineException extends Exception +{ + /** + * Version for serialization. + */ + private static final long serialVersionUID = -5371327391243047616L; + + public LibvirtVirtualMachineException( String errorMsg ) + { + super( errorMsg ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/AppTest.java b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/AppTest.java index 126fd26d..9f8f925f 100644 --- a/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/AppTest.java +++ b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/AppTest.java @@ -63,7 +63,7 @@ public class AppTest assertTrue( shortHelpOptionCorrectOutput.contains( App.APP_DESC ) ); // test that no error was logged and output is available - assertEquals( 1641, shortHelpOptionCorrectOutput.length() ); + assertEquals( 2026, shortHelpOptionCorrectOutput.length() ); assertEquals( 0, shortHelpOptionCorrectErrOutput.length() ); } @@ -91,7 +91,7 @@ public class AppTest assertTrue( longHelpOptionCorrectOutput.contains( App.APP_DESC ) ); // test that no error was logged and output is available - assertEquals( 1641, longHelpOptionCorrectOutput.length() ); + assertEquals( 2026, longHelpOptionCorrectOutput.length() ); assertEquals( 0, longHelpOptionCorrectErrOutput.length() ); } @@ -119,7 +119,7 @@ public class AppTest assertTrue( shortHelpOptionIncorrectOutput.contains( App.APP_DESC ) ); // test that error was logged and output is available - assertEquals( 1641, shortHelpOptionIncorrectOutput.length() ); + assertEquals( 2026, shortHelpOptionIncorrectOutput.length() ); assertEquals( 0, shortHelpOptionIncorrectErrOutput.length() ); } @@ -147,7 +147,7 @@ public class AppTest assertTrue( longHelpOptionIncorrectOutput.contains( App.APP_DESC ) ); // test that error was logged and output is available - assertEquals( 1641, longHelpOptionIncorrectOutput.length() ); + assertEquals( 2026, longHelpOptionIncorrectOutput.length() ); assertEquals( 0, longHelpOptionIncorrectErrOutput.length() ); } diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/cmdln/CommandLineArgsTest.java b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/cmdln/CommandLineArgsTest.java index 1399f9a4..ee3e0d1d 100644 --- a/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/cmdln/CommandLineArgsTest.java +++ b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/cmdln/CommandLineArgsTest.java @@ -13,8 +13,8 @@ import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs.CmdLnOption; public class CommandLineArgsTest { // @formatter:off - private static final String CMDLN_PREFIX_OPTION_SHORT = "-"; - private static final String CMDLN_PREFIX_OPTION_LONG = "--"; + public static final String CMDLN_PREFIX_OPTION_SHORT = "-"; + public static final String CMDLN_PREFIX_OPTION_LONG = "--"; private static final String CMDLN_TEST_NAME = "test"; private static final String CMDLN_TEST_FILENAME = System.getProperty( "user.dir" ) + File.separator + CMDLN_TEST_NAME; @@ -25,7 +25,6 @@ public class CommandLineArgsTest private static final String CMDLN_TEST_PARPORT = "/dev/parport0"; private static final String CMDLN_TEST_SERPORT = "/dev/ttyS0"; private static final String CMDLN_TEST_MAC = "02:42:8e:77:1b:e6"; - private static final String CMDLN_TEST_AUDIO_MODEL = "sb16"; // @formatter:on @Test @@ -519,30 +518,114 @@ public class CommandLineArgsTest } @Test - @DisplayName( "Test the parsing of the VM first sound card type command line option (short version)" ) - public void testCmdlnOptionVmAudio0Short() throws CommandLineArgsException + @DisplayName( "Test the parsing of the VM first file system source command line option (short version)" ) + public void testCmdlnOptionVmFsSrc0Short() throws CommandLineArgsException { final String[] args = { - CMDLN_PREFIX_OPTION_SHORT + CmdLnOption.VM_AUDIO0.getShortOption(), - CMDLN_TEST_AUDIO_MODEL + CMDLN_PREFIX_OPTION_SHORT + CmdLnOption.VM_FSSRC0.getShortOption(), + CMDLN_TEST_FILENAME + }; + + CommandLineArgs cmdLn = new CommandLineArgs( args ); + + assertEquals( CMDLN_TEST_FILENAME, cmdLn.getVmFsSrc0() ); + } + + @Test + @DisplayName( "Test the parsing of the VM first file system source command line option (long version)" ) + public void testCmdlnOptionVmFsSrc0Long() throws CommandLineArgsException + { + final String[] args = { + CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_FSSRC0.getLongOption(), + CMDLN_TEST_FILENAME + }; + + CommandLineArgs cmdLn = new CommandLineArgs( args ); + + assertEquals( CMDLN_TEST_FILENAME, cmdLn.getVmFsSrc0() ); + } + + @Test + @DisplayName( "Test the parsing of the VM first file system target command line option (short version)" ) + public void testCmdlnOptionVmFsTgt0Short() throws CommandLineArgsException + { + final String[] args = { + CMDLN_PREFIX_OPTION_SHORT + CmdLnOption.VM_FSTGT0.getShortOption(), + CMDLN_TEST_NAME + }; + + CommandLineArgs cmdLn = new CommandLineArgs( args ); + + assertEquals( CMDLN_TEST_NAME, cmdLn.getVmFsTgt0() ); + } + + @Test + @DisplayName( "Test the parsing of the VM first file system target command line option (long version)" ) + public void testCmdlnOptionVmFsTgt0Long() throws CommandLineArgsException + { + final String[] args = { + CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_FSTGT0.getLongOption(), + CMDLN_TEST_NAME }; CommandLineArgs cmdLn = new CommandLineArgs( args ); - assertEquals( CMDLN_TEST_AUDIO_MODEL, cmdLn.getVmModelSoundCard0() ); + assertEquals( CMDLN_TEST_NAME, cmdLn.getVmFsTgt0() ); } @Test - @DisplayName( "Test the parsing of the VM first sound card type command line option (long version)" ) - public void testCmdlnOptionVmAudio0Long() throws CommandLineArgsException + @DisplayName( "Test the parsing of the VM second file system source command line option (short version)" ) + public void testCmdlnOptionVmFsSrc1Short() throws CommandLineArgsException { final String[] args = { - CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_AUDIO0.getLongOption(), - CMDLN_TEST_AUDIO_MODEL + CMDLN_PREFIX_OPTION_SHORT + CmdLnOption.VM_FSSRC1.getShortOption(), + CMDLN_TEST_FILENAME + }; + + CommandLineArgs cmdLn = new CommandLineArgs( args ); + + assertEquals( CMDLN_TEST_FILENAME, cmdLn.getVmFsSrc1() ); + } + + @Test + @DisplayName( "Test the parsing of the VM second file system source command line option (long version)" ) + public void testCmdlnOptionVmFsSrc1Long() throws CommandLineArgsException + { + final String[] args = { + CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_FSSRC1.getLongOption(), + CMDLN_TEST_FILENAME + }; + + CommandLineArgs cmdLn = new CommandLineArgs( args ); + + assertEquals( CMDLN_TEST_FILENAME, cmdLn.getVmFsSrc1() ); + } + + @Test + @DisplayName( "Test the parsing of the VM second file system target command line option (short version)" ) + public void testCmdlnOptionVmFsTgt1Short() throws CommandLineArgsException + { + final String[] args = { + CMDLN_PREFIX_OPTION_SHORT + CmdLnOption.VM_FSTGT1.getShortOption(), + CMDLN_TEST_NAME + }; + + CommandLineArgs cmdLn = new CommandLineArgs( args ); + + assertEquals( CMDLN_TEST_NAME, cmdLn.getVmFsTgt1() ); + } + + @Test + @DisplayName( "Test the parsing of the VM second file system target command line option (long version)" ) + public void testCmdlnOptionVmFsTgt1Long() throws CommandLineArgsException + { + final String[] args = { + CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_FSTGT1.getLongOption(), + CMDLN_TEST_NAME }; CommandLineArgs cmdLn = new CommandLineArgs( args ); - assertEquals( CMDLN_TEST_AUDIO_MODEL, cmdLn.getVmModelSoundCard0() ); + assertEquals( CMDLN_TEST_NAME, cmdLn.getVmFsTgt1() ); } } diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericCpuTest.java b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericCpuTest.java new file mode 100644 index 00000000..3814bfb6 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericCpuTest.java @@ -0,0 +1,34 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.Domain.CpuCheck; +import org.openslx.libvirt.domain.Domain.CpuMode; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; + +public class FilterGenericCpuTest +{ + @Test + @DisplayName( "Test filtering of VM CPU configuration" ) + public void testFilterGenericCpu() throws FilterException + { + final FilterGenericCpu filter = new FilterGenericCpu(); + final Domain config = FilterTestUtils.getDefaultDomain(); + final CommandLineArgs args = FilterTestUtils.getDefaultCmdLnArgs(); + + assertNotEquals( Integer.parseInt( FilterTestUtils.DEFAULT_VM_NCPUS ), config.getVCpu() ); + assertNotEquals( CpuMode.HOST_PASSTHROUGH, config.getCpuMode() ); + assertEquals( CpuCheck.PARTIAL, config.getCpuCheck() ); + + filter.filter( config, args ); + + assertEquals( Integer.parseInt( FilterTestUtils.DEFAULT_VM_NCPUS ), config.getVCpu() ); + assertEquals( CpuMode.HOST_PASSTHROUGH, config.getCpuMode() ); + assertEquals( CpuCheck.PARTIAL, config.getCpuCheck() ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskStorageDevicesTest.java b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskStorageDevicesTest.java new file mode 100644 index 00000000..93282e78 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericDiskStorageDevicesTest.java @@ -0,0 +1,61 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.util.ArrayList; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.device.Disk.StorageType; +import org.openslx.libvirt.domain.device.DiskStorage; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; + +public class FilterGenericDiskStorageDevicesTest +{ + @Test + @DisplayName( "Test filtering of VM disk storage devices configuration with specified input data" ) + public void testFilterGenericDiskStorageDevices() throws FilterException + { + final FilterGenericDiskStorageDevices filter = new FilterGenericDiskStorageDevices(); + final Domain config = FilterTestUtils.getDefaultDomain(); + final CommandLineArgs args = FilterTestUtils.getDefaultCmdLnArgs(); + + final ArrayList devicesBeforeFiltering = config.getDiskStorageDevices(); + assertEquals( 1, devicesBeforeFiltering.size() ); + assertNotEquals( StorageType.FILE, devicesBeforeFiltering.get( 0 ).getStorageType() ); + assertNotEquals( FilterTestUtils.DEFAULT_VM_HDD0, devicesBeforeFiltering.get( 0 ).getStorageSource() ); + + filter.filter( config, args ); + + final ArrayList devicesAfterFiltering = config.getDiskStorageDevices(); + assertEquals( 1, devicesAfterFiltering.size() ); + assertEquals( StorageType.FILE, devicesAfterFiltering.get( 0 ).getStorageType() ); + assertEquals( FilterTestUtils.DEFAULT_VM_HDD0, devicesAfterFiltering.get( 0 ).getStorageSource() ); + } + + @Test + @DisplayName( "Test filtering of VM disk storage devices configuration with unspecified input data" ) + public void testFilterGenericDiskStorageDevicesNoData() throws FilterException + { + final FilterGenericDiskStorageDevices filter = new FilterGenericDiskStorageDevices(); + final Domain config = FilterTestUtils.getDefaultDomain(); + final CommandLineArgs args = FilterTestUtils.getEmptyCmdLnArgs(); + + final ArrayList devicesBeforeFiltering = config.getDiskStorageDevices(); + assertEquals( 1, devicesBeforeFiltering.size() ); + + filter.filter( config, args ); + + final ArrayList devicesAfterFiltering = config.getDiskStorageDevices(); + assertEquals( 0, devicesAfterFiltering.size() ); + } + + public static void main( String[] args ) throws FilterException + { + FilterGenericDiskStorageDevicesTest test = new FilterGenericDiskStorageDevicesTest(); + test.testFilterGenericDiskStorageDevicesNoData(); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericMemoryTest.java b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericMemoryTest.java new file mode 100644 index 00000000..794e251c --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericMemoryTest.java @@ -0,0 +1,35 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.math.BigInteger; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.DomainUtils; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; + +public class FilterGenericMemoryTest +{ + @Test + @DisplayName( "Test filtering of VM memory configuration" ) + public void testFilterGenericMemory() throws FilterException + { + final FilterGenericMemory filter = new FilterGenericMemory(); + final Domain config = FilterTestUtils.getDefaultDomain(); + final CommandLineArgs args = FilterTestUtils.getDefaultCmdLnArgs(); + + final BigInteger defaultMemory = DomainUtils.decodeMemory( FilterTestUtils.DEFAULT_VM_MEM, "MiB" ); + + assertNotEquals( defaultMemory.toString(), config.getMemory().toString() ); + assertNotEquals( defaultMemory.toString(), config.getCurrentMemory().toString() ); + + filter.filter( config, args ); + + assertEquals( defaultMemory.toString(), config.getMemory().toString() ); + assertEquals( defaultMemory.toString(), config.getCurrentMemory().toString() ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericNameTest.java b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericNameTest.java new file mode 100644 index 00000000..93224702 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericNameTest.java @@ -0,0 +1,30 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.openslx.libvirt.domain.Domain; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; + +public class FilterGenericNameTest +{ + @Test + @DisplayName( "Test filtering of VM (display) name configuration" ) + public void testFilterGenericName() throws FilterException + { + final FilterGenericName filter = new FilterGenericName(); + final Domain config = FilterTestUtils.getDefaultDomain(); + final CommandLineArgs args = FilterTestUtils.getDefaultCmdLnArgs(); + + assertNotEquals( FilterTestUtils.DEFAULT_VM_NAME, config.getName() ); + assertNotEquals( FilterTestUtils.DEFAULT_VM_DSPLNAME, config.getTitle() ); + + filter.filter( config, args ); + + assertEquals( FilterTestUtils.DEFAULT_VM_NAME, config.getName() ); + assertEquals( FilterTestUtils.DEFAULT_VM_DSPLNAME, config.getTitle() ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericUuidTest.java b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericUuidTest.java new file mode 100644 index 00000000..c206b0e9 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterGenericUuidTest.java @@ -0,0 +1,28 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.openslx.libvirt.domain.Domain; +import org.openslx.runvirt.configuration.FilterException; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; + +public class FilterGenericUuidTest +{ + @Test + @DisplayName( "Test filtering of VM UUID configuration" ) + public void testFilterGenericUuid() throws FilterException + { + final FilterGenericUuid filter = new FilterGenericUuid(); + final Domain config = FilterTestUtils.getDefaultDomain(); + final CommandLineArgs args = FilterTestUtils.getDefaultCmdLnArgs(); + + assertNotEquals( FilterTestUtils.DEFAULT_VM_UUID, config.getUuid() ); + + filter.filter( config, args ); + + assertEquals( FilterTestUtils.DEFAULT_VM_UUID, config.getUuid() ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterTestResources.java b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterTestResources.java new file mode 100644 index 00000000..80fa2636 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterTestResources.java @@ -0,0 +1,17 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import java.io.File; +import java.net.URL; + +public class FilterTestResources +{ + private static final String LIBVIRT_PREFIX_PATH = File.separator + "libvirt"; + private static final String LIBVIRT_PREFIX_PATH_XML = LIBVIRT_PREFIX_PATH + File.separator + "xml"; + + public static File getLibvirtXmlFile( String libvirtXmlFileName ) + { + String libvirtXmlPath = FilterTestResources.LIBVIRT_PREFIX_PATH_XML + File.separator + libvirtXmlFileName; + URL libvirtXml = FilterTestResources.class.getResource( libvirtXmlPath ); + return new File( libvirtXml.getFile() ); + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterTestUtils.java b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterTestUtils.java new file mode 100644 index 00000000..45abb025 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/configuration/FilterTestUtils.java @@ -0,0 +1,112 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import static org.junit.jupiter.api.Assertions.fail; + +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.xml.LibvirtXmlDocumentException; +import org.openslx.libvirt.xml.LibvirtXmlSerializationException; +import org.openslx.libvirt.xml.LibvirtXmlValidationException; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs.CmdLnOption; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgsException; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgsTest; + +public class FilterTestUtils +{ + // @formatter:off + public static final String DEFAULT_VM_NAME = "archlinux"; + public static final String DEFAULT_VM_UUID = "4ec504d5-5eac-482f-a344-dbf1dd4956c8"; + public static final String DEFAULT_VM_DSPLNAME = "Archlinux"; + public static final String DEFAULT_VM_OS = "Windows 10 (x64)"; + public static final String DEFAULT_VM_NCPUS = "16"; + public static final String DEFAULT_VM_MEM = "1024"; + public static final String DEFAULT_VM_HDD0 = "/mnt/vm/windows.qcow2"; + public static final String DEFAULT_VM_FLOPPY0 = "/mnt/vm/floppy0.qcow2"; + public static final String DEFAULT_VM_FLOPPY1 = "/mnt/vm/floppy1.qcow2"; + public static final String DEFAULT_VM_CDROM0 = "/dev/sr0"; + public static final String DEFAULT_VM_CDROM1 = "/mnt/vm/cdrom1.qcow2"; + public static final String DEFAULT_VM_PARALLEL0 = "/dev/parport0"; + public static final String DEFAULT_VM_SERIAL0 = "/dev/ttyS0"; + public static final String DEFAULT_VM_MAC0 = "ca:06:29:84:f0:6d"; + public static final String DEFAULT_VM_FSSRC0 = "/mnt/shared/folder0"; + public static final String DEFAULT_VM_FSTGT0 = "folder0"; + public static final String DEFAULT_VM_FSSRC1 = "/mnt/shared/folder1"; + public static final String DEFAULT_VM_FSTGT1 = "folder1"; + // @formatter:on + + private static final String[] DEFAULT_CMDLN_ARGS = { + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_NAME.getLongOption(), + FilterTestUtils.DEFAULT_VM_NAME, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_UUID.getLongOption(), + FilterTestUtils.DEFAULT_VM_UUID, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_DSPLNAME.getLongOption(), + FilterTestUtils.DEFAULT_VM_DSPLNAME, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_OS.getLongOption(), + FilterTestUtils.DEFAULT_VM_OS, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_NCPUS.getLongOption(), + FilterTestUtils.DEFAULT_VM_NCPUS, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_MEM.getLongOption(), + FilterTestUtils.DEFAULT_VM_MEM, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_HDD0.getLongOption(), + FilterTestUtils.DEFAULT_VM_HDD0, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_FLOPPY0.getLongOption(), + FilterTestUtils.DEFAULT_VM_FLOPPY0, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_FLOPPY1.getLongOption(), + FilterTestUtils.DEFAULT_VM_FLOPPY1, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_CDROM0.getLongOption(), + FilterTestUtils.DEFAULT_VM_CDROM0, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_CDROM1.getLongOption(), + FilterTestUtils.DEFAULT_VM_CDROM1, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_PARALLEL0.getLongOption(), + FilterTestUtils.DEFAULT_VM_PARALLEL0, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_SERIAL0.getLongOption(), + FilterTestUtils.DEFAULT_VM_SERIAL0, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_MAC0.getLongOption(), + FilterTestUtils.DEFAULT_VM_MAC0, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_FSSRC0.getLongOption(), + FilterTestUtils.DEFAULT_VM_FSSRC0, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_FSTGT0.getLongOption(), + FilterTestUtils.DEFAULT_VM_FSTGT0, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_FSSRC1.getLongOption(), + FilterTestUtils.DEFAULT_VM_FSSRC1, + CommandLineArgsTest.CMDLN_PREFIX_OPTION_LONG + CmdLnOption.VM_FSTGT1.getLongOption(), + FilterTestUtils.DEFAULT_VM_FSTGT1 + }; + + private static CommandLineArgs getCmdLnArgs( String[] args ) + { + final CommandLineArgs cmdLnArgs = new CommandLineArgs(); + + try { + cmdLnArgs.parseCmdLnArgs( args ); + } catch ( CommandLineArgsException e ) { + fail( e.getLocalizedMessage() ); + } + + return cmdLnArgs; + } + + public static CommandLineArgs getDefaultCmdLnArgs() + { + return FilterTestUtils.getCmdLnArgs( FilterTestUtils.DEFAULT_CMDLN_ARGS ); + } + + public static CommandLineArgs getEmptyCmdLnArgs() + { + return FilterTestUtils.getCmdLnArgs( new String[] {} ); + } + + public static Domain getDefaultDomain() + { + Domain domain = null; + + try { + domain = new Domain( FilterTestResources.getLibvirtXmlFile( "qemu-kvm_default-ubuntu-20-04-vm.xml" ) ); + } catch ( LibvirtXmlDocumentException | LibvirtXmlSerializationException | LibvirtXmlValidationException e ) { + fail( "Cannot prepare requested Libvirt domain XML file from the resources folder: " + + e.getLocalizedMessage() ); + } + + return domain; + } +} diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/test/resources/libvirt/xml/qemu-kvm_capabilities_default.xml b/core/modules/qemu/runvirt-plugin-qemu/src/test/resources/libvirt/xml/qemu-kvm_capabilities_default.xml new file mode 100644 index 00000000..4f2a94f2 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/test/resources/libvirt/xml/qemu-kvm_capabilities_default.xml @@ -0,0 +1,986 @@ + + + + 9b2f12af-1fba-444c-b72b-9cbc43fb3ca5 + + x86_64 + Skylake-Client-IBRS + Intel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tcp + rdma + + + + + + 16161320 + 4040330 + 0 + 0 + + + + + + + + + + + + + + + + + none + 0 + + + + + hvm + + 64 + /usr/bin/qemu-system-alpha + clipper + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-arm + integratorcp + ast2600-evb + borzoi + spitz + virt-2.7 + nuri + mcimx7d-sabre + romulus-bmc + virt-3.0 + virt-5.0 + npcm750-evb + virt-2.10 + musca-b1 + virt-2.8 + realview-pbx-a9 + versatileab + kzm + musca-a + virt-3.1 + mcimx6ul-evk + virt-5.1 + smdkc210 + sx1 + virt-2.11 + imx25-pdk + virt-2.9 + orangepi-pc + z2 + virt-5.2 + virt + xilinx-zynq-a9 + tosa + mps2-an500 + virt-2.12 + mps2-an521 + sabrelite + mps2-an511 + canon-a1100 + realview-eb + emcraft-sf2 + realview-pb-a8 + virt-4.0 + raspi1ap + palmetto-bmc + sx1-v1 + n810 + tacoma-bmc + n800 + virt-4.1 + quanta-gsj + versatilepb + terrier + mainstone + realview-eb-mpcore + supermicrox11-bmc + virt-4.2 + witherspoon-bmc + swift-bmc + vexpress-a9 + midway + musicpal + lm3s811evb + lm3s6965evb + microbit + mps2-an505 + mps2-an385 + cubieboard + verdex + netduino2 + mps2-an386 + raspi2b + raspi2 + vexpress-a15 + sonorapass-bmc + cheetah + virt-2.6 + ast2500-evb + highbank + akita + connex + netduinoplus2 + collie + raspi0 + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-arm + integratorcp + ast2600-evb + borzoi + spitz + virt-2.7 + nuri + mcimx7d-sabre + romulus-bmc + virt-3.0 + virt-5.0 + npcm750-evb + virt-2.10 + musca-b1 + virt-2.8 + realview-pbx-a9 + versatileab + kzm + musca-a + virt-3.1 + mcimx6ul-evk + virt-5.1 + smdkc210 + sx1 + virt-2.11 + imx25-pdk + virt-2.9 + orangepi-pc + z2 + virt-5.2 + virt + xilinx-zynq-a9 + tosa + mps2-an500 + virt-2.12 + mps2-an521 + sabrelite + mps2-an511 + canon-a1100 + realview-eb + emcraft-sf2 + realview-pb-a8 + virt-4.0 + raspi1ap + palmetto-bmc + sx1-v1 + n810 + tacoma-bmc + n800 + virt-4.1 + quanta-gsj + versatilepb + terrier + mainstone + realview-eb-mpcore + supermicrox11-bmc + virt-4.2 + witherspoon-bmc + swift-bmc + vexpress-a9 + midway + musicpal + lm3s811evb + lm3s6965evb + microbit + mps2-an505 + mps2-an385 + cubieboard + verdex + netduino2 + mps2-an386 + raspi2b + raspi2 + vexpress-a15 + sonorapass-bmc + cheetah + virt-2.6 + ast2500-evb + highbank + akita + connex + netduinoplus2 + collie + raspi0 + + + + + + + + + + + hvm + + 64 + /usr/bin/qemu-system-aarch64 + integratorcp + ast2600-evb + borzoi + spitz + virt-2.7 + nuri + mcimx7d-sabre + romulus-bmc + virt-3.0 + virt-5.0 + npcm750-evb + virt-2.10 + musca-b1 + virt-2.8 + realview-pbx-a9 + versatileab + kzm + musca-a + virt-3.1 + mcimx6ul-evk + virt-5.1 + smdkc210 + sx1 + virt-2.11 + imx25-pdk + virt-2.9 + orangepi-pc + z2 + virt-5.2 + virt + xilinx-zynq-a9 + xlnx-zcu102 + tosa + mps2-an500 + virt-2.12 + mps2-an521 + sabrelite + mps2-an511 + canon-a1100 + realview-eb + emcraft-sf2 + realview-pb-a8 + sbsa-ref + virt-4.0 + raspi1ap + palmetto-bmc + sx1-v1 + n810 + tacoma-bmc + n800 + virt-4.1 + quanta-gsj + versatilepb + terrier + mainstone + realview-eb-mpcore + supermicrox11-bmc + virt-4.2 + witherspoon-bmc + swift-bmc + vexpress-a9 + midway + musicpal + lm3s811evb + lm3s6965evb + microbit + mps2-an505 + mps2-an385 + raspi3ap + cubieboard + verdex + netduino2 + xlnx-versal-virt + mps2-an386 + raspi3b + raspi3 + raspi2b + raspi2 + vexpress-a15 + sonorapass-bmc + cheetah + virt-2.6 + ast2500-evb + highbank + akita + connex + netduinoplus2 + collie + raspi0 + + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-cris + axis-dev88 + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-i386 + pc-i440fx-5.2 + pc + pc-q35-5.2 + q35 + pc-i440fx-2.12 + pc-i440fx-2.0 + pc-q35-4.2 + pc-i440fx-2.5 + pc-i440fx-4.2 + pc-i440fx-1.5 + pc-q35-2.7 + pc-i440fx-2.2 + pc-1.1 + pc-i440fx-2.7 + pc-q35-2.4 + pc-q35-2.10 + pc-i440fx-1.7 + pc-q35-5.1 + pc-q35-2.9 + pc-i440fx-2.11 + pc-q35-3.1 + pc-q35-4.1 + pc-i440fx-2.4 + pc-1.3 + pc-i440fx-4.1 + pc-i440fx-5.1 + pc-i440fx-2.9 + isapc + pc-i440fx-1.4 + pc-q35-2.6 + pc-i440fx-3.1 + pc-q35-2.12 + pc-i440fx-2.1 + pc-1.0 + pc-i440fx-2.6 + pc-q35-4.0.1 + pc-i440fx-1.6 + pc-q35-5.0 + pc-q35-2.8 + pc-i440fx-2.10 + pc-q35-3.0 + pc-q35-4.0 + microvm + pc-i440fx-2.3 + pc-1.2 + pc-i440fx-4.0 + pc-i440fx-5.0 + pc-i440fx-2.8 + pc-q35-2.5 + pc-i440fx-3.0 + pc-q35-2.11 + + + + + + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-m68k + mcf5208evb + an5206 + q800 + next-cube + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-microblaze + petalogix-s3adsp1800 + petalogix-ml605 + xlnx-zynqmp-pmu + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-microblazeel + petalogix-s3adsp1800 + petalogix-ml605 + xlnx-zynqmp-pmu + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-mips + malta + mipssim + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-mipsel + malta + mipssim + + + + + + + + + + + hvm + + 64 + /usr/bin/qemu-system-mips64 + malta + pica61 + mipssim + magnum + + + + + + + + + + + hvm + + 64 + /usr/bin/qemu-system-mips64el + malta + mipssim + pica61 + magnum + boston + fuloong2e + fulong2e + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-ppc + g3beige + virtex-ml507 + mac99 + ppce500 + sam460ex + bamboo + 40p + ref405ep + mpc8544ds + taihu + + + + + + + + + + + hvm + + 64 + /usr/bin/qemu-system-ppc64 + pseries-5.2 + pseries + powernv9 + powernv + taihu + pseries-4.1 + mpc8544ds + pseries-2.5 + powernv10 + pseries-4.2 + pseries-2.6 + ppce500 + pseries-2.7 + pseries-3.0 + pseries-5.0 + 40p + pseries-2.8 + pseries-3.1 + pseries-5.1 + pseries-2.9 + bamboo + g3beige + pseries-2.12-sxxm + pseries-2.10 + virtex-ml507 + pseries-2.11 + pseries-2.1 + pseries-2.12 + pseries-2.2 + mac99 + sam460ex + ref405ep + pseries-2.3 + powernv8 + pseries-4.0 + pseries-2.4 + + + + + + + + + + + hvm + + 64 + /usr/bin/qemu-system-ppc64 + pseries-5.2 + pseries + powernv9 + powernv + taihu + pseries-4.1 + mpc8544ds + pseries-2.5 + powernv10 + pseries-4.2 + pseries-2.6 + ppce500 + pseries-2.7 + pseries-3.0 + pseries-5.0 + 40p + pseries-2.8 + pseries-3.1 + pseries-5.1 + pseries-2.9 + bamboo + g3beige + pseries-2.12-sxxm + pseries-2.10 + virtex-ml507 + pseries-2.11 + pseries-2.1 + pseries-2.12 + pseries-2.2 + mac99 + sam460ex + ref405ep + pseries-2.3 + powernv8 + pseries-4.0 + pseries-2.4 + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-riscv32 + spike + virt + opentitan + sifive_e + sifive_u + + + + + + + + + + + hvm + + 64 + /usr/bin/qemu-system-riscv64 + spike + virt + sifive_e + sifive_u + microchip-icicle-kit + + + + + + + + + + + hvm + + 64 + /usr/bin/qemu-system-s390x + s390-ccw-virtio-5.2 + s390-ccw-virtio + s390-ccw-virtio-4.0 + s390-ccw-virtio-3.1 + s390-ccw-virtio-2.6 + s390-ccw-virtio-2.12 + s390-ccw-virtio-2.9 + s390-ccw-virtio-5.1 + s390-ccw-virtio-3.0 + s390-ccw-virtio-4.2 + s390-ccw-virtio-2.5 + s390-ccw-virtio-2.11 + s390-ccw-virtio-2.8 + s390-ccw-virtio-5.0 + s390-ccw-virtio-4.1 + s390-ccw-virtio-2.4 + s390-ccw-virtio-2.10 + s390-ccw-virtio-2.7 + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-sh4 + shix + r2d + + + + + + + + + + + hvm + + 64 + /usr/bin/qemu-system-sh4eb + shix + r2d + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-sparc + SS-5 + SS-20 + LX + SPARCClassic + leon3_generic + SPARCbook + SS-4 + SS-600MP + SS-10 + Voyager + + + + + + + + + + + hvm + + 64 + /usr/bin/qemu-system-sparc64 + sun4u + niagara + sun4v + + + + + + + + + + + hvm + + 64 + /usr/bin/qemu-system-x86_64 + pc-i440fx-5.2 + pc + pc-q35-5.2 + q35 + pc-i440fx-2.12 + pc-i440fx-2.0 + pc-q35-4.2 + pc-i440fx-2.5 + pc-i440fx-4.2 + pc-i440fx-1.5 + pc-q35-2.7 + pc-i440fx-2.2 + pc-1.1 + pc-i440fx-2.7 + pc-q35-2.4 + pc-q35-2.10 + pc-i440fx-1.7 + pc-q35-5.1 + pc-q35-2.9 + pc-i440fx-2.11 + pc-q35-3.1 + pc-q35-4.1 + pc-i440fx-2.4 + pc-1.3 + pc-i440fx-4.1 + pc-i440fx-5.1 + pc-i440fx-2.9 + isapc + pc-i440fx-1.4 + pc-q35-2.6 + pc-i440fx-3.1 + pc-q35-2.12 + pc-i440fx-2.1 + pc-1.0 + pc-i440fx-2.6 + pc-q35-4.0.1 + pc-i440fx-1.6 + pc-q35-5.0 + pc-q35-2.8 + pc-i440fx-2.10 + pc-q35-3.0 + pc-q35-4.0 + microvm + pc-i440fx-2.3 + pc-1.2 + pc-i440fx-4.0 + pc-i440fx-5.0 + pc-i440fx-2.8 + pc-q35-2.5 + pc-i440fx-3.0 + pc-q35-2.11 + + + + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-xtensa + sim + kc705 + ml605 + ml605-nommu + virt + lx60-nommu + lx200 + lx200-nommu + lx60 + kc705-nommu + + + + + + + + + + + hvm + + 32 + /usr/bin/qemu-system-xtensaeb + sim + kc705 + ml605 + ml605-nommu + virt + lx60-nommu + lx200 + lx200-nommu + lx60 + kc705-nommu + + + + + + + + + + + + diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/test/resources/libvirt/xml/qemu-kvm_default-ubuntu-20-04-vm.xml b/core/modules/qemu/runvirt-plugin-qemu/src/test/resources/libvirt/xml/qemu-kvm_default-ubuntu-20-04-vm.xml new file mode 100644 index 00000000..241a6807 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/test/resources/libvirt/xml/qemu-kvm_default-ubuntu-20-04-vm.xml @@ -0,0 +1,164 @@ + + ubuntu-20-04 + 8dc5433c-0228-49e4-b019-fa2b606aa544 + Ubuntu 20.04 + Ubuntu 20.04 desktop installation + + + + + + 4194304 + 4194304 + 2 + + hvm + + + + + + + + + + + + + + destroy + restart + destroy + + + + + + /usr/bin/qemu-system-x86_64 + + + + +
+ + + + + +
+ + + + +
+ + +
+ + + +
+ + + +
+ + + +
+ + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + +
+ + +
+ + + + + + +
+ + + + + + + + + + + +
+ + + +
+ + +
+ + + + + + + + +
+ +