tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1572Shell 203Rust 109Markdown 993728 Sutichaykuna

⎇ 8730aad34e868068796f9c85ca4e4c89cfb43fa6 scripts/farm/farm-run.sh Shell · 69 siq'ikuna · 3.4 KB Ñawpa willay ch'uya

granja: fix host-key en workers efímeros — known_hosts a /dev/null e2e5bc6f0 · sergio ·

1#!/usr/bin/env bash
2# farm-run.sh [N] — el ciclo EFÍMERO de una tanda, de punta a punta y DESATENDIDO: levanta N
3# workers desde el snapshot golden, los alinea con la cola actual del laptop, espera a que MUELAN
4# la cola entera (un ciclo completo del worker-loop), y en cuanto terminan COSECHA su store y los
5# DESTRUYE. "Subí la cola, corré esto, andá a hacer otra cosa; se apaga solo cuando termina."
6#
7# Es el pegamento up→esperar→down: farm-up.sh + farm-down.sh existen sueltos (control manual/parcial);
8# farm-run.sh los encadena con la detección de "ya no queda nada nuevo por construir".
9#
10# Detección de "terminó": el worker-loop (farm-worker-loop.sh) imprime "ciclo terminado" al journal
11# tras construir TODAS las colas una vez. Contamos esas líneas ANTES de arrancar (baseline, persisten
12# en el journal) y esperamos a que el contador suba: +1 ⇒ el worker intentó la cola entera una vez
13# (lo que se pudo sellar, sellado; lo que falla, falla y se reintentaría en vano). Robusto a skew de
14# reloj (contamos ocurrencias, no comparamos timestamps) y a builds largos (no hay falso-positivo por
15# "store estable": sólo el marcador de fin-de-ciclo cuenta). Con varios workers, espera a TODOS.
16#
17# Uso:   scripts/farm/farm-run.sh          # 1 worker, cola actual, cosecha+destruye+firma al terminar
18#        scripts/farm/farm-run.sh 3        # 3 workers en paralelo sobre la misma cola
19# Env:   POLL (def 60s entre sondeos), MAXWAIT (def 21600s=6h tope duro), + los de farm-up/down
20#        (IMAGE/TYPE/LOCATION/SSHKEY/SSH_KEY/REMOTE/NO_PROMOTE).
21set -euo pipefail
22
23N="${1:-1}"
24POLL="${POLL:-60}"
25MAXWAIT="${MAXWAIT:-21600}"
26SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
27ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
28FLEET="$ROOT/scripts/farm/.fleet"
29# Ver nota en farm-up.sh: workers efímeros reciclan IPs ⇒ known_hosts a /dev/null (hub-and-spoke,
30# worker sin secretos, sin superficie MITM que proteger).
31SSH="ssh -i $SSH_KEY -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR -o ConnectTimeout=10"
32cd "$ROOT"
33
34cycles() { $SSH "root@$1" 'journalctl -u hammer-farm -o cat --no-pager 2>/dev/null | grep -c "ciclo terminado"' 2>/dev/null || echo 0; }
35
36echo "==> [farm-run] levantando $N worker(s) y alineando la cola…"
37scripts/farm/farm-up.sh "$N"
38
39# Baseline por worker de la flota recién levantada (los que YA existían también entran: esperamos
40# a que cada uno complete un ciclo nuevo desde el restart que hizo farm-up).
41declare -A base
42while read -r name ip; do
43  [ -n "${name:-}" ] || continue
44  base["$name|$ip"]=$(cycles "$ip")
45done < "$FLEET"
46
47echo "==> [farm-run] esperando a que la flota muela la cola (POLL=${POLL}s, tope ${MAXWAIT}s)…"
48waited=0
49while :; do
50  pending=0
51  while read -r name ip; do
52    [ -n "${name:-}" ] || continue
53    b=${base["$name|$ip"]:-0}
54    c=$(cycles "$ip")
55    if [ "$c" -le "$b" ]; then
56      pending=$((pending + 1))
57    fi
58  done < "$FLEET"
59  [ "$pending" -eq 0 ] && { echo "==> [farm-run] la flota completó un ciclo — cola molida."; break; }
60  if [ "$waited" -ge "$MAXWAIT" ]; then
61    echo "  ⚠ [farm-run] tope de espera (${MAXWAIT}s) alcanzado con $pending worker(s) sin cerrar ciclo — cosecho igual lo que haya."
62    break
63  fi
64  sleep "$POLL"; waited=$((waited + POLL))
65done
66
67echo "==> [farm-run] cosechando + destruyendo + firmando…"
68scripts/farm/farm-down.sh
69echo "==> [farm-run] listo. Baseline €0 (sin cajas vivas de la tanda)."