Varios comandos como flatpak
, podman
, rpm-ostree
etc. no se pueden utilizar realmente dentro de un contenedor OCI. Algunos de ellos, como podman
, pueden tener un uso limitado, pero, en general, la gente espera ejecutarlos directamente en el host.
Al mismo tiempo, esperamos que un buen porcentaje de usuarios de la interfaz de línea de comandos pasen la mayor parte de su tiempo dentro de un contenedor de caja de herramientas, y uno de los objetivos del proyecto Toolbox es reducir la carga cognitiva de usar contenedores mutables en bloqueado- sistemas operativos host inactivos e inmutables como Silverblue. Los comandos como flatpak
y rpm-ostree
son herramientas importantes para interactuar con dichos sistemas operativos.
Por lo tanto, sería bueno si pudiéramos brindar una experiencia de usuario que fuera mejor que tener que alternar entre un host y un shell de caja de herramientas, o tener que anteponer cada comando con cosas como flatpak-spawn --host
.
La opción más sencilla es instalar alias en el shell que se ejecuta dentro del contenedor. Sin embargo, no nos da cosas como manuales y finalización de shell.
Otra opción es preinstalar los RPM flatpak
, podman
, rpm-ostree
, etc. en las imágenes base fedora-toolbox
pero eliminar todo el código, dejando atrás sólo los manuales y la terminación del shell. Luego, el comando toolbox
puede colocar las calzas correspondientes a través de montajes de enlace para reenviar las llamadas al host cuando se inician los contenedores de la caja de herramientas.
Esto asegurará que las imágenes fedora-toolbox
no se agranden con binarios de Go inútiles, y los contenedores se pueden mantener actualizados a través del paquete toolbox
en el host. Una ventaja de tener shims explícitos sobre los alias es que podemos interceptar esos casos de esquina en los que las invocaciones de comandos no se pueden reenviar al host. por ejemplo, pueden implicar una ruta que no se comparte entre el host y el contenedor. Fallar con un mensaje de error claro es mejor que una falla oscura o efectos secundarios extraños.
Sin embargo, no sé qué pasará si uno de estos paquetes se actualiza dentro de los contenedores. ¿Interferirían con las calzas montadas en la unión? Sería bueno si pudiéramos recortar los bits inútiles de esos paquetes durante o después de actualizar el RPM.
Creo que será dramáticamente más simple si agregamos /usr/libexec/toolbox/bin
y cambiamos los scripts de inicio del shell para inyectar eso en $PATH
primero.
Ejecutar podman dentro de la caja de herramientas puede ser inmensamente útil. Trabajo con muchos proyectos en los que crear scripts es simplemente llamar imágenes de la ventana acoplable, y poder ejecutar esos scripts dentro de la caja de herramientas puede ser realmente útil. Sin embargo, puede crear problemas difíciles de detectar con los montajes de enlace fuera del directorio de inicio que reflejarían el host silverblue y no la caja de herramientas.
Agregaré docker-compose
a la lista de cosas útiles para los flujos de desarrollo. Tiene una barrera de entrada realmente baja para cualquier cosa que necesite un almacén de datos o dos, por lo que un buen número de aplicaciones web la usan, de código abierto y no.
Construyo una caja FROM registry.fedoraproject.org/f31/fedora-toolbox:31
herramientas derivada host-runner
en /usr/local/bin/host-runner
$ cat /usr/local/bin/host-runner
#!/bin/bash
executable=$(basename $0)
set -x
exec flatpak-spawn --host $executable "$@"
Luego creo un enlace simbólico a host-runner
para cualquier cosa que quiera ejecutar en el contexto del host:
$ 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
NOTA : la lista de comandos que un usuario quiere que se transfieran al host probablemente sea diferente para cada usuario, por lo que probablemente deberíamos crear una forma genérica de configurarlo y luego dejar que los usuarios lo hagan ellos mismos.
Luego, ejecuta las cosas desde dentro de la caja de herramientas, pero se transfiere al host. El único bit adicional es que el comando real que se ejecuta se imprime en stderr antes de que se ejecute. Por ejemplo:
$ virsh list --all
+ exec flatpak-spawn --host virsh list --all
Id Name State
----------------------------------
43 f31_vanilla-f31 running
47 tester running
- fcos shut off
Podríamos proporcionar algo como esto en el contenedor de caja de herramientas creado. Todavía estoy puliendo esto un poco. Una cosa que aún no funciona y en la que deberíamos pensar es qué hacer si el usuario quisiera ejecutar el comando en el host como sudo.
Traté de duplicar esto, pero coloqué host-runner
en ~/.local/bin
lugar de crear una nueva imagen ... y como resultado de ser tan vago obtuve
[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
Por supuesto, dado que ~/.local/bin
está en la RUTA en el host y el contenedor, host-runner ejecutó el enlace simbólico podman en ~/.local/bin
.. que ejecutó host-runner en el host, pero flatpak-spawn no no está instalado allí. No me atrevo a pensar qué habría sucedido la recursividad anidada si fuera: wink:
De todos modos lo resolví cambiando
executable=$(basename $0)
a executable=/usr/bin/$(basename $0)
que funciona bastante bien por ahora.
EDITAR : Esto causa algunos otros problemas. Por ejemplo, toolbox
en el host ya no funcionará mientras intenta llamar a ~/.local/bin/podman
. Mi solución por ahora es tener una ruta de bandeja separada que solo agrego a PATH en el contenedor de mi caja de herramientas.
¡Usar flatpak-spawn --host
es un truco genial! Aquí hay una versión sh * pura de esto que funciona en ~/.local/bin
y evita el bucle infinito si accidentalmente ejecuta el comando directamente:
#!/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}" "$@"
(Esto no se ha probado en casos de ejecución anidados extraños, aunque creo que debería funcionar).
* asume que realpath
está disponible
Otra opción podría ser hacer que podman dentro del contenedor siempre use --remote
. El socket para el servidor API parece estar visible dentro de un contenedor de caja de herramientas.
Comentario más útil
Construyo una caja
FROM registry.fedoraproject.org/f31/fedora-toolbox:31
herramientas derivadahost-runner
en/usr/local/bin/host-runner
Luego creo un enlace simbólico a
host-runner
para cualquier cosa que quiera ejecutar en el contexto del host:NOTA : la lista de comandos que un usuario quiere que se transfieran al host probablemente sea diferente para cada usuario, por lo que probablemente deberíamos crear una forma genérica de configurarlo y luego dejar que los usuarios lo hagan ellos mismos.
Luego, ejecuta las cosas desde dentro de la caja de herramientas, pero se transfiere al host. El único bit adicional es que el comando real que se ejecuta se imprime en stderr antes de que se ejecute. Por ejemplo:
Podríamos proporcionar algo como esto en el contenedor de caja de herramientas creado. Todavía estoy puliendo esto un poco. Una cosa que aún no funciona y en la que deberíamos pensar es qué hacer si el usuario quisiera ejecutar el comando en el host como sudo.