systemd (Français)/User (Français) - ArchWiki

Jump to content

# systemd (Français)/User (Français)

From ArchWiki
< Systemd (Français)

État de la traduction: Cet article est la version francophone de systemd/User. Date de la dernière traduction: 2022-04-30. Vous pouvez aider à synchroniser la traduction s'il y a eu des changements dans la version anglaise.

Related articles

- systemd (Français)
- Getty (Français)#Connexion automatique à la console
- Xinit (Français)#Démarrage automatique de X à la connexion

Systemd offre la possibilité de gérer des services sous le contrôle de l'utilisateur en lui permettant de démarrer, arrêter, activer ou désactiver une unité utilisateur. Cette option est pratique pour les daemons et autres services qui ne sont généralement exécutés que pour un seul utilisateur, comme mpd, ou pour effectuer des tâches automatisées comme la récupération du courrier électronique.

## Fonctionnement

Selon la configuration par défaut dans `/etc/pam.d/system-login`, le module `pam_systemd` lance automatiquement une instance `systemd --user` lorsque l'utilisateur se connecte pour la première fois. Ce processus survivra tant qu'il y aura une session pour cet utilisateur, et sera tué dès que la dernière session de l'utilisateur sera fermée. Lorsque #Démarrage automatique des instances utilisateur systemd est activé, l'instance est démarrée au démarrage et ne sera pas tuée. L'instance utilisateur systemd est responsable de la gestion des services utilisateurs, qui peuvent être utilisés pour exécuter des daemons ou des tâches automatisées, avec tous les avantages de systemd, tels que l'activation des sockets, les timers, le système de dépendances ou le contrôle strict des processus via les cgroups.

De la même manière que les unités système, les unités utilisateur sont situées dans les répertoires suivants (classés par ordre de préséance ascendante) :

- `/usr/lib/systemd/user/` où appartiennent les unités fournies par les paquets installés.
- `~/.local/share/systemd/user/` où appartiennent les unités des paquets qui ont été installés dans le répertoire personnel.
- `/etc/systemd/user/` où sont placées les unités des utilisateurs du système par l'administrateur système.
- `~/.config/systemd/user/` où l'utilisateur place ses propres unités.

Lorsqu'une instance utilisateur de systemd démarre, elle active la cible par utilisateur `default.target`. Les autres unités peuvent être contrôlées manuellement avec `systemctl --user`. Consultez systemd.special(7) § UNITS MANAGED BY THE USER SERVICE MANAGER.

Note:

- Sachez que l'instance `systemd --user` est un processus par utilisateur, et non par session. La raison en est que la plupart des ressources gérées par les services utilisateur, comme les sockets ou les fichiers d'état, seront par utilisateur (dans le répertoire personnel de l'utilisateur) et non par session. Cela signifie que tous les services utilisateur s'exécutent en dehors d'une session. Par conséquent, les programmes qui doivent être exécutés à l'intérieur d'une session seront probablement interrompus dans les services utilisateur. La façon dont systemd gère les sessions utilisateur est en pleine évolution. Consultez [1] et [2] pour obtenir des indications sur l'avancement.
- `systemd --user` s'exécute comme un processus distinct du processus `systemd --system`. Les unités de l'utilisateur ne peuvent pas référencer ou dépendre des unités du système ou des unités d'autres utilisateurs.

## Configuration de base

Toutes les unités de l'utilisateur seront placées dans `~/.config/systemd/user/`. Si vous voulez démarrer les unités à la première connexion, exécutez `systemctl --user enable unit` pour toute unité que vous voulez démarrer automatiquement.

Astuce: Si vous voulez activer une unité pour tous les utilisateurs plutôt que pour l'utilisateur qui exécute la commande systemctl, exécutez `systemctl --global enable unit` en tant que root. De même pour `disable`.

### Variables d'environnement

L'instance utilisateur de systemd n'hérite d'aucune des variables d'environnement définies dans des endroits comme `.bashrc`, etc. Il existe plusieurs façons de définir les variables d'environnement pour l'instance utilisateur de systemd :

- Pour les utilisateurs ayant un répertoire `$HOME`, créez un fichier .conf dans le répertoire `~/.config/environment.d/` avec des lignes de la forme `NAME=VAL`. Affecte uniquement l'unité utilisateur de cet utilisateur. Consultez environment.d(5) pour plus d'informations.
- Utiliser l'option `DefaultEnvironment` dans le fichier `/etc/systemd/user.conf`. Affecte toutes les unités utilisateur.
- Ajouter un fichier de configuration de dépôt dans `/etc/systemd/system/user@.service.d/`. Affecte toutes les unités utilisateur ; consultez #Exemple de service.
- A tout moment, utilisez `systemctl --user set-environment` ou `systemctl --user import-environment`. Affecte toutes les unités utilisateur démarrées après la définition des variables d'environnement, mais pas les unités qui étaient déjà en cours d'exécution.
- Utiliser la commande `dbus-update-activation-environment --systemd --all` fournie par dbus. A le même effet que `systemctl --user import-environment`, mais affecte également la session D-Bus. Vous pouvez ajouter ceci à la fin de votre fichier d'initialisation du shell.
- Pour les variables d'environnement "globales" pour l'environnement de l'utilisateur, vous pouvez utiliser les répertoires `environment.d` qui sont analysés par certains générateurs. Consultez environment.d(5) et systemd.generator(7) pour plus d'informations.
- Vous pouvez également écrire un script systemd.environment-generator(7) qui peut produire des variables d'environnement qui varient d'un utilisateur à l'autre, c'est probablement la meilleure façon si vous avez besoin d'environnements par utilisateur (c'est le cas pour `XDG_RUNTIME_DIR`, `DBUS_SESSION_BUS_ADDRESS`, etc).

