addstorage: Absorb advanced field UI

Share the UI for changing all these disk properties:

- shareable
- readonly
- removable
- cache
- discard
- detect zeroes

Move them all under the 'Advanced options' expander in details, and
add the checkbox options to the addhardware wizard.

Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2020-09-07 18:29:20 -04:00
parent 8d5439567b
commit c54da68535
10 changed files with 410 additions and 453 deletions

View File

@ -148,6 +148,8 @@ class AddHardware(uiutils.UITestCase):
tab = self._select_hw(addhw, "Storage", "storage-tab")
tab.combo_select("Bus type:", "VirtIO")
tab.find("Advanced options", "toggle button").click_expander()
tab.find("Shareable:", "check box").click()
tab.find("Readonly:", "check box").click()
tab.combo_select("Cache mode:", "none")
tab.combo_select("Discard mode:", "ignore")
tab.combo_select("Detect zeroes:", "unmap")

View File

@ -333,6 +333,7 @@ class NewVM(uiutils.UITestCase):
# Device is now 'USB Disk 1'
c = hwlist.find("USB Disk 1", "table cell")
uiutils.check(lambda: c.state_selected)
tab.find("Advanced options", "toggle button").click_expander()
tab.find("Removable:", "check box").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)

View File

@ -366,12 +366,12 @@ class Details(uiutils.UITestCase):
# Disk options
tab = self._select_hw(win, "IDE Disk 1", "disk-tab")
tab.find("Advanced options", "toggle button").click_expander()
tab.find("Shareable:", "check box").click()
tab.find("Readonly:", "check box").click()
tab.find("Advanced options", "toggle button").click_expander()
tab.find("Cache mode:", "text").set_text("unsafe")
tab.find("Discard mode:", "text").set_text("unmap")
tab.find("Detect zeroes:", "text").set_text("unmap")
tab.combo_select("Cache mode:", "unsafe")
tab.combo_select("Discard mode:", "unmap")
tab.combo_select("Detect zeroes:", "unmap")
appl.click()
uiutils.check(lambda: not appl.sensitive)
@ -441,6 +441,7 @@ class Details(uiutils.UITestCase):
# Fail to hotremove
tab = self._select_hw(win, "Floppy 1", "disk-tab")
tab.find("Advanced options", "toggle button").click_expander()
share = tab.find("Shareable", "check box")
share.click()
uiutils.check(lambda: appl.sensitive)
@ -620,7 +621,7 @@ class Details(uiutils.UITestCase):
# Attempt to apply changes when skipping away, but they fail
tab.find("Advanced options", "toggle button").click_expander()
tab.find("Cache mode:", "text").set_text("badcachemode")
tab.find("Cache mode:", "combo").find(None, "text").set_text("badcachemode")
hwlist.find("CPUs", "table cell").click()
self._click_alert_button("There are unapplied changes", "Yes")
self._click_alert_button("badcachemode", "Close")

View File

@ -213,101 +213,15 @@
</packing>
</child>
<child>
<object class="GtkExpander" id="disk-advanced-expander">
<object class="GtkAlignment" id="storage-advanced-align">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkGrid" id="grid3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="label28">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Cac_he mode:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">storage-cache</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="storage-cache">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-storage-discard">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Discard mod_e:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">storage-discard</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="storage-discard">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-storage-detect-zeroes">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Detect _zeroes:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">storage-detect-zeroes</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="storage-detect-zeroes">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label19">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Ad_vanced options&lt;/b&gt;</property>
<property name="use_markup">True</property>
<property name="use_underline">True</property>
</object>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<!-- Generated with glade 3.36.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">1000000</property>
<property name="step_increment">0.10000000000000001</property>
<property name="step_increment">0.1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkBox" id="storage-box">
@ -237,4 +237,213 @@
</packing>
</child>
</object>
<object class="GtkBox" id="storage-advanced-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkExpander" id="storage-advanced">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkGrid" id="table19">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">3</property>
<property name="column_spacing">8</property>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Cac_he mode:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-cache</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="disk-cache">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<signal name="changed" handler="on_disk_cache_combo_changed" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-disk-discard">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Discard mod_e:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-discard</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="disk-discard">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<signal name="changed" handler="on_disk_discard_combo_changed" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-disk-detect-zeroes">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Detect _zeroes:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-detect-zeroes</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="disk-detect-zeroes">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<signal name="changed" handler="on_disk_detect_zeroes_combo_changed" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="permissions-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">R_eadonly:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-readonly</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Sharea_ble:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-shareable</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="disk-readonly">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_disk_readonly_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="disk-shareable">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_disk_shareable_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label46">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Removab_le:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-removable</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="disk-removable">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="use_stock">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_disk_removable_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label31">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Advanced _options</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</interface>

