diff --git a/scripts/atuq-nested.sh b/scripts/atuq-nested.sh index c16b6dbd..d6371c98 100755 --- a/scripts/atuq-nested.sh +++ b/scripts/atuq-nested.sh @@ -41,6 +41,7 @@ RAICES="atuq gcc-libs gtk3 atk gdk-pixbuf-shared pango-shared cairo-shared libep libxml2-shared dejavu-fonts bzip2-shared expat-shared ncurses-shared libsndfile libudev-zero zstd dbus-shared libnotify + ffmpeg libva xkeyboard-config grim" # ⚠ `gcc-libs` FALTABA, y su ausencia hacía MENTIR a esta prueba entera (2026-09-07). `atuq` declara # `NEEDED libstdc++.so.6` y `libgcc_s.so.1` —lo hereda de firefox, que va con clang++ y la libstdc++ @@ -59,6 +60,15 @@ RAICES="atuq gcc-libs gtk3 atk gdk-pixbuf-shared pango-shared cairo-shared libep # `libdbus-1.so.3` lo pide pipewire y NO lo trae `dbus` sino `dbus-shared`, el mismo cuadro de las # variantes `-shared` de gtk3. Mantener esta lista a mano es lo que falla: por eso ahora hay un # guardián que la audita en vez de confiar en que alguien se acuerde. +# `ffmpeg` y `libva` entran el 2026-09-07 y NO son recetas nuevas: las dos estaban selladas en el +# corpus y ya viven en la CLAUSURA de los cuatro escritorios, arrastradas por `mpv`. Lo que faltaba +# era esta lista, o sea otra vez el instrumento. Firefox abre `libavcodec.so.<53..63>` por `dlopen` +# literal —está en las cadenas de `libxul.so`— y nuestro ffmpeg 7.1 publica `libavcodec.so.61`, o +# sea H.264/AAC por software. Sin estas dos raíces el runner mide un rootfs MÁS POBRE que la imagen +# y reporta un hueco que la imagen no tiene. Ver SDD 26 §6.10. +# ⚠ `libva` va por simetría con la imagen, no porque encienda VA-API: las tres mesa construyen con +# `-Dgallium-va=disabled -Dvideo-codecs=`, así que el cargador está y no hay UN SOLO driver +# (`*_drv_video.so`) que cargar. Es media función, como libnotify sin daemon. # `grim` no lo necesita atuq: lo necesita QUIEN LO MIRA. Con `CAPTURA=` este script # saca la pantalla real desde dentro de la jaula, contra el mismo socket wayland. Es lo que separó # «el proceso vive» de «la ventana muestra lo que queremos»: durante horas dije «mirá tu pantalla» @@ -89,21 +99,42 @@ done [ -z "$faltan" ] || { echo "✗ faltan artefactos:$faltan" >&2; exit 1; } SELLO="$RFS/.raices" -if [ "${REHIDRATAR:-0}" = "1" ] || [ ! -f "$SELLO" ] || [ "$VIGENTES" != "$(cat "$SELLO")" ]; then +# ⚠ LOS DOS LADOS DE LA COMPARACIÓN TIENEN QUE PASAR POR LA MISMA TRITURADORA. `$VIGENTES` termina +# en `\n` y `$(cat …)` RECORTA los `\n` finales ⇒ comparados en crudo NUNCA son iguales y el rootfs +# se rehidrataba entero en CADA corrida (3013 ficheros), diciendo «DESACTUALIZADO» aunque estuviera +# perfecto. La caché existía y no cacheaba nada; medido 2026-09-07. Metiendo el de la izquierda en +# otra sustitución de comandos, los dos pierden el mismo `\n` y la comparación vuelve a significar +# lo que dice. +if [ "${REHIDRATAR:-0}" = "1" ] || [ ! -f "$SELLO" ] || [ "$(printf '%s' "$VIGENTES")" != "$(cat "$SELLO")" ]; then # Nada de `diff <(...)`: esto es /bin/sh, y la sustitución de proceso es de bash. Un script que # sólo funciona cuando /bin/sh resulta ser bash es una trampa que salta en otra máquina. [ -f "$SELLO" ] && echo "==> el rootfs está DESACTUALIZADO — se rehidrata" echo "==> hidratando $(echo $RAICES | wc -w) raíces en $RFS" rm -rf "$RFS"; mkdir -p "$RFS" + # ⚠ ESTE BUCLE SALÍA 1 SIEMPRE, Y CON `set -e` MATABA EL SCRIPT SIN IMPRIMIR NADA (2026-09-07). + # `$VIGENTES` termina en `\n` y `echo` agrega otro ⇒ la última vuelta lee la línea VACÍA, el + # `[ -n "$d" ]` da 1, ése es el estado de la última vuelta, ése es el estado del `while`, ése es + # el del pipeline, y `set -e` sale. Justo DESPUÉS de hidratar bien las 41 raíces: la única señal + # era `exit=1` tras «==> hidratando». No se veía porque esta rama sólo corre cuando cambian los + # hashes —con el sello al día el script ni entra—, así que el bug vivía escondido detrás de la + # caché. Lo destapó agregar `ffmpeg` a las raíces. Ahora: `continue` en la vacía, y un `hydrate` + # que falla GRITA en vez de dejar un rootfs a medias con el sello sin escribir. echo "$VIGENTES" | while read -r d; do - [ -n "$d" ] && "$H" --store "$STORE" hydrate "${d%%-*}" --into "$RFS" >/dev/null - done + [ -n "$d" ] || continue + "$H" --store "$STORE" hydrate "${d%%-*}" --into "$RFS" >/dev/null || { + echo "✗ hydrate falló en $d" >&2; exit 1; } + done || exit 1 printf '%s' "$VIGENTES" > "$SELLO" echo "==> hidratado: $(find "$RFS" -type f | wc -l) ficheros" else echo "==> rootfs al día ($(echo "$VIGENTES" | grep -c . ) raíces, hashes vigentes)" fi +# `ROOTFS_ONLY=1` corta acá: deja el rootfs hidratado y al día, y no abre ventana ni pide pantalla. +# Lo usa `scripts/test-atuq-codecs.sh`, que corre headless y necesita el MISMO árbol que esta +# ventana — duplicar la lista de raíces en dos scripts es exactamente cómo se desincronizan. +[ "${ROOTFS_ONLY:-0}" = "1" ] && exit 0 + [ -n "${WAYLAND_DISPLAY:-}" ] || { echo "✗ no hay WAYLAND_DISPLAY — esto necesita una pantalla" >&2; exit 1; } SOCK="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/$WAYLAND_DISPLAY" [ -S "$SOCK" ] || { echo "✗ no existe el socket $SOCK" >&2; exit 1; }