From d79299d351e7be838d69a836e2bd3d13046636b8 Mon Sep 17 00:00:00 2001 From: Sergio Date: Mon, 14 Sep 2026 14:12:31 +0000 Subject: [PATCH] =?UTF-8?q?granja:=20cuatro=20sondas=20quedaron=20ciegas?= =?UTF-8?q?=20tras=20el=20renombre=20=E2=80=94=20el=20informe=20dec=C3=ADa?= =?UTF-8?q?=20=C2=ABidle=C2=BB=20compilando?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Todas buscaban el proceso `release/hammer`, y desde el ADR 0016 el worker invoca `./target/release/takana`. Ninguna daba error: simplemente no encontraban nada. Medido hoy, no deducido: `estado-granja.sh` imprimía «moliendo: (nada — idle o entre colas)» mientras en el worker corría `./target/release/takana --store ./store build recipes/centrifugo.toml`. Leyendo ese informe se concluye que la granja está seca. Tras el arreglo, el mismo informe dice «moliendo: cilium-cli.toml» y `pgrep` allá confirma exactamente ese proceso. Las cuatro: · estado-granja.sh «moliendo» — mentía sobre si hay trabajo · farm-worker-loop.sh×2 detección de build en vuelo · deadman.sh `hay_trabajo` — y acá el precio es un worker BORRADO a mitad de un build. En el LXC no llegó a morder (sólo borra cajas hcloud y su timer no está activo allá), pero la próxima caja de pago sí lo habría pagado. Se aceptan LOS DOS nombres: cargo sigue compilando `hammer` como alias, y una sonda que sólo mira el nombre nuevo se rompería con un worker que arrastre binario viejo — que es justo lo que pasa acá, porque la siembra excluye `/target`. Es el mismo renombre que dejó colgado el enlace de `go` (commit anterior). Un renombre no rompe sólo lo que compila: rompe las cadenas que alguien escribió a mano. --- scripts/farm/deadman.sh | 7 ++++++- scripts/farm/estado-granja.sh | 9 ++++++++- scripts/farm/farm-worker-loop.sh | 6 ++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/scripts/farm/deadman.sh b/scripts/farm/deadman.sh index fd3cb092..9fae7005 100644 --- a/scripts/farm/deadman.sh +++ b/scripts/farm/deadman.sh @@ -106,7 +106,12 @@ hay_trabajo() { # está SIEMPRE vivo (idle-loopea con la cola vacía) ⇒ contarlo como trabajo hacía que el worker # NUNCA acumulara ticks y NUNCA se matara — un worker con cola seca quedaba idle para siempre # (incidente 2026-07-23, 2ª vez). El loop construyendo YA se ve por su `takana build` hijo. - pgrep -f 'release/hammer.* build ' >/dev/null 2>&1 && { echo "hammer build en vuelo"; return 0; } + # ⚠ LOS DOS NOMBRES, y acá el precio de equivocarse es un worker BORRADO a mitad de un build: + # tras el renombre hammer→takana esta sonda no reconocía `./target/release/takana build`, o sea + # que `hay_trabajo` decía NO con el worker compilando. En el LXC no llegó a morder (el dead-man + # sólo borra cajas hcloud, y su timer ni siquiera está activo allá), pero la próxima caja de + # pago sí. `hammer` sigue compilándose como alias ⇒ se aceptan los dos. + pgrep -f 'release/(takana|hammer).* build ' >/dev/null 2>&1 && { echo "takana build en vuelo"; return 0; } pgrep -f 'campana-deuda' >/dev/null 2>&1 && { echo "campaña deliberada en vuelo"; return 0; } # UNA TRANSFERENCIA TAMBIÉN ES TRABAJO (2026-08-09). Poblar el volumen con el store del hub son # horas de rsync durante las cuales no corre ningún `takana build` ⇒ el worker acumulaba ticks y diff --git a/scripts/farm/estado-granja.sh b/scripts/farm/estado-granja.sh index f4a3040f..84f16509 100755 --- a/scripts/farm/estado-granja.sh +++ b/scripts/farm/estado-granja.sh @@ -16,7 +16,14 @@ if [ -s "$FLEET" ]; then $SSH "root@$ip" ' echo " $(uptime | sed "s/.*load average/load/")" n=$(ls /opt/takana/store 2>/dev/null | wc -l); echo " store: $n artefactos" - b=$(pgrep -af "release/hammer" | grep -E "release/hammer (build|--store|hash)" | grep -oE "[^ /]+\.toml" | sort -u | tr "\n" " ") + # ⚠ LOS DOS NOMBRES. El renombre hammer→takana (ADR 0016) dejó esta sonda ciega: el worker + # invoca `./target/release/takana` y acá se buscaba `release/hammer`, así que «moliendo» + # decía «(nada — idle)» CON EL WORKER CONSTRUYENDO. Comprobado el 2026-09-14: el informe + # decía idle mientras allá corría `takana --store ./store build recipes/centrifugo.toml`. + # Un informe que miente sobre si hay trabajo es peor que no tenerlo — leyendo ese «idle» se + # concluye que la granja está seca. El binario `hammer` sigue existiendo (cargo lo compila + # como alias), así que se aceptan los dos. + b=$(pgrep -af "release/(takana|hammer)" | grep -E "release/(takana|hammer) (build|--store|hash)" | grep -oE "[^ /]+\.toml" | sort -u | tr "\n" " ") echo " moliendo: ${b:-(nada — idle o entre colas)}" ' 2>/dev/null || echo " ⚠ sin respuesta (¿dead-man lo mató? ¿aún arrancando?)" done < "$FLEET" diff --git a/scripts/farm/farm-worker-loop.sh b/scripts/farm/farm-worker-loop.sh index d72b25fd..c4a0d5f7 100755 --- a/scripts/farm/farm-worker-loop.sh +++ b/scripts/farm/farm-worker-loop.sh @@ -48,7 +48,9 @@ SUELO_FRIO_MIN="${SUELO_FRIO_MIN:-120}" # vendor`/resolve_phases (host-side, ANTES de que arranque el bwrap) el árbol no está bind-montado # ⇒ la protección 1 no lo cubre. Una tanda Go con árbol de deps enorme (dnscontrol/lazysql) tarda # minutos vendoreando; sin esto, el watchdog le borra el go.mod a mitad → "no build system". - building=$(pgrep -af 'release/hammer' 2>/dev/null | grep -oE '[^ ]+\.toml' | sed 's#.*/##;s#\.toml$##' | sort -u) + # los DOS nombres del binario: el renombre hammer→takana dejó esta sonda ciega (ver + # estado-granja.sh). `hammer` sigue compilándose como alias, así que se aceptan ambos. + building=$(pgrep -af 'release/(takana|hammer)' 2>/dev/null | grep -oE '[^ ]+\.toml' | sed 's#.*/##;s#\.toml$##' | sort -u) for d in work/sources/*/; do [ -d "$d" ] || continue; dd=${d%/} printf '%s\n' "$active" | grep -qxF "$dd" && continue @@ -88,7 +90,7 @@ SUELO_FRIO_MIN="${SUELO_FRIO_MIN:-120}" # protegidas). Por eso NO purgo las caches Go si hay CUALQUIER `takana build` en vuelo (no solo # un `go mod vendor` visible en este instante): difiero al próximo tick / al gap idle entre # ciclos. El sandbox `go install` usa GOCACHE=/src + -mod=vendor ⇒ no toca estas caches del host. - if pgrep -f 'go mod vendor' >/dev/null 2>&1 || pgrep -f 'release/hammer.* build ' >/dev/null 2>&1; then + if pgrep -f 'go mod vendor' >/dev/null 2>&1 || pgrep -f 'release/(takana|hammer).* build ' >/dev/null 2>&1; then echo "$(date -u +%FT%TZ) watchdog: disco ${use}% ≥ ${DISK_HIGH}% pero hay build en vuelo ⇒ difiero purga caches Go" else echo "$(date -u +%FT%TZ) watchdog: disco ${use}% ≥ ${DISK_HIGH}% ⇒ purgo caches Go"