View File

@ -2423,61 +2423,6 @@
<property name="border_width">3</property>
<property name="row_spacing">4</property>
<property name="column_spacing">8</property>
<child>
<object class="GtkLabel" id="permissions-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">R_eadonly:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-readonly</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Sharea_ble:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-shareable</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="disk-readonly">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_disk_readonly_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="disk-shareable">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_disk_shareable_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
@ -2614,35 +2559,6 @@
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label46">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Removab_le:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-removable</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="disk-removable">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="use_stock">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_disk_removable_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">6</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="disk-bus-labeller">
<property name="visible">True</property>
@ -2707,131 +2623,11 @@
</packing>
</child>
<child>
<object class="GtkExpander" id="expander4">
<object class="GtkAlignment" id="storage-advanced-align">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="box10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkGrid" id="table19">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">3</property>
<property name="column_spacing">8</property>
<child>
<object class="GtkLabel" id="label123">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Cac_he mode:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-cache-text</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="disk-cache">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<signal name="changed" handler="on_disk_cache_combo_changed" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry" id="disk-cache-text">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-disk-discard">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Discard mod_e:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-discard-text</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="disk-discard">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<signal name="changed" handler="on_disk_discard_combo_changed" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry" id="disk-discard-text">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-disk-detect-zeroes">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Detect _zeroes:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">disk-detect-zeroes-text</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="disk-detect-zeroes">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<signal name="changed" handler="on_disk_detect_zeroes_combo_changed" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry" id="disk-detect-zeroes-text">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label31">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Advanced _options</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">expander4</property>
</object>
<placeholder/>
</child>
</object>
<packing>

View File

