virt-manager/virtManager/device/fsdetails.py

294 lines
9.7 KiB
Python

# Copyright (C) 2006-2007, 2013, 2014 Red Hat, Inc.
# Copyright (C) 2006 Hugh O. Brock <hbrock@redhat.com>
# Copyright (C) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from gi.repository import Gtk
from virtinst import DeviceFilesystem
from virtinst import xmlutil
from ..lib import uiutil
from ..baseclass import vmmGObjectUI
from ..storagebrowse import vmmStorageBrowser
_EDIT_FS_ENUM = range(1, 8)
(
_EDIT_FS_TYPE,
_EDIT_FS_DRIVER,
_EDIT_FS_SOURCE,
_EDIT_FS_RAM_SOURCE,
_EDIT_FS_READONLY,
_EDIT_FS_TARGET,
_EDIT_FS_FORMAT,
) = _EDIT_FS_ENUM
class vmmFSDetails(vmmGObjectUI):
__gsignals__ = {
"changed": (vmmGObjectUI.RUN_FIRST, None, [])
}
def __init__(self, vm, builder, topwin):
vmmGObjectUI.__init__(self, "fsdetails.ui",
None, builder=builder, topwin=topwin)
self.vm = vm
self.conn = vm.conn
self._storage_browser = None
self._active_edits = []
def _e(edittype):
def signal_cb(*args):
self._change_cb(edittype)
return signal_cb
self.builder.connect_signals({
"on_fs_source_browse_clicked": self._browse_fs_source_cb,
"on_fs_type_combo_changed": _e(_EDIT_FS_TYPE),
"on_fs_driver_combo_changed": _e(_EDIT_FS_DRIVER),
"on_fs_readonly_toggled": _e(_EDIT_FS_READONLY),
"on_fs_format_combo_changed": _e(_EDIT_FS_FORMAT),
"on_fs_source_changed": _e(_EDIT_FS_SOURCE),
"on_fs_ram_source_changed": _e(_EDIT_FS_RAM_SOURCE),
"on_fs_target_changed": _e(_EDIT_FS_TARGET),
})
self._init_ui()
self.top_box = self.widget("vmm-fs-details")
def _cleanup(self):
self.vm = None
self.conn = None
if self._storage_browser:
self._storage_browser.cleanup()
self._storage_browser = None
##########################
# Initialization methods #
##########################
def _init_ui(self):
def simple_store_set(comboname, values):
combo = self.widget(comboname)
# [XML value, label]
model = Gtk.ListStore(str, str)
combo.set_model(model)
uiutil.init_combo_text_column(combo, 1)
for xmlval in values:
label = xmlval
if xmlval is None:
label = _("Hypervisor default")
model.append([xmlval, label])
# Filesystem widgets
if self.conn.is_container_only():
simple_store_set("fs-type-combo",
[DeviceFilesystem.TYPE_MOUNT,
DeviceFilesystem.TYPE_FILE,
DeviceFilesystem.TYPE_BLOCK,
DeviceFilesystem.TYPE_RAM])
else:
simple_store_set("fs-type-combo", [DeviceFilesystem.TYPE_MOUNT])
if self.conn.is_container_only():
simple_store_set("fs-driver-combo",
[DeviceFilesystem.DRIVER_LOOP,
DeviceFilesystem.DRIVER_NBD,
None])
else:
domcaps = self.vm.get_domain_capabilities()
rows = []
if domcaps.supports_filesystem_virtiofs():
rows.append(["virtiofs", "virtiofs"])
rows.append([None, "virtio-9p"])
uiutil.build_simple_combo(
self.widget("fs-driver-combo"), rows, sort=False)
simple_store_set("fs-format-combo", ["raw", "qcow2"])
self.widget("fs-readonly").set_visible(
self.conn.is_qemu() or
self.conn.is_test() or
self.conn.is_lxc())
##############
# UI syncing #
##############
def _sync_ui(self):
fstype = uiutil.get_list_selection(self.widget("fs-type-combo"))
fsdriver = uiutil.get_list_selection(self.widget("fs-driver-combo"))
is_qemu = self.conn.is_qemu() or self.conn.is_test()
show_ram_source = fstype == DeviceFilesystem.TYPE_RAM
uiutil.set_grid_row_visible(
self.widget("fs-ram-source-box"), show_ram_source)
uiutil.set_grid_row_visible(
self.widget("fs-source-box"), not show_ram_source)
show_format = bool(
fsdriver == DeviceFilesystem.DRIVER_NBD)
uiutil.set_grid_row_visible(
self.widget("fs-format-combo"), show_format)
show_driver_combo = is_qemu or fstype == DeviceFilesystem.TYPE_FILE
if fstype == DeviceFilesystem.TYPE_TEMPLATE:
source_text = _("Te_mplate:")
else:
source_text = _("_Source path:")
self.widget("fs-source-title").set_text(source_text)
self.widget("fs-source-title").set_use_underline(True)
uiutil.set_grid_row_visible(
self.widget("fs-type-combo"), not is_qemu)
uiutil.set_grid_row_visible(
self.widget("fs-driver-combo"), show_driver_combo)
need_shared_mem = fsdriver == "virtiofs"
have_shared_mem, _shared_mem_err = self.vm.has_shared_mem()
show_shared_mem_warn = need_shared_mem and not have_shared_mem
uiutil.set_grid_row_visible(
self.widget("fs-driver-warn-box"), show_shared_mem_warn)
if show_shared_mem_warn:
label = _(
"You may need to 'Enable shared memory' on the 'Memory' screen.")
self.widget("fs-driver-warn").set_markup(
"<small>%s</small>" % xmlutil.xml_escape(label))
##############
# Public API #
##############
def reset_state(self):
self.widget("fs-type-combo").set_active(0)
self.widget("fs-driver-combo").set_active(0)
self.widget("fs-format-combo").set_active(0)
self.widget("fs-source").set_text("")
self.widget("fs-target").set_text("")
self.widget("fs-readonly").set_active(False)
self._sync_ui()
self._active_edits = []
def set_dev(self, dev):
self.reset_state()
uiutil.set_list_selection(
self.widget("fs-type-combo"), dev.type)
uiutil.set_list_selection(
self.widget("fs-driver-combo"), dev.driver_type)
uiutil.set_list_selection(
self.widget("fs-format-combo"), dev.driver_format)
if dev.type != DeviceFilesystem.TYPE_RAM:
self.widget("fs-source").set_text(dev.source)
else:
self.widget("fs-ram-source-spin").set_value(int(dev.source) // 1024)
self.widget("fs-target").set_text(dev.target or "")
self.widget("fs-readonly").set_active(dev.readonly)
self._active_edits = []
###################
# Device building #
###################
def _set_values(self, dev):
fstype = uiutil.get_list_selection(self.widget("fs-type-combo"))
usage = uiutil.spin_get_helper(self.widget("fs-ram-source-spin"))
source = self.widget("fs-source").get_text()
target = self.widget("fs-target").get_text()
readonly = self.widget("fs-readonly").get_active()
fsformat = uiutil.get_list_selection(self.widget("fs-format-combo"))
if not self.widget("fs-format-combo").get_visible():
fsformat = None
driver = uiutil.get_list_selection(self.widget("fs-driver-combo"))
if not self.widget("fs-driver-combo").get_visible():
driver = None
if _EDIT_FS_TYPE in self._active_edits:
dev.type = fstype
if (_EDIT_FS_RAM_SOURCE in self._active_edits or
_EDIT_FS_SOURCE in self._active_edits):
if fstype == DeviceFilesystem.TYPE_RAM:
dev.source = usage
dev.source_units = 'MiB'
else:
dev.source = source
if _EDIT_FS_TARGET in self._active_edits:
dev.target = target
if _EDIT_FS_READONLY in self._active_edits:
dev.readonly = readonly
if _EDIT_FS_DRIVER in self._active_edits:
origdriver = dev.driver_type
dev.driver_type = driver
if origdriver == "virtiofs" or driver == "virtiofs":
# Need to reset the accessmode for virtiofs
dev.accessmode = dev.default_accessmode()
if _EDIT_FS_FORMAT in self._active_edits:
dev.driver_format = fsformat
def build_device(self):
self._active_edits = _EDIT_FS_ENUM[:]
conn = self.conn.get_backend()
dev = DeviceFilesystem(conn)
self._set_values(dev)
dev.validate_target(dev.target)
dev.validate()
return dev
def update_device(self, dev):
newdev = DeviceFilesystem(dev.conn, parsexml=dev.get_xml())
self._set_values(newdev)
return newdev
####################
# Internal helpers #
####################
def _browse_file(self, textent, isdir=False):
def set_storage_cb(src, path):
if path:
textent.set_text(path)
reason = (isdir and
self.config.CONFIG_DIR_FS or
self.config.CONFIG_DIR_IMAGE)
if self._storage_browser is None:
self._storage_browser = vmmStorageBrowser(self.conn)
self._storage_browser.set_finish_cb(set_storage_cb)
self._storage_browser.set_browse_reason(reason)
self._storage_browser.show(self.topwin.get_ancestor(Gtk.Window))
#############
# Listeners #
#############
def _change_cb(self, edittype):
self._sync_ui()
if edittype not in self._active_edits:
self._active_edits.append(edittype)
self.emit("changed")
def _browse_fs_source_cb(self, src):
self._browse_file(self.widget("fs-source"), isdir=True)