[virt-tools-list] [PATCH] wip: add VirtualSmartCardDevice
Cole Robinson
crobinso at redhat.com
Tue Jul 5 19:35:30 UTC 2011
On 06/23/2011 11:33 AM, Marc-André Lureau wrote:
> 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.
Pushed with man pages and a few fixes:
http://git.fedorahosted.org/git?p=python-virtinst.git;a=commit;h=b4237e50d4a5f50a1b951a33d5fef7b4e2f1eaaf
Thanks!
Cole
> ---
> 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 #
> ######################
More information about the virt-tools-list
mailing list