Une variable que vous pouvez vouloir définir est `PATH`.

Après la configuration, la commande `systemctl --user show-environment` peut être utilisée pour vérifier que les valeurs sont correctes.

#### Exemple de service

Créez le répertoire «drop-in» `/etc/systemd/system/user@.service.d/` et créez à l'intérieur un fichier ayant l'extension .conf (par exemple `local.conf`) :

    /etc/systemd/system/user@.service.d/local.conf

    [Service]
    Environment="PATH=/usr/lib/ccache/bin:/usr/local/bin:/usr/bin:/bin"
    Environment="EDITOR=nano -c"
    Environment="BROWSER=firefox"
    Environment="NO_AT_BRIDGE=1"

#### DISPLAY et XAUTHORITY

`DISPLAY` est utilisé par toute application X pour savoir quel affichage utiliser et `XAUTHORITY` pour fournir un chemin vers le fichier `.Xauthority` de l'utilisateur et donc le cookie nécessaire pour accéder au serveur X. Si vous prévoyez de lancer des applications X à partir d'unités systemd, ces variables doivent être définies. Systemd fournit un script dans `/etc/X11/xinit/xinitrc.d/50-systemd-user.sh` pour importer ces variables dans la session de l'utilisateur systemd au lancement de l'application. [3] Donc, à moins que vous ne démarriez X d'une manière non standard, les services utilisateurs devraient être conscients des variables `DISPLAY` et `XAUTHORITY`.

#### PATH

Si vous personnalisez votre `PATH` et prévoyez de lancer des applications qui l'utilisent à partir d'unités systemd, vous devez vous assurer que le `PATH` modifié est défini dans l'environnement systemd. En supposant que vous avez défini votre `PATH` dans `.bash_profile`, la meilleure façon de faire connaître à systemd votre `PATH` modifié est d'ajouter ce qui suit à `.bash_profile` après la définition de la variable `PATH` :

    ~/.bash_profile

    systemctl --user import-environnement PATH

Note:

- Cela n'affectera pas les services systemd démarrés avant l'importation du `PATH`.
- systemd ne regarde pas le `PATH` défini lorsqu'il résout lui-même les binaires sans chemin absolus.

#### pam_env

Note: Cette façon de définir les variables d'environnement par utilisateur est obsolète et sera supprimée.

Les variables d'environnement peuvent être rendues disponibles par l'utilisation du module `pam_env.so`. Consultez Environment variables#Using pam_env pour les détails de configuration.

### Démarrage automatique des instances utilisateur systemd

