Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Fedora/Linux Management Tools (http://www.linux-archive.org/fedora-linux-management-tools/)
-   -   [et-mgmt-tools] [PATCH] virt-manager reorg common commands, add error reporting (http://www.linux-archive.org/fedora-linux-management-tools/2356-et-mgmt-tools-patch-virt-manager-reorg-common-commands-add-error-reporting.html)

Cole Robinson 11-21-2007 05:28 PM

[et-mgmt-tools] [PATCH] virt-manager reorg common commands, add error reporting
 
The attached patch is the result of trying to add error reporting
to some common tasks in virt-manager: pause, unpause, shutdown, and run,
as well as save and destroy.

Since the first 4 commands can be called from 3 different locations
(console, details, manager), I consolidated their code into engine.py, as
had been done in the past with save and destroy. All these commands now
show an error dialog if an exception is thrown. I also fixed an associated
issue where the pause buttons in console and details can be put out of
sync if pause/unpause failed.

I tested all these by manually throwing exceptions in the libvirt
bindings. It's kind of a lot of churn, but I think it's more maintainable
this way.

- Cole

> console.py | 71 +++++++++------------------------
> details.py | 129 +++++++++++++++++++------------------------------------------
> engine.py | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ +--
> manager.py | 32 +++++++++++----
> 4 files changed, 196 insertions(+), 150 deletions(-)

--
Cole Robinson
crobinso@redhat.com
diff -r 30260e2c3a37 src/virtManager/console.py
--- a/src/virtManager/console.py Tue Nov 20 11:12:20 2007 -0500
+++ b/src/virtManager/console.py Wed Nov 21 12:19:57 2007 -0500
@@ -48,7 +48,15 @@ class vmmConsole(gobject.GObject):
"action-show-help": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, [str]),
"action-destroy-domain": (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, (str,str))
+ gobject.TYPE_NONE, (str,str)),
+ "action-suspend-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
+ "action-resume-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
+ "action-run-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
+ "action-shutdown-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
}
def __init__(self, config, vm):
self.__gobject_init__()
@@ -512,59 +520,22 @@ class vmmConsole(gobject.GObject):
fcdialog.hide()
fcdialog.destroy()

- def control_vm_run(self, src):
- status = self.vm.status()
- if status != libvirt.VIR_DOMAIN_SHUTOFF:
- pass
- else:
- try:
- self.vm.startup()
- except:
- (type, value, stacktrace) = sys.exc_info ()
-
- # Detailed error message, in English so it can be Googled.
- details =
- "Unable to start virtual machine '%s'" %
- (str(type) + " " + str(value) + "
" +
- traceback.format_exc (stacktrace))
-
- dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
- str(value),
- details)
- dg.run()
- dg.hide()
- dg.destroy()
-
-
-
- def control_vm_shutdown(self, src):
- status = self.vm.status()
- if not(status in [ libvirt.VIR_DOMAIN_SHUTDOWN, libvirt.VIR_DOMAIN_SHUTOFF, libvirt.VIR_DOMAIN_CRASHED ]):
- self.vm.shutdown()
- else:
- logging.warning("Shutdown requested, but machine is already shutting down / shutoff")
-
def control_vm_pause(self, src):
if self.ignorePause:
return

- status = self.vm.status()
- if status in [ libvirt.VIR_DOMAIN_SHUTDOWN, libvirt.VIR_DOMAIN_SHUTOFF, libvirt.VIR_DOMAIN_CRASHED ]:
- logging.warning("Pause/resume requested, but machine is shutdown / shutoff")
- else:
- if status in [ libvirt.VIR_DOMAIN_PAUSED ]:
- if not src.get_active():
- self.vm.resume()
- else:
- logging.warning("Pause requested, but machine is already paused")
- else:
- if src.get_active():
- self.vm.suspend()
- else:
- logging.warning("Resume requested, but machine is already running")
-
- self.window.get_widget("control-pause").set_active(src.get_active())
- self.window.get_widget("menu-vm-pause").set_active(src.get_active())
+ if src.get_active():
+ self.emit("action-suspend-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())
+ else:
+ self.emit("action-resume-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())
+
+ self.update_widget_states(self.vm, self.vm.status())
+
+ def control_vm_run(self, src):
+ self.emit("action-run-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())
+
+ def control_vm_shutdown(self, src):
+ self.emit("action-shutdown-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())

def control_vm_terminal(self, src):
self.emit("action-show-terminal", self.vm.get_connection().get_uri(), self.vm.get_uuid())
diff -r 30260e2c3a37 src/virtManager/details.py
--- a/src/virtManager/details.py Tue Nov 20 11:12:20 2007 -0500
+++ b/src/virtManager/details.py Wed Nov 21 12:19:57 2007 -0500
@@ -60,6 +60,14 @@ class vmmDetails(gobject.GObject):
gobject.TYPE_NONE, (str,str)),
"action-destroy-domain": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (str,str)),
+ "action-suspend-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
+ "action-resume-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
+ "action-run-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
+ "action-shutdown-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
"action-show-help": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, [str]),
}
@@ -218,58 +226,22 @@ class vmmDetails(gobject.GObject):
selection.select_path(0)
self.window.get_widget("hw-panel").set_current_page(0)

