[virt-tools-list] [PATCH] wip: add VirtualSmartCardDevice
Marc-André Lureau
marcandre.lureau at gmail.com
Thu Jun 23 15:33:23 UTC 2011
From: Marc-André Lureau <marcandre.lureau at redhat.com>
This is not a complete patch (it doesn't support all the smartcard
options, in particular host-certificates method), but it does good
enough for spice smartcard passthrough & virt-manager integration.
Feel free to take it up from there and improving it if you feel like
it's not ready for merge.
---
tests/clitest.py | 27 +++++++++++
tests/xmlparse.py | 17 +++++++
virt-image | 1 +
virt-install | 4 ++
virtinst/Guest.py | 1 +
virtinst/VirtualDevice.py | 4 +-
virtinst/VirtualSmartCardDevice.py | 88 ++++++++++++++++++++++++++++++++++++
virtinst/__init__.py | 4 +-
virtinst/cli.py | 49 ++++++++++++++++++++
9 files changed, 193 insertions(+), 2 deletions(-)
create mode 100644 virtinst/VirtualSmartCardDevice.py
diff --git a/tests/clitest.py b/tests/clitest.py
index 31cd061..10a3f70 100644
--- a/tests/clitest.py
+++ b/tests/clitest.py
@@ -349,6 +349,33 @@ args_dict = {
}, # category "graphics"
+ "smartcard": {
+ "args": "--noautoconsole --nodisks --pxe",
+
+ "valid": [
+ # --smartcard host
+ "--graphics host",
+ # --smartcard none,
+ "--graphics none",
+ # --smartcard mode with type
+ "--graphics passthrough,type=spicevmc",
+ # --smartcard mode with type
+ "--graphics passthrough,type=tcp",
+ ],
+
+ "invalid": [
+ # Missing argument
+ "--smartcard",
+ # Invalid argument
+ "--smartcard foo",
+ # Invalid type
+ "--smartcard passthrough,type=foo",
+ # --smartcard bogus
+ "--smarcard host,foobar=baz",
+ ],
+
+ }, # category "smartcard"
+
"char" : {
"args": "--hvm --nographics --noautoconsole --nodisks --pxe",
diff --git a/tests/xmlparse.py b/tests/xmlparse.py
index 3f19c98..636e043 100644
--- a/tests/xmlparse.py
+++ b/tests/xmlparse.py
@@ -639,6 +639,23 @@ class XMLParseTest(unittest.TestCase):
self._alter_compare(guest.get_config_xml(), outfile)
+ def testAlterSmartCard(self):
+ infile = "tests/xmlparse-xml/change-smartcard-in.xml"
+ outfile = "tests/xmlparse-xml/change-smartcard-out.xml"
+ guest = virtinst.Guest(connection=conn,
+ parsexml=file(infile).read())
+
+ dev1 = guest.get_devices("smartcard")[0]
+ dev2 = guest.get_devices("smartcard")[1]
+
+ check = self._make_checker(dev1)
+ check("type", None, "tcp")
+
+ check = self._make_checker(dev2)
+ check("mode", "passthrough", "host")
+ check("type", "spicevmc", None)
+
+ self._alter_compare(guest.get_config_xml(), outfile)
def testConsoleCompat(self):
infile = "tests/xmlparse-xml/console-compat-in.xml"
diff --git a/virt-image b/virt-image
index ea55181..19fa5d4 100755
--- a/virt-image
+++ b/virt-image
@@ -172,6 +172,7 @@ def main():
get_graphics(image.domain, guest, options)
cli.get_video(guest)
+ cli.get_smartcard(guest, options.smartcard)
cli.set_os_variant(guest, options.distro_type, options.distro_variant)
diff --git a/virt-install b/virt-install
index e2309b9..62c79c1 100755
--- a/virt-install
+++ b/virt-install
@@ -488,6 +488,7 @@ def build_guest_instance(conn, options):
get_chardevs(VirtualDevice.VIRTUAL_DEV_CHANNEL, options.channels, guest)
get_chardevs(VirtualDevice.VIRTUAL_DEV_CONSOLE, options.consoles, guest)
cli.get_hostdevs(options.hostdevs, guest)
+ cli.get_smartcard(guest, options.smartcard)
# Install options
@@ -867,6 +868,9 @@ def parse_args():
help=_("Don't create network interfaces for the guest."))
parser.add_option_group(netg)
+ scg = cli.smartcard_option_group(parser)
+ parser.add_option_group(scg)
+
vncg = cli.graphics_option_group(parser)
vncg.add_option("", "--noautoconsole", action="store_false",
dest="autoconsole", default=True,
diff --git a/virtinst/Guest.py b/virtinst/Guest.py
index 60b8175..430dd8d 100644
--- a/virtinst/Guest.py
+++ b/virtinst/Guest.py
@@ -784,6 +784,7 @@ class Guest(XMLBuilderDomain.XMLBuilderDomain):
"watchdog" : virtinst.VirtualWatchdog,
"controller": virtinst.VirtualController,
"filesystem": virtinst.VirtualFilesystem,
+ "smartcard" : virtinst.VirtualSmartCardDevice,
}
# Hand off all child element parsing to relevant classes
diff --git a/virtinst/VirtualDevice.py b/virtinst/VirtualDevice.py
index 87af418..158037c 100644
--- a/virtinst/VirtualDevice.py
+++ b/virtinst/VirtualDevice.py
@@ -41,6 +41,7 @@ class VirtualDevice(XMLBuilderDomain):
VIRTUAL_DEV_CONTROLLER = "controller"
VIRTUAL_DEV_WATCHDOG = "watchdog"
VIRTUAL_DEV_FILESYSTEM = "filesystem"
+ VIRTUAL_DEV_SMARTCARD = "smartcard"
# Ordering in this list is important: it will be the order the
# Guest class outputs XML. So changing this may upset the test suite
@@ -57,7 +58,8 @@ class VirtualDevice(XMLBuilderDomain):
VIRTUAL_DEV_AUDIO,
VIRTUAL_DEV_VIDEO,
VIRTUAL_DEV_HOSTDEV,
- VIRTUAL_DEV_WATCHDOG]
+ VIRTUAL_DEV_WATCHDOG,
+ VIRTUAL_DEV_SMARTCARD]
# General device type (disk, interface, etc.)
_virtual_device_type = None
diff --git a/virtinst/VirtualSmartCardDevice.py b/virtinst/VirtualSmartCardDevice.py
new file mode 100644
index 0000000..f07bbf3
--- /dev/null
+++ b/virtinst/VirtualSmartCardDevice.py
@@ -0,0 +1,88 @@
+# coding=utf-8
+#
+# Copyright 2011 Red Hat, Inc.
+# Cole Robinson <crobinso at redhat.com>
+# Marc-André Lureau <marcandre.lureau at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA.
+
+import VirtualDevice
+from XMLBuilderDomain import _xml_property
+from virtinst import _virtinst as _
+
+class VirtualSmartCardDevice(VirtualDevice.VirtualDevice):
+
+ _virtual_device_type = VirtualDevice.VirtualDevice.VIRTUAL_DEV_SMARTCARD
+
+ # Default models list
+ MODE_DEFAULT = "passthrough"
+ _modes = [ "passthrough", "host-certificates", "host" ]
+
+ TYPE_DEFAULT = "tcp"
+ _types = [ "tcp", "spicevmc", None ]
+
+ def __init__(self, conn, mode=MODE_DEFAULT,
+ parsexml=None, parsexmlnode=None, caps=None):
+ VirtualDevice.VirtualDevice.__init__(self, conn,
+ parsexml, parsexmlnode, caps)
+
+ self._mode = None
+ self._type = None
+
+ if self._is_parse():
+ return
+
+ self.mode = mode
+
+ def get_modes(self):
+ return self._modes[:]
+ modes = property(get_modes)
+
+ def get_mode(self):
+ return self._mode
+ def set_mode(self, val):
+ if val not in self.modes:
+ raise ValueError(_("Unknown smartcard mode '%s'") % val)
+ self._mode = val
+ mode = _xml_property(get_mode, set_mode,
+ xpath="./@mode")
+
+ def get_types(self):
+ return self._types[:]
+ types = property(get_types)
+
+ def get_type(self):
+ if self._type is None and self.mode == "passthrough":
+ return "spicevmc"
+ return self._type
+ def set_type(self, val):
+ if val not in self.types:
+ raise ValueError(_("Unknown smartcard type '%s'") % val)
+ self._type = val
+ type = _xml_property(get_type, set_type,
+ xpath="./@type")
+
+ def _get_xml_config(self):
+ mode = self.mode
+
+ xml = " <smartcard mode='%s'" % mode
+ if self.type:
+ xml += " type='%s'" % self.type
+ xml += ">\n"
+ xml += " <protocol type='raw'/>\n"
+ xml += " </smartcard>"
+
+ return xml
diff --git a/virtinst/__init__.py b/virtinst/__init__.py
index 287e90e..6460e95 100644
--- a/virtinst/__init__.py
+++ b/virtinst/__init__.py
@@ -44,6 +44,7 @@ from VirtualVideoDevice import VirtualVideoDevice
from VirtualController import VirtualController
from VirtualWatchdog import VirtualWatchdog
from VirtualFilesystem import VirtualFilesystem
+from VirtualSmartCardDevice import VirtualSmartCardDevice
from FullVirtGuest import FullVirtGuest
from ParaVirtGuest import ParaVirtGuest
from DistroInstaller import DistroInstaller
@@ -73,4 +74,5 @@ __all__ = ["Guest", "XenGuest", "VirtualNetworkInterface",
"CPU",
"VirtualHostDevice", "VirtualHostDeviceUSB", "VirtualVideoDevice",
"VirtualHostDevicePCI", "VirtualCharDevice", "VirtualInputDevice",
- "VirtualController", "VirtualWatchdog"]
+ "VirtualController", "VirtualWatchdog",
+ "VirtualFilesystem", "VirtualSmartCardDevice"]
diff --git a/virtinst/cli.py b/virtinst/cli.py
index 4f78738..19602cf 100644
--- a/virtinst/cli.py
+++ b/virtinst/cli.py
@@ -969,6 +969,16 @@ def get_hostdevs(hostdevs, guest):
name=devname)
guest.hostdevs.append(dev)
+def get_smartcard(guest, sc_opts):
+ for sc in sc_opts:
+ try:
+ dev = parse_smartcard(guest, sc)
+ except Exception, e:
+ fail(_("Error in smartcard device parameters: %s") % str(e))
+
+ if dev:
+ guest.add_device(dev)
+
#############################
# Common CLI option/group #
#############################
@@ -1036,6 +1046,17 @@ def network_option_group(parser):
return netg
+def smartcard_option_group(parser):
+ """
+ Register smartcard options for virt-install and virt-image
+ """
+ scg = optparse.OptionGroup(parser, _("SmartCard Configuration"))
+
+ scg.add_option("-S", "--smartcard", dest="smartcard", action="append",
+ help=_("Add a smartcard device to the domain. Ex:\n"
+ "--smartcard mode=passthrough\n"))
+ return scg
+
#############################################
# CLI complex parsing helpers #
# (for options like --disk, --network, etc. #
@@ -1480,6 +1501,34 @@ def parse_graphics(guest, optstring):
return dev
+#######################
+# --smartcard parsing #
+#######################
+def parse_smartcard(guest, optstring):
+ if optstring is None:
+ return None
+
+ # Peel the mode off the front
+ opts = parse_optstr(optstring, remove_first="mode")
+ if opts.get("mode") == "none":
+ return None
+ dev = virtinst.VirtualSmartCardDevice(guest.conn, opts.get("mode"))
+
+ def set_param(paramname, dictname, val=None):
+ val = get_opt_param(opts, dictname, val)
+ if val == None:
+ return
+
+ setattr(dev, paramname, val)
+
+ set_param("mode", "mode")
+ set_param("type", "type")
+
+ if opts:
+ raise ValueError(_("Unknown options %s") % opts.keys())
+
+ return dev
+
######################
# --watchdog parsing #
######################
--
1.7.5.2
More information about the virt-tools-list
mailing list