diff --git a/recipes/incoming-gnome/gdm.toml b/recipes/incoming-gnome/gdm.toml index a69bba85..12a8aec5 100644 --- a/recipes/incoming-gnome/gdm.toml +++ b/recipes/incoming-gnome/gdm.toml @@ -5,6 +5,19 @@ # arje-logind-compat (D-Bus, ya sellado). gdm se apoya en ESE login1. Por eso -Dsystemd=false y el # soporte de sesión va por el shim. (NO es frontera: login1 está cubierto.) # Feature-minimal: plymouth/selinux/systemd-journal off; Wayland-only (sin X11). El greeter es GNOME. +# +# ── 🧱 BLOQUEADA POR GTK3, QUE ESTÁ APARCADO POR DISEÑO (medido 2026-08-07) ───────────────────── +# Las TRES recetas que quedaban en deuda en la granja (gnome-session, gnome-settings-daemon, gdm) +# NO son tres problemas: son UNO. Todas mueren en GTK3, que es una de las tres deudas que el frente +# GNOME aparcó a propósito (GTK3 / X11 / PAM). Verificado contra el `meson.build` de cada tag: +# · gnome-session 48.0 → `gtk_dep = dependency('gtk+-3.0')` en el nivel superior, sin `if`. +# · gnome-settings-daemon 48.1→ gtk+-3.0 **y `gtk+-x11-3.0`**, ambos incondicionales ⇒ bloqueada +# por DOS de las tres deudas aparcadas, no por una. +# · gdm 48.0 → su gtk+-3.0 sí es condicional (`if have_xdmcp`, y xdmcp es opción), +# pero da igual: depende de gnome-session y muere construyéndola. +# ⇒ No reintentar estas tres esperando que cambie algo. Se destraban el día que entre GTK3 (y para +# gnome-settings-daemon, también X11), no antes. Es una decisión de alcance, no un fallo. + name = "gdm" version = "48.0" license = "GPL-2.0-or-later" diff --git a/recipes/incoming-gnome/gnome-session.toml b/recipes/incoming-gnome/gnome-session.toml index 6a0c06be..a0e1291c 100644 --- a/recipes/incoming-gnome/gnome-session.toml +++ b/recipes/incoming-gnome/gnome-session.toml @@ -5,6 +5,10 @@ # Esta distro NO usa systemd: el login1 lo provee arje-logind-compat (D-Bus), el init es arje-zero. # Feature-minimal: -Dsystemd=false -Dsystemd_journal=false (sin dep de libsystemd), docs/man off. # gnome-session usa gtk4 para el diálogo de fallo ("failwhale") y json-glib para el perfil de sesión. +# +# ⛔ APARCADA: el diagnóstico completo está más abajo, junto a `[deps]` (GTK3 **y** libsystemd, los +# dos incondicionales). Lo confirmado el 2026-08-07 no lo cambia; sólo añade que la granja seguía +# reintentándola, que es un problema de COLA, no de receta. name = "gnome-session" version = "48.0" license = "GPL-2.0-or-later" @@ -19,7 +23,19 @@ target = "x86_64-linux-musl" link = "static" [build.phases] -configure = "PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload --prefer-static -Ddefault_library=static -Dsystemd=false -Dsystemd_journal=false -Ddocbook=false -Dman=false -Dc_args=-Wno-error=date-time" +# ── `-Dsystemd=false -Dsystemd_journal=false` NO EXISTEN en 48.0 y mataban el build ──────────── +# Fallaba con `meson.build:1:0: ERROR: Unknown option: "systemd"`. Comprobado contra el +# `meson_options.txt` del tag 48.0, las opciones REALES son exactamente seis: +# deprecation_flags · session_selector · systemduserunitdir · docbook · man · x11 +# O sea que el soporte de systemd dejó de ser una perilla booleana; lo único que queda de systemd es +# `systemduserunitdir`, que es una RUTA, no un interruptor. Pasar perillas que no existen no es +# inofensivo: meson aborta en la primera, así que la receta nunca llegó a configurar. +# ⇒ Lección: una opción `-D` inventada no se ignora, mata el build. Verificar contra el +# `meson_options.txt` DEL TAG que la receta pinea, no contra la memoria de otra versión. +# +# `-Dx11=false`: la imagen es Wayland pura y el default de esa opción es `true`, que arrastraría la +# torre de X11 que deliberadamente no tenemos (ver la deuda aparcada de GTK3/X11/PAM del frente). +configure = "PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload --prefer-static -Ddefault_library=static -Dx11=false -Ddocbook=false -Dman=false -Dc_args=-Wno-error=date-time" compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output" install = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild" diff --git a/recipes/incoming-gnome/gnome-settings-daemon.toml b/recipes/incoming-gnome/gnome-settings-daemon.toml index d883ec62..fb833daf 100644 --- a/recipes/incoming-gnome/gnome-settings-daemon.toml +++ b/recipes/incoming-gnome/gnome-settings-daemon.toml @@ -17,6 +17,19 @@ # NO BLOQUEA EL ESCRITORIO: gnome-shell no depende de g-s-d ni en build ni para arrancar; sin él la # sesión sube y lo que se pierde son las teclas de medios, la gestión de energía y el perfil de color # (los aplica este daemon, no el shell). Es degradación, no ausencia de escritorio. +# +# ── 🧱 BLOQUEADA POR GTK3, QUE ESTÁ APARCADO POR DISEÑO (medido 2026-08-07) ───────────────────── +# Las TRES recetas que quedaban en deuda en la granja (gnome-session, gnome-settings-daemon, gdm) +# NO son tres problemas: son UNO. Todas mueren en GTK3, que es una de las tres deudas que el frente +# GNOME aparcó a propósito (GTK3 / X11 / PAM). Verificado contra el `meson.build` de cada tag: +# · gnome-session 48.0 → `gtk_dep = dependency('gtk+-3.0')` en el nivel superior, sin `if`. +# · gnome-settings-daemon 48.1→ gtk+-3.0 **y `gtk+-x11-3.0`**, ambos incondicionales ⇒ bloqueada +# por DOS de las tres deudas aparcadas, no por una. +# · gdm 48.0 → su gtk+-3.0 sí es condicional (`if have_xdmcp`, y xdmcp es opción), +# pero da igual: depende de gnome-session y muere construyéndola. +# ⇒ No reintentar estas tres esperando que cambie algo. Se destraban el día que entre GTK3 (y para +# gnome-settings-daemon, también X11), no antes. Es una decisión de alcance, no un fallo. + name = "gnome-settings-daemon" version = "48.1" license = "GPL-2.0-or-later" diff --git a/scripts/build-farm.sh b/scripts/build-farm.sh index aeba93d3..e3431b1d 100755 --- a/scripts/build-farm.sh +++ b/scripts/build-farm.sh @@ -35,6 +35,30 @@ rm -rf "$FARM"; mkdir -p "$FARM/log" "$FARM/status" queue=$(ls "$QUEUE"/*.toml 2>/dev/null || true) [ -n "$queue" ] || { echo "cola vacía: $QUEUE/*.toml"; exit 0; } + +# ── NO REHACER LO QUE EL HUB YA SELLÓ ────────────────────────────────────────────────────────── +# `farm-sync.sh` sincroniza el store en UN SOLO SENTIDO: sube el código EXCLUYENDO /store y baja el +# store del worker. O sea que el worker nunca recibe los artefactos que se sellan en el hub — y por +# tanto reintenta cada ciclo, y vuelve a fallar, trabajo que YA ESTÁ HECHO. Medido el 2026-08-07: +# de 20 «fallos» de incoming-gnome, 17 correspondían a recetas con artefacto vigente en el hub. +# No eran marcadores rancios (el status se borra en cada ciclo): era CPU quemada de verdad. +# +# Mandarle los artefactos costaría gigabytes por un enlace de 8 Mbps. Mandarle la LISTA cuesta unos +# kilobytes: `work/farm-sellados.txt` son los nombres `-` del store del hub. Si el +# hash vigente de una receta está ahí, el hub ya la tiene y el worker se la salta. +SELLADOS="${SELLADOS:-work/farm-sellados.txt}" +if [ -s "$SELLADOS" ]; then + saltadas=0; filtrada="" + for f in $queue; do + n=$(basename "$f" .toml) + H=$("$HAMMER" --store "$STORE" hash "$f" 2>/dev/null | tail -1 | sed 's/^b3://') + if [ -n "$H" ] && grep -qx "$H-$n" "$SELLADOS"; then saltadas=$((saltadas+1)); continue; fi + filtrada="$filtrada $f" + done + [ "$saltadas" -gt 0 ] && echo " (saltadas $saltadas ya selladas en el hub — ver la nota del sync unidireccional)" + queue="$filtrada" + [ -n "$(echo $queue)" ] || { echo "nada que hacer en $QUEUE: todo sellado en el hub"; exit 0; } +fi n_total=$(printf '%s\n' "$queue" | wc -l | tr -d ' ') echo "==> GRANJA: $n_total recetas en $QUEUE, $JOBS workers en paralelo" diff --git a/scripts/farm/farm-sync.sh b/scripts/farm/farm-sync.sh index 36e6ec50..6e49123a 100755 --- a/scripts/farm/farm-sync.sh +++ b/scripts/farm/farm-sync.sh @@ -19,8 +19,18 @@ ROOT="$(cd "$(dirname "$0")/../.." && pwd)" cd "$ROOT" SSH="ssh -i $SSH_KEY -o StrictHostKeyChecking=accept-new" +# El MANIFIESTO de lo ya sellado en el hub, para que el worker no rehaga trabajo hecho. Es la otra +# mitad del arreglo del sync unidireccional (ver la nota en `scripts/build-farm.sh`): el store no +# viaja hub→worker porque son gigabytes, pero la lista de nombres son kilobytes y evita que el worker +# reintente y falle cada ciclo lo que el hub ya tiene. Se regenera acá, en cada sync, para que no se +# quede vieja sola. +mkdir -p work +ls ./store 2>/dev/null | grep -E '^[0-9a-f]{64}-' > work/farm-sellados.txt || true +echo "==> 0. manifiesto de sellados del hub: $(wc -l < work/farm-sellados.txt) artefactos" + echo "==> 1. subiendo código + cola al worker ($VPS:$REMOTE)" rsync -az --delete -e "$SSH" \ + --include '/work/' --include '/work/farm-sellados.txt' \ --exclude /work --exclude /store --exclude '/store-*' --exclude /target \ --exclude /dist --exclude /.dev-fs --exclude /.git --exclude /.scratch \ --exclude '*.png' --exclude '/content*' \ diff --git a/scripts/respaldo-storagebox.sh b/scripts/respaldo-storagebox.sh index fd9135cb..a1c3952f 100755 --- a/scripts/respaldo-storagebox.sh +++ b/scripts/respaldo-storagebox.sh @@ -103,11 +103,23 @@ reintentar() { done } -if ! $SSH_CMD "$SB_USER@$SB_HOST" 'df -h .' >/dev/null 2>&1; then - echo "!! No hay SSH al Storage Box ($SB_HOST:$SB_PORT)." - echo "!! Si acabás de crearlo, el DNS tarda unos minutos en propagar. Reintentá." - exit 1 -fi +# ── LA COMPROBACIÓN INICIAL TAMBIÉN REINTENTA ────────────────────────────────────────────────── +# Era un `if` de un solo intento, y el 2026-08-07 tiró la corrida al relanzar el respaldo justo al +# llegar a casa: el wifi todavía no había levantado, el `ssh` falló una vez y el script se rindió con +# «no hay SSH» — cuando medio minuto después conectaba perfecto. Es el peor momento para rendirse: +# quien relanza un respaldo interrumpido acaba de cambiar de red, así que el hipo es LO ESPERABLE. +# Mismo criterio que el bucle de transferencia: insistir es barato, rendirse cuesta una noche. +intento=1 +until $SSH_CMD "$SB_USER@$SB_HOST" 'df -h .' >/dev/null 2>&1; do + if [ "$intento" -ge 20 ]; then + echo "!! No hay SSH al Storage Box ($SB_HOST:$SB_PORT) tras 20 intentos." + echo "!! Si acabás de crearlo, el DNS tarda unos minutos en propagar." + exit 1 + fi + echo ".. sin SSH al box todavía (¿red recién levantada?). Intento $intento; reintento en 15s." + intento=$((intento + 1)) + sleep 15 +done echo "==> destino: $SB_USER@$SB_HOST:$SB_PORT ${SECO:+(SECO)}" $SSH_CMD "$SB_USER@$SB_HOST" 'mkdir hammer hammer/store hammer/repo hammer/estado' >/dev/null 2>&1 || true