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.
This commit is contained in:
Cole Robinson 2013-09-01 14:19:23 -04:00
parent 82ef6ba173
commit 280663c685
2 changed files with 31 additions and 129 deletions

View File

@ -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

View File

@ -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 #
###################