virt-manager: Properly handle errors when --show-* options are used.

crobinso: Fix some pylint
This commit is contained in:
Leonardo Garcia 2013-07-12 23:10:16 -03:00 committed by Cole Robinson
parent e1be39d986
commit 40cff67836
4 changed files with 99 additions and 78 deletions

View File

@ -277,7 +277,9 @@ def main():
if options.show:
def cb(conn):
launch_specific_window(engine, options.show, options.uri, options.uuid)
ignore = conn
launch_specific_window(engine,
options.show, options.uri, options.uuid)
return True
engine.uri_cb = cb
engine.show_manager_window = False

View File

@ -141,13 +141,13 @@ class vmmGObject(GObject.GObject):
self.idle_add(emitwrap, signal, *args)
def idle_add(self, func, *args):
def idle_add(self, func, *args, **kwargs):
"""
Make sure idle functions are run thread safe
"""
def cb():
try:
return func(*args)
return func(*args, **kwargs)
except:
print traceback.format_exc()
return False

View File

@ -25,6 +25,7 @@ from gi.repository import Gtk
# pylint: enable=E0611
import logging
import re
import Queue
import threading
@ -333,14 +334,17 @@ class vmmEngine(vmmGObject):
self.windows -= 1
logging.debug("window counter decremented to %s", self.windows)
# Don't exit if system tray is enabled
if (self.windows <= 0 and
self.systray and
not self.systray.is_visible()):
if self._can_exit():
# Defer this to an idle callback, since we can race with
# a vmmDetails window being deleted.
self.idle_add(self.exit_app, src)
def _can_exit(self):
# Don't exit if system tray is enabled
return (self.windows <= 0 and
self.systray and
not self.systray.is_visible())
def _cleanup(self):
self.err = None
@ -451,6 +455,7 @@ class vmmEngine(vmmGObject):
conn.connect("vm-removed", self._do_vm_removed)
conn.connect("state-changed", self._do_conn_changed)
conn.connect("connect-error", self._connect_error)
conn.connect("priority-tick", self._schedule_priority_tick)
self.emit("conn-added", conn)
@ -521,6 +526,73 @@ class vmmEngine(vmmGObject):
raise RuntimeError(_("Unknown connection URI %s") % uri)
return conn
def _connect_error(self, conn, errmsg, tb, warnconsole):
errmsg = errmsg.strip(" \n")
tb = tb.strip(" \n")
hint = ""
show_errmsg = True
if conn.is_remote():
logging.debug(conn.get_transport())
if re.search(r"nc: .* -- 'U'", tb):
hint += _("The remote host requires a version of netcat/nc\n"
"which supports the -U option.")
show_errmsg = False
elif (conn.get_transport()[0] == "ssh" and
re.search(r"ssh-askpass", tb)):
if self.config.askpass_package:
ret = packageutils.check_packagekit(
self.err,
self.config.askpass_package,
False)
if ret:
conn.open()
return
hint += _("You need to install openssh-askpass or "
"similar\nto connect to this host.")
show_errmsg = False
else:
hint += _("Verify that the 'libvirtd' daemon is running\n"
"on the remote host.")
elif conn.is_xen():
hint += _("Verify that:\n"
" - A Xen host kernel was booted\n"
" - The Xen service has been started")
else:
if warnconsole:
hint += _("Could not detect a local session: if you are \n"
"running virt-manager over ssh -X or VNC, you \n"
"may not be able to connect to libvirt as a \n"
"regular user. Try running as root.")
show_errmsg = False
elif re.search(r"libvirt-sock", tb):
hint += _("Verify that the 'libvirtd' daemon is running.")
show_errmsg = False
msg = _("Unable to connect to libvirt.")
if show_errmsg:
msg += "\n\n%s" % errmsg
if hint:
msg += "\n\n%s" % hint
msg = msg.strip("\n")
details = msg
details += "\n\n"
details += "Libvirt URI is: %s\n\n" % conn.get_uri()
details += tb
title = _("Virtual Machine Manager Connection Failure")
if self._can_exit():
self.err.show_err(msg, details, title, async=False)
self.idle_add(self.exit_app, conn)
else:
self.err.show_err(msg, details, title)
####################
# Dialog launchers #
####################
@ -623,6 +695,15 @@ class vmmEngine(vmmGObject):
def _show_vm_helper(self, src, uri, uuid, page=None, forcepage=False):
try:
if uuid not in self.conns[uri]["conn"].vms:
# This will only happen if --show-* option was used during
# virt-manager launch and an invalid UUID is passed.
# The error message must be sync otherwise the user will not
# know why the application ended.
self.err.show_err("%s does not have VM with UUID %s" %
(uri, uuid), async=False)
return
details = self._get_details_dialog(uri, uuid)
if forcepage or not details.is_visible():
@ -636,9 +717,11 @@ class vmmEngine(vmmGObject):
details.activate_default_page()
details.show()
return details
except Exception, e:
src.err.show_err(_("Error launching details: %s") % str(e))
finally:
if self._can_exit():
self.idle_add(self.exit_app, src)
def _do_show_vm(self, src, uri, uuid):
self._show_vm_helper(src, uri, uuid)
@ -751,16 +834,16 @@ class vmmEngine(vmmGObject):
self._do_show_create(self.get_manager(), uri)
def show_domain_console(self, uri, uuid):
self._show_vm_helper(self.get_manager(), uri, uuid,
page=DETAILS_CONSOLE, forcepage=True)
self.idle_add(self._show_vm_helper, self.get_manager(), uri, uuid,
page=DETAILS_CONSOLE, forcepage=True)
def show_domain_editor(self, uri, uuid):
self._show_vm_helper(self.get_manager(), uri, uuid,
page=DETAILS_CONFIG, forcepage=True)
self.idle_add(self._show_vm_helper, self.get_manager(), uri, uuid,
page=DETAILS_CONFIG, forcepage=True)
def show_domain_performance(self, uri, uuid):
self._show_vm_helper(self.get_manager(), uri, uuid,
page=DETAILS_PERF, forcepage=True)
self.idle_add(self._show_vm_helper, self.get_manager(), uri, uuid,
page=DETAILS_PERF, forcepage=True)
#######################################

