[virt-tools-list] [PATCH] wip: add basic SmartCardDevice support
Marc-André Lureau
marcandre.lureau at gmail.com
Thu Jun 23 15:42:03 UTC 2011
From: Marc-André Lureau <marcandre.lureau at redhat.com>
This patch allows to add and list smartcard devices in host or
passthrough & spicevmc mode.
It doesn't provide all the various smartcard combination
options, but it's good enough for Spice usage.
(The patch requires python-virtinst support sent earlier)
---
src/virtManager/addhardware.py | 29 +++++++++++-
src/virtManager/details.py | 32 ++++++++++++-
src/virtManager/domain.py | 10 ++++
src/virtManager/uihelpers.py | 22 +++++++++
src/vmm-add-hardware.glade | 74 +++++++++++++++++++++++++++++
src/vmm-details.glade | 100 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 265 insertions(+), 2 deletions(-)
diff --git a/src/virtManager/addhardware.py b/src/virtManager/addhardware.py
index ea96356..fe3bcee 100644
--- a/src/virtManager/addhardware.py
+++ b/src/virtManager/addhardware.py
@@ -25,7 +25,7 @@ import gtk
import virtinst
from virtinst import (VirtualCharDevice, VirtualDevice, VirtualVideoDevice,
- VirtualWatchdog, VirtualFilesystem)
+ VirtualWatchdog, VirtualFilesystem, VirtualSmartCardDevice)
import virtManager.util as util
import virtManager.uihelpers as uihelpers
@@ -45,6 +45,7 @@ PAGE_CHAR = 7
PAGE_VIDEO = 8
PAGE_WATCHDOG = 9
PAGE_FILESYSTEM = 10
+PAGE_SMARTCARD = 11
char_widget_mappings = {
"source_path" : "char-path",
@@ -345,6 +346,10 @@ class vmmAddHardware(vmmGObjectUI):
simple_store_set("fs-mode-combo", VirtualFilesystem.MOUNT_MODES)
self.show_pair_combo("fs-type", self.conn.is_openvz())
+ # Smartcard widgets
+ combo = self.window.get_widget("smartcard-mode")
+ uihelpers.build_smartcard_mode_combo(self.vm, combo)
+
# Available HW options
is_local = not self.conn.is_remote()
is_storage_capable = self.conn.is_storage_capable()
@@ -407,6 +412,8 @@ class vmmAddHardware(vmmGObjectUI):
self.vm.get_hv_type()),
_("Not supported for this hypervisor/libvirt "
"combination."))
+ add_hw_option("Smartcard", "device_serial", PAGE_SMARTCARD,
+ True, None)
def reset_state(self):
# Storage init
@@ -733,6 +740,12 @@ class vmmAddHardware(vmmGObjectUI):
return combo.get_model()[combo.get_active()][0]
+ # Smartcard getters
+ def get_config_smartcard_mode(self):
+ mode = self.window.get_widget("smartcard-mode")
+ modestr = mode.get_model().get_value(mode.get_active_iter(), 0)
+ return modestr
+
################
# UI listeners #
################
@@ -909,6 +922,8 @@ class vmmAddHardware(vmmGObjectUI):
return _("Watchdog Device")
if page == PAGE_FILESYSTEM:
return _("Filesystem Passthrough")
+ if page == PAGE_SMARTCARD:
+ return _("Smartcard")
if page == PAGE_CHAR:
return self.get_char_type().capitalize() + " Device"
@@ -1083,6 +1098,8 @@ class vmmAddHardware(vmmGObjectUI):
return self.validate_page_watchdog()
elif page_num == PAGE_FILESYSTEM:
return self.validate_page_filesystem()
+ elif page_num == PAGE_SMARTCARD:
+ return self.validate_page_smartcard()
def validate_page_storage(self):
bus, device = self.get_config_disk_target()
@@ -1340,6 +1357,16 @@ class vmmAddHardware(vmmGObjectUI):
return self.err.val_err(_("Filesystem parameter error"),
str(e))
+ def validate_page_smartcard(self):
+ conn = self.conn.vmm
+ mode = self.get_config_smartcard_mode()
+
+ try:
+ self._dev = VirtualSmartCardDevice(conn, mode)
+ except Exception, e:
+ return self.err.val_err(_("Video device parameter error"),
+ str(e))
+
####################
# Unsorted helpers #
diff --git a/src/virtManager/details.py b/src/virtManager/details.py
index 9a0d562..763050e 100644
--- a/src/virtManager/details.py
+++ b/src/virtManager/details.py
@@ -62,12 +62,13 @@ HW_LIST_TYPE_VIDEO = 12
HW_LIST_TYPE_WATCHDOG = 13
HW_LIST_TYPE_CONTROLLER = 14
HW_LIST_TYPE_FILESYSTEM = 15
+HW_LIST_TYPE_SMARTCARD = 16
remove_pages = [HW_LIST_TYPE_NIC, HW_LIST_TYPE_INPUT,
HW_LIST_TYPE_GRAPHICS, HW_LIST_TYPE_SOUND, HW_LIST_TYPE_CHAR,
HW_LIST_TYPE_HOSTDEV, HW_LIST_TYPE_DISK, HW_LIST_TYPE_VIDEO,
HW_LIST_TYPE_WATCHDOG, HW_LIST_TYPE_CONTROLLER,
- HW_LIST_TYPE_FILESYSTEM]
+ HW_LIST_TYPE_FILESYSTEM, HW_LIST_TYPE_SMARTCARD]
# Boot device columns
BOOT_DEV_TYPE = 0
@@ -369,6 +370,8 @@ class vmmDetails(vmmGObjectUI):
"on_watchdog_model_combo_changed": self.config_enable_apply,
"on_watchdog_action_combo_changed": self.config_enable_apply,
+ "on_smartcard_mode_combo_changed": self.config_enable_apply,
+
"on_config_apply_clicked": self.config_apply,
"on_details_help_activate": self.show_help,
@@ -802,6 +805,10 @@ class vmmDetails(vmmGObjectUI):
uihelpers.build_watchdogaction_combo(self.vm, combo,
no_default=no_default)
+ # Smartcard mode
+ sc_mode = self.window.get_widget("smartcard-mode-combo")
+ uihelpers.build_smartcard_mode_combo(self.vm, sc_mode)
+
# Helper function to handle the combo/label pattern used for
# video model, sound model, network model, etc.
def set_combo_label(self, prefix, value, model_idx=0, label="",
@@ -1023,6 +1030,8 @@ class vmmDetails(vmmGObjectUI):
self.refresh_controller_page()
elif pagetype == HW_LIST_TYPE_FILESYSTEM:
self.refresh_filesystem_page()
+ elif pagetype == HW_LIST_TYPE_SMARTCARD:
+ self.refresh_smartcard_page()
else:
pagetype = -1
except Exception, e:
@@ -1638,6 +1647,8 @@ class vmmDetails(vmmGObjectUI):
ret = self.config_video_apply(key)
elif pagetype is HW_LIST_TYPE_WATCHDOG:
ret = self.config_watchdog_apply(key)
+ elif pagetype is HW_LIST_TYPE_SMARTCARD:
+ ret = self.config_smartcard_apply(key)
else:
ret = False
except Exception, e:
@@ -1850,6 +1861,13 @@ class vmmDetails(vmmGObjectUI):
return self._change_config_helper(self.vm.define_sound_model,
(dev_id_info, model))
+ # Smartcard options
+ def config_smartcard_apply(self, dev_id_info):
+ model = self.get_combo_label_value("smartcard-mode")
+ if model:
+ return self._change_config_helper(self.vm.define_smartcard_mode,
+ (dev_id_info, model))
+
# Network options
def config_network_apply(self, dev_id_info):
net_list = self.window.get_widget("network-source-combo")
@@ -2550,6 +2568,13 @@ class vmmDetails(vmmGObjectUI):
self.set_combo_label("sound-model", sound.model)
+ def refresh_smartcard_page(self):
+ sc = self.get_hw_selection(HW_LIST_COL_DEVICE)
+ if not sc:
+ return
+
+ self.set_combo_label("smartcard-mode", sc.mode)
+
def refresh_char_page(self):
chardev = self.get_hw_selection(HW_LIST_COL_DEVICE)
if not chardev:
@@ -2920,6 +2945,11 @@ class vmmDetails(vmmGObjectUI):
_("Filesystem %s") % target,
gtk.STOCK_DIRECTORY)
+ # Populate list of smartcard devices
+ for sc in self.vm.get_smartcard_devices():
+ update_hwlist(HW_LIST_TYPE_SMARTCARD, sc,
+ _("Smartcard: %s" % sc.mode), "device_serial")
+
devs = range(len(hw_list_model))
devs.reverse()
for i in devs:
diff --git a/src/virtManager/domain.py b/src/virtManager/domain.py
index 674ebcd..eb5299a 100644
--- a/src/virtManager/domain.py
+++ b/src/virtManager/domain.py
@@ -47,6 +47,7 @@ def compare_device(origdev, newdev, idx):
"controller" : ["type", "index"],
"channel" : ["char_type", "target_name"],
"filesystem" : ["target" , "vmmindex"],
+ "smartcard" : ["mode" , "vmmindex"],
}
if id(origdev) == id(newdev):
@@ -633,6 +634,13 @@ class vmmDomain(vmmLibvirtObject):
editdev.action = newval
return self._redefine_device(change, devobj)
+ # Smartcard define methods
+
+ def define_smartcard_mode(self, devobj, newmodel):
+ def change(editdev):
+ editdev.mode = newmodel
+ return self._redefine_device(change, devobj)
+
####################
# Hotplug routines #
@@ -899,6 +907,8 @@ class vmmDomain(vmmLibvirtObject):
return self._build_device_list("controller")
def get_filesystem_devices(self):
return self._build_device_list("filesystem")
+ def get_smartcard_devices(self):
+ return self._build_device_list("smartcard")
def get_disk_devices(self, refresh_if_necc=True, inactive=False):
devs = self._build_device_list("disk", refresh_if_necc, inactive)
diff --git a/src/virtManager/uihelpers.py b/src/virtManager/uihelpers.py
index 1dc482f..4abcf50 100644
--- a/src/virtManager/uihelpers.py
+++ b/src/virtManager/uihelpers.py
@@ -214,6 +214,28 @@ def populate_source_mode_combo(vm, combo):
model.append(["private", "Private"])
model.append(["passthrough", "Passthrough"])
+def build_smartcard_mode_combo(vm, combo):
+ dev_model = gtk.ListStore(str, str)
+ combo.set_model(dev_model)
+ text = gtk.CellRendererText()
+ combo.pack_start(text, True)
+ combo.add_attribute(text, 'text', 1)
+ dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
+
+ populate_smartcard_mode_combo(vm, combo)
+ combo.set_active(0)
+
+def populate_smartcard_mode_combo(vm, combo):
+ ignore = vm
+ model = combo.get_model()
+ model.clear()
+
+ # [xml value, label]
+ model.append(["passthrough", "Passthrough"])
+ model.append(["host", "Host"])
+# TODO
+# model.append(["host-certificates", "Host Certificates"])
+
def build_netmodel_combo(vm, combo):
dev_model = gtk.ListStore(str, str)
combo.set_model(dev_model)
diff --git a/src/vmm-add-hardware.glade b/src/vmm-add-hardware.glade
index 5eb218c..dcac618 100644
--- a/src/vmm-add-hardware.glade
+++ b/src/vmm-add-hardware.glade
@@ -2181,12 +2181,86 @@ and default action should be used.</property>
<property name="position">1</property>
</packing>
</child>
+
</widget>
<packing>
<property name="position">10</property>
</packing>
</child>
<child>
+ <widget class="GtkVBox" id="page5-box">
+ <property name="visible">True</property>
+ <property name="border_width">1</property>
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Please indicate what smartcard device mode to connect to the virtual machine.</property>
+ <property name="use_markup">True</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment4">
+ <property name="visible">True</property>
+ <property name="left_padding">24</property>
+ <child>
+ <widget class="GtkTable" id="table2">
+ <property name="visible">True</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <widget class="GtkComboBox" id="smartcard-mode">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Mode:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">smartcard-mode</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
<widget class="GtkLabel" id="label14">
<property name="visible">True</property>
<property name="label">fs</property>
diff --git a/src/vmm-details.glade b/src/vmm-details.glade
index 2d69c27..218639c 100644
--- a/src/vmm-details.glade
+++ b/src/vmm-details.glade
@@ -5492,6 +5492,106 @@ I/O:</property>
<property name="type">tab</property>
</packing>
</child>
+ <child>
+ <widget class="GtkVBox" id="vbox58">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFrame" id="frame13">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment159">
+ <property name="visible">True</property>
+ <property name="top_padding">3</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkTable" id="table36">
+ <property name="visible">True</property>
+ <property name="border_width">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">8</property>
+ <property name="row_spacing">4</property>
+ <child>
+ <widget class="GtkLabel" id="label452">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Smartcard m_ode:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">smartcard-mode-combo</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox11">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkComboBox" id="smartcard-mode-combo">
+ <property name="visible">True</property>
+ <signal name="changed" handler="on_smartcard_mode_combo_changed"/>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="smartcard-mode-label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label">insert smartcard mode</property>
+ <property name="selectable">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label451">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><b>Smartcard Device</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">9</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label440">
+ <property name="visible">True</property>
+ <property name="label">snd</property>
+ </widget>
+ <packing>
+ <property name="position">9</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
</widget>
</child>
</widget>
--
1.7.5.2
More information about the virt-tools-list
mailing list