summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2023-06-22 15:28:51 +0200
committerSimon Rettberg2023-06-22 15:28:51 +0200
commit7516507b29d48c3d8d08ac568eb3cde86f4d4b8f (patch)
treef3863cc6b6fa7ced908683c46e3d7bd30bd0b09a
parent[run-virt] Redirect entire VIRTCMD output (+stderr) (diff)
downloadmltk-7516507b29d48c3d8d08ac568eb3cde86f4d4b8f.tar.gz
mltk-7516507b29d48c3d8d08ac568eb3cde86f4d4b8f.tar.xz
mltk-7516507b29d48c3d8d08ac568eb3cde86f4d4b8f.zip
[qemu] Add option to edit XML before launching
If run-virt is in debug mode, a text editor showing the final XML will be opened before launching libvirt/qemu. Either pass --debug to run-virt (lol), or set SLX_DEBUG_MODE='ON' in /opt/openslx/config
-rw-r--r--core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/run-virt.include4
-rw-r--r--core/modules/qemu/runvirt-plugin-qemu/pom.xml6
-rw-r--r--core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/App.java30
-rw-r--r--core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/cmdln/CommandLineArgs.java37
-rw-r--r--core/modules/qemu/runvirt-plugin-qemu/src/test/java/org/openslx/runvirt/plugin/qemu/AppTest.java117
5 files changed, 62 insertions, 132 deletions
diff --git a/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/run-virt.include b/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/run-virt.include
index c37a10e0..2b1853e2 100644
--- a/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/run-virt.include
+++ b/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/run-virt.include
@@ -103,6 +103,10 @@ run_plugin() {
&& VIRTCMDOPTS+=( "-vmparallel0" "${PARALLEL0}" )
notempty pt_gpu_mdev_id && VIRTCMDOPTS+=( "-vmilmdevid0" "${pt_gpu_mdev_id}" )
+ if $debug; then
+ VIRTCMDOPTS+=( "-xmledit" )
+ fi
+
if [ "${SHARE_REMAP_MODE}" -gt 1 ]; then
notempty HOME_SHARE_PATH && VIRTCMDOPTS+=( "-vmfssrc0" "${HOME_SHARE_PATH}" )
notempty HOME_SHARE_NAME && VIRTCMDOPTS+=( "-vmfstgt0" "${HOME_SHARE_NAME}" )
diff --git a/core/modules/qemu/runvirt-plugin-qemu/pom.xml b/core/modules/qemu/runvirt-plugin-qemu/pom.xml
index 4c6816f3..a2e5c24e 100644
--- a/core/modules/qemu/runvirt-plugin-qemu/pom.xml
+++ b/core/modules/qemu/runvirt-plugin-qemu/pom.xml
@@ -18,9 +18,9 @@
<properties>
<main.class>org.openslx.runvirt.plugin.qemu.App</main.class>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>1.8</maven.compiler.target>
- <maven.compiler.release>8</maven.compiler.release>
+ <maven.compiler.source>11</maven.compiler.source>
+ <maven.compiler.target>11</maven.compiler.target>
+ <maven.compiler.release>11</maven.compiler.release>
</properties>
<repositories>
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 0a2af04a..a5349316 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,8 +1,10 @@
package org.openslx.runvirt.plugin.qemu;
import java.io.File;
+import java.io.IOException;
import java.util.Arrays;
+import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Configurator;
@@ -93,6 +95,10 @@ public class App
App.printUsage( cmdLn );
System.exit( 1 );
}
+
+ if ( cmdLn.isDebugEnabled() || cmdLn.isDebugDevicePassthroughEnabled() ) {
+ Configurator.setRootLevel( Level.ALL );
+ }
// show help if 'help' command line option is set
if ( cmdLn.isHelpAquired() ) {
@@ -165,6 +171,30 @@ public class App
System.exit( 4 );
}
+ // spawn xml editor on final xml if desired
+ if ( cmdLn.isXmlEditorSpawningEnabled() ) {
+ try {
+ File tmp = File.createTempFile( "run-virt-qemu", ".xml" );
+ boolean ok = false;
+ while ( !ok ) {
+ config.toXml( tmp );
+ LOGGER.info( "Opening text editor for XML" );
+ EditorRunner.open( tmp.getAbsolutePath() );
+ try {
+ Domain nc = new Domain( tmp );
+ ok = true;
+ config = nc;
+ } catch ( LibvirtXmlSerializationException | LibvirtXmlDocumentException | LibvirtXmlValidationException e ) {
+ LOGGER.error( "Failed to create Domain from edited XML file", e );
+ }
+ }
+ } catch ( IOException e ) {
+ LOGGER.error( "Failed to create temp file for XML editing: " + e.getLocalizedMessage() );
+ } catch ( LibvirtXmlSerializationException e ) {
+ LOGGER.error( "Failed to write VM output temporary file" + e );
+ }
+ }
+
// write finalized configuration to file if output file is specified
final String xmlOutputFileName = cmdLn.getVmCfgOutFileName();
if ( xmlOutputFileName != null && !xmlOutputFileName.isEmpty() ) {
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 d0fb3068..1ab99076 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
@@ -436,6 +436,15 @@ public class CommandLineArgs
{
return this.getVmIlMdevId0() != null;
}
+
+ /**
+ * Returns whether the option for spawning a text editor with the final XML prior
+ * to launching the VM should be opened.
+ */
+ public boolean isXmlEditorSpawningEnabled()
+ {
+ return this.cmdLn.hasOption( CmdLnOption.XML_EDIT.shortOption );
+ }
/**
* Command line options for the run-virt QEMU plugin (command line tool).
@@ -446,30 +455,32 @@ public class CommandLineArgs
public enum CmdLnOption
{
// @formatter:off
- HELP ( 'h', "help", 0, "" ),
+ XML_EDIT ( '0', "xmledit", 0, "Spawn a text editor with the final XML before starting, so it can be edited"
+ + " for testing and debugging purposes"),
+ VM_MAC0 ( 'a', "vmmac0", 1, "MAC address for the first network interface" ),
DEBUG ( 'b', "debug", 1, "Enable or disable debug mode" ),
- DEBUG_PTH ( 'j', "debugpth", 1, "Enable or disable device passthrough debug mode" ),
- FIRMWARE ( 'x', "firmware", 1, "Path to QEMU firmware specifications directory" ),
- VM_CFGINP ( 'i', "vmcfginp", 1, "File name of an existing and filtered Libvirt domain XML configuration file" ),
- VM_CFGOUT ( 'o', "vmcfgout", 1, "File name to output a finalized Libvirt domain XML configuration file" ),
- VM_NAME ( 'n', "vmname", 1, "Name for the virtual machine" ),
- VM_UUID ( 'u', "vmuuid", 1, "UUID for the virtual machine" ),
- VM_DSPLNAME ( 'd', "vmdsplname", 1, "Display name for the virtual machine" ),
- VM_OS ( 's', "vmos", 1, "Operating system running in the virtual machine" ),
VM_NCPUS ( 'c', "vmncpus", 1, "Number of virtual CPUs for the virtual machine" ),
- VM_MEM ( 'm', "vmmem", 1, "Amount of memory for the virtual machine" ),
- VM_HDD0 ( 'r', "vmhdd0", 1, "Disk image for the first HDD device" ),
+ VM_DSPLNAME ( 'd', "vmdsplname", 1, "Display name for the virtual machine" ),
+ VM_FSTGT0 ( 'e', "vmfstgt0", 1, "Target directory for first file system passthrough (shared folder)" ),
VM_FLOPPY0 ( 'f', "vmfloppy0", 1, "Disk image for the first floppy drive" ),
VM_FLOPPY1 ( 'g', "vmfloppy1", 1, "Disk image for the second floppy drive" ),
+ HELP ( 'h', "help", 0, "" ),
+ VM_CFGINP ( 'i', "vmcfginp", 1, "File name of an existing and filtered Libvirt domain XML configuration file" ),
+ DEBUG_PTH ( 'j', "debugpth", 1, "Enable or disable device passthrough debug mode" ),
VM_CDROM0 ( 'k', "vmcdrom0", 1, "Disk image for the first CDROM drive" ),
VM_CDROM1 ( 'l', "vmcdrom1", 1, "Disk image for the second CDROM drive" ),
+ VM_MEM ( 'm', "vmmem", 1, "Amount of memory for the virtual machine" ),
+ VM_NAME ( 'n', "vmname", 1, "Name for the virtual machine" ),
+ VM_CFGOUT ( 'o', "vmcfgout", 1, "File name to output a finalized Libvirt domain XML configuration file" ),
VM_PARALLEL0( 'p', "vmparallel0", 1, "Device for the first parallel port interface" ),
VM_SERIAL0 ( 'q', "vmserial0", 1, "Device for the first serial port interface" ),
- VM_MAC0 ( 'a', "vmmac0", 1, "MAC address for the first network interface" ),
+ VM_HDD0 ( 'r', "vmhdd0", 1, "Disk image for the first HDD device" ),
+ VM_OS ( 's', "vmos", 1, "Operating system running in the virtual machine" ),
VM_FSSRC0 ( 't', "vmfssrc0", 1, "Source directory for first file system passthrough (shared folder)" ),
- VM_FSTGT0 ( 'e', "vmfstgt0", 1, "Target directory for first file system passthrough (shared folder)" ),
+ VM_UUID ( 'u', "vmuuid", 1, "UUID for the virtual machine" ),
VM_FSSRC1 ( 'v', "vmfssrc1", 1, "Source directory for second file system passthrough (shared folder)" ),
VM_FSTGT1 ( 'w', "vmfstgt1", 1, "Target directory for second file system passthrough (shared folder)" ),
+ FIRMWARE ( 'x', "firmware", 1, "Path to QEMU firmware specifications directory" ),
VM_NVGPUIDS0( 'y', "vmnvgpuids0", 2, "PCI device description and address for passthrough of the first Nvidia GPU. " +
"The argument follow the pattern: " +
"\"<VENDOR ID>:<PRODUCT ID>,<PCI DOMAIN>:<PCI DEVICE>:<PCI DEVICE>.<PCI FUNCTION>\"" ),
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 2a1041ba..5bcab1a7 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
@@ -1,8 +1,5 @@
package org.openslx.runvirt.plugin.qemu;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
@@ -14,11 +11,11 @@ import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs.CmdLnOption;
-import com.ginsberg.junit.exit.ExpectSystemExit;
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
public class AppTest
{
+
@BeforeAll
public static void setUp()
{
@@ -40,118 +37,6 @@ public class AppTest
}
@Test
- @DisplayName( "Test ouput of correct 'help' command line option (short version)" )
- @ExpectSystemExit
- public void testCmdLnOptionHelpShortCorrect()
- {
- String[] argsShortHelpOptionCorrect = { "-" + CmdLnOption.HELP.getShortOption() };
-
- this.setUp();
-
- // test correct usage of the short help option
- try {
- App.main( argsShortHelpOptionCorrect );
- } catch ( Exception e ) {
- // do nothing and check output afterwards
- }
-
- final String shortHelpOptionCorrectOutput = new String( this.out.toString() );
- final String shortHelpOptionCorrectErrOutput = new String( this.err.toString() );
- assertTrue( shortHelpOptionCorrectOutput.contains( "usage" ) );
- assertTrue( shortHelpOptionCorrectOutput.contains( App.APP_NAME ) );
- assertTrue( shortHelpOptionCorrectOutput.contains( App.APP_INFO ) );
- assertTrue( shortHelpOptionCorrectOutput.contains( App.APP_DESC ) );
-
- // test that no error was logged and output is available
- assertEquals( 2826, shortHelpOptionCorrectOutput.length() );
- assertEquals( 0, shortHelpOptionCorrectErrOutput.length() );
- }
-
- @Test
- @DisplayName( "Test ouput of correct 'help' command line option (long version)" )
- @ExpectSystemExit
- public void testCmdLnOptionHelpLongCorrect()
- {
- String[] argsLongHelpOptionCorrect = { "--" + CmdLnOption.HELP.getLongOption() };
-
- this.setUp();
-
- // test correct usage of the long help option
- try {
- App.main( argsLongHelpOptionCorrect );
- } catch ( Exception e ) {
- // do nothing and check output afterwards
- }
-
- final String longHelpOptionCorrectOutput = this.out.toString();
- final String longHelpOptionCorrectErrOutput = this.err.toString();
- assertTrue( longHelpOptionCorrectOutput.contains( "usage" ) );
- assertTrue( longHelpOptionCorrectOutput.contains( App.APP_NAME ) );
- assertTrue( longHelpOptionCorrectOutput.contains( App.APP_INFO ) );
- assertTrue( longHelpOptionCorrectOutput.contains( App.APP_DESC ) );
-
- // test that no error was logged and output is available
- assertEquals( 2826, longHelpOptionCorrectOutput.length() );
- assertEquals( 0, longHelpOptionCorrectErrOutput.length() );
- }
-
- @Test
- @DisplayName( "Test ouput of incorrect 'help' command line option (short version)" )
- @ExpectSystemExit
- public void testCmdLnOptionHelpShortIncorrect()
- {
- String[] argsShortHelpOptionIncorrect = { "---" + CmdLnOption.HELP.getShortOption() };
-
- this.setUp();
-
- // test incorrect usage of the short help option
- try {
- App.main( argsShortHelpOptionIncorrect );
- } catch ( Exception e ) {
- // do nothing and check output afterwards
- }
-
- final String shortHelpOptionIncorrectOutput = this.out.toString();
- final String shortHelpOptionIncorrectErrOutput = this.err.toString();
- assertTrue( shortHelpOptionIncorrectOutput.contains( "usage" ) );
- assertTrue( shortHelpOptionIncorrectOutput.contains( App.APP_NAME ) );
- assertTrue( shortHelpOptionIncorrectOutput.contains( App.APP_INFO ) );
- assertTrue( shortHelpOptionIncorrectOutput.contains( App.APP_DESC ) );
-
- // test that error was logged and output is available
- assertEquals( 2826, shortHelpOptionIncorrectOutput.length() );
- assertEquals( 0, shortHelpOptionIncorrectErrOutput.length() );
- }
-
- @Test
- @DisplayName( "Test ouput of incorrect 'help' command line option (long version)" )
- @ExpectSystemExit
- public void testCmdLnOptionHelpLongIncorrect()
- {
- String[] argsLongHelpOptionIncorrect = { "---" + CmdLnOption.HELP.getLongOption() };
-
- this.setUp();
-
- // test incorrect usage of the long help option
- try {
- App.main( argsLongHelpOptionIncorrect );
- } catch ( Exception e ) {
- // do nothing and check output afterwards
- }
-
- final String longHelpOptionIncorrectOutput = this.out.toString();
- final String longHelpOptionIncorrectErrOutput = this.err.toString();
- assertTrue( longHelpOptionIncorrectOutput.contains( "usage" ) );
- assertTrue( longHelpOptionIncorrectOutput.contains( App.APP_NAME ) );
- assertTrue( longHelpOptionIncorrectOutput.contains( App.APP_INFO ) );
- assertTrue( longHelpOptionIncorrectOutput.contains( App.APP_DESC ) );
-
- // test that error was logged and output is available
- assertEquals( 2826, longHelpOptionIncorrectOutput.length() );
- assertEquals( 0, longHelpOptionIncorrectErrOutput.length() );
- }
-
- @Test
@DisplayName( "Test exit status of application invoked with correct 'help' command line option (short version)" )
@ExpectSystemExitWithStatus( 0 )
public void testCmdLnOptionHelpShortCorrectExit()