diff options
Diffstat (limited to 'src/main/java/org/openslx/libvirt')
58 files changed, 9738 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/libvirt/capabilities/Capabilities.java b/src/main/java/org/openslx/libvirt/capabilities/Capabilities.java new file mode 100644 index 0000000..7987371 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/capabilities/Capabilities.java @@ -0,0 +1,155 @@ +package org.openslx.libvirt.capabilities; + +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.openslx.libvirt.capabilities.cpu.Cpu; +import org.openslx.libvirt.capabilities.guest.Guest; +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.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +/** + * Implementation of the Libvirt capabilities XML document. + * + * The Libvirt capabilities XML document is used to describe the configuration and capabilities of + * the hypervisor's host. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Capabilities extends LibvirtXmlDocument +{ + /** + * Creates Libvirt capabilities XML document from {@link String} providing Libvirt capabilities + * XML content. + * + * @param xml {@link String} with Libvirt capabilities XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the capabilities XML content failed. + * @throws LibvirtXmlValidationException XML content is not a valid capabilities XML document. + */ + public Capabilities( String xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException + { + super( xml, LibvirtXmlResources.getLibvirtRng( "capabilities.rng" ) ); + } + + /** + * Creates Libvirt capabilities XML document from {@link File} containing Libvirt capabilities + * XML content. + * + * @param xml existing {@link File} containing Libvirt capabilities XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the capabilities XML content failed. + * @throws LibvirtXmlValidationException XML content is not a valid capabilities XML document. + */ + public Capabilities( File xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException + { + super( xml, LibvirtXmlResources.getLibvirtRng( "capabilities.rng" ) ); + } + + /** + * Creates Libvirt capabilities XML document from {@link InputStream} providing Libvirt + * capabilities XML content. + * + * @param xml {@link InputStream} providing Libvirt capabilities XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the capabilities XML content failed. + * @throws LibvirtXmlValidationException XML content is not a valid capabilities XML document. + */ + public Capabilities( InputStream xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException + { + super( xml, LibvirtXmlResources.getLibvirtRng( "capabilities.rng" ) ); + } + + /** + * Creates Libvirt capabilities XML document from {@link InputSource} providing Libvirt + * capabilities XML content. + * + * @param xml {@link InputSource} providing Libvirt capabilities XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the capabilities XML content failed. + * @throws LibvirtXmlValidationException XML content is not a valid capabilities XML document. + */ + public Capabilities( InputSource xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException + { + super( xml, LibvirtXmlResources.getLibvirtRng( "capabilities.rng" ) ); + } + + /** + * Returns UUID of the Libvirt host machine. + * + * @return UUID of the host machine. + */ + public String getHostUuid() + { + return this.getRootXmlNode().getXmlElementValue( "host/uuid" ); + } + + /** + * Returns CPU capabilities of the host machine. + * + * @return CPU capabilities of the host machine. + */ + public Cpu getHostCpu() + { + final Node hostCpuNode = this.getRootXmlNode().getXmlElement( "host/cpu" ); + + if ( hostCpuNode == null ) { + return null; + } else { + final LibvirtXmlNode hostCpuXmlNode = new LibvirtXmlNode( this.getRootXmlNode().getXmlDocument(), + hostCpuNode ); + return Cpu.newInstance( hostCpuXmlNode ); + } + } + + /** + * Checks whether the Libvirt host machine has IOMMU support. + * + * @return State of the IOMMU support. + */ + public boolean hasHostIommuSupport() + { + return this.getRootXmlNode().getXmlElementAttributeValueAsBool( "host/iommu", "support" ); + } + + /** + * Returns capabilities of all possible guest machines. + * + * @return capabilities of all possible guest machines. + */ + public List<Guest> getGuests() + { + final List<Guest> guestList = new ArrayList<Guest>(); + final NodeList guestNodes = this.getRootXmlNode().getXmlNodes( "guest" ); + + for ( int i = 0; i < guestNodes.getLength(); i++ ) { + final LibvirtXmlNode guestNode = new LibvirtXmlNode( this.getRootXmlNode().getXmlDocument(), + guestNodes.item( i ) ); + final Guest guest = Guest.newInstance( guestNode ); + + if ( guest != null ) { + guestList.add( guest ); + } + } + + return guestList; + } +} diff --git a/src/main/java/org/openslx/libvirt/capabilities/cpu/Cpu.java b/src/main/java/org/openslx/libvirt/capabilities/cpu/Cpu.java new file mode 100644 index 0000000..dc5fbd0 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/capabilities/cpu/Cpu.java @@ -0,0 +1,165 @@ +package org.openslx.libvirt.capabilities.cpu; + +import java.util.ArrayList; +import java.util.List; + +import org.openslx.libvirt.xml.LibvirtXmlNode; +import org.w3c.dom.NodeList; + +/** + * Implementation of the host CPU capabilities as part of the Libvirt capabilities XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Cpu extends LibvirtXmlNode +{ + /** + * Creates an empty host CPU capabilities instance. + */ + public Cpu() + { + super(); + } + + /** + * Creates a host CPU capabilities instance representing an existing Libvirt XML host CPU + * capabilities element. + * + * @param xmlNode existing Libvirt XML host CPU capabilities element. + */ + public Cpu( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns the architecture name of the host CPU. + * + * @return architecture name of the host CPU. + */ + public String getArch() + { + return this.getXmlElementValue( "arch" ); + } + + /** + * Returns the model name of the host CPU. + * + * @return model name of the host CPU. + */ + public String getModel() + { + return this.getXmlElementValue( "model" ); + } + + /** + * Returns the vendor name of the host CPU. + * + * @return vendor name of the host CPU. + */ + public String getVendor() + { + return this.getXmlElementValue( "vendor" ); + } + + /** + * Returns the number of sockets of the host CPU. + * + * @return number of sockets of the host CPU. + */ + public int getTopologySockets() + { + final String numSockets = this.getXmlElementAttributeValue( "topology", "sockets" ); + return Integer.parseInt( numSockets ); + } + + /** + * Returns the number of dies of the host CPU. + * + * @return number of dies of the host CPU. + */ + public int getTopologyDies() + { + final String numDies = this.getXmlElementAttributeValue( "topology", "dies" ); + return Integer.parseInt( numDies ); + } + + /** + * Returns the number of cores of the host CPU. + * + * @return number of cores of the host CPU. + */ + public int getTopologyCores() + { + final String numCores = this.getXmlElementAttributeValue( "topology", "cores" ); + return Integer.parseInt( numCores ); + } + + /** + * Returns the number of threads of the host CPU. + * + * @return number of threads of the host CPU. + */ + public int getTopologyThreads() + { + final String numThreads = this.getXmlElementAttributeValue( "topology", "threads" ); + return Integer.parseInt( numThreads ); + } + + /** + * Returns the supported features of the host CPU. + * + * @return supported features of the host CPU. + */ + public List<Feature> getFeatures() + { + final List<Feature> featureList = new ArrayList<Feature>(); + final NodeList featureNodes = this.getXmlNodes( "feature" ); + + for ( int i = 0; i < featureNodes.getLength(); i++ ) { + final LibvirtXmlNode featureNode = new LibvirtXmlNode( this.getXmlDocument(), featureNodes.item( i ) ); + final Feature feature = Feature.newInstance( featureNode ); + + if ( feature != null ) { + featureList.add( feature ); + } + } + + return featureList; + } + + /** + * Returns the supported memory pages of the host CPU. + * + * @return supported memory pages of the host CPU. + */ + public List<Pages> getPages() + { + final List<Pages> pagesList = new ArrayList<Pages>(); + final NodeList pagesNodes = this.getXmlNodes( "pages" ); + + for ( int i = 0; i < pagesNodes.getLength(); i++ ) { + final LibvirtXmlNode pagesNode = new LibvirtXmlNode( this.getXmlDocument(), pagesNodes.item( i ) ); + final Pages pages = Pages.newInstance( pagesNode ); + + if ( pages != null ) { + pagesList.add( pages ); + } + } + + return pagesList; + } + + /** + * Creates a host CPU capabilities instance representing an existing Libvirt XML host CPU + * capabilities element. + * + * @param xmlNode existing Libvirt XML host CPU capabilities element. + * @return host CPU capabilities instance. + */ + public static Cpu newInstance( LibvirtXmlNode xmlNode ) + { + return new Cpu( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/capabilities/cpu/Feature.java b/src/main/java/org/openslx/libvirt/capabilities/cpu/Feature.java new file mode 100644 index 0000000..96c77d5 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/capabilities/cpu/Feature.java @@ -0,0 +1,51 @@ +package org.openslx.libvirt.capabilities.cpu; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * Implementation of a host CPU feature as part of the Libvirt capabilities XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Feature extends LibvirtXmlNode +{ + /** + * Creates an empty host CPU feature instance. + */ + public Feature() + { + super(); + } + + /** + * Creates an host CPU feature representing an existing Libvirt XML host CPU feature element. + * + * @param xmlNode existing Libvirt XML host CPU feature element. + */ + public Feature( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns the name of the host CPU feature. + * + * @return name of the host CPU feature. + */ + public String getName() + { + return this.getXmlElementAttributeValue( "name" ); + } + + /** + * Creates an host CPU feature representing an existing Libvirt XML host CPU feature element. + * + * @param xmlNode existing Libvirt XML host CPU feature element. + * @return host CPU feature instance. + */ + public static Feature newInstance( LibvirtXmlNode xmlNode ) + { + return new Feature( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/capabilities/cpu/Pages.java b/src/main/java/org/openslx/libvirt/capabilities/cpu/Pages.java new file mode 100644 index 0000000..eea5a36 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/capabilities/cpu/Pages.java @@ -0,0 +1,60 @@ +package org.openslx.libvirt.capabilities.cpu; + +import java.math.BigInteger; + +import org.openslx.libvirt.domain.DomainUtils; +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * Implementation of a host CPU memory pages instance as part of the Libvirt capabilities XML + * document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Pages extends LibvirtXmlNode +{ + /** + * Creates an empty host CPU memory pages instance. + */ + public Pages() + { + super(); + } + + /** + * Creates a host CPU memory pages instance representing an existing Libvirt XML host CPU pages + * element. + * + * @param xmlNode existing Libvirt XML host CPU pages element. + */ + public Pages( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns size of the memory pages instance. + * + * @return size of the memory pages instance. + */ + public BigInteger getSize() + { + final String pagesValue = this.getXmlElementAttributeValue( "size" ); + final String pagesUnit = this.getXmlElementAttributeValue( "unit" ); + + return DomainUtils.decodeMemory( pagesValue, pagesUnit ); + } + + /** + * Creates a host CPU memory pages instance representing an existing Libvirt XML host CPU pages + * element. + * + * @param xmlNode existing Libvirt XML host CPU pages element. + * @return host CPU memory pages instance. + */ + public static Pages newInstance( LibvirtXmlNode xmlNode ) + { + return new Pages( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/capabilities/guest/Domain.java b/src/main/java/org/openslx/libvirt/capabilities/guest/Domain.java new file mode 100644 index 0000000..8716064 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/capabilities/guest/Domain.java @@ -0,0 +1,53 @@ +package org.openslx.libvirt.capabilities.guest; + +import org.openslx.libvirt.domain.Domain.Type; +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * Implementation of a guest domain as part of the Libvirt capabilities XML capabilities document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Domain extends LibvirtXmlNode +{ + /** + * Creates an empty guest domain instance. + */ + public Domain() + { + super(); + } + + /** + * Creates a guest domain representing an existing Libvirt XML guest domain element. + * + * @param xmlNode existing Libvirt XML guest domain element. + */ + public Domain( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns the domain type of the guest domain. + * + * @return type of the guest domain. + */ + public Type getType() + { + final String type = this.getXmlElementAttributeValue( "type" ); + return Type.fromString( type ); + } + + /** + * Creates a guest domain representing an existing Libvirt XML guest domain element. + * + * @param xmlNode existing Libvirt XML guest domain element. + * @return guest domain instance. + */ + public static Domain newInstance( LibvirtXmlNode xmlNode ) + { + return new Domain( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/capabilities/guest/Guest.java b/src/main/java/org/openslx/libvirt/capabilities/guest/Guest.java new file mode 100644 index 0000000..2471180 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/capabilities/guest/Guest.java @@ -0,0 +1,127 @@ +package org.openslx.libvirt.capabilities.guest; + +import java.util.ArrayList; +import java.util.List; + +import org.openslx.libvirt.domain.Domain.OsType; +import org.openslx.libvirt.xml.LibvirtXmlNode; +import org.w3c.dom.NodeList; + +/** + * Implementation of the guest capabilities as part of the Libvirt capabilities XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Guest extends LibvirtXmlNode +{ + /** + * Creates an empty guest instance. + */ + public Guest() + { + super(); + } + + /** + * Creates a guest representing an existing Libvirt XML guest capabilities element. + * + * @param xmlNode existing Libvirt XML guest capabilities element. + */ + public Guest( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Return OS type of the guest. + * + * @return OS type of the guest. + */ + public OsType getOsType() + { + final String osType = this.getXmlElementValue( "os_type" ); + return OsType.fromString( osType ); + } + + /** + * Returns the architecture name of the guest. + * + * @return architecture name of the guest. + */ + public String getArchName() + { + return this.getXmlElementAttributeValue( "arch", "name" ); + } + + /** + * Return word size of the guest's architecture. + * + * @return word size of the guest's architecture. + */ + public int getArchWordSize() + { + final String archWordSize = this.getXmlElementValue( "arch/wordsize" ); + return Integer.parseInt( archWordSize ); + } + + public String getArchEmulator() + { + return this.getXmlElementValue( "arch/emulator" ); + } + + /** + * Returns the available machines of the guest's architecture. + * + * @return available machines of the guest's architecture. + */ + public List<Machine> getArchMachines() + { + final List<Machine> machinesList = new ArrayList<Machine>(); + final NodeList machineNodes = this.getXmlNodes( "arch/machine" ); + + for ( int i = 0; i < machineNodes.getLength(); i++ ) { + final LibvirtXmlNode machineNode = new LibvirtXmlNode( this.getXmlDocument(), machineNodes.item( i ) ); + final Machine machine = Machine.newInstance( machineNode ); + + if ( machine != null ) { + machinesList.add( machine ); + } + } + + return machinesList; + } + + /** + * Returns the supported domains of the guest. + * + * @return supported domains of the guest. + */ + public List<Domain> getArchDomains() + { + final List<Domain> domainList = new ArrayList<Domain>(); + final NodeList domainNodes = this.getXmlNodes( "arch/domain" ); + + for ( int i = 0; i < domainNodes.getLength(); i++ ) { + final LibvirtXmlNode domainNode = new LibvirtXmlNode( this.getXmlDocument(), domainNodes.item( i ) ); + final Domain domain = Domain.newInstance( domainNode ); + + if ( domain != null ) { + domainList.add( domain ); + } + } + + return domainList; + } + + /** + * Creates a guest representing an existing Libvirt XML guest capabilities element. + * + * @param xmlNode existing Libvirt XML guest capabilities element. + * @return guest capabilities instance. + */ + public static Guest newInstance( LibvirtXmlNode xmlNode ) + { + return new Guest( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/capabilities/guest/Machine.java b/src/main/java/org/openslx/libvirt/capabilities/guest/Machine.java new file mode 100644 index 0000000..dfe6362 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/capabilities/guest/Machine.java @@ -0,0 +1,72 @@ +package org.openslx.libvirt.capabilities.guest; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * Implementation of a guest machine as part of the Libvirt XML capabilities document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Machine extends LibvirtXmlNode +{ + /** + * Creates an empty guest machine instance. + */ + public Machine() + { + super(); + } + + /** + * Creates an guest machine representing an existing Libvirt XML guest machine element. + * + * @param xmlNode existing Libvirt XML guest machine element. + */ + public Machine( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns the canonical machine name. + * + * @return canonical machine name. + */ + public String getCanonicalMachine() + { + return this.getXmlElementAttributeValue( "canonical" ); + } + + /** + * Returns the maximum number of CPUs supported by the guest machine. + * + * @return maximum number of CPUs supported by the guest machine. + */ + public int getMaxCpus() + { + final String numMaxCpus = this.getXmlElementAttributeValue( "maxCpus" ); + return Integer.parseUnsignedInt( numMaxCpus ); + } + + /** + * Returns the name of the guest machine. + * + * @return name of the guest machine. + */ + public String getName() + { + return this.getXmlElementValue( null ); + } + + /** + * Creates an guest machine representing an existing Libvirt XML guest machine element. + * + * @param xmlNode existing Libvirt XML guest machine element. + * @return guest machine instance. + */ + public static Machine newInstance( LibvirtXmlNode xmlNode ) + { + return new Machine( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/Domain.java b/src/main/java/org/openslx/libvirt/domain/Domain.java new file mode 100644 index 0000000..c19b2a3 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/Domain.java @@ -0,0 +1,1743 @@ +package org.openslx.libvirt.domain; + +import java.io.File; +import java.io.InputStream; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import javax.xml.XMLConstants; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import org.openslx.libvirt.domain.device.Controller; +import org.openslx.libvirt.domain.device.ControllerFloppy; +import org.openslx.libvirt.domain.device.ControllerIde; +import org.openslx.libvirt.domain.device.ControllerPci; +import org.openslx.libvirt.domain.device.ControllerSata; +import org.openslx.libvirt.domain.device.ControllerScsi; +import org.openslx.libvirt.domain.device.ControllerUsb; +import org.openslx.libvirt.domain.device.Device; +import org.openslx.libvirt.domain.device.Disk; +import org.openslx.libvirt.domain.device.DiskCdrom; +import org.openslx.libvirt.domain.device.DiskFloppy; +import org.openslx.libvirt.domain.device.DiskStorage; +import org.openslx.libvirt.domain.device.FileSystem; +import org.openslx.libvirt.domain.device.Graphics; +import org.openslx.libvirt.domain.device.GraphicsSpice; +import org.openslx.libvirt.domain.device.GraphicsVnc; +import org.openslx.libvirt.domain.device.Hostdev; +import org.openslx.libvirt.domain.device.HostdevMdev; +import org.openslx.libvirt.domain.device.HostdevPci; +import org.openslx.libvirt.domain.device.HostdevUsb; +import org.openslx.libvirt.domain.device.Interface; +import org.openslx.libvirt.domain.device.InterfaceBridge; +import org.openslx.libvirt.domain.device.InterfaceNetwork; +import org.openslx.libvirt.domain.device.Parallel; +import org.openslx.libvirt.domain.device.Serial; +import org.openslx.libvirt.domain.device.Shmem; +import org.openslx.libvirt.domain.device.Sound; +import org.openslx.libvirt.domain.device.Video; +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.util.XmlHelper; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +/** + * Implementation of the Libvirt domain XML document. + * + * The Libvirt domain XML document is used to describe virtual machines and their configurations. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Domain extends LibvirtXmlDocument +{ + /** + * XML namespace URI for QEMU command line elements in the Libvirt domain XML document. + */ + private static final String XMLNS_QEMU_NS_URI = "http://libvirt.org/schemas/domain/qemu/1.0"; + + /** + * XML namespace prefix for QEMU command line elements in the Libvirt domain XML document. + */ + private static final String XMLNS_QEMU_NS_PREFIX = "qemu"; + + /** + * Creates Libvirt domain XML document from {@link String} providing Libvirt domain XML content. + * + * @param xml {@link String} with Libvirt domain XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the domain XML content failed. + * @throws LibvirtXmlValidationException XML content is not a valid domain XML document. + */ + public Domain( String xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException + { + super( xml, LibvirtXmlResources.getLibvirtRng( "domain.rng" ) ); + this.assertDomainType(); + } + + /** + * Creates Libvirt domain XML document from {@link File} containing Libvirt domain XML content. + * + * @param xml existing {@link File} containing Libvirt domain XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the domain XML content failed. + * @throws LibvirtXmlValidationException XML content is not a valid domain XML document. + */ + public Domain( File xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException + { + super( xml, LibvirtXmlResources.getLibvirtRng( "domain.rng" ) ); + this.assertDomainType(); + } + + /** + * Creates Libvirt domain XML document from {@link InputStream} providing Libvirt domain XML + * content. + * + * @param xml {@link InputStream} providing Libvirt domain XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the domain XML content failed. + * @throws LibvirtXmlValidationException XML content is not a valid domain XML document. + */ + public Domain( InputStream xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException + { + super( xml, LibvirtXmlResources.getLibvirtRng( "domain.rng" ) ); + this.assertDomainType(); + } + + /** + * Creates Libvirt domain XML document from {@link InputSource} providing Libvirt domain XML + * content. + * + * @param xml {@link InputSource} providing Libvirt domain XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the domain XML content failed. + * @throws LibvirtXmlValidationException XML content is not a valid domain XML document. + */ + public Domain( InputSource xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException + { + super( xml, LibvirtXmlResources.getLibvirtRng( "domain.rng" ) ); + this.assertDomainType(); + } + + /** + * Quick sanity check whether this could be a libvirt domain file at all. + * We just check if the root node is called domain and has the attribute type. + * + * @throws LibvirtXmlValidationException If this is not met. + */ + private void assertDomainType() throws LibvirtXmlValidationException + { + try { + XPathExpression expr = XmlHelper.compileXPath( "/domain[@type]" ); + Object nodesObject = expr.evaluate( this.getRootXmlNode().getXmlDocument(), XPathConstants.NODESET ); + NodeList nodes = (NodeList)nodesObject; + if ( nodes.getLength() == 0 ) + throw new LibvirtXmlValidationException( "Root element isn't <domain type=...>" ); + } catch ( XPathExpressionException e ) { + e.printStackTrace(); + } + } + + /** + * Types of hypervisors specifiable for a virtual machine in the Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum Type + { + // @formatter:off + QEMU ( "qemu" ), + KQEMU ( "kqemu" ), + KVM ( "kvm" ), + XEN ( "xen" ), + LXC ( "lxc" ), + UML ( "uml" ), + OPENVZ( "openvz" ), + TEST ( "test" ), + VMWARE( "vmware" ), + HYPERV( "hyperv" ), + VBOX ( "vbox" ), + PHYP ( "phyp" ), + VZ ( "vz" ), + BHYVE ( "bhyve" ); + // @formatter:on + + /** + * Name of the hypervisor in a Libvirt domain XML document. + */ + private String type; + + /** + * Creates a hypervisor type. + * + * @param type valid name of the hypervisor in a Libvirt domain XML document. + */ + Type( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates a hypervisor type from its name with error check. + * + * @param type name of the hypervisor in the Libvirt domain XML document. + * @return valid hypervisor type. + */ + public static Type fromString( String type ) + { + for ( Type t : Type.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } + + /** + * Returns hypervisor type defined in the Libvirt domain XML document. + * + * @return hypervisor type. + */ + public Type getType() + { + String typeValue = this.getRootXmlNode().getXmlElementAttributeValue( null, "type" ); + return Type.fromString( typeValue ); + } + + /** + * Sets hypervisor type in Libvirt domain XML document. + * + * @param type hypervisor type for Libvirt domain XML document. + */ + public void setType( Type type ) + { + this.getRootXmlNode().setXmlElementAttributeValue( null, "type", type.toString() ); + } + + /** + * Returns virtual machine name defined in the Libvirt domain XML document. + * + * @return name of the virtual machine. + */ + public String getName() + { + return this.getRootXmlNode().getXmlElementValue( "name" ); + } + + /** + * Sets virtual machine name in the Libvirt domain XML document. + * + * @param name virtual machine name for Libvirt domain XML document. + */ + public void setName( String name ) + { + this.getRootXmlNode().setXmlElementValue( "name", name ); + } + + /** + * Returns virtual machine title defined in the Libvirt domain XML document. + * + * @return title of the virtual machine. + */ + public String getTitle() + { + return this.getRootXmlNode().getXmlElementValue( "title" ); + } + + /** + * Sets virtual machine title in the Libvirt domain XML document. + * + * @param title virtual machine title for Libvirt domain XML document. + */ + public void setTitle( String title ) + { + this.getRootXmlNode().setXmlElementValue( "title", title ); + } + + /** + * Returns virtual machine description defined in the Libvirt domain XML document. + * + * @return description of virtual machine. + */ + public String getDescription() + { + return this.getRootXmlNode().getXmlElementValue( "description" ); + } + + /** + * Sets virtual machine description in the Libvirt domain XML document. + * + * @param description virtual machine description for Libvirt domain XML document. + */ + public void setDescription( String description ) + { + 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 the state of the Hyper-V vendor identifier feature. + * + * @return state of the Hyper-V vendor identifier feature. + */ + public boolean isFeatureHypervVendorIdStateOn() + { + return this.getRootXmlNode().getXmlElementAttributeValueAsBool( "features/hyperv/vendor_id", "state" ); + } + + /** + * Sets the state of the Hyper-V vendor identifier feature. + * + * @param on state for the Hyper-V vendor identifier feature. + */ + public void setFeatureHypervVendorIdState( boolean on ) + { + this.getRootXmlNode().setXmlElementAttributeValueOnOff( "features/hyperv/vendor_id", "state", on ); + } + + /** + * Returns the value of the Hyper-V vendor identifier feature. + * + * @return value of the Hyper-V vendor identifier feature. + */ + public String getFeatureHypervVendorIdValue() + { + return this.getRootXmlNode().getXmlElementAttributeValue( "features/hyperv/vendor_id", "value" ); + } + + /** + * Sets the value of the Hyper-V vendor identifier feature. + * + * @param value value for the Hyper-V vendor identifier feature. + */ + public void setFeatureHypervVendorIdValue( String value ) + { + this.getRootXmlNode().setXmlElementAttributeValue( "features/hyperv/vendor_id", "value", value ); + } + + /** + * Returns the state of the KVM hidden feature. + * + * @return state of the KVM hidden feature. + */ + public boolean isFeatureKvmHiddenStateOn() + { + return this.getRootXmlNode().getXmlElementAttributeValueAsBool( "features/kvm/hidden", "state" ); + } + + /** + * Sets the state of the KVM hidden feature. + * + * @param on state for the KVM hidden feature. + */ + public void setFeatureKvmHiddenState( boolean on ) + { + this.getRootXmlNode().setXmlElementAttributeValueOnOff( "features/kvm/hidden", "state", on ); + this.getRootXmlNode().setXmlElement( "cpu" ); + if ( on ) { + Element cpu = this.getRootXmlNode().getXmlElement( "cpu" ); + XmlHelper.getOrCreateElement( this.getRootXmlNode().getXmlDocument(), cpu, + null, null, + "feature", "name", "hypervisor" ); + this.getRootXmlNode().setXmlElementAttributeValue( "cpu/feature", "policy", "disable" ); + } else { + this.getRootXmlNode().removeXmlElement( "cpu/feature[@name='hypervisor']" ); + } + } + + /** + * Returns virtual machine UUID defined in the Libvirt domain XML document. + * + * @return UUID of virtual machine. + */ + public String getUuid() + { + return this.getRootXmlNode().getXmlElementValue( "uuid" ); + } + + /** + * Sets virtual machine UUID in the Libvirt domain XML document. + * + * @param uuid virtual machine UUID for Libvirt domain XML document. + */ + public void setUuid( String uuid ) + { + this.getRootXmlNode().setXmlElementValue( "uuid", uuid ); + } + + /** + * Removes virtual machine UUID in the Libvirt domain XML document. + */ + public void removeUuid() + { + this.getRootXmlNode().removeXmlElement( "uuid" ); + } + + /** + * Returns virtual machine memory defined in the Libvirt domain XML document. + * + * @return memory of virtual machine. + */ + public BigInteger getMemory() + { + String memValue = this.getRootXmlNode().getXmlElementValue( "memory" ); + String memUnit = this.getRootXmlNode().getXmlElementAttributeValue( "memory", "unit" ); + return DomainUtils.decodeMemory( memValue, memUnit ); + } + + /** + * Sets virtual machine memory in the Libvirt domain XML document. + * + * @param memory virtual machine memory in the Libvirt domain XML document. + */ + public void setMemory( BigInteger memory ) + { + this.getRootXmlNode().setXmlElementAttributeValue( "memory", "unit", "KiB" ); + this.getRootXmlNode().setXmlElementValue( "memory", DomainUtils.encodeMemory( memory, "KiB" ) ); + } + + /** + * Returns current virtual machine memory defined in the Libvirt domain XML document. + * + * @return current memory of virtual machine. + */ + public BigInteger getCurrentMemory() + { + String memValue = this.getRootXmlNode().getXmlElementValue( "currentMemory" ); + String memUnit = this.getRootXmlNode().getXmlElementAttributeValue( "currentMemory", "unit" ); + return DomainUtils.decodeMemory( memValue, memUnit ); + } + + /** + * Set current virtual machine memory in the Libvirt domain XML document. + * + * @param currentMemory current virtual machine memory in the Libvirt domain XML document. + */ + public void setCurrentMemory( BigInteger currentMemory ) + { + this.getRootXmlNode().setXmlElementAttributeValue( "currentMemory", "unit", "KiB" ); + this.getRootXmlNode().setXmlElementValue( "currentMemory", DomainUtils.encodeMemory( currentMemory, "KiB" ) ); + } + + /** + * Returns number of virtual machine CPUs defined in the Libvirt domain XML document. + * + * @return number of CPUs of the virtual machine. + */ + public int getVCpu() + { + String number = this.getRootXmlNode().getXmlElementValue( "vcpu" ); + return Integer.parseUnsignedInt( number ); + } + + /** + * Set number of virtual machine CPUs in the Libvirt domain XML document. + * + * @param number virtual machine CPUs. + */ + public void setVCpu( int number ) + { + this.getRootXmlNode().setXmlElementValue( "vcpu", Integer.toString( number ) ); + } + + /** + * Returns OS type defined in the Libvirt domain XML document. + * + * @return OS type of the virtual machine. + */ + public OsType getOsType() + { + final String osType = this.getRootXmlNode().getXmlElementValue( "os/type" ); + return OsType.fromString( osType ); + } + + /** + * Set OS type in the Libvirt domain XML document. + * + * @param type OS type for the virtual machine. + */ + public void setOsType( OsType type ) + { + this.getRootXmlNode().setXmlElementValue( "os/type", type.toString() ); + } + + /** + * Returns OS architecture defined in the Libvirt domain XML document. + * + * @return OS architecture of the virtual machine. + */ + public String getOsArch() + { + return this.getRootXmlNode().getXmlElementAttributeValue( "os/type", "arch" ); + } + + /** + * Set OS architecture in the Libvirt domain XML document. + * + * @param arch OS architecture for the virtual machine. + */ + public void setOsArch( String arch ) + { + this.getRootXmlNode().setXmlElementAttributeValue( "os/type", "arch", arch ); + } + + /** + * Returns OS machine defined in the Libvirt domain XML document. + * + * @return OS machine of the virtual machine. + */ + public String getOsMachine() + { + return this.getRootXmlNode().getXmlElementAttributeValue( "os/type", "machine" ); + } + + /** + * Set OS machine in the Libvirt domain XML document. + * + * @param machine OS machine for the virtual machine. + */ + public void setOsMachine( String machine ) + { + this.getRootXmlNode().setXmlElementAttributeValue( "os/type", "machine", machine ); + } + + /** + * Returns OS loader defined in the Libvirt domain XML document. + * + * @return OS loader of the virtual machine. + */ + public String getOsLoader() + { + return this.getRootXmlNode().getXmlElementValue( "os/loader" ); + } + + /** + * Set OS loader in the Libvirt domain XML document. + * + * @param loader OS loader for the virtual machine. + */ + public void setOsLoader( String loader ) + { + this.getRootXmlNode().setXmlElementValue( "os/loader", loader ); + } + + /** + * Returns OS Nvram defined in the Libvirt domain XML document. + * + * @return OS Nvram of the virtual machine. + */ + public String getOsNvram() + { + return this.getRootXmlNode().getXmlElementValue( "os/nvram" ); + } + + /** + * Set OS Nvram in the Libvirt domain XML document. + * + * @param nvram OS Nvram for the virtual machine. + */ + public void setOsNvram( String nvram ) + { + this.getRootXmlNode().setXmlElementValue( "os/nvram", nvram ); + } + + /** + * Operating system types specifiable for a virtual machine in the Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum OsType + { + // @formatter:off + XEN ( "xen" ), + LINUX( "linux" ), + HVM ( "hvm" ), + EXE ( "exe" ), + UML ( "uml" ); + // @formatter:on + + /** + * Name of the OS type in a Libvirt domain XML document. + */ + private final String osType; + + /** + * Creates an OS type. + * + * @param osType valid name of the OS type in the Libvirt domain XML document. + */ + OsType( String osType ) + { + this.osType = osType; + } + + @Override + public String toString() + { + return this.osType; + } + + /** + * Creates an OS type from its name with error check. + * + * @param osType name of the OS type in the Libvirt domain XML document. + * @return valid OS type. + */ + public static OsType fromString( String osType ) + { + for ( OsType t : OsType.values() ) { + if ( t.osType.equalsIgnoreCase( osType ) ) { + return t; + } + } + + return null; + } + } + + /** + * Returns virtual machine CPU model defined in the Libvirt domain XML document. + * + * @return CPU model of virtual machine. + */ + public String getCpuModel() + { + return this.getRootXmlNode().getXmlElementValue( "cpu/model" ); + } + + /** + * Sets virtual machine CPU model in the Libvirt domain XML document. + * + * @param model virtual machine CPU model. + */ + public void setCpuModel( String model ) + { + this.getRootXmlNode().setXmlElementValue( "cpu/model", model ); + } + + /** + * CPU modes specifiable for a virtual machine in the Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum CpuMode + { + // @formatter:off + CUSTOM ( "custom" ), + HOST_MODEL ( "host-model" ), + HOST_PASSTHROUGH( "host-passthrough" ); + // @formatter:on + + /** + * Name of the CPU mode in a Libvirt domain XML document. + */ + private String cpuMode; + + /** + * Creates a CPU mode. + * + * @param mode valid name of the CPU mode in the Libvirt domain XML document. + */ + CpuMode( String mode ) + { + this.cpuMode = mode; + } + + @Override + public String toString() + { + return this.cpuMode; + } + + /** + * Creates a CPU mode from its name with error check. + * + * @param mode name of the CPU mode in the Libvirt domain XML document. + * @return valid CPU mode. + */ + public static CpuMode fromString( String mode ) + { + for ( CpuMode t : CpuMode.values() ) { + if ( t.cpuMode.equalsIgnoreCase( mode ) ) { + return t; + } + } + + return null; + } + } + + /** + * Returns virtual machine CPU mode defined in the Libvirt domain XML document. + * + * @return CPU mode of the virtual machine. + */ + public CpuMode getCpuMode() + { + String cpuMode = this.getRootXmlNode().getXmlElementAttributeValue( "cpu", "mode" ); + return CpuMode.fromString( cpuMode ); + } + + /** + * Sets virtual machine CPU mode in the Libvirt domain XML document. + * + * @param mode virtual machine CPU mode. + */ + public void setCpuMode( CpuMode mode ) + { + this.getRootXmlNode().setXmlElementAttributeValue( "cpu", "mode", mode.toString() ); + // Pass through cache information as well, because for some reason this is no the default + // when we do CPU host passthrough.... + if ( mode == CpuMode.HOST_PASSTHROUGH ) { + this.getRootXmlNode().setXmlElementAttributeValue( "cpu/cache", "mode", "passthrough" ); + } else if ( "passthrough".equals( this.getRootXmlNode().getXmlElementAttributeValue( "cpu/cache", "mode" ) ) ) { + this.getRootXmlNode().removeXmlElement( "cpu/cache" ); + } + } + + /** + * Returns if the CPU migratable flag is set in the Libvirt domain XML document. + */ + public boolean getCpuMigratable() + { + return this.getRootXmlNode().getXmlElementAttributeValueAsBool( "cpu", "migratable" ); + } + + /** + * Sets if vCPU is migratable in the Libvirt domain XML document. + */ + public void setCpuMigratable( boolean migratable ) + { + this.getRootXmlNode().setXmlElementAttributeValueOnOff( "cpu", "migratable", migratable ); + } + + /** + * CPU checks specifiable for a virtual machine in the Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum CpuCheck + { + // @formatter:off + NONE ( "none" ), + PARTIAL( "partial" ), + FULL ( "full" ); + // @formatter:on + + /** + * Name of the CPU check in the Libvirt domain XML document. + */ + private String cpuCheck; + + /** + * Creates a CPU check. + * + * @param check valid name of the CPU check in the Libvirt domain XML document. + */ + CpuCheck( String check ) + { + this.cpuCheck = check; + } + + @Override + public String toString() + { + return this.cpuCheck; + } + + /** + * Creates a CPU check from its name with error check. + * + * @param check name of the CPU check in the Libvirt domain XML document. + * @return valid CPU check. + */ + public static CpuCheck fromString( String check ) + { + for ( CpuCheck t : CpuCheck.values() ) { + if ( t.cpuCheck.equalsIgnoreCase( check ) ) { + return t; + } + } + + return null; + } + } + + /** + * Returns virtual machine CPU check defined in the Libvirt domain XML document. + * + * @return CPU check of the virtual machine. + */ + public CpuCheck getCpuCheck() + { + String cpuCheck = this.getRootXmlNode().getXmlElementAttributeValue( "cpu", "check" ); + return CpuCheck.fromString( cpuCheck ); + } + + /** + * Sets virtual machine CPU check in the Libvirt domain XML document. + * + * @param check virtual machine CPU check. + */ + public void setCpuCheck( CpuCheck check ) + { + this.getRootXmlNode().setXmlElementAttributeValue( "cpu", "check", check.toString() ); + } + + /** + * Returns the number of virtual machine CPU dies defined in the Libvirt domain XML document. + * + * @return number of virtual machine CPU dies. + */ + public int getCpuDies() + { + final String numDies = this.getRootXmlNode().getXmlElementAttributeValue( "cpu/topology", "dies" ); + return Integer.valueOf( numDies ); + } + + /** + * Set number of virtual machine CPU dies in the Libvirt domain XML document. + * + * @param number virtual machine CPU dies. + */ + public void setCpuDies( int number ) + { + this.getRootXmlNode().setXmlElementAttributeValue( "cpu/topology", "dies", Integer.toString( number ) ); + } + + /** + * Returns the number of virtual machine CPU sockets defined in the Libvirt domain XML document. + * + * @return number of virtual machine CPU sockets. + */ + public int getCpuSockets() + { + final String numSockets = this.getRootXmlNode().getXmlElementAttributeValue( "cpu/topology", "sockets" ); + return Integer.valueOf( numSockets ); + } + + /** + * Set number of virtual machine CPU dies in the Libvirt domain XML document. + * + * @param number virtual machine CPU dies. + */ + public void setCpuSockets( int number ) + { + this.getRootXmlNode().setXmlElementAttributeValue( "cpu/topology", "sockets", Integer.toString( number ) ); + } + + /** + * Returns the number of virtual machine CPU cores defined in the Libvirt domain XML document. + * + * @return number of virtual machine CPU cores. + */ + public int getCpuCores() + { + final String numCores = this.getRootXmlNode().getXmlElementAttributeValue( "cpu/topology", "cores" ); + return Integer.valueOf( numCores ); + } + + /** + * Set number of virtual machine CPU cores in the Libvirt domain XML document. + * + * @param number virtual machine CPU cores. + */ + public void setCpuCores( int number ) + { + this.getRootXmlNode().setXmlElementAttributeValue( "cpu/topology", "cores", Integer.toString( number ) ); + } + + /** + * Returns the number of virtual machine CPU threads defined in the Libvirt domain XML document. + * + * @return number of virtual machine CPU threads. + */ + public int getCpuThreads() + { + final String numThreads = this.getRootXmlNode().getXmlElementAttributeValue( "cpu/topology", "threads" ); + return Integer.valueOf( numThreads ); + } + + /** + * Set number of virtual machine CPU threads in the Libvirt domain XML document. + * + * @param number virtual machine CPU threads. + */ + public void setCpuThreads( int number ) + { + this.getRootXmlNode().setXmlElementAttributeValue( "cpu/topology", "threads", Integer.toString( number ) ); + } + + /** + * Returns the file name of the emulator binary defined in the Libvirt domain XML document. + * + * @return file name of the emulator binary. + */ + public String getDevicesEmulator() + { + return this.getRootXmlNode().getXmlElementValue( "devices/emulator" ); + } + + /** + * Sets the file name of the emulator binary in the Libvirt domain XML document. + * + * @param emulator file name of the emulator binary. + */ + public void setDevicesEmulator( String emulator ) + { + this.getRootXmlNode().setXmlElementValue( "devices/emulator", emulator ); + } + + /** + * Returns virtual machine devices defined in the Libvirt domain XML document. + * + * @return devices of the virtual machine. + */ + public ArrayList<Device> getDevices() + { + ArrayList<Device> devices = new ArrayList<Device>(); + Node devicesNode = this.getRootXmlNode().getXmlElement( "devices" ); + + if ( devicesNode != null ) { + + NodeList devicesElements = devicesNode.getChildNodes(); + + for ( int i = 0; i < devicesElements.getLength(); i++ ) { + final Node childNode = devicesElements.item( i ); + if ( childNode.getNodeType() == Node.ELEMENT_NODE ) { + LibvirtXmlNode deviceNode = new LibvirtXmlNode( this.getRootXmlNode().getXmlDocument(), childNode ); + Device device = Device.newInstance( deviceNode ); + + if ( device != null ) { + devices.add( device ); + } + } + } + } + + return devices; + } + + /** + * Filter list of virtual machine devices of type {@link Device} and cast filtered instances to + * more specific device type <code>R</code>. + * + * @param <R> specific device type for filtering and casting. + * @param cls specific device type's class. + * @param devices list of virtual machines devices. + * @return filtered list of virtual machines devices of type <code>R</code>. + */ + private static <R> ArrayList<R> filterDevices( Class<R> cls, ArrayList<Device> devices ) + { + Predicate<Device> byFilter = device -> cls.isInstance( device ); + Function<Device, R> castFunction = device -> cls.cast( device ); + + return devices.stream().filter( byFilter ).map( castFunction ) + .collect( Collectors.toCollection( ArrayList::new ) ); + } + + /** + * Returns list of virtual machine controller devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine controller devices. + */ + public ArrayList<Controller> getControllerDevices() + { + return Domain.filterDevices( Controller.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine floppy controller devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine floppy controller devices. + */ + public ArrayList<ControllerFloppy> getFloppyControllerDevices() + { + return Domain.filterDevices( ControllerFloppy.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine IDE controller devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine IDE controller devices. + */ + public ArrayList<ControllerIde> getIdeControllerDevices() + { + return Domain.filterDevices( ControllerIde.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine floppy controller devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine floppy controller devices. + */ + public ArrayList<ControllerPci> getPciControllerDevices() + { + return Domain.filterDevices( ControllerPci.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine SATA controller devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine SATA controller devices. + */ + public ArrayList<ControllerSata> getSataControllerDevices() + { + return Domain.filterDevices( ControllerSata.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine SCSI controller devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine SCSI controller devices. + */ + public ArrayList<ControllerScsi> getScsiControllerDevices() + { + return Domain.filterDevices( ControllerScsi.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine USB controller devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine USB controller devices. + */ + public ArrayList<ControllerUsb> getUsbControllerDevices() + { + return Domain.filterDevices( ControllerUsb.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine disk devices specified in the Libvirt domain XML document. + * + * @return list of virtual machine disk devices. + */ + public ArrayList<Disk> getDiskDevices() + { + return Domain.filterDevices( Disk.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine disk CDROM devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine disk CDROM devices. + */ + public ArrayList<DiskCdrom> getDiskCdromDevices() + { + return Domain.filterDevices( DiskCdrom.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine disk floppy devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine disk floppy devices. + */ + public ArrayList<DiskFloppy> getDiskFloppyDevices() + { + return Domain.filterDevices( DiskFloppy.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine disk storage devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine disk storage devices. + */ + public ArrayList<DiskStorage> getDiskStorageDevices() + { + return Domain.filterDevices( DiskStorage.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine file system devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine file system devices. + */ + public ArrayList<FileSystem> getFileSystemDevices() + { + return Domain.filterDevices( FileSystem.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine hostdev devices specified in the Libvirt domain XML document. + * + * @return list of virtual machine hostdev devices. + */ + public ArrayList<Hostdev> getHostdevDevices() + { + return Domain.filterDevices( Hostdev.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine mediated hostdev devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine mediated hostdev devices. + */ + public ArrayList<HostdevMdev> getHostdevMdevDevices() + { + return Domain.filterDevices( HostdevMdev.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine PCI hostdev devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine PCI hostdev devices. + */ + public ArrayList<HostdevPci> getHostdevPciDevices() + { + return Domain.filterDevices( HostdevPci.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine USB hostdev devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine USB hostdev devices. + */ + public ArrayList<HostdevUsb> getHostdevUsbDevices() + { + return Domain.filterDevices( HostdevUsb.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine network interface devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine network interface devices. + */ + public ArrayList<Interface> getInterfaceDevices() + { + return Domain.filterDevices( Interface.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine graphic devices specified in the Libvirt domain XML document. + * + * @return list of virtual machine graphic devices. + */ + public ArrayList<Graphics> getGraphicDevices() + { + return Domain.filterDevices( Graphics.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine SPICE graphic devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine SPICE graphic devices. + */ + public ArrayList<GraphicsSpice> getGraphicSpiceDevices() + { + return Domain.filterDevices( GraphicsSpice.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine VNC graphic devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine VNC graphic devices. + */ + public ArrayList<GraphicsVnc> getGraphicVncDevices() + { + return Domain.filterDevices( GraphicsVnc.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine parallel port devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine parallel port devices. + */ + public ArrayList<Parallel> getParallelDevices() + { + return Domain.filterDevices( Parallel.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine serial port devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine serial port devices. + */ + public ArrayList<Serial> getSerialDevices() + { + return Domain.filterDevices( Serial.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine shared memory devices specified in the Libvirt domain XML + * document. + * + * @return list of virtual machine shared memory devices. + */ + public ArrayList<Shmem> getShmemDevices() + { + return Domain.filterDevices( Shmem.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine sound devices specified in the Libvirt domain XML document. + * + * @return list of virtual machine sound devices. + */ + public ArrayList<Sound> getSoundDevices() + { + return Domain.filterDevices( Sound.class, this.getDevices() ); + } + + /** + * Returns list of virtual machine video devices specified in the Libvirt domain XML document. + * + * @return list of virtual machine video devices. + */ + public ArrayList<Video> getVideoDevices() + { + return Domain.filterDevices( Video.class, this.getDevices() ); + } + + /** + * Returns the values of QEMU command line arguments from the Libvirt domain XML document. + * + * @return values of QEMU command line arguments from the Libvirt domain XML document. + */ + public ArrayList<String> getQemuCmdlnArguments() + { + final Document xmlDocument = this.getRootXmlNode().getXmlDocument(); + final ArrayList<String> qemuCmdlnArgs = new ArrayList<String>(); + + final NodeList qemuCmdlnNodes = xmlDocument.getElementsByTagNameNS( XMLNS_QEMU_NS_URI, "commandline" ); + if ( qemuCmdlnNodes.getLength() > 0 ) { + final Node qemuCmdlnNode = qemuCmdlnNodes.item( 0 ); + final NodeList qemuCmdlnArgNodes = qemuCmdlnNode.getChildNodes(); + for ( int i = 0; i < qemuCmdlnArgNodes.getLength(); i++ ) { + final Node qemuCmdlnArgNode = qemuCmdlnArgNodes.item( i ); + if ( qemuCmdlnArgNode.getNodeType() == Node.ELEMENT_NODE ) { + final Element qemuCmdlnArgElement = Element.class.cast( qemuCmdlnArgNode ); + final String value = qemuCmdlnArgElement.getAttribute( "value" ); + if ( value != null && !value.isEmpty() ) { + qemuCmdlnArgs.add( value ); + } + } + } + } + + return qemuCmdlnArgs; + } + + /** + * Adds a virtual machine device to the Libvirt domain XML document. + * + * @param device virtual machine device that is added to the Libvirt domain XML document. + * @return reference to the added device for configuration purposes if creation was successful. + */ + public Device addDevice( Device device ) + { + Device addedDevice = null; + + if ( device != null ) { + Node devicesNode = this.getRootXmlNode().getXmlElement( "devices" ); + + if ( devicesNode != null ) { + LibvirtXmlNode parentDevicesNode = null; + parentDevicesNode = new LibvirtXmlNode( this.getRootXmlNode().getXmlDocument(), devicesNode ); + addedDevice = Device.createInstance( device, parentDevicesNode ); + } + } + + return addedDevice; + } + + /** + * Adds a virtual machine controller device to the Libvirt domain XML document. + * + * @return reference to the added controller device if creation was successful. + */ + public Controller addControllerDevice() + { + return Controller.class.cast( this.addDevice( new Controller() ) ); + } + + /** + * Adds a virtual machine floppy controller device to the Libvirt domain XML document. + * + * @return reference to the added floppy controller device if creation was successful. + */ + public ControllerFloppy addControllerFloppyDevice() + { + return ControllerFloppy.class.cast( this.addDevice( new ControllerFloppy() ) ); + } + + /** + * Adds a virtual machine IDE controller device to the Libvirt domain XML document. + * + * @return reference to the added IDE controller device if creation was successful. + */ + public ControllerIde addControllerIdeDevice() + { + return ControllerIde.class.cast( this.addDevice( new ControllerIde() ) ); + } + + /** + * Adds a virtual machine PCI controller device to the Libvirt domain XML document. + * + * @return reference to the added PCI controller device if creation was successful. + */ + public ControllerPci addControllerPciDevice() + { + return ControllerPci.class.cast( this.addDevice( new ControllerPci() ) ); + } + + /** + * Adds a virtual machine SATA controller device to the Libvirt domain XML document. + * + * @return reference to the added SATA controller device if creation was successful. + */ + public ControllerSata addControllerSataDevice() + { + return ControllerSata.class.cast( this.addDevice( new ControllerSata() ) ); + } + + /** + * Adds a virtual machine SCSI controller device to the Libvirt domain XML document. + * + * @return reference to the added SCSI controller device if creation was successful. + */ + public ControllerScsi addControllerScsiDevice() + { + return ControllerScsi.class.cast( this.addDevice( new ControllerScsi() ) ); + } + + /** + * Adds a virtual machine USB controller device to the Libvirt domain XML document. + * + * @return reference to the added USB controller device if creation was successful. + */ + public ControllerUsb addControllerUsbDevice() + { + return ControllerUsb.class.cast( this.addDevice( new ControllerUsb() ) ); + } + + /** + * Adds a virtual machine disk device to the Libvirt domain XML document. + * + * @return reference to the added disk device if creation was successful. + */ + public Disk addDiskDevice() + { + return Disk.class.cast( this.addDevice( new Disk() ) ); + } + + /** + * Adds a virtual machine CDROM disk device to the Libvirt domain XML document. + * + * @return reference to the added CDROM disk device if creation was successful. + */ + public DiskCdrom addDiskCdromDevice() + { + return DiskCdrom.class.cast( this.addDevice( new DiskCdrom() ) ); + } + + /** + * Adds a virtual machine floppy disk device to the Libvirt domain XML document. + * + * @return reference to the added floppy disk device if creation was successful. + */ + public DiskFloppy addDiskFloppyDevice() + { + return DiskFloppy.class.cast( this.addDevice( new DiskFloppy() ) ); + } + + /** + * Adds a virtual machine storage disk device to the Libvirt domain XML document. + * + * @return reference to the added storage disk device if creation was successful. + */ + public DiskStorage addDiskStorageDevice() + { + return DiskStorage.class.cast( this.addDevice( new DiskStorage() ) ); + } + + /** + * Adds a virtual machine file system device to the Libvirt domain XML document. + * + * @return reference to the added file system device if creation was successful. + */ + public FileSystem addFileSystemDevice() + { + return FileSystem.class.cast( this.addDevice( new FileSystem() ) ); + } + + /** + * Adds a virtual machine hostdev device to the Libvirt domain XML document. + * + * @return reference to the added hostdev device if creation was successful. + */ + public Hostdev addHostdevDevice() + { + return Hostdev.class.cast( this.addDevice( new Hostdev() ) ); + } + + /** + * Adds a virtual machine mediated hostdev device to the Libvirt domain XML document. + * + * @return reference to the added mediated hostdev device if creation was successful. + */ + public HostdevMdev addHostdevMdevDevice() + { + return HostdevMdev.class.cast( this.addDevice( new HostdevMdev() ) ); + } + + /** + * Adds a virtual machine PCI hostdev device to the Libvirt domain XML document. + * + * @return reference to the added PCI hostdev device if creation was successful. + */ + public HostdevPci addHostdevPciDevice() + { + return HostdevPci.class.cast( this.addDevice( new HostdevPci() ) ); + } + + /** + * Adds a virtual machine USB hostdev device to the Libvirt domain XML document. + * + * @return reference to the added USB hostdev device if creation was successful. + */ + public HostdevUsb addHostdevUsbDevice() + { + return HostdevUsb.class.cast( this.addDevice( new HostdevUsb() ) ); + } + + /** + * Adds a virtual machine network device to the Libvirt domain XML document. + * + * @return reference to the added network device if creation was successful. + */ + public Interface addInterfaceDevice() + { + return Interface.class.cast( this.addDevice( new Interface() ) ); + } + + /** + * Adds a virtual machine network bridge interface device to the Libvirt domain XML document. + * + * @return reference to the added network interface device if creation was successful. + */ + public InterfaceBridge addInterfaceBridgeDevice() + { + return InterfaceBridge.class.cast( this.addDevice( new InterfaceBridge() ) ); + } + + /** + * Adds a virtual machine network interface device to the Libvirt domain XML document. + * + * @return reference to the added network interface device if creation was successful. + */ + public InterfaceNetwork addInterfaceNetworkDevice() + { + return InterfaceNetwork.class.cast( this.addDevice( new InterfaceNetwork() ) ); + } + + /** + * Adds a virtual machine graphics device to the Libvirt domain XML document. + * + * @return reference to the added graphics device if creation was successful. + */ + public Graphics addGraphicsDevice() + { + return Graphics.class.cast( this.addDevice( new Graphics() ) ); + } + + /** + * Adds a virtual machine SPICE graphics device to the Libvirt domain XML document. + * + * @return reference to the added SPICE graphics device if creation was successful. + */ + public GraphicsSpice addGraphicsSpiceDevice() + { + return GraphicsSpice.class.cast( this.addDevice( new GraphicsSpice() ) ); + } + + /** + * Adds a virtual machine VNC graphics device to the Libvirt domain XML document. + * + * @return reference to the added VNC graphics device if creation was successful. + */ + public GraphicsVnc addGraphicsVncDevice() + { + return GraphicsVnc.class.cast( this.addDevice( new GraphicsVnc() ) ); + } + + /** + * Adds a virtual machine parallel port device to the Libvirt domain XML document. + * + * @return reference to the added parallel port device if creation was successful. + */ + public Parallel addParallelDevice() + { + return Parallel.class.cast( this.addDevice( new Parallel() ) ); + } + + /** + * Adds a virtual machine serial port device to the Libvirt domain XML document. + * + * @return reference to the added serial port device if creation was successful. + */ + public Serial addSerialDevice() + { + return Serial.class.cast( this.addDevice( new Serial() ) ); + } + + /** + * Adds a virtual machine shared memory device to the Libvirt domain XML document. + * + * @return reference to the added shared memory device if creation was successful. + */ + public Shmem addShmemDevice() + { + return Shmem.class.cast( this.addDevice( new Shmem() ) ); + } + + /** + * Adds a virtual machine sound device to the Libvirt domain XML document. + * + * @return reference to the added sound device if creation was successful. + */ + public Sound addSoundDevice() + { + return Sound.class.cast( this.addDevice( new Sound() ) ); + } + + /** + * Adds a virtual machine video device to the Libvirt domain XML document. + * + * @return reference to the added video device if creation was successful. + */ + public Video addVideoDevice() + { + return Video.class.cast( this.addDevice( new Video() ) ); + } + + /** + * Adds an given value as QEMU command line argument to the Libvirt domain XML document. + * + * @param value QEMU command line argument value. + */ + public void addQemuCmdlnArgument( final String value ) + { + final Element rootElement = Element.class.cast( this.getRootXmlNode().getXmlBaseNode() ); + final Document xmlDocument = this.getRootXmlNode().getXmlDocument(); + final Element qemuCmdlnElement; + + final NodeList qemuCmdlnNodes = rootElement.getElementsByTagNameNS( XMLNS_QEMU_NS_URI, "commandline" ); + if ( qemuCmdlnNodes.getLength() < 1 ) { + // add missing <domain xmlns:qemu="..."> namespace attribute + rootElement.setAttributeNS( XMLConstants.XMLNS_ATTRIBUTE_NS_URI, + XMLConstants.XMLNS_ATTRIBUTE + ":" + XMLNS_QEMU_NS_PREFIX, XMLNS_QEMU_NS_URI ); + // add missing <qemu:commandline> element + qemuCmdlnElement = xmlDocument.createElementNS( XMLNS_QEMU_NS_URI, "commandline" ); + qemuCmdlnElement.setPrefix( XMLNS_QEMU_NS_PREFIX ); + rootElement.appendChild( qemuCmdlnElement ); + } else { + // use available <qemu:commandline> element + final Node qemuCmdlnNode = qemuCmdlnNodes.item( 0 ); + assert ( qemuCmdlnNode.getNodeType() == Node.ELEMENT_NODE ); + qemuCmdlnElement = Element.class.cast( qemuCmdlnNode ); + } + + // append <qemu:arg value='...'> element with attribute + final Element qemuCmdlnArgElement = xmlDocument.createElementNS( XMLNS_QEMU_NS_URI, "arg" ); + qemuCmdlnArgElement.setAttribute( "value", value ); + qemuCmdlnElement.appendChild( qemuCmdlnArgElement ); + } + + public void addGvtg( String optionalRomfile ) + { + final Element rootElement = Element.class.cast( this.getRootXmlNode().getXmlBaseNode() ); + final Document xmlDocument = this.getRootXmlNode().getXmlDocument(); + final Element qemuOverrideElement; + + final NodeList qemuCmdlnNodes = rootElement.getElementsByTagNameNS( XMLNS_QEMU_NS_URI, "override" ); + if ( qemuCmdlnNodes.getLength() < 1 ) { + // add missing <domain xmlns:qemu="..."> namespace attribute + rootElement.setAttributeNS( XMLConstants.XMLNS_ATTRIBUTE_NS_URI, + XMLConstants.XMLNS_ATTRIBUTE + ":" + XMLNS_QEMU_NS_PREFIX, XMLNS_QEMU_NS_URI ); + // add missing <qemu:override> element + qemuOverrideElement = xmlDocument.createElementNS( XMLNS_QEMU_NS_URI, "override" ); + qemuOverrideElement.setPrefix( XMLNS_QEMU_NS_PREFIX ); + rootElement.appendChild( qemuOverrideElement ); + } else { + // use available <qemu:override> element + final Node qemuOverrideNode = qemuCmdlnNodes.item( 0 ); + assert ( qemuOverrideNode.getNodeType() == Node.ELEMENT_NODE ); + qemuOverrideElement = Element.class.cast( qemuOverrideNode ); + } + + // Get device subnode + Element qemuDeviceElement = XmlHelper.getOrCreateElement( xmlDocument, qemuOverrideElement, + XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "device", "alias", "hostdev0" ); + // + Element qemuFrontendElement = XmlHelper.getOrCreateElement( xmlDocument, qemuDeviceElement, + XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "frontend", null, null ); + // Properties + Element prop; + prop = XmlHelper.getOrCreateElement( xmlDocument, qemuFrontendElement, + XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "property", "name", "x-igd-opregion" ); + prop.setAttribute( "type", "bool" ); + prop.setAttribute( "value", "true" ); + prop = XmlHelper.getOrCreateElement( xmlDocument, qemuFrontendElement, + XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "property", "name", "driver" ); + prop.setAttribute( "type", "string" ); + prop.setAttribute( "value", "vfio-pci-nohotplug" ); + prop = XmlHelper.getOrCreateElement( xmlDocument, qemuFrontendElement, + XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "property", "name", "ramfb" ); + prop.setAttribute( "type", "bool" ); + prop.setAttribute( "value", "true" ); + if ( optionalRomfile != null ) { + prop = XmlHelper.getOrCreateElement( xmlDocument, qemuFrontendElement, + XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "property", "name", "romfile" ); + prop.setAttribute( "type", "string" ); + prop.setAttribute( "value", optionalRomfile ); + } + } + + /** + * Removes boot oder entries in the Libvirt domain XML document. + */ + public void removeBootOrder() + { + // remove boot order entries of all disk devices + for ( Disk diskDevice : this.getDiskDevices() ) { + diskDevice.removeBootOrder(); + } + + // remove boot order entries of all network interface devices + for ( Interface interfaceDevice : this.getInterfaceDevices() ) { + interfaceDevice.removeBootOrder(); + } + + // remove boot order entries of all hostdev devices + for ( Hostdev hostdevDevice : this.getHostdevDevices() ) { + hostdevDevice.removeBootOrder(); + } + + // remove boot oder entries under the 'os' element + this.getRootXmlNode().removeXmlElement( "os/boot" ); + } + + /** + * Removes underlying source for all disk devices in the Libvirt domain XML document. + * + * @implNote Calling this method will result in an invalid Libvirt domain XML document. + */ + public void removeDiskDevicesStorage() + { + for ( Disk diskDevice : this.getDiskDevices() ) { + diskDevice.removeStorage(); + } + } + + /** + * Removes specified Nvram file in the Libvirt domain XML document. + */ + public void removeOsNvram() + { + final Node nvramElement = this.getRootXmlNode().getXmlElement( "os/nvram" ); + + if ( nvramElement != null ) { + nvramElement.getParentNode().removeChild( nvramElement ); + } + } + + /** + * Removes network source for all interface devices in the Libvirt domain XML document. + */ + public void removeInterfaceDevicesSource() + { + for ( Interface interfaceDevice : this.getInterfaceDevices() ) { + // set empty source to preserve the XML attribute (to prevent XML validation errors) + interfaceDevice.setSource( "" ); + } + } + + /** + * Remove any existing CPU pinning and numa config + */ + public void resetCpuPin() + { + this.getRootXmlNode().removeXmlElement( "cputune" ); + this.getRootXmlNode().removeXmlElement( "numatune" ); + } + + public void addCpuPin( int virtualCore, int hostCore ) + { + final Element rootElement = Element.class.cast( this.getRootXmlNode().getXmlBaseNode() ); + final Document xmlDocument = this.getRootXmlNode().getXmlDocument(); + Node cpuTune = this.getRootXmlNode().getXmlElement( "cputune" ); + if ( cpuTune == null ) { + cpuTune = xmlDocument.createElement( "cputune" ); + rootElement.appendChild( cpuTune ); + } + Element pin = xmlDocument.createElement( "vcpupin" ); + pin.setAttribute( "vcpu", Integer.toString( virtualCore ) ); + pin.setAttribute( "cpuset", Integer.toString( hostCore ) ); + cpuTune.appendChild( pin ); + Node vcpuNode = this.getRootXmlNode().getXmlElement( "vcpu" ); + if ( vcpuNode instanceof Element ) { + ( (Element)vcpuNode ).setAttribute( "placement", "static" ); + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/DomainUtils.java b/src/main/java/org/openslx/libvirt/domain/DomainUtils.java new file mode 100644 index 0000000..2462371 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/DomainUtils.java @@ -0,0 +1,118 @@ +package org.openslx.libvirt.domain; + +import java.math.BigInteger; + +/** + * Collection of helper functions to maintain a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public final class DomainUtils +{ + + /** + * Converts memory value with specified SI unit to absolute value in bytes. + * + * @param value amount of memory in specified SI unit. + * @param unit SI unit name, one of: bytes, KB, k, KiB, MB, M, MiB, GB, G, GiB, TB, T, TiB, for + * <code>value</code>. + * @return absolute amount of memory in bytes. + */ + public static BigInteger decodeMemory( String value, String unit ) + { + BigInteger factor = null; + BigInteger result = new BigInteger( value ); + + switch ( unit ) { + case "b": + case "bytes": + factor = new BigInteger( "1" ); + break; + case "KB": + factor = new BigInteger( "1000" ); + break; + case "k": + case "KiB": + factor = new BigInteger( "1024" ); + break; + case "MB": + factor = new BigInteger( "1000000" ); + break; + case "M": + case "MiB": + factor = new BigInteger( "1048576" ); + break; + case "GB": + factor = new BigInteger( "1000000000" ); + break; + case "G": + case "GiB": + factor = new BigInteger( "1073741824" ); + break; + case "TB": + factor = new BigInteger( "1000000000000" ); + break; + case "T": + case "TiB": + factor = new BigInteger( "1099511627776" ); + break; + default: + return null; + } + + return result.multiply( factor ); + } + + /** + * Convert memory from absolute value in bytes to value in specified SI unit. + * + * @param value absolute amount of memory in bytes. + * @param unit SI unit name, one of: bytes, KB, k, KiB, MB, M, MiB, GB, G, GiB, TB, T, TiB for + * returned memory value. + * @return amount of memory in specified SI unit. + */ + public static String encodeMemory( BigInteger value, String unit ) + { + BigInteger dividend = null; + + switch ( unit ) { + case "b": + case "bytes": + dividend = new BigInteger( "1" ); + break; + case "KB": + dividend = new BigInteger( "1000" ); + break; + case "k": + case "KiB": + dividend = new BigInteger( "1024" ); + break; + case "MB": + dividend = new BigInteger( "1000000" ); + break; + case "M": + case "MiB": + dividend = new BigInteger( "1048576" ); + break; + case "GB": + dividend = new BigInteger( "1000000000" ); + break; + case "G": + case "GiB": + dividend = new BigInteger( "1073741824" ); + break; + case "TB": + dividend = new BigInteger( "1000000000000" ); + break; + case "T": + case "TiB": + dividend = new BigInteger( "1099511627776" ); + break; + default: + return null; + } + + return value.divide( dividend ).toString(); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/Controller.java b/src/main/java/org/openslx/libvirt/domain/device/Controller.java new file mode 100644 index 0000000..626462b --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/Controller.java @@ -0,0 +1,181 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A controller (PCI, USB, ...) device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Controller extends Device +{ + /** + * Creates an empty controller device. + */ + public Controller() + { + super(); + } + + /** + * Creates a controller device representing an existing Libvirt XML controller device element. + * + * @param xmlNode existing Libvirt XML controller device element. + */ + public Controller( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns index of the controller. + * + * @return index of the controller. + */ + public int getIndex() + { + String index = this.getXmlElementAttributeValue( "index" ); + return Integer.parseInt( index ); + } + + /** + * Sets index for the controller. + * + * @param index index for the controller. + */ + public void setIndex( int index ) + { + this.setXmlElementAttributeValue( "index", Integer.toString( index ) ); + } + + /** + * Creates a non-existent controller device as Libvirt XML device element. + * + * @param controller controller device that is created. + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created controller device instance. + */ + public static Controller createInstance( Controller controller, LibvirtXmlNode xmlNode ) + { + Controller addedController = null; + + if ( controller instanceof ControllerFloppy ) { + xmlNode.setXmlElementAttributeValue( "type", Type.FLOPPY.toString() ); + addedController = ControllerFloppy.createInstance( xmlNode ); + } else if ( controller instanceof ControllerIde ) { + xmlNode.setXmlElementAttributeValue( "type", Type.IDE.toString() ); + addedController = ControllerIde.createInstance( xmlNode ); + } else if ( controller instanceof ControllerPci ) { + xmlNode.setXmlElementAttributeValue( "type", Type.PCI.toString() ); + addedController = ControllerPci.createInstance( xmlNode ); + } else if ( controller instanceof ControllerSata ) { + xmlNode.setXmlElementAttributeValue( "type", Type.SATA.toString() ); + addedController = ControllerSata.createInstance( xmlNode ); + } else if ( controller instanceof ControllerScsi ) { + xmlNode.setXmlElementAttributeValue( "type", Type.SCSI.toString() ); + addedController = ControllerScsi.createInstance( xmlNode ); + } else if ( controller instanceof ControllerUsb ) { + xmlNode.setXmlElementAttributeValue( "type", Type.USB.toString() ); + addedController = ControllerUsb.createInstance( xmlNode ); + } + + return addedController; + } + + /** + * Creates a controller device representing an existing Libvirt XML controller device element. + * + * @param xmlNode existing Libvirt XML controller device element. + * @return controller device instance. + */ + public static Controller newInstance( LibvirtXmlNode xmlNode ) + { + + Controller deviceController = null; + Type type = Type.fromString( xmlNode.getXmlElementAttributeValue( "type" ) ); + + if ( type == null ) { + return null; + } + + switch ( type ) { + case FLOPPY: + deviceController = ControllerFloppy.newInstance( xmlNode ); + break; + case IDE: + deviceController = ControllerIde.newInstance( xmlNode ); + break; + case PCI: + deviceController = ControllerPci.newInstance( xmlNode ); + break; + case SATA: + deviceController = ControllerSata.newInstance( xmlNode ); + break; + case SCSI: + deviceController = ControllerScsi.newInstance( xmlNode ); + break; + case USB: + deviceController = ControllerUsb.newInstance( xmlNode ); + break; + } + + return deviceController; + } + + /** + * Type of controller device. + * + * @author Manuel Bentele + * @version 1.0 + */ + enum Type + { + // @formatter:off + FLOPPY( "fdc" ), + IDE ( "ide" ), + PCI ( "pci" ), + SATA ( "sata" ), + SCSI ( "scsi" ), + USB ( "usb" ); + // @formatter:on + + /** + * Name of the controller device type. + */ + private String type = null; + + /** + * Creates controller device type. + * + * @param type valid name of the controller device type in a Libvirt domain XML document. + */ + Type( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates controller device type from its name with error check. + * + * @param type name of the controller device type in a Libvirt domain XML document. + * @return valid controller device type. + */ + public static Type fromString( String type ) + { + for ( Type t : Type.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerFloppy.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerFloppy.java new file mode 100644 index 0000000..5e580bd --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerFloppy.java @@ -0,0 +1,54 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A floppy controller device in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class ControllerFloppy extends Controller +{ + /** + * Creates an empty floppy controller device. + */ + public ControllerFloppy() + { + super(); + } + + /** + * Creates a floppy controller device representing an existing Libvirt XML floppy controller + * device element. + * + * @param xmlNode existing Libvirt XML controller device element. + */ + public ControllerFloppy( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Creates a non-existent floppy controller device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created floppy controller device instance. + */ + public static ControllerFloppy createInstance( LibvirtXmlNode xmlNode ) + { + return ControllerFloppy.newInstance( xmlNode ); + } + + /** + * Creates a floppy controller device representing an existing Libvirt XML floppy controller + * device element. + * + * @param xmlNode existing Libvirt XML controller device element. + * @return floppy controller device instance. + */ + public static ControllerFloppy newInstance( LibvirtXmlNode xmlNode ) + { + return new ControllerFloppy( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerIde.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerIde.java new file mode 100644 index 0000000..062b67d --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerIde.java @@ -0,0 +1,128 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * An IDE controller device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class ControllerIde extends Controller +{ + /** + * Creates an empty IDE controller device. + */ + public ControllerIde() + { + super(); + } + + /** + * Creates an IDE controller device representing an existing Libvirt XML IDE controller device + * element. + * + * @param xmlNode existing Libvirt XML IDE controller device element. + */ + public ControllerIde( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns emulated hardware model of the IDE controller. + * + * @return hardware model of the IDE controller. + */ + public Model getModel() + { + String model = this.getXmlElementAttributeValue( "model" ); + return Model.fromString( model ); + } + + /** + * Sets hardware model for the IDE controller. + * + * @param model hardware model for the IDE controller. + */ + public void setModel( Model model ) + { + this.setXmlElementAttributeValue( "model", model.toString() ); + } + + /** + * Creates a non-existent IDE controller device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created IDE controller device instance. + */ + public static ControllerIde createInstance( LibvirtXmlNode xmlNode ) + { + return ControllerIde.newInstance( xmlNode ); + } + + /** + * Creates an IDE controller device representing an existing Libvirt XML IDE controller device + * element. + * + * @param xmlNode existing Libvirt XML IDE controller device element. + * @return IDE controller device instance. + */ + public static ControllerIde newInstance( LibvirtXmlNode xmlNode ) + { + return new ControllerIde( xmlNode ); + } + + /** + * Model of IDE controller device. + * + * @author Manuel Bentele + * @version 1.0 + */ + enum Model + { + // @formatter:off + PIIX3( "piix3" ), + PIIX4( "pixx4" ), + ICH6 ( "ich6" ); + // @formatter:on + + /** + * Name of the IDE controller device model. + */ + private String model = null; + + /** + * Creates IDE controller device model. + * + * @param type valid name of the IDE controller device model in a Libvirt domain XML document. + */ + Model( String model ) + { + this.model = model; + } + + @Override + public String toString() + { + return this.model; + } + + /** + * Creates IDE controller device model from its name with error check. + * + * @param type name of the IDE controller device model in a Libvirt domain XML document. + * @return valid IDE controller device model. + */ + public static Model fromString( String model ) + { + for ( Model t : Model.values() ) { + if ( t.model.equalsIgnoreCase( model ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerPci.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerPci.java new file mode 100644 index 0000000..feb8b1a --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerPci.java @@ -0,0 +1,145 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A PCI controller device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class ControllerPci extends Controller +{ + /** + * Creates an empty PCI controller device. + */ + public ControllerPci() + { + super(); + } + + /** + * Creates a PCI controller device representing an existing Libvirt XML PCI controller device + * element. + * + * @param xmlNode existing Libvirt XML PCI controller device element. + */ + public ControllerPci( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns model of the PCI controller. + * + * @return model of the PCI controller. + */ + public Model getModel() + { + String model = this.getXmlElementAttributeValue( "model" ); + return Model.fromString( model ); + } + + /** + * Sets model for the PCI controller. + * + * @param model model for the PCI controller. + */ + public void setModel( Model model ) + { + this.setXmlElementAttributeValue( "model", model.toString() ); + } + + /** + * Returns emulated hardware model of the PCI controller. + * + * @return emulated hardware model of the PCI controller. + */ + public String getModelEmulated() + { + return this.getXmlElementAttributeValue( "model", "name" ); + } + + /** + * Creates a non-existent PCI controller device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created PCI controller device instance. + */ + public static ControllerPci createInstance( LibvirtXmlNode xmlNode ) + { + return ControllerPci.newInstance( xmlNode ); + } + + /** + * Creates a PCI controller device representing an existing Libvirt XML PCI controller device + * element. + * + * @param xmlNode existing Libvirt XML PCI controller device element. + * @return PCI controller device instance. + */ + public static ControllerPci newInstance( LibvirtXmlNode xmlNode ) + { + return new ControllerPci( xmlNode ); + } + + /** + * Model of PCI controller device. + * + * @author Manuel Bentele + * @version 1.0 + */ + enum Model + { + // @formatter:off + PCI_ROOT ( "pci-root" ), + PCI_BRDIGE ( "pci-bridge" ), + PCIE_ROOT ( "pcie-root" ), + PCI_DMI2BRIDGE ( "dmi-to-pci-bridge" ), + PCIE_ROOT_PORT ( "pcie-root-port" ), + PCIE_SWITCH_UPSTREAM_PORT ( "pcie-switch-upstream-port" ), + PCIE_SWITCH_DOWNSTREAM_PORT( "pcie-switch-downstream-port" ), + PCI_EXPANDER_BUS ( "pci-expander-bus" ), + PCIE_EXPANDER_BUS ( "pcie-expander-bus" ), + PCIE2PCI_BRIDGE ( "pcie-to-pci-bridge" ); + // @formatter:on + + /** + * Name of the PCI controller device model. + */ + private String model = null; + + /** + * Creates PCI controller device model. + * + * @param type valid name of the PCI controller device model in a Libvirt domain XML document. + */ + Model( String model ) + { + this.model = model; + } + + @Override + public String toString() + { + return this.model; + } + + /** + * Creates PCI controller device model from its name with error check. + * + * @param type name of the PCI controller device model in a Libvirt domain XML document. + * @return valid PCI controller device model. + */ + public static Model fromString( String model ) + { + for ( Model t : Model.values() ) { + if ( t.model.equalsIgnoreCase( model ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerSata.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerSata.java new file mode 100644 index 0000000..b784ae0 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerSata.java @@ -0,0 +1,54 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A SATA controller device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class ControllerSata extends Controller +{ + /** + * Creates an empty SATA controller device. + */ + public ControllerSata() + { + super(); + } + + /** + * Creates a SATA controller device representing an existing Libvirt XML SATA controller device + * element. + * + * @param xmlNode existing Libvirt XML SATA controller device element. + */ + public ControllerSata( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Creates a non-existent SATA controller device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created SATA controller device instance. + */ + public static ControllerSata createInstance( LibvirtXmlNode xmlNode ) + { + return ControllerSata.newInstance( xmlNode ); + } + + /** + * Creates a SATA controller device representing an existing Libvirt XML SATA controller device + * element. + * + * @param xmlNode existing Libvirt XML SATA controller device element. + * @return SATA controller device instance. + */ + public static ControllerSata newInstance( LibvirtXmlNode xmlNode ) + { + return new ControllerSata( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerScsi.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerScsi.java new file mode 100644 index 0000000..16c3a0f --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerScsi.java @@ -0,0 +1,138 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A SCSI controller device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class ControllerScsi extends Controller +{ + /** + * Creates an empty SCSI controller device. + */ + public ControllerScsi() + { + super(); + } + + /** + * Creates a SCSI controller device representing an existing Libvirt XML SCSI controller device + * element. + * + * @param xmlNode existing Libvirt XML SCSI controller device element. + */ + public ControllerScsi( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns hardware model of the PCI controller. + * + * @return hardware model of the PCI controller. + */ + public Model getModel() + { + String model = this.getXmlElementAttributeValue( "model" ); + return Model.fromString( model ); + } + + /** + * Sets hardware model for the PCI controller. + * + * @param model hardware model for the PCI controller. + */ + public void setModel( Model model ) + { + this.setXmlElementAttributeValue( "model", model.toString() ); + } + + /** + * Creates a non-existent SCSI controller device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created SCSI controller device instance. + */ + public static ControllerScsi createInstance( LibvirtXmlNode xmlNode ) + { + return ControllerScsi.newInstance( xmlNode ); + } + + /** + * Creates a SCSI controller device representing an existing Libvirt XML SCSI controller device + * element. + * + * @param xmlNode existing Libvirt XML SCSI controller device element. + * @return SCSI controller device instance. + */ + public static ControllerScsi newInstance( LibvirtXmlNode xmlNode ) + { + return new ControllerScsi( xmlNode ); + } + + /** + * Model of SCSI controller device. + * + * @author Manuel Bentele + * @version 1.0 + */ + enum Model + { + // @formatter:off + AUTO ( "auto" ), + BUSLOGIC ( "buslogic" ), + IBMVSCSI ( "ibmvscsi" ), + LSISAS1068 ( "lsisas1068" ), + LSISAS1078 ( "lsisas1078" ), + VIRTIO_SCSI ( "virtio-scsi" ), + VMPVSCSI ( "vmpvscsi" ), + VIRTIO_TRANSITIONAL ( "virtio-transitional" ), + VIRTIO_NON_TRANSITIONAL( "virtio-non-transitional" ), + NCR53C90 ( "ncr53c90" ), + AM53C974 ( "am53c974" ), + DC390 ( "dc390" ); + // @formatter:on + + /** + * Name of the SCSI controller device model. + */ + private String model = null; + + /** + * Creates SCSI controller device model. + * + * @param type valid name of the SCSI controller device model in a Libvirt domain XML + * document. + */ + Model( String model ) + { + this.model = model; + } + + @Override + public String toString() + { + return this.model; + } + + /** + * Creates SCSI controller device model from its name with error check. + * + * @param type name of the SCSI controller device model in a Libvirt domain XML document. + * @return valid SCSI controller device model. + */ + public static Model fromString( String model ) + { + for ( Model t : Model.values() ) { + if ( t.model.equalsIgnoreCase( model ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerUsb.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerUsb.java new file mode 100644 index 0000000..1798027 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerUsb.java @@ -0,0 +1,139 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A USB controller device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class ControllerUsb extends Controller +{ + /** + * Creates an empty USB controller device. + */ + public ControllerUsb() + { + super(); + } + + /** + * Creates an USB controller device representing an existing Libvirt XML USB controller device + * element. + * + * @param xmlNode existing Libvirt XML USB controller device element. + */ + public ControllerUsb( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns hardware model of the PCI controller. + * + * @return hardware model of the PCI controller. + */ + public Model getModel() + { + String model = this.getXmlElementAttributeValue( "model" ); + return Model.fromString( model ); + } + + /** + * Sets hardware model for the PCI controller. + * + * @param model hardware model for the PCI controller. + */ + public void setModel( Model model ) + { + this.setXmlElementAttributeValue( "model", model.toString() ); + } + + /** + * Creates a non-existent USB controller device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created USB controller device instance. + */ + public static ControllerUsb createInstance( LibvirtXmlNode xmlNode ) + { + return ControllerUsb.newInstance( xmlNode ); + } + + /** + * Creates an USB controller device representing an existing Libvirt XML USB controller device + * element. + * + * @param xmlNode existing Libvirt XML USB controller device element. + * @return USB controller device instance. + */ + public static ControllerUsb newInstance( LibvirtXmlNode xmlNode ) + { + return new ControllerUsb( xmlNode ); + } + + /** + * Model of PCI controller device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum Model + { + // @formatter:off + NONE ( "none" ), + PIIX3_UHCI ( "piix3-uhci" ), + PIIX4_UHCI ( "piix4-uhci" ), + EHCI ( "ehci" ), + ICH9_EHCI1 ( "ich9-ehci1" ), + ICH9_UHCI1 ( "ich9-uhci1" ), + ICH9_UHCI2 ( "ich9-uhci2" ), + ICH9_UHCI3 ( "ich9-uhci3" ), + VT82C686B_UHCI( "vt82c686b-uhci" ), + PCI_OHCI ( "pci-ohci" ), + NEC_XHCI ( "nec-xhci" ), + QUSB1 ( "qusb1" ), + QUSB2 ( "qusb2" ), + QEMU_XHCI ( "qemu-xhci" ); + // @formatter:on + + /** + * Name of the USB controller device model. + */ + private String model = null; + + /** + * Creates USB controller device model. + * + * @param type valid name of the USB controller device model in a Libvirt domain XML document. + */ + Model( String model ) + { + this.model = model; + } + + @Override + public String toString() + { + return this.model; + } + + /** + * Creates USB controller device model from its name with error check. + * + * @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 ) + { + for ( Model t : Model.values() ) { + if ( t.model.equalsIgnoreCase( model ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/Device.java b/src/main/java/org/openslx/libvirt/domain/device/Device.java new file mode 100644 index 0000000..31a54ca --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/Device.java @@ -0,0 +1,290 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * A virtual machines device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Device extends LibvirtXmlNode implements HostdevAddressableTarget<HostdevPciDeviceAddress> +{ + /** + * Creates an empty virtual machine device. + */ + public Device() + { + super(); + } + + /** + * Creates a virtual machine device representing an existing Libvirt XML device element. + * + * @param xmlNode existing Libvirt XML device element. + */ + public Device( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Removes device from Libvirt domain XML document. + */ + public void remove() + { + Node node = this.getXmlElement(); + node.getParentNode().removeChild( node ); + } + + /** + * Creates a Libvirt XML device element as child of a given Libvirt XML parent node. + * + * @param xmlParentNode parent Libvirt XML node of the Libvirt XML device element that is + * created. + * @param deviceType type of the Libvirt XML device element. + * @return created Libvirt XML device node. + */ + private static LibvirtXmlNode createDeviceElement( LibvirtXmlNode xmlParentNode, Type deviceType ) + { + // create XML element as part of the Libvirt XML document + Document xmlDocument = xmlParentNode.getXmlDocument(); + Element deviceNode = xmlDocument.createElement( deviceType.toString() ); + + // append the created XML element to the Libvirt XML document + xmlParentNode.getXmlBaseNode().appendChild( deviceNode ); + + return new LibvirtXmlNode( xmlParentNode.getXmlDocument(), deviceNode ); + } + + /** + * Creates a non-existent virtual machine device as Libvirt XML device element. + * + * @param device virtual machine device that is created. + * @param xmlParentNode parent Libvirt XML node of the Libvirt XML device that is created. + * @return created virtual machine device instance. + */ + public static Device createInstance( Device device, LibvirtXmlNode xmlParentNode ) + { + Device createdDevice = null; + + if ( device instanceof Controller ) { + LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.CONTROLLER ); + createdDevice = Controller.createInstance( Controller.class.cast( device ), xmlNode ); + } else if ( device instanceof Disk ) { + LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.DISK ); + createdDevice = Disk.createInstance( Disk.class.cast( device ), xmlNode ); + } else if ( device instanceof FileSystem ) { + LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.FILESYSTEM ); + createdDevice = FileSystem.createInstance( xmlNode ); + } else if ( device instanceof Hostdev ) { + LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.HOSTDEV ); + createdDevice = Hostdev.createInstance( Hostdev.class.cast( device ), xmlNode ); + } else if ( device instanceof Interface ) { + LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.INTERFACE ); + createdDevice = Interface.createInstance( Interface.class.cast( device ), xmlNode ); + } else if ( device instanceof Graphics ) { + LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.GRAPHICS ); + createdDevice = Graphics.createInstance( Graphics.class.cast( device ), xmlNode ); + } else if ( device instanceof Parallel ) { + LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.PARALLEL ); + createdDevice = Parallel.createInstance( xmlNode ); + } else if ( device instanceof Serial ) { + LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.SERIAL ); + createdDevice = Serial.createInstance( xmlNode ); + } else if ( device instanceof Shmem ) { + LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.SHMEM ); + createdDevice = Shmem.createInstance( xmlNode ); + } else if ( device instanceof Sound ) { + LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.SOUND ); + createdDevice = Sound.createInstance( xmlNode ); + } else if ( device instanceof Video ) { + LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.VIDEO ); + createdDevice = Video.createInstance( xmlNode ); + } + + return createdDevice; + } + + /** + * Creates a virtual machine device representing an existing Libvirt XML device element. + * + * @param xmlNode existing Libvirt XML device element. + * @return virtual machine device instance. + */ + public static Device newInstance( LibvirtXmlNode xmlNode ) + { + + Node element = xmlNode.getXmlElement(); + + if ( element == null ) { + return null; + } else { + Device device = null; + Type type = Type.fromString( element.getNodeName() ); + + if ( type == null ) { + return null; + } + + switch ( type ) { + case CONTROLLER: + device = Controller.newInstance( xmlNode ); + break; + case DISK: + device = Disk.newInstance( xmlNode ); + break; + case FILESYSTEM: + device = FileSystem.newInstance( xmlNode ); + break; + case HOSTDEV: + device = Hostdev.newInstance( xmlNode ); + break; + case INTERFACE: + device = Interface.newInstance( xmlNode ); + break; + case GRAPHICS: + device = Graphics.newInstance( xmlNode ); + break; + case PARALLEL: + device = Parallel.newInstance( xmlNode ); + break; + case SERIAL: + device = Serial.newInstance( xmlNode ); + break; + case SHMEM: + device = Shmem.newInstance( xmlNode ); + break; + case SOUND: + device = Sound.newInstance( xmlNode ); + break; + case VIDEO: + device = Video.newInstance( xmlNode ); + break; + } + + return device; + } + } + + /** + * Sets the PCI device address for an XML address element selected by a XPath expression. + * + * @param expression XPath expression to select the XML address element. + * @param address PCI device address for the selected XML address element. + */ + protected void setPciAddress( final String expression, final HostdevPciDeviceAddress address ) + { + final String pciDomain = HostdevUtils.appendHexPrefix( address.getPciDomainAsString() ); + final String pciBus = HostdevUtils.appendHexPrefix( address.getPciBusAsString() ); + final String pciDevice = HostdevUtils.appendHexPrefix( address.getPciDeviceAsString() ); + final String pciFunction = HostdevUtils.appendHexPrefix( address.getPciFunctionAsString() ); + + this.setXmlElementAttributeValue( expression, "domain", pciDomain ); + this.setXmlElementAttributeValue( expression, "bus", pciBus ); + this.setXmlElementAttributeValue( expression, "slot", pciDevice ); + this.setXmlElementAttributeValue( expression, "function", pciFunction ); + } + + /** + * Returns the PCI device address from an address XML element selected by a XPath expression. + * + * @param expression XPath expression to select the XML address element. + * @return PCI device address from the selected XML address element. + */ + protected HostdevPciDeviceAddress getPciAddress( final String expression ) + { + String pciDomain = this.getXmlElementAttributeValue( expression, "domain" ); + String pciBus = this.getXmlElementAttributeValue( expression, "bus" ); + String pciDevice = this.getXmlElementAttributeValue( expression, "slot" ); + String pciFunction = this.getXmlElementAttributeValue( expression, "function" ); + + pciDomain = HostdevUtils.removeHexPrefix( pciDomain ); + pciBus = HostdevUtils.removeHexPrefix( pciBus ); + pciDevice = HostdevUtils.removeHexPrefix( pciDevice ); + pciFunction = HostdevUtils.removeHexPrefix( pciFunction ); + + return HostdevPciDeviceAddress.valueOf( pciDomain + ":" + pciBus + ":" + pciDevice + "." + pciFunction ); + } + + /** + * Returns this devices PCI bus address, or null if it doesn't have an explicit one + * set, or if the address type isn't PCI. + */ + public HostdevPciDeviceAddress getPciTarget() + { + if ( !"pci".equals( this.getXmlElementAttributeValue( "address", "type" ) ) ) + return null; + return this.getPciAddress( "address" ); + } + + public void setPciTarget( HostdevPciDeviceAddress address ) + { + this.setPciAddress( "address", address ); + this.setXmlElementAttributeValue( "address", "type", "pci" ); + } + + /** + * Type of virtual machine devices. + * + * @author Manuel Bentele + * @version 1.0 + */ + enum Type + { + // @formatter:off + CONTROLLER( "controller" ), + DISK ( "disk" ), + FILESYSTEM( "filesystem" ), + HOSTDEV ( "hostdev" ), + INTERFACE ( "interface" ), + GRAPHICS ( "graphics" ), + PARALLEL ( "parallel" ), + SERIAL ( "serial" ), + SHMEM ( "shmem" ), + SOUND ( "sound" ), + VIDEO ( "video" ); + // @formatter:on + + /** + * Name of the virtual machine device type. + */ + private String type = null; + + /** + * Creates virtual machine device type. + * + * @param type valid name of the virtual machine device type in a Libvirt domain XML document. + */ + Type( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates virtual machine device type from its name with error check. + * + * @param type name of the virtual machine device type in a Libvirt domain XML document. + * @return valid virtual machine device type. + */ + public static Type fromString( String type ) + { + for ( Type t : Type.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/Disk.java b/src/main/java/org/openslx/libvirt/domain/device/Disk.java new file mode 100644 index 0000000..7694538 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/Disk.java @@ -0,0 +1,427 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; +import org.w3c.dom.Node; + +/** + * A disk (floppy, CDROM, ...) device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Disk extends Device +{ + /** + * Creates an empty disk device. + */ + public Disk() + { + super(); + } + + /** + * Creates a disk device representing an existing Libvirt XML disk device element. + * + * @param xmlNode existing Libvirt XML disk device element. + */ + public Disk( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns storage type of the disk device. + * + * @return storage type of underlying source for the disk device. + */ + public StorageType getStorageType() + { + String storageType = this.getXmlElementAttributeValue( "type" ); + return StorageType.fromString( storageType ); + } + + /** + * Sets storage type for the disk device. + * + * @param storageType storage type of underlying source for the disk device. + * + * @implNote Please call {@link #setStorageSource(String)} after calling this method, otherwise + * the underlying source for the disk device may be invalid. + */ + protected void setStorageType( StorageType storageType ) + { + this.setXmlElementAttributeValue( "type", storageType.toString() ); + } + + /** + * Returns underlying source of disk device. + * + * @return file path to underlying source of disk device. + */ + public String getStorageSource() + { + StorageType storageType = this.getStorageType(); + String storageSource = null; + + switch ( storageType ) { + case FILE: + storageSource = this.getXmlElementAttributeValue( "source", "file" ); + break; + case BLOCK: + storageSource = this.getXmlElementAttributeValue( "source", "dev" ); + break; + } + + return storageSource; + } + + /** + * Sets underlying source for disk device. + * + * @param source file path to underlying source for disk device. + * + * @implNote Please call {@link #setStorageType(StorageType)} before calling this method, + * otherwise the underlying source for the disk device is not set. + */ + protected void setStorageSource( String source ) + { + StorageType storageType = this.getStorageType(); + + // remove all attributes from sub-element 'source' + this.removeXmlElementAttributes( "source" ); + + // rewrite specific attribute depending on the storage type + switch ( storageType ) { + case FILE: + this.setXmlElementAttributeValue( "source", "file", source ); + break; + case BLOCK: + this.setXmlElementAttributeValue( "source", "dev", source ); + break; + } + } + + /** + * Sets storage type and underlying source for disk device. + * + * @param storageType storage type of underlying source for the disk device. + * @param source file path to underlying source for disk device. + */ + public void setStorage( StorageType storageType, String source ) + { + this.setStorageType( storageType ); + this.setStorageSource( source ); + } + + /** + * Removes underlying source of the disk device. + * + * @implNote Calling this method will result in an invalid Libvirt domain XML content. + */ + public void removeStorage() + { + this.removeXmlElement( "source" ); + } + + /** + * Removes boot oder entry of the disk device. + */ + public void removeBootOrder() + { + this.removeXmlElement( "boot" ); + } + + /** + * Returns read only state of disk device. + * + * @return read only state of disk device. + */ + public boolean isReadOnly() + { + Node readOnly = this.getXmlElement( "readonly" ); + + if ( readOnly == null ) { + return false; + } else { + return true; + } + } + + /** + * Sets read only state for disk device. + * + * @param readOnly state for disk device and its read only functionality. + */ + public void setReadOnly( boolean readOnly ) + { + if ( readOnly ) { + this.setXmlElement( "readonly" ); + } else { + this.removeXmlElement( "readonly" ); + } + } + + /** + * Returns bus type of the disk device. + * + * @return bus type of the disk device. + */ + public BusType getBusType() + { + String busType = this.getXmlElementAttributeValue( "target", "bus" ); + return BusType.fromString( busType ); + } + + /** + * Sets bus type for the disk device. + * + * @param busType bus type for the disk device. + */ + public void setBusType( BusType busType ) + { + this.setXmlElementAttributeValue( "target", "bus", busType.toString() ); + } + + /** + * Returns target device of the disk device. + * + * @return target device of the disk device. + */ + public String getTargetDevice() + { + return this.getXmlElementAttributeValue( "target", "dev" ); + } + + /** + * Sets target device for the disk device. + * + * @param targetDevice target device for the disk device. + */ + public void setTargetDevice( String targetDevice ) + { + this.setXmlElementAttributeValue( "target", "dev", targetDevice ); + } + + /** + * Creates a non-existent disk device as Libvirt XML device element. + * + * @param disk disk device that is created. + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created disk device instance. + */ + public static Disk createInstance( Disk disk, LibvirtXmlNode xmlNode ) + { + Disk addedDisk = null; + + if ( disk instanceof DiskCdrom ) { + xmlNode.setXmlElementAttributeValue( "device", Type.CDROM.toString() ); + addedDisk = DiskCdrom.createInstance( xmlNode ); + } else if ( disk instanceof DiskFloppy ) { + xmlNode.setXmlElementAttributeValue( "device", Type.FLOPPY.toString() ); + addedDisk = DiskFloppy.createInstance( xmlNode ); + } else if ( disk instanceof DiskStorage ) { + xmlNode.setXmlElementAttributeValue( "device", Type.STORAGE.toString() ); + addedDisk = DiskStorage.createInstance( xmlNode ); + } + + return addedDisk; + } + + /** + * Creates a disk device representing an existing Libvirt XML disk device element. + * + * @param xmlNode existing Libvirt XML disk device element. + * @return disk device instance. + */ + public static Disk newInstance( LibvirtXmlNode xmlNode ) + { + Disk deviceDisk = null; + Type type = Type.fromString( xmlNode.getXmlElementAttributeValue( "device" ) ); + + if ( type == null ) { + return null; + } + + switch ( type ) { + case CDROM: + deviceDisk = DiskCdrom.newInstance( xmlNode ); + break; + case FLOPPY: + deviceDisk = DiskFloppy.newInstance( xmlNode ); + break; + case STORAGE: + deviceDisk = DiskStorage.newInstance( xmlNode ); + break; + } + + return deviceDisk; + } + + /** + * Type of disk device. + * + * Indicates how a disk is to be exposed to the guest OS. + * + * @author Manuel Bentele + * @version 1.0 + */ + enum Type + { + // @formatter:off + CDROM ( "cdrom" ), + FLOPPY ( "floppy" ), + STORAGE( "disk" ); + // @formatter:on + + /** + * Name of the disk device type. + */ + private String type = null; + + /** + * Creates disk device type. + * + * @param type valid name of the disk device type in a Libvirt domain XML document. + */ + Type( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates disk device type from its name with error check. + * + * @param type name of the disk device type in a Libvirt domain XML document. + * @return valid disk device type. + */ + public static Type fromString( String type ) + { + for ( Type t : Type.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } + + /** + * Storage type of a disk device. + * + * The storage type refers to the underlying source for the disk. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum StorageType + { + // @formatter:off + FILE ( "file" ), + BLOCK ( "block" ); + // @formatter:on + + /** + * Name of the disk device type. + */ + private String storageType = null; + + /** + * Creates disk device storage type. + * + * @param storageType valid name of the disk device storage type in a Libvirt domain XML + * document. + */ + StorageType( String storageType ) + { + this.storageType = storageType; + } + + @Override + public String toString() + { + return this.storageType; + } + + /** + * Creates disk device storage type from its name with error check. + * + * @param storageType name of the disk device storage type in a Libvirt domain XML document. + * @return valid disk device storage type. + */ + public static StorageType fromString( String storageType ) + { + for ( StorageType t : StorageType.values() ) { + if ( t.storageType.equalsIgnoreCase( storageType ) ) { + return t; + } + } + + return null; + } + } + + /** + * Bus type (IDE, SATA, ...) of a disk device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum BusType + { + // @formatter:off + IDE ( "ide" ), + FDC ( "fdc" ), + SATA ( "sata" ), + SCSI ( "scsi" ), + SD ( "sd" ), + USB ( "usb" ), + VIRTIO( "virtio" ), + XEN ( "xen" ); + // @formatter:on + + /** + * Name of the disk device bus type. + */ + private String busType = null; + + /** + * Creates disk device bus type. + * + * @param busType valid name of the disk device bus type in a Libvirt domain XML document. + */ + BusType( String busType ) + { + this.busType = busType; + } + + @Override + public String toString() + { + return this.busType; + } + + /** + * Creates disk device bus type from its name with error check. + * + * @param busType name of the disk device bus type in a Libvirt domain XML document. + * @return valid disk device bus type. + */ + public static BusType fromString( String busType ) + { + for ( BusType t : BusType.values() ) { + if ( t.busType.equalsIgnoreCase( busType ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/DiskCdrom.java b/src/main/java/org/openslx/libvirt/domain/device/DiskCdrom.java new file mode 100644 index 0000000..2ae08e1 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/DiskCdrom.java @@ -0,0 +1,55 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A CDROM disk device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class DiskCdrom extends Disk +{ + /** + * Creates an empty CDROM disk device. + */ + public DiskCdrom() + { + super(); + } + + /** + * Creates a CDROM disk device representing an existing Libvirt XML CDROM disk device element. + * + * @param xmlNode existing Libvirt XML CDROM disk device element. + */ + public DiskCdrom( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + + // restrict CDROM disk device default read/write access always to readonly + this.setReadOnly( true ); + } + + /** + * Creates a non-existent CDROM disk device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created CDROM disk device instance. + */ + public static DiskCdrom createInstance( LibvirtXmlNode xmlNode ) + { + return DiskCdrom.newInstance( xmlNode ); + } + + /** + * Creates a CDROM disk device representing an existing Libvirt XML CDROM disk device element. + * + * @param xmlNode existing Libvirt XML CDROM disk device element. + * @return CDROM disk device instance. + */ + public static DiskCdrom newInstance( LibvirtXmlNode xmlNode ) + { + return new DiskCdrom( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/DiskFloppy.java b/src/main/java/org/openslx/libvirt/domain/device/DiskFloppy.java new file mode 100644 index 0000000..ce9733b --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/DiskFloppy.java @@ -0,0 +1,52 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A floppy disk device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class DiskFloppy extends Disk +{ + /** + * Creates an empty floppy disk device. + */ + public DiskFloppy() + { + super(); + } + + /** + * Creates a floppy disk device representing an existing Libvirt XML floppy disk device element. + * + * @param xmlNode existing Libvirt XML floppy disk device element. + */ + public DiskFloppy( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Creates a non-existent floppy disk device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created floppy disk device instance. + */ + public static DiskFloppy createInstance( LibvirtXmlNode xmlNode ) + { + return DiskFloppy.newInstance( xmlNode ); + } + + /** + * Creates a floppy disk device representing an existing Libvirt XML floppy disk device element. + * + * @param xmlNode existing Libvirt XML floppy disk device element. + * @return floppy disk device instance. + */ + public static DiskFloppy newInstance( LibvirtXmlNode xmlNode ) + { + return new DiskFloppy( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/DiskStorage.java b/src/main/java/org/openslx/libvirt/domain/device/DiskStorage.java new file mode 100644 index 0000000..7fca789 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/DiskStorage.java @@ -0,0 +1,54 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A storage (HDD, SSD, ...) disk device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class DiskStorage extends Disk +{ + /** + * Creates an empty storage disk device. + */ + public DiskStorage() + { + super(); + } + + /** + * Creates a storage disk device representing an existing Libvirt XML storage disk device + * element. + * + * @param xmlNode existing Libvirt XML storage disk device element. + */ + public DiskStorage( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Creates a non-existent storage disk device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created storage disk device instance. + */ + public static DiskStorage createInstance( LibvirtXmlNode xmlNode ) + { + return DiskStorage.newInstance( xmlNode ); + } + + /** + * Creates a storage disk device representing an existing Libvirt XML storage disk device + * element. + * + * @param xmlNode existing Libvirt XML storage disk device element. + * @return storage disk device instance. + */ + public static DiskStorage newInstance( LibvirtXmlNode xmlNode ) + { + return new DiskStorage( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/FileSystem.java b/src/main/java/org/openslx/libvirt/domain/device/FileSystem.java new file mode 100644 index 0000000..9ec8caf --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/FileSystem.java @@ -0,0 +1,292 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A file system device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class FileSystem extends Device +{ + /** + * Creates an empty file system device. + */ + public FileSystem() + { + super(); + } + + /** + * Creates a file system device representing an existing Libvirt XML file system device element. + * + * @param xmlNode existing Libvirt XML file system device element. + */ + public FileSystem( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns access mode of the file system device. + * + * @return access mode of the file system device. + */ + public AccessMode getAccessMode() + { + final String mode = this.getXmlElementAttributeValue( "accessmode" ); + return AccessMode.fromString( mode ); + } + + /** + * Sets access mode for the file system device. + * + * @param mode access mode for the file system device. + */ + public void setAccessMode( AccessMode mode ) + { + this.setXmlElementAttributeValue( "accessmode", mode.toString() ); + } + + /** + * Returns type of the file system device. + * + * @return type of the file system device. + */ + public Type getType() + { + final String type = this.getXmlElementAttributeValue( "type" ); + return Type.fromString( type ); + } + + /** + * Sets type for the file system device. + * + * @param type type for the file system device. + */ + public void setType( Type type ) + { + this.setXmlElementAttributeValue( "type", type.toString() ); + } + + /** + * Returns source of the file system device. + * + * @return source of the file system device. + */ + public String getSource() + { + final Type type = this.getType(); + String source = null; + + switch ( type ) { + case BIND: + source = this.getXmlElementAttributeValue( "source", "dir" ); + break; + case BLOCK: + source = this.getXmlElementAttributeValue( "source", "dev" ); + break; + case FILE: + source = this.getXmlElementAttributeValue( "source", "file" ); + break; + case MOUNT: + source = this.getXmlElementAttributeValue( "source", "dir" ); + break; + case RAM: + source = this.getXmlElementAttributeValue( "source", "usage" ); + break; + case TEMPLATE: + source = this.getXmlElementAttributeValue( "source", "name" ); + break; + } + + return source; + } + + /** + * Sets source for the file system device. + * + * @param source source for the file system device. + */ + public void setSource( String source ) + { + Type type = this.getType(); + + // remove all attributes from sub-element 'source' + this.removeXmlElementAttributes( "source" ); + + switch ( type ) { + case BIND: + this.setXmlElementAttributeValue( "source", "dir", source ); + break; + case BLOCK: + this.setXmlElementAttributeValue( "source", "dev", source ); + break; + case FILE: + this.setXmlElementAttributeValue( "source", "file", source ); + break; + case MOUNT: + this.setXmlElementAttributeValue( "source", "dir", source ); + break; + case RAM: + this.setXmlElementAttributeValue( "source", "usage", source ); + break; + case TEMPLATE: + this.setXmlElementAttributeValue( "source", "name", source ); + break; + } + } + + /** + * Returns target of the file system device. + * + * @return target of the file system device. + */ + public String getTarget() + { + return this.getXmlElementAttributeValue( "target", "dir" ); + } + + /** + * Sets target for the file system device. + * + * @param target target for the file system device. + */ + public void setTarget( String target ) + { + this.setXmlElementAttributeValue( "target", "dir", target ); + } + + /** + * Creates a non-existent file system device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created file system device instance. + */ + public static FileSystem createInstance( LibvirtXmlNode xmlNode ) + { + return FileSystem.newInstance( xmlNode ); + } + + /** + * Creates a file system device representing an existing Libvirt XML file system device element. + * + * @param xmlNode existing Libvirt XML file system device element. + * @return file system device instance. + */ + public static FileSystem newInstance( LibvirtXmlNode xmlNode ) + { + return new FileSystem( xmlNode ); + } + + /** + * Access mode for the file system device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum AccessMode + { + // @formatter:off + PASSTHROUGH( "passthrough" ), + MAPPED ( "mapped" ), + SQUASH ( "squash" ); + // @formatter:on + + /** + * Name of the file system device access mode. + */ + private String mode; + + /** + * Creates file system device access mode. + * + * @param mode valid name of the file system device access mode in a Libvirt domain XML + * document. + */ + AccessMode( String mode ) + { + this.mode = mode; + } + + @Override + public String toString() + { + return this.mode; + } + + /** + * Creates file system device access mode from its name with error check. + * + * @param mode name of the file system device access mode in a Libvirt domain XML document. + * @return valid file system device access mode. + */ + public static AccessMode fromString( String mode ) + { + for ( AccessMode a : AccessMode.values() ) { + if ( a.mode.equalsIgnoreCase( mode ) ) { + return a; + } + } + + return null; + } + } + + /** + * Type of file system device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum Type + { + // @formatter:off + MOUNT ( "mount" ), + TEMPLATE( "template" ), + FILE ( "file" ), + BLOCK ( "block" ), + RAM ( "ram" ), + BIND ( "bind" ); + // @formatter:on + + /** + * Name of the file system device type. + */ + private String type; + + /** + * Creates file system device type. + * + * @param type valid name of the file system device type in a Libvirt domain XML document. + */ + Type( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates file system device type from its name with error check. + * + * @param type name of the file system device type in a Libvirt domain XML document. + * @return valid file system device type. + */ + public static Type fromString( String type ) + { + for ( Type t : Type.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/Graphics.java b/src/main/java/org/openslx/libvirt/domain/device/Graphics.java new file mode 100644 index 0000000..3fd2f81 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/Graphics.java @@ -0,0 +1,269 @@ +package org.openslx.libvirt.domain.device; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A graphics (display) device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Graphics extends Device +{ + /** + * Creates an empty graphics device. + */ + public Graphics() + { + super(); + } + + /** + * Creates a graphics device representing an existing Libvirt XML graphics device element. + * + * @param xmlNode existing Libvirt XML graphics device element. + */ + public Graphics( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns the listen type of the graphics device. + * + * @return listen type of the graphics device. + */ + public ListenType getListenType() + { + final String listenType = this.getXmlElementAttributeValue( "listen", "type" ); + return ListenType.fromString( listenType ); + } + + /** + * Sets the listen type for the graphics device. + * + * @param type listen type for the graphics device. + */ + public void setListenType( ListenType type ) + { + this.setXmlElementAttributeValue( "listen", "type", type.toString() ); + } + + /** + * Returns the listen address of the graphics device. + * + * @return listen address of the graphics device. + */ + public InetAddress getListenAddress() + { + InetAddress parsedListenAddress = null; + + if ( this.getListenType() == ListenType.ADDRESS ) { + // only read listen address, if address listen type is set + final String rawListenAddress = this.getXmlElementAttributeValue( "listen", "address" ); + + try { + parsedListenAddress = InetAddress.getByName( rawListenAddress ); + } catch ( UnknownHostException e ) { + parsedListenAddress = null; + } + } + + return parsedListenAddress; + } + + /** + * Sets the listen address for the graphics device. + * + * @param listenAddress listen address for the graphics device. + */ + public void setListenAddress( InetAddress listenAddress ) + { + if ( this.getListenType() == ListenType.ADDRESS && listenAddress != null ) { + // only set listen address, if address listen type is set + this.setXmlElementAttributeValue( "listen", "address", listenAddress.getHostAddress() ); + } + } + + /** + * Returns the listen port of the graphics device. + * + * @return listen port of the graphics device. + */ + public int getListenPort() + { + final String listenPort = this.getXmlElementAttributeValue( "port" ); + return Integer.valueOf( listenPort ); + } + + /** + * Sets the listen port for the graphics device. + * + * @param listenPort listen port for the graphics device. + */ + public void setListenPort( int listenPort ) + { + if ( this.getListenType() == ListenType.ADDRESS ) { + // only set listen port, if address listen type is set + this.setXmlElementAttributeValue( "port", Integer.toString( listenPort ) ); + } + } + + /** + * Creates a non-existent graphics device as Libvirt XML device element. + * + * @param graphics graphics device that is created. + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created graphics device instance. + */ + public static Graphics createInstance( Graphics graphics, LibvirtXmlNode xmlNode ) + { + Graphics addedGraphics = null; + + if ( graphics instanceof GraphicsSpice ) { + xmlNode.setXmlElementAttributeValue( "type", Type.SPICE.toString() ); + addedGraphics = GraphicsSpice.createInstance( xmlNode ); + } else if ( graphics instanceof GraphicsVnc ) { + xmlNode.setXmlElementAttributeValue( "type", Type.VNC.toString() ); + addedGraphics = GraphicsVnc.createInstance( xmlNode ); + } + + return addedGraphics; + } + + /** + * Creates a graphics device representing an existing Libvirt XML graphics device element. + * + * @param xmlNode existing Libvirt XML graphics device element. + * @return graphics device instance. + */ + public static Graphics newInstance( LibvirtXmlNode xmlNode ) + { + Graphics deviceGraphics = null; + Type type = Type.fromString( xmlNode.getXmlElementAttributeValue( "type" ) ); + + if ( type == null ) { + return null; + } + + switch ( type ) { + case SPICE: + deviceGraphics = GraphicsSpice.newInstance( xmlNode ); + break; + case VNC: + deviceGraphics = GraphicsVnc.newInstance( xmlNode ); + break; + } + + return deviceGraphics; + } + + /** + * Listen type of graphics device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum ListenType + { + // @formatter:off + NONE ( "none" ), + ADDRESS( "address" ), + NETWORK( "network" ), + SOCKET ( "socket" ); + // @formatter:on + + /** + * Name of graphics device listen type. + */ + private String type = null; + + /** + * Creates graphics device listen type. + * + * @param type valid name of the graphics device listen type in a Libvirt domain XML document. + */ + ListenType( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates graphics device listen type from its name with error check. + * + * @param type name of the graphics device listen type in a Libvirt domain XML document. + * @return valid graphics device listen type. + */ + public static ListenType fromString( String type ) + { + for ( ListenType t : ListenType.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } + + /** + * Type of graphics device. + * + * @author Manuel Bentele + * @version 1.0 + */ + enum Type + { + // @formatter:off + SPICE( "spice" ), + VNC ( "vnc" ); + // @formatter:on + + /** + * Name of graphics device type. + */ + private String type = null; + + /** + * Creates graphics device type. + * + * @param type valid name of the graphics device type in a Libvirt domain XML document. + */ + Type( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates graphics device type from its name with error check. + * + * @param type name of the graphics device type in a Libvirt domain XML document. + * @return valid graphics device type. + */ + public static Type fromString( String type ) + { + for ( Type t : Type.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/GraphicsSpice.java b/src/main/java/org/openslx/libvirt/domain/device/GraphicsSpice.java new file mode 100644 index 0000000..be67200 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/GraphicsSpice.java @@ -0,0 +1,261 @@ +package org.openslx.libvirt.domain.device; + +import java.net.InetAddress; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A graphics SPICE device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class GraphicsSpice extends Graphics +{ + /** + * Default address of a SPICE graphics listener. + */ + public static final InetAddress DEFAULT_ADDRESS = InetAddress.getLoopbackAddress(); + + /** + * Default port of a SPICE graphics listener. + */ + public static final int DEFAULT_PORT = 59000; + + /** + * Creates an empty graphics SPICE device. + */ + public GraphicsSpice() + { + super(); + } + + /** + * Creates a graphics SPICE device representing an existing Libvirt XML graphics SPICE device + * element. + * + * @param xmlNode existing Libvirt XML graphics SPCIE device element. + */ + public GraphicsSpice( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns the state whether OpenGL hardware acceleration is enabled or not. + * + * @return state whether OpenGL hardware acceleration is enabled or not. + */ + public boolean isOpenGlEnabled() + { + return this.getXmlElementAttributeValueAsBool( "gl", "enable" ); + } + + /** + * Sets the state whether OpenGL hardware acceleration is enabled or not. + * + * @param enabled state whether OpenGL hardware acceleration is enabled or not. + */ + public void setOpenGl( boolean enabled ) + { + this.setXmlElementAttributeValueYesNo( "gl", "enable", enabled ); + } + + /** + * Returns the image compression type. + * + * @return image compression type. + */ + public ImageCompression getImageCompression() + { + final String imageCompression = this.getXmlElementAttributeValue( "image", "compression" ); + return ImageCompression.fromString( imageCompression ); + } + + /** + * Sets the image compression type. + * + * @param type image compression type. + */ + public void setImageCompression( ImageCompression type ) + { + this.setXmlElementAttributeValue( "image", "compression", type.toString() ); + } + + /** + * Checks if audio playback compression is enabled or not. + * + * @return state whether audio playback compression is enabled or not. + */ + public boolean isPlaybackCompressionOn() + { + return this.getXmlElementAttributeValueAsBool( "playback", "compression" ); + } + + /** + * Sets the state whether audio playback compression is enabled or not. + * + * @param enabled state whether audio playback compression is enabled or not. + */ + public void setPlaybackCompression( boolean enabled ) + { + this.setXmlElementAttributeValueOnOff( "playback", "compression", enabled ); + } + + /** + * Returns the streaming mode. + * + * @return streaming mode type. + */ + public StreamingMode getStreamingMode() + { + final String streamingMode = this.getXmlElementAttributeValue( "streaming", "mode" ); + return StreamingMode.fromString( streamingMode ); + } + + /** + * Sets the streaming mode. + * + * @param type streaming mode type. + */ + public void setStreamingMode( StreamingMode type ) + { + this.setXmlElementAttributeValue( "streaming", "mode", type.toString() ); + } + + /** + * Creates a non-existent graphics SPICE device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created graphics SPICE device instance. + */ + public static GraphicsSpice createInstance( LibvirtXmlNode xmlNode ) + { + return GraphicsSpice.newInstance( xmlNode ); + } + + /** + * Creates a graphics SPICE device representing an existing Libvirt XML graphics SPICE device + * element. + * + * @param xmlNode existing Libvirt XML graphics SPICE device element. + * @return graphics SPICE device instance. + */ + public static GraphicsSpice newInstance( LibvirtXmlNode xmlNode ) + { + return new GraphicsSpice( xmlNode ); + } + + /** + * Image compression type of graphics device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum ImageCompression + { + // @formatter:off + AUTO_GLZ( "auto_glz" ), + AUTO_LZ ( "auto_lz" ), + QUIC ( "quic" ), + GLZ ( "glz" ), + LZ ( "lz" ), + OFF ( "off" ); + // @formatter:on + + /** + * Name of graphics device image compression type. + */ + private String type = null; + + /** + * Creates graphics device image compression type. + * + * @param type valid name of the graphics device image compression type in a Libvirt domain + * XML document. + */ + ImageCompression( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates graphics device image compression type from its name with error check. + * + * @param type name of the graphics device image compression type in a Libvirt domain XML + * document. + * @return valid graphics device image compression type. + */ + public static ImageCompression fromString( String type ) + { + for ( ImageCompression t : ImageCompression.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } + + /** + * Streaming mode type of graphics device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum StreamingMode + { + // @formatter:off + ALL ( "all" ), + FILTER( "filter" ), + OFF ( "off" ); + // @formatter:on + + /** + * Name of graphics device image compression type. + */ + private String type = null; + + /** + * Creates graphics device streaming mode type. + * + * @param type valid name of the graphics device streaming mode type in a Libvirt domain XML + * document. + */ + StreamingMode( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates graphics device streaming mode type from its name with error check. + * + * @param type name of the graphics device streaming mode type in a Libvirt domain XML + * document. + * @return valid graphics device streaming mode type. + */ + public static StreamingMode fromString( String type ) + { + for ( StreamingMode t : StreamingMode.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/GraphicsVnc.java b/src/main/java/org/openslx/libvirt/domain/device/GraphicsVnc.java new file mode 100644 index 0000000..f595699 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/GraphicsVnc.java @@ -0,0 +1,54 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A graphics VNC device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class GraphicsVnc extends Graphics +{ + /** + * Creates an empty graphics VNC device. + */ + public GraphicsVnc() + { + super(); + } + + /** + * Creates a graphics VNC device representing an existing Libvirt XML graphics VNC device + * element. + * + * @param xmlNode existing Libvirt XML graphics VNC device element. + */ + public GraphicsVnc( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Creates a non-existent graphics VNC device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created graphics VNC device instance. + */ + public static GraphicsVnc createInstance( LibvirtXmlNode xmlNode ) + { + return GraphicsVnc.newInstance( xmlNode ); + } + + /** + * Creates a graphics VNC device representing an existing Libvirt XML graphics VNC device + * element. + * + * @param xmlNode existing Libvirt XML graphics VNC device element. + * @return graphics VNC device instance. + */ + public static GraphicsVnc newInstance( LibvirtXmlNode xmlNode ) + { + return new GraphicsVnc( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/Hostdev.java b/src/main/java/org/openslx/libvirt/domain/device/Hostdev.java new file mode 100644 index 0000000..dc9cf5e --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/Hostdev.java @@ -0,0 +1,175 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A hostdev device node in a Libvirt domain XML document for PCI, USB, ... passthrough. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Hostdev extends Device +{ + /** + * Creates an empty hostdev device. + */ + public Hostdev() + { + super(); + } + + /** + * Creates a hostdev device representing an existing Libvirt XML hostdev device element. + * + * @param xmlNode existing Libvirt XML hostdev device element. + */ + public Hostdev( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Checks if hostdev device is managed. + * + * If {@link #isManaged()} returns <code>true</code> the hostdev device is detached from the + * host before being passed on to the guest and reattached to the host after the guest exits. + * + * @return state whether hostdev device is managed. + */ + public boolean isManaged() + { + return this.getXmlElementAttributeValueAsBool( "managed" ); + } + + /** + * Sets state whether hostdev device is managed. + * + * If the <code>managed</code> parameter is set to <code>true</code> the hostdev device is + * detached from the host before being passed on to the guest and reattached to the host after + * the guest exits. + * + * @param managed state whether hostdev device is managed or not. + */ + public void setManaged( boolean managed ) + { + this.setXmlElementAttributeValueYesNo( "managed", managed ); + } + + /** + * Removes boot oder entry of the hostdev device. + */ + public void removeBootOrder() + { + this.removeXmlElement( "boot" ); + } + + /** + * Creates a non-existent hostdev device as Libvirt XML device element. + * + * @param hostdev hostdev device that is created. + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created hostdev device instance. + */ + public static Hostdev createInstance( Hostdev hostdev, LibvirtXmlNode xmlNode ) + { + Hostdev addedHostdev = null; + + xmlNode.setXmlElementAttributeValue( "mode", "subsystem" ); + + if ( hostdev instanceof HostdevMdev ) { + xmlNode.setXmlElementAttributeValue( "type", Type.MDEV.toString() ); + addedHostdev = HostdevMdev.createInstance( xmlNode ); + } else if ( hostdev instanceof HostdevPci ) { + xmlNode.setXmlElementAttributeValue( "type", Type.PCI.toString() ); + addedHostdev = HostdevPci.createInstance( xmlNode ); + } else if ( hostdev instanceof HostdevUsb ) { + xmlNode.setXmlElementAttributeValue( "type", Type.USB.toString() ); + addedHostdev = HostdevUsb.createInstance( xmlNode ); + } + + return addedHostdev; + } + + /** + * Creates a hostdev device representing an existing Libvirt XML hostdev device element. + * + * @param xmlNode existing Libvirt XML hostdev device element. + * @return hostdev device instance. + */ + public static Hostdev newInstance( LibvirtXmlNode xmlNode ) + { + Hostdev deviceHostdev = null; + Type type = Type.fromString( xmlNode.getXmlElementAttributeValue( "type" ) ); + + if ( type == null ) { + return null; + } + + switch ( type ) { + case MDEV: + deviceHostdev = HostdevMdev.newInstance( xmlNode ); + break; + case PCI: + deviceHostdev = HostdevPci.newInstance( xmlNode ); + break; + case USB: + deviceHostdev = HostdevUsb.newInstance( xmlNode ); + break; + } + + return deviceHostdev; + } + + /** + * Type of hostdev device subsystem passthrough. + * + * @author Manuel Bentele + * @version 1.0 + */ + enum Type + { + // @formatter:off + MDEV( "mdev" ), + PCI ( "pci" ), + USB ( "usb" ); + // @formatter:on + + /** + * Name of the hostdev device type. + */ + private String type = null; + + /** + * Creates hostdev device type. + * + * @param type valid name of the hostdev device type in a Libvirt domain XML document. + */ + Type( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates hostdev device type from its name with error check. + * + * @param type name of the hostdev device storage in a Libvirt domain XML document. + * @return valid hostdev device type. + */ + public static Type fromString( String type ) + { + for ( Type t : Type.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableSource.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableSource.java new file mode 100644 index 0000000..9377421 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableSource.java @@ -0,0 +1,26 @@ +package org.openslx.libvirt.domain.device; + +/** + * Addressable source operations for a hostdev device. + * + * @author Manuel Bentele + * @version 1.0 + * + * @param <T> type of the source. + */ +public abstract interface HostdevAddressableSource<T> +{ + /** + * Returns the source of the source device (on the Libvirt host). + * + * @return source of the source device (on the Libvirt host). + */ + public T getSource(); + + /** + * Sets the source for the source device (on the Libvirt host). + * + * @param source source for the source device (on the Libvirt host). + */ + public void setSource( T source ); +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableTarget.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableTarget.java new file mode 100644 index 0000000..ca06065 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableTarget.java @@ -0,0 +1,26 @@ +package org.openslx.libvirt.domain.device; + +/** + * Addressable target operations for a hostdev device. + * + * @author Manuel Bentele + * @version 1.0 + * + * @param <T> type of the target. + */ +public abstract interface HostdevAddressableTarget<T> +{ + /** + * Returns the target of the target device (in the virtual machine). + * + * @return target of the target device (in the virtual machine). + */ + public T getPciTarget(); + + /** + * Sets the target for the target device (in the virtual machine). + * + * @param target target for the target device (in the virtual machine). + */ + public void setPciTarget( T target ); +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevMdev.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevMdev.java new file mode 100644 index 0000000..082ea5b --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevMdev.java @@ -0,0 +1,182 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A hostdev mediated device node in a Libvirt domain XML document for mediated device passthrough. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class HostdevMdev extends Hostdev implements HostdevAddressableSource<HostdevMdevDeviceAddress> +{ + /** + * Creates an empty hostdev mediated device. + */ + public HostdevMdev() + { + super(); + } + + /** + * Creates a hostdev mediated device representing an existing Libvirt XML hostdev mediated device + * element. + * + * @param xmlNode existing Libvirt XML hostdev mediated device element. + */ + public HostdevMdev( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Checks whether the hostdev mediated device display is on or off. + * + * @return state whether the hostdev mediated device display is on or off. + */ + public boolean isDisplayOn() + { + return this.getXmlElementAttributeValueAsBool( "display" ); + } + + /** + * Sets the state of the hostdev mediated device display. + * + * @param on state whether the hostdev mediated device display is on or off. + */ + public void setDisplayOn( boolean on ) + { + this.setXmlElementAttributeValueOnOff( "display", on ); + } + + /** + * Checks whether the hostdev mediated device memory framebuffer is on or off. + * + * @return state whether the hostdev mediated device memory framebuffer is on or off. + */ + public boolean isMemoryFramebufferOn() + { + return this.getXmlElementAttributeValueAsBool( "ramfb" ); + } + + /** + * Sets the state of the hostdev mediated device memory framebuffer. + * + * @param on state whether the hostdev mediated device memory framebuffer is on or off. + */ + public void setMemoryFramebufferOn( boolean on ) + { + this.setXmlElementAttributeValueOnOff( "ramfb", on ); + } + + /** + * Returns the hostdev mediated device model. + * + * @return hostdev mediated device model. + */ + public Model getModel() + { + final String model = this.getXmlElementAttributeValue( "model" ); + return Model.fromString( model ); + } + + /** + * Sets the hostdev mediated device model. + * + * @param model hostdev mediated device model that is set. + */ + public void setModel( Model model ) + { + this.setXmlElementAttributeValue( "model", model.toString() ); + } + + @Override + public HostdevMdevDeviceAddress getSource() + { + final String mdevDeviceAddress = this.getXmlElementAttributeValue( "source/address", "uuid" ); + return HostdevMdevDeviceAddress.valueOf( mdevDeviceAddress ); + } + + @Override + public void setSource( HostdevMdevDeviceAddress source ) + { + this.setXmlElementAttributeValue( "source/address", "uuid", source.getDeviceAddressAsString() ); + } + + /** + * Creates a non-existent hostdev mediated device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created hostdev mediated device instance. + */ + public static HostdevMdev createInstance( LibvirtXmlNode xmlNode ) + { + return HostdevMdev.newInstance( xmlNode ); + } + + /** + * Creates a hostdev mediated device representing an existing Libvirt XML hostdev mediated device + * element. + * + * @param xmlNode existing Libvirt XML hostdev mediated device element. + * @return hostdev mediated device instance. + */ + public static HostdevMdev newInstance( LibvirtXmlNode xmlNode ) + { + return new HostdevMdev( xmlNode ); + } + + /** + * Model for hostdev mediated device passthrough. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum Model + { + // @formatter:off + VFIO_PCI( "vfio-pci" ), + VFIO_CCW( "vfio-ccw" ), + VFIO_AP ( "vfio-ap" ); + // @formatter:on + + /** + * Name of the hostdev mediated device model. + */ + private String model = null; + + /** + * Creates hostdev mediated device model. + * + * @param type valid name of the hostdev mediated device model in a Libvirt domain XML + * document. + */ + Model( String model ) + { + this.model = model; + } + + @Override + public String toString() + { + return this.model; + } + + /** + * Creates hostdev mediated device model from its name with error check. + * + * @param model name of the hostdev mediated device model in a Libvirt domain XML document. + * @return valid hostdev mediated device model. + */ + public static Model fromString( String model ) + { + for ( Model m : Model.values() ) { + if ( m.model.equalsIgnoreCase( model ) ) { + return m; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevMdevDeviceAddress.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevMdevDeviceAddress.java new file mode 100644 index 0000000..337791d --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevMdevDeviceAddress.java @@ -0,0 +1,99 @@ +package org.openslx.libvirt.domain.device; + +import java.util.UUID; + +/** + * Representation of an address from a mediated device. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class HostdevMdevDeviceAddress +{ + /** + * Address of the hostdev mediated device. + */ + private final UUID deviceAddress; + + /** + * Creates a new mediated device address and sets the address information to the default address + * {@code 00000000-0000-0000-0000-000000000000}. + */ + public HostdevMdevDeviceAddress() + { + this( new UUID( 0, 0 ) ); + } + + /** + * Creates a new mediated device address consisting of a specified mediated device address. + * + * @param mdevDeviceAddress mediated device address. + */ + public HostdevMdevDeviceAddress( UUID mdevDeviceAddress ) + { + this.deviceAddress = mdevDeviceAddress; + } + + /** + * Returns the address of the mediated device. + * + * @return address of the mediated device. + */ + public UUID getDeviceAddress() + { + return this.deviceAddress; + } + + /** + * Returns the address of the mediated device as {@code String}. + * + * @return address of the mediated device as {@code String}. + */ + public String getDeviceAddressAsString() + { + return this.getDeviceAddress().toString(); + } + + /** + * Creates a new mediated device address parsed from a {@link String}. + * + * @param mdevDeviceAddress textual information containing a mediated device address as + * {@link String}. The textual mediated device address should be well-formed according + * to the string representation as described in {@link UUID#toString}. + * + * @return mediated device address instance. + */ + public static HostdevMdevDeviceAddress valueOf( String mdevDeviceAddress ) + { + HostdevMdevDeviceAddress parsedMdevDeviceAddress = null; + + try { + final UUID deviceAddress = UUID.fromString( mdevDeviceAddress ); + parsedMdevDeviceAddress = new HostdevMdevDeviceAddress( deviceAddress ); + } catch ( IllegalArgumentException e ) { + parsedMdevDeviceAddress = null; + } + + return parsedMdevDeviceAddress; + } + + @Override + public boolean equals( Object obj ) + { + if ( obj == null ) { + return false; + } else if ( this.getClass() != obj.getClass() ) { + return false; + } else { + // check if MDEV device addresses are equal + final HostdevMdevDeviceAddress other = HostdevMdevDeviceAddress.class.cast( obj ); + return other.getDeviceAddress().equals( this.getDeviceAddress() ); + } + } + + @Override + public String toString() + { + return this.getDeviceAddressAsString(); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevPci.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevPci.java new file mode 100644 index 0000000..1351f26 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevPci.java @@ -0,0 +1,74 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A hostdev PCI device node in a Libvirt domain XML document for PCI passthrough. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class HostdevPci extends Hostdev implements HostdevAddressableSource<HostdevPciDeviceAddress> +{ + /** + * Creates an empty hostdev PCI device. + */ + public HostdevPci() + { + super(); + } + + /** + * Creates a hostdev PCI device representing an existing Libvirt XML hostdev PCI device element. + * + * @param xmlNode existing Libvirt XML hostdev PCI device element. + */ + public HostdevPci( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + @Override + public HostdevPciDeviceAddress getSource() + { + return this.getPciAddress( "source/address" ); + } + + @Override + public void setSource( HostdevPciDeviceAddress address ) + { + this.setPciAddress( "source/address", address ); + } + + /** + * Set multifunction mode. + * + * If enabled, the device is said to have multiple functions. + */ + public void setMultifunction( boolean on ) + { + this.setXmlElementAttributeValueOnOff( "address", "multifunction", on ); + } + + /** + * Creates a non-existent hostdev PCI device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created hostdev PCI device instance. + */ + public static HostdevPci createInstance( LibvirtXmlNode xmlNode ) + { + return HostdevPci.newInstance( xmlNode ); + } + + /** + * Creates a hostdev PCI device representing an existing Libvirt XML hostdev PCI device element. + * + * @param xmlNode existing Libvirt XML hostdev PCI device element. + * @return hostdev PCI device instance. + */ + public static HostdevPci newInstance( LibvirtXmlNode xmlNode ) + { + return new HostdevPci( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java new file mode 100644 index 0000000..9281500 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java @@ -0,0 +1,295 @@ +package org.openslx.libvirt.domain.device; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Representation of a slot address from a PCI device. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class HostdevPciDeviceAddress +{ + /** + * Regular expression to parse a PCI device address from a {@link String}. + * <p> + * The regular expression matches a PCI device address if its textual PCI device address is + * well-formed according to the following examples: + * + * <pre> + * 0000:00:02.3 + * 0000:01:00.0 + * 0000:00:1f.3 + * </pre> + */ + private static final String DEVICE_ADDRESS_REGEX = "^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\\.([0-7]{1})$"; + + /** + * Minimum value for a valid PCI device address component number. + */ + private static final int DEVICE_ADDRESS_MIN_VALUE = 0; + + /** + * Maximum value for a valid PCI device domain number. + */ + private static final int DEVICE_ADDRESS_DOMAIN_MAX_VALUE = 0xffff; + + /** + * Maximum value for a valid PCI device bus number. + */ + private static final int DEVICE_ADDRESS_BUS_MAX_VALUE = 0xff; + + /** + * Maximum value for a valid PCI device device number. + */ + private static final int DEVICE_ADDRESS_DEVICE_MAX_VALUE = 0x1f; + + /** + * Maximum value for a valid PCI device function number. + */ + private static final int DEVICE_ADDRESS_FUNCTION_MAX_VALUE = 0x7; + + /** + * Domain number of the PCI device address. + */ + final int pciDomain; + + /** + * Bus number of the PCI device address. + */ + final int pciBus; + + /** + * Device number of the PCI device address. + */ + final int pciDevice; + + /** + * Function number of the PCI device address. + */ + final int pciFunction; + + /** + * Creates a new PCI device address and sets the address information to the default + * address {@code 0000:00:00.0}. + */ + public HostdevPciDeviceAddress() + { + this( 0, 0, 0, 0 ); + } + + /** + * Creates a new PCI device address consisting of a specified PCI bus, device, and function. + * <p> + * The domain of the PCI device address is set to the default number {@code 0000}. + * + * @param pciBus number of the PCI bus. + * @param pciDevice number of the PCI device. + * @param pciFunction number of the PCI function. + * + * @throws IllegalArgumentException failed to validate the PCI bus, device and function. + */ + public HostdevPciDeviceAddress( int pciBus, int pciDevice, int pciFunction ) throws IllegalArgumentException + { + this( 0, pciBus, pciDevice, pciFunction ); + } + + /** + * Creates a new PCI device address consisting of a specified PCI domain, bus, device, and + * function. + * + * @param pciDomain number of the PCI domain. + * @param pciBus number of the PCI bus. + * @param pciDevice number of the PCI device. + * @param pciFunction number of the PCI function. + * + * @throws IllegalArgumentException failed to validate the PCI domain, bus, device and function. + */ + public HostdevPciDeviceAddress( int pciDomain, int pciBus, int pciDevice, int pciFunction ) + throws IllegalArgumentException + { + HostdevPciDeviceAddress.validatePciDeviceAddress( pciDomain, "PCI domain", + HostdevPciDeviceAddress.DEVICE_ADDRESS_DOMAIN_MAX_VALUE ); + HostdevPciDeviceAddress.validatePciDeviceAddress( pciBus, "PCI bus", + HostdevPciDeviceAddress.DEVICE_ADDRESS_BUS_MAX_VALUE ); + HostdevPciDeviceAddress.validatePciDeviceAddress( pciDevice, "PCI device", + HostdevPciDeviceAddress.DEVICE_ADDRESS_DEVICE_MAX_VALUE ); + HostdevPciDeviceAddress.validatePciDeviceAddress( pciFunction, "PCI function", + HostdevPciDeviceAddress.DEVICE_ADDRESS_FUNCTION_MAX_VALUE ); + + this.pciDomain = pciDomain; + this.pciBus = pciBus; + this.pciDevice = pciDevice; + this.pciFunction = pciFunction; + } + + /** + * Validates a specified PCI address component (PCI domain, bus, device or function). + * + * @param address value of the PCI address component. + * @param addressName name of the PCI address component. + * @param upperLimit maximum value for the PCI address component + * + * @throws IllegalArgumentException + */ + private static void validatePciDeviceAddress( final int address, final String addressName, final int upperLimit ) + throws IllegalArgumentException + { + if ( address < HostdevPciDeviceAddress.DEVICE_ADDRESS_MIN_VALUE ) { + throw new IllegalArgumentException( + "The " + addressName + " address must be larger or equal than " + + HostdevPciDeviceAddress.DEVICE_ADDRESS_MIN_VALUE ); + } else if ( address > upperLimit ) { + throw new IllegalArgumentException( + "The " + addressName + " address must be smaller or equal than " + upperLimit ); + } + } + + /** + * Returns the PCI domain. + * + * @return PCI domain. + */ + public int getPciDomain() + { + return this.pciDomain; + } + + /** + * Returns the PCI domain as {@link String}. + * + * @return PCI domain as {@link String}. + */ + public String getPciDomainAsString() + { + return String.format( "%04x", HostdevPciDeviceAddress.DEVICE_ADDRESS_DOMAIN_MAX_VALUE & this.getPciDomain() ); + } + + /** + * Returns the PCI bus. + * + * @return PCI bus. + */ + public int getPciBus() + { + return this.pciBus; + } + + /** + * Returns the PCI bus as {@link String}. + * + * @return PCI bus as {@link String}. + */ + public String getPciBusAsString() + { + return String.format( "%02x", HostdevPciDeviceAddress.DEVICE_ADDRESS_BUS_MAX_VALUE & this.getPciBus() ); + } + + /** + * Returns the PCI device. + * + * @return PCI device. + */ + public int getPciDevice() + { + return this.pciDevice; + } + + /** + * Returns the PCI device as {@link String}. + * + * @return PCI device as {@link String}. + */ + public String getPciDeviceAsString() + { + return String.format( "%02x", HostdevPciDeviceAddress.DEVICE_ADDRESS_DEVICE_MAX_VALUE & this.getPciDevice() ); + } + + /** + * Returns the PCI function. + * + * @return PCI function. + */ + public int getPciFunction() + { + return this.pciFunction; + } + + /** + * Returns the PCI function as {@link String}. + * + * @return PCI function as {@link String}. + */ + public String getPciFunctionAsString() + { + return String.format( "%01x", HostdevPciDeviceAddress.DEVICE_ADDRESS_FUNCTION_MAX_VALUE & this.getPciFunction() ); + } + + /** + * Creates a new PCI device address parsed from a {@link String}. + * <p> + * The PCI device address consists of a PCI domain, bus, device and function parsed from the + * specified {@link String}. + * + * @param pciDeviceAddress textual information containing a PCI device address as {@link String}. + * The textual PCI device address should be well-formed according to the defined + * regular expression {@link #DEVICE_ADDRESS_REGEX}. + * + * @return PCI device address instance. + */ + public static HostdevPciDeviceAddress valueOf( String pciDeviceAddress ) + { + HostdevPciDeviceAddress parsedPciDeviceAddress; + + if ( pciDeviceAddress == null || pciDeviceAddress.isEmpty() ) { + parsedPciDeviceAddress = null; + } else { + final Pattern pciDeviceAddressPattern = Pattern.compile( HostdevPciDeviceAddress.DEVICE_ADDRESS_REGEX ); + final Matcher pciDeviceAddressMatcher = pciDeviceAddressPattern.matcher( pciDeviceAddress.toLowerCase() ); + + if ( pciDeviceAddressMatcher.find() ) { + final int pciDomain = Integer.valueOf( pciDeviceAddressMatcher.group( 1 ), 16 ); + final int pciBus = Integer.valueOf( pciDeviceAddressMatcher.group( 2 ), 16 ); + final int pciDevice = Integer.valueOf( pciDeviceAddressMatcher.group( 3 ), 16 ); + final int pciFunction = Integer.valueOf( pciDeviceAddressMatcher.group( 4 ), 16 ); + + try { + parsedPciDeviceAddress = new HostdevPciDeviceAddress( pciDomain, pciBus, pciDevice, pciFunction ); + } catch ( IllegalArgumentException e ) { + parsedPciDeviceAddress = null; + } + } else { + parsedPciDeviceAddress = null; + } + } + + return parsedPciDeviceAddress; + } + + @Override + public boolean equals( Object obj ) + { + if ( obj == null ) { + return false; + } else if ( this.getClass() != obj.getClass() ) { + return false; + } else { + // check if PCI domain, bus, device and function are equal + final HostdevPciDeviceAddress other = HostdevPciDeviceAddress.class.cast( obj ); + if ( this.getPciDomain() == other.getPciDomain() && this.getPciBus() == other.getPciBus() + && this.getPciDevice() == other.getPciDevice() && this.getPciFunction() == other.getPciFunction() ) { + return true; + } else { + return false; + } + } + } + + @Override + public String toString() + { + return this.getPciDomainAsString() + ":" + this.getPciBusAsString() + ":" + this.getPciDeviceAsString() + "." + + this.getPciFunctionAsString(); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceDescription.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceDescription.java new file mode 100644 index 0000000..25c29f2 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceDescription.java @@ -0,0 +1,186 @@ +package org.openslx.libvirt.domain.device; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Representation of a PCI device description. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class HostdevPciDeviceDescription extends Hostdev +{ + /** + * Regular expression to parse a PCI vendor and device identifier from a {@link String}. + * <p> + * The regular expression matches a PCI device description if its textual PCI device description + * is well-formed according to the following examples: + * + * <pre> + * 8086:a170 + * 10ec:8168 + * 8086:15b7 + * </pre> + */ + private static final String DEVICE_DESCRIPTION_REGEX = "^([a-f0-9]{4}):([a-f0-9]{4})$"; + + /** + * Minimum value of a valid identifier from a PCI device description. + */ + private static final int DEVICE_DESCRIPTION_ID_MIN_VALUE = 0x0000; + + /** + * Maximum value of a valid identifier from a PCI device description. + */ + private static final int DEVICE_DESCRIPTION_ID_MAX_VALUE = 0xffff; + + /** + * Vendor identifier of the PCI device. + */ + final int vendorId; + + /** + * Device identifier of the PCI device. + */ + final int deviceId; + + /** + * Creates a new PCI device description consisting of a PCI vendor and device identifier. + * + * @param vendorId vendor identifier of the PCI device. + * @param deviceId device identifier of the PCI device. + * + * @throws throws IllegalArgumentException failed to validate the PCI device description + * identifiers. + */ + public HostdevPciDeviceDescription( int vendorId, int deviceId ) throws IllegalArgumentException + { + HostdevPciDeviceDescription.validatePciDeviceDescriptionId( "PCI vendor ID", vendorId ); + HostdevPciDeviceDescription.validatePciDeviceDescriptionId( "PCI device ID", deviceId ); + + this.vendorId = vendorId; + this.deviceId = deviceId; + } + + /** + * Validates a PCI device description ID (a PCI vendor or device ID). + * + * @param idName name of the PCI device description identifier. + * @param id value of the PCI device description identifier that should be validated. + * + * @throws IllegalArgumentException failed to validate the PCI device description identifier. + */ + private static void validatePciDeviceDescriptionId( final String idName, final int id ) + throws IllegalArgumentException + { + if ( id < HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MIN_VALUE ) { + throw new IllegalArgumentException( + "The " + idName + "must be larger or equal than " + + HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MIN_VALUE ); + } else if ( id > HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE ) { + throw new IllegalArgumentException( + "The " + idName + "must be smaller or equal than " + + HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE ); + } + } + + /** + * Returns the PCI vendor identifier. + * + * @return PCI vendor identifier. + */ + public int getVendorId() + { + return this.vendorId; + } + + /** + * Returns the PCI vendor identifier as {@link String}. + * + * @return PCI vendor identifier as {@link String}. + */ + public String getVendorIdAsString() + { + return String.format( "%04x", HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE & this.getVendorId() ); + } + + /** + * Returns the PCI device identifier. + * + * @return PCI device identifier. + */ + public int getDeviceId() + { + return this.deviceId; + } + + /** + * Returns the PCI device identifier as {@link String}. + * + * @return PCI device identifier as {@link String}. + */ + public String getDeviceIdAsString() + { + return String.format( "%04x", HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE & this.getDeviceId() ); + } + + /** + * Creates a new PCI device description parsed from a {@link String}. + * <p> + * The PCI device description consists of a PCI vendor and device identifier parsed from the + * specified {@link String}. + * + * @param vendorDeviceId textual information containing a PCI device description as + * {@link String}. The textual PCI device description should be well-formed according + * to the defined regular expression {@link #DEVICE_DESCRIPTION_REGEX}. + * + * @return PCI device description instance. + */ + public static HostdevPciDeviceDescription valueOf( String vendorDeviceId ) + { + final HostdevPciDeviceDescription pciDeviceDescription; + + if ( vendorDeviceId == null || vendorDeviceId.isEmpty() ) { + pciDeviceDescription = null; + } else { + final Pattern pciDeviceDescPattern = Pattern.compile( HostdevPciDeviceDescription.DEVICE_DESCRIPTION_REGEX ); + final Matcher pciDeviceDescMatcher = pciDeviceDescPattern.matcher( vendorDeviceId.toLowerCase() ); + + if ( pciDeviceDescMatcher.find() ) { + final int vendorId = Integer.valueOf( pciDeviceDescMatcher.group( 1 ), 16 ); + final int deviceId = Integer.valueOf( pciDeviceDescMatcher.group( 2 ), 16 ); + + pciDeviceDescription = new HostdevPciDeviceDescription( vendorId, deviceId ); + } else { + pciDeviceDescription = null; + } + } + + return pciDeviceDescription; + } + + @Override + public boolean equals( Object obj ) + { + if ( obj == null ) { + return false; + } else if ( this.getClass() != obj.getClass() ) { + return false; + } else { + // check if vendor and device ID are equal + final HostdevPciDeviceDescription other = HostdevPciDeviceDescription.class.cast( obj ); + if ( this.getVendorId() == other.getVendorId() && this.getDeviceId() == other.getDeviceId() ) { + return true; + } else { + return false; + } + } + } + + @Override + public String toString() + { + return this.getVendorIdAsString() + ":" + this.getDeviceIdAsString(); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevUsb.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsb.java new file mode 100644 index 0000000..7bf13f4 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsb.java @@ -0,0 +1,88 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A hostdev USB device node in a Libvirt domain XML document for USB passthrough. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class HostdevUsb extends Hostdev implements HostdevAddressableSource<HostdevUsbDeviceDescription> +{ + /** + * Creates an empty hostdev USB device. + */ + public HostdevUsb() + { + super(); + } + + /** + * Creates a hostdev USB device representing an existing Libvirt XML hostdev USB device element. + * + * @param xmlNode existing Libvirt XML hostdev USB device element. + */ + public HostdevUsb( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + @Override + public HostdevUsbDeviceDescription getSource() + { + String vendorId = this.getXmlElementAttributeValue( "source/address/vendor", "id" ); + String productId = this.getXmlElementAttributeValue( "source/address/product", "id" ); + + vendorId = HostdevUtils.removeHexPrefix( vendorId ); + productId = HostdevUtils.removeHexPrefix( productId ); + + return HostdevUsbDeviceDescription.valueOf( vendorId + ":" + productId ); + } + + @Override + public void setSource( HostdevUsbDeviceDescription description ) + { + final String vendorId = HostdevUtils.appendHexPrefix( description.getVendorIdAsString() ); + final String productId = HostdevUtils.appendHexPrefix( description.getProductIdAsString() ); + + this.setXmlElementAttributeValue( "source/address/vendor", "id", vendorId ); + this.setXmlElementAttributeValue( "source/address/product", "id", productId ); + } + + public HostdevUsbDeviceAddress getUsbTarget() + { + final String usbBus = this.getXmlElementAttributeValue( "address", "bus" ); + final String usbPort = this.getXmlElementAttributeValue( "address", "port" ); + + return HostdevUsbDeviceAddress.valueOf( usbBus, usbPort ); + } + + public void setUsbTarget( HostdevUsbDeviceAddress address ) + { + this.setXmlElementAttributeValue( "address", "bus", Integer.toString( address.getUsbBus() ) ); + this.setXmlElementAttributeValue( "address", "port", Integer.toString( address.getUsbPort() ) ); + } + + /** + * Creates a non-existent hostdev USB device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created hostdev USB device instance. + */ + public static HostdevUsb createInstance( LibvirtXmlNode xmlNode ) + { + return HostdevUsb.newInstance( xmlNode ); + } + + /** + * Creates a hostdev USB device representing an existing Libvirt XML hostdev USB device element. + * + * @param xmlNode existing Libvirt XML hostdev USB device element. + * @return hostdev USB device instance. + */ + public static HostdevUsb newInstance( LibvirtXmlNode xmlNode ) + { + return new HostdevUsb( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceAddress.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceAddress.java new file mode 100644 index 0000000..02961a1 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceAddress.java @@ -0,0 +1,141 @@ +package org.openslx.libvirt.domain.device; + +/** + * Representation of an address from an USB device. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class HostdevUsbDeviceAddress +{ + /** + * Minimum value for a valid USB device address component number. + */ + private static final int DEVICE_ADDRESS_MIN_VALUE = 0; + + /** + * Maximum value for a valid USB device bus number. + */ + static final int DEVICE_BUS_MAX_VALUE = 127; + + /** + * Maximum value for a valid USB device port number. + */ + static final int DEVICE_PORT_MAX_VALUE = 127; + + /** + * USB bus of the USB device. + */ + final int usbBus; + + /** + * USB port of the USB device. + */ + final int usbPort; + + public HostdevUsbDeviceAddress( int usbBus, int usbPort ) throws IllegalArgumentException + { + HostdevUsbDeviceAddress.validateUsbDeviceAddress( usbBus, "USB bus", + HostdevUsbDeviceAddress.DEVICE_BUS_MAX_VALUE ); + HostdevUsbDeviceAddress.validateUsbDeviceAddress( usbPort, "USB port", + HostdevUsbDeviceAddress.DEVICE_PORT_MAX_VALUE ); + + this.usbBus = usbBus; + this.usbPort = usbPort; + } + + /** + * Validates a specified USB device address component (USB bus or port). + * + * @param address value of the USB address component. + * @param addressName name of the USB address component. + * @param upperLimit maximum value for the USB address component + * + * @throws IllegalArgumentException + */ + private static void validateUsbDeviceAddress( final int address, final String addressName, final int upperLimit ) + throws IllegalArgumentException + { + if ( address < HostdevUsbDeviceAddress.DEVICE_ADDRESS_MIN_VALUE ) { + throw new IllegalArgumentException( + "The " + addressName + " must be larger or equal than " + + HostdevUsbDeviceAddress.DEVICE_ADDRESS_MIN_VALUE ); + } else if ( address > upperLimit ) { + throw new IllegalArgumentException( + "The " + addressName + " must be smaller or equal than " + upperLimit ); + } + } + + /** + * Returns the USB bus number. + * + * @return USB bus number. + */ + public int getUsbBus() + { + return this.usbBus; + } + + /** + * Returns the USB port number. + * + * @return USB port number. + */ + public int getUsbPort() + { + return this.usbPort; + } + + /** + * Creates a new USB device address parsed from {@link String}s. + * + * @param usbBus textual information containing a decimal USB device bus number as + * {@link String}. + * @param usbPort textual information containing a decimal USB device port number as + * {@link String}. + * @return USB device address instance. + */ + public static HostdevUsbDeviceAddress valueOf( String usbBus, String usbPort ) + { + HostdevUsbDeviceAddress usbDeviceAddress; + + if ( usbBus == null || usbBus.isEmpty() || usbPort == null || usbPort.isEmpty() ) { + usbDeviceAddress = null; + } else { + try { + final int parsedUsbBus = Integer.valueOf( usbBus ); + final int parsedUsbPort = Integer.valueOf( usbPort ); + usbDeviceAddress = new HostdevUsbDeviceAddress( parsedUsbBus, parsedUsbPort ); + } catch ( IllegalArgumentException e ) { + usbDeviceAddress = null; + } + } + + return usbDeviceAddress; + + } + + @Override + public boolean equals( Object obj ) + { + if ( obj == null ) { + return false; + } else if ( this.getClass() != obj.getClass() ) { + return false; + } else { + // check if USB bus and port are equal + final HostdevUsbDeviceAddress other = HostdevUsbDeviceAddress.class.cast( obj ); + if ( this.getUsbBus() == other.getUsbBus() && this.getUsbPort() == other.getUsbPort() ) { + return true; + } else { + return false; + } + } + } + + @Override + public String toString() + { + return this.getUsbBus() + ":" + this.getUsbPort(); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceDescription.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceDescription.java new file mode 100644 index 0000000..d1c546f --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceDescription.java @@ -0,0 +1,190 @@ +package org.openslx.libvirt.domain.device; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Representation of an USB device description. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class HostdevUsbDeviceDescription +{ + /** + * Regular expression to parse an USB device vendor and product identifier from a {@link String}. + * <p> + * The regular expression matches an USB device description if its textual USB device description + * is well-formed according to the following examples: + * + * <pre> + * 1d6b:0002 + * 0461:4d22 + * 046d:c312 + * </pre> + */ + private static final String DEVICE_DESCRIPTION_REGEX = "^([a-f0-9]{4}):([a-f0-9]{4})$"; + + /** + * Minimum value of a valid identifier from an USB device description. + */ + private static final int DEVICE_DESCRIPTION_ID_MIN_VALUE = 0x0000; + + /** + * Maximum value of a valid identifier from an USB device description. + */ + private static final int DEVICE_DESCRIPTION_ID_MAX_VALUE = 0xffff; + + /** + * Vendor identifier of the USB device. + */ + final int vendorId; + + /** + * Product identifier of the USB device. + */ + final int productId; + + /** + * Creates a new USB device description consisting of a USB vendor and product identifier. + * + * @param vendorId vendor identifier of the USB device. + * @param productId product identifier of the USB device. + * + * @throws throws IllegalArgumentException failed to validate the USB device description + * identifiers. + */ + public HostdevUsbDeviceDescription( int vendorId, int productId ) throws IllegalArgumentException + { + HostdevUsbDeviceDescription.validateUsbDeviceDescriptionId( "PCI vendor ID", vendorId ); + HostdevUsbDeviceDescription.validateUsbDeviceDescriptionId( "PCI device ID", productId ); + + this.vendorId = vendorId; + this.productId = productId; + } + + /** + * Validates an USB device description ID (an USB vendor or product ID). + * + * @param idName name of the USB device description identifier. + * @param id value of the USB device description identifier that should be validated. + * + * @throws IllegalArgumentException failed to validate the USB device description identifier. + */ + private static void validateUsbDeviceDescriptionId( final String idName, final int id ) + throws IllegalArgumentException + { + if ( id < HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MIN_VALUE ) { + throw new IllegalArgumentException( + "The " + idName + "must be larger or equal than " + + HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MIN_VALUE ); + } else if ( id > HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE ) { + throw new IllegalArgumentException( + "The " + idName + "must be smaller or equal than " + + HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE ); + } + } + + /** + * Returns the USB device vendor identifier. + * + * @return USB device vendor identifier. + */ + public int getVendorId() + { + return this.vendorId; + } + + /** + * Returns the USB vendor identifier as {@link String}. + * + * @return USB vendor identifier as {@link String}. + */ + public String getVendorIdAsString() + { + return String.format( "%04x", HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE & this.getVendorId() ); + } + + /** + * Returns the USB device product identifier. + * + * @return USB device product identifier. + */ + public int getProductId() + { + return this.productId; + } + + /** + * Returns the USB device product identifier as {@link String}. + * + * @return USB device product identifier as {@link String}. + */ + public String getProductIdAsString() + { + return String.format( "%04x", HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE & this.getProductId() ); + } + + /** + * Creates a new USB device description parsed from a {@link String}. + * <p> + * The USB device description consists of an USB vendor and product identifier parsed from the + * specified {@link String}. + * + * @param vendorProductId textual information containing an USB device description as + * {@link String}. The textual USB device description should be well-formed according + * to the defined regular expression {@link #DEVICE_DESCRIPTION_REGEX}. + * + * @return USB device description instance. + */ + public static HostdevUsbDeviceDescription valueOf( String vendorProductId ) + { + HostdevUsbDeviceDescription usbDeviceDescription; + + if ( vendorProductId == null || vendorProductId.isEmpty() ) { + usbDeviceDescription = null; + } else { + final Pattern usbDeviceDescPattern = Pattern.compile( HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_REGEX ); + final Matcher usbDeviceDescMatcher = usbDeviceDescPattern.matcher( vendorProductId.toLowerCase() ); + + if ( usbDeviceDescMatcher.find() ) { + final int vendorId = Integer.valueOf( usbDeviceDescMatcher.group( 1 ), 16 ); + final int productId = Integer.valueOf( usbDeviceDescMatcher.group( 2 ), 16 ); + + try { + usbDeviceDescription = new HostdevUsbDeviceDescription( vendorId, productId ); + } catch ( IllegalArgumentException e ) { + usbDeviceDescription = null; + } + } else { + usbDeviceDescription = null; + } + } + + return usbDeviceDescription; + } + + @Override + public boolean equals( Object obj ) + { + if ( obj == null ) { + return false; + } else if ( this.getClass() != obj.getClass() ) { + return false; + } else { + // check if vendor and product ID are equal + final HostdevUsbDeviceDescription other = HostdevUsbDeviceDescription.class.cast( obj ); + if ( this.getVendorId() == other.getVendorId() && this.getProductId() == other.getProductId() ) { + return true; + } else { + return false; + } + } + } + + @Override + public String toString() + { + return this.getVendorIdAsString() + ":" + this.getProductIdAsString(); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevUtils.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevUtils.java new file mode 100644 index 0000000..204bea9 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevUtils.java @@ -0,0 +1,32 @@ +package org.openslx.libvirt.domain.device; + +/** + * Collection of helper methods to maintain a Libvirt related hostdev XML element. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class HostdevUtils +{ + /** + * Appends the HEX prefix to a specified hostdev address component without any HEX prefix. + * + * @param component address component without any HEX prefix. + * @return address component with the HEX prefix. + */ + public static String appendHexPrefix( String component ) + { + return "0x" + component; + } + + /** + * Removes a possible HEX prefix of a specified hostdev address component. + * + * @param component address component with possible HEX prefix. + * @return address component without any HEX prefix. + */ + public static String removeHexPrefix( String component ) + { + return component.replaceFirst( "0x", "" ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/Interface.java b/src/main/java/org/openslx/libvirt/domain/device/Interface.java new file mode 100644 index 0000000..44b8e4c --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/Interface.java @@ -0,0 +1,344 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A network interface device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Interface extends Device +{ + /** + * Creates an empty network device. + */ + public Interface() + { + super(); + } + + /** + * Creates a network device representing an existing Libvirt XML network interface device + * element. + * + * @param xmlNode existing Libvirt XML network interface device element. + */ + public Interface( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns hardware model of the network device. + * + * @return hardware model of the network device. + */ + public Model getModel() + { + String model = this.getXmlElementAttributeValue( "model", "type" ); + return Model.fromString( model ); + } + + /** + * Sets hardware model for the network device. + * + * @param model hardware model for the network device. + */ + public void setModel( Model model ) + { + this.setXmlElementAttributeValue( "model", "type", model.toString() ); + } + + /** + * Returns type of the network device. + * + * @return type of the network device. + */ + public Type getType() + { + return Type.fromString( this.getXmlElementAttributeValue( "type" ) ); + } + + /** + * Sets type of the network device. + * + * @param type network device type. + */ + public void setType( Type type ) + { + String source = this.getSource(); + + // change type and set source again + this.setXmlElementAttributeValue( "type", type.toString() ); + this.setSource( source ); + } + + /** + * Returns the source of the network device. + * + * @return source of the network device. + */ + public String getSource() + { + Type type = this.getType(); + String source = null; + + switch ( type ) { + case BRIDGE: + source = this.getXmlElementAttributeValue( "source", "bridge" ); + break; + case NETWORK: + source = this.getXmlElementAttributeValue( "source", "network" ); + break; + } + + return source; + } + + /** + * Sets the source for the network device. + * + * @param source for the network device. + */ + public void setSource( String source ) + { + Type type = this.getType(); + + // remove all attributes from sub-element 'source' + this.removeXmlElementAttributes( "source" ); + + switch ( type ) { + case BRIDGE: + this.setXmlElementAttributeValue( "source", "bridge", source ); + break; + case NETWORK: + this.setXmlElementAttributeValue( "source", "network", source ); + break; + } + } + + /** + * Returns MAC address of the network device. + * + * @return MAC address of the network device. + */ + public String getMacAddress() + { + return this.getXmlElementAttributeValue( "mac", "address" ); + } + + /** + * Sets MAC address of the network device. + * + * @param macAddress MAC address for the network device. + */ + public void setMacAddress( String macAddress ) + { + this.setXmlElementAttributeValue( "mac", "address", macAddress ); + } + + /** + * Removes boot oder entry of the network interface device. + */ + public void removeBootOrder() + { + this.removeXmlElement( "boot" ); + } + + /** + * Removes network source of the network interface device. + */ + public void removeSource() + { + this.removeXmlElement( "source" ); + } + + /** + * Removes MAC address of the network interface device. + */ + public void removeMacAddress() + { + this.removeXmlElement( "mac" ); + } + + /** + * Creates a non-existent network interface device as Libvirt XML device element. + * + * @param iface network device that is created. + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created network device instance. + */ + public static Interface createInstance( Interface iface, LibvirtXmlNode xmlNode ) + { + Interface addedInterface = null; + + if ( iface instanceof InterfaceBridge ) { + xmlNode.setXmlElementAttributeValue( "type", Type.BRIDGE.toString() ); + addedInterface = InterfaceBridge.createInstance( xmlNode ); + } else if ( iface instanceof InterfaceNetwork ) { + xmlNode.setXmlElementAttributeValue( "type", Type.NETWORK.toString() ); + addedInterface = InterfaceNetwork.createInstance( xmlNode ); + } + + return addedInterface; + } + + /** + * Creates a network interface device representing an existing Libvirt XML network interface + * device element. + * + * @param xmlNode existing Libvirt XML network interface device element. + * @return network interface device instance. + */ + public static Interface newInstance( LibvirtXmlNode xmlNode ) + { + Interface deviceInterface = null; + Type type = Type.fromString( xmlNode.getXmlElementAttributeValue( "type" ) ); + + if ( type == null ) { + return null; + } + + switch ( type ) { + case BRIDGE: + deviceInterface = InterfaceBridge.newInstance( xmlNode ); + break; + case NETWORK: + deviceInterface = InterfaceNetwork.newInstance( xmlNode ); + break; + } + + return deviceInterface; + } + + /** + * Type of network interface device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum Type + { + // @formatter:off + BRIDGE ( "bridge" ), + NETWORK( "network" ); + // @formatter:on + + /** + * Name of the network interface device type. + */ + private String type = null; + + /** + * Creates network interface device type. + * + * @param type valid name of the network interface device type in a Libvirt domain XML + * document. + */ + Type( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates network interface device type from its name with error check. + * + * @param type name of the network interface device type in a Libvirt domain XML document. + * @return valid network interface device type. + */ + public static Type fromString( String type ) + { + for ( Type t : Type.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } + + /** + * Model of network interface device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum Model + { + // @formatter:off + E1000 ( "e1000" ), + E1000_82544GC ( "e1000-82544gc" ), + E1000_82545EM ( "e1000-82545em" ), + E1000E ( "e1000e" ), + I82550 ( "i82550" ), + I82551 ( "i82551" ), + I82557A ( "i82557a" ), + I82557B ( "i82557b" ), + I82557C ( "i82557c" ), + I82558A ( "i82558a" ), + I82558B ( "i82558b" ), + I82559A ( "i82559a" ), + I82559B ( "i82559b" ), + I82559C ( "i82559c" ), + I82559ER ( "i82559er" ), + I82562 ( "i82562" ), + I82801 ( "i82801" ), + NE2K_PCI ( "ne2k_pci" ), + PCNET ( "pcnet" ), + RTL8139 ( "rtl8139" ), + TULIP ( "tulip" ), + VIRTIO ( "virtio" ), + VIRTIO_NET_PCI ( "virtio-net-pci" ), + VIRTIO_NET_PCI_NON_TRANSITIONAL( "virtio-net-pci-non-transitional" ), + VIRTIO_NET_PCI_TRANSITIONAL ( "virtio-net-pci-transitional" ), + VMXNET3 ( "vmxnet3" ); + // @formatter:on + + /** + * Name of the network interface device model. + */ + private String model = null; + + /** + * Creates network interface device model. + * + * @param type valid name of the network interface device model in a Libvirt domain XML + * document. + */ + Model( String model ) + { + this.model = model; + } + + @Override + public String toString() + { + return this.model; + } + + /** + * Creates network interface device model from its name with error check. + * + * @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 ) + { + for ( Model m : Model.values() ) { + if ( m.model.equalsIgnoreCase( model ) ) { + return m; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/InterfaceBridge.java b/src/main/java/org/openslx/libvirt/domain/device/InterfaceBridge.java new file mode 100644 index 0000000..02eabb0 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/InterfaceBridge.java @@ -0,0 +1,54 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A network bridge interface device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class InterfaceBridge extends Interface +{ + /** + * Creates an empty network bridge interface device. + */ + public InterfaceBridge() + { + super(); + } + + /** + * Creates a network bridge interface device representing an existing Libvirt XML network bridge + * interface device element. + * + * @param xmlNode existing Libvirt XML network bridge interface device element. + */ + public InterfaceBridge( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Creates a non-existent network bridge interface device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created network bridge interface device instance. + */ + public static InterfaceBridge createInstance( LibvirtXmlNode xmlNode ) + { + return InterfaceBridge.newInstance( xmlNode ); + } + + /** + * Creates a network bridge interface device representing an existing Libvirt XML network bridge + * interface device element. + * + * @param xmlNode existing Libvirt XML network bridge interface device element. + * @return network bridge interface device instance. + */ + public static InterfaceBridge newInstance( LibvirtXmlNode xmlNode ) + { + return new InterfaceBridge( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/InterfaceNetwork.java b/src/main/java/org/openslx/libvirt/domain/device/InterfaceNetwork.java new file mode 100644 index 0000000..ae1fd40 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/InterfaceNetwork.java @@ -0,0 +1,54 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A network interface device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class InterfaceNetwork extends Interface +{ + /** + * Creates an empty network interface device. + */ + public InterfaceNetwork() + { + super(); + } + + /** + * Creates a network interface device representing an existing Libvirt XML network interface + * device element. + * + * @param xmlNode existing Libvirt XML network interface device element. + */ + public InterfaceNetwork( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Creates a non-existent network interface device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created network interface device device instance. + */ + public static InterfaceNetwork createInstance( LibvirtXmlNode xmlNode ) + { + return InterfaceNetwork.newInstance( xmlNode ); + } + + /** + * Creates a network interface device representing an existing Libvirt XML network interface + * device element. + * + * @param xmlNode existing Libvirt XML network interface device element. + * @return network interface device instance. + */ + public static InterfaceNetwork newInstance( LibvirtXmlNode xmlNode ) + { + return new InterfaceNetwork( xmlNode ); + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/Parallel.java b/src/main/java/org/openslx/libvirt/domain/device/Parallel.java new file mode 100644 index 0000000..7db60ca --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/Parallel.java @@ -0,0 +1,158 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A parallel port device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Parallel extends Device +{ + /** + * Creates an empty parallel port device. + */ + public Parallel() + { + super(); + } + + /** + * Creates a parallel port device representing an existing Libvirt XML parallel port device + * element. + * + * @param xmlNode existing Libvirt XML parallel port device element. + */ + public Parallel( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns the type of the parallel port device. + * + * @return type of the parallel port device. + */ + public Type getType() + { + final String type = this.getXmlElementAttributeValue( "type" ); + return Type.fromString( type ); + } + + /** + * Sets the type for the parallel port device. + * + * @param type type for the parallel port device. + */ + public void setType( Type type ) + { + this.setXmlElementAttributeValue( "type", type.toString() ); + } + + /** + * Returns the source of the parallel port device. + * + * @return source of the parallel port device. + */ + public String getSource() + { + return this.getXmlElementAttributeValue( "source", "path" ); + } + + /** + * Sets the source for the parallel port device. + * + * @param source source for the parallel port device. + */ + public void setSource( String source ) + { + this.setXmlElementAttributeValue( "source", "path", source ); + } + + /** + * Creates a non-existent parallel port device as Libvirt XML parallel port device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML parallel port device that is created. + * @return created parallel port device instance. + */ + public static Parallel createInstance( LibvirtXmlNode xmlNode ) + { + return Parallel.newInstance( xmlNode ); + } + + /** + * Creates a parallel port device representing an existing Libvirt XML parallel port device + * element. + * + * @param xmlNode existing Libvirt XML parallel port device element. + * @return parallel port device instance. + */ + public static Parallel newInstance( LibvirtXmlNode xmlNode ) + { + return new Parallel( xmlNode ); + } + + /** + * Type of parallel port device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum Type + { + // @formatter:off + DEV ( "dev" ), + FILE ( "file" ), + PIPE ( "pipe" ), + UNIX ( "unix" ), + TCP ( "tcp" ), + UDP ( "udp" ), + NULL ( "null" ), + STDIO ( "stdio" ), + VC ( "vc" ), + PTY ( "pty" ), + SPICEVMC ( "spicevmc" ), + SPICEPORT( "spiceport" ), + NMDM ( "nmdm" ); + // @formatter:on + + /** + * Name of the parallel port device type. + */ + private String type; + + /** + * Creates parallel port device type. + * + * @param type valid name of the parallel port device type in a Libvirt domain XML document. + */ + Type( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates parallel port device type from its name with error check. + * + * @param type name of the parallel port device type in a Libvirt domain XML document. + * @return valid parallel port device type. + */ + public static Type fromString( String type ) + { + for ( Type t : Type.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/Serial.java b/src/main/java/org/openslx/libvirt/domain/device/Serial.java new file mode 100644 index 0000000..54be26e --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/Serial.java @@ -0,0 +1,156 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A serial port device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Serial extends Device +{ + /** + * Creates an empty serial port device. + */ + public Serial() + { + super(); + } + + /** + * Creates a serial port device representing an existing Libvirt XML serial port device element. + * + * @param xmlNode existing Libvirt XML serial port device element. + */ + public Serial( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns the type of the serial port device. + * + * @return type of the serial port device. + */ + public Type getType() + { + final String type = this.getXmlElementAttributeValue( "type" ); + return Type.fromString( type ); + } + + /** + * Sets the type for the serial port device. + * + * @param type type for the serial port device. + */ + public void setType( Type type ) + { + this.setXmlElementAttributeValue( "type", type.toString() ); + } + + /** + * Returns the source of the serial port device. + * + * @return source of the serial port device. + */ + public String getSource() + { + return this.getXmlElementAttributeValue( "source", "path" ); + } + + /** + * Sets the source for the serial port device. + * + * @param source source for the serial port device. + */ + public void setSource( String source ) + { + this.setXmlElementAttributeValue( "source", "path", source ); + } + + /** + * Creates a non-existent serial port device as Libvirt XML serial port device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML serial port device that is created. + * @return created serial port device instance. + */ + public static Serial createInstance( LibvirtXmlNode xmlNode ) + { + return Serial.newInstance( xmlNode ); + } + + /** + * Creates a serial port device representing an existing Libvirt XML serial port device element. + * + * @param xmlNode existing Libvirt XML serial port device element. + * @return serial port device instance. + */ + public static Serial newInstance( LibvirtXmlNode xmlNode ) + { + return new Serial( xmlNode ); + } + + /** + * Type of serial port device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum Type + { + // @formatter:off + DEV ( "dev" ), + FILE ( "file" ), + PIPE ( "pipe" ), + UNIX ( "unix" ), + TCP ( "tcp" ), + UDP ( "udp" ), + NULL ( "null" ), + STDIO ( "stdio" ), + VC ( "vc" ), + PTY ( "pty" ), + SPICEVMC ( "spicevmc" ), + SPICEPORT( "spiceport" ), + NMDM ( "nmdm" ); + // @formatter:on + + /** + * Name of the serial port device type. + */ + private String type; + + /** + * Creates serial port device type. + * + * @param type valid name of the serial port device type in a Libvirt domain XML document. + */ + Type( String type ) + { + this.type = type; + } + + @Override + public String toString() + { + return this.type; + } + + /** + * Creates serial port device type from its name with error check. + * + * @param type name of the serial port device type in a Libvirt domain XML document. + * @return valid serial port device type. + */ + public static Type fromString( String type ) + { + for ( Type t : Type.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/Shmem.java b/src/main/java/org/openslx/libvirt/domain/device/Shmem.java new file mode 100644 index 0000000..3c48c95 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/Shmem.java @@ -0,0 +1,178 @@ +package org.openslx.libvirt.domain.device; + +import java.math.BigInteger; + +import org.openslx.libvirt.domain.DomainUtils; +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A shared memory device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Shmem extends Device +{ + /** + * Creates an empty sound device. + */ + public Shmem() + { + super(); + } + + /** + * Creates a shared memory device representing an existing Libvirt XML shared memory device + * element. + * + * @param xmlNode existing Libvirt XML shared memory device element. + */ + public Shmem( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns the model of the shared memory device. + * + * @return model of the shared memory device. + */ + public Model getModel() + { + String model = this.getXmlElementAttributeValue( "model", "type" ); + return Model.fromString( model ); + } + + /** + * Sets the model for the shared memory device. + * + * @param model model for the shared memory device. + */ + public void setModel( Model model ) + { + this.setXmlElementAttributeValue( "model", "type", model.toString() ); + } + + /** + * Returns the name of the shared memory device. + * + * @return name of the shared memory device. + */ + public String getName() + { + return this.getXmlElementAttributeValue( "name" ); + } + + /** + * Sets the name for the shared memory device. + * + * @param name name for the shared memory device. + */ + public void setName( String name ) + { + this.setXmlElementAttributeValue( "name", name ); + } + + /** + * Returns the memory size of the shared memory device. + * + * @return memory size of the shared memory device in bytes. + */ + public BigInteger getSize() + { + final String unit = this.getXmlElementAttributeValue( "size", "unit" ); + final String size = this.getXmlElementValue( "size" ); + + return DomainUtils.decodeMemory( size, unit ); + } + + /** + * Sets the memory size for the shared memory device. + * + * @param size memory size for the shared memory device in bytes. + */ + public void setSize( BigInteger memory ) + { + final String unit = "M"; + final String size = DomainUtils.encodeMemory( memory, unit ); + + this.setXmlElementAttributeValue( "size", "unit", unit ); + this.setXmlElementValue( "size", size ); + } + + /** + * Creates a non-existent shared memory device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created shared memory device instance. + */ + public static Shmem createInstance( LibvirtXmlNode xmlNode ) + { + return Shmem.newInstance( xmlNode ); + } + + /** + * Creates a shared memory device representing an existing Libvirt XML shared memory device + * element. + * + * @param xmlNode existing Libvirt XML shared memory device element. + * @return shared memory device instance. + */ + public static Shmem newInstance( LibvirtXmlNode xmlNode ) + { + return new Shmem( xmlNode ); + } + + /** + * Model of shared memory device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum Model + { + // @formatter:off + IVSHMEM ( "ivshmem" ), + IVSHMEM_PLAIN ( "ivshmem-plain" ), + IVSHMEM_DOORBELL( "ivshmem-doorbell" ); + // @formatter:on + + /** + * Name of the shared memory device model. + */ + private String model; + + /** + * Creates shared memory device model. + * + * @param type valid name of the shared memory device model in a Libvirt domain XML document. + */ + Model( String model ) + { + this.model = model; + } + + @Override + public String toString() + { + return this.model; + } + + /** + * Creates shared memory device model from its name with error check. + * + * @param model name of the shared memory device model in a Libvirt domain XML document. + * @return valid shared memory device model. + */ + public static Model fromString( String model ) + { + for ( Model m : Model.values() ) { + if ( m.model.equalsIgnoreCase( model ) ) { + return m; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/Sound.java b/src/main/java/org/openslx/libvirt/domain/device/Sound.java new file mode 100644 index 0000000..dfeeffd --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/Sound.java @@ -0,0 +1,128 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A sound device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Sound extends Device +{ + /** + * Creates an empty sound device. + */ + public Sound() + { + super(); + } + + /** + * Creates a sound device representing an existing Libvirt XML sound device element. + * + * @param xmlNode existing Libvirt XML sound device element. + */ + public Sound( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns hardware model of the sound device. + * + * @return hardware model of the sound device. + */ + public Model getModel() + { + String model = this.getXmlElementAttributeValue( "model" ); + return Model.fromString( model ); + } + + /** + * Sets hardware model for the sound device. + * + * @param model hardware model for the sound device. + */ + public void setModel( Model model ) + { + this.setXmlElementAttributeValue( "model", model.toString() ); + } + + /** + * Creates a non-existent sound device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created sound device instance. + */ + public static Sound createInstance( LibvirtXmlNode xmlNode ) + { + return Sound.newInstance( xmlNode ); + } + + /** + * Creates a sound device representing an existing Libvirt XML sound device element. + * + * @param xmlNode existing Libvirt XML sound device element. + * @return sound device instance. + */ + public static Sound newInstance( LibvirtXmlNode xmlNode ) + { + return new Sound( xmlNode ); + } + + /** + * Model of sound device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum Model + { + // @formatter:off + AC97 ( "ac97" ), + ES1370( "es1370" ), + ICH6 ( "ich6" ), + ICH9 ( "ich9" ), + SB16 ( "sb16" ); + // @formatter:on + + /** + * Name of the sound device model. + */ + private String model; + + /** + * Creates sound device model. + * + * @param type valid name of the sound device model in a Libvirt domain XML document. + */ + Model( String model ) + { + this.model = model; + } + + @Override + public String toString() + { + return this.model; + } + + /** + * Creates sound device model from its name with error check. + * + * @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 ) + { + for ( Model m : Model.values() ) { + if ( m.model.equalsIgnoreCase( model ) ) { + return m; + } + } + + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/domain/device/Video.java b/src/main/java/org/openslx/libvirt/domain/device/Video.java new file mode 100644 index 0000000..a674715 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/Video.java @@ -0,0 +1,197 @@ +package org.openslx.libvirt.domain.device; + +import org.openslx.libvirt.xml.LibvirtXmlNode; + +/** + * A video (GPU) device node in a Libvirt domain XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class Video extends Device +{ + /** + * Creates an empty video device. + */ + public Video() + { + super(); + } + + /** + * Creates a video device representing an existing Libvirt XML video device element. + * + * @param xmlNode existing Libvirt XML video device element. + */ + public Video( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns hardware model of the video device. + * + * @return hardware model of the video device. + */ + public Model getModel() + { + String model = this.getXmlElementAttributeValue( "model", "type" ); + return Model.fromString( model ); + } + + /** + * Sets hardware model for the video device. + * + * @param model hardware model for the video device. + */ + public void setModel( Model model ) + { + this.setXmlElementAttributeValue( "model", "type", model.toString() ); + } + + /** + * Checks whether 2D hardware video acceleration is turned on or off. + * + * @return state of 2D hardware video acceleration. + */ + public boolean get2DAcceleration() + { + return this.getXmlElementAttributeValueAsBool( "model/acceleration", "accel2d" ); + } + + /** + * Turns 2D hardware video acceleration on or off. + * + * @param acceleration state of 2D hardware video acceleration. + */ + public void set2DAcceleration( boolean acceleration ) + { + Model model = this.getModel(); + + if ( model != null ) { + if ( model == Model.VIRTIO ) { + // only set acceleration on supported Virtio GPUs + this.setXmlElementAttributeValueYesNo( "model/acceleration", "accel2d", acceleration ); + } else { + String errorMsg = + "Video card model '" + model.toString() + "' does not support enabled 2D hardware acceleration."; + throw new IllegalArgumentException( errorMsg ); + } + } + } + + /** + * Checks whether 3D hardware video acceleration is turned on or off. + * + * @return state of 3D hardware video acceleration. + */ + public boolean get3DAcceleration() + { + return this.getXmlElementAttributeValueAsBool( "model/acceleration", "accel3d" ); + } + + /** + * Turns 3D hardware video acceleration on or off. + * + * @param acceleration state of 3D hardware video acceleration. + */ + public void set3DAcceleration( boolean acceleration ) + { + Model model = this.getModel(); + + if ( model == Model.VIRTIO ) { + // only set acceleration on supported Virtio GPUs + this.setXmlElementAttributeValueYesNo( "model/acceleration", "accel3d", acceleration ); + } else { + String errorMsg = + "Video card model '" + model.toString() + "' does not support enabled 3D hardware acceleration."; + throw new IllegalArgumentException( errorMsg ); + } + } + + /** + * Disables the video device by setting the model to {@link Model#NONE}. + */ + public void disable() + { + this.removeXmlElementChilds(); + this.setModel( Model.NONE ); + } + + /** + * Creates a non-existent video device as Libvirt XML device element. + * + * @param xmlNode Libvirt XML node of the Libvirt XML device that is created. + * @return created video device instance. + */ + public static Video createInstance( LibvirtXmlNode xmlNode ) + { + return Video.newInstance( xmlNode ); + } + + /** + * Creates a video device representing an existing Libvirt XML video device element. + * + * @param xmlNode existing Libvirt XML video device element. + * @return video device instance. + */ + public static Video newInstance( LibvirtXmlNode xmlNode ) + { + return new Video( xmlNode ); + } + + /** + * Model of video device. + * + * @author Manuel Bentele + * @version 1.0 + */ + public enum Model + { + // @formatter:off + NONE ( "none" ), + QXL ( "qxl" ), + VGA ( "vga" ), + VMVGA ( "vmvga" ), + VIRTIO( "virtio" ); + // @formatter:on + + /** + * Name of the video device model. + */ + private String model = null; + + /** + * Creates video device model. + * + * @param type valid name of the video device model in a Libvirt domain XML document. + */ + Model( String model ) + { + this.model = model; + } + + @Override + public String toString() + { + return this.model; + } + + /** + * Creates video device model from its name with error check. + * + * @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 ) + { + for ( Model m : Model.values() ) { + if ( m.model.equalsIgnoreCase( model ) ) { + return m; + } + } + + return null; + } + } +} 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<Os> getOses() + { + final ArrayList<Os> oses = new ArrayList<Os>(); + 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<Os> 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<Os> 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/LibvirtXmlCreatable.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlCreatable.java new file mode 100644 index 0000000..e799ace --- /dev/null +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlCreatable.java @@ -0,0 +1,26 @@ +package org.openslx.libvirt.xml; + +import org.w3c.dom.Node; + +/** + * Serializability of a Libvirt XML object from/to its XML representation. + * + * @author Manuel Bentele + * @version 1.0 + */ +public interface LibvirtXmlCreatable +{ + /** + * Serializing an object from its XML representation. + * + * @param xmlNode The object's XML representation. + */ + void fromXmlNode( Node xmlNode ); + + /** + * Serializing the object to its XML representation. + * + * @return XML representation of the object. + */ + Node toXmlNode(); +} diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java new file mode 100644 index 0000000..805376f --- /dev/null +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java @@ -0,0 +1,355 @@ +package org.openslx.libvirt.xml; + +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; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * A generic representation of a Libvirt XML file. + * + * @implNote Base class to derive the representation of specific Libvirt XML files. + * + * @author Manuel Bentele + * @version 1.0 + */ +public abstract class LibvirtXmlDocument implements LibvirtXmlSerializable, LibvirtXmlValidatable +{ + /** + * Document builder to parse Libvirt XML document from file. + */ + private DocumentBuilder domBuilder = null; + + /** + * Representation of a Libvirt XML document. + */ + private Document xmlDocument = null; + + /** + * XML transformer to transform Libvirt XML document to a file. + */ + private Transformer xmlTransformer = null; + + /** + * XML root node of the Libvirt XML document. + */ + private LibvirtXmlNode rootXmlNode = null; + + /** + * RNG schema validator to validate the Libvirt XML document content. + */ + private LibvirtXmlSchemaValidator rngValidator = null; + + /** + * Creates and initializes XML context to create and transform a Libvirt XML file from/to a file. + * + * @param rngSchema RNG schema to validate the Libvirt XML document content. + * + * @throws LibvirtXmlDocumentException error occured during setup of the XML context to read and + * write from/to a Libvirt XML file. + */ + private void createXmlContext( InputStream rngSchema ) throws LibvirtXmlDocumentException + { + // used for XML input + try { + DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); + domFactory.setIgnoringElementContentWhitespace( true ); + domFactory.setNamespaceAware( true ); + this.domBuilder = domFactory.newDocumentBuilder(); + } catch ( ParserConfigurationException e ) { + String errorMsg = "Setting up XML context for reading from the Libvirt XML document failed."; + throw new LibvirtXmlDocumentException( errorMsg ); + } + + // used for XML output + try { + // use hack to load specific transformer factory implementation for XSLT + System.setProperty( TransformerFactory.class.getName(), + "org.apache.xalan.processor.TransformerFactoryImpl" ); + + // create XML transformer factory to create XML transformer with specific indentation + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + + // create XML transformer and apply settings for output XML transformation + InputStream xslOutputSchemaStream = LibvirtXmlResources.getLibvirtXsl( "xml-output-transformation.xsl" ); + StreamSource xslOutputSchema = new StreamSource( xslOutputSchemaStream ); + this.xmlTransformer = transformerFactory.newTransformer( xslOutputSchema ); + this.xmlTransformer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" ); + } catch ( TransformerConfigurationException e ) { + String errorMsg = "Setting up XML context for writing to the Libvirt XML document failed."; + throw new LibvirtXmlDocumentException( errorMsg ); + } + + // used for XML validation with RNG schema files + if ( rngSchema != null ) { + try { + this.rngValidator = new LibvirtXmlSchemaValidator( rngSchema ); + } catch ( SAXException e ) { + String errorMsg = "Setting up XML context for validating to the Libvirt XML document failed."; + e.printStackTrace(); + throw new LibvirtXmlDocumentException( errorMsg ); + } + } + } + + /** + * Creates a Libvirt XML document from a given XML content. + * + * @param xml XML content as {@link String}. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the XML content failed. + */ + public LibvirtXmlDocument( String xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException + { + this( xml, null ); + } + + /** + * Creates a Libvirt XML document from a given XML content. + * + * @param xml XML content as {@link String}. + * @param rngSchema RNG schema to validate XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the XML content failed. + */ + public LibvirtXmlDocument( String xml, InputStream rngSchema ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException + { + this.createXmlContext( rngSchema ); + this.fromXml( xml ); + } + + /** + * Creates a Libvirt XML document from a given XML content. + * + * @param xml XML content as {@link File}. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the XML content failed. + */ + public LibvirtXmlDocument( File xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException + { + this( xml, null ); + } + + /** + * Creates a Libvirt XML document from a given XML content. + * + * @param xml XML content as {@link File}. + * @param rngSchema RNG schema to validate XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the XML content failed. + */ + public LibvirtXmlDocument( File xml, InputStream rngSchema ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException + { + this.createXmlContext( rngSchema ); + this.fromXml( xml ); + } + + /** + * Creates a Libvirt XML document from a given XML content. + * + * @param xml XML content as {@link InputStream}. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the XML content failed. + */ + public LibvirtXmlDocument( InputStream xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException + { + this( xml, null ); + } + + /** + * Creates a Libvirt XML document from a given XML content. + * + * @param xml XML content as {@link InputStream}. + * @param rngSchema RNG schema to validate XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the XML content failed. + */ + public LibvirtXmlDocument( InputStream xml, InputStream rngSchema ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException + { + this.createXmlContext( rngSchema ); + this.fromXml( xml ); + } + + /** + * Creates a Libvirt XML document from a given XML content. + * + * @param xml XML content as {@link InputSource}. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the XML content failed. + */ + public LibvirtXmlDocument( InputSource xml ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException + { + this( xml, null ); + } + + /** + * Creates a Libvirt XML document from a given XML content. + * + * @param xml XML content as {@link InputSource}. + * @param rngSchema RNG schema to validate XML content. + * + * @throws LibvirtXmlDocumentException creation of XML context failed. + * @throws LibvirtXmlSerializationException serialization of the XML content failed. + */ + public LibvirtXmlDocument( InputSource xml, InputStream rngSchema ) + throws LibvirtXmlDocumentException, LibvirtXmlSerializationException + { + this.createXmlContext( rngSchema ); + this.fromXml( xml ); + } + + /** + * Returns the XML root node of the Libvirt XML document. + * + * @return root node of the Libvirt XML document. + */ + public LibvirtXmlNode getRootXmlNode() + { + return this.rootXmlNode; + } + + @Override + public void fromXml( String xml ) throws LibvirtXmlSerializationException + { + this.fromXml( new InputSource( new StringReader( xml ) ) ); + } + + @Override + public void fromXml( File xml ) throws LibvirtXmlSerializationException + { + try { + this.xmlDocument = this.domBuilder.parse( xml ); + this.xmlDocument.getDocumentElement().normalize(); + } catch ( SAXException e ) { + throw new LibvirtXmlSerializationException( e.getLocalizedMessage() ); + } catch ( IOException e ) { + throw new LibvirtXmlSerializationException( e.getLocalizedMessage() ); + } + + this.rootXmlNode = new LibvirtXmlNode( this.xmlDocument, this.xmlDocument.getDocumentElement() ); + } + + @Override + public void fromXml( InputStream xml ) throws LibvirtXmlSerializationException + { + try { + this.xmlDocument = this.domBuilder.parse( xml ); + this.xmlDocument.getDocumentElement().normalize(); + } catch ( SAXException e ) { + throw new LibvirtXmlSerializationException( e.getLocalizedMessage() ); + } catch ( IOException e ) { + throw new LibvirtXmlSerializationException( e.getLocalizedMessage() ); + } + + this.rootXmlNode = new LibvirtXmlNode( this.xmlDocument, this.xmlDocument.getDocumentElement() ); + } + + @Override + public void fromXml( InputSource xml ) throws LibvirtXmlSerializationException + { + try { + this.xmlDocument = this.domBuilder.parse( xml ); + this.xmlDocument.getDocumentElement().normalize(); + } catch ( SAXException e ) { + throw new LibvirtXmlSerializationException( e.getLocalizedMessage() ); + } catch ( IOException e ) { + throw new LibvirtXmlSerializationException( e.getLocalizedMessage() ); + } + + this.rootXmlNode = new LibvirtXmlNode( this.xmlDocument, this.xmlDocument.getDocumentElement() ); + } + + @Override + public String toXml() throws LibvirtXmlSerializationException + { + StringWriter xmlWriter = null; + String xml = null; + + try { + xmlWriter = new StringWriter(); + DOMSource source = new DOMSource( this.xmlDocument ); + StreamResult xmlString = new StreamResult( xmlWriter ); + this.xmlTransformer.transform( source, xmlString ); + xml = xmlWriter.toString(); + } catch ( Exception e ) { + throw new LibvirtXmlSerializationException( e.getLocalizedMessage() ); + } finally { + try { + xmlWriter.close(); + } catch ( Throwable e ) { + } + } + + return xml; + } + + @Override + public void toXml( File xml ) throws LibvirtXmlSerializationException + { + FileWriter xmlWriter = null; + + try { + xmlWriter = new FileWriter( xml ); + DOMSource source = new DOMSource( this.xmlDocument ); + StreamResult xmlStream = new StreamResult( xmlWriter ); + this.xmlTransformer.transform( source, xmlStream ); + } catch ( Exception e ) { + e.printStackTrace(); + throw new LibvirtXmlSerializationException( e.getLocalizedMessage() ); + } finally { + try { + xmlWriter.close(); + } catch ( Throwable e ) { + } + } + } + + @Override + public void validateXml() throws LibvirtXmlValidationException + { + if ( this.rngValidator != null ) { + this.rngValidator.validate( this.xmlDocument ); + } + } + + @Override + public String toString() + { + try { + return this.toXml(); + } catch ( LibvirtXmlSerializationException e ) { + return null; + } + } +} diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocumentException.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocumentException.java new file mode 100644 index 0000000..f8605ed --- /dev/null +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocumentException.java @@ -0,0 +1,25 @@ +package org.openslx.libvirt.xml; + +/** + * An exception of a Libvirt XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class LibvirtXmlDocumentException extends Exception +{ + /** + * Version number for serialization. + */ + private static final long serialVersionUID = -7423926322035713576L; + + /** + * Creates an document exception including an error message. + * + * @param errorMsg message to describe a specific document error. + */ + public LibvirtXmlDocumentException( String errorMsg ) + { + super( errorMsg ); + } +} diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlEditable.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlEditable.java new file mode 100644 index 0000000..0143e46 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlEditable.java @@ -0,0 +1,285 @@ +package org.openslx.libvirt.xml; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * Editability of XML nodes based on XPath expressions. + * + * @author Manuel Bentele + * @version 1.0 + */ +public interface LibvirtXmlEditable +{ + /** + * Returns XML node selected by a XPath expression + * + * @param expression XPath expression to select XML node. + * @return selected XML node. + */ + public Node getXmlNode( String expression ); + + /** + * Returns XML nodes selected by a XPath expression + * + * @param expression XPath expression to select XML nodes. + * @return selected XML nodes. + */ + public NodeList getXmlNodes( String expression ); + + /** + * Return current XML root element. + * + * @return current XML root element. + */ + public default Node getXmlElement() + { + return this.getXmlElement( null ); + } + + /** + * Returns XML element from selection by a XPath expression. + * + * @param expression XPath expression to select XML element. + * @return selected XML element. + */ + public Node getXmlElement( String expression ); + + /** + * Sets an XML element selected by a XPath expression. + * + * If the XML element selected by the given XPath expression does not exists, the XML + * element will be created. + * + * @param expression XPath expression to select XML element. + */ + public default void setXmlElement( String expression ) + { + this.setXmlElement( expression, null ); + } + + /** + * Sets a XML element selected by a XPath expression and appends child XML node. + * + * 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 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 XPath expression. + * + * @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 XPath expression. + * + * @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 XPath expression. + * + * @param expression XPath expression to select XML element. + */ + public void removeXmlElement( String expression ); + + /** + * Removes all child elements of the current XML root element. + */ + public default void removeXmlElementChilds() + { + this.removeXmlElementChilds( null ); + } + + /** + * Removes all child elements of a XML element selected by a XPath expression. + * + * @param expression XPath expression to select XML element. + */ + public void removeXmlElementChilds( String expression ); + + /** + * Returns the text value of a XML attribute from the current XML root element. + * + * @param attributeName name to select XML attribute of the current XML root element. + * @return attribute text of the XML attribute from the current XML root element as + * {@link String}. + */ + public default String getXmlElementAttributeValue( String attributeName ) + { + return this.getXmlElementAttributeValue( null, attributeName ); + } + + /** + * Returns the binary choice of a XML attribute from the current XML root element. + * + * If the text value of the XML attribute equals to <i>yes</i> or <i>on</i>, the returned + * {@link boolean} value is set to <i>true</i>. Otherwise, if the text value of the XML attribute + * equals to <i>no</i> or <i>off</i>, the returned {@link boolean} value is set to <i>false</i>. + * + * @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}. + */ + public default boolean getXmlElementAttributeValueAsBool( String attributeName ) + { + final String attributeValue = this.getXmlElementAttributeValue( attributeName ); + return "yes".equals( attributeValue ) || "on".equals( attributeValue ) || "true".equals( attributeValue ); + } + + /** + * 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 <i>yes</i> or <i>on</i>, the returned + * {@link boolean} value is set to <i>true</i>. Otherwise, if the text value of the XML attribute + * equals to <i>no</i> or <i>off</i>, the returned {@link boolean} value is set to <i>false</i>. + * + * @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}. + */ + public default boolean getXmlElementAttributeValueAsBool( String expression, String attributeName ) + { + final String attributeValue = this.getXmlElementAttributeValue( expression, attributeName ); + return "yes".equals( attributeValue ) || "on".equals( attributeValue ); + } + + /** + * Returns the text value of a XML attribute from a XML element selected by a XPath expression. + * + * @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. + */ + public String getXmlElementAttributeValue( String expression, String attributeName ); + + /** + * Sets the text value of a XML attribute from the current XML root element. + * + * @param attributeName name to select XML attribute of the current XML root element. + * @param value XML attribute value for the selected XML attribute from the current XML root + * element. + */ + public default void setXmlElementAttributeValue( String attributeName, String value ) + { + this.setXmlElementAttributeValue( null, attributeName, value ); + } + + /** + * Sets the binary choice value of a XML attribute from the current XML root element. + * + * If the binary choice value for the XML attribute equals to <i>true</i>, the text value of the + * selected XML attribute is set to <i>yes</i>. Otherwise, if the binary choice value for the + * selected XML attribute equals to <i>false</i>, the text value of the selected XML attribute is + * set to <i>no</i>. + * + * @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. + */ + public default void setXmlElementAttributeValueYesNo( String attributeName, boolean value ) + { + final String valueYesNo = value ? "yes" : "no"; + this.setXmlElementAttributeValue( attributeName, valueYesNo ); + } + + /** + * 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 <i>true</i>, the text value of the + * selected XML attribute is set to <i>yes</i>. Otherwise, if the binary choice value for the + * selected XML attribute equals to <i>false</i>, the text value of the selected XML attribute is + * set to <i>no</i>. + * + * @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. + */ + public default void setXmlElementAttributeValueYesNo( String expression, String attributeName, boolean value ) + { + final String valueYesNo = value ? "yes" : "no"; + this.setXmlElementAttributeValue( expression, attributeName, valueYesNo ); + } + + /** + * Sets the binary choice value of a XML attribute from the current XML root element. + * + * If the binary choice value for the XML attribute equals to <i>true</i>, the text value of the + * selected XML attribute is set to <i>on</i>. Otherwise, if the binary choice value for the + * selected XML attribute equals to <i>false</i>, the text value of the selected XML attribute is + * set to <i>off</i>. + * + * @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. + */ + public default void setXmlElementAttributeValueOnOff( String attributeName, boolean value ) + { + final String valueOnOff = value ? "on" : "off"; + this.setXmlElementAttributeValue( attributeName, valueOnOff ); + } + + /** + * 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 <i>true</i>, the text value of the + * selected XML attribute is set to <i>on</i>. Otherwise, if the binary choice value for the + * selected XML attribute equals to <i>false</i>, the text value of the selected XML attribute is + * set to <i>off</i>. + * + * @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. + */ + public default void setXmlElementAttributeValueOnOff( String expression, String attributeName, boolean value ) + { + final String valueOnOff = value ? "on" : "off"; + this.setXmlElementAttributeValue( expression, attributeName, valueOnOff ); + } + + /** + * Sets the text value of a XML attribute from a XML element selected by a XPath expression. + * + * @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. + */ + public void setXmlElementAttributeValue( String expression, String attributeName, String value ); + + /** + * Removes an XML attribute from the current XML root element. + * + * @param attributeName name of the attribute which should be deleted. + */ + public default void removeXmlElementAttribute( String attributeName ) + { + this.removeXmlElementAttribute( null, attributeName ); + } + + /** + * Removes an XML attribute from a XML element selected by a XPath expression. + * + * @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 XPath expression. + * + * @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 new file mode 100644 index 0000000..a941acb --- /dev/null +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java @@ -0,0 +1,350 @@ +package org.openslx.libvirt.xml; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * A representation of a XML node as part of a {@link LibvirtXmlDocument}. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class LibvirtXmlNode implements LibvirtXmlCreatable, LibvirtXmlEditable +{ + /** + * Separation character for internal XPath expressions. + */ + private static final String XPATH_EXPRESSION_SEPARATOR = "/"; + + /** + * Current XML node selection character for internal XPath expressions. + */ + private static final String XPATH_EXPRESSION_CURRENT_NODE = "."; + + /** + * Factory to create XPath objects. + */ + private XPathFactory xPathFactory = null; + + /** + * Representation of the XML document, in which this {@link LibvirtXmlNode} is part of. + */ + private Document xmlDocument = null; + + /** + * Current XML base node as XML root anchor for relative internal XPath expressions. + */ + private Node xmlBaseNode = null; + + /** + * Create and initialize XPath context to define and compile custom XPath expressions. + */ + private void createXPathContext() + { + this.xPathFactory = XPathFactory.newInstance(); + } + + /** + * Creates empty Libvirt XML node, which does not belong to any XML document and does not specify + * any XML base node. + * + * @implNote Please call {@link LibvirtXmlNode#setXmlDocument(Document)} and + * {@link LibvirtXmlNode#setXmlBaseNode(Node)} manually to obtain a functional Libvirt + * XML node. + */ + public LibvirtXmlNode() + { + this( null, null ); + } + + /** + * Creates Libvirt XML node from a existing Libvirt XML node by reference. + * + * @param xmlNode existing Libvirt XML node. + */ + public LibvirtXmlNode( LibvirtXmlNode xmlNode ) + { + this( xmlNode.getXmlDocument(), xmlNode.getXmlBaseNode() ); + } + + /** + * Creates Libvirt XML node as part of a existing XML document. + * + * @param xmlDocument existing XML document. + * + * @implNote Please call {@link LibvirtXmlNode#setXmlBaseNode(Node)} manually to obtain a + * functional Libvirt XML node. + */ + public LibvirtXmlNode( Document xmlDocument ) + { + this( xmlDocument, null ); + } + + /** + * Creates Libvirt XML node with a specific XML base node. + * + * @param xmlBaseNode existing XML base node. + * + * @implNote Please call {@link LibvirtXmlNode#setXmlDocument(Document)} manually to obtain a + * functional Libvirt XML node. + */ + public LibvirtXmlNode( Node xmlBaseNode ) + { + this( null, xmlBaseNode ); + } + + /** + * Creates Libvirt XML node with a specific XML base node as part of a XML document. + * + * @param xmlDocument existing XML document. + * @param xmlBaseNode existing XML base node. + */ + public LibvirtXmlNode( Document xmlDocument, Node xmlBaseNode ) + { + this.createXPathContext(); + + this.setXmlDocument( xmlDocument ); + this.setXmlBaseNode( xmlBaseNode ); + } + + /** + * Returns referenced XML document. + * + * @return referenced XML document. + */ + public Document getXmlDocument() + { + return this.xmlDocument; + } + + /** + * Sets existing XML document for Libvirt XML node. + * + * @param xmlDocument existing XML document. + */ + public void setXmlDocument( Document xmlDocument ) + { + this.xmlDocument = xmlDocument; + } + + /** + * Returns current XML base node. + * + * @return current XML base node as XML root anchor of relative internal XPath expressions. + */ + public Node getXmlBaseNode() + { + return this.xmlBaseNode; + } + + /** + * Sets existing XML base node for Libvirt XML node. + * + * @param xmlBaseNode existing XML base node as XML root anchor for relative internal XPath + * expressions. + */ + public void setXmlBaseNode( Node xmlBaseNode ) + { + this.xmlBaseNode = xmlBaseNode; + } + + @Override + public Node getXmlNode( String expression ) + { + if ( XPATH_EXPRESSION_CURRENT_NODE.equals( expression ) ) { + return this.xmlBaseNode; + } + NodeList nodes = this.getXmlNodes( expression ); + return nodes.item( 0 ); + } + + @Override + public NodeList getXmlNodes( String expression ) + { + Object nodes = null; + + try { + XPath xPath = this.xPathFactory.newXPath(); + XPathExpression xPathExpr = xPath.compile( expression ); + nodes = xPathExpr.evaluate( this.xmlBaseNode, XPathConstants.NODESET ); + } catch ( XPathExpressionException e ) { + e.printStackTrace(); + } + + return NodeList.class.cast( nodes ); + } + + @Override + public Element getXmlElement( String expression ) + { + String completeExpression = null; + + if ( expression == null || expression.isEmpty() ) { + completeExpression = XPATH_EXPRESSION_CURRENT_NODE; + } else { + completeExpression = XPATH_EXPRESSION_CURRENT_NODE + XPATH_EXPRESSION_SEPARATOR + expression; + } + + Node node = this.getXmlNode( completeExpression ); + + if ( node != null && node.getNodeType() == Node.ELEMENT_NODE ) { + return (Element)node; + } else { + return null; + } + } + + private Node createXmlElement( String expression ) + { + Node parentNode = this.xmlBaseNode; + Node currentNode = parentNode; + + if ( expression != null && !expression.isEmpty() ) { + String[] nodeNames = expression.split( XPATH_EXPRESSION_SEPARATOR ); + String partialExpression = XPATH_EXPRESSION_CURRENT_NODE; + + for ( int i = 0; i < nodeNames.length; i++ ) { + partialExpression += XPATH_EXPRESSION_SEPARATOR + nodeNames[i]; + currentNode = this.getXmlNode( partialExpression ); + + if ( currentNode == null ) { + currentNode = this.xmlDocument.createElement( nodeNames[i] ); + parentNode.appendChild( currentNode ); + } + + parentNode = currentNode; + } + } + + return currentNode; + } + + @Override + public void setXmlElement( String expression, Node child ) + { + Node node = this.createXmlElement( expression ); + + if ( child != null ) { + node.appendChild( child ); + } + } + + @Override + public String getXmlElementValue( String expression ) + { + Node node = this.getXmlElement( expression ); + + if ( node != null ) { + return node.getTextContent(); + } else { + return null; + } + } + + @Override + public void setXmlElementValue( String expression, String value ) + { + Node node = this.createXmlElement( expression ); + node.setTextContent( value ); + } + + @Override + public void removeXmlElement( String expression ) + { + Node node = this.getXmlElement( expression ); + + if ( node != null ) { + node.getParentNode().removeChild( node ); + } + } + + @Override + public void removeXmlElementChilds( String expression ) + { + Node node = this.getXmlElement( expression ); + + if ( node != null ) { + final NodeList childs = node.getChildNodes(); + while ( childs.getLength() > 0 ) { + Node child = childs.item( 0 ); + node.removeChild( child ); + } + } + } + + @Override + public String getXmlElementAttributeValue( String expression, String attributeName ) + { + Node node = this.getXmlElement( expression ); + + if ( node == null ) { + return null; + } else { + Node attribute = node.getAttributes().getNamedItem( attributeName ); + + if ( attribute == null ) { + return null; + } else { + return attribute.getNodeValue(); + } + } + } + + @Override + public void setXmlElementAttributeValue( String expression, String attributeName, String value ) + { + Node node = this.createXmlElement( expression ); + Node attribute = node.getAttributes().getNamedItem( attributeName ); + + if ( attribute == null ) { + Element element = Element.class.cast( node ); + element.setAttribute( attributeName, value ); + } else { + attribute.setNodeValue( value ); + } + } + + @Override + public void removeXmlElementAttribute( String expression, String attributeName ) + { + Node node = this.getXmlElement( expression ); + + if ( node != null ) { + Node attribute = node.getAttributes().getNamedItem( attributeName ); + node.getAttributes().removeNamedItem( attribute.getNodeName() ); + } + } + + @Override + public void removeXmlElementAttributes( String expression ) + { + Node node = this.getXmlElement( expression ); + + if ( node != null ) { + for ( int i = 0; i < node.getAttributes().getLength(); i++ ) { + Node attribute = node.getAttributes().item( 0 ); + node.getAttributes().removeNamedItem( attribute.getNodeName() ); + } + } + } + + @Override + public void fromXmlNode( Node xmlNode ) + { + this.setXmlBaseNode( xmlNode ); + } + + @Override + public Node toXmlNode() + { + return this.getXmlBaseNode(); + } +} diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlResources.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlResources.java new file mode 100644 index 0000000..5aa3a5b --- /dev/null +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlResources.java @@ -0,0 +1,105 @@ +package org.openslx.libvirt.xml; + +import java.io.InputStream; + +import org.openslx.util.Resources; + +/** + * Collection of resource utils for a Libvirt XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public final class LibvirtXmlResources +{ + /** + * File path prefix of the absolute path to the libvirt resource folder in a *.jar file. + */ + private static final String LIBVIRT_PREFIX_PATH = Resources.PATH_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 = Resources.PATH_SEPARATOR + "libvirt" + Resources.PATH_SEPARATOR + + "libosinfo"; + + /** + * File path prefix of the absolute path to the libvirt XSL resource folder in a *.jar file. + */ + private static final String LIBVIRT_PREFIX_PATH_XSL = LIBVIRT_PREFIX_PATH + Resources.PATH_SEPARATOR + "xsl"; + + /** + * File path prefix of the absolute path to the libvirt RNG resource folder in a *.jar file. + */ + private static final String LIBVIRT_PREFIX_PATH_RNG = LIBVIRT_PREFIX_PATH + Resources.PATH_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 + Resources.PATH_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 + Resources.PATH_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 + Resources.PATH_SEPARATOR + fileName; + return LibvirtXmlResources.class.getResourceAsStream( path ); + } + + /** + * Returns a Libvirt XSL resource as stream. + * + * @param libvirtXslFileName file name of the XSL resource in the resources *.jar folder. + * @return Libvirt XSL resource as stream. + */ + public static InputStream getLibvirtXsl( String libvirtXslFileName ) + { + return LibvirtXmlResources.getLibvirtResource( LibvirtXmlResources.LIBVIRT_PREFIX_PATH_XSL, libvirtXslFileName ); + } + + /** + * Returns a Libvirt RNG schema resource as stream. + * + * @param libvirtRngFileName file name of the RNG schema resource in the resources *.jar folder. + * @return Libvirt RNG schema resource as stream. + */ + public static InputStream getLibvirtRng( String libvirtRngFileName ) + { + 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/libvirt/xml/LibvirtXmlSchemaValidator.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSchemaValidator.java new file mode 100644 index 0000000..d589d41 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSchemaValidator.java @@ -0,0 +1,284 @@ +package org.openslx.libvirt.xml; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.nio.charset.StandardCharsets; + +import javax.xml.XMLConstants; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + +import org.w3c.dom.Document; +import org.w3c.dom.ls.LSInput; +import org.w3c.dom.ls.LSResourceResolver; +import org.xml.sax.SAXException; + +/** + * Resource resolver input for RelaxNG schemas. + * + * @author Manuel Bentele + * @version 1.0 + */ +class LibvirtXmlSchemaResourceInput implements LSInput +{ + /** + * Stores the public identification of the schema resource. + */ + private String publicId; + + /** + * Stores the system identification of the schema resource. + */ + private String systemId; + + /** + * Stream to process and read the schema resource. + */ + private BufferedInputStream inputStream; + + /** + * Creates a resource resolver input for a RelaxNG schema. + * + * @param publicId public identification of the schema resource. + * @param sysId system identification of the schema resource. + * @param input stream of the schema resource. + */ + public LibvirtXmlSchemaResourceInput( String publicId, String sysId, InputStream input ) + { + this.publicId = publicId; + this.systemId = sysId; + this.inputStream = new BufferedInputStream( input ); + } + + @Override + public String getBaseURI() + { + return null; + } + + @Override + public InputStream getByteStream() + { + return null; + } + + @Override + public boolean getCertifiedText() + { + return false; + } + + @Override + public Reader getCharacterStream() + { + return null; + } + + @Override + public String getEncoding() + { + return null; + } + + @Override + public String getPublicId() + { + return this.publicId; + } + + @Override + public String getStringData() + { + String data = null; + + synchronized ( this.inputStream ) { + try { + int inputLength = this.inputStream.available(); + byte[] input = new byte[ inputLength ]; + this.inputStream.read( input ); + data = new String( input, StandardCharsets.UTF_8 ); + } catch ( IOException e ) { + e.printStackTrace(); + } + } + + return data; + } + + @Override + public String getSystemId() + { + return this.systemId; + } + + @Override + public void setBaseURI( String arg0 ) + { + } + + @Override + public void setByteStream( InputStream arg0 ) + { + } + + @Override + public void setCertifiedText( boolean arg0 ) + { + } + + @Override + public void setCharacterStream( Reader arg0 ) + { + } + + @Override + public void setEncoding( String arg0 ) + { + } + + @Override + public void setPublicId( String arg0 ) + { + this.publicId = arg0; + } + + @Override + public void setStringData( String arg0 ) + { + } + + @Override + public void setSystemId( String arg0 ) + { + this.systemId = arg0; + } +} + +/** + * Resource resolver for RelaxNG schemas. + * + * @author Manuel Bentele + * @version 1.0 + */ +class LibvirtXmlSchemaResourceResolver implements LSResourceResolver +{ + @Override + public LSInput resolveResource( String type, String namespaceURI, String publicId, String systemId, String baseURI ) + { + InputStream rngResourceStream = LibvirtXmlResources.getLibvirtRng( systemId ); + return new LibvirtXmlSchemaResourceInput( publicId, systemId, rngResourceStream ); + } +} + +/** + * Validator for validation of Libvirt XML documents with RelaxNG schemas. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class LibvirtXmlSchemaValidator +{ + /** + * RelaxNG based validator for validation of Libvirt XML documents. + */ + private Validator rngSchemaValidator; + + /** + * Creates a validator for validation of Libvirt XML documents with RelaxNG schemas. + * + * @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 + { + this.createValidationContext( rngSchema ); + } + + /** + * Creates context for validation of Libvirt XML documents with a RelaxNG schema. + * + * @param rngSchema RelaxNG schema used for validation with {@link #validate(Document)}. + * + * @throws SAXException Loading, creation and processing of <code>rngSchema</code> has failed. + */ + private void createValidationContext( InputStream rngSchema ) throws SAXException + { + // use hack to load specific schema factory implementation for RelaxNG schemas + System.setProperty( SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI, + "com.thaiopensource.relaxng.jaxp.XMLSyntaxSchemaFactory" ); + + // create schema resource resolver to resolve schema resources during parsing and validation + LibvirtXmlSchemaResourceResolver schemaResolver = new LibvirtXmlSchemaResourceResolver(); + + // create schema factory to be able to create a RelaxNG schema validator + SchemaFactory factory = SchemaFactory.newInstance( XMLConstants.RELAXNG_NS_URI ); + factory.setResourceResolver( schemaResolver ); + Schema schema = factory.newSchema( new StreamSource( rngSchema ) ); + + // create the RelaxNG schema validator + this.rngSchemaValidator = schema.newValidator(); + this.rngSchemaValidator.setResourceResolver( schemaResolver ); + } + + /** + * Transforms a DOM source to a Stream source. + * + * @param domSource DOM source of a Libvirt XML document. + * @return Stream source of a Libvirt XML document. + * + * @throws TransformerException Transformation of DOM source to a Stream source has failed. + * + * @implNote This utility method is necessary in {@link #validate(Document)} to be able to + * validate a DOM Libvirt XML document with the schema and validator implementation for + * RelaxNG schema files from + * <code>com.thaiopensource.relaxng.jaxp.XMLSyntaxSchemaFactory</code>. + */ + private static StreamSource toStreamSource( DOMSource domSource ) throws TransformerException + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + StreamResult result = new StreamResult( outputStream ); + + // create identity transformer + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.transform( domSource, result ); + + ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() ); + return new StreamSource( inputStream ); + } + + /** + * Validates a given (and parsed) DOM Libvirt XML document. + * + * Validation takes place if the specified <code>xmlDocument</code> is non-null, otherwise the + * validation succeeds immediately. If the validation of the <code>xmlDocument</code> fails, a + * validation exception is thrown. + * + * @param xmlDocument Libvirt XML document. + * + * @throws LibvirtXmlValidationException Validation of Libvirt XML document failed. + */ + public void validate( Document xmlDocument ) throws LibvirtXmlValidationException + { + if ( xmlDocument != null ) { + try { + DOMSource domSource = new DOMSource( xmlDocument ); + StreamSource source = LibvirtXmlSchemaValidator.toStreamSource( domSource ); + this.rngSchemaValidator.validate( source ); + } catch ( SAXException | TransformerException | IOException e ) { + throw new LibvirtXmlValidationException( e.getLocalizedMessage() ); + } + } + } +} diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializable.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializable.java new file mode 100644 index 0000000..4cd0a32 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializable.java @@ -0,0 +1,69 @@ +package org.openslx.libvirt.xml; + +import java.io.File; +import java.io.InputStream; + +import org.xml.sax.InputSource; + +/** + * Serializability of a Libvirt XML document from/to a XML file. + * + * @author Manuel Bentele + * @version 1.0 + */ +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; + + /** + * 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; + + /** + * 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; + + /** + * 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; + + /** + * 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; + + /** + * 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/libvirt/xml/LibvirtXmlSerializationException.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializationException.java new file mode 100644 index 0000000..d522107 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializationException.java @@ -0,0 +1,25 @@ +package org.openslx.libvirt.xml; + +/** + * An exception of an serialization error during Libvirt XML serialization. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class LibvirtXmlSerializationException extends Exception +{ + /** + * Version number for serialization. + */ + private static final long serialVersionUID = 7995955592221349949L; + + /** + * Creates a XML serialization exception including an error message. + * + * @param errorMsg message to describe a specific XML serialization error. + */ + public LibvirtXmlSerializationException( String errorMsg ) + { + super( errorMsg ); + } +} diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidatable.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidatable.java new file mode 100644 index 0000000..8574cc4 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidatable.java @@ -0,0 +1,18 @@ +package org.openslx.libvirt.xml; + +/** + * Validatability of Libvirt XML document. + * + * @author Manuel Bentele + * @version 1.0 + */ +public abstract interface LibvirtXmlValidatable +{ + /** + * Validates the XML document's content and report error if document is not a valid Libvirt XML + * document. + * + * @throws LibvirtXmlValidationException XML content is not a valid Libvirt XML. + */ + public void validateXml() throws LibvirtXmlValidationException; +} diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidationException.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidationException.java new file mode 100644 index 0000000..24e9db7 --- /dev/null +++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidationException.java @@ -0,0 +1,25 @@ +package org.openslx.libvirt.xml; + +/** + * An exception of an unsuccessful Libvirt XML validation. + * + * @author Manuel Bentele + * @version 1.0 + */ +public class LibvirtXmlValidationException extends Exception +{ + /** + * Version number for serialization. + */ + private static final long serialVersionUID = 2299967599483742777L; + + /** + * Creates a validation exception including an error message. + * + * @param errorMsg message to describe a specific Libvirt XML error. + */ + public LibvirtXmlValidationException( String errorMsg ) + { + super( errorMsg ); + } +} |