diff options
author | Simon Rettberg | 2024-09-19 11:56:48 +0200 |
---|---|---|
committer | Simon Rettberg | 2024-09-19 11:56:48 +0200 |
commit | 31678dce36c9eaa4b3382088e98114bf22c003a9 (patch) | |
tree | cd4947f3b753924d8d72f96061ab7982819a1cbc | |
parent | fileserver: Also silence socket timeouts (diff) | |
download | master-sync-shared-31678dce36c9eaa4b3382088e98114bf22c003a9.tar.gz master-sync-shared-31678dce36c9eaa4b3382088e98114bf22c003a9.tar.xz master-sync-shared-31678dce36c9eaa4b3382088e98114bf22c003a9.zip |
[libvirt] Add support for <redirdev> devices
6 files changed, 259 insertions, 9 deletions
diff --git a/src/main/java/org/openslx/libvirt/domain/Domain.java b/src/main/java/org/openslx/libvirt/domain/Domain.java index af3e63c..b059353 100644 --- a/src/main/java/org/openslx/libvirt/domain/Domain.java +++ b/src/main/java/org/openslx/libvirt/domain/Domain.java @@ -37,6 +37,7 @@ 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.RedirDevice; import org.openslx.libvirt.domain.device.Serial; import org.openslx.libvirt.domain.device.Shmem; import org.openslx.libvirt.domain.device.Sound; @@ -1269,6 +1270,11 @@ public class Domain extends LibvirtXmlDocument return Domain.filterDevices( Video.class, this.getDevices() ); } + public ArrayList<RedirDevice> getRedirectDevices() + { + return Domain.filterDevices( RedirDevice.class, this.getDevices() ); + } + /** * Returns the values of QEMU command line arguments from the Libvirt domain XML document. * diff --git a/src/main/java/org/openslx/libvirt/domain/device/BusType.java b/src/main/java/org/openslx/libvirt/domain/device/BusType.java new file mode 100644 index 0000000..e0ce50e --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/BusType.java @@ -0,0 +1,59 @@ +package org.openslx.libvirt.domain.device; + +/** + * Union of all known bus types, for generic querying. + */ +public enum BusType +{ + // @formatter:off + MDEV ( "mdev" ), + PCI ( "pci" ), + SATA ( "sata" ), + PS2 ( "ps2" ), + VIRTIO( "virtio" ), + IDE ( "ide" ), + FDC ( "fdc" ), + SCSI ( "scsi" ), + SD ( "sd" ), + XEN ( "xen" ), + 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. + */ + BusType( 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 BusType fromString( String type ) + { + for ( BusType t : BusType.values() ) { + if ( t.type.equalsIgnoreCase( type ) ) { + return t; + } + } + + return null; + } +}
\ No newline at end of file diff --git a/src/main/java/org/openslx/libvirt/domain/device/Device.java b/src/main/java/org/openslx/libvirt/domain/device/Device.java index 31a54ca..e3adf90 100644 --- a/src/main/java/org/openslx/libvirt/domain/device/Device.java +++ b/src/main/java/org/openslx/libvirt/domain/device/Device.java @@ -152,6 +152,9 @@ public class Device extends LibvirtXmlNode implements HostdevAddressableTarget<H case PARALLEL: device = Parallel.newInstance( xmlNode ); break; + case REDIRDEV: + device = RedirDevice.newInstance( xmlNode ); + break; case SERIAL: device = Serial.newInstance( xmlNode ); break; @@ -171,6 +174,19 @@ public class Device extends LibvirtXmlNode implements HostdevAddressableTarget<H } /** + * Sets the USB device address for an XML address element selected by a XPath expression. + * + * @param expression XPath expression to select the XML address element. + * @param address USB device address for the selected XML address element. + */ + protected void setUsbAddress( final String expression, final HostdevUsbDeviceAddress address ) + { + this.setXmlElementAttributeValue( expression, "bus", Integer.toString( address.getUsbBus() ) ); + this.setXmlElementAttributeValue( expression, "port", Integer.toString( address.getUsbPort() ) ); + this.setXmlElementAttributeValue( expression, "type", BusType.USB.toString() ); + } + + /** * 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. @@ -187,6 +203,7 @@ public class Device extends LibvirtXmlNode implements HostdevAddressableTarget<H this.setXmlElementAttributeValue( expression, "bus", pciBus ); this.setXmlElementAttributeValue( expression, "slot", pciDevice ); this.setXmlElementAttributeValue( expression, "function", pciFunction ); + this.setXmlElementAttributeValue( expression, "type", BusType.PCI.toString() ); } /** @@ -224,6 +241,36 @@ public class Device extends LibvirtXmlNode implements HostdevAddressableTarget<H public void setPciTarget( HostdevPciDeviceAddress address ) { this.setPciAddress( "address", address ); + } + + /** + * Returns the USB device address from an address XML element selected by a XPath expression. + * + * @param expression XPath expression to select the XML address element. + * @return USB device address from the selected XML address element. + */ + protected HostdevUsbDeviceAddress getUsbAddress( final String expression ) + { + String bus = this.getXmlElementAttributeValue( expression, "bus" ); + String port = this.getXmlElementAttributeValue( expression, "port" ); + + return HostdevUsbDeviceAddress.valueOf( bus, port ); + } + + /** + * Returns this devices USB bus/port address, or null if it doesn't have an explicit one + * set, or if the address type isn't USB. + */ + public HostdevUsbDeviceAddress getUsbTarget() + { + if ( !"usb".equals( this.getXmlElementAttributeValue( "address", "type" ) ) ) + return null; + return this.getUsbAddress( "address" ); + } + + public void setUsbTarget( HostdevUsbDeviceAddress address ) + { + this.setUsbAddress( "address", address ); this.setXmlElementAttributeValue( "address", "type", "pci" ); } @@ -243,6 +290,7 @@ public class Device extends LibvirtXmlNode implements HostdevAddressableTarget<H INTERFACE ( "interface" ), GRAPHICS ( "graphics" ), PARALLEL ( "parallel" ), + REDIRDEV ( "redirdev" ), SERIAL ( "serial" ), SHMEM ( "shmem" ), SOUND ( "sound" ), diff --git a/src/main/java/org/openslx/libvirt/domain/device/Hostdev.java b/src/main/java/org/openslx/libvirt/domain/device/Hostdev.java index dc9cf5e..f69ac9d 100644 --- a/src/main/java/org/openslx/libvirt/domain/device/Hostdev.java +++ b/src/main/java/org/openslx/libvirt/domain/device/Hostdev.java @@ -77,13 +77,13 @@ public class Hostdev extends Device xmlNode.setXmlElementAttributeValue( "mode", "subsystem" ); if ( hostdev instanceof HostdevMdev ) { - xmlNode.setXmlElementAttributeValue( "type", Type.MDEV.toString() ); + xmlNode.setXmlElementAttributeValue( "type", HostdevType.MDEV.toString() ); addedHostdev = HostdevMdev.createInstance( xmlNode ); } else if ( hostdev instanceof HostdevPci ) { - xmlNode.setXmlElementAttributeValue( "type", Type.PCI.toString() ); + xmlNode.setXmlElementAttributeValue( "type", HostdevType.PCI.toString() ); addedHostdev = HostdevPci.createInstance( xmlNode ); } else if ( hostdev instanceof HostdevUsb ) { - xmlNode.setXmlElementAttributeValue( "type", Type.USB.toString() ); + xmlNode.setXmlElementAttributeValue( "type", HostdevType.USB.toString() ); addedHostdev = HostdevUsb.createInstance( xmlNode ); } @@ -99,7 +99,7 @@ public class Hostdev extends Device public static Hostdev newInstance( LibvirtXmlNode xmlNode ) { Hostdev deviceHostdev = null; - Type type = Type.fromString( xmlNode.getXmlElementAttributeValue( "type" ) ); + HostdevType type = HostdevType.fromString( xmlNode.getXmlElementAttributeValue( "type" ) ); if ( type == null ) { return null; @@ -126,7 +126,7 @@ public class Hostdev extends Device * @author Manuel Bentele * @version 1.0 */ - enum Type + enum HostdevType { // @formatter:off MDEV( "mdev" ), @@ -144,7 +144,7 @@ public class Hostdev extends Device * * @param type valid name of the hostdev device type in a Libvirt domain XML document. */ - Type( String type ) + HostdevType( String type ) { this.type = type; } @@ -161,9 +161,9 @@ public class Hostdev extends Device * @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 ) + public static HostdevType fromString( String type ) { - for ( Type t : Type.values() ) { + for ( HostdevType t : HostdevType.values() ) { if ( t.type.equalsIgnoreCase( type ) ) { return t; } diff --git a/src/main/java/org/openslx/libvirt/domain/device/RedirDevice.java b/src/main/java/org/openslx/libvirt/domain/device/RedirDevice.java new file mode 100644 index 0000000..2656bbe --- /dev/null +++ b/src/main/java/org/openslx/libvirt/domain/device/RedirDevice.java @@ -0,0 +1,129 @@ +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 RedirDevice extends Device +{ + /** + * Creates an empty video device. + */ + public RedirDevice() + { + super(); + } + + /** + * Creates a redirect device representing an existing Libvirt XML redirect device element. + */ + public RedirDevice( LibvirtXmlNode xmlNode ) + { + super( xmlNode ); + } + + /** + * Returns type of redirect device. + */ + public SrcType getSrcType() + { + String type = this.getXmlElementAttributeValue( "type" ); + return SrcType.fromString( type ); + } + + /** + * Sets type for the redirect device. + */ + public void setSrcType( SrcType type ) + { + this.setXmlElementAttributeValue( "type", type.toString() ); + } + + /** + * Get bus type. + */ + public BusType getBus() + { + return BusType.fromString( this.getXmlElementAttributeValue( "bus" ) ); + } + + /** + * 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 RedirDevice createInstance( LibvirtXmlNode xmlNode ) + { + return RedirDevice.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 RedirDevice newInstance( LibvirtXmlNode xmlNode ) + { + return new RedirDevice( xmlNode ); + } + + /** + * Type of redirected device. + */ + public enum SrcType + { + // @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" ), + QEMU_VDAGENT( "qemu-vdagent" ), + DBUS ( "dbus" ); + // @formatter:on + + /** + * Type of device redirect, as expected in the xml file. + */ + private String typeString = null; + + SrcType( String typeString ) + { + this.typeString = typeString; + } + + @Override + public String toString() + { + return this.typeString; + } + + /** + * Returns Type instance from its name with error check. + */ + public static SrcType fromString( String model ) + { + for ( SrcType m : SrcType.values() ) { + if ( m.typeString.equalsIgnoreCase( model ) ) { + return m; + } + } + + return null; + } + } +} diff --git a/src/test/java/org/openslx/libvirt/domain/DomainTest.java b/src/test/java/org/openslx/libvirt/domain/DomainTest.java index f55c511..d73abe0 100644 --- a/src/test/java/org/openslx/libvirt/domain/DomainTest.java +++ b/src/test/java/org/openslx/libvirt/domain/DomainTest.java @@ -412,7 +412,7 @@ public class DomainTest public void testGetDevices() { Domain vm = DomainTest.getDomain( "qemu-kvm_default-ubuntu-20-04-vm.xml" ); - assertEquals( 22, vm.getDevices().size() ); + assertEquals( 24, vm.getDevices().size() ); } @Test @@ -496,6 +496,14 @@ public class DomainTest } @Test + @DisplayName( "Get all Redir devices from libvirt XML file" ) + public void testGetRedirDevices() + { + Domain vm = DomainTest.getDomain( "qemu-kvm_default-ubuntu-20-04-vm.xml" ); + assertEquals( 2, vm.getRedirectDevices().size() ); + } + + @Test @DisplayName( "Get all QEMU command line arguments from libvirt XML file" ) public void testGetQemuCmdlnArguments() { |