[virt-tools-list] [PATCH 3/4] Add --redirdev device

Marc-André Lureau marcandre.lureau at gmail.com
Fri Sep 2 01:21:18 UTC 2011


Allows to add a redirected device.

USB redirection via TCP server:

--redirdev usb,type=tcp,server=host:port

Or over Spice:

--redirdev usb,type=spicevmc
---
 man/en/virt-install.1         |   38 ++++++++++++++++++++++++++-----
 man/en/virt-install.pod.in    |   28 +++++++++++++++++++++++
 tests/clitest.py              |   28 +++++++++++++++++++++++
 tests/xmlparse.py             |   18 +++++++++++++++
 virt-install                  |    1 +
 virtinst/Guest.py             |    1 +
 virtinst/VirtualDevice.py     |    4 ++-
 virtinst/VirtualHostDevice.py |    1 +
 virtinst/__init__.py          |    4 ++-
 virtinst/cli.py               |   49 +++++++++++++++++++++++++++++++++++++++++
 10 files changed, 164 insertions(+), 8 deletions(-)

diff --git a/man/en/virt-install.1 b/man/en/virt-install.1
index 7bd35df..31c9c10 100644
--- a/man/en/virt-install.1
+++ b/man/en/virt-install.1
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "VIRT-INSTALL 1"
-.TH VIRT-INSTALL 1 "2011-07-28" "" "Virtual Machine Install Tools"
+.TH VIRT-INSTALL 1 "2011-09-02" "" "Virtual Machine Install Tools"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -415,6 +415,8 @@ Values for some recent \s-1OS\s0 options are:
 .IX Item "freebsd8             : FreeBSD 8.x"
 .IP "generic              : Generic" 2
 .IX Item "generic              : Generic"
+.IP "debianwheezy         : Debian Wheezy" 2
+.IX Item "debianwheezy         : Debian Wheezy"
 .IP "debiansqueeze        : Debian Squeeze" 2
 .IX Item "debiansqueeze        : Debian Squeeze"
 .IP "debianlenny          : Debian Lenny" 2
@@ -988,18 +990,18 @@ Named pipe (see \fIpipe\fR\|(7))
 .IP "\fB\-\-serial tcp,host=HOST:PORT,mode=MODE,protocol=PROTOCOL\fR" 4
 .IX Item "--serial tcp,host=HOST:PORT,mode=MODE,protocol=PROTOCOL"
 \&\s-1TCP\s0 net console. \s-1MODE\s0 is either 'bind' (wait for connections on \s-1HOST:PORT\s0)
-or 'connect' (send output to \s-1HOST:PORT\s0), default is 'connect'. \s-1HOST\s0 defaults
+or 'connect' (send output to \s-1HOST:PORT\s0), default is 'bind'. \s-1HOST\s0 defaults
 to '127.0.0.1', but \s-1PORT\s0 is required. \s-1PROTOCOL\s0 can be either 'raw' or 'telnet'
 (default 'raw'). If 'telnet', the port acts like a telnet server or client.
 Some examples:
 .Sp
-Connect to localhost, port 1234:
+Wait for connections on any address, port 4567:
 .Sp
-\&\-\-serial tcp,host=:1234
+\&\-\-serial tcp,host=0.0.0.0:4567
 .Sp
-Wait for connections on any address, port 4567:
+Connect to localhost, port 1234:
 .Sp
-\&\-\-serial tcp,host=0.0.0.0:4567,mode=bind
+\&\-\-serial tcp,host=:1234,mode=connect
 .Sp
 Wait for telnet connection on localhost, port 2222. The user could then
 connect interactively to this console via 'telnet localhost 2222':
