Convert all DBus usage to Gio GDBUS

And drop a whole bunch of legacy dbus fallback stuff. Now that we
are bumping the host dependencies to very recent gtk, none of the
back compat should matter.
This commit is contained in:
Cole Robinson 2013-04-16 13:38:19 -04:00
parent 8b31a10117
commit c60ad16b3b
8 changed files with 108 additions and 167 deletions

View File

@ -40,10 +40,6 @@ List debugging output to the console (normally this is only logged in
Don't fork C<virt-manager> off into the backround: run it blocking the Don't fork C<virt-manager> off into the backround: run it blocking the
current terminal. Useful for seeing possible errors dumped to stdout/stderr. current terminal. Useful for seeing possible errors dumped to stdout/stderr.
=item --no-dbus
Disable the DBus API used for remote control of the C<virt-manager> UI
=item --no-conn-autostart =item --no-conn-autostart
Don't autostart any libvirt connections when launching C<virt-manager>. Don't autostart any libvirt connections when launching C<virt-manager>.
@ -86,7 +82,7 @@ Please see L<http://virt-manager.org/page/BugReporting>
=head1 COPYRIGHT =head1 COPYRIGHT
Copyright (C) 2006-2007 Red Hat, Inc, and various contributors. Copyright (C) 2006-2013 Red Hat, Inc, and various contributors.
This is free software. You may redistribute copies of it under the terms of the GNU General This is free software. You may redistribute copies of it under the terms of the GNU General
Public License C<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to the extent Public License C<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to the extent
permitted by law. permitted by law.

View File

@ -114,8 +114,6 @@ def parse_commandline():
optParser.add_option("--debug", action="store_true", dest="debug", optParser.add_option("--debug", action="store_true", dest="debug",
help="Print debug output to stdout (implies --no-fork)", help="Print debug output to stdout (implies --no-fork)",
default=False) default=False)
optParser.add_option("--no-dbus", action="store_true", dest="nodbus",
help="Disable DBus service for controlling UI")
optParser.add_option("--no-fork", action="store_true", dest="nofork", optParser.add_option("--no-fork", action="store_true", dest="nofork",
help="Don't fork into background on startup") help="Don't fork into background on startup")
optParser.add_option("--no-conn-autostart", action="store_true", optParser.add_option("--no-conn-autostart", action="store_true",
@ -216,11 +214,6 @@ def main():
import libvirt import libvirt
virtManager.module_trace.wrap_module(libvirt) virtManager.module_trace.wrap_module(libvirt)
import dbus
import dbus.mainloop.glib
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
dbus.mainloop.glib.threads_init()
# Specifically init config/gconf before the fork, so that pam # Specifically init config/gconf before the fork, so that pam
# doesn't think we closed the app, therefor robbing us of # doesn't think we closed the app, therefor robbing us of
# display access # display access

View File

@ -79,9 +79,6 @@ Requires: gnome-python2-gconf >= 1.99.11-7
# This version not strictly required: virt-manager should work with older, # This version not strictly required: virt-manager should work with older,
# however varying amounts of functionality will not be enabled. # however varying amounts of functionality will not be enabled.
Requires: libvirt-python >= 0.7.0 Requires: libvirt-python >= 0.7.0
# Definitely does not work with earlier due to python API changes
Requires: dbus-python >= 0.61
Requires: dbus-x11
%if 0%{?rhel} > 6 %if 0%{?rhel} > 6
# Might work with earlier, but this is what we've tested # Might work with earlier, but this is what we've tested
Requires: gnome-keyring >= 0.4.9 Requires: gnome-keyring >= 0.4.9

View File

@ -22,12 +22,12 @@ import logging
import socket import socket
# pylint: disable=E0611 # pylint: disable=E0611
from gi.repository import Gio
from gi.repository import GObject from gi.repository import GObject
from gi.repository import Gtk from gi.repository import Gtk
# pylint: enable=E0611 # pylint: enable=E0611
import virtinst import virtinst
import dbus
from virtManager.baseclass import vmmGObjectUI from virtManager.baseclass import vmmGObjectUI
@ -79,7 +79,6 @@ class vmmConnect(vmmGObjectUI):
self.browser = None self.browser = None
self.browser_sigs = [] self.browser_sigs = []
self.can_browse = False
# Set this if we can't resolve 'hostname.local': means avahi # Set this if we can't resolve 'hostname.local': means avahi
# prob isn't configured correctly, and we should strip .local # prob isn't configured correctly, and we should strip .local
@ -90,15 +89,13 @@ class vmmConnect(vmmGObjectUI):
self.set_initial_state() self.set_initial_state()
self.bus = None self.dbus = None
self.server = None self.avahiserver = None
self.can_browse = False
try: try:
self.bus = dbus.SystemBus() self.dbus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
self.server = dbus.Interface( self.avahiserver = Gio.DBusProxy.new_sync(self.dbus, 0, None,
self.bus.get_object("org.freedesktop.Avahi", "/"), "org.freedesktop.Avahi", "/",
"org.freedesktop.Avahi.Server") "org.freedesktop.Avahi.Server", None)
self.can_browse = True
except Exception, e: except Exception, e:
logging.debug("Couldn't contact avahi: %s", str(e)) logging.debug("Couldn't contact avahi: %s", str(e))
@ -166,13 +163,22 @@ class vmmConnect(vmmGObjectUI):
ignore = flags ignore = flags
try: try:
# Async service resolving # Async service resolving
res = self.server.ServiceResolverNew(interface, protocol, name, res = self.avahiserver.ServiceResolverNew("(iisssiu)",
typ, domain, -1, 0) interface, protocol,
resint = dbus.Interface(self.bus.get_object( name, typ, domain, -1, 0)
"org.freedesktop.Avahi", res), resint = Gio.DBusProxy.new_sync(self.dbus, 0, None,
"org.freedesktop.Avahi.ServiceResolver") "org.freedesktop.Avahi", res,
self.browser_sigs.append( "org.freedesktop.Avahi.ServiceResolver",
resint.connect_to_signal("Found", self.add_conn_to_list)) None)
def cb(proxy, sender, signal, args):
ignore = proxy
ignore = sender
if signal == "Found":
self.add_conn_to_list(*args)
sig = resint.connect("g-signal", cb)
self.browser_sigs.append((resint, sig))
except Exception, e: except Exception, e:
logging.exception(e) logging.exception(e)
@ -216,7 +222,7 @@ class vmmConnect(vmmGObjectUI):
logging.exception(e) logging.exception(e)
def start_browse(self): def start_browse(self):
if self.browser or not self.can_browse: if self.browser or not self.avahiserver:
return return
# Call method to create new browser, and get back an object path for it. # Call method to create new browser, and get back an object path for it.
interface = -1 # physical interface to use? -1 is unspec interface = -1 # physical interface to use? -1 is unspec
@ -224,23 +230,31 @@ class vmmConnect(vmmGObjectUI):
service = '_libvirt._tcp' # Service name to poll for service = '_libvirt._tcp' # Service name to poll for
flags = 0 # Extra option flags flags = 0 # Extra option flags
domain = "" # Domain to browse in. NULL uses default domain = "" # Domain to browse in. NULL uses default
bpath = self.server.ServiceBrowserNew(interface, protocol, service, bpath = self.avahiserver.ServiceBrowserNew("(iissu)",
domain, flags) interface, protocol,
service, domain, flags)
# Create browser interface for the new object # Create browser interface for the new object
self.browser = dbus.Interface(self.bus.get_object( self.browser = Gio.DBusProxy.new_sync(self.dbus, 0, None,
"org.freedesktop.Avahi", bpath), "org.freedesktop.Avahi", bpath,
"org.freedesktop.Avahi.ServiceBrowser") "org.freedesktop.Avahi.ServiceBrowser",
None)
self.browser_sigs.append( def cb(proxy, sender, signal, args):
self.browser.connect_to_signal("ItemNew", self.add_service)) ignore = proxy
self.browser_sigs.append( ignore = sender
self.browser.connect_to_signal("ItemRemove", self.remove_service)) if signal == "ItemNew":
self.add_service(*args)
elif signal == "ItemRemove":
self.remove_service(*args)
self.browser_sigs.append((self.browser,
self.browser.connect("g-signal", cb)))
def stop_browse(self): def stop_browse(self):
if self.browser: if self.browser:
for sig in self.browser_sigs: for obj, sig in self.browser_sigs:
sig.remove() obj.disconnect(sig)
self.browser_sigs = [] self.browser_sigs = []
self.browser = None self.browser = None
@ -280,7 +294,7 @@ class vmmConnect(vmmGObjectUI):
self.widget("connection").set_sensitive(is_remote) self.widget("connection").set_sensitive(is_remote)
self.widget("autoconnect").set_active(not is_remote) self.widget("autoconnect").set_active(not is_remote)
self.widget("username-entry").set_sensitive(is_remote) self.widget("username-entry").set_sensitive(is_remote)
if is_remote and self.can_browse: if is_remote and self.avahiserver:
self.start_browse() self.start_browse()
else: else:
self.stop_browse() self.stop_browse()

View File

@ -20,86 +20,40 @@
# pylint: disable=E0611 # pylint: disable=E0611
from gi.repository import GLib from gi.repository import GLib
from gi.repository import Gio
# pylint: enable=E0611 # pylint: enable=E0611
import logging import logging
import os import os
import time import time
import dbus
import libvirt import libvirt
def do_we_have_session(): def do_we_have_session():
pid = os.getpid() pid = os.getpid()
try: try:
bus = dbus.SystemBus() bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
except: except:
logging.exception("Error getting system bus handle") logging.exception("Error getting system bus handle")
return return
# Check systemd # Check systemd
try: try:
manager = dbus.Interface(bus.get_object( manager = Gio.DBusProxy.new_sync(bus, 0, None,
"org.freedesktop.login1", "org.freedesktop.login1",
"/org/freedesktop/login1"), "/org/freedesktop/login1",
"org.freedesktop.login1.Manager") "org.freedesktop.login1.Manager", None)
ret = manager.GetSessionByPID(pid)
ret = manager.GetSessionByPID("(u)", pid)
logging.debug("Found login1 session=%s", ret) logging.debug("Found login1 session=%s", ret)
return True return True
except: except:
logging.exception("Couldn't connect to logind") logging.exception("Couldn't connect to logind")
# Check ConsoleKit
try:
manager = dbus.Interface(bus.get_object(
"org.freedesktop.ConsoleKit",
"/org/freedesktop/ConsoleKit/Manager"),
"org.freedesktop.ConsoleKit.Manager")
ret = manager.GetSessionForUnixProcess(pid)
logging.debug("Found ConsoleKit session=%s", ret)
return True
except:
logging.exception("Couldn't connect to ConsoleKit")
return False return False
def creds_polkit(action):
"""
Libvirt openAuth callback for PolicyKit < 1.0
"""
if os.getuid() == 0:
logging.debug("Skipping policykit check as root")
return 0
logging.debug("Doing policykit for %s", action)
try:
# First try to use org.freedesktop.PolicyKit.AuthenticationAgent
# which is introduced with PolicyKit-0.7
bus = dbus.SessionBus()
obj = bus.get_object("org.freedesktop.PolicyKit.AuthenticationAgent",
"/")
pkit = dbus.Interface(obj,
"org.freedesktop.PolicyKit.AuthenticationAgent")
pkit.ObtainAuthorization(action, 0, os.getpid())
except dbus.exceptions.DBusException, e:
if (e.get_dbus_name() != "org.freedesktop.DBus.Error.ServiceUnknown"):
raise
# If PolicyKit < 0.7, fallback to org.gnome.PolicyKit
logging.debug("Falling back to org.gnome.PolicyKit")
obj = bus.get_object("org.gnome.PolicyKit",
"/org/gnome/PolicyKit/Manager")
pkit = dbus.Interface(obj, "org.gnome.PolicyKit.Manager")
pkit.ShowDialog(action, 0)
return 0
def creds_dialog(creds): def creds_dialog(creds):
""" """
Thread safe wrapper for libvirt openAuth user/pass callback Thread safe wrapper for libvirt openAuth user/pass callback
@ -199,10 +153,12 @@ def acquire_tgt():
""" """
logging.debug("In acquire tgt.") logging.debug("In acquire tgt.")
try: try:
bus = dbus.SessionBus() bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
ka = bus.get_object('org.gnome.KrbAuthDialog', ka = Gio.DBusProxy.new_sync(bus, 0, None,
'/org/gnome/KrbAuthDialog') "org.gnome.KrbAuthDialog",
ret = ka.acquireTgt("", dbus_interface='org.gnome.KrbAuthDialog') "/org/gnome/KrbAuthDialog",
"org.freedesktop.KrbAuthDialog", None)
ret = ka.acquireTgt("(s)", "")
except Exception, e: except Exception, e:
logging.info("Cannot acquire tgt" + str(e)) logging.info("Cannot acquire tgt" + str(e))
ret = False ret = False

View File

@ -928,13 +928,10 @@ class vmmConnection(vmmGObject):
""" """
ignore = cbdata ignore = cbdata
try: try:
if (len(creds) == 1 and
creds[0][0] == libvirt.VIR_CRED_EXTERNAL and
creds[0][2] == "PolicyKit"):
return connectauth.creds_polkit(creds[0][1])
for cred in creds: for cred in creds:
if cred[0] == libvirt.VIR_CRED_EXTERNAL: if cred[0] == libvirt.VIR_CRED_EXTERNAL:
logging.debug("Don't know how to handle external cred %s",
cred[2])
return -1 return -1
return connectauth.creds_dialog(creds) return connectauth.creds_dialog(creds)

View File

@ -190,7 +190,6 @@ class vmmEngine(vmmGObject):
logging.debug("Determining default libvirt URI") logging.debug("Determining default libvirt URI")
ret = None ret = None
did_install_libvirt = False
try: try:
libvirt_packages = self.config.libvirt_packages libvirt_packages = self.config.libvirt_packages
packages = self.config.hv_packages + libvirt_packages packages = self.config.hv_packages + libvirt_packages

View File

@ -19,11 +19,10 @@
# #
# pylint: disable=E0611 # pylint: disable=E0611
from gi.repository import Gio
from gi.repository import Gtk from gi.repository import Gtk
# pylint: enable=E0611 # pylint: enable=E0611
import dbus
import logging import logging
import time import time
import traceback import traceback
@ -40,18 +39,18 @@ def check_packagekit(errbox, packages, ishv):
Returns None when we determine nothing useful. Returns None when we determine nothing useful.
Returns (success, did we just install libvirt) otherwise. Returns (success, did we just install libvirt) otherwise.
""" """
packages = ["avahi-tools"]
if not packages: if not packages:
logging.debug("No PackageKit packages to search for.") logging.debug("No PackageKit packages to search for.")
return return
logging.debug("Asking PackageKit what's installed locally.") logging.debug("Asking PackageKit what's installed locally.")
try: try:
session = dbus.SystemBus() bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
pk_control = Gio.DBusProxy.new_sync(bus, 0, None,
pk_control = dbus.Interface( "org.freedesktop.PackageKit",
session.get_object("org.freedesktop.PackageKit", "/org/freedesktop/PackageKit",
"/org/freedesktop/PackageKit"), "org.freedesktop.PackageKit", None)
"org.freedesktop.PackageKit")
except Exception: except Exception:
logging.exception("Couldn't connect to packagekit") logging.exception("Couldn't connect to packagekit")
return return
@ -63,7 +62,7 @@ def check_packagekit(errbox, packages, ishv):
found = [] found = []
progWin = vmmAsyncJob(_do_async_search, progWin = vmmAsyncJob(_do_async_search,
[session, pk_control, packages], msg, msg, [bus, pk_control, packages], msg, msg,
errbox.get_parent(), async=False) errbox.get_parent(), async=False)
error, ignore = progWin.run() error, ignore = progWin.run()
if error: if error:
@ -111,11 +110,11 @@ def check_packagekit(errbox, packages, ishv):
return do_install return do_install
def _do_async_search(asyncjob, session, pk_control, packages): def _do_async_search(asyncjob, bus, pk_control, packages):
found = [] found = []
try: try:
for name in packages: for name in packages:
ret_found = packagekit_search(session, pk_control, name, packages) ret_found = packagekit_search(bus, pk_control, name, packages)
found += ret_found found += ret_found
except Exception, e: except Exception, e:
@ -126,34 +125,25 @@ def _do_async_search(asyncjob, session, pk_control, packages):
def packagekit_install(package_list): def packagekit_install(package_list):
session = dbus.SessionBus() bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
pk_control = Gio.DBusProxy.new_sync(bus, 0, None,
pk_control = dbus.Interface( "org.freedesktop.PackageKit",
session.get_object("org.freedesktop.PackageKit", "/org/freedesktop/PackageKit",
"/org/freedesktop/PackageKit"), "org.freedesktop.PackageKit.Modify", None)
"org.freedesktop.PackageKit.Modify")
# Set 2 hour timeout # Set 2 hour timeout
timeout = 60 * 60 * 2 timeout = 1000 * 60 * 60 * 2
logging.debug("Installing packages: %s", package_list) logging.debug("Installing packages: %s", package_list)
pk_control.InstallPackageNames(dbus.UInt32(0), pk_control.InstallPackageNames("(uass)", 0,
package_list, "hide-confirm-search", package_list, "hide-confirm-search",
timeout=timeout) timeout=timeout)
def packagekit_search(session, pk_control, package_name, packages): def packagekit_search(bus, pk_control, package_name, packages):
newstyle = False
try:
tid = pk_control.GetTid()
except dbus.exceptions.DBusException, e:
if e.get_dbus_name() != "org.freedesktop.DBus.Error.UnknownMethod":
raise
newstyle = True
tid = pk_control.CreateTransaction() tid = pk_control.CreateTransaction()
pk_trans = Gio.DBusProxy.new_sync(bus, 0, None,
pk_trans = dbus.Interface( "org.freedesktop.PackageKit", tid,
session.get_object("org.freedesktop.PackageKit", tid), "org.freedesktop.PackageKit.Transaction", None)
"org.freedesktop.PackageKit.Transaction")
found = [] found = []
def package(info, package_id, summary): def package(info, package_id, summary):
@ -171,20 +161,18 @@ def packagekit_search(session, pk_control, package_name, packages):
def finished(ignore, runtime_ignore): def finished(ignore, runtime_ignore):
Gtk.main_quit() Gtk.main_quit()
pk_trans.connect_to_signal('Finished', finished) def signal_cb(proxy, sender, signal, args):
pk_trans.connect_to_signal('ErrorCode', error) ignore = proxy
pk_trans.connect_to_signal('Package', package) sender = proxy
try: if signal == "Finished":
searchtype = "installed" finished(*args)
if newstyle: elif signal == "ErrorCode":
searchtype = 2 ** 2 error(*args)
pk_trans.SearchNames(searchtype, [package_name]) elif signal == "Package":
except dbus.exceptions.DBusException, e: package(*args)
if e.get_dbus_name() != "org.freedesktop.DBus.Error.UnknownMethod":
raise
# Try older search API pk_trans.connect("g-signal", signal_cb)
pk_trans.SearchName("installed", package_name) pk_trans.SearchNames("(tas)", 2 ** 2, [package_name])
# Call main() so this function is synchronous # Call main() so this function is synchronous
Gtk.main() Gtk.main()
@ -204,28 +192,29 @@ def start_libvirtd():
unitname = "libvirtd.service" unitname = "libvirtd.service"
try: try:
bus = dbus.SystemBus() bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
except: except:
logging.exception("Error getting system bus handle") logging.exception("Error getting system bus handle")
return return
try: try:
systemd = dbus.Interface(bus.get_object( systemd = Gio.DBusProxy.new_sync(bus, 0, None,
"org.freedesktop.systemd1", "org.freedesktop.systemd1",
"/org/freedesktop/systemd1"), "/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager") "org.freedesktop.systemd1.Manager", None)
except: except:
logging.exception("Couldn't connect to systemd") logging.exception("Couldn't connect to systemd")
return return
try: try:
unitpath = systemd.GetUnit(unitname) unitpath = systemd.GetUnit("(s)", unitname)
proxy = bus.get_object("org.freedesktop.systemd1", unitpath) unit = Gio.DBusProxy.new_sync(bus, 0, None,
props = dbus.Interface(proxy, "org.freedesktop.DBus.Properties") "org.freedesktop.systemd1", unitpath,
state = props.Get("org.freedesktop.systemd1.Unit", "ActiveState") "org.freedesktop.systemd1.Unit", None)
state = unit.get_cached_property("ActiveState")
logging.debug("libvirtd state=%s", state) logging.debug("libvirtd state=%s", state)
if str(state).lower() == "active": if str(state).lower().strip("'") == "active":
logging.debug("libvirtd already active, not starting") logging.debug("libvirtd already active, not starting")
return True return True
except: except:
@ -236,11 +225,11 @@ def start_libvirtd():
try: try:
logging.debug("libvirtd not running, asking system-config-services " logging.debug("libvirtd not running, asking system-config-services "
"to start it") "to start it")
scs = dbus.Interface(bus.get_object( scs = Gio.DBusProxy.new_sync(bus, 0, None,
"org.fedoraproject.Config.Services", "org.fedoraproject.Config.Services",
"/org/fedoraproject/Config/Services/systemd1"), "/org/fedoraproject/Config/Services/systemd1",
"org.freedesktop.systemd1.Manager") "org.freedesktop.systemd1.Manager", None)
scs.StartUnit(unitname, "replace") scs.StartUnit("(ss)", unitname, "replace")
time.sleep(2) time.sleep(2)
logging.debug("Starting libvirtd appeared to succeed") logging.debug("Starting libvirtd appeared to succeed")
return True return True