L'instance utilisateur systemd est démarrée après la première connexion d'un utilisateur et tuée après la fermeture de la dernière session de l'utilisateur. Parfois, il peut être utile de la lancer juste après le démarrage, et de maintenir l'instance utilisateur systemd en cours d'exécution après la fermeture de la dernière session, par exemple pour avoir un processus utilisateur en cours d'exécution sans aucune session ouverte. Lingering est utilisé à cet effet. Utilisez la commande suivante pour activer le lingering pour un utilisateur spécifique :

    # loginctl enable-linger username

Attention: Les services Systemd ne sont pas des sessions, ils s'exécutent en dehors de logind. N'utilisez pas le lingering pour activer la connexion automatique car cela casse la session.

## Écrire des unités utilisateur

Consultez Systemd (Français)#Écrire des unités pour des informations générales sur l'écriture des fichiers d'unités de systemd.

### Exemple

Voici un exemple d'une version utilisateur du service mpd :

    ~/.config/systemd/user/mpd.service

    [Unit]
    Description=Music Player Daemon

    [Service]
    ExecStart=/usr/bin/mpd --no-daemon

    [Install]
    WantedBy=default.target

### Exemple avec variables

Ci-dessous, le service utilisateur de foldingathomeAUR, qui tient compte par une variable des répertoires personnels où Folding@home peut trouver certains fichiers :

    ~/.config/systemd/user/foldingathome-user.service

    [Unit]
    Description=Folding@home distributed computing client
    After=network.target

    [Service]
    Type=simple
    WorkingDirectory=%h/.config/fah
    ExecStart=/usr/bin/FAHClient
    CPUSchedulingPolicy=idle
    IOSchedulingClass=3

    [Install]
    WantedBy=default.target

Comme détaillé dans systemd.unit(5) § SPECIFIERS, la variable `%h` est remplacée par le répertoire personnel de l'utilisateur qui exécute le service. Il existe d'autres variables qui peuvent être prises en compte dans les pages de manuel de systemd.

### Lecture du journal

Le journal de l'utilisateur peut être lu en utilisant la commande analogue :

    $ journalctl --user

Pour spécifier une unité, on peut utiliser

    $ journalctl --user-unit monunité.service

Ou, de manière équivalente

    $ journalctl --user -u monunité.service

Note: journald n'écrira pas de journaux d'utilisateur pour les utilisateurs avec des UIDs inférieurs à 1000, il dirigera tout vers le journal du système à la place.

## Fichiers temporaires

