granja: el worker llevaba 5 días sin poder construir NINGUNA receta Go, en silencio

El enlace `~/.cargo/bin/go` del worker apuntaba a `/opt/hammer/.dev-fs/tools/go/bin/go`
— la ruta de ANTES del renombre a takana (ADR 0016, 2026-09-09). `/opt/hammer` ya no
existe, así que el enlace estaba COLGADO desde entonces.

Nada falló. `go` lo invoca takana DEL LADO DEL HOST (`go mod vendor` durante el fetch,
con red), fuera del sandbox, así que el rootfs no lo cubre — es el mismo modo de fallo
que `patch` en agosto, y `vps-setup.sh` ya lo tiene escrito como regla: «toda herramienta
que takana invoque HOST-SIDE va en esta lista». `go` no estaba.

Cómo se descubrió: por casualidad, verificando reproducibilidad. 16 de 25 recetas Go
murieron en SEGUNDOS. Un fallo sistémico se lee como 16 recetas rotas si nadie abre el
error — el verificador manda la salida del build a /dev/null. El error era
`spawn go mod vendor: No such file or directory (¿está `go` en el PATH del host?)`, que
lo decía todo.

Arreglado en el worker (enlaces repuestos a /opt/takana) y COMPROBADO con un build real:
`gron` no construía, ahora construye y reproduce bit a bit (why-differs: 5 entradas
idénticas, 0 divergen).

Acá va la parte que evita la repetición: el script daba «go enlazado ✓» sin comprobar
nada — `ln -sfn` crea un enlace colgado tan campante. Ahora repone un enlace colgado
preexistente (avisando) y comprueba que RESUELVE ejecutando `go version` A TRAVÉS DE ÉL;
si no ejecuta, sale 1 con el síntoma escrito. Un enlace que existe no es un `go` que corre.

Probado en los tres sentidos, con control que TIENE que pasar:
  · enlace sano                  ⇒ ok, rc=0
  · enlace colgado a /opt/hammer ⇒ avisa, lo repone, rc=0
  · destino inexistente          ⇒ falla ruidoso, rc=1
This commit is contained in:
Sergio
2026-09-14 14:08:55 +00:00
parent 6c1c316671
commit d570a8e03f
+30 -3
View File
@@ -149,10 +149,37 @@ else
ok "go $GO_VER instalado en $GO_LINK"
fi
# Symlink en un dir del PATH del host (junto a cargo) para que el fetch encuentre `go`.
#
# ⚠ EL ENLACE SE COMPRUEBA, NO SE DA POR HECHO — y esto es MEDIDO (2026-09-14). El enlace guarda
# una ruta ABSOLUTA derivada de dónde vivía el repo el día que se corrió esto. El renombre
# hammer→takana movió `/opt/hammer` a `/opt/takana` (ADR 0016, 2026-09-09) y el enlace del worker
# quedó apuntando a un directorio que ya no existe. Nada falló: `ln -sfn` crea un enlace colgado
# tan campante, este script imprimía «go enlazado ✓», y el worker pasó CINCO DÍAS sin poder
# construir NINGUNA receta Go. El síntoma, cuando por fin se lo buscó, era
# `spawn go mod vendor: No such file or directory` — el mismo modo de fallo que `patch` en agosto,
# y por la misma razón: `go` lo invoca takana DEL LADO DEL HOST, fuera del sandbox, así que el
# rootfs no lo cubre.
#
# Se descubrió por casualidad, verificando reproducibilidad: 16 de 25 recetas Go murieron en
# SEGUNDOS. Un fallo sistémico se lee como 16 recetas rotas si nadie mira el error.
#
# ⇒ Se repara un enlace colgado que ya estuviera, y se comprueba que el enlace RESUELVE ejecutando
# `go version` A TRAVÉS DE ÉL. Un enlace que existe no es un `go` que corre.
if [[ -d "$HOME/.cargo/bin" ]]; then
ln -sfn "$GO_LINK/bin/go" "$HOME/.cargo/bin/go"
ln -sfn "$GO_LINK/bin/gofmt" "$HOME/.cargo/bin/gofmt"
ok "go enlazado en ~/.cargo/bin (PATH del host/worker)"
for b in go gofmt; do
if [[ -L "$HOME/.cargo/bin/$b" && ! -e "$HOME/.cargo/bin/$b" ]]; then
log "go: enlace COLGADO $HOME/.cargo/bin/$b -> $(readlink "$HOME/.cargo/bin/$b") ⇒ lo repongo"
fi
ln -sfn "$GO_LINK/bin/$b" "$HOME/.cargo/bin/$b"
done
if "$HOME/.cargo/bin/go" version >/dev/null 2>&1; then
ok "go enlazado en ~/.cargo/bin y COMPROBADO ($("$HOME/.cargo/bin/go" version))"
else
echo "!! go: el enlace $HOME/.cargo/bin/go existe pero NO EJECUTA." >&2
echo "!! Sin esto el host no puede hacer \`go mod vendor\` y TODA receta Go muere con" >&2
echo "!! 'spawn go mod vendor: No such file or directory'. Destino: $GO_LINK/bin/go" >&2
exit 1
fi
else
log "go: ~/.cargo/bin no existe; agregá $GO_LINK/bin al PATH del host a mano"
fi