mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-12-25 23:21:45 +03:00
Give better errors if PolicyKit auth fails
Coupled with a recent libvirt patch, try and give more info about a couple common policykit failure scenarios, like launching virt-manager over SSH or VNC. Do this by checking to see if we have a 'session' with ConsoleKit: the above culprits don't give the user a local session, which causes PolicyKit to deny.
This commit is contained in:
parent
8a92690a55
commit
2f10fc668c
@ -20,11 +20,11 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
import traceback
|
||||
import re
|
||||
import socket
|
||||
import threading
|
||||
import time
|
||||
import socket
|
||||
import traceback
|
||||
|
||||
import dbus
|
||||
import libvirt
|
||||
@ -48,6 +48,34 @@ def _is_virtinst_test_uri(uri):
|
||||
except:
|
||||
return False
|
||||
|
||||
def _do_we_have_session():
|
||||
pid = os.getpid()
|
||||
|
||||
try:
|
||||
bus = dbus.SystemBus()
|
||||
except:
|
||||
logging.exception("Error getting system bus handle")
|
||||
return False
|
||||
|
||||
# Check ConsoleKit
|
||||
try:
|
||||
manager = dbus.Interface(bus.get_object(
|
||||
"org.freedesktop.ConsoleKit",
|
||||
"/org/freedesktop/ConsoleKit/Manager"),
|
||||
"org.freedesktop.ConsoleKit.Manager")
|
||||
except:
|
||||
logging.exception("Couldn't connect to ConsoleKit")
|
||||
return False
|
||||
|
||||
try:
|
||||
ret = manager.GetSessionForUnixProcess(pid)
|
||||
logging.debug("Found ConsoleKit session=%s" % ret)
|
||||
except:
|
||||
logging.exception("Failed to lookup pid session")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
class vmmConnection(vmmGObject):
|
||||
|
||||
STATE_DISCONNECTED = 0
|
||||
@ -1151,6 +1179,7 @@ class vmmConnection(vmmGObject):
|
||||
libexc = None
|
||||
exc = None
|
||||
tb = None
|
||||
warnconsole = False
|
||||
try:
|
||||
self.vmm = self._try_open()
|
||||
except libvirt.libvirtError, libexc:
|
||||
@ -1173,6 +1202,15 @@ class vmmConnection(vmmGObject):
|
||||
logging.debug("User cancelled auth, not raising any error.")
|
||||
break
|
||||
|
||||
if (libexc and
|
||||
libexc.get_error_code() == libvirt.VIR_ERR_AUTH_FAILED and
|
||||
"not authorized" in libexc.get_error_message().lower()):
|
||||
logging.debug("Looks like we might have failed policykit "
|
||||
"auth. Checking to see if we have a valid "
|
||||
"console session")
|
||||
if not self.is_remote() and not _do_we_have_session():
|
||||
warnconsole = True
|
||||
|
||||
if (libexc and
|
||||
libexc.get_error_code() == libvirt.VIR_ERR_AUTH_FAILED and
|
||||
"GSSAPI Error" in libexc.get_error_message() and
|
||||
@ -1180,7 +1218,7 @@ class vmmConnection(vmmGObject):
|
||||
if self._acquire_tgt():
|
||||
continue
|
||||
|
||||
self.connectError = "%s\n\n%s" % (exc, tb)
|
||||
self.connectError = (str(exc), tb, warnconsole)
|
||||
break
|
||||
|
||||
# We want to kill off this thread asap, so schedule an
|
||||
@ -1208,7 +1246,7 @@ class vmmConnection(vmmGObject):
|
||||
|
||||
if self.state == self.STATE_DISCONNECTED:
|
||||
if self.connectError:
|
||||
self.idle_emit("connect-error", self.connectError)
|
||||
self.idle_emit("connect-error", *self.connectError)
|
||||
self.connectError = None
|
||||
|
||||
|
||||
@ -1706,4 +1744,4 @@ vmmGObject.signal_new(vmmConnection, "mediadev-removed", [str])
|
||||
|
||||
vmmGObject.signal_new(vmmConnection, "resources-sampled", [])
|
||||
vmmGObject.signal_new(vmmConnection, "state-changed", [])
|
||||
vmmGObject.signal_new(vmmConnection, "connect-error", [str])
|
||||
vmmGObject.signal_new(vmmConnection, "connect-error", [str, str, bool])
|
||||
|
@ -644,27 +644,42 @@ class vmmManager(vmmGObjectUI):
|
||||
conn.open()
|
||||
return True
|
||||
|
||||
def _connect_error(self, conn, details):
|
||||
if conn.get_driver() == "xen" and not conn.is_remote():
|
||||
self.err.show_err(
|
||||
_("Unable to open a connection to the Xen hypervisor/daemon.\n\n" +
|
||||
"Verify that:\n" +
|
||||
" - A Xen host kernel was booted\n" +
|
||||
" - The Xen service has been started\n"),
|
||||
details=details,
|
||||
title=_("Virtual Machine Manager Connection Failure"))
|
||||
def _connect_error(self, conn, shortmsg, tb, warnconsole):
|
||||
shortmsg = shortmsg.strip(" \n")
|
||||
tb = tb.strip(" \n")
|
||||
msg = _("Unable to connect to libvirt:\n\n%s\n\n") % shortmsg
|
||||
|
||||
if conn.is_xen() and not conn.is_remote():
|
||||
msg += _("Verify that:\n"
|
||||
" - A Xen host kernel was booted\n"
|
||||
" - The Xen service has been started\n")
|
||||
msg = msg.strip("\n")
|
||||
details = "%s\n\n%s" % (msg, tb)
|
||||
|
||||
else:
|
||||
hint = ''
|
||||
if re.search(r"nc: .* -- 'U'", details):
|
||||
hint = _("\n - The remote netcat understands the '-U' option")
|
||||
self.err.show_err(
|
||||
_("Unable to open a connection to the libvirt "
|
||||
"management daemon.\n\n" +
|
||||
"Libvirt URI is: %s\n\n" % conn.get_uri() +
|
||||
"Verify that:\n" +
|
||||
" - The 'libvirtd' daemon has been started") + hint,
|
||||
details=details,
|
||||
title=_("Virtual Machine Manager Connection Failure"))
|
||||
hints = []
|
||||
if conn.is_remote() and re.search(r"nc: .* -- 'U'", details):
|
||||
hints.append(
|
||||
_("\n - The remote netcat understands the '-U' option"))
|
||||
|
||||
if warnconsole:
|
||||
msg += _("Could not detect a local session: if you are \n"
|
||||
"running virt-manager over ssh -X or VNC, you \n"
|
||||
"may not be able to connect to libvirt as a \n"
|
||||
"regular user. Try running as root.\n\n")
|
||||
else:
|
||||
msg += _("Verify that:\n" +
|
||||
" - The 'libvirtd' daemon has been started")
|
||||
for hint in hints:
|
||||
msg += hint
|
||||
|
||||
msg = msg.strip("\n")
|
||||
details = (("%s\n\n" % msg) +
|
||||
(_("Libvirt URI is: %s\n\n") % conn.get_uri()) +
|
||||
tb)
|
||||
|
||||
self.err.show_err(msg, details,
|
||||
title=_("Virtual Machine Manager Connection Failure"))
|
||||
|
||||
|
||||
####################################
|
||||
|
Loading…
Reference in New Issue
Block a user