systemd-tmpfiles permet aux utilisateurs de gérer des fichiers et des répertoires volatils et temporaires personnalisés, tout comme pour le système dans son ensemble (consultez Systemd (Français)#systemd-tmpfiles - fichiers temporaires). Les fichiers de configuration spécifiques à l'utilisateur sont lus dans `~/.config/user-tmpfiles.d/` et `~/.local/share/user-tmpfiles.d/`, dans cet ordre. Pour que cette fonctionnalité puisse être utilisée, il est nécessaire d'activer les unités utilisateur systemd nécessaires pour votre utilisateur :

    $ systemctl --user enable systemd-tmpfiles-setup.service systemd-tmpfiles-clean.timer

La syntaxe des fichiers de configuration est la même que celle utilisée dans tout le système. Consultez les pages de manuel systemd-tmpfiles(8) et tmpfiles.d(5) pour plus de détails.

## Xorg et systemd

Il y a plusieurs façons d'exécuter xorg dans les unités systemd. Ci-dessous, il y a deux options, soit en démarrant une nouvelle session utilisateur avec un processus xorg, soit en lançant xorg depuis un service utilisateur systemd.

### Connexion automatique à Xorg sans gestionnaire d'affichage

Cette option lancera une unité système qui démarrera une session utilisateur avec un serveur xorg, puis exécutera les `~/.xinitrc` habituels pour lancer le gestionnaire de fenêtres, etc. Vous devez avoir installé xlogin-gitAUR. Configurez votre xinitrc comme indiqué dans la section Xinit (Français)#xinitrc.

La session utilisera son propre daemon dbus, mais divers utilitaires systemd se connecteront automatiquement à l'instance `dbus.service`. Enfin, activez le service `xlogin@username` pour une connexion automatique au démarrage. La session utilisateur vit entièrement à l'intérieur d'un scope systemd et tout ce qui se trouve dans la session utilisateur devrait fonctionner parfaitement.

### Xorg comme service utilisateur systemd

Alternativement, xorg peut être exécuté à partir d'un service utilisateur systemd. C'est une bonne chose puisque d'autres unités liées à X peuvent être rendues dépendantes de xorg, etc, mais d'un autre côté, cela a quelques inconvénients expliqués ci-dessous.

xorg-server fournit une intégration avec systemd de deux manières :

- Il peut être exécuté sans privilège, déléguant la gestion des périphériques à logind (consultez les commits de Hans de Goede autour de ce commit).
- Peut être transformé en un service activé par socket (consultez ce commit). Cela supprime le besoin de systemd-xorg-launch-helper-gitAUR.

Malheureusement, pour pouvoir exécuter xorg en mode non privilégié, il doit être exécuté dans une session. Donc, actuellement, le handicap de l'exécution de xorg en tant que service utilisateur est qu'il doit être exécuté avec les privilèges root (comme avant la 1.16), et ne peut pas profiter du mode non privilégié introduit dans la 1.16.

Note: Ce n'est pas une restriction fondamentale imposée par logind, mais la raison semble être que xorg a besoin de savoir quelle session prendre en charge, et pour l'instant il obtient cette information en appelant `GetSessionByPID` de logind en utilisant son propre pid comme argument. Consultez cette discussion et les sources de xorg. Il semble probable que xorg puisse être modifié pour obtenir la session à partir du tty auquel il est attaché, et qu'il puisse ensuite être exécuté sans privilège à partir d'un service utilisateur en dehors d'une session.
Attention: Sur xorg 1.18, l'activation des sockets semble ne pas fonctionner. Le client qui déclenche l'activation se bloque. Consultez le rapport de bogue amont [4]. Comme solution temporaire, vous pouvez démarrer le serveur xorg sans l'activation des sockets, en vous assurant que les clients se connectent après un délai, afin que le serveur soit complètement démarré. Il semble qu'il n'existe aucun mécanisme permettant d'obtenir une notification de démarrage du serveur X.

Voici comment lancer xorg à partir d'un service utilisateur :

1. Faites tourner xorg avec les privilèges root pour n'importe quel utilisateur, en éditant `/etc/X11/Xwrapper.config`.

    /etc/X11/Xwrapper.config

    allowed_users=anybody
    needs_root_rights=yes

2. Ajoutez les unités suivantes à `~/.config/systemd/user`

    ~/.config/systemd/user/xorg@.socket

    [Unit]
    Description=Socket for xorg at display %i

    [Socket]
    ListenStream=/tmp/.X11-unix/X%i

    ~/.config/systemd/user/xorg@.service

    [Unit]
    Description=Xorg server at display %i

    Requires=xorg@%i.socket
    After=xorg@%i.socket

    [Service]
    Type=simple
    SuccessExitStatus=0 1

    ExecStart=/usr/bin/Xorg :%i -nolisten tcp -noreset -verbose 2 "vt${XDG_VTNR}"

où `${XDG_VTNR}` est le terminal virtuel où xorg sera lancé, soit codé en dur dans l'unité de service, soit défini dans l'environnement systemd avec

    $ systemctl --user set-environment XDG_VTNR=1

Note: xorg doit être lancé sur le même terminal virtuel que celui où l'utilisateur s'est connecté. Sinon, logind considérera que la session est inactive.

3. Assurez-vous de configurer la variable d'environnement `DISPLAY` comme expliqué ci-dessus.

4. Ensuite, pour activer l'activation de la socket pour xorg sur l'affichage 0 et le tty 2, il faut faire :

    $ systemctl --user set-environment XDG_VTNR=2 # Pour que xorg@.service sache quel vt utiliser
    $ systemctl --user start xorg@0.socket # Commence à écouter sur le socket pour l'affichage 0

Maintenant, l'exécution de toute application X lancera xorg sur le terminal virtuel 2 automatiquement.

La variable d'environnement `XDG_VTNR` peut être définie dans l'environnement systemd à partir de `.bash_profile`, et l'on peut alors démarrer n'importe quelle application X, y compris un gestionnaire de fenêtres, en tant qu'unité systemd qui dépend de `xorg@0.socket`.

Attention: L'exécution actuelle d'un gestionnaire de fenêtres en tant que service utilisateur signifie qu'il fonctionne en dehors d'une session avec les problèmes que cela peut entraîner : casser la session. Cependant, il semble que les développeurs de systemd aient l'intention de rendre quelque chose comme cela possible. Consultez [5] et [6]

### Clients X en tant que service utilisateur

Avec une version adaptée de sx, on peut facilement faire fonctionner tous les clients X en tant que service utilisateur tout en laissant Xorg, le serveur, fonctionner dans une session non privilégiée.

Premièrement, mettez une copie de `/usr/bin/sx` sous `/usr/local/bin/`. La copie peut être nommée par exemple `sdsx` afin que l'original `sx` reste accessible.

Ensuite, remplacez

    trap 'DISPLAY=:$tty exec "${@:-$cfgdir/sxrc}" & wait "$ !" USR1

par

    trap 'systemd-run --user -u sx-client-$tty -E DISPLAY=:$tty -E XAUTHORITY="$XAUTHORITY" \
          "${@:-$cfgdir/sxrc}" & wait "$pid"' USR1

et remplacez

    (trap '' USR1 && exec Xorg : "$tty" -keeptty vt "$tty" -noreset -auth "$XAUTHORITY") & pid=$!

avec

    (trap '' USR1 && exec Xorg :"$tty" -keeptty vt"$tty" -terminate -auth "$XAUTHORITY") & pid=$!

L'inconvénient de cette approche est que, si pour une raison quelconque, aucun client X n'a réussi à atteindre le serveur, le serveur devra être tué manuellement à partir d'un autre tty. De plus, si, par exemple, `xrdb` doit être exécuté dans `sxrc`, il devra maintenant être exécuté avec l'option `-retain`. Consultez Xserver(1) et xrdb(1) pour plus de détails.

L'un des cas d'utilisation et/ou des avantages de cette approche est que les clients X seront désormais exécutés sous le gestionnaire d'utilisateurs (`user@$uid.service`) et que le snippet (c'est-à-dire `systemctl edit`) qui lui est appliqué (par exemple, `NetworkNamespacePath=`) sera également appliqué aux programmes exécutés dans l'environnement graphique (y compris, mais sans s'y limiter, les shells de ligne de commande exécutés dans un émulateur de terminal).

