Move packagekit helpers to their own file

This commit is contained in:
Cole Robinson 2012-07-08 15:05:28 -04:00
parent 5333002646
commit f5ee7c256c
2 changed files with 230 additions and 198 deletions

View File

@ -22,15 +22,16 @@ import gobject
import gtk
import logging
import traceback
import threading
import os
import time
import libvirt
import virtinst
import dbus
from virtManager import halhelper
from virtManager import packageutils
from virtManager import uihelpers
from virtManager import util
from virtManager.about import vmmAbout
from virtManager.baseclass import vmmGObject
from virtManager.clone import vmmCloneVM
@ -45,9 +46,6 @@ from virtManager.create import vmmCreate
from virtManager.host import vmmHost
from virtManager.error import vmmErrorDialog
from virtManager.systray import vmmSystray
import virtManager.uihelpers as uihelpers
import virtManager.halhelper as halhelper
import virtManager.util as util
# Enable this to get a report of leaked objects on app shutdown
debug_ref_leaks = True
@ -74,196 +72,6 @@ def _safe_getattr(obj, name):
return None
return getattr(obj, name)
#############################
# PackageKit lookup helpers #
#############################
def check_packagekit(errbox, packages, libvirt_packages):
"""
Returns None when we determine nothing useful.
Returns (success, did we just install libvirt) otherwise.
"""
if not packages:
logging.debug("No PackageKit packages to search for.")
return
logging.debug("Asking PackageKit what's installed locally.")
try:
session = dbus.SystemBus()
pk_control = dbus.Interface(
session.get_object("org.freedesktop.PackageKit",
"/org/freedesktop/PackageKit"),
"org.freedesktop.PackageKit")
except Exception:
logging.exception("Couldn't connect to packagekit")
return
found = []
progWin = vmmAsyncJob(_do_async_search,
[session, pk_control, packages],
_("Searching for available hypervisors..."),
_("Searching for available hypervisors..."),
None, async=False)
error, ignore = progWin.run()
if error:
return
found = progWin.get_data()
not_found = filter(lambda x: x not in found, packages)
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 (True, False)
else:
logging.debug("No packages are available for install.")
return
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?") %
reduce(lambda x, y: x + "\n" + y, do_install, ""))
ret = errbox.yes_no(_("Packages required for KVM usage"), msg)
if not ret:
logging.debug("Package install declined.")
return
try:
packagekit_install(do_install)
except Exception, e:
errbox.show_err(_("Error talking to PackageKit: %s") % str(e))
return
need_libvirt = False
for p in libvirt_packages:
if p in do_install:
need_libvirt = True
break
return (True, need_libvirt)
def _do_async_search(asyncjob, session, pk_control, packages):
found = []
try:
for name in packages:
ret_found = packagekit_search(session, pk_control, name, packages)
found += ret_found
except Exception, e:
logging.exception("Error searching for installed packages")
asyncjob.set_error(str(e), "".join(traceback.format_exc()))
asyncjob.set_data(found)
def packagekit_install(package_list):
session = dbus.SessionBus()
pk_control = dbus.Interface(
session.get_object("org.freedesktop.PackageKit",
"/org/freedesktop/PackageKit"),
"org.freedesktop.PackageKit.Modify")
# Set 2 hour timeout
timeout = 60 * 60 * 2
logging.debug("Installing packages: %s", package_list)
pk_control.InstallPackageNames(0, package_list, "hide-confirm-search",
timeout=timeout)
def packagekit_search(session, pk_control, package_name, packages):
tid = pk_control.GetTid()
pk_trans = dbus.Interface(
session.get_object("org.freedesktop.PackageKit", tid),
"org.freedesktop.PackageKit.Transaction")
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()
pk_trans.connect_to_signal('Finished', finished)
pk_trans.connect_to_signal('ErrorCode', error)
pk_trans.connect_to_signal('Package', package)
try:
pk_trans.SearchNames("installed", [package_name])
except dbus.exceptions.DBusException, e:
if e.get_dbus_name() != "org.freedesktop.DBus.Error.UnknownMethod":
raise
# Try older search API
pk_trans.SearchName("installed", package_name)
# Call main() so this function is synchronous
gtk.main()
return found
def start_libvirtd():
"""
Connect to systemd and start libvirtd if required
"""
logging.debug("Trying to start libvirtd through systemd")
unitname = "libvirtd.service"
try:
bus = dbus.SystemBus()
except:
logging.exception("Error getting system bus handle")
return
try:
systemd = dbus.Interface(bus.get_object(
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1"),
"org.freedesktop.systemd1.Manager")
except:
logging.exception("Couldn't connect to systemd")
return
try:
unitpath = systemd.GetUnit(unitname)
proxy = bus.get_object("org.freedesktop.systemd1", unitpath)
props = dbus.Interface(proxy, "org.freedesktop.DBus.Properties")
state = props.Get("org.freedesktop.systemd1.Unit", "ActiveState")
logging.debug("libvirtd state=%s", state)
if state == "Active":
logging.debug("libvirtd already active, not starting")
return True
except:
logging.exception("Failed to lookup libvirtd status")
return
# Connect to system-config-services and offer to start
try:
scs = dbus.Interface(bus.get_object(
"org.fedoraproject.Config.Services",
"/org/fedoraproject/Config/Services/systemd1"),
"org.freedesktop.systemd1.Manager")
scs.StartUnit(unitname, "replace")
time.sleep(2)
return True
except:
logging.exception("Failed to talk to system-config-services")
class vmmEngine(vmmGObject):
def __init__(self):
@ -355,7 +163,8 @@ class vmmEngine(vmmGObject):
libvirt_packages = self.config.libvirt_packages
packages = self.config.hv_packages + libvirt_packages
ret = check_packagekit(self.err, packages, libvirt_packages)
ret = packageutils.check_packagekit(self.err, packages,
libvirt_packages)
except:
logging.exception("Error talking to PackageKit")
@ -372,7 +181,7 @@ class vmmEngine(vmmGObject):
return
if did_install_libvirt:
didstart = start_libvirtd()
didstart = packageutils.start_libvirtd()
warnmsg = _(
"Libvirt was just installed, so the 'libvirtd' service will\n"
"will need to be started.\n"

View File

@ -0,0 +1,223 @@
#
# Copyright (C) 2012 Red Hat, Inc.
# Copyright (C) 2012 Cole Robinson <crobinso@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
#
import gtk
import dbus
import logging
import time
import traceback
from virtManager.asyncjob import vmmAsyncJob
#############################
# PackageKit lookup helpers #
#############################
def check_packagekit(errbox, packages, libvirt_packages):
"""
Returns None when we determine nothing useful.
Returns (success, did we just install libvirt) otherwise.
"""
if not packages:
logging.debug("No PackageKit packages to search for.")
return
logging.debug("Asking PackageKit what's installed locally.")
try:
session = dbus.SystemBus()
pk_control = dbus.Interface(
session.get_object("org.freedesktop.PackageKit",
"/org/freedesktop/PackageKit"),
"org.freedesktop.PackageKit")
except Exception:
logging.exception("Couldn't connect to packagekit")
return
found = []
progWin = vmmAsyncJob(_do_async_search,
[session, pk_control, packages],
_("Searching for available hypervisors..."),
_("Searching for available hypervisors..."),
None, async=False)
error, ignore = progWin.run()
if error:
return
found = progWin.get_data()
not_found = filter(lambda x: x not in found, packages)
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 (True, False)
else:
logging.debug("No packages are available for install.")
return
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?") %
reduce(lambda x, y: x + "\n" + y, do_install, ""))
ret = errbox.yes_no(_("Packages required for KVM usage"), msg)
if not ret:
logging.debug("Package install declined.")
return
try:
packagekit_install(do_install)
except Exception, e:
errbox.show_err(_("Error talking to PackageKit: %s") % str(e))
return
need_libvirt = False
for p in libvirt_packages:
if p in do_install:
need_libvirt = True
break
return (True, need_libvirt)
def _do_async_search(asyncjob, session, pk_control, packages):
found = []
try:
for name in packages:
ret_found = packagekit_search(session, pk_control, name, packages)
found += ret_found
except Exception, e:
logging.exception("Error searching for installed packages")
asyncjob.set_error(str(e), "".join(traceback.format_exc()))
asyncjob.set_data(found)
def packagekit_install(package_list):
session = dbus.SessionBus()
pk_control = dbus.Interface(
session.get_object("org.freedesktop.PackageKit",
"/org/freedesktop/PackageKit"),
"org.freedesktop.PackageKit.Modify")
# Set 2 hour timeout
timeout = 60 * 60 * 2
logging.debug("Installing packages: %s", package_list)
pk_control.InstallPackageNames(0, package_list, "hide-confirm-search",
timeout=timeout)
def packagekit_search(session, pk_control, package_name, packages):
tid = pk_control.GetTid()
pk_trans = dbus.Interface(
session.get_object("org.freedesktop.PackageKit", tid),
"org.freedesktop.PackageKit.Transaction")
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()
pk_trans.connect_to_signal('Finished', finished)
pk_trans.connect_to_signal('ErrorCode', error)
pk_trans.connect_to_signal('Package', package)
try:
pk_trans.SearchNames("installed", [package_name])
except dbus.exceptions.DBusException, e:
if e.get_dbus_name() != "org.freedesktop.DBus.Error.UnknownMethod":
raise
# Try older search API
pk_trans.SearchName("installed", package_name)
# Call main() so this function is synchronous
gtk.main()
return found
###################
# Service helpers #
###################
def start_libvirtd():
"""
Connect to systemd and start libvirtd if required
"""
logging.debug("Trying to start libvirtd through systemd")
unitname = "libvirtd.service"
try:
bus = dbus.SystemBus()
except:
logging.exception("Error getting system bus handle")
return
try:
systemd = dbus.Interface(bus.get_object(
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1"),
"org.freedesktop.systemd1.Manager")
except:
logging.exception("Couldn't connect to systemd")
return
try:
unitpath = systemd.GetUnit(unitname)
proxy = bus.get_object("org.freedesktop.systemd1", unitpath)
props = dbus.Interface(proxy, "org.freedesktop.DBus.Properties")
state = props.Get("org.freedesktop.systemd1.Unit", "ActiveState")
logging.debug("libvirtd state=%s", state)
if state == "Active":
logging.debug("libvirtd already active, not starting")
return True
except:
logging.exception("Failed to lookup libvirtd status")
return
# Connect to system-config-services and offer to start
try:
scs = dbus.Interface(bus.get_object(
"org.fedoraproject.Config.Services",
"/org/fedoraproject/Config/Services/systemd1"),
"org.freedesktop.systemd1.Manager")
scs.StartUnit(unitname, "replace")
time.sleep(2)
return True
except:
logging.exception("Failed to talk to system-config-services")