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.
53 lines
2.4 KiB
Bash
Executable File
53 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# estado-granja.sh — foto RÁPIDA de la granja, on-demand (no depende del cron). Corre cuando quieras
|
|
# ver dónde va sin esperar al latido: salud del worker, qué muele, avance KDE, y si el cron corrió.
|
|
# scripts/farm/estado-granja.sh
|
|
set -uo pipefail
|
|
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
|
|
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
|
|
FLEET="$ROOT/scripts/farm/.fleet"
|
|
SSH="ssh -i $SSH_KEY -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o BatchMode=yes -o LogLevel=ERROR -o ConnectTimeout=12"
|
|
|
|
echo "══ WORKERS ($(date '+%H:%M:%S')) ══"
|
|
if [ -s "$FLEET" ]; then
|
|
while read -r name ip; do
|
|
[ -n "${name:-}" ] || continue
|
|
echo "▶ $name ($ip)"
|
|
$SSH "root@$ip" '
|
|
echo " $(uptime | sed "s/.*load average/load/")"
|
|
n=$(ls /opt/takana/store 2>/dev/null | wc -l); echo " store: $n artefactos"
|
|
b=$(pgrep -af "release/hammer" | grep -E "release/hammer (build|--store|hash)" | grep -oE "[^ /]+\.toml" | sort -u | tr "\n" " ")
|
|
echo " moliendo: ${b:-(nada — idle o entre colas)}"
|
|
' 2>/dev/null || echo " ⚠ sin respuesta (¿dead-man lo mató? ¿aún arrancando?)"
|
|
done < "$FLEET"
|
|
else
|
|
echo " flota vacía (scripts/farm/.fleet) — no hay worker vivo"
|
|
fi
|
|
|
|
echo; echo "══ AVANCE KDE (grafo local) ══"
|
|
if [ -f docs/state/build-state-kde.json ]; then
|
|
python3 - <<'PY'
|
|
import json,os,time
|
|
f="docs/state/build-state-kde.json"
|
|
d=json.load(open(f)); q=d["by_queue"].get("incoming-kde",{})
|
|
tot=sum(q.values()); s=q.get("sealed",0)
|
|
age=int(time.time()-os.path.getmtime(f))
|
|
bar=int(30*s/tot) if tot else 0
|
|
print(f" [{'#'*bar}{'.'*(30-bar)}] {s}/{tot} sellado "
|
|
f"(deuda {q.get('debt',0)}, nunca {q.get('never',0)})")
|
|
print(f" grafo regenerado hace {age//60}m {age%60}s (lo actualiza el cron o `scripts/build-state.py --kde`)")
|
|
PY
|
|
else
|
|
echo " (sin grafo — corré scripts/build-state.py --kde)"
|
|
fi
|
|
|
|
echo; echo "══ CRON DE COSECHA ══"
|
|
line=$(crontab -l 2>/dev/null | grep cosecha-cron | grep -v '^#')
|
|
[ -n "$line" ] && echo " instalado: $line" || echo " ⚠ NO instalado en el crontab"
|
|
if [ -f work/cosecha-cron.log ]; then
|
|
echo " último ciclo (tail):"
|
|
grep -E 'cosecha-cron (arranca|fin)|siembra|cosecha ✓|estado commit' work/cosecha-cron.log | tail -6 | sed 's/^/ /'
|
|
else
|
|
echo " (aún no corrió — no hay work/cosecha-cron.log; el cron dispara en :00 y :30)"
|
|
fi
|