@@ -1106,6 +1108,30 @@ to the guest
 See \f(CW\*(C`http://libvirt.org/formatdomain.html#elementsSmartcard\*(C'\fR for complete
 details.
 .RE
+.IP "\-\-redirdev=BUS[,OPTS]" 2
+.IX Item "--redirdev=BUS[,OPTS]"
+Add a redirected device.
+.RS 2
+.IP "\fBtype\fR" 4
+.IX Item "type"
+The redirection type, currently supported is \fBtcp\fR or \fBspicevmc\fR.
+.IP "\fBserver\fR" 4
+.IX Item "server"
+The \s-1TCP\s0 server connection details, of the form 'server:port'.
+.RE
+.RS 2
+.Sp
+Examples of invocation:
+.IP "\fB\-\-redirdev usb,type=tcp,server=localhost:4000\fR" 4
+.IX Item "--redirdev usb,type=tcp,server=localhost:4000"
+Add a \s-1USB\s0 redirected device provided by the \s-1TCP\s0 server on 'localhost'
+port 4000.
+.IP "\fB\-\-redirdev usb,type=spicevmc\fR" 4
+.IX Item "--redirdev usb,type=spicevmc"
+Add a \s-1USB\s0 device redirected via a dedicated Spice channel.
+.RE
+.RS 2
+.RE
 .SS "Miscellaneous Options"
 .IX Subsection "Miscellaneous Options"
 .IP "\-\-autostart" 2
diff --git a/man/en/virt-install.pod.in b/man/en/virt-install.pod.in
index da4142d..8239067 100644
--- a/man/en/virt-install.pod.in
+++ b/man/en/virt-install.pod.in
@@ -1104,8 +1104,36 @@ to the guest
 See C<http://libvirt.org/formatdomain.html#elementsSmartcard> for complete
 details.
 
+=item --redirdev=BUS[,OPTS]
 
+Add a redirected device.
 
+=over 4
+
+=item B<type>
+
+The redirection type, currently supported is B<tcp> or B<spicevmc>.
+
+=item B<server>
+
+The TCP server connection details, of the form 'server:port'.
+
+=back
+
+Examples of invocation:
+
+=over 4
+
+=item B<--redirdev usb,type=tcp,server=localhost:4000>
+
+Add a USB redirected device provided by the TCP server on 'localhost'
+port 4000.
+
+=item B<--redirdev usb,type=spicevmc>
+
+Add a USB device redirected via a dedicated Spice channel.
+
+=back
 
 =back
 
diff --git a/tests/clitest.py b/tests/clitest.py
index 9fe2d2f..128e1f2 100644
--- a/tests/clitest.py
+++ b/tests/clitest.py
@@ -698,6 +698,34 @@ args_dict = {
       ],
      }, # category "hostdev"
 
+     "redirdev" : {
+      "args": "--noautoconsole --nographics --nodisks --pxe",
+
+      "valid" : [
+        "--redirdev usb,type=spicevmc",
+        "--redirdev usb,type=tcp,server=localhost:4000",
+        # Different host server
+        "--redirdev usb,type=tcp,server=127.0.0.1:4002",
+      ],
+
+      "invalid" : [
+        # Missing argument
+        "--redirdev",
+        # Unsupported bus
+        "--redirdev pci",
+        # Invalid argument
+        "--redirdev usb,type=spicevmc,server=foo:12",
+        # Missing argument
+        "--redirdev usb,type=tcp,server=",
+        # Invalid address
+        "--redirdev usb,type=tcp,server=localhost:p4000",
+        # Missing address
+        "--redirdev usb,type=tcp,server=localhost:",
+        # Missing host
+        "--redirdev usb,type=tcp,server=:399",
+      ],
+     }, # category "redirdev"
+
      "remote" : {
       "args": "--connect %(REMOTEURI)s --nographics --noautoconsole",
 
diff --git a/tests/xmlparse.py b/tests/xmlparse.py
index 0ec0ad9..674f28e 100644
--- a/tests/xmlparse.py
+++ b/tests/xmlparse.py
@@ -672,6 +672,24 @@ class XMLParseTest(unittest.TestCase):
 
         self._alter_compare(guest.get_config_xml(), outfile)
 
+    def testAlterRedirdev(self):
+        infile  = "tests/xmlparse-xml/change-redirdev-in.xml"
+        outfile = "tests/xmlparse-xml/change-redirdev-out.xml"
+        guest = virtinst.Guest(conn=conn,
+                               parsexml=file(infile).read())
+
+        dev1 = guest.get_devices("redirdev")[0]
+        dev2 = guest.get_devices("redirdev")[1]
+
+        check = self._make_checker(dev1)
+        check("host", "foo", "bar")
+        check("service", "12", "42")
+
+        check = self._make_checker(dev2)
+        check("type", "spicevmc")
+
+        self._alter_compare(guest.get_config_xml(), outfile)
+
     def testConsoleCompat(self):
         infile  = "tests/xmlparse-xml/console-compat-in.xml"
         outfile = "tests/xmlparse-xml/console-compat-out.xml"
diff --git a/virt-install b/virt-install
index e398481..1dd97a6 100755
--- a/virt-install
+++ b/virt-install
@@ -491,6 +491,7 @@ def build_guest_instance(conn, options):
 
     # Non-default devices
     cli.get_controller(guest, options.controller)
+    cli.get_redirdev(guest, options.redirdev)
     if not options.nonetworks:
         get_networks(guest, options)
     get_graphics(guest, options)
diff --git a/virtinst/Guest.py b/virtinst/Guest.py
index dfb5ed2..3dd04d1 100644
--- a/virtinst/Guest.py
+++ b/virtinst/Guest.py
@@ -772,6 +772,7 @@ class Guest(XMLBuilderDomain.XMLBuilderDomain):
             "controller": virtinst.VirtualController,
             "filesystem": virtinst.VirtualFilesystem,
             "smartcard" : virtinst.VirtualSmartCardDevice,
+            "redirdev"   : virtinst.VirtualRedirDevice,
         }
 
         # Hand off all child element parsing to relevant classes
diff --git a/virtinst/VirtualDevice.py b/virtinst/VirtualDevice.py
index e817bf7..2234979 100644
--- a/virtinst/VirtualDevice.py
+++ b/virtinst/VirtualDevice.py
@@ -43,6 +43,7 @@ class VirtualDevice(XMLBuilderDomain):
     VIRTUAL_DEV_WATCHDOG        = "watchdog"
     VIRTUAL_DEV_FILESYSTEM      = "filesystem"
     VIRTUAL_DEV_SMARTCARD       = "smartcard"
+    VIRTUAL_DEV_REDIRDEV        = "redirdev"
 
     # Ordering in this list is important: it will be the order the
     # Guest class outputs XML. So changing this may upset the test suite
@@ -60,7 +61,8 @@ class VirtualDevice(XMLBuilderDomain):
                             VIRTUAL_DEV_VIDEO,
                             VIRTUAL_DEV_HOSTDEV,
                             VIRTUAL_DEV_WATCHDOG,
-                            VIRTUAL_DEV_SMARTCARD]
+                            VIRTUAL_DEV_SMARTCARD,
+                            VIRTUAL_DEV_REDIRDEV]
 
     # General device type (disk, interface, etc.)
     _virtual_device_type = None
diff --git a/virtinst/VirtualHostDevice.py b/virtinst/VirtualHostDevice.py
index 2175266..b90518d 100644
--- a/virtinst/VirtualHostDevice.py
+++ b/virtinst/VirtualHostDevice.py
@@ -245,6 +245,7 @@ class VirtualHostDeviceUSB(VirtualHostDevice):
         # No libvirt api support for USB Detach/Reset yet
         return
 
+
 class VirtualHostDevicePCI(VirtualHostDevice):
 
     def __init__(self, conn, nodedev=None):
diff --git a/virtinst/__init__.py b/virtinst/__init__.py
index d7c328b..efa4d0d 100644
--- a/virtinst/__init__.py
+++ b/virtinst/__init__.py
@@ -50,6 +50,7 @@ from VirtualController import VirtualController
 from VirtualWatchdog import VirtualWatchdog
 from VirtualFilesystem import VirtualFilesystem
 from VirtualSmartCardDevice import VirtualSmartCardDevice
+from VirtualRedirDevice import VirtualRedirDevice
 from FullVirtGuest import FullVirtGuest
 from ParaVirtGuest import ParaVirtGuest
 from DistroInstaller import DistroInstaller
@@ -80,4 +81,5 @@ __all__ = ["Guest", "XenGuest", "VirtualNetworkInterface",
            "VirtualHostDevice", "VirtualHostDeviceUSB", "VirtualVideoDevice",
            "VirtualHostDevicePCI", "VirtualCharDevice", "VirtualInputDevice",
            "VirtualController", "VirtualWatchdog",
-           "VirtualFilesystem", "VirtualSmartCardDevice"]
+           "VirtualFilesystem", "VirtualSmartCardDevice",
+           "VirtualHostDeviceUSBRedir"]
diff --git a/virtinst/cli.py b/virtinst/cli.py
index 40cabff..14ecbe7 100644
--- a/virtinst/cli.py
+++ b/virtinst/cli.py
@@ -1007,6 +1007,16 @@ def get_controller(guest, sc_opts):
         if dev:
             guest.add_device(dev)
 
+def get_redirdev(guest, sc_opts):
+    for sc in listify(sc_opts):
+        try:
+            dev = parse_redirdev(guest, sc)
+        except Exception, e:
+            fail(_("Error in redirdev device parameters: %s") % str(e))
+
+        if dev:
+            guest.add_device(dev)
+
 #############################
 # Common CLI option/group   #
 #############################
@@ -1099,6 +1109,9 @@ def add_device_options(devg):
     devg.add_option("", "--smartcard", dest="smartcard", action="append",
                     help=_("Configure a guest smartcard device. Ex:\n"
                            "--smartcard mode=passthrough"))
+    devg.add_option("", "--redirdev", dest="redirdev", action="append",
+                    help=_("Configure a guest redirection device. Ex:\n"
+                           "--redirdev usb,type=tcp,server=192.168.1.1:4000"))
 
 def add_gfx_option(devg):
     devg.add_option("", "--graphics", dest="graphics", action="append",
@@ -1752,6 +1765,42 @@ def parse_smartcard(guest, optstring, dev=None):
     return dev
 
 ######################
+# --redirdev parsing #
+######################
+
+def parse_redirdev(guest, optstring, dev=None):
+    if optstring is None:
+        return None
+
+    # Peel the mode off the front
+    opts = parse_optstr(optstring, remove_first="bus")
+    bus = get_opt_param(opts, "bus")
+    stype = get_opt_param(opts, "type")
+    server = get_opt_param(opts, "server")
+
+    if bus == "none":
+        return None
+
+    if not dev:
+        dev = virtinst.VirtualRedirDevice(bus=bus,
+                                          stype=stype,
+                                          conn=guest.conn)
+
+    if stype == "spicevmc" and server:
+        raise ValueError(_("The server option is invalid with spicevmc redirection"))
+
+    if stype == "tcp" and not server:
+        raise ValueError(_("The server option is missing for TCP redirection"))
+
+    if server:
+        dev.parse_friendly_server(server)
+
+    if opts:
+        raise ValueError(_("Unknown options %s") % opts.keys())
+
+    return dev
+
+######################
 # --watchdog parsing #
 ######################
 
-- 
1.7.6




More information about the virt-tools-list mailing list