- def control_vm_run(self, src):
- status = self.vm.status()
- if status != libvirt.VIR_DOMAIN_SHUTOFF:
- pass
- else:
- try:
- self.vm.startup()
- except:
- (type, value, stacktrace) = sys.exc_info ()
-
- # Detailed error message, in English so it can be Googled.
- details =
- "Unable to start virtual machine '%s'" %
- (str(type) + " " + str(value) + "
" +
- traceback.format_exc (stacktrace))
-
- dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
- str(value),
- details)
- dg.run()
- dg.hide()
- dg.destroy()
-
-
- def control_vm_shutdown(self, src):
- status = self.vm.status()
- if not(status in [ libvirt.VIR_DOMAIN_SHUTDOWN, libvirt.VIR_DOMAIN_SHUTOFF, libvirt.VIR_DOMAIN_CRASHED ]):
- self.vm.shutdown()
- else:
- logging.warning("Shutdown requested, but machine is already shutting down / shutoff")
-
def control_vm_pause(self, src):
if self.ignorePause:
return

- status = self.vm.status()
- if status in [ libvirt.VIR_DOMAIN_SHUTDOWN, libvirt.VIR_DOMAIN_SHUTOFF, libvirt.VIR_DOMAIN_CRASHED ]:
- logging.warning("Pause/resume requested, but machine is shutdown / shutoff")
- else:
- if status in [ libvirt.VIR_DOMAIN_PAUSED ]:
- if not src.get_active():
- self.vm.resume()
- else:
- logging.warning("Pause requested, but machine is already paused")
- else:
- if src.get_active():
- self.vm.suspend()
- else:
- logging.warning("Resume requested, but machine is already running")
-
- self.window.get_widget("control-pause").set_active(src.get_active())
- self.window.get_widget("details-menu-pause").set_active(src.get_active())
+ if src.get_active():
+ self.emit("action-suspend-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())
+ else:
+ self.emit("action-resume-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())
+
+ self.update_widget_states(self.vm, self.vm.status())
+
+ def control_vm_run(self, src):
+ self.emit("action-run-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())
+
+ def control_vm_shutdown(self, src):
+ self.emit("action-shutdown-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())

def control_vm_terminal(self, src):
self.emit("action-show-terminal", self.vm.get_connection().get_uri(), self.vm.get_uuid())
@@ -565,13 +537,8 @@ class vmmDetails(gobject.GObject):
type=diskinfo[0],
device=diskinfo[2])
except Exception, e:
- dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE,
- _("Error Removing Disk: %s" % str(e)),
- "".join(traceback.format_exc()))
- dg.run()
- dg.hide()
- dg.destroy()
+ _err_dialog(_("Error Removing Disk: %s" % str(e)),
+ "".join(traceback.format_exc()))
return

xml = vbd.get_xml_config(diskinfo[3])
@@ -594,13 +561,8 @@ class vmmDetails(gobject.GObject):
else:
vnic = virtinst.VirtualNetworkInterface(type=netinfo[0], macaddr=netinfo[3])
except ValueError, e:
- dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE,
- _("Error Removing Network: %s" % str(e)),
- "".join(traceback.format_exc()))
- dg.run()
- dg.hide()
- dg.destroy()
+ _err_dialog(_("Error Removing Network: %s" % str(e)),
+ "".join(traceback.format_exc()))
return

xml = vnic.get_xml_config()
@@ -788,30 +750,20 @@ class vmmDetails(gobject.GObject):
try:
self.vm.disconnect_cdrom_device(self.window.get_wi dget("disk-target-device").get_text())
except Exception, e:
- dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE,
- _("Error Removing CDROM: %s" % str(e)),
- "".join(traceback.format_exc()))
- dg.run()
- dg.hide()
- dg.destroy()
+ self._err_dialog(_("Error Removing CDROM: %s" % str(e)),
+ "".join(traceback.format_exc()))
return

