From ec56a33f7ccc9f21054716a90c3ba26bec2bc469 Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Fri, 10 Dec 2010 14:40:08 -0500
Subject: [PATCH] Run domain startup asynchronously

Sometimes startup is actually a domain restore, which can take a while, so
run it all async
---
 src/virtManager/asyncjob.py | 30 +++++++++++++++++++++++++++---
 src/virtManager/engine.py   | 25 +++++++++++++++++++------
 2 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/src/virtManager/asyncjob.py b/src/virtManager/asyncjob.py
index 21816bb83..ef04d0c83 100644
--- a/src/virtManager/asyncjob.py
+++ b/src/virtManager/asyncjob.py
@@ -42,16 +42,38 @@ def cb_wrapper(callback, asyncjob, *args, **kwargs):
     try:
         callback(asyncjob, *args, **kwargs)
     except Exception, e:
-        asyncjob.set_error(e, "".join(traceback.format_exc()))
+        asyncjob.set_error(str(e), "".join(traceback.format_exc()))
+
+def _simple_async(callback, args, title, text, parent, errorintro,
+                  show_progress):
+    asyncjob = vmmAsyncJob(callback, args, title, text,
+                           show_progress=show_progress)
+    error, details = asyncjob.run()
+    if error is None:
+        return
+
+    error = errorintro + ": " + error
+    parent.err.show_err(error, error + "\n\n" + details)
 
 # Displays a progress bar while executing the "callback" method.
 class vmmAsyncJob(vmmGObjectUI):
 
+    @staticmethod
+    def simple_async(callback, args, title, text, parent, errorintro):
+        _simple_async(callback, args, title, text, parent, errorintro, True)
+
+    @staticmethod
+    def simple_async_noshow(callback, args, parent, errorintro):
+        _simple_async(callback, args, "", "", parent, errorintro, False)
+
+
     def __init__(self, callback, args, title, text,
-                 run_main=True, cancel_back=None, cancel_args=None):
+                 run_main=True, show_progress=True,
+                 cancel_back=None, cancel_args=None):
         vmmGObjectUI.__init__(self, "vmm-progress.glade", "vmm-progress")
 
         self.run_main = bool(run_main)
+        self.show_progress = bool(show_progress)
         self.cancel_job = cancel_back
         self.cancel_args = cancel_args or []
         self.cancel_args = [self] + self.cancel_args
@@ -82,7 +104,9 @@ class vmmAsyncJob(vmmGObjectUI):
 
     def run(self):
         timer = util.safe_timeout_add(100, self.exit_if_necessary)
-        self.topwin.present()
+
+        if self.show_progress:
+            self.topwin.present()
 
         if not self.cancel_job:
             self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
diff --git a/src/virtManager/engine.py b/src/virtManager/engine.py
index 645f35ba8..974f8c16e 100644
--- a/src/virtManager/engine.py
+++ b/src/virtManager/engine.py
@@ -880,8 +880,8 @@ class vmmEngine(vmmGObject):
 
         progWin = vmmAsyncJob(self._restore_saved_callback,
                               [path, conn],
-                              _("Restoring Virtual Machine"),
-                              _("Restoring Virtual Machine"))
+                              _("Restoring domain"),
+                              _("Restoring domain"))
         error, details = progWin.run()
 
         if error is not None:
@@ -959,11 +959,24 @@ class vmmEngine(vmmGObject):
         vm = conn.get_vm(uuid)
 
         logging.debug("Starting vm '%s'." % vm.get_name())
-        try:
+
+        def asyncfunc(asyncjob):
+            ignore = asyncjob
             vm.startup()
-        except Exception, e:
-            src.err.show_err(_("Error starting domain: %s" % str(e)),
-                             "".join(traceback.format_exc()))
+
+        if vm.hasSavedImage():
+            # VM will be restored, which can take some time, so show a
+            # progress dialog.
+            errorintro  = _("Error restoring domain")
+            title = _("Restoring domain")
+            text = _("Restoring domain")
+            vmmAsyncJob.simple_async(asyncfunc, [], title, text, src,
+                                     errorintro)
+
+        else:
+            # Regular startup
+            errorintro  = _("Error starting domain")
+            vmmAsyncJob.simple_async_noshow(asyncfunc, [], src, errorintro)
 
     def _do_shutdown_domain(self, src, uri, uuid):
         conn = self._lookup_connection(uri)