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>
68 lines
3.9 KiB
Bash
Executable File
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
|