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:
parent
82ef6ba173
commit
280663c685
|
@ -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
|
||||
|
|
|
@ -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 #
|
||||
###################
|
||||
|
|
Loading…
Reference in New Issue