engine: Move VM action callbacks to vmmenu.py

Call the callbacks directly rather than using signals. engine.py
has become a bit of a catchall for shared functionality and this
is a step towards disentangling it
This commit is contained in:
Cole Robinson
2018-03-08 13:42:45 -05:00
parent 42e4cc33bf
commit 717ff72684
5 changed files with 216 additions and 320 deletions

View File

@ -339,14 +339,6 @@ def _label_for_os_type(os_type):
class vmmDetails(vmmGObjectUI):
__gsignals__ = {
"action-save-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-destroy-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-suspend-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-resume-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-run-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-shutdown-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-reset-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-reboot-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-exit-app": (GObject.SignalFlags.RUN_FIRST, None, []),
"action-view-manager": (GObject.SignalFlags.RUN_FIRST, None, []),
"action-migrate-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
@ -470,16 +462,6 @@ class vmmDetails(vmmGObjectUI):
"on_details_cancel_customize_clicked": self._customize_cancel_clicked,
"on_details_menu_virtual_manager_activate": self.control_vm_menu,
"on_details_menu_run_activate": self.control_vm_run,
"on_details_menu_poweroff_activate": self.control_vm_shutdown,
"on_details_menu_reboot_activate": self.control_vm_reboot,
"on_details_menu_save_activate": self.control_vm_save,
"on_details_menu_reset_activate": self.control_vm_reset,
"on_details_menu_destroy_activate": self.control_vm_destroy,
"on_details_menu_pause_activate": self.control_vm_pause,
"on_details_menu_clone_activate": self.control_vm_clone,
"on_details_menu_migrate_activate": self.control_vm_migrate,
"on_details_menu_delete_activate": self.control_vm_delete,
"on_details_menu_screenshot_activate": self.control_vm_screenshot,
"on_details_menu_usb_redirection": self.control_vm_usb_redirection,
"on_details_menu_view_toolbar_activate": self.toggle_toolbar,
@ -1433,13 +1415,9 @@ class vmmDetails(vmmGObjectUI):
self.set_pause_state(not do_pause)
if do_pause:
self.emit("action-suspend-domain",
self.vm.conn.get_uri(),
self.vm.get_connkey())
vmmenu.VMActionUI.suspend(self, self.vm)
else:
self.emit("action-resume-domain",
self.vm.conn.get_uri(),
self.vm.get_connkey())
vmmenu.VMActionUI.resume(self, self.vm)
def control_vm_menu(self, src_ignore):
can_usb = bool(self.console.details_viewer_has_usb_redirection() and
@ -1449,40 +1427,10 @@ class vmmDetails(vmmGObjectUI):
def control_vm_run(self, src_ignore):
if self.has_unapplied_changes(self.get_hw_row()):
return
self.emit("action-run-domain",
self.vm.conn.get_uri(), self.vm.get_connkey())
vmmenu.VMActionUI.run(self, self.vm)
def control_vm_shutdown(self, src_ignore):
self.emit("action-shutdown-domain",
self.vm.conn.get_uri(), self.vm.get_connkey())
def control_vm_reboot(self, src_ignore):
self.emit("action-reboot-domain",
self.vm.conn.get_uri(), self.vm.get_connkey())
def control_vm_save(self, src_ignore):
self.emit("action-save-domain",
self.vm.conn.get_uri(), self.vm.get_connkey())
def control_vm_reset(self, src_ignore):
self.emit("action-reset-domain",
self.vm.conn.get_uri(), self.vm.get_connkey())
def control_vm_destroy(self, src_ignore):
self.emit("action-destroy-domain",
self.vm.conn.get_uri(), self.vm.get_connkey())
def control_vm_clone(self, src_ignore):
self.emit("action-clone-domain",
self.vm.conn.get_uri(), self.vm.get_connkey())
def control_vm_migrate(self, src_ignore):
self.emit("action-migrate-domain",
self.vm.conn.get_uri(), self.vm.get_connkey())
def control_vm_delete(self, src_ignore):
self.emit("action-delete-domain",
self.vm.conn.get_uri(), self.vm.get_connkey())
vmmenu.VMActionUI.shutdown(self, self.vm)
def control_vm_screenshot(self, src):
ignore = src

View File

@ -39,7 +39,6 @@ from .preferences import vmmPreferences
from .manager import vmmManager
from .migrate import vmmMigrateDialog
from .details import vmmDetails
from .asyncjob import vmmAsyncJob
from .create import vmmCreate
from .host import vmmHost
from .error import vmmErrorDialog
@ -176,14 +175,6 @@ class vmmEngine(vmmGObject):
def _init_systray(self):
self._systray = vmmSystray()
self._systray.connect("action-toggle-manager", self._do_toggle_manager)
self._systray.connect("action-suspend-domain", self._do_suspend_domain)
self._systray.connect("action-resume-domain", self._do_resume_domain)
self._systray.connect("action-run-domain", self._do_run_domain)
self._systray.connect("action-shutdown-domain", self._do_shutdown_domain)
self._systray.connect("action-reboot-domain", self._do_reboot_domain)
self._systray.connect("action-destroy-domain", self._do_destroy_domain)
self._systray.connect("action-reset-domain", self._do_reset_domain)
self._systray.connect("action-save-domain", self._do_save_domain)
self._systray.connect("action-show-domain", self._do_show_vm)
self._systray.connect("action-migrate-domain", self._do_show_migrate)
self._systray.connect("action-delete-domain", self._do_delete_domain)
@ -781,14 +772,6 @@ class vmmEngine(vmmGObject):
conn = self._lookup_conn(uri)
obj = vmmDetails(conn.get_vm(connkey))
obj.connect("action-save-domain", self._do_save_domain)
obj.connect("action-destroy-domain", self._do_destroy_domain)
obj.connect("action-reset-domain", self._do_reset_domain)
obj.connect("action-suspend-domain", self._do_suspend_domain)
obj.connect("action-resume-domain", self._do_resume_domain)
obj.connect("action-run-domain", self._do_run_domain)
obj.connect("action-shutdown-domain", self._do_shutdown_domain)
obj.connect("action-reboot-domain", self._do_reboot_domain)
obj.connect("action-exit-app", self.exit_app)
obj.connect("action-view-manager", self._do_show_manager)
obj.connect("action-migrate-domain", self._do_show_migrate)
@ -829,14 +812,6 @@ class vmmEngine(vmmGObject):
return self.windowManager
obj = vmmManager()
obj.connect("action-suspend-domain", self._do_suspend_domain)
obj.connect("action-resume-domain", self._do_resume_domain)
obj.connect("action-run-domain", self._do_run_domain)
obj.connect("action-shutdown-domain", self._do_shutdown_domain)
obj.connect("action-reboot-domain", self._do_reboot_domain)
obj.connect("action-destroy-domain", self._do_destroy_domain)
obj.connect("action-reset-domain", self._do_reset_domain)
obj.connect("action-save-domain", self._do_save_domain)
obj.connect("action-migrate-domain", self._do_show_migrate)
obj.connect("action-delete-domain", self._do_delete_domain)
obj.connect("action-clone-domain", self._do_show_clone)
@ -1059,178 +1034,6 @@ class vmmEngine(vmmGObject):
logging.debug("Error handling cli command", exc_info=True)
self._exit_app_if_no_windows()
#######################################
# Domain actions run/destroy/save ... #
#######################################
def _do_save_domain(self, src, uri, connkey):
conn = self._lookup_conn(uri)
vm = conn.get_vm(connkey)
if not src.err.chkbox_helper(self.config.get_confirm_poweroff,
self.config.set_confirm_poweroff,
text1=_("Are you sure you want to save '%s'?") % vm.get_name()):
return
_cancel_cb = None
if vm.getjobinfo_supported:
_cancel_cb = (self._save_cancel, vm)
def cb(asyncjob):
vm.save(meter=asyncjob.get_meter())
def finish_cb(error, details):
if error is not None:
error = _("Error saving domain: %s") % error
src.err.show_err(error, details=details)
progWin = vmmAsyncJob(cb, [],
finish_cb, [],
_("Saving Virtual Machine"),
_("Saving virtual machine memory to disk "),
src.topwin, cancel_cb=_cancel_cb)
progWin.run()
def _save_cancel(self, asyncjob, vm):
logging.debug("Cancelling save job")
if not vm:
return
try:
vm.abort_job()
except Exception as e:
logging.exception("Error cancelling save job")
asyncjob.show_warning(_("Error cancelling save job: %s") % str(e))
return
asyncjob.job_canceled = True
return
def _do_destroy_domain(self, src, uri, connkey):
conn = self._lookup_conn(uri)
vm = conn.get_vm(connkey)
if not src.err.chkbox_helper(
self.config.get_confirm_forcepoweroff,
self.config.set_confirm_forcepoweroff,
text1=_("Are you sure you want to force poweroff '%s'?" %
vm.get_name()),
text2=_("This will immediately poweroff the VM without "
"shutting down the OS and may cause data loss.")):
return
logging.debug("Destroying vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.destroy, [], src,
_("Error shutting down domain"))
def _do_suspend_domain(self, src, uri, connkey):
conn = self._lookup_conn(uri)
vm = conn.get_vm(connkey)
if not src.err.chkbox_helper(self.config.get_confirm_pause,
self.config.set_confirm_pause,
text1=_("Are you sure you want to pause '%s'?" %
vm.get_name())):
return
logging.debug("Pausing vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.suspend, [], src,
_("Error pausing domain"))
def _do_resume_domain(self, src, uri, connkey):
conn = self._lookup_conn(uri)
vm = conn.get_vm(connkey)
logging.debug("Unpausing vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.resume, [], src,
_("Error unpausing domain"))
def _do_run_domain(self, src, uri, connkey):
conn = self._lookup_conn(uri)
vm = conn.get_vm(connkey)
logging.debug("Starting vm '%s'", vm.get_name())
if vm.has_managed_save():
def errorcb(error, details):
# This is run from the main thread
res = src.err.show_err(
_("Error restoring domain") + ": " + error,
details=details,
text2=_(
"The domain could not be restored. Would you like\n"
"to remove the saved state and perform a regular\n"
"start up?"),
dialog_type=Gtk.MessageType.WARNING,
buttons=Gtk.ButtonsType.YES_NO,
modal=True)
if not res:
return
try:
vm.remove_saved_image()
self._do_run_domain(src, uri, connkey)
except Exception as e:
src.err.show_err(_("Error removing domain state: %s")
% str(e))
# VM will be restored, which can take some time, so show progress
title = _("Restoring Virtual Machine")
text = _("Restoring virtual machine memory from disk")
vmmAsyncJob.simple_async(vm.startup, [], src,
title, text, "", errorcb=errorcb)
else:
# Regular startup
errorintro = _("Error starting domain")
vmmAsyncJob.simple_async_noshow(vm.startup, [], src, errorintro)
def _do_shutdown_domain(self, src, uri, connkey):
conn = self._lookup_conn(uri)
vm = conn.get_vm(connkey)
if not src.err.chkbox_helper(self.config.get_confirm_poweroff,
self.config.set_confirm_poweroff,
text1=_("Are you sure you want to poweroff '%s'?" %
vm.get_name())):
return
logging.debug("Shutting down vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.shutdown, [], src,
_("Error shutting down domain"))
def _do_reboot_domain(self, src, uri, connkey):
conn = self._lookup_conn(uri)
vm = conn.get_vm(connkey)
if not src.err.chkbox_helper(self.config.get_confirm_poweroff,
self.config.set_confirm_poweroff,
text1=_("Are you sure you want to reboot '%s'?" %
vm.get_name())):
return
logging.debug("Rebooting vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.reboot, [], src,
_("Error rebooting domain"))
def _do_reset_domain(self, src, uri, connkey):
conn = self._lookup_conn(uri)
vm = conn.get_vm(connkey)
if not src.err.chkbox_helper(
self.config.get_confirm_forcepoweroff,
self.config.set_confirm_forcepoweroff,
text1=_("Are you sure you want to force reset '%s'?" %
vm.get_name()),
text2=_("This will immediately reset the VM without "
"shutting down the OS and may cause data loss.")):
return
logging.debug("Resetting vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.reset, [], src,
_("Error resetting domain"))
def _do_delete_domain(self, src, uri, connkey):
conn = self._lookup_conn(uri)
vm = conn.get_vm(connkey)

View File

@ -96,14 +96,6 @@ class vmmManager(vmmGObjectUI):
"action-show-host": (GObject.SignalFlags.RUN_FIRST, None, [str]),
"action-show-preferences": (GObject.SignalFlags.RUN_FIRST, None, []),
"action-show-create": (GObject.SignalFlags.RUN_FIRST, None, [str]),
"action-suspend-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-resume-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-run-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-shutdown-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-reset-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-reboot-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-destroy-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-save-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-migrate-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-delete-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-clone-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
@ -534,34 +526,14 @@ class vmmManager(vmmGObjectUI):
self.set_pause_state(not do_pause)
if do_pause:
self.pause_vm(None)
vmmenu.VMActionUI.suspend(self, self.current_vm())
else:
self.resume_vm(None)
vmmenu.VMActionUI.resume(self, self.current_vm())
def start_vm(self, ignore):
vm = self.current_vm()
if vm is None:
return
self.emit("action-run-domain", vm.conn.get_uri(), vm.get_connkey())
def poweroff_vm(self, ignore):
vm = self.current_vm()
if vm is None:
return
self.emit("action-shutdown-domain",
vm.conn.get_uri(), vm.get_connkey())
def pause_vm(self, ignore):
vm = self.current_vm()
if vm is None:
return
self.emit("action-suspend-domain", vm.conn.get_uri(), vm.get_connkey())
def resume_vm(self, ignore):
vm = self.current_vm()
if vm is None:
return
self.emit("action-resume-domain", vm.conn.get_uri(), vm.get_connkey())
vmmenu.VMActionUI.run(self, self.current_vm())
def poweroff_vm(self, _src):
vmmenu.VMActionUI.shutdown(self, self.current_vm())
def close_conn(self, ignore):
conn = self.current_conn()

View File

@ -32,14 +32,6 @@ class vmmSystray(vmmGObject):
__gsignals__ = {
"action-toggle-manager": (GObject.SignalFlags.RUN_FIRST, None, []),
"action-view-manager": (GObject.SignalFlags.RUN_FIRST, None, []),
"action-suspend-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-resume-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-run-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-shutdown-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-reset-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-reboot-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-destroy-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-save-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-migrate-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-delete-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),
"action-clone-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]),

View File

@ -18,8 +18,12 @@
# MA 02110-1301 USA.
#
import logging
from gi.repository import Gtk
from .asyncjob import vmmAsyncJob
####################################################################
# Build toolbar shutdown button menu (manager and details toolbar) #
@ -34,8 +38,8 @@ class _VMMenu(Gtk.Menu):
self._init_state()
def _add_action(self, label, signal,
iconname="system-shutdown", addcb=True):
def _add_action(self, label, widgetname, cb,
iconname="system-shutdown"):
if label.startswith("gtk-"):
item = Gtk.ImageMenuItem.new_from_stock(label, None)
else:
@ -49,19 +53,17 @@ class _VMMenu(Gtk.Menu):
Gtk.IconSize.MENU)
item.set_image(icon)
item.vmm_widget_name = signal
if addcb:
item.connect("activate", self._action_cb)
item.vmm_widget_name = widgetname
if cb:
def _cb(_menuitem):
_vm = self._current_vm_cb()
if _vm:
return cb(self._parent, _vm)
item.connect("activate", _cb)
self.add(item)
return item
def _action_cb(self, src):
vm = self._current_vm_cb()
if not vm:
return
self._parent.emit("action-%s-domain" % src.vmm_widget_name,
vm.conn.get_uri(), vm.get_connkey())
def _init_state(self):
raise NotImplementedError()
def update_widget_states(self, vm):
@ -69,13 +71,17 @@ class _VMMenu(Gtk.Menu):
class VMShutdownMenu(_VMMenu):
"""
Shutdown submenu for reboot, forceoff, reset, etc.
"""
def _init_state(self):
self._add_action(_("_Reboot"), "reboot")
self._add_action(_("_Shut Down"), "shutdown")
self._add_action(_("F_orce Reset"), "reset")
self._add_action(_("_Force Off"), "destroy")
self._add_action(_("_Reboot"), "reboot", VMActionUI.reboot)
self._add_action(_("_Shut Down"), "shutdown", VMActionUI.shutdown)
self._add_action(_("F_orce Reset"), "reset", VMActionUI.reset)
self._add_action(_("_Force Off"), "destroy", VMActionUI.destroy)
self.add(Gtk.SeparatorMenuItem())
self._add_action(_("Sa_ve"), "save", iconname=Gtk.STOCK_SAVE)
self._add_action(_("Sa_ve"), "save", VMActionUI.save,
iconname=Gtk.STOCK_SAVE)
self.show_all()
@ -84,8 +90,8 @@ class VMShutdownMenu(_VMMenu):
"reboot": bool(vm and vm.is_stoppable()),
"shutdown": bool(vm and vm.is_stoppable()),
"reset": bool(vm and vm.is_stoppable()),
"save": bool(vm and vm.is_destroyable()),
"destroy": bool(vm and vm.is_destroyable()),
"save": bool(vm and vm.is_destroyable()),
}
for child in self.get_children():
@ -103,21 +109,37 @@ class VMShutdownMenu(_VMMenu):
class VMActionMenu(_VMMenu):
"""
VM submenu for run, pause, shutdown, clone, etc
"""
def _init_state(self):
self._add_action(_("_Run"), "run", Gtk.STOCK_MEDIA_PLAY)
self._add_action(_("_Pause"), "suspend", Gtk.STOCK_MEDIA_PAUSE)
self._add_action(_("R_esume"), "resume", Gtk.STOCK_MEDIA_PAUSE)
s = self._add_action(_("_Shut Down"), "shutdown", addcb=False)
self._add_action(_("_Run"), "run", VMActionUI.run,
iconname=Gtk.STOCK_MEDIA_PLAY)
self._add_action(_("_Pause"), "suspend", VMActionUI.suspend,
Gtk.STOCK_MEDIA_PAUSE)
self._add_action(_("R_esume"), "resume", VMActionUI.resume,
Gtk.STOCK_MEDIA_PAUSE)
s = self._add_action(_("_Shut Down"), "shutdown", None)
s.set_submenu(VMShutdownMenu(self._parent, self._current_vm_cb))
def _make_emit_cb(_name):
def _emit_cb(_src, _vm):
return _src.emit(_name, _vm.conn.get_uri(), _vm.get_name())
return _emit_cb
self.add(Gtk.SeparatorMenuItem())
self._add_action(_("Clone..."), "clone", None)
self._add_action(_("Migrate..."), "migrate", None)
self._add_action(_("_Delete"), "delete", Gtk.STOCK_DELETE)
self._add_action(_("Clone..."), "clone",
_make_emit_cb("action-clone-domain"), iconname=None)
self._add_action(_("Migrate..."), "migrate",
_make_emit_cb("action-migrate-domain"), iconname=None)
self._add_action(_("_Delete"), "delete",
_make_emit_cb("action-delete-domain"),
iconname=Gtk.STOCK_DELETE)
if self._show_open:
self.add(Gtk.SeparatorMenuItem())
self._add_action(Gtk.STOCK_OPEN, "show", None)
self._add_action(Gtk.STOCK_OPEN, "show",
_make_emit_cb("action-show-domain"), iconname=None)
self.show_all()
@ -148,3 +170,162 @@ class VMActionMenu(_VMMenu):
for child in self.get_children():
if getattr(child, "vmm_widget_name", None) == "run":
child.get_child().set_label(text)
class VMActionUI(object):
"""
Singleton object for handling VM actions, asking for confirmation,
showing errors/progress dialogs, etc.
"""
@staticmethod
def save_cancel(asyncjob, vm):
logging.debug("Cancelling save job")
if not vm:
return
try:
vm.abort_job()
except Exception as e:
logging.exception("Error cancelling save job")
asyncjob.show_warning(_("Error cancelling save job: %s") % str(e))
return
asyncjob.job_canceled = True
return
@staticmethod
def save(src, vm):
if not src.err.chkbox_helper(src.config.get_confirm_poweroff,
src.config.set_confirm_poweroff,
text1=_("Are you sure you want to save '%s'?") % vm.get_name()):
return
_cancel_cb = None
if vm.getjobinfo_supported:
_cancel_cb = (VMActionUI.save_cancel, vm)
def cb(asyncjob):
vm.save(meter=asyncjob.get_meter())
def finish_cb(error, details):
if error is not None:
error = _("Error saving domain: %s") % error
src.err.show_err(error, details=details)
progWin = vmmAsyncJob(cb, [],
finish_cb, [],
_("Saving Virtual Machine"),
_("Saving virtual machine memory to disk "),
src.topwin, cancel_cb=_cancel_cb)
progWin.run()
@staticmethod
def destroy(src, vm):
if not src.err.chkbox_helper(
src.config.get_confirm_forcepoweroff,
src.config.set_confirm_forcepoweroff,
text1=_("Are you sure you want to force poweroff '%s'?" %
vm.get_name()),
text2=_("This will immediately poweroff the VM without "
"shutting down the OS and may cause data loss.")):
return
logging.debug("Destroying vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.destroy, [], src,
_("Error shutting down domain"))
@staticmethod
def suspend(src, vm):
if not src.err.chkbox_helper(src.config.get_confirm_pause,
src.config.set_confirm_pause,
text1=_("Are you sure you want to pause '%s'?" %
vm.get_name())):
return
logging.debug("Pausing vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.suspend, [], src,
_("Error pausing domain"))
@staticmethod
def resume(src, vm):
logging.debug("Unpausing vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.resume, [], src,
_("Error unpausing domain"))
@staticmethod
def run(src, vm):
logging.debug("Starting vm '%s'", vm.get_name())
if vm.has_managed_save():
def errorcb(error, details):
# This is run from the main thread
res = src.err.show_err(
_("Error restoring domain") + ": " + error,
details=details,
text2=_(
"The domain could not be restored. Would you like\n"
"to remove the saved state and perform a regular\n"
"start up?"),
dialog_type=Gtk.MessageType.WARNING,
buttons=Gtk.ButtonsType.YES_NO,
modal=True)
if not res:
return
try:
vm.remove_saved_image()
VMActionUI.run(src, vm)
except Exception as e:
src.err.show_err(_("Error removing domain state: %s")
% str(e))
# VM will be restored, which can take some time, so show progress
title = _("Restoring Virtual Machine")
text = _("Restoring virtual machine memory from disk")
vmmAsyncJob.simple_async(vm.startup, [], src,
title, text, "", errorcb=errorcb)
else:
# Regular startup
errorintro = _("Error starting domain")
vmmAsyncJob.simple_async_noshow(vm.startup, [], src, errorintro)
@staticmethod
def shutdown(src, vm):
if not src.err.chkbox_helper(src.config.get_confirm_poweroff,
src.config.set_confirm_poweroff,
text1=_("Are you sure you want to poweroff '%s'?" %
vm.get_name())):
return
logging.debug("Shutting down vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.shutdown, [], src,
_("Error shutting down domain"))
@staticmethod
def reboot(src, vm):
if not src.err.chkbox_helper(src.config.get_confirm_poweroff,
src.config.set_confirm_poweroff,
text1=_("Are you sure you want to reboot '%s'?" %
vm.get_name())):
return
logging.debug("Rebooting vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.reboot, [], src,
_("Error rebooting domain"))
@staticmethod
def reset(src, vm):
if not src.err.chkbox_helper(
src.config.get_confirm_forcepoweroff,
src.config.set_confirm_forcepoweroff,
text1=_("Are you sure you want to force reset '%s'?" %
vm.get_name()),
text2=_("This will immediately reset the VM without "
"shutting down the OS and may cause data loss.")):
return
logging.debug("Resetting vm '%s'", vm.get_name())
vmmAsyncJob.simple_async_noshow(vm.reset, [], src,
_("Error resetting domain"))