9

I've automated my Ubuntu installation - I've got Python code that runs automatically (after a clean install, but before the first user login - it's in a temporary /etc/init.d/ script) that sets up everything from Apache & its configuration to my personal Gnome preferences. It's the latter that's giving me trouble.

This worked fine in Ubuntu 8.04 (Hardy), but when I use this with 8.10 (Intrepid), the first time I try to access gconf, I get this exception:

Failed to contact configuration server; some possible causes are that you need to enable TCP/IP networking for ORBit, or you have stale NFS locks due to a system crash. See http://www.gnome.org/projects/gconf/ for information. (Details - 1: Not running within active session)

Yes, right, there's no Gnome session when this is running, because the user hasn't logged in yet - however, this worked before; this appears to be new with Intrepid's Gnome (2.24?).

Short of modifying the gconf's XML files directly, is there a way to make some sort of proxy Gnome session? Or, any other suggestions?

(More details: this is python code that runs as root, but setuid's & setgid's to be me before setting my preferences using the "gconf" module from the python-gconf package.)

4

3 回答 3

8

我可以通过在我的机器上安装 GConf 2.24 来重现这一点。GConf 2.22 工作正常,但 2.24 打破了它。

GConf 无法启动,因为 D-Bus 没有运行。手动生成 D-Bus 和 GConf 守护程序可以再次完成这项工作。

我尝试通过执行以下操作来生成 D-Bus 会话总线:

import dbus
dummy_bus = dbus.SessionBus()

...但是得到了这个:

dbus.exceptions.DBusException: org.freedesktop.DBus.Error.Spawn.ExecFailed: dbus-launch failed to autolaunch D-Bus session: Autolaunch error: X11 initialization failed.

诡异的。如果 X 没有运行,它似乎不喜欢出现。要解决这个问题,请手动启动 dbus-launch(IIRC 使用os.system()调用):

$ dbus-launch 
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-eAmT3q94u0,guid=c250f62d3c4739dcc9a12d48490fc268
DBUS_SESSION_BUS_PID=15836

您需要以某种方式解析输出并将它们注入环境变量(您可能想要使用os.putenv)。对于我的测试,我只是使用了 shell,并使用export DBUS_SESSION_BUS_ADDRESS=blahblah...等手动设置环境变量。

接下来,您需要gconftool-2 --spawn使用从dbus-launch. 这将启动 GConf 守护进程。如果未设置 D-Bus 环境变量,则守护程序将不会启动。

然后,运行您的 GConf 代码。如果您为自己的脚本设置了 D-Bus 会话总线环境变量,您现在将能够与 GConf 守护进程通信。

我知道这很复杂。

gconftool-2提供了一个--direct选项,使您能够设置 GConf 变量而无需与服务器通信,但我无法找到 Python 绑定的等效选项(缺少手动输出 XML)。

编辑:为了将来参考,如果有人想dbus-launch在普通bash脚本中运行(而不是 Python 脚本,正如这个线程正在讨论的那样),检索会话总线地址以在脚本中使用非常容易:

#!/bin/bash

eval `dbus-launch --sh-syntax`

export DBUS_SESSION_BUS_ADDRESS
export DBUS_SESSION_BUS_PID

do_other_stuff_here
于 2008-11-04T03:07:40.530 回答
1

嗯,我想我明白这个问题了。看起来您的脚本只需要启动 dbus 守护程序,或者确保它已启动。我相信这里的“会话”是指 dbus 会话。(这里有一些证据),而不是 Gnome 会话。没有 Gnome,Dbus 和 gconf 都可以正常运行。

无论哪种方式,伪造“活动会话”听起来都是个坏主意。它只会在需要时寻找它。

也许我们可以在 pastebin 中看到脚本?在发表任何评论之前,我应该真的看过它。

于 2008-11-03T02:52:42.030 回答
1

谢谢,阿里和杰里米 - 你的回答都帮了大忙。我仍在为此工作(尽管我已经在晚上停下来了)。

首先,我从 Ali 那里得到了提示,并尝试了 Jeremy 的部分建议:我使用 dbus-launch 来运行“gconftool-2 --spawn”。它对我不起作用;我现在明白了为什么(谢谢,Jeremy)——我试图在启动 dbus 和 gconftool 的同一个 python 程序中使用 gconf,但它的环境没有环境变量——duh。

当我注意到 gconftool-2 的 --direct 选项时,我把这个策略放在一边;在内部,gconftool-2 正在使用 gconf python 绑定未公开的 API。所以,我修改了 python-gconf 以公开额外的方法,一旦构建(我有一些不相关的问题让它工作),我们将看看它是否修复了问题 - 如果它没有(也许如果它确实,因为构建这些绑定似乎构建了所有 gnome!),我会找到一种更好的方法来管理第一个策略中的环境变量。

(明天我会在这里添加另一个答案)

第二天:我修改后的 python-gconf 遇到了一点麻烦,这启发了我尝试 Jeremy 的更简单的想法,它运行良好 - 在进行第一次 gconf 操作之前,我只是运行“dbus-launch”,解析生成的名称-值对,并将它们直接添加到 python 的环境中。完成后,我运行了“gconftool-2 --spawn”。问题解决了。

于 2008-11-04T07:39:34.617 回答