Diverses commandes comme flatpak
, podman
, rpm-ostree
etc. ne peuvent pas vraiment être utilisées dans un conteneur OCI. Certains d'entre eux, comme podman
, peuvent avoir une utilisation limitée, mais, dans l'ensemble, les gens s'attendent à les exécuter directement sur l'hôte.
Dans le même temps, nous nous attendons à ce qu'un bon pourcentage d'utilisateurs de l'interface de ligne de commande passent la plupart de leur temps dans un conteneur de boîte à outils, et l'un des objectifs du projet Toolbox est de réduire la charge cognitive de l'utilisation de conteneurs mutables sur des fichiers verrouillés. des systèmes d'exploitation hôtes en panne et immuables comme Silverblue. Des commandes comme flatpak
et rpm-ostree
sont des outils importants pour l'interfaçage avec de tels systèmes d'exploitation.
Par conséquent, ce serait bien si nous pouvions fournir une expérience utilisateur meilleure que d'avoir à basculer entre un hôte et un shell de boîte à outils, ou d'avoir à préfixer chaque commande avec des choses comme flatpak-spawn --host
.
L'option la plus simple consiste à installer des alias dans le shell exécuté à l'intérieur du conteneur. Cependant, cela ne nous donne pas des choses comme les manuels et la complétion du shell.
Une autre option consiste à pré-installer les flatpak
, podman
, rpm-ostree
, etc. RPM dans les images de base fedora-toolbox
mais supprimer tout le code, laissant derrière seulement les manuels et l'achèvement du shell. Ensuite, la commande toolbox
peut placer les cales correspondantes via des montages de liaison pour transférer les appels à l'hôte lors du démarrage des conteneurs de la boîte à outils.
Cela garantira que les images fedora-toolbox
ne grossissent pas avec les binaires Go inutiles, et les wrappers peuvent être mis à jour via le package toolbox
sur l'hôte. L'un des avantages d'avoir des shims explicites sur les alias est que nous pouvons intercepter les cas extrêmes où les invocations de commandes ne peuvent pas être transmises à l'hôte. par exemple, ils peuvent impliquer un chemin qui n'est pas partagé entre l'hôte et le conteneur. Échouer avec un message d'erreur clair vaut mieux qu'un échec obscur ou des effets secondaires étranges.
Cependant, je ne sais pas ce qui se passera si l'un de ces packages est mis à jour à l'intérieur des conteneurs. Interféreraient-ils avec les cales montées sur la liaison ? Ce serait bien si nous pouvions supprimer les bits inutiles de ces packages pendant ou après la mise à jour du RPM.
Je pense que ce sera considérablement plus simple si nous ajoutons /usr/libexec/toolbox/bin
et modifions les scripts de démarrage du shell pour les injecter d'abord dans $PATH
.
L'exécution de podman dans la boîte à outils peut être extrêmement utile. Je travaille avec de nombreux projets où les scripts de construction appellent simplement des images docker, et pouvoir exécuter ces scripts dans la boîte à outils peut être très utile. Cela pourrait créer des problèmes difficiles à détecter avec les montages de liaison en dehors du répertoire de base qui refléteraient l'hôte silverblue et non la boîte à outils.
Je vais ajouter docker-compose
à la liste des choses utiles pour les flux de développement. Il a une très faible barrière à l'entrée pour tout ce qui a besoin d'un magasin de données ou deux, donc un bon nombre de choses de type application Web l'utilisent - open source et non.
Je construis une boîte FROM registry.fedoraproject.org/f31/fedora-toolbox:31
outils dérivée host-runner
dans /usr/local/bin/host-runner
$ cat /usr/local/bin/host-runner
#!/bin/bash
executable=$(basename $0)
set -x
exec flatpak-spawn --host $executable "$@"
Je crée ensuite un lien symbolique vers host-runner
pour tout ce que je veux exécuter dans le contexte hôte :
$ ls -l /usr/local/bin/
total 4
lrwxrwxrwx. 1 root root 13 Jan 28 14:16 chromium-browser -> ./host-runner
-rwxr-xr-x. 1 root root 89 Jan 31 10:39 host-runner
lrwxrwxrwx. 1 root root 13 Jan 29 10:51 podman -> ./host-runner
lrwxrwxrwx. 1 root root 13 Jan 28 12:39 systemctl -> ./host-runner
lrwxrwxrwx. 1 root root 13 Jan 28 12:39 virsh -> ./host-runner
lrwxrwxrwx. 1 root root 13 Jan 28 12:39 virt-install -> ./host-runner
REMARQUE : la liste des commandes qu'un utilisateur souhaite transmettre par proxy à l'hôte est probablement différente pour chaque utilisateur, nous devrions donc probablement simplement créer un moyen générique de la configurer, puis laisser les utilisateurs le faire eux-mêmes.
Vous exécutez ensuite les choses à partir de la boîte à outils, mais elles sont transmises par proxy à l'hôte. Le seul élément supplémentaire est que la commande réelle qui est exécutée est imprimée sur stderr avant d'être exécutée. Par exemple:
$ virsh list --all
+ exec flatpak-spawn --host virsh list --all
Id Name State
----------------------------------
43 f31_vanilla-f31 running
47 tester running
- fcos shut off
Nous pourrions fournir quelque chose comme ceci dans le conteneur de boîte à outils créé. Je peaufine encore un peu ça. Une chose qui ne fonctionne pas encore et à laquelle nous devrions réfléchir est ce qu'il faut faire si l'utilisateur souhaite exécuter la commande sur l'hôte en tant que sudo.
J'ai essayé de dupliquer cela, mais j'ai juste placé host-runner
dans ~/.local/bin
plutôt que de créer une nouvelle image .. et à cause d'être paresseux comme ça, j'ai eu
[user<strong i="8">@toolbox</strong> ~] podman ps
+ exec flatpak-spawn --host podman ps
+ exec flatpak-spawn --host podman ps
/var/home/user/.local/bin/podman: line 4: exec: flatpak-spawn: not found
Bien sûr, puisque ~/.local/bin
est dans le PATH sur l'hôte et le conteneur, host-runner a exécuté le lien symbolique podman dans ~/.local/bin
.. qui a exécuté host-runner sur l'hôte, mais flatpak-spawn était n'y est pas installé. Je n'ose pas penser à ce que la récursivité imbriquée se serait produite si c'était :wink:
Quoi qu'il en soit, je l'ai résolu en changeant
executable=$(basename $0)
à executable=/usr/bin/$(basename $0)
qui fonctionne assez bien pour le moment.
EDIT : Cela pose quelques autres problèmes. Par exemple, toolbox
sur l'hôte ne fonctionnera plus car il essaie d'appeler ~/.local/bin/podman
. Ma solution pour l'instant est d'avoir un chemin de bac séparé que je n'ajoute qu'à PATH dans mon conteneur de boîte à outils.
Utiliser flatpak-spawn --host
est une astuce sympa ! Voici une version pure sh* de ceci qui fonctionne dans ~/.local/bin
et évite la boucle infinie si vous exécutez accidentellement la commande directement :
#!/bin/sh
set -o errexit
set -o nounset
executable="$(basename "$0")"
if [ "$(basename "$(realpath "$0")")" = "${executable}" ]; then
echo "can't run ${executable} via ${executable}" >&2
exit 1
fi
# This seems like the best way to detect if we're inside a toolbox container.
if [ -n "${TOOLBOX_PATH:-}" ]; then
set -x
exec flatpak-spawn --host "${executable}" "$@"
fi
# Otherwise do a little dance to find the executable that would have run if not
# for $0 being on the path, and run that instead.
executable="$(
# Remove this script's directory from PATH; this assumes that you'll never want
# to run a sibling via this script.
dir="$(dirname "$0")"
PATH="$(echo "${PATH}" | sed "s+:${dir}:++")"
PATH="$(echo "${PATH}" | sed "s+${dir}:++")"
PATH="$(echo "${PATH}" | sed "s+:${dir}++")"
command -v "${executable}"
)"
exec "${executable}" "$@"
(Cela n'a pas été testé dans des cas d'exécution imbriqués étranges, bien que je pense que cela devrait fonctionner.)
*suppose que realpath
est disponible
Une autre option pourrait être de faire en sorte que podman dans le conteneur utilise toujours --remote
. Le socket du serveur d'API semble être visible dans un conteneur de boîte à outils.
Commentaire le plus utile
Je construis une boîte
FROM registry.fedoraproject.org/f31/fedora-toolbox:31
outils dérivéehost-runner
dans/usr/local/bin/host-runner
Je crée ensuite un lien symbolique vers
host-runner
pour tout ce que je veux exécuter dans le contexte hôte :REMARQUE : la liste des commandes qu'un utilisateur souhaite transmettre par proxy à l'hôte est probablement différente pour chaque utilisateur, nous devrions donc probablement simplement créer un moyen générique de la configurer, puis laisser les utilisateurs le faire eux-mêmes.
Vous exécutez ensuite les choses à partir de la boîte à outils, mais elles sont transmises par proxy à l'hôte. Le seul élément supplémentaire est que la commande réelle qui est exécutée est imprimée sur stderr avant d'être exécutée. Par exemple:
Nous pourrions fournir quelque chose comme ceci dans le conteneur de boîte à outils créé. Je peaufine encore un peu ça. Une chose qui ne fonctionne pas encore et à laquelle nous devrions réfléchir est ce qu'il faut faire si l'utilisateur souhaite exécuter la commande sur l'hôte en tant que sudo.