#!/bin/sh # sway-headless.sh — arranca el perfil escritorio-sway SIN QEMU, SIN kernel y SIN imagen de disco, y # captura la pantalla con grim. Hermano de sway-start.sh (que arranca dentro de la VM); éste corre el # cierre hidratado dentro de un `bwrap` sobre la máquina de desarrollo. # # PARA QUÉ. Validar «el escritorio dibuja» costaba armar un product-rootfs + imagen EFI + arranque en # QEMU: ~40 min por vuelta y hace falta un `takana bootstrap product` que hoy no está en el store. # Headless da la misma evidencia —píxeles reales, dibujados por NUESTROS binarios— en ~2 min, así que # el ciclo de diagnóstico deja de ser el cuello de botella. NO sustituye al arranque en QEMU: no prueba # kernel, ni initramfs, ni DRM, ni el PID1. Prueba el compositor y sus clientes, que es justo lo que # el arranque en VM tapa detrás de una pantalla negra. # # INVOCACIÓN (desde la raíz del repo, con work/sway-rootfs ya hidratado): # mkdir -p /tmp/sway-out # bwrap --bind work/sway-rootfs / --bind /usr/lib/musl /usr/lib/musl \ # --bind /tmp/sway-out /salida --dev /dev --proc /proc --tmpfs /run --tmpfs /tmp \ # --unshare-user --uid 0 --gid 0 --setenv PATH /usr/bin:/bin:/usr/sbin:/sbin \ # /bin/sh /sway-headless.sh # # ── LO QUE EL CIERRE 121/121 NO TRAE Y HAY QUE INYECTAR ──────────────────────────────────────── # Medido el 2026-08-26 sobre el perfil COMPLETO. Nada de esto lo aporta la clausura: # · libz.so.1 / libexpat.so.1 / libffi.so.8 — sway salió DINÁMICO contra ellas y el corpus sólo # produce los `.a`. `libz.so.1` está como artefacto aparte (`zlib-shared`); las otras dos hoy # sólo existen en `.dev-fs/alpine`. Sin ellas sway ni arranca: «Error relocating /usr/bin/sway: # XML_ParserFree: symbol not found». # · /etc/passwd — sin él yambar hace getpwuid y falla. (`fonts.conf` NO hace falta: lo trae el # propio artefacto de fontconfig; el problema eran las fuentes, no su configuración.) # # YA NO hace falta inyectar `xkeyboard-config` ni `dejavu-fonts`: desde el 2026-08-26 están # DECLARADAS como raíces de `escritorio-sway` y las recetas viven en `recipes/incoming-wlr/`. Antes # existían sólo en las colas de kde/gnome/cosmic, así que el perfil no las alcanzaba y el escritorio # arrancaba sin datos XKB y sin una sola fuente. Prueba de que la declaración es equivalente a la # inyección manual: la captura resultante es **bit a bit idéntica**, mismo sha256. # # ── BASH NO CORRE EN ESTE ROOTFS, Y ASÍ ES COMO SE VE ────────────────────────────────────────── # `/bin/bash` está enlazado dinámico contra ncurses y el corpus sólo produce `libncurses.a`: # Error relocating /bin/bash: tgetent: symbol not found # El síntoma NO fue un error de bash. Fue que `foot` abría, sway registraba «New xdg_shell toplevel» # —o sea la ventana EXISTÍA en el árbol— y la captura salía con UN SOLO COLOR, el de swaybg: foot # lanzaba el shell, el shell moría al instante y la ventana se cerraba antes del frame. Por eso acá # el shell es busybox, que sí es autosuficiente. # # ── LA EVIDENCIA ES CONTAR COLORES, NO LEER EL LOG ───────────────────────────────────────────── # El log entero puede estar en verde con la pantalla vacía. La medida que no se puede falsear: # 1 color = sólo el fondo de swaybg ⇒ NINGÚN cliente dibujó (aunque el árbol los liste) # ~380 = terminal con texto ⇒ #242424 fondo de foot, #285577/#4c7899 bordes de sway, # #d0d0d0 el texto. ESO es un escritorio dibujando. export XDG_RUNTIME_DIR=/run/user/0 mkdir -p "$XDG_RUNTIME_DIR"; chmod 700 "$XDG_RUNTIME_DIR" export WLR_BACKENDS=headless export WLR_HEADLESS_OUTPUTS=1 export WLR_RENDERER=pixman export XDG_CONFIG_HOME=/root/.config export SHELL=/bin/bash export LANG=C export HOME=/root ( i=0 while [ ! -S /run/user/0/wayland-1 ] && [ $i -lt 40 ]; do sleep 1; i=$((i+1)); done [ -S /run/user/0/wayland-1 ] || { echo "!! el socket wayland nunca apareció"; exit 1; } export WAYLAND_DISPLAY=wayland-1 echo "== socket listo, lanzando clientes" /usr/bin/swaybg -c '#1a4b8c' & sleep 2 # bash NO corre en este rootfs: está enlazado dinámico contra ncurses y el corpus sólo produce # libncurses.a ⇒ «Error relocating /bin/bash: tgetent: symbol not found». foot lanzaba el shell, # el shell moría al instante y foot cerraba la ventana: el toplevel APARECÍA en el árbol de sway # y la captura salía 100% del color de swaybg. Se usa busybox, que sí es autosuficiente. /usr/bin/foot -- /bin/busybox sh -c ' echo " hammer — distro reproducible desde fuente" echo echo " compositor : sway 1.10 / wlroots 0.18.2" echo " terminal : foot 1.27.0" echo " libc : musl toolchain: zig cc" echo /bin/busybox uname -a echo echo " binarios en /usr/bin: $(/bin/busybox ls /usr/bin | /bin/busybox wc -l)" /bin/busybox sleep 60' >/salida/foot.log 2>&1 & sleep 12 echo "== capturando" /usr/bin/grim /salida/captura.png 2>&1 && echo "== grim OK: $(ls -l /tmp/captura.png)" sleep 1 /usr/bin/swaymsg exit 2>/dev/null ) & exec /usr/bin/sway -d 2>&1