Rework shutdown, pause, unpause, and run commands to call central routine. Add error catching and reporting for these, as well as save and destory.

This commit is contained in:
Cole Robinson
2007-11-27 11:31:30 -05:00
parent 847084ab23
commit a88aebea6f
4 changed files with 192 additions and 146 deletions

View File

@@ -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) + "\n" + \
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")
if src.get_active():
self.emit("action-suspend-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())
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.emit("action-resume-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())
self.window.get_widget("control-pause").set_active(src.get_active())
self.window.get_widget("menu-vm-pause").set_active(src.get_active())
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())

View File

@@ -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) + "\n" + \
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")
if src.get_active():
self.emit("action-suspend-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())
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.emit("action-resume-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid())
self.window.get_widget("control-pause").set_active(src.get_active())
self.window.get_widget("details-menu-pause").set_active(src.get_active())
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_widget("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)

View File

@@ -37,6 +37,7 @@ from virtManager.asyncjob import vmmAsyncJob
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__ = {
@@ -58,6 +59,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,12 +378,23 @@ 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)
vm = con.get_vm(uuid)
@@ -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)

View File

@@ -24,6 +24,7 @@ import gtk.glade
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,10 +721,13 @@ 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)