@ -46,24 +46,6 @@ from .xmleditor import vmmXMLEditor
PAGE_VSOCK) = range(17)
def _build_combo(combo, values, default_value=None, sort=True):
"""
Helper to build a combo with model schema [xml value, label]
"""
model = Gtk.ListStore(object, str)
combo.set_model(model)
uiutil.init_combo_text_column(combo, 1)
if sort:
model.set_sort_column_id(1, Gtk.SortType.ASCENDING)
for xmlval, label in values:
model.append([xmlval, label])
if default_value:
uiutil.set_list_selection(combo, default_value)
elif len(model):
combo.set_active(0)
class vmmAddHardware(vmmGObjectUI):
def __init__(self, vm):
vmmGObjectUI.__init__(self, "addhardware.ui", "vmm-add-hardware")
@ -89,6 +71,8 @@ class vmmAddHardware(vmmGObjectUI):
self.addstorage = vmmAddStorage(self.conn, self.builder, self.topwin)
self.widget("storage-align").add(self.addstorage.top_box)
self.widget("storage-advanced-align").add(
self.addstorage.advanced_top_box)
self.addstorage.connect("browse-clicked", self._browse_storage_cb)
self._vsockdetails = vmmVsockDetails(self.vm, self.builder, self.topwin)
@ -191,16 +175,12 @@ class vmmAddHardware(vmmGObjectUI):
# Individual HW page UI
self.build_disk_bus_combo(self.vm, self.widget("storage-bustype"))
self._build_disk_device_combo()
self.build_disk_cache_combo(self.vm, self.widget("storage-cache"))
self.build_disk_discard_combo(self.vm, self.widget("storage-discard"))
self.build_disk_detect_zeroes_combo(self.vm,
self.widget("storage-detect-zeroes"))
self.build_network_model_combo(self.vm, self.widget("net-model"))
self._build_input_combo()
self.build_sound_combo(self.vm, self.widget("sound-model"))
self._build_hostdev_treeview()
self.build_video_combo(self.vm, self.widget("video-model"))
_build_combo(self.widget("char-device-type"), [])
uiutil.build_simple_combo(self.widget("char-device-type"), [])
self._build_char_target_type_combo()
self._build_char_target_name_combo()
self.build_watchdogmodel_combo(self.vm, self.widget("watchdog-model"))
@ -209,7 +189,7 @@ class vmmAddHardware(vmmGObjectUI):
self._build_redir_type_combo()
self._build_tpm_type_combo(self.vm)
self._build_panic_model_combo()
_build_combo(self.widget("controller-model"), [])
uiutil.build_simple_combo(self.widget("controller-model"), [])
self._build_controller_type_combo()
@ -301,8 +281,6 @@ class vmmAddHardware(vmmGObjectUI):
# Storage params
self.widget("storage-devtype").set_active(0)
self.widget("storage-devtype").emit("changed")
self.widget("storage-cache").set_active(0)
self.widget("disk-advanced-expander").set_expanded(False)
self.addstorage.reset_state()
@ -709,30 +687,9 @@ class vmmAddHardware(vmmGObjectUI):
"drive-harddisk", _("LUN Passthrough")])
target_list.set_active(0)
@staticmethod
def build_disk_cache_combo(_vm, combo):
values = [[None, _("Hypervisor default")]]
for m in DeviceDisk.CACHE_MODES:
values.append([m, m])
_build_combo(combo, values, sort=False)
@staticmethod
def build_disk_discard_combo(_vm, combo):
values = [[None, _("Hypervisor default")]]
for m in DeviceDisk.DISCARD_MODES:
values.append([m, m])
_build_combo(combo, values, sort=False)
@staticmethod
def build_disk_detect_zeroes_combo(_vm, combo):
values = [[None, _("Hypervisor default")]]
for m in DeviceDisk.DETECT_ZEROES_MODES:
values.append([m, m])
_build_combo(combo, values, sort=False)
@staticmethod
def build_disk_bus_combo(_vm, combo):
_build_combo(combo, [])
uiutil.build_simple_combo(combo, [])
@staticmethod
def populate_disk_bus_combo(vm, devtype, model):
@ -759,7 +716,7 @@ class vmmAddHardware(vmmGObjectUI):
@staticmethod
def build_network_model_combo(vm, combo):
_build_combo(combo, [])
uiutil.build_simple_combo(combo, [])
vmmAddHardware.populate_network_model_combo(vm, combo)
@ -774,7 +731,7 @@ class vmmAddHardware(vmmGObjectUI):
cvals = [((t, b), vmmAddHardware.input_pretty_name(t, b))
for t, b in devices]
_build_combo(self.widget("input-type"), cvals)
uiutil.build_simple_combo(self.widget("input-type"), cvals)
@staticmethod
@ -784,7 +741,7 @@ class vmmAddHardware(vmmGObjectUI):
values.append([m, vmmAddHardware.sound_pretty_model(m)])
default = DeviceSound.default_model(vm.xmlobj)
_build_combo(combo, values, default_value=default)
uiutil.build_simple_combo(combo, values, default_value=default)
def _build_hostdev_treeview(self):
@ -833,7 +790,7 @@ class vmmAddHardware(vmmGObjectUI):
if not values:
values.append([None, _("Hypervisor default")])
default = DeviceVideo.default_model(vm.xmlobj)
_build_combo(combo, values, default_value=default)
uiutil.build_simple_combo(combo, values, default_value=default)
def _build_char_target_type_combo(self):
@ -842,13 +799,13 @@ class vmmAddHardware(vmmGObjectUI):
values.append(["virtio", "VirtIO"])
else:
values.append([None, _("Hypervisor default")])
_build_combo(self.widget("char-target-type"), values)
uiutil.build_simple_combo(self.widget("char-target-type"), values)
def _build_char_target_name_combo(self):
values = []
for n in DeviceChannel.CHANNEL_NAMES:
values.append([n, n])
_build_combo(self.widget("char-target-name"), values)
uiutil.build_simple_combo(self.widget("char-target-name"), values)
def _populate_char_device_type_combo(self):
char_class = self._get_char_class()
@ -865,14 +822,14 @@ class vmmAddHardware(vmmGObjectUI):
values = []
for m in DeviceWatchdog.MODELS:
values.append([m, m.upper()])
_build_combo(combo, values, default_value=DeviceWatchdog.MODEL_I6300)
uiutil.build_simple_combo(combo, values, default_value=DeviceWatchdog.MODEL_I6300)
@staticmethod
def build_watchdogaction_combo(_vm, combo):
values = []
for m in DeviceWatchdog.ACTIONS:
values.append([m, vmmAddHardware.watchdog_pretty_action(m)])
_build_combo(combo, values, default_value=DeviceWatchdog.ACTION_RESET)
uiutil.build_simple_combo(combo, values, default_value=DeviceWatchdog.ACTION_RESET)
@staticmethod
@ -881,27 +838,27 @@ class vmmAddHardware(vmmGObjectUI):
["passthrough", _("Passthrough")],
["host", _("Host")],
]
_build_combo(combo, values)
uiutil.build_simple_combo(combo, values)
def _build_redir_type_combo(self):
values = [["spicevmc", _("Spice channel")]]
_build_combo(self.widget("usbredir-list"), values)
uiutil.build_simple_combo(self.widget("usbredir-list"), values)
def _build_tpm_type_combo(self, vm):
values = []
for t in DeviceTpm.TYPES:
values.append([t, vmmAddHardware.tpm_pretty_type(t)])
_build_combo(self.widget("tpm-type"), values)
uiutil.build_simple_combo(self.widget("tpm-type"), values)
values = []
for t in vmmAddHardware._get_tpm_model_list(vm, None):
values.append([t, vmmAddHardware.tpm_pretty_model(t)])
_build_combo(self.widget("tpm-model"), values)
uiutil.build_simple_combo(self.widget("tpm-model"), values)
values = []
for t in DeviceTpm.VERSIONS:
values.append([t, t])
_build_combo(self.widget("tpm-version"), values,
uiutil.build_simple_combo(self.widget("tpm-version"), values,
default_value=DeviceTpm.VERSION_2_0)
@staticmethod
@ -929,7 +886,7 @@ class vmmAddHardware(vmmGObjectUI):
@staticmethod
def build_tpm_model_combo(vm, combo, tpmversion):
_build_combo(combo, [])
uiutil.build_simple_combo(combo, [])
vmmAddHardware.populate_tpm_model_combo(vm, combo, tpmversion)
@ -939,7 +896,7 @@ class vmmAddHardware(vmmGObjectUI):
values.append([m, vmmAddHardware.panic_pretty_model(m)])
default = DevicePanic.get_default_model(self.vm.get_xmlobj())
_build_combo(self.widget("panic-model"), values, default_value=default)
uiutil.build_simple_combo(self.widget("panic-model"), values, default_value=default)
def _build_controller_type_combo(self):
@ -947,7 +904,7 @@ class vmmAddHardware(vmmGObjectUI):
for t in vmmAddHardware.controller_recommended_types():
values.append([t, vmmAddHardware.controller_pretty_type(t)])
_build_combo(self.widget("controller-type"), values,
uiutil.build_simple_combo(self.widget("controller-type"), values,
default_value=DeviceController.TYPE_SCSI)
@staticmethod
@ -1483,24 +1440,12 @@ class vmmAddHardware(vmmGObjectUI):
self.widget("storage-bustype"))
device = uiutil.get_list_selection(
self.widget("storage-devtype"))
cache = uiutil.get_list_selection(
self.widget("storage-cache"))
discard = uiutil.get_list_selection(
self.widget("storage-discard"))
detect_zeroes = uiutil.get_list_selection(
self.widget("storage-detect-zeroes"))
disk = self.addstorage.build_device(self.vm.get_name(),
collideguest=self.vm.xmlobj, device=device)
used = []
disk.bus = bus
if cache:
disk.driver_cache = cache
if discard:
disk.driver_discard = discard
if detect_zeroes:
disk.driver_detect_zeroes = detect_zeroes
# Generate target
disks = (self.vm.xmlobj.devices.disk +

View File

@ -52,14 +52,9 @@ from ..delete import vmmDeleteStorage
EDIT_KERNEL,
EDIT_INIT,
EDIT_DISK_RO,
EDIT_DISK_SHARE,
EDIT_DISK_REMOVABLE,
EDIT_DISK_CACHE,
EDIT_DISK_DISCARD,
EDIT_DISK_DETECT_ZEROES,
EDIT_DISK_BUS,
EDIT_DISK_PATH,
EDIT_DISK,
EDIT_SOUND_MODEL,
@ -94,7 +89,7 @@ from ..delete import vmmDeleteStorage
EDIT_FS,
EDIT_HOSTDEV_ROMBAR) = range(1, 49)
EDIT_HOSTDEV_ROMBAR) = range(1, 44)
# Columns in hw list model
@ -404,6 +399,11 @@ class vmmDetails(vmmGObjectUI):
self.vsockdetails.connect("changed-auto-cid", _e(EDIT_VSOCK_AUTO))
self.vsockdetails.connect("changed-cid", _e(EDIT_VSOCK_CID))
self._addstorage = vmmAddStorage(self.conn, self.builder, self.topwin)
self.widget("storage-advanced-align").add(
self._addstorage.advanced_top_box)
self._addstorage.connect("changed", _e(EDIT_DISK))
self._xmleditor = vmmXMLEditor(self.builder, self.topwin,
self.widget("hw-panel-align"),
self.widget("hw-panel"))
@ -467,12 +467,6 @@ class vmmDetails(vmmGObjectUI):
"on_disk_source_browse_clicked": self._disk_source_browse_clicked_cb,
"on_disk_readonly_changed": _e(EDIT_DISK_RO),
"on_disk_shareable_changed": _e(EDIT_DISK_SHARE),
"on_disk_removable_changed": _e(EDIT_DISK_REMOVABLE),
"on_disk_cache_combo_changed": _e(EDIT_DISK_CACHE),
"on_disk_discard_combo_changed": _e(EDIT_DISK_DISCARD),
"on_disk_detect_zeroes_combo_changed": _e(EDIT_DISK_DETECT_ZEROES),
"on_disk_bus_combo_changed": _e(EDIT_DISK_BUS),
"on_network_model_combo_changed": _e(EDIT_NET_MODEL),
@ -810,18 +804,6 @@ class vmmDetails(vmmGObjectUI):
for name in domcaps.get_cpu_models():
model.append([name, name, name, False])
# Disk cache combo
disk_cache = self.widget("disk-cache")
vmmAddHardware.build_disk_cache_combo(self.vm, disk_cache)
# Discard combo
combo = self.widget("disk-discard")
vmmAddHardware.build_disk_discard_combo(self.vm, combo)
# Detect zeroes combo
combo = self.widget("disk-detect-zeroes")
vmmAddHardware.build_disk_detect_zeroes_combo(self.vm, combo)
# Disk bus combo
disk_bus = self.widget("disk-bus")
vmmAddHardware.build_disk_bus_combo(self.vm, disk_bus)
@ -1521,27 +1503,9 @@ class vmmDetails(vmmGObjectUI):
vmmAddStorage.check_path_search(self, self.conn, path)
kwargs["path"] = path or None
if self._edited(EDIT_DISK_RO):
kwargs["readonly"] = self.widget("disk-readonly").get_active()
if self._edited(EDIT_DISK_SHARE):
kwargs["shareable"] = self.widget("disk-shareable").get_active()
if self._edited(EDIT_DISK_REMOVABLE):
kwargs["removable"] = bool(
self.widget("disk-removable").get_active())
if self._edited(EDIT_DISK_CACHE):
kwargs["cache"] = uiutil.get_list_selection(
self.widget("disk-cache"))
if self._edited(EDIT_DISK_DISCARD):
kwargs["discard"] = uiutil.get_list_selection(
self.widget("disk-discard"))
if self._edited(EDIT_DISK_DETECT_ZEROES):
kwargs["detect_zeroes"] = uiutil.get_list_selection(
self.widget("disk-detect-zeroes"))
if self._edited(EDIT_DISK):
vals = self._addstorage.get_values()
kwargs.update(vals)
if self._edited(EDIT_DISK_BUS):
kwargs["bus"] = uiutil.get_list_selection(
@ -2004,13 +1968,7 @@ class vmmDetails(vmmGObjectUI):
def _refresh_disk_page(self, disk):
path = disk.path
devtype = disk.device
ro = disk.read_only
share = disk.shareable
bus = disk.bus
removable = disk.removable
cache = disk.driver_cache
discard = disk.driver_discard
detect_zeroes = disk.driver_detect_zeroes
size = "-"
if path:
@ -2019,31 +1977,11 @@ class vmmDetails(vmmGObjectUI):
if vol:
size = vol.get_pretty_capacity()
is_usb = (bus == "usb")
can_set_removable = (is_usb and (self.conn.is_qemu() or
self.conn.is_test()))
if removable is None:
removable = False
else:
can_set_removable = True
pretty_name = _label_for_device(disk)
self.widget("disk-target-type").set_text(pretty_name)
self.widget("disk-readonly").set_active(ro)
self.widget("disk-readonly").set_sensitive(not disk.is_cdrom())
self.widget("disk-shareable").set_active(share)
self.widget("disk-removable").set_active(removable)
uiutil.set_grid_row_visible(self.widget("disk-removable"),
can_set_removable)
self.widget("disk-size").set_text(size)
uiutil.set_list_selection(self.widget("disk-cache"), cache)
uiutil.set_list_selection(self.widget("disk-discard"), discard)
uiutil.set_list_selection(self.widget("disk-detect-zeroes"),
detect_zeroes)
vmmAddHardware.populate_disk_bus_combo(self.vm, devtype,
self.widget("disk-bus").get_model())
@ -2060,6 +1998,8 @@ class vmmDetails(vmmGObjectUI):
self._mediacombo.reset_state(is_floppy=disk.is_floppy())
self._mediacombo.set_path(path or "")
self._addstorage.set_dev(disk)
def _refresh_network_page(self, net):
vmmAddHardware.populate_network_model_combo(
self.vm, self.widget("network-model"))

View File

@ -13,11 +13,21 @@ from virtinst import log
from ..lib import uiutil
from ..baseclass import vmmGObjectUI
(
_EDIT_CACHE,
_EDIT_DISCARD,
_EDIT_DETECT_ZEROES,
_EDIT_RO,
_EDIT_SHARE,
_EDIT_REMOVABLE,
) = range(1, 7)
class vmmAddStorage(vmmGObjectUI):
__gsignals__ = {
"browse-clicked": (vmmGObjectUI.RUN_FIRST, None, [object]),
"storage-toggled": (vmmGObjectUI.RUN_FIRST, None, [object])
"storage-toggled": (vmmGObjectUI.RUN_FIRST, None, [object]),
"changed": (vmmGObjectUI.RUN_FIRST, None, []),
}
def __init__(self, conn, builder, topwin):
@ -25,12 +35,26 @@ class vmmAddStorage(vmmGObjectUI):
builder=builder, topwin=topwin)
self.conn = conn
def _e(edittype):
def signal_cb(*args):
self._change_cb(edittype)
return signal_cb
self.builder.connect_signals({
"on_storage_browse_clicked": self._browse_storage,
"on_storage_select_toggled": self._toggle_storage_select,
"on_disk_cache_combo_changed": _e(_EDIT_CACHE),
"on_disk_discard_combo_changed": _e(_EDIT_DISCARD),
"on_disk_detect_zeroes_combo_changed": _e(_EDIT_DETECT_ZEROES),
"on_disk_readonly_changed": _e(_EDIT_RO),
"on_disk_shareable_changed": _e(_EDIT_SHARE),
"on_disk_removable_changed": _e(_EDIT_REMOVABLE),
})
self._active_edits = []
self.top_box = self.widget("storage-box")
self.advanced_top_box = self.widget("storage-advanced-box")
self._init_ui()
def _cleanup(self):
self.conn = None
@ -67,6 +91,28 @@ class vmmAddStorage(vmmGObjectUI):
hd_label = ("<span>%s</span>" % hd_label)
widget.set_markup(hd_label)
def _init_ui(self):
# Disk cache combo
values = [[None, _("Hypervisor default")]]
for m in virtinst.DeviceDisk.CACHE_MODES:
values.append([m, m])
uiutil.build_simple_combo(
self.widget("disk-cache"), values, sort=False)
# Discard combo
values = [[None, _("Hypervisor default")]]
for m in virtinst.DeviceDisk.DISCARD_MODES:
values.append([m, m])
uiutil.build_simple_combo(
self.widget("disk-discard"), values, sort=False)
# Detect zeroes combo
values = [[None, _("Hypervisor default")]]
for m in virtinst.DeviceDisk.DETECT_ZEROES_MODES:
values.append([m, m])
uiutil.build_simple_combo(
self.widget("disk-detect-zeroes"), values, sort=False)
##############
# Public API #
@ -122,10 +168,19 @@ class vmmAddStorage(vmmGObjectUI):
def reset_state(self):
self._update_host_space()
self._active_edits = []
self.widget("storage-create").set_active(True)
self.widget("storage-size").set_value(20)
self.widget("storage-entry").set_text("")
self.widget("storage-create-box").set_sensitive(True)
self.widget("disk-cache").set_active(0)
self.widget("disk-discard").set_active(0)
self.widget("disk-detect-zeroes").set_active(0)
self.widget("storage-advanced").set_expanded(False)
self.widget("disk-readonly").set_active(False)
self.widget("disk-shareable").set_active(False)
self.widget("disk-removable").set_active(False)
uiutil.set_grid_row_visible(self.widget("disk-removable"), False)
storage_tooltip = None
@ -170,6 +225,18 @@ class vmmAddStorage(vmmGObjectUI):
disk = virtinst.DeviceDisk(self.conn.get_backend())
disk.path = path or None
disk.device = device
vals = self.get_values()
if vals.get("cache") is not None:
disk.driver_cache = vals.get("cache")
if vals.get("discard") is not None:
disk.driver_discard = vals.get("discard")
if vals.get("detect_zeroes") is not None:
disk.driver_detect_zeroes = vals.get("detect_zeroes")
if vals.get("readonly") is not None:
disk.read_only = vals.get("readonly")
if vals.get("shareable") is not None:
disk.shareable = vals.get("shareable")
if disk.wants_storage_creation():
pool = disk.get_parent_pool()
@ -212,6 +279,65 @@ class vmmAddStorage(vmmGObjectUI):
self.check_path_search(self, self.conn, disk.path)
##################
# Device editing #
##################
def set_dev(self, disk):
cache = disk.driver_cache
discard = disk.driver_discard
detect_zeroes = disk.driver_detect_zeroes
ro = disk.read_only
share = disk.shareable
removable = disk.removable
is_usb = (disk.bus == "usb")
can_set_removable = (is_usb and (self.conn.is_qemu() or
self.conn.is_test()))
if removable is None:
removable = False
else:
can_set_removable = True
uiutil.set_list_selection(self.widget("disk-cache"), cache)
uiutil.set_list_selection(self.widget("disk-discard"), discard)
uiutil.set_list_selection(
self.widget("disk-detect-zeroes"), detect_zeroes)
self.widget("disk-readonly").set_active(ro)
self.widget("disk-readonly").set_sensitive(not disk.is_cdrom())
self.widget("disk-shareable").set_active(share)
self.widget("disk-removable").set_active(removable)
uiutil.set_grid_row_visible(
self.widget("disk-removable"), can_set_removable)
# This comes last
self._active_edits = []
def get_values(self):
ret = {}
if _EDIT_CACHE in self._active_edits:
ret["cache"] = uiutil.get_list_selection(
self.widget("disk-cache"))
if _EDIT_DISCARD in self._active_edits:
ret["discard"] = uiutil.get_list_selection(
self.widget("disk-discard"))
if _EDIT_DETECT_ZEROES in self._active_edits:
ret["detect_zeroes"] = uiutil.get_list_selection(
self.widget("disk-detect-zeroes"))
if _EDIT_RO in self._active_edits:
ret["readonly"] = self.widget("disk-readonly").get_active()
if _EDIT_SHARE in self._active_edits:
ret["shareable"] = self.widget("disk-shareable").get_active()
if _EDIT_REMOVABLE in self._active_edits:
ret["removable"] = bool(
self.widget("disk-removable").get_active())
return ret
#############
# Listeners #
#############
@ -223,3 +349,8 @@ class vmmAddStorage(vmmGObjectUI):
act = src.get_active()
self.widget("storage-browse-box").set_sensitive(act)
self.emit("storage-toggled", src)
def _change_cb(self, edittype):
if edittype not in self._active_edits:
self._active_edits.append(edittype)
self.emit("changed")

View File

@ -176,3 +176,21 @@ def pretty_mem(val):
return "%2.2f GiB" % (val / (1024.0 * 1024.0))
else:
return "%2.0f MiB" % (val / 1024.0)
def build_simple_combo(combo, values, default_value=None, sort=True):
"""
Helper to build a combo with model schema [xml value, label]
"""
model = Gtk.ListStore(object, str)
combo.set_model(model)
init_combo_text_column(combo, 1)
if sort:
model.set_sort_column_id(1, Gtk.SortType.ASCENDING)
for xmlval, label in values:
model.append([xmlval, label])
if default_value:
set_list_selection(combo, default_value)
elif len(model):
combo.set_active(0)