Files
takana/scripts/farm/farm-lab-sync.sh
T
SergioandClaude Opus 5 1c17f2f255 granja: empujar el lab anclado al worker y PROBAR que sella igual que el hub
farm-sync excluye /.dev-fs a proposito (el lab es del entorno, no del repo).
Eso valia cuando el toolchain no entraba en el hash. Desde 58d3161 si entra,
asi que un worker con el lab horneado de la golden (rustc 1.96) sella en
direcciones DISTINTAS a las del hub (1.97): no es que compile distinto, es
que lo guarda donde el hub nunca lo va a buscar.

Tampoco basta bootstrap-devfs.sh en el worker: su paso 0 solo trae la imagen
si NO hay rootfs, y la golden trae uno. Se reemplaza a la fuerza.

La imagen se EMPUJA por scp desde el hub en vez de bajarla del Storage Box,
para no poner la llave del box en el worker: el modelo hub-and-spoke dice que
el worker es compute puro sin secretos.

El paso 4 no es 'extraje la imagen', es comparar el hammer hash de una receta
testigo entre worker y hub. Si divergen FALLA: un worker que sella en otra
direccion quema dinero produciendo artefactos que nadie encuentra.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 11:18:09 +00:00

68 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# farm-lab-sync.sh <ip> — pone el LAB ANCLADO en un worker y PRUEBA que sella igual que el hub.
#
# ── POR QUÉ NO BASTA CON farm-sync ──────────────────────────────────────────────────────────────
# `farm-sync.sh` sube el código con `--exclude /.dev-fs`, a propósito: el lab es del entorno, no del
# repo. Eso estaba bien cuando el toolchain NO entraba en el hash. Desde el 2026-08-10 sí entra
# (`hammer-core/src/lab.rs`), así que un worker con su lab horneado en la golden —rustc 1.96— sella
# en direcciones DISTINTAS a las del hub —1.97— y su trabajo no le sirve a nadie: no es que compile
# distinto, es que lo guarda en otra dirección y el hub nunca lo encuentra.
#
# Tampoco basta con correr `bootstrap-devfs.sh` en el worker: su paso 0 sólo trae la imagen si NO
# hay rootfs, y la golden trae uno. Se reemplaza a la fuerza.
#
# ── EL WORKER SIGUE SIN SECRETOS ────────────────────────────────────────────────────────────────
# La imagen se EMPUJA desde el hub por scp, no se baja del Storage Box. Así el worker no necesita la
# llave del box y se mantiene el invariante del modelo hub-and-spoke: compute puro y descartable.
#
# ── EVIDENCIA, NO FE ────────────────────────────────────────────────────────────────────────────
# El paso final NO es "extraje la imagen": es comparar el `hammer hash` de una receta testigo entre
# worker y hub. Si no coinciden, este script FALLA y el worker no debe construir — un worker que
# sella en otra dirección quema dinero produciendo artefactos que nadie va a encontrar.
#
# Uso: scripts/farm/farm-lab-sync.sh <ip-del-worker>
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
IP="${1:?falta la IP del worker}"
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
REMOTE="${REMOTE:-/opt/hammer}"
SSH="ssh -i $SSH_KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
IMG="$ROOT/.dev-fs/lab-image.tar.zst"
TESTIGO="${TESTIGO:-recipes/zlib.toml}"
log() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }
ok() { printf '\033[1;32m✓\033[0m %s\n' "$*"; }
[ -f "$IMG" ] || { echo "no existe $IMG — corré scripts/lab-image.sh --crear" >&2; exit 1; }
log "1/4 empujando la imagen del lab ($(du -h "$IMG" | cut -f1)) a $IP"
rsync -a --partial-dir=.rsync-partial -e "$SSH" "$IMG" "root@$IP:$REMOTE/.dev-fs/lab-image.tar.zst"
log "2/4 reemplazando el rootfs del worker (rotación, no extracción encima)"
$SSH "root@$IP" "set -e
cd $REMOTE/.dev-fs
rm -rf alpine.nuevo && mkdir -p alpine.nuevo
zstd -d -q -c lab-image.tar.zst | tar -x -C alpine.nuevo
rm -rf alpine.viejo
[ -d alpine ] && mv alpine alpine.viejo
mv alpine.nuevo/alpine alpine
rmdir alpine.nuevo
rm -rf alpine.viejo"
log "3/4 recompilando hammer en el worker (el binario debe traer el lab en hash_inputs)"
$SSH "root@$IP" "cd $REMOTE && . \$HOME/.cargo/env 2>/dev/null; cargo build --release --bin hammer 2>&1 | tail -2"
log "4/4 EVIDENCIA: ¿el worker sella en la misma dirección que el hub?"
h_hub=$("$ROOT/target/release/hammer" --store "$ROOT/store" hash "$TESTIGO" | tail -1)
h_w=$($SSH "root@$IP" "cd $REMOTE && ./target/release/hammer --store ./store hash $TESTIGO 2>&1 | tail -1")
echo " hub : $h_hub"
echo " worker : $h_w"
if [ "$h_hub" = "$h_w" ]; then
ok "el worker sella igual que el hub — puede construir"
else
echo "⛔ DIVERGEN. Este worker NO debe construir: sus artefactos irían a direcciones que el hub"
echo " nunca va a buscar. Revisá que la imagen del lab llegó entera y que recompiló hammer." >&2
exit 1
fi