Conteneur et interface graphique

Published: 25-01-2015

Updated: 05-10-2016

By: Maxime de Roucy

tags: nspawn xorg

X11

Sources :

Il est possible d’utiliser des outils graphiques dans un nspawn, voire lancer une session utilisateur. Il n’est pas possible de lancer un serveur X dans un nspawn. En revanche il est possible d’indiquer au application tournant dans le conteneur de s’afficher dans un serveur X distant (hébergé sur l’hote)… du « X forwarding » via export DIPSPLAY=:….

Pour afficher les applications du conteneur dans une fenetres séparée j’utilise Xephyr (fourni par le paquet xorg-server-xephyr sur Archlinux) qui en gros lance une serveur X dans une fenêtre du serveur principal (X11 ou Wayland).

max@laptop % Xephyr -screen 800x600 :1

Gnome

Il est possible d’avoir une session gnome complète tournant dans un nspawn et s’affichant sur un serveur X distant. Deux techniques :

Sur une Debian il est possible de faire une installation minimaliste de Gnome via le paquet gnome-core.

gnome-session

Sources :

Lancer Xephyr sur la machine hôte.

max@laptop % Xephyr -terminate -screen 800x600 :1

Démarrage du nspawn et ajout de l’utilisateur non privilégié « max » qui servira pour lancer les applications graphiques (ici je suis sur une debian). Authentification en temps que « max » et lancement de la session graphique.

root@laptop # systemd-nspawn -b -D nspawn-name
…
debian login: root
Mot de passe : 
…
root@nspawn # adduser max
root@nspawn # logout
…	
debian login: max
Mot de passe : 
…
max@laptop % DISPLAY=:1 gnome-session

Il peut aussi être intéressant de désactiver gdm dans le nspawn étant donné que nous ne nous en servons pas.

root@nspawn # systemctl disable gdm.service
root@nspawn # systemctl stop gdm.service

gdm

Sources :

gdm peut être lancer en temps que serveur XDMCP autonome (sans serveur X local).

Il faut modifier le fichier de configuration de gdm (/etc/gdm3/daemon.conf ou /etc/gdm/custom.conf suivant la distribution) dans le nspawn et ajouter :

[xdmcp]
Enable=true
ShowLocalGreeter=false
PingIntervalSeconds=0

En théorie cela devrais fonctionné normalement mais le bug 743440 empéche gdm de prendre en compte le paramètre ShowLocalGreeter. Le patch correctif résout le problème mais tant que celui-ci n’aura pas été accépté et intégré vous devrez générer et installer un nouveau packet incluant le patche.

Note : Avec un gdm non patché le démon va essayé de démarré un serveur X dans le nspawn et va échoué. Il ne crashera pas pour autant et vous pourrez tous de même l’utiliser en XDMCP. Vous trouverez juste des erreurs lié au démarrage de X échoué dans les logs.

Une fois que vous avez un gdm configuré tournant dans votre nspawn, vous pouvez vous y connecter depuis votre machine hôte via la commande suivante.

max@laptop % Xephyr -query localhost -terminate -screen 800x600 :1

Wayland

Pour une application X11 on lancait un serveur sur la machine hôte puis on déportait l’affichage de l’application s’exécutant sur le guest vers ce nouveau serveur. Avec Wayland j’utilise une technique un peu différente. Je lance le serveur à l’intérieur du guest (rappel: il n’est pas possible de lancé un serveur X à l’interieur du guest).

Pour lancer un environment Wayland à l’interieurs d’un autre environment graphique j’ai utilisé weston (l’implémentation de référence de Wayland).

Pour lancer weston à l’interieur d’un serveur X :

max@laptop % env --unset=WAYLAND_DISPLAY DISPLAY=:0 weston

Pour lancer weston à l’interieur d’un autre serveur wayland :

max@laptop % WAYLAND_DISPLAY=wayland-0 weston --socket=test

Ici weston (lui-même un serveur wayland) est lancé dans le serveur wayland attaché à la socket (fichier, pour l’instant wayland ne support pas les sockets réseau) « wayland-0 ». C’est la socket principal, j’aurai donc pu enlever l’instruction WAYLAND_DISPLAY=wayland-0, le résultat aurrait été le même. La socket associé à weston s’appel « test » et est placé dans le dossier XDG_RUNTIME_DIR (/run/user/1000/ chez moi). Sans l’option --socket weston créé une socket nommé « wayland-X » ou X égal 0,1,2…

WAYLAND_DISPLAY peut être utilisé avec n’importe qu’elle autre application compatible wayland.

Comme wayland utilise une socket locale pour communiquer je dois faire en sorte qu’elle soit partagée entre le guest et l’hôte.

max@laptop % sudo systemd-nspawn --bind=/run/user/1000:/xdg-wayland -b -x -M arch-64-test -D /var/lib/machines/arch-64
…
[root@arch-64-test ~]# pacman -Syu
…
[root@arch-64-test ~]# pacman -S weston
…
[root@arch-64-test ~]# useradd -m max
[root@arch-64-test ~]# reboot
…
[root@arch-64-test ~]# su - max
[max@arch-64-test ~]$ XDG_RUNTIME_DIR=/xdg-wayland WAYLAND_DISPLAY=wayland-0 weston --socket=test

L’interface weston apparait sur l’hôte.

Dans le conteneur, j’ai eu besoins de spécifier WAYLAND_DISPLAY=wayland-0 et --socket=test sinon weston ne fonctionné pas.

test non fonctionnel

Avant d’essayé la méthode décrite ci-dessus j’ai essayé de lancer weston sur la machine hôte. Ça fonctionne à peu près mais ça peut poser problème :

max@laptop % weston --socket=test &> /dev/null &
max@laptop % sudo systemd-nspawn --bind=/run/user/1000/ -b -x -M arch-64-test -D /var/lib/machines/arch-64
…
[root@arch-64-test ~]# pacman -Syu
…
[root@arch-64-test ~]# pacman -S gnome-terminal
…
[root@arch-64-test ~]# useradd -m max
[root@arch-64-test ~]# reboot
…
[root@arch-64-test ~]# su - max
[max@arch-64-test ~]$ XDG_RUNTIME_DIR=/run/user/1000/ WAYLAND_DISPLAY=test gnome-terminal

Une fenetre « gnome-terminal » s’affiche effectivement dans weston. Cependant, le programe gnome-terminal est executé sur l’hôte et non sur le guest. Si j’installe et lance weston à l’interieur du guest, weston tourne bien dans le guest et non dans l’hôte. Le fonctionnement observé avec gnome-terminal est donc dû au fonctionnement de l’application (communication dbus à un serveur de terminal), mais ça peut être sournois…

Avec la méthode précédente ce genre de problème n’est pas possible.