Iniciando um aplicativo de sessão DBus a partir do modo de usuário systemd

0

Eu tenho uma simples necessidade de executar um serviço do usuário systemd com acesso a todas as variáveis de ambiente fornecidas pela sessão do usuário DBus. Aqui está minha unidade de exemplo:

[Unit]
Description=Environment Demo

[Service]
Type=simple
Environment=DISPLAY=:0
ExecStart=/bin/bash -c 'env > shell.env.sh'
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=default.target

As chaves exportadas são:

_
DISPLAY
HOME
LANG
LOGNAME
MANAGERPID
PATH
PWD
SHELL
SHLVL
USER
XDG_RUNTIME_DIR

Isso está muito longe da lista completa de variáveis de ambiente presentes se eu iniciar um aplicativo de desktop da minha bandeja ou do meu launcher (estou no elementary OS Loki aka Ubuntu 16.04 xenial). Se eu iniciar meu emulador de terminal ( pantheon-terminal ) e obtiver uma lista classificada de minhas variáveis de ambiente, obtenho o seguinte:

_
DBUS_SESSION_BUS_ADDRESS
DEFAULTS_PATH
DESKTOP_SESSION
DISPLAY
EDITOR
GDM_LANG
GDMSESSION
GIO_LAUNCHED_DESKTOP_FILE
GIO_LAUNCHED_DESKTOP_FILE_PID
GNOME_DESKTOP_SESSION_ID
GPG_TTY
GSETTINGS_SCHEMA_DIR
GTK_CSD
GTK_MODULES
HOME
LANG
LANGUAGE
LESSCLOSE
LESSOPEN
LOGNAME
LS_COLORS
MANDATORY_PATH
PANTHEON_TERMINAL_ID
PATH
PROMPT_COMMAND
PWD
QT_ACCESSIBILITY
QT_IM_MODULE
QT_LINUX_ACCESSIBILITY_ALWAYS_ON
QT_STYLE_OVERRIDE
SESSION_MANAGER
SHELL
SHLVL
SSH_AGENT_PID
SSH_AUTH_SOCK
TERM
USER
VTE_VERSION
XAUTHORITY
XDG_CONFIG_DIRS
XDG_CURRENT_DESKTOP
XDG_DATA_DIRS
XDG_GREETER_DATA_DIR
XDG_MENU_PREFIX
XDG_RUNTIME_DIR
XDG_SEAT
XDG_SEAT_PATH
XDG_SESSION_DESKTOP
XDG_SESSION_ID
XDG_SESSION_PATH
XDG_SESSION_TYPE
XDG_VTNR
XMODIFIERS

Para tornar as coisas mais claras:

diff --git a/systemd-user.env.txt b/pantheon-terminal.env.txt
index c684056..f6d0685 100644
--- a/systemd-user.env.txt
+++ b/pantheon-terminal.env.txt
@@ -1,12 +1,54 @@
 _
+DBUS_SESSION_BUS_ADDRESS
+DEFAULTS_PATH
+DESKTOP_SESSION
 DISPLAY
+EDITOR
+GDM_LANG
+GDMSESSION
+GIO_LAUNCHED_DESKTOP_FILE
+GIO_LAUNCHED_DESKTOP_FILE_PID
+GNOME_DESKTOP_SESSION_ID
+GPG_TTY
+GSETTINGS_SCHEMA_DIR
+GTK_CSD
+GTK_MODULES
 HOME
 LANG
+LANGUAGE
+LESSCLOSE
+LESSOPEN
 LOGNAME
-MANAGERPID
+LS_COLORS
+MANDATORY_PATH
+PANTHEON_TERMINAL_ID
 PATH
+PROMPT_COMMAND
 PWD
+QT_ACCESSIBILITY
+QT_IM_MODULE
+QT_LINUX_ACCESSIBILITY_ALWAYS_ON
+QT_STYLE_OVERRIDE
+SESSION_MANAGER
 SHELL
 SHLVL
+SSH_AGENT_PID
+SSH_AUTH_SOCK
+TERM
 USER
+VTE_VERSION
+XAUTHORITY
+XDG_CONFIG_DIRS
+XDG_CURRENT_DESKTOP
+XDG_DATA_DIRS
+XDG_GREETER_DATA_DIR
+XDG_MENU_PREFIX
 XDG_RUNTIME_DIR
+XDG_SEAT
+XDG_SEAT_PATH
+XDG_SESSION_DESKTOP
+XDG_SESSION_ID
+XDG_SESSION_PATH
+XDG_SESSION_TYPE
+XDG_VTNR
+XMODIFIERS

Existem cerca de 30 mais variáveis de ambiente ao iniciar algo assim.

Meu caso de uso é o seguinte: Eu quero poder iniciar processos com um ambiente completo, como no contexto do lançamento do meu aplicativo de terminal.

Como posso expor um ambiente completo (er) aos meus daemons de usuário do systemd?

    
por Naftuli Kay 02.06.2017 / 08:40

3 respostas

0

Você pode encontrar alguma ajuda na página wiki do ArchLinux que discute a configuração do ambiente para unidades do usuário. Em particular,

systemctl --user import-environment 

exportará todas as variáveis de ambiente atuais para o ambiente do usuário do systemd. Você pode fornecer uma lista explícita de variáveis. Você pode verificar executando

systemctl --user show-environment

antes e depois. Há também

systemctl --user set-environment MYVAR=myvalue ...
systemctl --user unset-environment MYVAR ...

Veja a página systemctl man. O wiki também menciona uma alternativa específica do dbus com a qual eu tive menos sucesso:

dbus-update-activation-environment --systemd --all
    
por 03.06.2017 / 21:17
0

Minha solução leva em conta a solução do @ meuh acima e algumas pesquisas.

O primeiro passo é criar uma unidade de usuário fictícia chamada dbus-environment.service :

[Unit]
Description=Environment Imported Target

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true

O próximo passo é criar um script Bash:

#!/bin/bash

systemctl --user import-environment
systemctl --user start dbus-environment.service

Em seguida, adicione este script aos aplicativos de inicialização do seu gerenciador de janelas que terão a garantia de rodar dentro da sessão do DBUS e do gerenciador de janelas, X, etc.

No login da sessão, o script será chamado, importando tudo para o daemon de usuário systemd.

Em seguida, para todas as unidades que dependem dessas variáveis de ambiente, basta que elas dependam de dbus-environment.service :

[Unit]
Description=Duplicity Backup Service
Requires=dbus-environment.service
After=dbus-environment.service

[Service]
Type=oneshot
ExecStart=/home/naftuli/.local/bin/duply home backup

Neste momento, quando este serviço é iniciado, é garantido que o ambiente será importado. Talvez eu deva usar um alvo em vez de um serviço, mas esse exercício terá que esperar.

    
por 06.12.2017 / 03:53
0

@Naftuli: Não teria sido melhor usar algo assim em todos os arquivos da unidade de serviços?

ExecStartPre=\usr\bin\sh -c "systemctl --user import-environment"
    
por 30.07.2018 / 16:28