## Quelques cas d'utilisation

### Gestionnaire de fenêtres

Pour exécuter un gestionnaire de fenêtres en tant que service systemd, vous devez d'abord exécuter #Xorg comme service utilisateur systemd. Dans ce qui suit, nous utiliserons awesome comme exemple :

    ~/.config/systemd/user/awesome.service

    [Unit]
    Description=Awesome window manager
    After=xorg.target
    Requires=xorg.target

    [Service]
    ExecStart=/usr/bin/awesome
    Restart=always
    RestartSec=10

    [Install]
    WantedBy=wm.target

Note: La section `[Install]` comprend une partie `WantedBy`. L'utilisation de `systemctl --user enable` liera ce service en tant que `~/.config/systemd/user/wm.target.wants/window_manager.service`, ce qui permettra de le démarrer à la connexion. Il est recommandé d'activer ce service, et non de le lier manuellement.

### Multiplexeur de terminal persistant

Vous pouvez souhaiter que votre session utilisateur exécute par défaut un multiplexeur de terminal, tel que GNU Screen ou Tmux, en arrière-plan plutôt que de vous connecter à une session de gestionnaire de fenêtres. Séparer la connexion de la connexion à X n'est probablement utile que pour ceux qui démarrent sur un TTY plutôt que sur un gestionnaire d'affichage (dans ce cas, vous pouvez simplement regrouper tout ce que vous démarrez avec `myStuff.target`).

Pour créer ce type de session utilisateur, procédez comme ci-dessus, mais au lieu de créer `wm.target`, créez `multiplexer.target` :

    [Unit]
    Description=Terminal multiplexer
    Documentation=info:screen man:screen(1) man:tmux(1)
    After=cruft.target
    Wants=cruft.target

    [Install]
    Alias=default.target