else:
# connect a new cdrom
if self.choose_cd is None:
self.choose_cd = vmmChooseCD(self.config, self.window.get_widget("disk-target-device").get_text())
- try:
- self.choose_cd.connect("cdrom-chosen", self.connect_cdrom)
- except Exception, e:
- dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE,
- _("Error Connecting CDROM: %s" % str(e)),
- "".join(traceback.format_exc()))
- dg.run()
- dg.hide()
- dg.destroy()
- return
+ try:
+ self.choose_cd.connect("cdrom-chosen", self.connect_cdrom)
+ except Exception, e:
+ self._err_dialog(_("Error Connecting CDROM: %s" % str(e)),
+ "".join(traceback.format_exc()))
+ return
else:
self.choose_cd.set_target(self.window.get_widget(" disk-target-device").get_text())
self.choose_cd.show()
@@ -823,13 +775,14 @@ class vmmDetails(gobject.GObject):
try:
self.vm.remove_device(xml)
except Exception, e:
- dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE,
- _("Error Removing Device: %s" % str(e)),
- "".join(traceback.format_exc()))
- dg.run()
- dg.hide()
- dg.destroy()
-
+ self._err_dialog(_("Error Removing Device: %s" % str(e)),
+ "".join(traceback.format_exc()))
+
+ def _err_dialog(self, summary, details):
+ dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_CLOSE, summary, details)
+ dg.run()
+ dg.hide()
+ dg.destroy()

gobject.type_register(vmmDetails)
diff -r 30260e2c3a37 src/virtManager/engine.py
--- a/src/virtManager/engine.py Tue Nov 20 11:12:20 2007 -0500
+++ b/src/virtManager/engine.py Wed Nov 21 12:19:57 2007 -0500
@@ -37,6 +37,7 @@ from virtManager.create import vmmCreate
from virtManager.create import vmmCreate
from virtManager.serialcon import vmmSerialConsole
from virtManager.host import vmmHost
+from virtManager.error import vmmErrorDialog

