From c3f08fe09a5a81379b059b6e2d77c6a2c8b337c4 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Sun, 8 Jul 2012 16:06:16 -0400 Subject: [PATCH] If managed restore fails, offer to remove broken state --- src/virtManager/asyncjob.py | 23 +++++++++++++---------- src/virtManager/domain.py | 14 +++++++++----- src/virtManager/engine.py | 30 +++++++++++++++++++++++++----- 3 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/virtManager/asyncjob.py b/src/virtManager/asyncjob.py index e9eb8a275..ce2e59cbf 100644 --- a/src/virtManager/asyncjob.py +++ b/src/virtManager/asyncjob.py @@ -104,7 +104,7 @@ def cb_wrapper(callback, asyncjob, *args, **kwargs): asyncjob.set_error(str(e), "".join(traceback.format_exc())) def _simple_async(callback, args, title, text, parent, errorintro, - show_progress, simplecb): + show_progress, simplecb, errorcb): """ @show_progress: Whether to actually show a progress dialog @simplecb: If true, build a callback wrapper that ignores the asyncjob @@ -124,9 +124,12 @@ def _simple_async(callback, args, title, text, parent, errorintro, if error is None: return - error = errorintro + ": " + error - parent.err.show_err(error, - details=details) + if errorcb: + errorcb(error, details) + else: + error = errorintro + ": " + error + parent.err.show_err(error, + details=details) def idle_wrapper(fn): def wrapped(self, *args, **kwargs): @@ -138,14 +141,15 @@ class vmmAsyncJob(vmmGObjectUI): @staticmethod def simple_async(callback, args, title, text, parent, errorintro, - simplecb=True): + simplecb=True, errorcb=None): _simple_async(callback, args, title, text, parent, errorintro, True, - simplecb) + simplecb, errorcb) @staticmethod - def simple_async_noshow(callback, args, parent, errorintro, simplecb=True): + def simple_async_noshow(callback, args, parent, errorintro, + simplecb=True, errorcb=None): _simple_async(callback, args, "", "", parent, errorintro, False, - simplecb) + simplecb, errorcb) def __init__(self, callback, args, title, text, parent, @@ -164,8 +168,7 @@ class vmmAsyncJob(vmmGObjectUI): self.async = bool(async) self.show_progress = bool(show_progress) self.cancel_job = cancel_back - self.cancel_args = cancel_args or [] - self.cancel_args = [self] + self.cancel_args + self.cancel_args = [self] + (cancel_args or []) self.job_canceled = False self._error_info = None diff --git a/src/virtManager/domain.py b/src/virtManager/domain.py index b547f9143..82680b826 100644 --- a/src/virtManager/domain.py +++ b/src/virtManager/domain.py @@ -1095,11 +1095,10 @@ class vmmDomain(vmmLibvirtObject): self.idle_add(self.force_update_status) def delete(self): - if self.hasSavedImage(): - try: - self._backend.managedSaveRemove(0) - except: - logging.exception("Failed to remove managed save state") + try: + self.removeSavedImage() + except: + logging.exception("Failed to remove managed save state") self._backend.undefine() def resume(self): @@ -1115,6 +1114,11 @@ class vmmDomain(vmmLibvirtObject): return False return self._backend.hasManagedSaveImage(0) + def removeSavedImage(self): + if not self.hasSavedImage(): + return + self._backend.managedSaveRemove(0) + def save(self, filename=None, meter=None): self._install_abort = True diff --git a/src/virtManager/engine.py b/src/virtManager/engine.py index 4fc6deb61..337fc6734 100644 --- a/src/virtManager/engine.py +++ b/src/virtManager/engine.py @@ -873,14 +873,34 @@ class vmmEngine(vmmGObject): logging.debug("Starting vm '%s'", vm.get_name()) if vm.hasSavedImage(): - # VM will be restored, which can take some time, so show a - # progress dialog. - errorintro = _("Error restoring domain") + 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.MESSAGE_WARNING, + buttons=gtk.BUTTONS_YES_NO, + async=False) + + if not res: + return + + try: + vm.removeSavedImage() + self._do_run_domain(src, uri, uuid) + except Exception, 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, - [], title, text, src, - errorintro) + [], title, text, src, "", errorcb=errorcb) else: # Regular startup