`cruft.target`, comme `mystuff.target` ci-dessus, devrait démarrer tout ce que vous pensez devoir être exécuté avant le démarrage de tmux ou de screen (ou que vous voulez démarrer au démarrage sans tenir compte du moment), comme une session du daemon GnuPG.

Vous devez ensuite créer un service pour votre session multiplexeur. Voici un exemple de service, utilisant tmux comme exemple et utilisant une session gpg-agent qui écrit ses informations dans `/tmp/gpg-agent-info`. Cette session d'exemple, lorsque vous démarrez X, sera également capable d'exécuter des programmes X, puisque DISPLAY est défini.

    [Unit]
    Description=tmux: A terminal multiplexer
    Documentation=man:tmux(1)
    After=gpg-agent.service
    Wants=gpg-agent.service

    [Service]
    Type=forking
    ExecStart=/usr/bin/tmux start
    ExecStop=/usr/bin/tmux kill-server
    Environment=DISPLAY=:0
    EnvironmentFile=/tmp/gpg-agent-info

    [Install]
    WantedBy=multiplexer.target

Une fois que c'est fait, activez `tmux.service`, `multiplexer.target` et tous les services que vous avez créés pour être exécutés par `cruft.target` et vous devriez être prêt à partir ! Démarrez `user@.service` comme d'habitude. Félicitations ! Vous avez un multiplexeur de terminal en fonctionnement et quelques autres programmes utiles prêts à être lancés au démarrage !

## Tuer les processus utilisateur lors de la déconnexion

Arch Linux construit le paquet systemd avec `--without-kill-user-processes`, définissant `KillUserProcesses` à `no` par défaut. Ce paramètre fait que les processus utilisateur ne sont pas tués lorsque l'utilisateur se déconnecte. Pour modifier ce comportement afin que tous les processus utilisateur soient tués lors de la déconnexion de l'utilisateur, définissez `KillUserProcesses=yes` dans `/etc/systemd/logind.conf`.

Notez que la modification de ce paramètre casse les multiplexeurs de terminaux tels que tmux et GNU Screen. Si vous modifiez ce paramètre, vous pouvez toujours utiliser un multiplexeur de terminal en utilisant `systemd-run` comme suit :

    $ systemd-run --scope --user command args.

Par exemple, pour exécuter `screen` vous devez faire :

    $ systemd-run --scope --user screen -S foo

L'utilisation de `systemd-run` ne maintiendra le processus en cours d'exécution après la déconnexion que si l'utilisateur est connecté au moins une fois ailleurs dans le système et que `user@.service` est toujours en cours d'exécution.

Après que l'utilisateur se soit déconnecté de toutes les sessions, `user@.service` sera également arrêté, par défaut, à moins que l'utilisateur n'ait activé la fonction "lingering" [7]. Pour permettre aux utilisateurs d'exécuter des tâches à long terme même s'ils sont complètement déconnectés, la fonction "lingering" doit être activée pour eux. Consultez #Démarrage automatique des instances utilisateur systemd et loginctl(1) pour plus de détails.

## Dépannage

### Runtime directory '/run/user/1000' is not owned by UID 1000, as it should

    systemd[1867]: pam_systemd(systemd-user:session): Runtime directory '/run/user/1000' is not owned by UID 1000, as it should.
    systemd[1867]: Trying to run as user instance, but $XDG_RUNTIME_DIR is not set

Si vous consultez des erreurs de ce type et que votre session de connexion est interrompue, il est possible qu'un autre service système (non utilisateur) sur votre système crée ce répertoire. Cela peut se produire par exemple si vous utilisez un conteneur docker qui a un montage bind sur `/run/user/1000`. Pour résoudre ce problème, vous pouvez soit réparer le conteneur en supprimant le montage, soit désactiver/retarder le service docker.

## Voir aussi

- Le wiki Bitbucket de KaiSforza
- Les unités de Zoqaeski sur GitHub
- Fil du forum Arch sur les changements dans les instances utilisateur de systemd 206

Category:

- System administration (Français)