uihelpers: Move a few more functions closer to their callers

This commit is contained in:
Cole Robinson
2014-01-26 17:51:15 -05:00
parent 20088ab8fb
commit 58d5e0b799
16 changed files with 258 additions and 275 deletions
+19 -2
View File
@@ -18,6 +18,7 @@
# MA 02110-1301 USA. # MA 02110-1301 USA.
# #
import os
import logging import logging
import socket import socket
@@ -28,7 +29,6 @@ from gi.repository import Gtk
# pylint: enable=E0611 # pylint: enable=E0611
from virtManager.baseclass import vmmGObjectUI from virtManager.baseclass import vmmGObjectUI
from virtManager import uihelpers
HV_XEN = 0 HV_XEN = 0
HV_QEMU = 1 HV_QEMU = 1
@@ -99,6 +99,23 @@ class vmmConnect(vmmGObjectUI):
self.reset_state() self.reset_state()
@staticmethod
def default_uri(always_system=False):
if os.path.exists('/var/lib/xen'):
if (os.path.exists('/dev/xen/evtchn') or
os.path.exists("/proc/xen")):
return 'xen:///'
if (os.path.exists("/usr/bin/qemu") or
os.path.exists("/usr/bin/qemu-kvm") or
os.path.exists("/usr/bin/kvm") or
os.path.exists("/usr/libexec/qemu-kvm")):
if always_system or os.geteuid() == 0:
return "qemu:///system"
else:
return "qemu:///session"
return None
def cancel(self, ignore1=None, ignore2=None): def cancel(self, ignore1=None, ignore2=None):
logging.debug("Cancelling open connection") logging.debug("Cancelling open connection")
self.close() self.close()
@@ -148,7 +165,7 @@ class vmmConnect(vmmGObjectUI):
return self.widget("connect-remote").get_active() return self.widget("connect-remote").get_active()
def set_default_hypervisor(self): def set_default_hypervisor(self):
default = uihelpers.default_uri(always_system=True) default = self.default_uri(always_system=True)
if not default or default.startswith("qemu"): if not default or default.startswith("qemu"):
self.widget("hypervisor").set_active(1) self.widget("hypervisor").set_active(1)
elif default.startswith("xen"): elif default.startswith("xen"):
+29
View File
@@ -129,6 +129,33 @@ class vmmConnection(vmmGObject):
self._init_virtconn() self._init_virtconn()
@staticmethod
def pretty_hv(gtype, domtype):
"""
Convert XML <domain type='foo'> and <os><type>bar</type>
into a more human relevant string.
"""
gtype = gtype.lower()
domtype = domtype.lower()
label = domtype
if domtype == "kvm":
if gtype == "xen":
label = "xenner"
elif domtype == "xen":
if gtype == "xen":
label = "xen (paravirt)"
elif gtype == "hvm":
label = "xen (fullvirt)"
elif domtype == "test":
if gtype == "xen":
label = "test (xen)"
elif gtype == "hvm":
label = "test (hvm)"
return label
################# #################
# Init routines # # Init routines #
################# #################
@@ -713,6 +740,8 @@ class vmmConnection(vmmGObject):
if p.get_name() == name: if p.get_name() == name:
return p return p
return None return None
def get_default_pool(self):
return self.get_pool_by_name("default")
def get_vol_by_path(self, path): def get_vol_by_path(self, path):
for pool in self.pools.values(): for pool in self.pools.values():
+1 -1
View File
@@ -679,7 +679,7 @@ class vmmCreate(vmmGObjectUI):
continue continue
dom = guest.domains[0] dom = guest.domains[0]
domtype = dom.hypervisor_type domtype = dom.hypervisor_type
label = uihelpers.pretty_hv(gtype, domtype) label = self.conn.pretty_hv(gtype, domtype)
# Don't add multiple rows for each arch # Don't add multiple rows for each arch
for m in model: for m in model:
+14 -2
View File
@@ -165,6 +165,18 @@ class vmmCreateInterface(vmmGObjectUI):
# Initialization routines # # Initialization routines #
########################### ###########################
@staticmethod
def iface_in_use_by(conn, name):
use_str = ""
for i in conn.list_interface_names():
iface = conn.get_interface(i)
if name in iface.get_slave_names():
if use_str:
use_str += ", "
use_str += iface.get_name()
return use_str
@staticmethod @staticmethod
def build_interface_startmode_combo(combo): def build_interface_startmode_combo(combo):
model = Gtk.ListStore(str) model = Gtk.ListStore(str)
@@ -558,8 +570,8 @@ class vmmCreateInterface(vmmGObjectUI):
for row in row_dict.values(): for row in row_dict.values():
name = row[INTERFACE_ROW_NAME] name = row[INTERFACE_ROW_NAME]
row[INTERFACE_ROW_IN_USE_BY] = uihelpers.iface_in_use_by(self.conn, row[INTERFACE_ROW_IN_USE_BY] = self.iface_in_use_by(self.conn,
name) name)
for row in row_dict.values(): for row in row_dict.values():
model.append(row) model.append(row)
+4 -4
View File
@@ -150,10 +150,10 @@ class vmmDeleteDialog(vmmGObjectUI):
title = _("Are you sure you want to delete the storage?") title = _("Are you sure you want to delete the storage?")
message = (_("The following paths will be deleted:\n\n%s") % message = (_("The following paths will be deleted:\n\n%s") %
"\n".join(devs)) "\n".join(devs))
ret = uihelpers.chkbox_helper(self, ret = self.err.chkbox_helper(
self.config.get_confirm_delstorage, self.config.get_confirm_delstorage,
self.config.set_confirm_delstorage, self.config.set_confirm_delstorage,
text1=title, text2=message) text1=title, text2=message)
if not ret: if not ret:
return return
+3 -3
View File
@@ -1100,7 +1100,7 @@ class vmmDetails(vmmGObjectUI):
if not self.widget("config-apply").get_sensitive(): if not self.widget("config-apply").get_sensitive():
return False return False
if not uihelpers.chkbox_helper(self, if not self.err.chkbox_helper(
self.config.get_confirm_unapplied, self.config.get_confirm_unapplied,
self.config.set_confirm_unapplied, self.config.set_confirm_unapplied,
text1=(_("There are unapplied changes. Would you like to apply " text1=(_("There are unapplied changes. Would you like to apply "
@@ -2243,7 +2243,7 @@ class vmmDetails(vmmGObjectUI):
def remove_device(self, dev_type, dev_id_info): def remove_device(self, dev_type, dev_id_info):
logging.debug("Removing device: %s %s", dev_type, dev_id_info) logging.debug("Removing device: %s %s", dev_type, dev_id_info)
if not uihelpers.chkbox_helper(self, self.config.get_confirm_removedev, if not self.err.chkbox_helper(self.config.get_confirm_removedev,
self.config.set_confirm_removedev, self.config.set_confirm_removedev,
text1=(_("Are you sure you want to remove this device?"))): text1=(_("Are you sure you want to remove this device?"))):
return return
@@ -2360,7 +2360,7 @@ class vmmDetails(vmmGObjectUI):
if self.is_visible(): if self.is_visible():
self.vm.refresh_xml() self.vm.refresh_xml()
except libvirt.libvirtError, e: except libvirt.libvirtError, e:
if uihelpers.exception_is_libvirt_error(e, "VIR_ERR_NO_DOMAIN"): if util.exception_is_libvirt_error(e, "VIR_ERR_NO_DOMAIN"):
self.close() self.close()
return return
raise raise
+3 -4
View File
@@ -34,7 +34,6 @@ from virtinst import Guest
from virtinst import util from virtinst import util
from virtinst import VirtualController from virtinst import VirtualController
from virtManager import uihelpers
from virtManager.libvirtobject import vmmLibvirtObject from virtManager.libvirtobject import vmmLibvirtObject
@@ -1011,7 +1010,7 @@ class vmmDomain(vmmLibvirtObject):
def get_hv_type(self): def get_hv_type(self):
return self.get_xmlobj().type return self.get_xmlobj().type
def get_pretty_hv_type(self): def get_pretty_hv_type(self):
return uihelpers.pretty_hv(self.get_abi_type(), self.get_hv_type()) return self.conn.pretty_hv(self.get_abi_type(), self.get_hv_type())
def get_arch(self): def get_arch(self):
return self.get_xmlobj().os.arch return self.get_xmlobj().os.arch
def get_init(self): def get_init(self):
@@ -1274,7 +1273,7 @@ class vmmDomain(vmmLibvirtObject):
try: try:
return self._backend.hasManagedSaveImage(0) return self._backend.hasManagedSaveImage(0)
except libvirt.libvirtError, e: except libvirt.libvirtError, e:
if not uihelpers.exception_is_libvirt_error(e, "VIR_ERR_NO_DOMAIN"): if not util.exception_is_libvirt_error(e, "VIR_ERR_NO_DOMAIN"):
raise raise
return False return False
@@ -1573,7 +1572,7 @@ class vmmDomain(vmmLibvirtObject):
info = self._backend.info() info = self._backend.info()
self._update_status(info[0]) self._update_status(info[0])
except libvirt.libvirtError, e: except libvirt.libvirtError, e:
if uihelpers.exception_is_libvirt_error(e, "VIR_ERR_NO_DOMAIN"): if util.exception_is_libvirt_error(e, "VIR_ERR_NO_DOMAIN"):
return return
raise raise
+7 -7
View File
@@ -203,7 +203,7 @@ class vmmEngine(vmmGObject):
if ret: if ret:
tryuri = "qemu:///system" tryuri = "qemu:///system"
else: else:
tryuri = uihelpers.default_uri(always_system=True) tryuri = vmmConnect.default_uri(always_system=True)
if tryuri is None: if tryuri is None:
manager.set_startup_error(msg) manager.set_startup_error(msg)
@@ -901,7 +901,7 @@ class vmmEngine(vmmGObject):
"libvirt version or hypervisor.")) "libvirt version or hypervisor."))
return return
if not uihelpers.chkbox_helper(src, self.config.get_confirm_poweroff, if not src.err.chkbox_helper(self.config.get_confirm_poweroff,
self.config.set_confirm_poweroff, self.config.set_confirm_poweroff,
text1=_("Are you sure you want to save '%s'?" % vm.get_name())): text1=_("Are you sure you want to save '%s'?" % vm.get_name())):
return return
@@ -971,7 +971,7 @@ class vmmEngine(vmmGObject):
conn = self._lookup_conn(uri) conn = self._lookup_conn(uri)
vm = conn.get_vm(uuid) vm = conn.get_vm(uuid)
if not uihelpers.chkbox_helper(src, if not src.err.chkbox_helper(
self.config.get_confirm_forcepoweroff, self.config.get_confirm_forcepoweroff,
self.config.set_confirm_forcepoweroff, self.config.set_confirm_forcepoweroff,
text1=_("Are you sure you want to force poweroff '%s'?" % text1=_("Are you sure you want to force poweroff '%s'?" %
@@ -988,7 +988,7 @@ class vmmEngine(vmmGObject):
conn = self._lookup_conn(uri) conn = self._lookup_conn(uri)
vm = conn.get_vm(uuid) vm = conn.get_vm(uuid)
if not uihelpers.chkbox_helper(src, self.config.get_confirm_pause, if not src.err.chkbox_helper(self.config.get_confirm_pause,
self.config.set_confirm_pause, self.config.set_confirm_pause,
text1=_("Are you sure you want to pause '%s'?" % text1=_("Are you sure you want to pause '%s'?" %
vm.get_name())): vm.get_name())):
@@ -1051,7 +1051,7 @@ class vmmEngine(vmmGObject):
conn = self._lookup_conn(uri) conn = self._lookup_conn(uri)
vm = conn.get_vm(uuid) vm = conn.get_vm(uuid)
if not uihelpers.chkbox_helper(src, self.config.get_confirm_poweroff, if not src.err.chkbox_helper(self.config.get_confirm_poweroff,
self.config.set_confirm_poweroff, self.config.set_confirm_poweroff,
text1=_("Are you sure you want to poweroff '%s'?" % text1=_("Are you sure you want to poweroff '%s'?" %
vm.get_name())): vm.get_name())):
@@ -1065,7 +1065,7 @@ class vmmEngine(vmmGObject):
conn = self._lookup_conn(uri) conn = self._lookup_conn(uri)
vm = conn.get_vm(uuid) vm = conn.get_vm(uuid)
if not uihelpers.chkbox_helper(src, self.config.get_confirm_poweroff, if not src.err.chkbox_helper(self.config.get_confirm_poweroff,
self.config.set_confirm_poweroff, self.config.set_confirm_poweroff,
text1=_("Are you sure you want to reboot '%s'?" % text1=_("Are you sure you want to reboot '%s'?" %
vm.get_name())): vm.get_name())):
@@ -1104,7 +1104,7 @@ class vmmEngine(vmmGObject):
conn = self._lookup_conn(uri) conn = self._lookup_conn(uri)
vm = conn.get_vm(uuid) vm = conn.get_vm(uuid)
if not uihelpers.chkbox_helper(src, if not src.err.chkbox_helper(
self.config.get_confirm_forcepoweroff, self.config.get_confirm_forcepoweroff,
self.config.set_confirm_forcepoweroff, self.config.set_confirm_forcepoweroff,
text1=_("Are you sure you want to force reset '%s'?" % text1=_("Are you sure you want to force reset '%s'?" %
+24
View File
@@ -179,6 +179,30 @@ class vmmErrorDialog(vmmGObject):
secondary_text=text2, secondary_text=text2,
chktext=chktext) chktext=chktext)
def chkbox_helper(self, getcb, setcb, text1, text2=None,
alwaysrecord=False,
default=True,
chktext=_("Don't ask me again")):
"""
Helper to prompt user about proceeding with an operation
Returns True if the 'yes' or 'ok' button was selected, False otherwise
@alwaysrecord: Don't require user to select 'yes' to record chkbox value
@default: What value to return if getcb tells us not to prompt
"""
do_prompt = getcb()
if not do_prompt:
return default
res = self.warn_chkbox(text1=text1, text2=text2,
chktext=chktext,
buttons=Gtk.ButtonsType.YES_NO)
response, skip_prompt = res
if alwaysrecord or response:
setcb(not skip_prompt)
return response
class _errorDialog (Gtk.MessageDialog): class _errorDialog (Gtk.MessageDialog):
""" """
+3 -3
View File
@@ -1003,7 +1003,7 @@ class vmmHost(vmmGObjectUI):
if interface is None: if interface is None:
return return
if not uihelpers.chkbox_helper(self, self.config.get_confirm_interface, if not self.err.chkbox_helper(self.config.get_confirm_interface,
self.config.set_confirm_interface, self.config.set_confirm_interface,
text1=_("Are you sure you want to stop the interface " text1=_("Are you sure you want to stop the interface "
"'%s'?" % interface.get_name())): "'%s'?" % interface.get_name())):
@@ -1018,7 +1018,7 @@ class vmmHost(vmmGObjectUI):
if interface is None: if interface is None:
return return
if not uihelpers.chkbox_helper(self, self.config.get_confirm_interface, if not self.err.chkbox_helper(self.config.get_confirm_interface,
self.config.set_confirm_interface, self.config.set_confirm_interface,
text1=_("Are you sure you want to start the interface " text1=_("Are you sure you want to start the interface "
"'%s'?" % interface.get_name())): "'%s'?" % interface.get_name())):
@@ -1160,7 +1160,7 @@ class vmmHost(vmmGObjectUI):
# This can fail if other interfaces are busted, so ignore errors # This can fail if other interfaces are busted, so ignore errors
used_by = None used_by = None
try: try:
used_by = uihelpers.iface_in_use_by(self.conn, name) used_by = vmmCreateInterface.iface_in_use_by(self.conn, name)
except Exception, e: except Exception, e:
logging.debug("Error looking up iface usage: %s", e) logging.debug("Error looking up iface usage: %s", e)
self.widget("interface-inuseby").set_text(used_by or "-") self.widget("interface-inuseby").set_text(used_by or "-")
+16 -2
View File
@@ -24,7 +24,6 @@ from gi.repository import GObject
import logging import logging
from virtManager import uihelpers
from virtManager.baseclass import vmmGObject from virtManager.baseclass import vmmGObject
@@ -54,6 +53,21 @@ class vmmLibvirtObject(vmmGObject):
self.connect("config-changed", self._reparse_xml) self.connect("config-changed", self._reparse_xml)
@staticmethod
def log_redefine_xml_diff(obj, origxml, newxml):
objname = "<%s name=%s>" % (obj.__class__.__name__, obj.get_name())
if origxml == newxml:
logging.debug("Redefine requested for %s, but XML didn't change!",
objname)
return
import difflib
diff = "".join(difflib.unified_diff(origxml.splitlines(1),
newxml.splitlines(1),
fromfile="Original XML",
tofile="New XML"))
logging.debug("Redefining %s with XML diff:\n%s", objname, diff)
def _cleanup(self): def _cleanup(self):
pass pass
@@ -205,7 +219,7 @@ class vmmLibvirtObject(vmmGObject):
return self._xmlobj_to_define return self._xmlobj_to_define
def _redefine_helper(self, origxml, newxml): def _redefine_helper(self, origxml, newxml):
uihelpers.log_redefine_xml_diff(self, origxml, newxml) self.log_redefine_xml_diff(self, origxml, newxml)
if origxml != newxml: if origxml != newxml:
self._define(newxml) self._define(newxml)
+1 -1
View File
@@ -790,7 +790,7 @@ class vmmManager(vmmGObjectUI):
desc = desc or "" desc = desc or ""
row[ROW_HINT] = util.xml_escape(desc) row[ROW_HINT] = util.xml_escape(desc)
except libvirt.libvirtError, e: except libvirt.libvirtError, e:
if uihelpers.exception_is_libvirt_error(e, "VIR_ERR_NO_DOMAIN"): if util.exception_is_libvirt_error(e, "VIR_ERR_NO_DOMAIN"):
return return
raise raise
+1 -1
View File
@@ -523,7 +523,7 @@ class vmmSnapshotPage(vmmGObjectUI):
xmlobj.description = desc xmlobj.description = desc
newxml = xmlobj.get_xml_config() newxml = xmlobj.get_xml_config()
uihelpers.log_redefine_xml_diff(snap, origxml, newxml) self.vm.log_redefine_xml_diff(snap, origxml, newxml)
if newxml == origxml: if newxml == origxml:
return return
self.vm.create_snapshot(newxml, redefine=True) self.vm.create_snapshot(newxml, redefine=True)
+1 -1
View File
@@ -179,7 +179,7 @@ class vmmStorageBrowser(vmmGObjectUI):
if not self._first_run: if not self._first_run:
self._first_run = True self._first_run = True
pool = uihelpers.get_default_pool(self.conn) pool = self.conn.get_default_pool()
uihelpers.set_row_selection( uihelpers.set_row_selection(
self.widget("pool-list"), pool and pool.get_uuid() or None) self.widget("pool-list"), pool and pool.get_uuid() or None)
# Manually trigger vol_selected, so buttons are in the correct state # Manually trigger vol_selected, so buttons are in the correct state
+127 -244
View File
@@ -28,8 +28,6 @@ from gi.repository import GObject
from gi.repository import Gtk from gi.repository import Gtk
# pylint: enable=E0611 # pylint: enable=E0611
import libvirt
import virtinst import virtinst
from virtManager import config from virtManager import config
@@ -63,9 +61,16 @@ def set_sparse_tooltip(widget):
widget.set_tooltip_text(sparse_str) widget.set_tooltip_text(sparse_str)
def _get_default_dir(conn):
pool = conn.get_default_pool()
if pool:
return pool.get_target_path()
return config.running_config.get_default_image_dir(conn)
def host_disk_space(conn): def host_disk_space(conn):
pool = get_default_pool(conn) pool = conn.get_default_pool()
path = get_default_dir(conn) path = _get_default_dir(conn)
avail = 0 avail = 0
if pool and pool.is_active(): if pool and pool.is_active():
@@ -98,7 +103,7 @@ def update_host_space(conn, widget):
def check_default_pool_active(err, conn): def check_default_pool_active(err, conn):
default_pool = get_default_pool(conn) default_pool = conn.get_default_pool()
if default_pool and not default_pool.is_active(): if default_pool and not default_pool.is_active():
res = err.yes_no(_("Default pool is not active."), res = err.yes_no(_("Default pool is not active."),
_("Storage pool '%s' is not active. " _("Storage pool '%s' is not active. "
@@ -118,6 +123,121 @@ def check_default_pool_active(err, conn):
return True return True
def _get_ideal_path_info(conn, name):
path = _get_default_dir(conn)
suffix = ".img"
return (path, name, suffix)
def get_ideal_path(conn, name):
target, name, suffix = _get_ideal_path_info(conn, name)
return os.path.join(target, name) + suffix
def get_default_path(conn, name, collidelist=None):
collidelist = collidelist or []
pool = conn.get_default_pool()
default_dir = _get_default_dir(conn)
def path_exists(p):
return os.path.exists(p) or p in collidelist
if not pool:
# Use old generating method
origf = os.path.join(default_dir, name + ".img")
f = origf
n = 1
while path_exists(f) and n < 100:
f = os.path.join(default_dir, name +
"-" + str(n) + ".img")
n += 1
if path_exists(f):
f = origf
path = f
else:
target, ignore, suffix = _get_ideal_path_info(conn, name)
# Sanitize collidelist to work with the collision checker
newcollidelist = []
for c in collidelist:
if c and os.path.dirname(c) == pool.get_target_path():
newcollidelist.append(os.path.basename(c))
path = virtinst.StorageVolume.find_free_name(
pool.get_backend(), name,
suffix=suffix, collidelist=newcollidelist)
path = os.path.join(target, path)
return path
def check_path_search_for_qemu(err, conn, path):
if conn.is_remote() or not conn.is_qemu_system():
return
user = config.running_config.default_qemu_user
for i in conn.caps.host.secmodels:
if i.model == "dac":
label = i.baselabels.get("kvm") or i.baselabels.get("qemu")
if not label:
continue
pwuid = pwd.getpwuid(int(label.split(":")[0].replace("+", "")))
if pwuid:
user = pwuid[0]
skip_paths = config.running_config.get_perms_fix_ignore()
broken_paths = virtinst.VirtualDisk.check_path_search_for_user(
conn.get_backend(),
path, user)
for p in broken_paths:
if p in skip_paths:
broken_paths.remove(p)
if not broken_paths:
return
logging.debug("No search access for dirs: %s", broken_paths)
resp, chkres = err.warn_chkbox(
_("The emulator may not have search permissions "
"for the path '%s'.") % path,
_("Do you want to correct this now?"),
_("Don't ask about these directories again."),
buttons=Gtk.ButtonsType.YES_NO)
if chkres:
config.running_config.add_perms_fix_ignore(broken_paths)
if not resp:
return
logging.debug("Attempting to correct permission issues.")
errors = virtinst.VirtualDisk.fix_path_search_for_user(conn.get_backend(),
path, user)
if not errors:
return
errmsg = _("Errors were encountered changing permissions for the "
"following directories:")
details = ""
for path, error in errors.items():
if path not in broken_paths:
continue
details += "%s : %s\n" % (path, error)
logging.debug("Permission errors:\n%s", details)
ignore, chkres = err.err_chkbox(errmsg, details,
_("Don't ask about these directories again."))
if chkres:
config.running_config.add_perms_fix_ignore(errors.keys())
######################################### #########################################
# VM <interface> device listing helpers # # VM <interface> device listing helpers #
######################################### #########################################
@@ -678,70 +798,6 @@ class VMActionMenu(_VMMenu):
child.get_child().set_label(text) child.get_child().set_label(text)
#####################################
# Path permissions checker for qemu #
#####################################
def check_path_search_for_qemu(err, conn, path):
if conn.is_remote() or not conn.is_qemu_system():
return
user = config.running_config.default_qemu_user
for i in conn.caps.host.secmodels:
if i.model == "dac":
label = i.baselabels.get("kvm") or i.baselabels.get("qemu")
if not label:
continue
pwuid = pwd.getpwuid(int(label.split(":")[0].replace("+", "")))
if pwuid:
user = pwuid[0]
skip_paths = config.running_config.get_perms_fix_ignore()
broken_paths = virtinst.VirtualDisk.check_path_search_for_user(
conn.get_backend(),
path, user)
for p in broken_paths:
if p in skip_paths:
broken_paths.remove(p)
if not broken_paths:
return
logging.debug("No search access for dirs: %s", broken_paths)
resp, chkres = err.warn_chkbox(
_("The emulator may not have search permissions "
"for the path '%s'.") % path,
_("Do you want to correct this now?"),
_("Don't ask about these directories again."),
buttons=Gtk.ButtonsType.YES_NO)
if chkres:
config.running_config.add_perms_fix_ignore(broken_paths)
if not resp:
return
logging.debug("Attempting to correct permission issues.")
errors = virtinst.VirtualDisk.fix_path_search_for_user(conn.get_backend(),
path, user)
if not errors:
return
errmsg = _("Errors were encountered changing permissions for the "
"following directories:")
details = ""
for path, error in errors.items():
if path not in broken_paths:
continue
details += "%s : %s\n" % (path, error)
logging.debug("Permission errors:\n%s", details)
ignore, chkres = err.err_chkbox(errmsg, details,
_("Don't ask about these directories again."))
if chkres:
config.running_config.add_perms_fix_ignore(errors.keys())
################ ################
@@ -762,83 +818,11 @@ def spin_get_helper(widget):
txt = widget.get_text() txt = widget.get_text()
try: try:
ret = int(txt) return int(txt)
except: except:
ret = adj.get_value() return adj.get_value()
return ret
def get_ideal_path_info(conn, name):
path = get_default_dir(conn)
suffix = ".img"
return (path, name, suffix)
def get_ideal_path(conn, name):
target, name, suffix = get_ideal_path_info(conn, name)
return os.path.join(target, name) + suffix
def get_default_pool(conn):
pool = None
for uuid in conn.list_pool_uuids():
p = conn.get_pool(uuid)
if p.get_name() == "default":
pool = p
return pool
def get_default_dir(conn):
pool = get_default_pool(conn)
if pool:
return pool.get_target_path()
else:
return config.running_config.get_default_image_dir(conn)
def get_default_path(conn, name, collidelist=None):
collidelist = collidelist or []
pool = get_default_pool(conn)
default_dir = get_default_dir(conn)
def path_exists(p):
return os.path.exists(p) or p in collidelist
if not pool:
# Use old generating method
origf = os.path.join(default_dir, name + ".img")
f = origf
n = 1
while path_exists(f) and n < 100:
f = os.path.join(default_dir, name +
"-" + str(n) + ".img")
n += 1
if path_exists(f):
f = origf
path = f
else:
target, ignore, suffix = get_ideal_path_info(conn, name)
# Sanitize collidelist to work with the collision checker
newcollidelist = []
for c in collidelist:
if c and os.path.dirname(c) == pool.get_target_path():
newcollidelist.append(os.path.basename(c))
path = virtinst.StorageVolume.find_free_name(
pool.get_backend(), name,
suffix=suffix, collidelist=newcollidelist)
path = os.path.join(target, path)
return path
def browse_local(parent, dialog_name, conn, start_folder=None, def browse_local(parent, dialog_name, conn, start_folder=None,
_type=None, dialog_type=None, _type=None, dialog_type=None,
@@ -926,70 +910,6 @@ def browse_local(parent, dialog_name, conn, start_folder=None,
return ret return ret
def pretty_hv(gtype, domtype):
"""
Convert XML <domain type='foo'> and <os><type>bar</type>
into a more human relevant string.
"""
gtype = gtype.lower()
domtype = domtype.lower()
label = domtype
if domtype == "kvm":
if gtype == "xen":
label = "xenner"
elif domtype == "xen":
if gtype == "xen":
label = "xen (paravirt)"
elif gtype == "hvm":
label = "xen (fullvirt)"
elif domtype == "test":
if gtype == "xen":
label = "test (xen)"
elif gtype == "hvm":
label = "test (hvm)"
return label
def iface_in_use_by(conn, name):
use_str = ""
for i in conn.list_interface_names():
iface = conn.get_interface(i)
if name in iface.get_slave_names():
if use_str:
use_str += ", "
use_str += iface.get_name()
return use_str
def chkbox_helper(src, getcb, setcb, text1, text2=None,
alwaysrecord=False,
default=True,
chktext=_("Don't ask me again")):
"""
Helper to prompt user about proceeding with an operation
Returns True if the 'yes' or 'ok' button was selected, False otherwise
@alwaysrecord: Don't require user to select 'yes' to record chkbox value
@default: What value to return if getcb tells us not to prompt
"""
do_prompt = getcb()
if not do_prompt:
return default
res = src.err.warn_chkbox(text1=text1, text2=text2,
chktext=chktext,
buttons=Gtk.ButtonsType.YES_NO)
response, skip_prompt = res
if alwaysrecord or response:
setcb(not skip_prompt)
return response
def get_list_selection(widget): def get_list_selection(widget):
selection = widget.get_selection() selection = widget.get_selection()
active = selection.get_selected() active = selection.get_selected()
@@ -1055,40 +975,3 @@ def set_grid_row_visible(child, visible):
for child in parent.get_children(): for child in parent.get_children():
if child_get_property(parent, child, "top-attach") == row: if child_get_property(parent, child, "top-attach") == row:
child.set_visible(visible) child.set_visible(visible)
def default_uri(always_system=False):
if os.path.exists('/var/lib/xen'):
if (os.path.exists('/dev/xen/evtchn') or
os.path.exists("/proc/xen")):
return 'xen:///'
if (os.path.exists("/usr/bin/qemu") or
os.path.exists("/usr/bin/qemu-kvm") or
os.path.exists("/usr/bin/kvm") or
os.path.exists("/usr/libexec/qemu-kvm")):
if always_system or os.geteuid() == 0:
return "qemu:///system"
else:
return "qemu:///session"
return None
def exception_is_libvirt_error(e, error):
return (hasattr(libvirt, error) and
e.get_error_code() == getattr(libvirt, error))
def log_redefine_xml_diff(obj, origxml, newxml):
objname = "<%s name=%s>" % (obj.__class__.__name__, obj.get_name())
if origxml == newxml:
logging.debug("Redefine requested for %s, but XML didn't change!",
objname)
return
import difflib
diff = "".join(difflib.unified_diff(origxml.splitlines(1),
newxml.splitlines(1),
fromfile="Original XML",
tofile="New XML"))
logging.debug("Redefining %s with XML diff:\n%s", objname, diff)
+5
View File
@@ -442,6 +442,11 @@ def is_error_nosupport(err):
return False return False
def exception_is_libvirt_error(e, error):
return (hasattr(libvirt, error) and
e.get_error_code() == getattr(libvirt, error))
def local_libvirt_version(): def local_libvirt_version():
""" """
Lookup the local libvirt library version, but cache the value since Lookup the local libvirt library version, but cache the value since