addhardware: Initial 'add filesystem' wizard

This commit is contained in:
Cole Robinson 2011-05-19 18:17:58 -04:00
parent bb3d879501
commit a99dee7dbd
3 changed files with 329 additions and 25 deletions

View File

@ -25,7 +25,7 @@ import gtk
import virtinst
from virtinst import (VirtualCharDevice, VirtualDevice, VirtualVideoDevice,
VirtualWatchdog)
VirtualWatchdog, VirtualFilesystem)
import virtManager.util as util
import virtManager.uihelpers as uihelpers
@ -44,6 +44,7 @@ PAGE_HOSTDEV = 6
PAGE_CHAR = 7
PAGE_VIDEO = 8
PAGE_WATCHDOG = 9
PAGE_FILESYSTEM = 10
char_widget_mappings = {
"source_path" : "char-path",
@ -105,6 +106,8 @@ class vmmAddHardware(vmmGObjectUI):
"on_char_device_type_changed": self.change_char_device_type,
"on_fs_type_combo_changed": self.change_fs_type,
# Char dev info signals
"char_device_type_focus": (self.update_doc, "char_type"),
"char_path_focus_in": (self.update_doc, "source_path"),
@ -324,6 +327,24 @@ class vmmAddHardware(vmmGObjectUI):
combo = self.window.get_widget("watchdog-action")
uihelpers.build_watchdogaction_combo(self.vm, combo)
def simple_store_set(comboname, values):
combo = self.window.get_widget(comboname)
model = gtk.ListStore(str, str)
combo.set_model(model)
text = gtk.CellRendererText()
combo.pack_start(text, True)
combo.add_attribute(text, 'text', 1)
model.set_sort_column_id(0, gtk.SORT_ASCENDING)
for val in values:
model.append([val, val.capitalize()])
# Filesystem widgets
simple_store_set("fs-type-combo",
[VirtualFilesystem.TYPE_MOUNT,
VirtualFilesystem.TYPE_TEMPLATE])
simple_store_set("fs-mode-combo", VirtualFilesystem.MOUNT_MODES)
self.show_pair_combo("fs-type", self.conn.is_openvz())
# Available HW options
is_local = not self.conn.is_remote()
is_storage_capable = self.conn.is_storage_capable()
@ -379,6 +400,13 @@ class vmmAddHardware(vmmGObjectUI):
add_hw_option("Watchdog", "device_pci", PAGE_WATCHDOG,
self.vm.is_hvm(),
_("Not supported for this guest type."))
add_hw_option("Filesystem", gtk.STOCK_DIRECTORY, PAGE_FILESYSTEM,
virtinst.support.check_conn_hv_support(
self.conn.vmm,
virtinst.support.SUPPORT_CONN_HV_FILESYSTEM,
self.vm.get_hv_type()),
_("Not supported for this hypervisor/libvirt "
"combination."))
def reset_state(self):
# Storage init
@ -452,6 +480,12 @@ class vmmAddHardware(vmmGObjectUI):
self.window.get_widget("char-use-telnet").set_active(False)
self.window.get_widget("char-target-name").set_text("com.redhat.spice.0")
# FS params
self.window.get_widget("fs-type-combo").set_active(0)
self.window.get_widget("fs-mode-combo").set_active(0)
self.window.get_widget("fs-source").set_text("")
self.window.get_widget("fs-target").set_text("")
# Hide all notebook pages, so the wizard isn't as big as the largest
# page
notebook = self.window.get_widget("create-pages")
@ -683,6 +717,22 @@ class vmmAddHardware(vmmGObjectUI):
modbox = self.window.get_widget("watchdog-action")
return modbox.get_model()[modbox.get_active()][0]
# FS getters
def get_config_fs_mode(self):
name = "fs-mode-combo"
combo = self.window.get_widget(name)
if not combo.get_property("visible"):
return None
return combo.get_model()[combo.get_active()][0]
def get_config_fs_type(self):
name = "fs-type-combo"
combo = self.window.get_widget(name)
if not combo.get_property("visible"):
return None
return combo.get_model()[combo.get_active()][0]
################
# UI listeners #
################
@ -857,6 +907,8 @@ class vmmAddHardware(vmmGObjectUI):
return _("Video Device")
if page == PAGE_WATCHDOG:
return _("Watchdog Device")
if page == PAGE_FILESYSTEM:
return _("Filesystem Passthrough")
if page == PAGE_CHAR:
return self.get_char_type().capitalize() + " Device"
@ -903,6 +955,31 @@ class vmmAddHardware(vmmGObjectUI):
if has_mode and self.window.get_widget("char-mode").get_active() == -1:
self.window.get_widget("char-mode").set_active(0)
def show_pair_combo(self, basename, show_combo):
combo = self.window.get_widget(basename + "-combo")
label = self.window.get_widget(basename + "-label")
combo.set_property("visible", show_combo)
label.set_property("visible", not show_combo)
def change_fs_type(self, src):
idx = src.get_active()
fstype = None
show_mode_combo = False
if idx >= 0 and src.get_property("visible"):
fstype = src.get_model()[idx][0]
if fstype == virtinst.VirtualFilesystem.TYPE_TEMPLATE:
source_text = _("Te_mplate:")
else:
source_text = _("_Source path:")
show_mode_combo = self.conn.is_qemu()
self.window.get_widget("fs-source-title").set_text(source_text)
self.window.get_widget("fs-source-title").set_use_underline(True)
self.show_pair_combo("fs-mode", show_mode_combo)
######################
# Add device methods #
@ -1004,6 +1081,8 @@ class vmmAddHardware(vmmGObjectUI):
return self.validate_page_video()
elif page_num == PAGE_WATCHDOG:
return self.validate_page_watchdog()
elif page_num == PAGE_FILESYSTEM:
return self.validate_page_filesystem()
def validate_page_storage(self):
bus, device = self.get_config_disk_target()
@ -1237,6 +1316,29 @@ class vmmAddHardware(vmmGObjectUI):
return self.err.val_err(_("Watchdog parameter error"),
str(e))
def validate_page_filesystem(self):
conn = self.conn.vmm
source = self.window.get_widget("fs-source").get_text()
target = self.window.get_widget("fs-target").get_text()
mode = self.get_config_fs_mode()
fstype = self.get_config_fs_type()
if not source:
return self.err.val_err(_("A filesystem source must be specified"))
if not target:
return self.err.val_err(_("A filesystem target must be specified"))
try:
self._dev = virtinst.VirtualFilesystem(conn=conn)
self._dev.source = source
self._dev.target = target
if mode:
self._dev.mode = mode
if fstype:
self._dev.type = fstype
except Exception, e:
return self.err.val_err(_("Filesystem parameter error"),
str(e))
####################

View File

@ -320,6 +320,15 @@ class vmmConnection(vmmGObject):
def is_local(self):
return bool(self.get_uri_hostname() == "localhost")
def is_lxc(self):
if self._is_virtinst_test_uri:
self.get_uri().count(",lxc")
return virtinst.util.uri_split(self.get_uri())[0].startswith("lxc")
def is_openvz(self):
return virtinst.util.uri_split(self.get_uri())[0].startswith("openvz")
def is_xen(self):
if self._is_virtinst_test_uri:
return self.get_uri().count(",xen")

View File

@ -6,7 +6,7 @@
<property name="visible">True</property>
<property name="title" translatable="yes">Add new virtual hardware</property>
<property name="type_hint">dialog</property>
<signal name="delete_event" handler="on_vmm_create_delete_event"/>
<signal name="delete_event" handler="on_vmm_create_delete_event" swapped="no"/>
<child>
<widget class="GtkVBox" id="vbox23">
<property name="visible">True</property>
@ -74,7 +74,7 @@
<property name="tab_border">0</property>
<property name="tab_hborder">0</property>
<property name="tab_vborder">0</property>
<signal name="switch_page" handler="on_create_pages_switch_page"/>
<signal name="switch_page" handler="on_create_pages_switch_page" swapped="no"/>
<child>
<widget class="GtkVBox" id="page0-box">
<property name="visible">True</property>
@ -270,7 +270,7 @@
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">config-storage-create</property>
<signal name="toggled" handler="on_config_storage_select_toggled"/>
<signal name="toggled" handler="on_config_storage_select_toggled" swapped="no"/>
<child>
<widget class="GtkLabel" id="label124">
<property name="visible">True</property>
@ -303,7 +303,7 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_config_storage_browse_clicked"/>
<signal name="clicked" handler="on_config_storage_browse_clicked" swapped="no"/>
</widget>
<packing>
<property name="expand">False</property>
@ -345,7 +345,7 @@
<accessibility>
<atkproperty name="AtkObject::accessible-name" translatable="yes">Device Type Field</atkproperty>
</accessibility>
<signal name="changed" handler="on_target_device_changed"/>
<signal name="changed" handler="on_target_device_changed" swapped="no"/>
</widget>
<packing>
<property name="left_attach">1</property>
@ -518,7 +518,7 @@
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
<signal name="clicked" handler="on_mac_address_clicked"/>
<signal name="clicked" handler="on_mac_address_clicked" swapped="no"/>
</widget>
<packing>
<property name="expand">False</property>
@ -863,7 +863,7 @@
<child>
<widget class="GtkComboBox" id="graphics-type">
<property name="visible">True</property>
<signal name="changed" handler="on_graphics_type_changed"/>
<signal name="changed" handler="on_graphics_type_changed" swapped="no"/>
</widget>
<packing>
<property name="left_attach">1</property>
@ -1040,7 +1040,7 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="relief">half</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_graphics_keymap_toggled"/>
<signal name="toggled" handler="on_graphics_keymap_toggled" swapped="no"/>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
@ -1162,7 +1162,7 @@
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_graphics_port_auto_toggled"/>
<signal name="toggled" handler="on_graphics_port_auto_toggled" swapped="no"/>
</widget>
<packing>
<property name="left_attach">3</property>
@ -1450,8 +1450,8 @@ to connect to the virtual machine.</property>
<child>
<widget class="GtkComboBox" id="char-device-type">
<property name="visible">True</property>
<signal name="changed" handler="on_char_device_type_changed"/>
<signal name="focus" handler="on_char_device_type_focus"/>
<signal name="changed" handler="on_char_device_type_changed" swapped="no"/>
<signal name="focus" handler="on_char_device_type_focus" swapped="no"/>
</widget>
<packing>
<property name="left_attach">1</property>
@ -1511,7 +1511,7 @@ to connect to the virtual machine.</property>
<widget class="GtkEntry" id="char-path">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="focus_in_event" handler="char_path_focus_in"/>
<signal name="focus_in_event" handler="char_path_focus_in" swapped="no"/>
</widget>
<packing>
<property name="left_attach">1</property>
@ -1522,7 +1522,7 @@ to connect to the virtual machine.</property>
<widget class="GtkEntry" id="char-target-name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="focus_in_event" handler="char_name_focus_in"/>
<signal name="focus_in_event" handler="char_name_focus_in" swapped="no"/>
</widget>
<packing>
<property name="left_attach">1</property>
@ -1553,7 +1553,7 @@ to connect to the virtual machine.</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="focus_in_event" handler="char_telnet_focus_in"/>
<signal name="focus_in_event" handler="char_telnet_focus_in" swapped="no"/>
</widget>
<packing>
<property name="left_attach">1</property>
@ -1582,8 +1582,8 @@ to connect to the virtual machine.</property>
<child>
<widget class="GtkComboBox" id="char-mode">
<property name="visible">True</property>
<signal name="changed" handler="on_char_mode_changed"/>
<signal name="focus" handler="on_char_mode_focus"/>
<signal name="changed" handler="on_char_mode_changed" swapped="no"/>
<signal name="focus" handler="on_char_mode_focus" swapped="no"/>
</widget>
<packing>
<property name="left_attach">1</property>
@ -1644,7 +1644,7 @@ to connect to the virtual machine.</property>
<widget class="GtkEntry" id="char-host">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="focus_in_event" handler="char_host_focus_in"/>
<signal name="focus_in_event" handler="char_host_focus_in" swapped="no"/>
</widget>
<packing>
<property name="position">0</property>
@ -1668,7 +1668,7 @@ to connect to the virtual machine.</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">0 0 67000 1 10 0</property>
<signal name="focus_in_event" handler="char_host_focus_in"/>
<signal name="focus_in_event" handler="char_host_focus_in" swapped="no"/>
</widget>
<packing>
<property name="expand">False</property>
@ -1691,7 +1691,7 @@ to connect to the virtual machine.</property>
<widget class="GtkEntry" id="char-bind-host">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="focus_in_event" handler="char_bind_host_focus_in"/>
<signal name="focus_in_event" handler="char_bind_host_focus_in" swapped="no"/>
</widget>
<packing>
<property name="position">0</property>
@ -1715,7 +1715,7 @@ to connect to the virtual machine.</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">0 0 67000 1 10 0</property>
<signal name="focus_in_event" handler="char_bind_host_focus_in"/>
<signal name="focus_in_event" handler="char_bind_host_focus_in" swapped="no"/>
</widget>
<packing>
<property name="expand">False</property>
@ -1927,7 +1927,7 @@ and default action should be used.</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="column_spacing">12</property>
<property name="row_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<widget class="GtkComboBox" id="watchdog-model">
<property name="visible">True</property>
@ -2004,6 +2004,199 @@ and default action should be used.</property>
<property name="type">tab</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="page10-box">
<property name="visible">True</property>
<property name="spacing">12</property>
<child>
<widget class="GtkLabel" id="label16">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Please indicate what watchdog device type
and default action should be used.</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="alignment16">
<property name="visible">True</property>
<property name="left_padding">24</property>
<child>
<widget class="GtkTable" id="table9">
<property name="visible">True</property>
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<widget class="GtkLabel" id="label18">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Type:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">fs-type-combo</property>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox11">
<property name="visible">True</property>
<child>
<widget class="GtkComboBox" id="fs-type-combo">
<property name="visible">True</property>
<signal name="changed" handler="on_fs_type_combo_changed" swapped="no"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="fs-type-label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label">Passthrough</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label19">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Mode:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">fs-type-combo</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox12">
<property name="visible">True</property>
<child>
<widget class="GtkComboBox" id="fs-mode-combo">
<property name="visible">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="fs-mode-label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Default</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="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="fs-source-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label">_Source label:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">fs-source</property>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label33">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Ta_rget path:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">fs-target</property>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="fs-source">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="fs-target">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="position">10</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label14">
<property name="visible">True</property>
<property name="label">fs</property>
</widget>
<packing>
<property name="position">10</property>
<property name="tab_fill">False</property>
<property name="type">tab</property>
</packing>
</child>
</widget>
</child>
</widget>
@ -2033,7 +2226,7 @@ and default action should be used.</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_create_help_clicked"/>
<signal name="clicked" handler="on_create_help_clicked" swapped="no"/>
</widget>
<packing>
<property name="expand">False</property>
@ -2049,7 +2242,7 @@ and default action should be used.</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_create_cancel_clicked"/>
<signal name="clicked" handler="on_create_cancel_clicked" swapped="no"/>
</widget>
<packing>
<property name="expand">False</property>
@ -2064,7 +2257,7 @@ and default action should be used.</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_create_finish_clicked"/>
<signal name="clicked" handler="on_create_finish_clicked" swapped="no"/>
</widget>
<packing>
<property name="expand">False</property>