From 32c3d1b552016c4303ff7abf887bb62a736db9f8 Mon Sep 17 00:00:00 2001 From: Manuel Bentele Date: Mon, 26 Apr 2021 15:34:02 +0200 Subject: Fix error while parsing Libvirt XML document from String --- .../java/org/openslx/libvirt/xml/LibvirtXmlDocument.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src/main/java/org/openslx/libvirt/xml') diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java index 9382ced..f24ba4f 100644 --- a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; +import java.io.StringReader; import java.io.StringWriter; import javax.xml.parsers.DocumentBuilder; @@ -252,16 +253,7 @@ public abstract class LibvirtXmlDocument implements LibvirtXmlSerializable, Libv @Override public void fromXml( String xml ) throws LibvirtXmlSerializationException { - try { - this.xmlDocument = this.domBuilder.parse( xml ); - this.xmlDocument.getDocumentElement().normalize(); - } catch ( SAXException e ) { - e.printStackTrace(); - } catch ( IOException e ) { - e.printStackTrace(); - } - - this.rootXmlNode = new LibvirtXmlNode( this.xmlDocument, this.xmlDocument.getDocumentElement() ); + this.fromXml( new InputSource( new StringReader( xml ) ) ); } @Override -- cgit v1.2.3-55-g7522 From c5d35cf6b739444ba0d065203d8f21db86d0c8c1 Mon Sep 17 00:00:00 2001 From: Manuel Bentele Date: Fri, 30 Apr 2021 12:11:32 +0200 Subject: Fix errors in Javadoc comments --- .../java/org/openslx/libvirt/domain/Domain.java | 2 +- .../libvirt/domain/device/ControllerUsb.java | 2 +- .../org/openslx/libvirt/domain/device/Disk.java | 2 +- .../openslx/libvirt/domain/device/HostdevPci.java | 2 +- .../openslx/libvirt/domain/device/Interface.java | 6 +- .../org/openslx/libvirt/domain/device/Sound.java | 2 +- .../org/openslx/libvirt/domain/device/Video.java | 2 +- .../openslx/libvirt/xml/LibvirtXmlEditable.java | 72 +++++++++++----------- .../org/openslx/libvirt/xml/LibvirtXmlNode.java | 22 +++---- .../libvirt/xml/LibvirtXmlSchemaValidator.java | 5 +- .../libvirt/xml/LibvirtXmlSerializable.java | 12 ++++ .../java/org/openslx/virtualization/Version.java | 2 +- .../configuration/VirtualizationConfiguration.java | 9 ++- .../VirtualizationConfigurationQemuUtils.java | 2 +- ...alizationConfigurationVirtualboxFileFormat.java | 9 +-- ...onfigurationDataDozModClientToDozModServer.java | 6 +- ...onfigurationDataDozModServerToDozModClient.java | 6 +- ...igurationDataDozModServerToStatelessClient.java | 6 +- ...nfigurationLogicDozModClientToDozModServer.java | 2 +- ...nfigurationLogicDozModServerToDozModClient.java | 2 +- ...gurationLogicDozModServerToStatelessClient.java | 2 +- .../transformation/TransformationSpecific.java | 1 + src/main/java/org/openslx/vm/disk/DiskImage.java | 2 +- .../java/org/openslx/vm/disk/DiskImageQcow2.java | 4 +- .../java/org/openslx/vm/disk/DiskImageUtils.java | 8 +-- .../java/org/openslx/vm/disk/DiskImageVmdk.java | 3 +- 26 files changed, 109 insertions(+), 84 deletions(-) (limited to 'src/main/java/org/openslx/libvirt/xml') diff --git a/src/main/java/org/openslx/libvirt/domain/Domain.java b/src/main/java/org/openslx/libvirt/domain/Domain.java index dbc60e6..c8f5303 100644 --- a/src/main/java/org/openslx/libvirt/domain/Domain.java +++ b/src/main/java/org/openslx/libvirt/domain/Domain.java @@ -603,7 +603,7 @@ public class Domain extends LibvirtXmlDocument /** * Creates a CPU check from its name with error check. * - * @param mode name of the CPU check in the Libvirt domain XML document. + * @param check name of the CPU check in the Libvirt domain XML document. * @return valid CPU check. */ public static CpuCheck fromString( String check ) diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerUsb.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerUsb.java index 695167c..1798027 100644 --- a/src/main/java/org/openslx/libvirt/domain/device/ControllerUsb.java +++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerUsb.java @@ -122,7 +122,7 @@ public class ControllerUsb extends Controller /** * Creates USB controller device model from its name with error check. * - * @param type name of the USB controller device model in a Libvirt domain XML document. + * @param model name of the USB controller device model in a Libvirt domain XML document. * @return valid USB controller device model. */ public static Model fromString( String model ) diff --git a/src/main/java/org/openslx/libvirt/domain/device/Disk.java b/src/main/java/org/openslx/libvirt/domain/device/Disk.java index d9007f5..7694538 100644 --- a/src/main/java/org/openslx/libvirt/domain/device/Disk.java +++ b/src/main/java/org/openslx/libvirt/domain/device/Disk.java @@ -195,7 +195,7 @@ public class Disk extends Device /** * Sets target device for the disk device. * - * @param target device for the disk device. + * @param targetDevice target device for the disk device. */ public void setTargetDevice( String targetDevice ) { diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevPci.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevPci.java index 3b26fb0..a0563f2 100644 --- a/src/main/java/org/openslx/libvirt/domain/device/HostdevPci.java +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevPci.java @@ -48,7 +48,7 @@ public class HostdevPci extends Hostdev * detached from the host before being passed on to the guest and reattached to the host after * the guest exits. * - * @return state whether PCI hostdev device is managed. + * @param managed state whether PCI hostdev device is managed or not. */ public void setManaged( boolean managed ) { diff --git a/src/main/java/org/openslx/libvirt/domain/device/Interface.java b/src/main/java/org/openslx/libvirt/domain/device/Interface.java index dae3c11..44b8e4c 100644 --- a/src/main/java/org/openslx/libvirt/domain/device/Interface.java +++ b/src/main/java/org/openslx/libvirt/domain/device/Interface.java @@ -62,8 +62,8 @@ public class Interface extends Device /** * Sets type of the network device. - * - * @return type of the network device. + * + * @param type network device type. */ public void setType( Type type ) { @@ -327,7 +327,7 @@ public class Interface extends Device /** * Creates network interface device model from its name with error check. * - * @param type name of the network interface device model in a Libvirt domain XML document. + * @param model name of the network interface device model in a Libvirt domain XML document. * @return valid network interface device model. */ public static Model fromString( String model ) diff --git a/src/main/java/org/openslx/libvirt/domain/device/Sound.java b/src/main/java/org/openslx/libvirt/domain/device/Sound.java index e424ed4..dfeeffd 100644 --- a/src/main/java/org/openslx/libvirt/domain/device/Sound.java +++ b/src/main/java/org/openslx/libvirt/domain/device/Sound.java @@ -111,7 +111,7 @@ public class Sound extends Device /** * Creates sound device model from its name with error check. * - * @param type name of the sound device model in a Libvirt domain XML document. + * @param model name of the sound device model in a Libvirt domain XML document. * @return valid sound device model. */ public static Model fromString( String model ) diff --git a/src/main/java/org/openslx/libvirt/domain/device/Video.java b/src/main/java/org/openslx/libvirt/domain/device/Video.java index e901b85..0f8861f 100644 --- a/src/main/java/org/openslx/libvirt/domain/device/Video.java +++ b/src/main/java/org/openslx/libvirt/domain/device/Video.java @@ -171,7 +171,7 @@ public class Video extends Device /** * Creates video device model from its name with error check. * - * @param type name of the video device model in a Libvirt domain XML document. + * @param model name of the video device model in a Libvirt domain XML document. * @return valid video device model. */ public static Model fromString( String model ) diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlEditable.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlEditable.java index 1ddddce..40d7b86 100644 --- a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlEditable.java +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlEditable.java @@ -4,7 +4,7 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** - * Editability of XML nodes based on {@link XPath} expressions. + * Editability of XML nodes based on XPath expressions. * * @author Manuel Bentele * @version 1.0 @@ -12,17 +12,17 @@ import org.w3c.dom.NodeList; public interface LibvirtXmlEditable { /** - * Returns XML node selected by a {@link XPath} expression + * Returns XML node selected by a XPath expression * - * @param expression {@link XPath} expression to select XML node. + * @param expression XPath expression to select XML node. * @return selected XML node. */ public Node getXmlNode( String expression ); /** - * Returns XML nodes selected by a {@link XPath} expression + * Returns XML nodes selected by a XPath expression * - * @param expression {@link XPath} expression to select XML nodes. + * @param expression XPath expression to select XML nodes. * @return selected XML nodes. */ public NodeList getXmlNodes( String expression ); @@ -38,20 +38,20 @@ public interface LibvirtXmlEditable } /** - * Returns XML element from selection by a {@link XPath} expression. + * Returns XML element from selection by a XPath expression. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. * @return selected XML element. */ public Node getXmlElement( String expression ); /** - * Sets an XML element selected by a {@link XPath} expression. + * Sets an XML element selected by a XPath expression. * - * If the XML element selected by the given {@link XPath} expression does not exists, the XML + * If the XML element selected by the given XPath expression does not exists, the XML * element will be created. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. */ public default void setXmlElement( String expression ) { @@ -59,43 +59,43 @@ public interface LibvirtXmlEditable } /** - * Sets a XML element selected by a {@link XPath} expression and appends child XML node. + * Sets a XML element selected by a XPath expression and appends child XML node. * - * If the XML element selected by the given {@link XPath} expression does not exists, the XML + * If the XML element selected by the given XPath expression does not exists, the XML * element will be created and the given XML child node is appended. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. * @param child XML node that will be appended to the selected XML element. */ public void setXmlElement( String expression, Node child ); /** - * Returns the text value of a XML element selected by a {@link XPath} expression. + * Returns the text value of a XML element selected by a XPath expression. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. * @return Text value of the selected XML element. */ public String getXmlElementValue( String expression ); /** - * Sets the text value of a XML element selected by a {@link XPath} expression. + * Sets the text value of a XML element selected by a XPath expression. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. * @param value text value to set selected XML element's text. */ public void setXmlElementValue( String expression, String value ); /** - * Removes a XML element and all its childs selected by a {@link XPath} expression. + * Removes a XML element and all its childs selected by a XPath expression. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. */ public void removeXmlElement( String expression ); /** - * Removes all child elements of a XML element selected by a {@link XPath} expression. + * Removes all child elements of a XML element selected by a XPath expression. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. */ public void removeXmlElementChilds( String expression ); @@ -128,14 +128,14 @@ public interface LibvirtXmlEditable } /** - * Returns the binary choice of a XML attribute from a XML element selected by a - * {@link XPath}expression. + * Returns the binary choice of a XML attribute from a XML element selected by a XPath + * expression. * * If the text value of the XML attribute equals to yes, the returned {@link boolean} * value is set to true. Otherwise, if the text value of the XML attribute equals to * no, the returned {@link boolean} value is set to false. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. * @param attributeName name to select XML attribute of the current XML root element. * @return attribute value of the XML attribute from the current XML root element as * {@link boolean}. @@ -146,10 +146,9 @@ public interface LibvirtXmlEditable } /** - * Returns the text value of a XML attribute from a XML element selected by a - * {@link XPath}expression. + * Returns the text value of a XML attribute from a XML element selected by a XPath expression. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. * @param attributeName name to select XML attribute of the selected XML element. * @return attribute text of the XML attribute from the selected XML element. */ @@ -185,15 +184,15 @@ public interface LibvirtXmlEditable } /** - * Sets the binary choice value of a XML attribute from a XML element selected by a - * {@link XPath} expression. + * Sets the binary choice value of a XML attribute from a XML element selected by a XPath + * expression. * * If the binary choice value for the XML attribute equals to true, the text value of the * selected XML attribute is set to yes. Otherwise, if the binary choice value for the * selected XML attribute equals to false, the text value of the selected XML attribute is * set to no. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. * @param attributeName name to select XML attribute of the selected XML element. * @param value binary choice value for the selected XML attribute from the selected XML element. */ @@ -204,10 +203,9 @@ public interface LibvirtXmlEditable } /** - * Sets the text value of a XML attribute from a XML element selected by a - * {@link XPath} expression. + * Sets the text value of a XML attribute from a XML element selected by a XPath expression. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. * @param attributeName name to select XML attribute of the selected XML element. * @param value XML attribute value for the selected XML attribute from the selected XML element. */ @@ -224,17 +222,17 @@ public interface LibvirtXmlEditable } /** - * Removes an XML attribute from a XML element selected by a {@link XPath} expression. + * Removes an XML attribute from a XML element selected by a XPath expression. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. * @param attributeName name of the attribute which should be deleted. */ public void removeXmlElementAttribute( String expression, String attributeName ); /** - * Removes all XML attributes from a XML element selected by a {@link XPath} expression. + * Removes all XML attributes from a XML element selected by a XPath expression. * - * @param expression {@link XPath} expression to select XML element. + * @param expression XPath expression to select XML element. */ public void removeXmlElementAttributes( String expression ); diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java index 93e28de..6d00271 100644 --- a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java @@ -12,7 +12,7 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** - * A representation of a XML node as part of a {@link LibvirtXMLDocument}. + * A representation of a XML node as part of a {@link LibvirtXmlDocument}. * * @author Manuel Bentele * @version 1.0 @@ -20,17 +20,17 @@ import org.w3c.dom.NodeList; public class LibvirtXmlNode implements LibvirtXmlCreatable, LibvirtXmlEditable { /** - * Separation character for internal {@link XPath} expressions. + * Separation character for internal XPath expressions. */ private static final String XPATH_EXPRESSION_SEPARATOR = "/"; /** - * Current XML node selection character for internal {@link XPath} expressions. + * Current XML node selection character for internal XPath expressions. */ private static final String XPATH_EXPRESSION_CURRENT_NODE = "."; /** - * Factory to create {@link XPath} objects. + * Factory to create XPath objects. */ private XPathFactory xPathFactory = null; @@ -40,13 +40,12 @@ public class LibvirtXmlNode implements LibvirtXmlCreatable, LibvirtXmlEditable private Document xmlDocument = null; /** - * Current XML base node as XML root anchor for relative internal {@link XPath} expressions. + * Current XML base node as XML root anchor for relative internal XPath expressions. */ private Node xmlBaseNode = null; /** - * Create and initialize {@link XPath} context to define and compile custom {@link XPath} - * expressions. + * Create and initialize XPath context to define and compile custom XPath expressions. */ private void createXPathContext() { @@ -139,8 +138,7 @@ public class LibvirtXmlNode implements LibvirtXmlCreatable, LibvirtXmlEditable /** * Returns current XML base node. * - * @return current XML base node as XML root anchor of relative internal {@link XPath} - * expressions. + * @return current XML base node as XML root anchor of relative internal XPath expressions. */ public Node getXmlBaseNode() { @@ -150,8 +148,8 @@ public class LibvirtXmlNode implements LibvirtXmlCreatable, LibvirtXmlEditable /** * Sets existing XML base node for Libvirt XML node. * - * @param xmlBaseNode existing XML base node as XML root anchor for relative internal - * {@link XPath} expressions. + * @param xmlBaseNode existing XML base node as XML root anchor for relative internal XPath + * expressions. */ public void setXmlBaseNode( Node xmlBaseNode ) { @@ -317,7 +315,7 @@ public class LibvirtXmlNode implements LibvirtXmlCreatable, LibvirtXmlEditable attribute.setNodeValue( value ); } } - + @Override public void removeXmlElementAttribute( String expression, String attributeName ) { diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSchemaValidator.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSchemaValidator.java index e074948..bc8f90f 100644 --- a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSchemaValidator.java +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSchemaValidator.java @@ -196,8 +196,9 @@ public class LibvirtXmlSchemaValidator /** * Creates a validator for validation of Libvirt XML documents with RelaxNG schemas. * - * @param rngSchema - * @throws SAXException + * @param rngSchema RelaxNG schema used for validation with {@link #validate(Document)}. + * + * @throws SAXException creation of a Libvirt XML validator failed. */ public LibvirtXmlSchemaValidator( InputStream rngSchema ) throws SAXException { diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializable.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializable.java index 6f11ce5..4cd0a32 100644 --- a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializable.java +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializable.java @@ -17,6 +17,8 @@ public abstract interface LibvirtXmlSerializable * Serialize Libvirt XML document from {@link String}. * * @param xml {@link String} containing XML content. + * + * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed. */ public void fromXml( String xml ) throws LibvirtXmlSerializationException; @@ -24,6 +26,8 @@ public abstract interface LibvirtXmlSerializable * Serialize Libvirt XML document from {@link File}. * * @param xml {@link File} containing XML content. + * + * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed. */ public void fromXml( File xml ) throws LibvirtXmlSerializationException; @@ -31,6 +35,8 @@ public abstract interface LibvirtXmlSerializable * Serialize Libvirt XML document from {@link InputStream}. * * @param xml {@link InputStream} providing XML content. + * + * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed. */ void fromXml( InputStream xml ) throws LibvirtXmlSerializationException; @@ -38,6 +44,8 @@ public abstract interface LibvirtXmlSerializable * Serialize Libvirt XML document from {@link InputSource}. * * @param xml {@link InputSource} providing XML content. + * + * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed. */ public void fromXml( InputSource xml ) throws LibvirtXmlSerializationException; @@ -45,6 +53,8 @@ public abstract interface LibvirtXmlSerializable * Serialize Libvirt XML document to {@link String}. * * @return XML {@link String} containing Libvirt XML document content. + * + * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed. */ public String toXml() throws LibvirtXmlSerializationException; @@ -52,6 +62,8 @@ public abstract interface LibvirtXmlSerializable * Serialize Libvirt XML document to {@link File}. * * @param xml XML {@link File} containing Libvirt XML document content. + * + * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed. */ public void toXml( File xml ) throws LibvirtXmlSerializationException; } diff --git a/src/main/java/org/openslx/virtualization/Version.java b/src/main/java/org/openslx/virtualization/Version.java index efc23af..5d99ac1 100644 --- a/src/main/java/org/openslx/virtualization/Version.java +++ b/src/main/java/org/openslx/virtualization/Version.java @@ -24,7 +24,7 @@ public class Version implements Comparable * The version consists of a major version, whereas the minor version is set to the value * 0 and the version name is undefined. * - * @param major + * @param major major version. */ public Version( short major ) { diff --git a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfiguration.java b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfiguration.java index b8e46ed..0ecd693 100644 --- a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfiguration.java +++ b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfiguration.java @@ -173,6 +173,8 @@ public abstract class VirtualizationConfiguration /** * Get operating system of this VM. + * + * @return operating system of the VM. */ public OperatingSystem getOs() { @@ -181,6 +183,8 @@ public abstract class VirtualizationConfiguration /** * Get all hard disks of this VM. + * + * @return list of hard disks of the VM. */ public List getHdds() { @@ -189,6 +193,8 @@ public abstract class VirtualizationConfiguration /** * Get display name of VM. + * + * @return display name of the VM. */ public String getDisplayName() { @@ -252,6 +258,7 @@ public abstract class VirtualizationConfiguration * @param osList List of supported operating systems * @param file VM's machine description file to get the metadata instance from * @return VmMetaData object representing the relevant parts of the given machine description + * @throws IOException failed to read machine description from specified file. */ public static VirtualizationConfiguration getInstance( List osList, File file ) throws IOException @@ -288,7 +295,7 @@ public abstract class VirtualizationConfiguration * @param vmContent VM's machine description as byte array (e.g. stored in DB) * @param length length of the byte array given as vmContent * @return VmMetaData object representing the relevant parts of the given machine description - * @throws IOException + * @throws IOException failed to read machine description from specified byte stream. */ public static VirtualizationConfiguration getInstance( List osList, byte[] vmContent, int length ) diff --git a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemuUtils.java b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemuUtils.java index 7ac3632..0288029 100644 --- a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemuUtils.java +++ b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemuUtils.java @@ -116,7 +116,7 @@ public class VirtualizationConfigurationQemuUtils /** * Converts a Libvirt network device model to a VM metadata ethernet device type. * - * @param soundDeviceModel Libvirt network device model. + * @param networkDeviceModel Libvirt network device model. * @return VM metadata ethernet device type. */ public static EthernetDevType convertNetworkDeviceModel( Interface.Model networkDeviceModel ) diff --git a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVirtualboxFileFormat.java b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVirtualboxFileFormat.java index 6a1f5a5..a0e1a1f 100644 --- a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVirtualboxFileFormat.java +++ b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVirtualboxFileFormat.java @@ -116,7 +116,7 @@ public class VirtualizationConfigurationVirtualboxFileFormat * * @param machineDescription content of the XML file saved as a byte array. * @param length of the machine description byte array. - * @throws IOException if an + * @throws VirtualizationConfigurationException creation of VirtualBox configuration file representation failed. */ public VirtualizationConfigurationVirtualboxFileFormat( byte[] machineDescription, int length ) throws VirtualizationConfigurationException { @@ -313,7 +313,7 @@ public class VirtualizationConfigurationVirtualboxFileFormat /** * Function finds and saves the name of the guest OS * - * @throws XPathExpressionException + * @throws XPathExpressionException failed to find and retrieve name of the guest OS. */ public void setOsType() throws XPathExpressionException { @@ -336,7 +336,7 @@ public class VirtualizationConfigurationVirtualboxFileFormat /** * Search for attached hard drives and determine their controller and their path. * - * @throws XPathExpressionException + * @throws XPathExpressionException failed to find attached hard drives and their controllers. */ public void setHdds() throws XPathExpressionException { @@ -452,6 +452,7 @@ public class VirtualizationConfigurationVirtualboxFileFormat * @param elementXPath given as an xpath expression * @param attribute attribute to change * @param value to set the attribute to + * @return state of the change operation whether the attribute was changed successful or not. */ public boolean changeAttribute( String elementXPath, String attribute, String value ) { @@ -491,7 +492,7 @@ public class VirtualizationConfigurationVirtualboxFileFormat * Adds a new node named nameOfNewNode to the given parent found by parentXPath. * * @param parentXPath XPath expression to the parent - * @param nameOfnewNode name of the node to be added + * @param childName name of the node to be added * @return the newly added Node */ public Node addNewNode( String parentXPath, String childName ) diff --git a/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModClientToDozModServer.java b/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModClientToDozModServer.java index 0d0c457..8a08d05 100644 --- a/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModClientToDozModServer.java +++ b/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModClientToDozModServer.java @@ -2,7 +2,8 @@ package org.openslx.virtualization.configuration.data; /** * Data container to collect and store input arguments for a - * {@link ConfigurationLogicDozModClientToDozModServer} transformation. + * {@link org.openslx.virtualization.configuration.logic.ConfigurationLogicDozModClientToDozModServer} + * transformation. * * @author Manuel Bentele * @version 1.0 @@ -11,7 +12,8 @@ public class ConfigurationDataDozModClientToDozModServer { /** * Creates a new data container to collect and store input arguments for a - * {@link ConfigurationLogicDozModClientToDozModServer} transformation. + * {@link org.openslx.virtualization.configuration.logic.ConfigurationLogicDozModClientToDozModServer} + * transformation. */ public ConfigurationDataDozModClientToDozModServer() { diff --git a/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModServerToDozModClient.java b/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModServerToDozModClient.java index 7b1c0b4..4e18d48 100644 --- a/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModServerToDozModClient.java +++ b/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModServerToDozModClient.java @@ -6,7 +6,8 @@ import org.openslx.bwlp.thrift.iface.OperatingSystem; /** * Data container to collect and store input arguments for a - * {@link ConfigurationLogicDozModServerToDozModClient} transformation. + * {@link org.openslx.virtualization.configuration.logic.ConfigurationLogicDozModServerToDozModClient} + * transformation. * * @author Manuel Bentele * @version 1.0 @@ -40,7 +41,8 @@ public class ConfigurationDataDozModServerToDozModClient /** * Creates a new data container to collect and store input arguments for a - * {@link ConfigurationLogicDozModServerToDozModClient} transformation. + * {@link org.openslx.virtualization.configuration.logic.ConfigurationLogicDozModServerToDozModClient} + * transformation. * * @param displayName display name for a transformation of a virtualization configuration. * @param diskImage disk image file for a transformation of a virtualization configuration. diff --git a/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModServerToStatelessClient.java b/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModServerToStatelessClient.java index e92df92..65cc7ce 100644 --- a/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModServerToStatelessClient.java +++ b/src/main/java/org/openslx/virtualization/configuration/data/ConfigurationDataDozModServerToStatelessClient.java @@ -2,7 +2,8 @@ package org.openslx.virtualization.configuration.data; /** * Data container to collect and store input arguments for a - * {@link ConfigurationLogicDozModServerToStatelessClient} transformation. + * {@link org.openslx.virtualization.configuration.logic.ConfigurationLogicDozModServerToStatelessClient} + * transformation. * * @author Manuel Bentele * @version 1.0 @@ -27,7 +28,8 @@ public class ConfigurationDataDozModServerToStatelessClient /** * Creates a new data container to collect and store input arguments for a - * {@link ConfigurationLogicDozModServerToStatelessClient} transformation. + * {@link org.openslx.virtualization.configuration.logic.ConfigurationLogicDozModServerToStatelessClient} + * transformation. * * @param displayName display name for a transformation of a virtualization configuration. * @param osId operating system identifier for a transformation of a virtualization diff --git a/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModClientToDozModServer.java b/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModClientToDozModServer.java index d64f42a..f375693 100644 --- a/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModClientToDozModServer.java +++ b/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModClientToDozModServer.java @@ -14,7 +14,7 @@ import org.openslx.virtualization.configuration.transformation.TransformationExc * *
  *   +------------------------------+  DozModClientToDozModServer   +------------------------------+
- *   | virtualization configuration | ----------------------------> | virtualization configuration |
+ *   | virtualization configuration | ----------------------------▶ | virtualization configuration |
  *   +---------------+--------------+     transformation logic      +---------------+--------------+
  *   | dozmod-client |                                              | dozmod-server |
  *   +---------------+                                              +---------------+
diff --git a/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModServerToDozModClient.java b/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModServerToDozModClient.java
index 05b3d4a..06c8ad1 100644
--- a/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModServerToDozModClient.java
+++ b/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModServerToDozModClient.java
@@ -18,7 +18,7 @@ import org.openslx.virtualization.configuration.transformation.TransformationExc
  * 
  * 
  *   +------------------------------+  DozModServerToDozModClient   +------------------------------+
- *   | virtualization configuration | ----------------------------> | virtualization configuration |
+ *   | virtualization configuration | ----------------------------▶ | virtualization configuration |
  *   +---------------+--------------+     transformation logic      +---------------+--------------+
  *   | dozmod-server |                                              | dozmod-client |
  *   +---------------+                                              +---------------+
diff --git a/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModServerToStatelessClient.java b/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModServerToStatelessClient.java
index 580b0fc..30d690a 100644
--- a/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModServerToStatelessClient.java
+++ b/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModServerToStatelessClient.java
@@ -16,7 +16,7 @@ import org.openslx.virtualization.configuration.transformation.TransformationExc
  * 
  * 
  *   +------------------------------+  DozModServerToStatelessClient   +------------------------------+
- *   | virtualization configuration | -------------------------------> | virtualization configuration |
+ *   | virtualization configuration | -------------------------------▶ | virtualization configuration |
  *   +---------------+--------------+      transformation logic        +------------------+-----------+
  *   | dozmod-server |                                                 | stateless client |
  *   +---------------+                                                 +------------------+
diff --git a/src/main/java/org/openslx/virtualization/configuration/transformation/TransformationSpecific.java b/src/main/java/org/openslx/virtualization/configuration/transformation/TransformationSpecific.java
index 5b13f45..7038abf 100644
--- a/src/main/java/org/openslx/virtualization/configuration/transformation/TransformationSpecific.java
+++ b/src/main/java/org/openslx/virtualization/configuration/transformation/TransformationSpecific.java
@@ -23,6 +23,7 @@ public abstract class TransformationSpecific extends Transformationtrue if image type is supported by the virtualizer; otherwise
 		 *         false.
 		 */
diff --git a/src/main/java/org/openslx/vm/disk/DiskImageQcow2.java b/src/main/java/org/openslx/vm/disk/DiskImageQcow2.java
index 04e61ea..657c144 100644
--- a/src/main/java/org/openslx/vm/disk/DiskImageQcow2.java
+++ b/src/main/java/org/openslx/vm/disk/DiskImageQcow2.java
@@ -51,7 +51,7 @@ public class DiskImageQcow2 extends DiskImage
 	/**
 	 * Creates a new QCOW2 disk image from an existing QCOW2 image file.
 	 * 
-	 * @param diskImage file to a QCOW2 disk storing the image content.
+	 * @param disk file to a QCOW2 disk storing the image content.
 	 * 
 	 * @throws FileNotFoundException cannot find specified QCOW2 disk image file.
 	 * @throws IOException cannot access the content of the QCOW2 disk image file.
@@ -64,7 +64,7 @@ public class DiskImageQcow2 extends DiskImage
 	/**
 	 * Creates a new QCOW2 disk image from an existing QCOW2 image file.
 	 * 
-	 * @param diskImage file to a QCOW2 disk storing the image content.
+	 * @param disk file to a QCOW2 disk storing the image content.
 	 */
 	public DiskImageQcow2( RandomAccessFile disk )
 	{
diff --git a/src/main/java/org/openslx/vm/disk/DiskImageUtils.java b/src/main/java/org/openslx/vm/disk/DiskImageUtils.java
index cc29721..ccb053f 100644
--- a/src/main/java/org/openslx/vm/disk/DiskImageUtils.java
+++ b/src/main/java/org/openslx/vm/disk/DiskImageUtils.java
@@ -114,12 +114,12 @@ public class DiskImageUtils
 	}
 
 	/**
-	 * Reads two bytes ({@link Short}) at a given offset from the specified disk image
-	 * file.
+	 * Reads a variable number of bytes (numBytes) at a given offset from the specified disk image file.
 	 * 
 	 * @param diskImage file to a disk storing the image content.
-	 * @param offset offset in bytes for reading the two bytes.
-	 * @return value of the two bytes from the disk image file as {@link Short}.
+	 * @param offset offset in bytes for reading numBytes bytes.
+	 * @param numBytes number of bytes to read at offset.
+	 * @return read bytes from the disk image file as {@link String}.
 	 * 
 	 * @throws DiskImageException unable to read two bytes from the disk image file.
 	 */
diff --git a/src/main/java/org/openslx/vm/disk/DiskImageVmdk.java b/src/main/java/org/openslx/vm/disk/DiskImageVmdk.java
index 7f59bc3..b2f45a1 100644
--- a/src/main/java/org/openslx/vm/disk/DiskImageVmdk.java
+++ b/src/main/java/org/openslx/vm/disk/DiskImageVmdk.java
@@ -183,7 +183,8 @@ public class DiskImageVmdk extends DiskImage
 	 * 
 	 * @return hardware version from the VMDK's embedded descriptor file.
 	 * 
-	 * @throws DiskImageException
+	 * @throws DiskImageException unable to obtain the VMDK's hardware version of the disk image
+	 *            format.
 	 */
 	public Version getHwVersion() throws DiskImageException
 	{
-- 
cgit v1.2.3-55-g7522


From 07e2d0fdde3c85ea6d126e8986694a091f1803ff Mon Sep 17 00:00:00 2001
From: Manuel Bentele
Date: Wed, 5 May 2021 09:37:45 +0200
Subject: Add OS detection for Libvirt/QEMU virtualization configurations

---
 pom.xml                                            |   2 +
 .../java/org/openslx/libvirt/domain/Domain.java    |  11 ++
 .../org/openslx/libvirt/libosinfo/LibOsInfo.java   | 158 ++++++++++++++++++++
 .../java/org/openslx/libvirt/libosinfo/os/Os.java  |  93 ++++++++++++
 .../openslx/libvirt/xml/LibvirtXmlResources.java   |  59 +++++++-
 .../java/org/openslx/util/LevenshteinDistance.java |  85 +++++++++++
 .../java/org/openslx/virtualization/Version.java   |  64 ++++++++
 .../configuration/VirtualizationConfiguration.java |  51 +++----
 .../VirtualizationConfigurationQemu.java           |  47 +++++-
 .../VirtualizationConfigurationUtils.java          |  52 +++++++
 .../VirtualizationConfigurationVirtualBox.java     |  98 +++++++-----
 .../VirtualizationConfigurationVmware.java         |  35 +++--
 .../org/openslx/libvirt/domain/DomainTest.java     |   8 +
 .../openslx/libvirt/libosinfo/LibOsInfoTest.java   |  28 ++++
 .../org/openslx/virtualization/VersionTest.java    |  17 +++
 .../VirtualizationConfigurationQemuTest.java       |  40 +++++
 .../logic/ConfigurationLogicTestUtils.java         |   2 +-
 .../xml/qemu-kvm_default-ubuntu-20-04-vm_i686.xml  | 164 +++++++++++++++++++++
 18 files changed, 929 insertions(+), 85 deletions(-)
 create mode 100644 src/main/java/org/openslx/libvirt/libosinfo/LibOsInfo.java
 create mode 100644 src/main/java/org/openslx/libvirt/libosinfo/os/Os.java
 create mode 100644 src/main/java/org/openslx/util/LevenshteinDistance.java
 create mode 100644 src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationUtils.java
 create mode 100644 src/test/java/org/openslx/libvirt/libosinfo/LibOsInfoTest.java
 create mode 100644 src/test/resources/libvirt/xml/qemu-kvm_default-ubuntu-20-04-vm_i686.xml

(limited to 'src/main/java/org/openslx/libvirt/xml')

diff --git a/pom.xml b/pom.xml
index b48bb26..ff2d062 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,6 +87,8 @@
 			
 				${basedir}/src/main/resources
 				
+					libvirt/libosinfo/rng/*
+					libvirt/libosinfo/xml/*
 					libvirt/rng/*
 					libvirt/xsl/*
 				
diff --git a/src/main/java/org/openslx/libvirt/domain/Domain.java b/src/main/java/org/openslx/libvirt/domain/Domain.java
index c8f5303..50d0811 100644
--- a/src/main/java/org/openslx/libvirt/domain/Domain.java
+++ b/src/main/java/org/openslx/libvirt/domain/Domain.java
@@ -260,6 +260,17 @@ public class Domain extends LibvirtXmlDocument
 		this.getRootXmlNode().setXmlElementValue( "description", description );
 	}
 
+	/**
+	 * Returns the libosinfo operating system identifier.
+	 * 
+	 * @return libosinfo operating system identifier.
+	 */
+	public String getLibOsInfoOsId()
+	{
+		return this.getRootXmlNode()
+				.getXmlElementAttributeValue( "metadata/*[local-name()='libosinfo']/*[local-name()='os']", "id" );
+	}
+
 	/**
 	 * Returns virtual machine UUID defined in the Libvirt domain XML document.
 	 * 
diff --git a/src/main/java/org/openslx/libvirt/libosinfo/LibOsInfo.java b/src/main/java/org/openslx/libvirt/libosinfo/LibOsInfo.java
new file mode 100644
index 0000000..f506d74
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/libosinfo/LibOsInfo.java
@@ -0,0 +1,158 @@
+package org.openslx.libvirt.libosinfo;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.function.Predicate;
+
+import org.openslx.libvirt.libosinfo.os.Os;
+import org.openslx.libvirt.xml.LibvirtXmlDocument;
+import org.openslx.libvirt.xml.LibvirtXmlDocumentException;
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+import org.openslx.libvirt.xml.LibvirtXmlResources;
+import org.openslx.libvirt.xml.LibvirtXmlSerializationException;
+import org.openslx.libvirt.xml.LibvirtXmlValidationException;
+import org.openslx.virtualization.Version;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+/**
+ * Implementation of a libosinfo XML document.
+ * 
+ * The libosinfo XML document is used to describe existing operating systems, devices and their
+ * configuration possibilities.
+ * 
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class LibOsInfo extends LibvirtXmlDocument
+{
+	/**
+	 * Creates a libosinfo XML document from a {@link String} providing libosinfo XML content.
+	 * 
+	 * @param xml {@link String} with libosinfo XML content.
+	 * 
+	 * @throws LibvirtXmlDocumentException creation of XML context failed.
+	 * @throws LibvirtXmlSerializationException serialization of the libosinfo XML content failed.
+	 * @throws LibvirtXmlValidationException XML content is not a valid libosinfo XML document.
+	 */
+	public LibOsInfo( String xml )
+			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+	{
+		super( xml, LibvirtXmlResources.getLibOsInfoRng( "osinfo.rng" ) );
+	}
+
+	/**
+	 * Creates a libosinfo XML document from a {@link File} containing libosinfo XML content.
+	 * 
+	 * @param xml existing {@link File} containing libosinfo XML content.
+	 * 
+	 * @throws LibvirtXmlDocumentException creation of XML context failed.
+	 * @throws LibvirtXmlSerializationException serialization of the libosinfo XML content failed.
+	 * @throws LibvirtXmlValidationException XML content is not a valid libosinfo XML document.
+	 */
+	public LibOsInfo( File xml )
+			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+	{
+		super( xml, LibvirtXmlResources.getLibOsInfoRng( "osinfo.rng" ) );
+	}
+
+	/**
+	 * Creates a libosinfo XML document from an {@link InputStream} providing libosinfo XML content.
+	 * 
+	 * @param xml {@link InputStream} providing libosinfo XML content.
+	 * 
+	 * @throws LibvirtXmlDocumentException creation of XML context failed.
+	 * @throws LibvirtXmlSerializationException serialization of the libosinfo XML content failed.
+	 * @throws LibvirtXmlValidationException XML content is not a valid libosinfo XML document.
+	 */
+	public LibOsInfo( InputStream xml )
+			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+	{
+		super( xml, LibvirtXmlResources.getLibOsInfoRng( "osinfo.rng" ) );
+	}
+
+	/**
+	 * Creates libosinfo XML document from {@link InputSource} providing libosinfo XML content.
+	 * 
+	 * @param xml {@link InputSource} providing libosinfo XML content.
+	 * 
+	 * @throws LibvirtXmlDocumentException creation of XML context failed.
+	 * @throws LibvirtXmlSerializationException serialization of the libosinfo XML content failed.
+	 * @throws LibvirtXmlValidationException XML content is not a valid libosinfo XML document.
+	 */
+	public LibOsInfo( InputSource xml )
+			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+	{
+		super( xml, LibvirtXmlResources.getLibOsInfoRng( "osinfo.rng" ) );
+	}
+
+	/**
+	 * Returns the version of the libosinfo database.
+	 * 
+	 * @return version of the libosinfo database.
+	 */
+	public Version getVersion()
+	{
+		final String version = this.getRootXmlNode().getXmlElementAttributeValue( "version" );
+		return Version.valueOf( version );
+	}
+
+	/**
+	 * Returns a list of all defined operating systems.
+	 * 
+	 * @return list of all defined operating systems.
+	 */
+	public ArrayList getOses()
+	{
+		final ArrayList oses = new ArrayList();
+		final NodeList osNodes = this.getRootXmlNode().getXmlNodes( "os" );
+
+		if ( osNodes != null ) {
+			for ( int i = 0; i < osNodes.getLength(); i++ ) {
+				final Node childNode = osNodes.item( i );
+				if ( childNode.getNodeType() == Node.ELEMENT_NODE ) {
+					final LibvirtXmlNode osNode = new LibvirtXmlNode( this.getRootXmlNode().getXmlDocument(), childNode );
+					final Os os = Os.newInstance( osNode );
+
+					if ( os != null ) {
+						oses.add( os );
+					}
+				}
+			}
+		}
+
+		return oses;
+	}
+
+	/**
+	 * Lookups an operating system in the libosinfo database specified by the operating system
+	 * identifier.
+	 * 
+	 * @param osId identifier of the operating system to lookup in the libosinfo database.
+	 * @return found operating system from the libosinfo database.
+	 */
+	public static Os lookupOs( String osId )
+	{
+		Os os = null;
+
+		if ( osId != null && !osId.isEmpty() ) {
+			ArrayList oses = null;
+
+			try {
+				final LibOsInfo osInfo = new LibOsInfo( LibvirtXmlResources.getLibOsInfoXml( "osinfo.xml" ) );
+				oses = osInfo.getOses();
+			} catch ( LibvirtXmlDocumentException | LibvirtXmlSerializationException | LibvirtXmlValidationException e ) {
+				oses = null;
+			}
+
+			if ( oses != null ) {
+				final Predicate byOsId = osCandidate -> osId.equals( osCandidate.getId() );
+				os = oses.stream().filter( byOsId ).findFirst().orElse( null );
+			}
+		}
+
+		return os;
+	}
+}
diff --git a/src/main/java/org/openslx/libvirt/libosinfo/os/Os.java b/src/main/java/org/openslx/libvirt/libosinfo/os/Os.java
new file mode 100644
index 0000000..37a0a2e
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/libosinfo/os/Os.java
@@ -0,0 +1,93 @@
+package org.openslx.libvirt.libosinfo.os;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+import org.openslx.virtualization.Version;
+
+/**
+ * A operating system node in a libosinfo XML document.
+ * 
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Os extends LibvirtXmlNode
+{
+	/**
+	 * Creates an empty operating system.
+	 */
+	public Os()
+	{
+		super();
+	}
+
+	/**
+	 * Creates a operating system representing an existing libosinfo XML operating system element.
+	 * 
+	 * @param xmlNode existing libosinfo XML operating system element.
+	 */
+	public Os( LibvirtXmlNode xmlNode )
+	{
+		super( xmlNode );
+	}
+
+	/**
+	 * Returns the identifier of the operating system.
+	 * 
+	 * @return identifier of the operating system.
+	 */
+	public String getId()
+	{
+		return this.getXmlElementAttributeValue( "id" );
+	}
+
+	/**
+	 * Returns the name of the operating system.
+	 * 
+	 * @return name of the operating system.
+	 */
+	public String getName()
+	{
+		return this.getXmlElementValue( "name" );
+	}
+
+	/**
+	 * Returns the version of the operating system.
+	 * 
+	 * @return version of the operating system.
+	 */
+	public Version getVersion()
+	{
+		final String version = this.getXmlElementValue( "version" );
+		return Version.valueOf( version );
+	}
+
+	/**
+	 * Returns the system family of the operating system.
+	 * 
+	 * @return system family of the operating system.
+	 */
+	public String getFamily()
+	{
+		return this.getXmlElementValue( "family" );
+	}
+
+	/**
+	 * Returns the distribution name of the operating system.
+	 * 
+	 * @return distribution name of the operating system.
+	 */
+	public String getDistro()
+	{
+		return this.getXmlElementValue( "distro" );
+	}
+
+	/**
+	 * Creates a operating system representing an existing libosinfo XML operating system element.
+	 * 
+	 * @param xmlNode existing libosinfo XML operating system element.
+	 * @return libosinfo XML operating system instance.
+	 */
+	public static Os newInstance( LibvirtXmlNode node )
+	{
+		return new Os( node );
+	}
+}
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlResources.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlResources.java
index 38c818b..a6b3e39 100644
--- a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlResources.java
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlResources.java
@@ -16,6 +16,11 @@ public final class LibvirtXmlResources
 	 */
 	private static final String LIBVIRT_PREFIX_PATH = File.separator + "libvirt";
 
+	/**
+	 * File path prefix of the absolute path to the libosinfo resource folder in a *.jar file.
+	 */
+	private static final String LIBOSINFO_PREFIX_PATH = File.separator + "libvirt" + File.separator + "libosinfo";
+
 	/**
 	 * File path prefix of the absolute path to the libvirt XSL resource folder in a *.jar file.
 	 */
@@ -26,6 +31,29 @@ public final class LibvirtXmlResources
 	 */
 	private static final String LIBVIRT_PREFIX_PATH_RNG = LIBVIRT_PREFIX_PATH + File.separator + "rng";
 
+	/**
+	 * File path prefix of the absolute path to the libosinfo RNG resource folder in a *.jar file.
+	 */
+	private static final String LIBOSINFO_PREFIX_PATH_RNG = LIBOSINFO_PREFIX_PATH + File.separator + "rng";
+	
+	/**
+	 * File path prefix of the absolute path to the libosinfo XML resource folder in a *.jar file.
+	 */
+	private static final String LIBOSINFO_PREFIX_PATH_XML = LIBOSINFO_PREFIX_PATH + File.separator + "xml";
+
+	/**
+	 * Returns a Libvirt resource as stream.
+	 * 
+	 * @param prefix file path of the Libvirt resource in the resources *.jar folder.
+	 * @param fileName file name of the Libvirt resource in the resources *.jar folder.
+	 * @return Libvirt resource as stream.
+	 */
+	private static InputStream getLibvirtResource( String prefix, String fileName )
+	{
+		final String path = prefix + File.separator + fileName;
+		return LibvirtXmlResources.class.getResourceAsStream( path );
+	}
+
 	/**
 	 * Returns a Libvirt XSL resource as stream.
 	 * 
@@ -34,8 +62,7 @@ public final class LibvirtXmlResources
 	 */
 	public static InputStream getLibvirtXsl( String libvirtXslFileName )
 	{
-		String libvirtXslPath = LibvirtXmlResources.LIBVIRT_PREFIX_PATH_XSL + File.separator + libvirtXslFileName;
-		return LibvirtXmlResources.class.getResourceAsStream( libvirtXslPath );
+		return LibvirtXmlResources.getLibvirtResource( LibvirtXmlResources.LIBVIRT_PREFIX_PATH_XSL, libvirtXslFileName );
 	}
 
 	/**
@@ -46,7 +73,31 @@ public final class LibvirtXmlResources
 	 */
 	public static InputStream getLibvirtRng( String libvirtRngFileName )
 	{
-		String libvirtRngPath = LibvirtXmlResources.LIBVIRT_PREFIX_PATH_RNG + File.separator + libvirtRngFileName;
-		return LibvirtXmlResources.class.getResourceAsStream( libvirtRngPath );
+		return LibvirtXmlResources.getLibvirtResource( LibvirtXmlResources.LIBVIRT_PREFIX_PATH_RNG, libvirtRngFileName );
+	}
+
+	/**
+	 * Returns a libosinfo RNG schema resource as stream.
+	 * 
+	 * @param libosInfoRngFileName file name of the RNG schema resource in the resources *.jar
+	 *           folder.
+	 * @return libosinfo RNG schema resource as stream.
+	 */
+	public static InputStream getLibOsInfoRng( String libosInfoRngFileName )
+	{
+		return LibvirtXmlResources.getLibvirtResource( LibvirtXmlResources.LIBOSINFO_PREFIX_PATH_RNG,
+				libosInfoRngFileName );
+	}
+
+	/**
+	 * Returns a libosinfo XML resource as stream.
+	 * 
+	 * @param libosInfoXmlFileName file name of the XML resource in the resources *.jar folder.
+	 * @return libosinfo XML resource as stream.
+	 */
+	public static InputStream getLibOsInfoXml( String libosInfoXmlFileName )
+	{
+		return LibvirtXmlResources.getLibvirtResource( LibvirtXmlResources.LIBOSINFO_PREFIX_PATH_XML,
+				libosInfoXmlFileName );
 	}
 }
diff --git a/src/main/java/org/openslx/util/LevenshteinDistance.java b/src/main/java/org/openslx/util/LevenshteinDistance.java
new file mode 100644
index 0000000..0f33167
--- /dev/null
+++ b/src/main/java/org/openslx/util/LevenshteinDistance.java
@@ -0,0 +1,85 @@
+package org.openslx.util;
+
+public final class LevenshteinDistance
+{
+	private final int insertionCost;
+	private final int deletionCost;
+	private final int substitutionCost;
+
+	public LevenshteinDistance()
+	{
+		this( 1, 1, 1 );
+	}
+
+	public LevenshteinDistance( int insertionCost, int deletionCost, int substitutionCost )
+	{
+		this.validateCostArgument( insertionCost >= 0, "Insertion cost must be greater than or equal to 0" );
+		this.validateCostArgument( deletionCost >= 0, "Deletion cost must be greater than or equal to 0" );
+		this.validateCostArgument( substitutionCost >= 0, "Substitution cost must be greater than or equal to 0" );
+
+		this.insertionCost = insertionCost;
+		this.deletionCost = deletionCost;
+		this.substitutionCost = substitutionCost;
+	}
+
+	private void validateCostArgument( boolean condition, String errorMsg )
+	{
+		if ( !condition ) {
+			throw new IllegalArgumentException( errorMsg );
+		}
+	}
+
+	public int calculateDistance( CharSequence source, CharSequence target )
+	{
+		if ( source == null || target == null ) {
+			throw new IllegalArgumentException( "Source or target cannot be null" );
+		}
+
+		int sourceLength = source.length();
+		int targetLength = target.length();
+
+		int[][] matrix = new int[ sourceLength + 1 ][ targetLength + 1 ];
+		matrix[0][0] = 0;
+
+		for ( int row = 1; row <= sourceLength; ++row ) {
+			matrix[row][0] = row;
+		}
+
+		for ( int col = 1; col <= targetLength; ++col ) {
+			matrix[0][col] = col;
+		}
+
+		for ( int row = 1; row <= sourceLength; ++row ) {
+			for ( int col = 1; col <= targetLength; ++col ) {
+				matrix[row][col] = calcMinCost( source, target, matrix, row, col );
+			}
+		}
+
+		return matrix[sourceLength][targetLength];
+	}
+
+	private int calcMinCost( CharSequence source, CharSequence target, int[][] matrix, int row, int col )
+	{
+		return Math.min( calcSubstitutionCost( source, target, matrix, row, col ),
+				Math.min( calcDeletionCost( matrix, row, col ), calcInsertionCost( matrix, row, col ) ) );
+	}
+
+	private int calcInsertionCost( int[][] matrix, int row, int col )
+	{
+		return matrix[row][col - 1] + insertionCost;
+	}
+
+	private int calcDeletionCost( int[][] matrix, int row, int col )
+	{
+		return matrix[row - 1][col] + deletionCost;
+	}
+
+	private int calcSubstitutionCost( CharSequence source, CharSequence target, int[][] matrix, int row, int col )
+	{
+		int cost = 0;
+		if ( source.charAt( row - 1 ) != target.charAt( col - 1 ) ) {
+			cost = substitutionCost;
+		}
+		return matrix[row - 1][col - 1] + cost;
+	}
+}
diff --git a/src/main/java/org/openslx/virtualization/Version.java b/src/main/java/org/openslx/virtualization/Version.java
index 5d99ac1..698e22e 100644
--- a/src/main/java/org/openslx/virtualization/Version.java
+++ b/src/main/java/org/openslx/virtualization/Version.java
@@ -2,6 +2,8 @@ package org.openslx.virtualization;
 
 import java.util.List;
 import java.util.function.Predicate;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Represents a version information.
@@ -14,8 +16,33 @@ import java.util.function.Predicate;
  */
 public class Version implements Comparable
 {
+	/**
+	 * Regular expression to parse a version from a {@link String}.
+	 * 

+ * The regular expression matches a version if its textual version information is well-formed + * according to the following examples: + * + *

+	 *   52
+	 *   4.31
+	 *   5.10.13
+	 * 
+ */ + private static final String VERSION_NUMBER_REGEX = "^(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?$"; + + /** + * Major number of the version. + */ private final short major; + + /** + * Minor number of the version. + */ private final short minor; + + /** + * Name or description of the version. + */ private final String name; /** @@ -173,6 +200,43 @@ public class Version implements Comparable return supportedVersions.stream().filter( byMajorMinor ).findFirst().orElse( null ); } + /** + * Creates a new version parsed from a {@link String}. + * + * The version consists of a major and a minor version parsed from the specified {@link String}. + * + * @param version textual information containing a version as {@link String}. The textual + * version should be well-formed according to the defined regular expression + * {@link #VERSION_NUMBER_REGEX}. + * @return version instance. + */ + public static Version valueOf( String version ) + { + final Version parsedVersion; + + if ( version == null || version.isEmpty() ) { + parsedVersion = null; + } else { + final Pattern versionPattern = Pattern.compile( Version.VERSION_NUMBER_REGEX ); + final Matcher versionMatcher = versionPattern.matcher( version ); + + if ( versionMatcher.find() ) { + final String majorStr = versionMatcher.group( 1 ); + final String minorStr = versionMatcher.group( 2 ); + + final short major = ( majorStr != null ) ? Short.valueOf( majorStr ) : 0; + final short minor = ( minorStr != null ) ? Short.valueOf( minorStr ) : 0; + + parsedVersion = new Version( major, minor ); + + } else { + parsedVersion = null; + } + } + + return parsedVersion; + } + @Override public boolean equals( Object obj ) { diff --git a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfiguration.java b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfiguration.java index 0ecd693..cd8af1e 100644 --- a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfiguration.java +++ b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfiguration.java @@ -8,7 +8,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import org.apache.log4j.Logger; import org.openslx.bwlp.thrift.iface.OperatingSystem; @@ -125,7 +124,7 @@ public abstract class VirtualizationConfiguration protected final List hdds = new ArrayList(); - private final List osList; + protected final List osList; private OperatingSystem os = null; @@ -180,6 +179,16 @@ public abstract class VirtualizationConfiguration { return os; } + + /** + * Sets the operating system for the virtualization configuration. + * + * @param os operating system for the virtualization configuration. + */ + public void setOs( OperatingSystem os ) + { + this.os = os; + } /** * Get all hard disks of this VM. @@ -216,42 +225,18 @@ public abstract class VirtualizationConfiguration public VirtualizationConfiguration( Virtualizer virtualizer, List osList ) { this.virtualizer = virtualizer; - this.osList = osList; + + if ( osList == null ) { + // create empty operating system list if none is specified + this.osList = new ArrayList(); + } else { + this.osList = osList; + } // register virtual hardware models for graphical editing of virtual devices (GPU, sound, USB, ...) this.registerVirtualHW(); } - /** - * Called from subclass to set the OS. If the OS cannot be determined from the - * given parameters, it will not be set. - * - * @param virtId - * virtualizer, eg "vmware" for VMware - * @param virtOsId - * the os identifier used by the virtualizer, eg. windows7-64 for - * 64bit Windows 7 on VMware - */ - protected final void setOs( String virtId, String virtOsId ) - { - OperatingSystem lazyMatch = null; - for ( OperatingSystem os : osList ) { - if ( os.getVirtualizerOsId() == null ) - continue; - for ( Entry entry : os.getVirtualizerOsId().entrySet() ) { - if ( !entry.getValue().equals( virtOsId ) ) - continue; - if ( entry.getKey().equals( virtId ) ) { - this.os = os; - return; - } else { - lazyMatch = os; - } - } - } - this.os = lazyMatch; - } - /** * Returns a VmMetaData instance of the given machine description given as file * diff --git a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemu.java b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemu.java index 710a42d..e844e4e 100644 --- a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemu.java +++ b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemu.java @@ -13,6 +13,8 @@ import org.openslx.libvirt.domain.DomainUtils; import org.openslx.libvirt.domain.device.ControllerUsb; import org.openslx.libvirt.domain.device.Disk.BusType; import org.openslx.libvirt.domain.device.Disk.StorageType; +import org.openslx.libvirt.libosinfo.LibOsInfo; +import org.openslx.libvirt.libosinfo.os.Os; import org.openslx.libvirt.domain.device.DiskCdrom; import org.openslx.libvirt.domain.device.DiskFloppy; import org.openslx.libvirt.domain.device.DiskStorage; @@ -24,6 +26,7 @@ import org.openslx.libvirt.domain.device.Video; import org.openslx.libvirt.xml.LibvirtXmlDocumentException; import org.openslx.libvirt.xml.LibvirtXmlSerializationException; import org.openslx.libvirt.xml.LibvirtXmlValidationException; +import org.openslx.util.LevenshteinDistance; import org.openslx.virtualization.Version; import org.openslx.virtualization.virtualizer.VirtualizerQemu; @@ -284,6 +287,9 @@ public class VirtualizationConfigurationQemu extends for ( DiskStorage storageDiskDevice : this.vmConfig.getDiskStorageDevices() ) { this.addHddMetaData( storageDiskDevice ); } + + // detect the operating system from the optional embedded libosinfo metadata + this.setOs( this.vmConfig.getLibOsInfoOsId() ); } /** @@ -302,6 +308,44 @@ public class VirtualizationConfigurationQemu extends this.hdds.add( new HardDisk( hddChipsetModel, hddChipsetBus, hddImagePath ) ); } + /** + * Detects the operating system by the specified libosinfo operating system identifier. + * + * @param osId libosinfo operating system identifier. + */ + private OperatingSystem detectOperatingSystem( String osId ) + { + OperatingSystem os = null; + + if ( osId != null && !osId.isEmpty() ) { + // lookup operating system identifier in the libosinfo database + final Os osLookup = LibOsInfo.lookupOs( osId ); + + // check if entry in the database was found + if ( osLookup != null ) { + // operating system entry was found + // so determine OpenSLX OS name with the smallest distance to the libosinfo OS name + final LevenshteinDistance distance = new LevenshteinDistance( 1, 1, 1 ); + int smallestDistance = Integer.MAX_VALUE; + + // get name of the OS and combine it with the optional available architecture + final String osLookupOsName = osLookup.getName() + " " + this.vmConfig.getOsArch(); + + for ( final OperatingSystem osCandidate : this.osList ) { + final int currentDistance = distance.calculateDistance( osLookupOsName, osCandidate.getOsName() ); + + if ( currentDistance < smallestDistance ) { + // if the distance is smaller save the current distance and operating system as best candidate + smallestDistance = currentDistance; + os = osCandidate; + } + } + } + } + + return os; + } + @Override public void transformEditable() throws VirtualizationConfigurationException { @@ -384,7 +428,8 @@ public class VirtualizationConfigurationQemu extends @Override public void setOs( String vendorOsId ) { - this.setOs( vendorOsId ); + final OperatingSystem os = this.detectOperatingSystem( vendorOsId ); + this.setOs( os ); } @Override diff --git a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationUtils.java b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationUtils.java new file mode 100644 index 0000000..2427001 --- /dev/null +++ b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationUtils.java @@ -0,0 +1,52 @@ +package org.openslx.virtualization.configuration; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.openslx.bwlp.thrift.iface.OperatingSystem; + +/** + * Utilities to set up and edit virtualization configurations. + * + * @author Manuel Bentele + * @version 1.0 + */ +public final class VirtualizationConfigurationUtils +{ + /** + * Returns an operating system from a given list of operating systems determined by the + * virtualizer specific operating system parameters. + * + * @param osList list of available operating systems. + * @param virtId virtualizer identifier, e.g. vmware for VMware + * @param virtOsId operating system identifier used by the virtualizer, eg. + * windows7-64 for 64bit Windows 7 on VMware. + */ + public static OperatingSystem getOsOfVirtualizerFromList( List osList, String virtId, + String virtOsId ) + { + OperatingSystem os = null; + + for ( final OperatingSystem osCandidate : osList ) { + final Map osVirtualizerMapping = osCandidate.getVirtualizerOsId(); + if ( osVirtualizerMapping != null ) { + for ( final Entry entry : osVirtualizerMapping.entrySet() ) { + // check if suitable OS has been found + if ( entry.getKey().equals( virtId ) && entry.getValue().equals( virtOsId ) ) { + // save OS and exit inner loop since OS has been found + os = osCandidate; + break; + } + } + + // exit outer loop if OS has been found + if ( os != null ) { + break; + } + } + } + + return os; + } +} diff --git a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVirtualBox.java b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVirtualBox.java index c53a7e0..8225af1 100644 --- a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVirtualBox.java +++ b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVirtualBox.java @@ -59,6 +59,7 @@ class VBoxUsbSpeedMeta { public final String value; public final int speed; + public VBoxUsbSpeedMeta( String value, int speed ) { this.value = value; @@ -66,13 +67,14 @@ class VBoxUsbSpeedMeta } } -public class VirtualizationConfigurationVirtualBox extends VirtualizationConfiguration +public class VirtualizationConfigurationVirtualBox + extends VirtualizationConfiguration { /** * File name extension for VirtualBox virtualization configuration files.. */ public static final String FILE_NAME_EXTENSION = "vbox"; - + private static final Logger LOGGER = Logger.getLogger( VirtualizationConfigurationVirtualBox.class ); private final VirtualizationConfigurationVirtualboxFileFormat config; @@ -89,14 +91,16 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu } } - public VirtualizationConfigurationVirtualBox( List osList, File file ) throws IOException, VirtualizationConfigurationException + public VirtualizationConfigurationVirtualBox( List osList, File file ) + throws IOException, VirtualizationConfigurationException { super( new VirtualizerVirtualBox(), osList ); this.config = new VirtualizationConfigurationVirtualboxFileFormat( file ); init(); } - public VirtualizationConfigurationVirtualBox( List osList, byte[] vmContent, int length ) throws IOException, VirtualizationConfigurationException + public VirtualizationConfigurationVirtualBox( List osList, byte[] vmContent, int length ) + throws IOException, VirtualizationConfigurationException { super( new VirtualizerVirtualBox(), osList ); this.config = new VirtualizationConfigurationVirtualboxFileFormat( vmContent, length ); @@ -118,11 +122,11 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu { // TODO Auto-generated method stub } - + @Override public void transformPrivacy() throws VirtualizationConfigurationException { - + } @Override @@ -136,11 +140,12 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu { return this.addHddTemplate( "%VM_DISK_PATH%", "%VM_DISK_MODE%", "%VM_DISK_REDOLOGDIR%" ); } - + @Override public boolean addHddTemplate( String diskImage, String hddMode, String redoDir ) { - config.changeAttribute( "/VirtualBox/Machine/MediaRegistry/HardDisks/HardDisk[@location='" + PlaceHolder.HDDLOCATION.toString() + "']", "location", diskImage ); + config.changeAttribute( "/VirtualBox/Machine/MediaRegistry/HardDisks/HardDisk[@location='" + + PlaceHolder.HDDLOCATION.toString() + "']", "location", diskImage ); config.changeAttribute( "/VirtualBox/Machine", "snapshotFolder", redoDir ); return true; } @@ -156,7 +161,8 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu // patching the new uuid in the vbox config file here String vboxUUid = "{" + newhdduuid.toString() + "}"; config.changeAttribute( "/VirtualBox/Machine/MediaRegistry/HardDisks/HardDisk", "uuid", vboxUUid ); - config.changeAttribute( "/VirtualBox/Machine/StorageControllers/StorageController/AttachedDevice/Image", "uuid", vboxUUid ); + config.changeAttribute( "/VirtualBox/Machine/StorageControllers/StorageController/AttachedDevice/Image", "uuid", + vboxUUid ); // the order of the UUID is BIG_ENDIAN but we need to change the order of the first 8 Bytes // to be able to write them to the vdi file... the PROBLEM here is that the first 8 @@ -206,7 +212,10 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu public void setOs( String vendorOsId ) { config.changeAttribute( "/VirtualBox/Machine", "OSType", vendorOsId ); - setOs( TConst.VIRT_VIRTUALBOX, vendorOsId ); + + final OperatingSystem os = VirtualizationConfigurationUtils.getOsOfVirtualizerFromList( this.osList, + TConst.VIRT_VIRTUALBOX, vendorOsId ); + this.setOs( os ); } @Override @@ -225,7 +234,8 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu public void addFloppy( int index, String image, boolean readOnly ) { Element floppyController = null; - NodeList matches = (NodeList)config.findNodes( "/VirtualBox/Machine/StorageControllers/StorageController[@name='Floppy']" ); + NodeList matches = (NodeList)config + .findNodes( "/VirtualBox/Machine/StorageControllers/StorageController[@name='Floppy']" ); if ( matches == null || matches.getLength() == 0 ) { floppyController = (Element)config.addNewNode( "/VirtualBox/Machine/StorageControllers", "StorageController" ); if ( floppyController == null ) { @@ -265,20 +275,24 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu LOGGER.error( "Failed to add to floppy device." ); return; } - floppyImage.setAttribute( "uuid", VirtualizationConfigurationVirtualboxFileFormat.PlaceHolder.FLOPPYUUID.toString() ); + floppyImage.setAttribute( "uuid", + VirtualizationConfigurationVirtualboxFileFormat.PlaceHolder.FLOPPYUUID.toString() ); // register the image in the media registry Element floppyImages = (Element)config.addNewNode( "/VirtualBox/Machine/MediaRegistry", "FloppyImages" ); if ( floppyImages == null ) { LOGGER.error( "Failed to add to media registry." ); return; } - Element floppyImageReg = (Element)config.addNewNode( "/VirtualBox/Machine/MediaRegistry/FloppyImages", "Image" ); + Element floppyImageReg = (Element)config.addNewNode( "/VirtualBox/Machine/MediaRegistry/FloppyImages", + "Image" ); if ( floppyImageReg == null ) { LOGGER.error( "Failed to add to floppy images in the media registry." ); return; } - floppyImageReg.setAttribute( "uuid", VirtualizationConfigurationVirtualboxFileFormat.PlaceHolder.FLOPPYUUID.toString() ); - floppyImageReg.setAttribute( "location", VirtualizationConfigurationVirtualboxFileFormat.PlaceHolder.FLOPPYLOCATION.toString() ); + floppyImageReg.setAttribute( "uuid", + VirtualizationConfigurationVirtualboxFileFormat.PlaceHolder.FLOPPYUUID.toString() ); + floppyImageReg.setAttribute( "location", + VirtualizationConfigurationVirtualboxFileFormat.PlaceHolder.FLOPPYLOCATION.toString() ); } } @@ -299,7 +313,8 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu public void setSoundCard( org.openslx.virtualization.configuration.VirtualizationConfiguration.SoundCardType type ) { VBoxSoundCardMeta sound = soundCards.get( type ); - config.changeAttribute( "/VirtualBox/Machine/Hardware/AudioAdapter", "enabled", Boolean.toString( sound.isPresent ) ); + config.changeAttribute( "/VirtualBox/Machine/Hardware/AudioAdapter", "enabled", + Boolean.toString( sound.isPresent ) ); config.changeAttribute( "/VirtualBox/Machine/Hardware/AudioAdapter", "controller", sound.value ); } @@ -309,7 +324,8 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu // initialize here to type None to avoid all null pointer exceptions thrown for unknown user written sound cards VirtualizationConfiguration.SoundCardType returnsct = VirtualizationConfiguration.SoundCardType.NONE; Element x = (Element)config.findNodes( "/VirtualBox/Machine/Hardware/AudioAdapter" ).item( 0 ); - if ( !x.hasAttribute( "enabled" ) || ( x.hasAttribute( "enabled" ) && x.getAttribute( "enabled" ).equals( "false" ) ) ) { + if ( !x.hasAttribute( "enabled" ) + || ( x.hasAttribute( "enabled" ) && x.getAttribute( "enabled" ).equals( "false" ) ) ) { return returnsct; } else { // extra separate case for the non-existing argument} @@ -318,7 +334,8 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu } else { String controller = x.getAttribute( "controller" ); VBoxSoundCardMeta soundMeta = null; - for ( VirtualizationConfiguration.SoundCardType type : VirtualizationConfiguration.SoundCardType.values() ) { + for ( VirtualizationConfiguration.SoundCardType type : VirtualizationConfiguration.SoundCardType + .values() ) { soundMeta = soundCards.get( type ); if ( soundMeta != null ) { if ( controller.equals( soundMeta.value ) ) { @@ -335,7 +352,8 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu public void setDDAcceleration( VirtualizationConfiguration.DDAcceleration type ) { VBoxDDAccelMeta accel = ddacc.get( type ); - config.changeAttribute( "/VirtualBox/Machine/Hardware/Display", "accelerate3D", Boolean.toString( accel.isPresent ) ); + config.changeAttribute( "/VirtualBox/Machine/Hardware/Display", "accelerate3D", + Boolean.toString( accel.isPresent ) ); } @Override @@ -377,8 +395,10 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu String index = "0"; VBoxEthernetDevTypeMeta nic = networkCards.get( type ); // cardIndex is not used yet...maybe later needed for different network cards - config.changeAttribute( "/VirtualBox/Machine/Hardware/Network/Adapter[@slot='" + index + "']", "enabled", Boolean.toString( nic.isPresent ) ); - config.changeAttribute( "/VirtualBox/Machine/Hardware/Network/Adapter[@slot='" + index + "']", "type", nic.value ); + config.changeAttribute( "/VirtualBox/Machine/Hardware/Network/Adapter[@slot='" + index + "']", "enabled", + Boolean.toString( nic.isPresent ) ); + config.changeAttribute( "/VirtualBox/Machine/Hardware/Network/Adapter[@slot='" + index + "']", "type", + nic.value ); } @Override @@ -386,7 +406,8 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu { VirtualizationConfiguration.EthernetDevType returnedt = VirtualizationConfiguration.EthernetDevType.NONE; Element x = (Element)config.findNodes( "/VirtualBox/Machine/Hardware/Network/Adapter" ).item( 0 ); - if ( !x.hasAttribute( "enabled" ) || ( x.hasAttribute( "enabled" ) && x.getAttribute( "enabled" ).equals( "false" ) ) ) { + if ( !x.hasAttribute( "enabled" ) + || ( x.hasAttribute( "enabled" ) && x.getAttribute( "enabled" ).equals( "false" ) ) ) { return returnedt; } else { // extra separate case for the non-existing argument} @@ -395,7 +416,8 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu } else { String temp = x.getAttribute( "type" ); VBoxEthernetDevTypeMeta etherMeta = null; - for ( VirtualizationConfiguration.EthernetDevType type : VirtualizationConfiguration.EthernetDevType.values() ) { + for ( VirtualizationConfiguration.EthernetDevType type : VirtualizationConfiguration.EthernetDevType + .values() ) { etherMeta = networkCards.get( type ); if ( etherMeta != null ) { if ( temp.equals( etherMeta.value ) ) { @@ -421,14 +443,21 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu ddacc.put( VirtualizationConfiguration.DDAcceleration.ON, new VBoxDDAccelMeta( true ) ); // none type needs to have a valid value; it takes the value of pcnetcpi2; if value is left null or empty vm will not start because value is not valid - networkCards.put( VirtualizationConfiguration.EthernetDevType.NONE, new VBoxEthernetDevTypeMeta( false, "Am79C970A" ) ); - networkCards.put( VirtualizationConfiguration.EthernetDevType.PCNETPCI2, new VBoxEthernetDevTypeMeta( true, "Am79C970A" ) ); - networkCards.put( VirtualizationConfiguration.EthernetDevType.PCNETFAST3, new VBoxEthernetDevTypeMeta( true, "Am79C973" ) ); - networkCards.put( VirtualizationConfiguration.EthernetDevType.PRO1000MTD, new VBoxEthernetDevTypeMeta( true, "82540EM" ) ); - networkCards.put( VirtualizationConfiguration.EthernetDevType.PRO1000TS, new VBoxEthernetDevTypeMeta( true, "82543GC" ) ); - networkCards.put( VirtualizationConfiguration.EthernetDevType.PRO1000MTS, new VBoxEthernetDevTypeMeta( true, "82545EM" ) ); - networkCards.put( VirtualizationConfiguration.EthernetDevType.PARAVIRT, new VBoxEthernetDevTypeMeta( true, "virtio" ) ); - + networkCards.put( VirtualizationConfiguration.EthernetDevType.NONE, + new VBoxEthernetDevTypeMeta( false, "Am79C970A" ) ); + networkCards.put( VirtualizationConfiguration.EthernetDevType.PCNETPCI2, + new VBoxEthernetDevTypeMeta( true, "Am79C970A" ) ); + networkCards.put( VirtualizationConfiguration.EthernetDevType.PCNETFAST3, + new VBoxEthernetDevTypeMeta( true, "Am79C973" ) ); + networkCards.put( VirtualizationConfiguration.EthernetDevType.PRO1000MTD, + new VBoxEthernetDevTypeMeta( true, "82540EM" ) ); + networkCards.put( VirtualizationConfiguration.EthernetDevType.PRO1000TS, + new VBoxEthernetDevTypeMeta( true, "82543GC" ) ); + networkCards.put( VirtualizationConfiguration.EthernetDevType.PRO1000MTS, + new VBoxEthernetDevTypeMeta( true, "82545EM" ) ); + networkCards.put( VirtualizationConfiguration.EthernetDevType.PARAVIRT, + new VBoxEthernetDevTypeMeta( true, "virtio" ) ); + usbSpeeds.put( VirtualizationConfiguration.UsbSpeed.NONE, new VBoxUsbSpeedMeta( null, 0 ) ); usbSpeeds.put( VirtualizationConfiguration.UsbSpeed.USB1_1, new VBoxUsbSpeedMeta( "OHCI", 1 ) ); usbSpeeds.put( VirtualizationConfiguration.UsbSpeed.USB2_0, new VBoxUsbSpeedMeta( "EHCI", 2 ) ); @@ -438,7 +467,8 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu @Override public boolean addEthernet( VirtualizationConfiguration.EtherType type ) { - Node hostOnlyInterfaceNode = config.addNewNode( "/VirtualBox/Machine/Hardware/Network/Adapter[@slot='0']", "HostOnlyInterface" ); + Node hostOnlyInterfaceNode = config.addNewNode( "/VirtualBox/Machine/Hardware/Network/Adapter[@slot='0']", + "HostOnlyInterface" ); if ( hostOnlyInterfaceNode == null ) { LOGGER.error( "Failed to create node for HostOnlyInterface." ); return false; @@ -498,7 +528,7 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu LOGGER.info( "Not ATTRIBUTE type" ); continue; } - String type = ((Attr)nodes.item( i )).getValue(); + String type = ( (Attr)nodes.item( i ) ).getValue(); for ( Entry s : usbSpeeds.entrySet() ) { if ( s.getValue().speed > maxSpeed && type.equals( s.getValue().value ) ) { maxSpeed = s.getValue().speed; @@ -514,7 +544,7 @@ public class VirtualizationConfigurationVirtualBox extends VirtualizationConfigu { return VirtualizationConfigurationVirtualBox.FILE_NAME_EXTENSION; } - + @Override public void validate() throws VirtualizationConfigurationException { diff --git a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVmware.java b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVmware.java index 3e8d913..39aaae5 100644 --- a/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVmware.java +++ b/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVmware.java @@ -54,7 +54,7 @@ class VmwareUsbSpeed { public final String keyName; public final int speedNumeric; - + public VmwareUsbSpeed( int speed, String key ) { this.keyName = key == null ? null : ( key + ".present" ); @@ -62,16 +62,18 @@ class VmwareUsbSpeed } } -public class VirtualizationConfigurationVmware extends VirtualizationConfiguration +public class VirtualizationConfigurationVmware extends + VirtualizationConfiguration { /** * File name extension for VMware virtualization configuration files. */ public static final String FILE_NAME_EXTENSION = "vmx"; - + private static final Logger LOGGER = Logger.getLogger( VirtualizationConfigurationVmware.class ); - private static final Pattern hddKey = Pattern.compile( "^(ide\\d|scsi\\d|sata\\d|nvme\\d):?(\\d)?\\.(.*)", Pattern.CASE_INSENSITIVE ); + private static final Pattern hddKey = Pattern.compile( "^(ide\\d|scsi\\d|sata\\d|nvme\\d):?(\\d)?\\.(.*)", + Pattern.CASE_INSENSITIVE ); // Lowercase list of allowed settings for upload (as regex) private static final Pattern[] whitelist; @@ -80,9 +82,12 @@ public class VirtualizationConfigurationVmware extends VirtualizationConfigurati // Init static members static { - String[] list = { "^guestos", "^uuid\\.bios", "^config\\.version", "^ehci[.:]", "^mks\\.enable3d", "^virtualhw\\.", - "^sound[.:]", "\\.pcislotnumber$", "^pcibridge", "\\.virtualdev$", "^tools\\.syncTime$", "^time\\.synchronize", - "^bios\\.bootDelay", "^rtc\\.", "^xhci[.:]", "^usb_xhci[.:]", "\\.deviceType$", "\\.port$", "\\.parent$", "^usb[.:]", + String[] list = { "^guestos", "^uuid\\.bios", "^config\\.version", "^ehci[.:]", "^mks\\.enable3d", + "^virtualhw\\.", + "^sound[.:]", "\\.pcislotnumber$", "^pcibridge", "\\.virtualdev$", "^tools\\.syncTime$", + "^time\\.synchronize", + "^bios\\.bootDelay", "^rtc\\.", "^xhci[.:]", "^usb_xhci[.:]", "\\.deviceType$", "\\.port$", "\\.parent$", + "^usb[.:]", "^firmware", "^hpet", "^vm\\.genid" }; whitelist = new Pattern[ list.length ]; for ( int i = 0; i < list.length; ++i ) { @@ -104,14 +109,16 @@ public class VirtualizationConfigurationVmware extends VirtualizationConfigurati private final Map disks = new HashMap<>(); - public VirtualizationConfigurationVmware( List osList, File file ) throws IOException, VirtualizationConfigurationException + public VirtualizationConfigurationVmware( List osList, File file ) + throws IOException, VirtualizationConfigurationException { super( new VirtualizerVmware(), osList ); this.config = new VirtualizationConfigurationVmwareFileFormat( file ); init(); } - public VirtualizationConfigurationVmware( List osList, byte[] vmxContent, int length ) throws VirtualizationConfigurationException + public VirtualizationConfigurationVmware( List osList, byte[] vmxContent, int length ) + throws VirtualizationConfigurationException { super( new VirtualizerVmware(), osList ); this.config = new VirtualizationConfigurationVmwareFileFormat( vmxContent, length ); // still unfiltered @@ -237,7 +244,7 @@ public class VirtualizationConfigurationVmware extends VirtualizationConfigurati device.present = Boolean.parseBoolean( value ); } } - + @Override public boolean addEmptyHddTemplate() { @@ -419,7 +426,10 @@ public class VirtualizationConfigurationVmware extends VirtualizationConfigurati public void setOs( String vendorOsId ) { addFiltered( "guestOS", vendorOsId ); - setOs( TConst.VIRT_VMWARE, vendorOsId ); + + final OperatingSystem os = VirtualizationConfigurationUtils.getOsOfVirtualizerFromList( this.osList, + TConst.VIRT_VMWARE, vendorOsId ); + this.setOs( os ); } public byte[] getConfigurationAsByteArray() @@ -536,7 +546,8 @@ public class VirtualizationConfigurationVmware extends VirtualizationConfigurati String temp = config.get( "ethernet" + cardIndex + ".virtualDev" ); if ( temp != null ) { VmWareEthernetDevTypeMeta ethernetDevTypeMeta = null; - for ( VirtualizationConfiguration.EthernetDevType type : VirtualizationConfiguration.EthernetDevType.values() ) { + for ( VirtualizationConfiguration.EthernetDevType type : VirtualizationConfiguration.EthernetDevType + .values() ) { ethernetDevTypeMeta = networkCards.get( type ); if ( ethernetDevTypeMeta == null ) { continue; diff --git a/src/test/java/org/openslx/libvirt/domain/DomainTest.java b/src/test/java/org/openslx/libvirt/domain/DomainTest.java index aa556f9..e1fb73b 100644 --- a/src/test/java/org/openslx/libvirt/domain/DomainTest.java +++ b/src/test/java/org/openslx/libvirt/domain/DomainTest.java @@ -110,6 +110,14 @@ public class DomainTest assertEquals( "Ubuntu 18.04 server installation", vm.getDescription() ); } + @Test + @DisplayName( "Get VM libosinfo operating system identifier in libvirt XML file" ) + public void testGetLibOsInfoOsId() + { + Domain vm = this.newDomainInstance( "qemu-kvm_default-ubuntu-20-04-vm.xml" ); + assertEquals( "http://ubuntu.com/ubuntu/20.04", vm.getLibOsInfoOsId() ); + } + @Test @DisplayName( "Get VM UUID from libvirt XML file" ) public void testGetUuid() diff --git a/src/test/java/org/openslx/libvirt/libosinfo/LibOsInfoTest.java b/src/test/java/org/openslx/libvirt/libosinfo/LibOsInfoTest.java new file mode 100644 index 0000000..af1c611 --- /dev/null +++ b/src/test/java/org/openslx/libvirt/libosinfo/LibOsInfoTest.java @@ -0,0 +1,28 @@ +package org.openslx.libvirt.libosinfo; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.openslx.libvirt.libosinfo.os.Os; +import org.openslx.virtualization.Version; + +public class LibOsInfoTest +{ + @Test + @DisplayName( "Test the lookup of an operating system" ) + public void testOsLookup() + { + final String osId = "http://ubuntu.com/ubuntu/20.04"; + final Os os = LibOsInfo.lookupOs( osId ); + + assertNotNull( os ); + + assertEquals( osId, os.getId() ); + assertEquals( "Ubuntu 20.04", os.getName() ); + assertEquals( "linux", os.getFamily() ); + assertEquals( "ubuntu", os.getDistro() ); + assertEquals( new Version( Short.valueOf( "20" ), Short.valueOf( "04" ) ), os.getVersion() ); + } +} diff --git a/src/test/java/org/openslx/virtualization/VersionTest.java b/src/test/java/org/openslx/virtualization/VersionTest.java index c1ad21b..988437a 100644 --- a/src/test/java/org/openslx/virtualization/VersionTest.java +++ b/src/test/java/org/openslx/virtualization/VersionTest.java @@ -2,6 +2,7 @@ package org.openslx.virtualization; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; @@ -41,6 +42,22 @@ public class VersionTest assertFalse( version.isSupported( versions ) ); } + @Test + @DisplayName( "Test that new version from String is valid" ) + public void testVersionValueOfValid() + { + assertEquals( new Version( Short.valueOf( "52" ) ), Version.valueOf( "52" ) ); + assertEquals( new Version( Short.valueOf( "1" ), Short.valueOf( "34" ) ), Version.valueOf( "1.34" ) ); + } + + @Test + @DisplayName( "Test that new version from String is invalid" ) + public void testVersionValueOfInvalid() + { + assertNull( Version.valueOf( "52." ) ); + assertNull( Version.valueOf( "1.34-release" ) ); + } + @Test @DisplayName( "Test that versions are equal" ) public void testVersionEquals() diff --git a/src/test/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemuTest.java b/src/test/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemuTest.java index b59a86d..1cc7841 100644 --- a/src/test/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemuTest.java +++ b/src/test/java/org/openslx/virtualization/configuration/VirtualizationConfigurationQemuTest.java @@ -25,6 +25,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; +import org.openslx.bwlp.thrift.iface.OperatingSystem; import org.openslx.libvirt.domain.Domain; import org.openslx.libvirt.domain.device.ControllerUsb; import org.openslx.libvirt.domain.device.DiskCdrom; @@ -38,12 +39,15 @@ import org.openslx.virtualization.configuration.VirtualizationConfiguration.Ethe import org.openslx.virtualization.configuration.VirtualizationConfiguration.EthernetDevType; import org.openslx.virtualization.configuration.VirtualizationConfiguration.SoundCardType; import org.openslx.virtualization.configuration.VirtualizationConfiguration.UsbSpeed; +import org.openslx.virtualization.configuration.logic.ConfigurationLogicTestUtils; import org.openslx.vm.disk.DiskImage; import org.openslx.vm.disk.DiskImageTestResources; import org.openslx.vm.disk.DiskImage.ImageFormat; public class VirtualizationConfigurationQemuTest { + public static final List STUB_OS_LIST = ConfigurationLogicTestUtils.STUB_OS_LIST; + private static Domain getPrivateDomainFromQemuMetaData( VirtualizationConfigurationQemu qemuMetadata ) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { @@ -110,6 +114,42 @@ public class VirtualizationConfigurationQemuTest assertDoesNotThrow( () -> vmConfig.validate() ); } + @Test + @DisplayName( "Test output of detected 32-bit OS from VM configuration" ) + public void testQemuMetaDataGetOs32Bit() + throws VirtualizationConfigurationException, IOException, NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException + { + final File file = LibvirtXmlTestResources.getLibvirtXmlFile( "qemu-kvm_default-ubuntu-20-04-vm_i686.xml" ); + final VirtualizationConfigurationQemu vmConfig = new VirtualizationConfigurationQemu( + VirtualizationConfigurationQemuTest.STUB_OS_LIST, file ); + + final OperatingSystem os = vmConfig.getOs(); + + assertNotNull( os ); + assertEquals( VirtualizationConfigurationQemuTest.STUB_OS_LIST.get( 3 ), os ); + + assertDoesNotThrow( () -> vmConfig.validate() ); + } + + @Test + @DisplayName( "Test output of detected 64-bit OS from VM configuration" ) + public void testQemuMetaDataGetOs64Bit() + throws VirtualizationConfigurationException, IOException, NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException + { + final File file = LibvirtXmlTestResources.getLibvirtXmlFile( "qemu-kvm_default-ubuntu-20-04-vm.xml" ); + final VirtualizationConfigurationQemu vmConfig = new VirtualizationConfigurationQemu( + VirtualizationConfigurationQemuTest.STUB_OS_LIST, file ); + + final OperatingSystem os = vmConfig.getOs(); + + assertNotNull( os ); + assertEquals( VirtualizationConfigurationQemuTest.STUB_OS_LIST.get( 4 ), os ); + + assertDoesNotThrow( () -> vmConfig.validate() ); + } + @Test @DisplayName( "Test output of HDDs from VM configuration" ) public void testQemuMetaDataGetHdds() diff --git a/src/test/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicTestUtils.java b/src/test/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicTestUtils.java index 4f85719..07046b5 100644 --- a/src/test/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicTestUtils.java +++ b/src/test/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicTestUtils.java @@ -21,7 +21,7 @@ import org.openslx.virtualization.configuration.VirtualizationConfiguration; public class ConfigurationLogicTestUtils { // @formatter:off - private static final List STUB_OS_LIST = Collections.unmodifiableList( Arrays.asList( + public static final List STUB_OS_LIST = Collections.unmodifiableList( Arrays.asList( new OperatingSystem( 1, "Windows 7 (64 Bit)", null, "AMD64", 196608, 256 ), new OperatingSystem( 2, "Windows 8 (32 Bit)", null, "x86", 4096, 32 ), new OperatingSystem( 3, "Windows 8 (64 Bit)", null, "AMD64", 131072, 256 ), diff --git a/src/test/resources/libvirt/xml/qemu-kvm_default-ubuntu-20-04-vm_i686.xml b/src/test/resources/libvirt/xml/qemu-kvm_default-ubuntu-20-04-vm_i686.xml new file mode 100644 index 0000000..91e86e6 --- /dev/null +++ b/src/test/resources/libvirt/xml/qemu-kvm_default-ubuntu-20-04-vm_i686.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 + + + + +
+ + + + + +
+ + + + +
+ + +
+ + + +
+ + + +
+ + + +
+ + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + +
+ + +
+ + + + + + +
+ + + + + + + + + + + +
+ + + +
+ + +
+ + + + + + + + +
+ +