Renombrado el directorio del worker y la unit, con las tres units del repo (farm, deadman service y timer). Todas las rutas /opt/hammer del hub pasan a /opt/takana: eran defaults REMOTE= y HAMMER_DIR=, mas los systemctl/journalctl que nombraban la unit sin el sufijo .service, que el primer sed no casaba. Orden, para que no quedara partido: el hub siembra por rsync a una ruta fija, asi que se saco el cron ANTES de mover. Si se movia el worker con el hub apuntando a la ruta vieja, la siguiente cosecha recreaba /opt/hammer y quedaban dos arboles. Verificado de punta a punta: - el worker cerro un ciclo de build REAL desde /opt/takana (dunst sellado, 1/1) - una cosecha completa del hub contra la ruta nueva: siembra, manifiesto, los nueve grafos, static-audit (691 estaticos, MIENTEN 0) y estado pusheado - la unit vieja quedo deshabilitada y borrada; /opt tiene una sola entrada NO se tocan dos referencias a /opt/hammer que siguen siendo CORRECTAS: docs/23-plan-rehasheo.md describe rutas EMBEBIDAS en artefactos ya construidos —que literalmente dicen /opt/hammer/work en sus secciones .debug— y el HANDOFF de la noche de KDE es registro. Cambiarlas haria que los documentos mientan.
70 lines
3.4 KiB
Bash
Executable File
70 lines
3.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# farm-run.sh [N] — el ciclo EFÍMERO de una tanda, de punta a punta y DESATENDIDO: levanta N
|
|
# workers desde el snapshot golden, los alinea con la cola actual del laptop, espera a que MUELAN
|
|
# la cola entera (un ciclo completo del worker-loop), y en cuanto terminan COSECHA su store y los
|
|
# DESTRUYE. "Subí la cola, corré esto, andá a hacer otra cosa; se apaga solo cuando termina."
|
|
#
|
|
# Es el pegamento up→esperar→down: farm-up.sh + farm-down.sh existen sueltos (control manual/parcial);
|
|
# farm-run.sh los encadena con la detección de "ya no queda nada nuevo por construir".
|
|
#
|
|
# Detección de "terminó": el worker-loop (farm-worker-loop.sh) imprime "ciclo terminado" al journal
|
|
# tras construir TODAS las colas una vez. Contamos esas líneas ANTES de arrancar (baseline, persisten
|
|
# en el journal) y esperamos a que el contador suba: +1 ⇒ el worker intentó la cola entera una vez
|
|
# (lo que se pudo sellar, sellado; lo que falla, falla y se reintentaría en vano). Robusto a skew de
|
|
# reloj (contamos ocurrencias, no comparamos timestamps) y a builds largos (no hay falso-positivo por
|
|
# "store estable": sólo el marcador de fin-de-ciclo cuenta). Con varios workers, espera a TODOS.
|
|
#
|
|
# Uso: scripts/farm/farm-run.sh # 1 worker, cola actual, cosecha+destruye+firma al terminar
|
|
# scripts/farm/farm-run.sh 3 # 3 workers en paralelo sobre la misma cola
|
|
# Env: POLL (def 60s entre sondeos), MAXWAIT (def 21600s=6h tope duro), + los de farm-up/down
|
|
# (IMAGE/TYPE/LOCATION/SSHKEY/SSH_KEY/REMOTE/NO_PROMOTE).
|
|
set -euo pipefail
|
|
|
|
N="${1:-1}"
|
|
POLL="${POLL:-60}"
|
|
MAXWAIT="${MAXWAIT:-21600}"
|
|
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
|
|
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
FLEET="$ROOT/scripts/farm/.fleet"
|
|
# Ver nota en farm-up.sh: workers efímeros reciclan IPs ⇒ known_hosts a /dev/null (hub-and-spoke,
|
|
# worker sin secretos, sin superficie MITM que proteger).
|
|
SSH="ssh -i $SSH_KEY -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR -o ConnectTimeout=10"
|
|
cd "$ROOT"
|
|
|
|
cycles() { $SSH "root@$1" 'journalctl -u takana-farm -o cat --no-pager 2>/dev/null | grep -c "ciclo terminado"' 2>/dev/null || echo 0; }
|
|
|
|
echo "==> [farm-run] levantando $N worker(s) y alineando la cola…"
|
|
scripts/farm/farm-up.sh "$N"
|
|
|
|
# Baseline por worker de la flota recién levantada (los que YA existían también entran: esperamos
|
|
# a que cada uno complete un ciclo nuevo desde el restart que hizo farm-up).
|
|
declare -A base
|
|
while read -r name ip; do
|
|
[ -n "${name:-}" ] || continue
|
|
base["$name|$ip"]=$(cycles "$ip")
|
|
done < "$FLEET"
|
|
|
|
echo "==> [farm-run] esperando a que la flota muela la cola (POLL=${POLL}s, tope ${MAXWAIT}s)…"
|
|
waited=0
|
|
while :; do
|
|
pending=0
|
|
while read -r name ip; do
|
|
[ -n "${name:-}" ] || continue
|
|
b=${base["$name|$ip"]:-0}
|
|
c=$(cycles "$ip")
|
|
if [ "$c" -le "$b" ]; then
|
|
pending=$((pending + 1))
|
|
fi
|
|
done < "$FLEET"
|
|
[ "$pending" -eq 0 ] && { echo "==> [farm-run] la flota completó un ciclo — cola molida."; break; }
|
|
if [ "$waited" -ge "$MAXWAIT" ]; then
|
|
echo " ⚠ [farm-run] tope de espera (${MAXWAIT}s) alcanzado con $pending worker(s) sin cerrar ciclo — cosecho igual lo que haya."
|
|
break
|
|
fi
|
|
sleep "$POLL"; waited=$((waited + POLL))
|
|
done
|
|
|
|
echo "==> [farm-run] cosechando + destruyendo + firmando…"
|
|
scripts/farm/farm-down.sh
|
|
echo "==> [farm-run] listo. Baseline €0 (sin cajas vivas de la tanda)."
|