gioser

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 1518Shell 194Rust 108Markdown 983677 Definitions

⎇ c82588ced8d61d9b48bb3544dac4f6e7b56da319 scripts/farm/farm-up.sh Shell · 64 lines · 3.2 KB History raw

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

1#!/usr/bin/env bash
2# farm-up.sh [N] — levanta N workers EFÍMEROS desde el snapshot golden y los alinea con la cola
3# actual del laptop. Modelo hub-and-spoke: el worker NO tiene secretos (ni firma ni gitea); es
4# compute puro y descartable. La imagen 'hammer-golden' trae el toolchain + el store sellado
5# horneados ⇒ el worker arranca con TODO el catálogo cacheado (cache-hit instantáneo), sólo
6# construye lo NUEVO que el hub le empuje.
7#
8# Flujo:  scripts/farm/farm-up.sh 3      # crea hworker-1..3, los alimenta con la cola actual
9#         ... (muelen) ...
10#         scripts/farm/farm-down.sh      # cosecha su store al laptop y los DESTRUYE
11#
12# La flota viva se registra en scripts/farm/.fleet ("<name> <ip>" por línea; gitignored).
13# Idempotente al escalar: re-correr con más N agrega workers sin pisar los vivos.
14#
15# Env: IMAGE (snapshot, def 405120842=hammer-golden-2026-07-05), TYPE (def ccx23), LOCATION
16#      (def hel1), SSHKEY (llave del proyecto Hetzner, def desarrollo@jlsoltech.com), SSH_KEY
17#      (privada local p/ SSH, def ~/.ssh/github5), REMOTE (def /opt/hammer).
18set -euo pipefail
19
20N="${1:-1}"
21IMAGE="${IMAGE:-405120842}"
22TYPE="${TYPE:-ccx23}"
23LOCATION="${LOCATION:-hel1}"
24SSHKEY="${SSHKEY:-desarrollo@jlsoltech.com}"
25SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
26REMOTE="${REMOTE:-/opt/hammer}"
27ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
28FLEET="$ROOT/scripts/farm/.fleet"
29# Workers efímeros RECICLAN IPs de Hetzner ⇒ un known_hosts persistente choca ("HOST KEY CHANGED")
30# y accept-new RECHAZA la clave cambiada, colgando el `until ssh true` para siempre. Como el modelo
31# es hub-and-spoke (el worker NO tiene secretos: compute puro descartable), saltamos la verificación
32# de host y no ensuciamos known_hosts (/dev/null). No hay superficie MITM que proteger acá.
33SSH="ssh -i $SSH_KEY -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR -o ConnectTimeout=10"
34cd "$ROOT"
35touch "$FLEET"
36
37# índice de arranque: el mayor hworker-N vivo + 1 (para escalar sin colisión de nombres)
38base=$(sed -n 's/^hworker-\([0-9]*\) .*/\1/p' "$FLEET" | sort -n | tail -1)
39base="${base:-0}"
40
41for k in $(seq 1 "$N"); do
42  i=$((base + k)); name="hworker-$i"
43  echo "==> creando $name ($TYPE @ $LOCATION desde image $IMAGE)"
44  hcloud server create --name "$name" --image "$IMAGE" --type "$TYPE" \
45    --location "$LOCATION" --ssh-key "$SSHKEY" --label role=hammer-worker >/dev/null
46  ip=$(hcloud server ip "$name")
47  echo "$name $ip" >> "$FLEET"
48  echo "   ip=$ip; esperando SSH…"
49  until $SSH root@"$ip" true 2>/dev/null; do sleep 3; done
50
51  echo "   alineando cola con el laptop (rsync código + recipes)…"
52  rsync -az --delete -e "$SSH" \
53    --exclude /work --exclude /store --exclude '/store-*' --exclude /target \
54    --exclude /dist --exclude /.dev-fs --exclude /.git --exclude /.scratch \
55    --exclude '*.png' --exclude '/content*' \
56    ./ "root@$ip:$REMOTE/"
57  # el servicio ya arrancó en el boot (baked/enabled); reiniciar fuerza rescan inmediato de la cola
58  $SSH root@"$ip" 'systemctl restart hammer-farm' 2>/dev/null || true
59  echo "   ✓ $name muele la cola actual"
60done
61
62sort -u -o "$FLEET" "$FLEET"
63echo "==> flota viva:"; cat "$FLEET"
64echo "cosechar+destruir con: scripts/farm/farm-down.sh"