From 280663c685544cb7cfdca3024b357a0b5d9b04c0 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Sun, 1 Sep 2013 14:19:23 -0400 Subject: [PATCH] packageutils: Don't implement our own search dialog (bz #746011) Our search dialog isn't as full featured as packagekits, so just call out to that. This was originally avoided because it doesn't full provide the semantics we want, but it's close enough and saves us from duplicating all their work. --- virtManager/engine.py | 11 ++- virtManager/packageutils.py | 149 ++++++------------------------------ 2 files changed, 31 insertions(+), 129 deletions(-) diff --git a/virtManager/engine.py b/virtManager/engine.py index c91eee5a..8e216b96 100644 --- a/virtManager/engine.py +++ b/virtManager/engine.py @@ -174,6 +174,9 @@ class vmmEngine(vmmGObject): if self.config.get_conn_uris(): return + self.timeout_add(1000, self._add_default_conn, manager) + + def _add_default_conn(self, manager): # Manager fail message msg = _("Could not detect a default hypervisor. Make\n" "sure the appropriate virtualization packages\n" @@ -189,11 +192,11 @@ class vmmEngine(vmmGObject): libvirt_packages = self.config.libvirt_packages packages = self.config.hv_packages + libvirt_packages - ret = packageutils.check_packagekit(manager.err, packages, True) + ret = packageutils.check_packagekit(manager, manager.err, packages) except: logging.exception("Error talking to PackageKit") - if ret is not None: + if ret: tryuri = "qemu:///system" else: tryuri = uihelpers.default_uri(always_system=True) @@ -551,9 +554,9 @@ class vmmEngine(vmmGObject): if self.config.askpass_package: ret = packageutils.check_packagekit( + None, self.err, - self.config.askpass_package, - False) + self.config.askpass_package) if ret: conn.open() return diff --git a/virtManager/packageutils.py b/virtManager/packageutils.py index 8b2b1ac0..dd52ee5d 100644 --- a/virtManager/packageutils.py +++ b/virtManager/packageutils.py @@ -20,21 +20,17 @@ # pylint: disable=E0611 from gi.repository import Gio -from gi.repository import Gtk # pylint: enable=E0611 import logging import time -import traceback -from virtManager.asyncjob import vmmAsyncJob ############################# # PackageKit lookup helpers # ############################# - -def check_packagekit(errbox, packages, ishv): +def check_packagekit(parent, errbox, packages): """ Returns None when we determine nothing useful. Returns (success, did we just install libvirt) otherwise. @@ -46,149 +42,52 @@ def check_packagekit(errbox, packages, ishv): logging.debug("Asking PackageKit what's installed locally.") try: bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None) - pk_control = Gio.DBusProxy.new_sync(bus, 0, None, - "org.freedesktop.PackageKit", - "/org/freedesktop/PackageKit", - "org.freedesktop.PackageKit", None) + Gio.DBusProxy.new_sync(bus, 0, None, + "org.freedesktop.PackageKit", + "/org/freedesktop/PackageKit", + "org.freedesktop.PackageKit", None) except Exception: logging.exception("Couldn't connect to packagekit") return - if ishv: - msg = _("Searching for available hypervisors...") - else: - msg = _("Checking for installed package '%s'") % packages[0] - - cancellable = Gio.Cancellable() - progWin = vmmAsyncJob(_do_async_search, - [bus, pk_control, packages, cancellable], msg, msg, - errbox.get_parent(), async=False, - cancel_cb=[_cancel_search, cancellable]) - error, ignore = progWin.run() - if error: - return - - found = progWin.get_extra_data() - - not_found = [x for x in packages if x not in found] - logging.debug("Missing packages: %s", not_found) - - do_install = not_found - if not do_install: - if not not_found: - # Got everything we wanted, try to connect - logging.debug("All packages found locally.") - return [] - - else: - logging.debug("No packages are available for install.") - return - - missing = reduce(lambda x, y: x + "\n" + y, do_install, "") - if ishv: - msg = (_("The following packages are not installed:\n%s\n\n" - "These are required to create KVM guests locally.\n" - "Would you like to install them now?") % missing) - title = _("Packages required for KVM usage") - else: - msg = _("The following packages are not installed:\n%s\n\n" - "Would you like to install them now?" % missing) - title = _("Recommended package installs") - - ret = errbox.yes_no(title, msg) - - if not ret: - logging.debug("Package install declined.") - return - try: - packagekit_install(do_install) + packagekit_install(parent, packages) except Exception, e: + if "Modify.transactionCancelled" in str(e): + logging.debug("PackageKit transaction cancelled.") + return errbox.show_err(_("Error talking to PackageKit: %s") % str(e)) return - return do_install + return True -def _cancel_search(asyncjob, cancellable): - cancellable.cancel() - asyncjob.job_cancelled = True - - -def _do_async_search(asyncjob, bus, pk_control, packages, cancellable): - found = [] - try: - for name in packages: - ret_found = packagekit_search(bus, pk_control, name, packages, - cancellable) - found += ret_found - except Exception, e: - if cancellable.is_cancelled(): - logging.debug("Package search cancelled by user") - asyncjob.set_error("Package search cancelled by user") - else: - logging.exception("Error searching for installed packages") - asyncjob.set_error(str(e), "".join(traceback.format_exc())) - - asyncjob.set_extra_data(found) - - -def packagekit_install(package_list): +def packagekit_install(parent, package_list): bus = Gio.bus_get_sync(Gio.BusType.SESSION, None) pk_control = Gio.DBusProxy.new_sync(bus, 0, None, "org.freedesktop.PackageKit", "/org/freedesktop/PackageKit", "org.freedesktop.PackageKit.Modify", None) + xid = 0 + try: + # Need to import GdkX11 just to get access to get_xid function + # This will likely fail on wayland in the future, so ignore errors + from gi.repository import GdkX11 # pylint: disable=E0611 + ignore = GdkX11 + + if parent and parent.topwin.get_window(): + xid = parent.topwin.get_window().get_xid() + except: + pass + # Set 2 hour timeout timeout = 1000 * 60 * 60 * 2 logging.debug("Installing packages: %s", package_list) - pk_control.InstallPackageNames("(uass)", 0, - package_list, "hide-confirm-search", + pk_control.InstallPackageNames("(uass)", xid, package_list, "", timeout=timeout) -def packagekit_search(bus, pk_control, package_name, packages, cancellable): - tid = pk_control.CreateTransaction() - pk_trans = Gio.DBusProxy.new_sync(bus, 0, None, - "org.freedesktop.PackageKit", tid, - "org.freedesktop.PackageKit.Transaction", - cancellable) - - found = [] - def package(info, package_id, summary): - ignore = info - ignore = summary - - found_name = str(package_id.split(";")[0]) - if found_name in packages: - found.append(found_name) - - def error(code, details): - raise RuntimeError("PackageKit search failure: %s %s" % - (code, details)) - - def finished(ignore, runtime_ignore): - Gtk.main_quit() - - def signal_cb(proxy, sender, signal, args): - ignore = proxy - sender = proxy - if signal == "Finished": - finished(*args) - elif signal == "ErrorCode": - error(*args) - elif signal == "Package": - package(*args) - - pk_trans.connect("g-signal", signal_cb) - pk_trans.SearchNames("(tas)", 2 ** 2, [package_name]) - - # Call main() so this function is synchronous - Gtk.main() - - return found - ################### # Service helpers # ###################