Как сделать фальшивый "активный сеанс" для gconf?

Я автоматизировал установку Ubuntu - у меня есть Python-код, который запускается автоматически (после чистой установки, но до первого входа пользователя - это временный скрипт /etc/init.d/), который настраивает все из Apache & его конфигурация в соответствии с моими личными предпочтениями Gnome. Это последнее, что доставляет мне неприятности.

Это работало нормально в Ubuntu 8.04 (Hardy), но когда я использую это с 8.10 (Intrepid), при первой попытке доступа к gconf я получаю следующее исключение:

Не удалось связаться с сервером конфигурации; Некоторые возможные причины: вам нужно включить сеть TCP/IP для ORBit, или у вас устаревшие блокировки NFS из-за сбоя системы. См. http://www.gnome.org/projects/gconf/ для получения информации. (Подробности - 1: не работает в активном сеансе)

Да, верно, сеанс Gnome не выполняется, когда он запущен, потому что пользователь еще не вошел в систему - однако это работало раньше; Похоже, что это новое для Intrepid's Gnome (2.24?).

Если не считать непосредственного изменения XML-файлов gconf, есть ли способ создать какую-то прокси-сессию Gnome? Или какие-то другие предложения?

(Подробнее: это код Python, который запускается от имени пользователя root, но setuid & setgid должны быть мной, прежде чем устанавливать свои предпочтения с помощью модуля "gconf" из пакета python-gconf.)

3 ответа

Я могу воспроизвести это, установив 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.

Weird. Похоже, он не любит подниматься, если 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). Для моего тестирования я просто использовал оболочку и вручную установил переменные среды с помощью 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

Ну, я думаю, я понимаю вопрос. Похоже, ваш скрипт просто должен запустить демон dbus или убедиться, что он запущен. Я полагаю, что "сессия" здесь относится к сеансу dbus. (вот некоторые доказательства), а не сессия Гнома. Dbus и gconf работают без Gnome.

В любом случае, подделка "активной сессии" звучит как довольно плохая идея. Он будет искать его только в том случае, если это будет необходимо.

Возможно, мы могли бы увидеть скрипт в пастбине? Я должен был действительно увидеть это, прежде чем делать какие-либо комментарии.

Спасибо, Али и Джереми - оба ваших ответа очень помогли. Я все еще работаю над этим (хотя я остановился на вечер).

Во-первых, я взял подсказку Али и попробовал часть предложения Джереми: я использовал dbus-launch для запуска "gconftool-2 -spawn". Это не сработало для меня; Теперь я понимаю, почему (thx, Джереми) - я пытался использовать gconf из той же самой программы на python, которая запускала dbus & gconftool, но его среда не имела переменных среды - duh.

Я отложил эту стратегию, когда заметил параметр --direct для gconftool-2; внутренне gconftool-2 использует API, который не предоставляется привязками gconf python. Итак, я изменил python-gconf для предоставления дополнительного метода, и как только он соберется (у меня были некоторые не связанные с этим проблемы, заставляющие его работать), мы посмотрим, исправит ли это вещи - если это не так (и, возможно, если это произойдет, поскольку создание этих привязок, по-видимому, создает весь gnome!), я найду лучший способ управления переменными среды в этой первой стратегии.

(Я добавлю другой ответ здесь завтра так или иначе)

И вот на следующий день: я столкнулся с небольшой проблемой с моим модифицированным python-gconf, который вдохновил меня попробовать более простую идею Джереми, которая работала хорошо - перед выполнением первой операции gconf я просто запустил "dbus-launch", проанализировал результирующие пары имя-значение и добавили их непосредственно в среду python. Сделав это, я запустил "gconftool-2 -spawn". Задача решена.

Другие вопросы по тегам