class vmmEngine(gobject.GObject):
__gsignals__ = {
@@ -57,6 +58,8 @@ class vmmEngine(gobject.GObject):

self.timer = None
self.last_timeout = 0
+
+ self._save_callback_info = []

self.config = config
self.config.on_stats_update_interval_changed(self. reschedule_timer)
@@ -186,6 +189,14 @@ class vmmEngine(gobject.GObject):
self.save_domain(src, uri, uuid)
def _do_destroy_domain(self, src, uri, uuid):
self.destroy_domain(src, uri, uuid)
+ def _do_suspend_domain(self, src, uri, uuid):
+ self.suspend_domain(src, uri, uuid)
+ def _do_resume_domain(self, src, uri, uuid):
+ self.resume_domain(src, uri, uuid)
+ def _do_run_domain(self, src, uri, uuid):
+ self.run_domain(src, uri, uuid)
+ def _do_shutdown_domain(self, src, uri, uuid):
+ self.shutdown_domain(src, uri, uuid)

def show_about(self):
if self.windowAbout == None:
@@ -231,6 +242,10 @@ class vmmEngine(gobject.GObject):
console.connect("action-save-domain", self._do_save_domain)
console.connect("action-destroy-domain", self._do_destroy_domain)
console.connect("action-show-help", self._do_show_help)
+ console.connect("action-suspend-domain", self._do_suspend_domain)
+ console.connect("action-resume-domain", self._do_resume_domain)
+ console.connect("action-run-domain", self._do_run_domain)
+ console.connect("action-shutdown-domain", self._do_shutdown_domain)
self.connections[uri]["windowConsole"][uuid] = console
self.connections[uri]["windowConsole"][uuid].show()

@@ -262,6 +277,10 @@ class vmmEngine(gobject.GObject):
details.connect("action-save-domain", self._do_save_domain)
details.connect("action-destroy-domain", self._do_destroy_domain)
details.connect("action-show-help", self._do_show_help)
+ details.connect("action-suspend-domain", self._do_suspend_domain)
+ details.connect("action-resume-domain", self._do_resume_domain)
+ details.connect("action-run-domain", self._do_run_domain)
+ details.connect("action-shutdown-domain", self._do_shutdown_domain)
self.connections[uri]["windowDetails"][uuid] = details
self.connections[uri]["windowDetails"][uuid].show()
return self.connections[uri]["windowDetails"][uuid]
@@ -269,6 +288,10 @@ class vmmEngine(gobject.GObject):
def get_manager(self):
if self.windowManager == None:
self.windowManager = vmmManager(self.get_config(), self)
+ self.windowManager.connect("action-suspend-domain", self._do_suspend_domain)
+ self.windowManager.connect("action-resume-domain", self._do_resume_domain)
+ self.windowManager.connect("action-run-domain", self._do_run_domain)
+ self.windowManager.connect("action-shutdown-domain", self._do_shutdown_domain)
self.windowManager.connect("action-show-console", self._do_show_console)
self.windowManager.connect("action-show-terminal", self._do_show_terminal)
self.windowManager.connect("action-show-details", self._do_show_details)
@@ -355,11 +378,22 @@ class vmmEngine(gobject.GObject):
self.fcdialog.hide()
if(response == gtk.RESPONSE_ACCEPT):
file_to_save = self.fcdialog.get_filename()
- progWin = vmmAsyncJob(self.config, vm.save,
- [file_to_save],
+ progWin = vmmAsyncJob(self.config, self._save_callback,
+ [vm, file_to_save],
_("Saving Virtual Machine"))
progWin.run()
self.fcdialog.destroy()
+
+ if self._save_callback_info != []:
+ self._err_dialog(_("Error saving domain: %s" % self._save_callback_info[0]), self._save_callback_info[1])
+ self._save_callback_info = []
+
+ def _save_callback(self, vm, file_to_save, ignore1=None):
+ try:
+ vm.save(file_to_save)
+ except Exception, e:
+ self._save_callback_info = [str(e),
+ "".join(traceback.format_exc())]

def destroy_domain(self, src, uri, uuid):
con = self.get_connection(uri, False)
@@ -378,8 +412,78 @@ class vmmEngine(gobject.GObject):
response_id = message_box.run()
message_box.destroy()
if response_id == gtk.RESPONSE_OK:
- vm.destroy()
- else:
- return
+ try:
+ vm.destroy()
+ except Exception, e:
+ self._err_dialog(_("Error shutting down domain: %s" % str(e)), "".join(traceback.format_exc()))
+
+ def suspend_domain(self, src, uri, uuid):
+ con = self.get_connection(uri, False)
+ vm = con.get_vm(uuid)
+ status = vm.status()
+ if status in [ libvirt.VIR_DOMAIN_SHUTDOWN,
+ libvirt.VIR_DOMAIN_SHUTOFF,
+ libvirt.VIR_DOMAIN_CRASHED ]:
+ logging.warning("Pause requested, but machine is shutdown / shutoff")
+ elif status in [ libvirt.VIR_DOMAIN_PAUSED ]:
+ logging.warning("Pause requested, but machine is already paused")
+ else:
+ try:
+ vm.suspend()
+ except Exception, e:
+ self._err_dialog(_("Error pausing domain: %s" % str(e)),
+ "".join(traceback.format_exc()))
+
+ def resume_domain(self, src, uri, uuid):
+ con = self.get_connection(uri, False)
+ vm = con.get_vm(uuid)
+ status = vm.status()
+ if status in [ libvirt.VIR_DOMAIN_SHUTDOWN,
+ libvirt.VIR_DOMAIN_SHUTOFF,
+ libvirt.VIR_DOMAIN_CRASHED ]:
+ logging.warning("Resume requested, but machine is shutdown / shutoff")
+ elif status in [ libvirt.VIR_DOMAIN_PAUSED ]:
+ try:
+ vm.resume()
+ except Exception, e:
+ self._err_dialog(_("Error unpausing domain: %s" % str(e)),
+ "".join(traceback.format_exc()))
+ else:
+ logging.warning("Resume requested, but machine is already running")
+
+ def run_domain(self, src, uri, uuid):
+ con = self.get_connection(uri, False)
+ vm = con.get_vm(uuid)
+ status = vm.status()
+ if status != libvirt.VIR_DOMAIN_SHUTOFF:
+ logging.warning("Run requested, but domain isn't shutoff.")
+ else:
+ try:
+ vm.startup()
+ except Exception, e:
+ self._err_dialog(_("Error starting domain: %s" % str(e)),
+ "".join(traceback.format_exc()))
+
+ def shutdown_domain(self, src, uri, uuid):
+ con = self.get_connection(uri, False)
+ vm = con.get_vm(uuid)
+ status = vm.status()
+ if not(status in [ libvirt.VIR_DOMAIN_SHUTDOWN,
+ libvirt.VIR_DOMAIN_SHUTOFF,
+ libvirt.VIR_DOMAIN_CRASHED ]):
+ try:
+ vm.shutdown()
+ except Exception, e:
+ self._err_dialog(_("Error shutting down domain: %s" % str(e)),
+ "".join(traceback.format_exc()))
+ else:
+ logging.warning("Shutdown requested, but machine is already shutting down / shutoff")
+
+ def _err_dialog(self, summary, details):
+ dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_CLOSE, summary, details)
+ dg.run()
+ dg.hide()
+ dg.destroy()

gobject.type_register(vmmEngine)
diff -r 30260e2c3a37 src/virtManager/manager.py
--- a/src/virtManager/manager.py Tue Nov 20 11:12:20 2007 -0500
+++ b/src/virtManager/manager.py Wed Nov 21 12:19:57 2007 -0500
@@ -24,6 +24,7 @@ import threading
import threading
import logging
import sys
+import traceback

import sparkline
import libvirt
@@ -81,6 +82,14 @@ class vmmManager(gobject.GObject):
gobject.TYPE_NONE, []),
"action-show-create": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, [str]),
+ "action-suspend-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
+ "action-resume-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
+ "action-run-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
+ "action-shutdown-domain": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (str, str)),
"action-connect": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, [str]),
"action-show-help": (gobject.SIGNAL_RUN_FIRST,
@@ -229,7 +238,7 @@ class vmmManager(gobject.GObject):
# store any error message from the restore-domain callback
self.domain_restore_error = ""

- self.window.get_widget("menu_file_restore_saved"). set_sensitive(False)
+ #self.window.get_widget("menu_file_restore_saved") .set_sensitive(False)

self.engine.connect("connection-added", self._add_connection)
self.engine.connect("connection-removed", self._remove_connection)
@@ -712,9 +721,12 @@ class vmmManager(gobject.GObject):
if result == gtk.RESPONSE_NO:
return
conn = vm.get_connection()
- vm.delete()
+ try:
+ vm.delete()
+ except Exception, e:
+ self._err_dialog(_("Error deleting domain: %s" % str(e)),
+ "".join(traceback.format_exc()))
conn.tick(noStatsUpdate=True)
-

def show_about(self, src):
self.emit("action-show-about")
@@ -929,22 +941,22 @@ class vmmManager(gobject.GObject):
def start_vm(self, ignore):
vm = self.current_vm()
if vm is not None:
- vm.startup()
+ self.emit("action-run-domain", vm.get_connection().get_uri(), vm.get_uuid())

def stop_vm(self, ignore):
vm = self.current_vm()
if vm is not None:
- vm.shutdown()
+ self.emit("action-shutdown-domain", vm.get_connection().get_uri(), vm.get_uuid())

def pause_vm(self, ignore):
vm = self.current_vm()
if vm is not None:
- vm.suspend()
+ self.emit("action-suspend-domain", vm.get_connection().get_uri(), vm.get_uuid())

def resume_vm(self, ignore):
vm = self.current_vm()
if vm is not None:
- vm.resume()
+ self.emit("action-resume-domain", vm.get_connection().get_uri(), vm.get_uuid())

def _add_connection(self, engine, conn):
conn.connect("vm-added", self.vm_added)
@@ -1001,5 +1013,11 @@ class vmmManager(gobject.GObject):
dg.hide()
dg.destroy()

+ def _err_dialog(self, summary, details):
+ dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_CLOSE, summary, details)
+ dg.run()
+ dg.hide()
+ dg.destroy()

gobject.type_register(vmmManager)
_______________________________________________
et-mgmt-tools mailing list
et-mgmt-tools@redhat.com
https://www.redhat.com/mailman/listinfo/et-mgmt-tools


All times are GMT. The time now is 03:58 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.