View File

@ -19,7 +19,6 @@
#
import logging
import re
# pylint: disable=E0611
from gi.repository import GObject
@ -28,7 +27,6 @@ from gi.repository import Gdk
from gi.repository import GdkPixbuf
# pylint: enable=E0611
from virtManager import packageutils
from virtManager import uihelpers
from virtManager.connection import vmmConnection
from virtManager.baseclass import vmmGObjectUI
@ -682,67 +680,6 @@ class vmmManager(vmmGObjectUI):
conn.open()
return True
def _connect_error(self, conn, errmsg, tb, warnconsole):
errmsg = errmsg.strip(" \n")
tb = tb.strip(" \n")
hint = ""
show_errmsg = True
if conn.is_remote():
logging.debug(conn.get_transport())
if re.search(r"nc: .* -- 'U'", tb):
hint += _("The remote host requires a version of netcat/nc\n"
"which supports the -U option.")
show_errmsg = False
elif (conn.get_transport()[0] == "ssh" and
re.search(r"ssh-askpass", tb)):
if self.config.askpass_package:
ret = packageutils.check_packagekit(
self.err,
self.config.askpass_package,
False)
if ret:
conn.open()
return
hint += _("You need to install openssh-askpass or "
"similar\nto connect to this host.")
show_errmsg = False
else:
hint += _("Verify that the 'libvirtd' daemon is running\n"
"on the remote host.")
elif conn.is_xen():
hint += _("Verify that:\n"
" - A Xen host kernel was booted\n"
" - The Xen service has been started")
else:
if warnconsole:
hint += _("Could not detect a local session: if you are \n"
"running virt-manager over ssh -X or VNC, you \n"
"may not be able to connect to libvirt as a \n"
"regular user. Try running as root.")
show_errmsg = False
elif re.search(r"libvirt-sock", tb):
hint += _("Verify that the 'libvirtd' daemon is running.")
show_errmsg = False
msg = _("Unable to connect to libvirt.")
if show_errmsg:
msg += "\n\n%s" % errmsg
if hint:
msg += "\n\n%s" % hint
msg = msg.strip("\n")
details = msg
details += "\n\n"
details += "Libvirt URI is: %s\n\n" % conn.get_uri()
details += tb
self.err.show_err(msg, details, title=_("Virtual Machine Manager Connection Failure"))
####################################
# VM add/remove management methods #
@ -880,7 +817,6 @@ class vmmManager(vmmGObjectUI):
conn.connect("vm-removed", self.vm_removed)
conn.connect("resources-sampled", self.conn_resources_sampled)
conn.connect("state-changed", self.conn_state_changed)
conn.connect("connect-error", self._connect_error)
# add the connection to the treeModel
vmlist = self.widget("vm-list")