Files
Sergio aacee245d6 takana: el worker pasa a /opt/takana y takana-farm.service
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.
2026-09-09 20:20:16 +00:00

54 lines
2.4 KiB
Bash
Executable File

#!/bin/sh
# tandas.sh — encadena varias campañas de deuda en el worker, en ORDEN y sin solaparse.
#
# POR QUÉ EN SERIE Y NO EN PARALELO: dos `takana build` simultáneos sobre el mismo store compiten
# por el mismo `work/sources` y por el watchdog de disco del worker-loop (que borra árboles que
# ningún bwrap tiene montado). El paralelismo del worker está DENTRO de cada build (`-j$(nproc)`),
# no entre builds.
#
# POR QUÉ TANDAS Y NO UNA LISTA LARGA: una tanda es una unidad con sentido topológico — la cadena
# GUI, el stack wayland, los kernels. Si una tanda se cae entera por su raíz (como pango arrastró a
# 7 recetas el 2026-07-21), se ve de un vistazo en el resumen y se re-lanza sola. Una lista de 40
# nombres planos no dice nada cuando falla.
#
# Espera a que termine cualquier campaña en vuelo antes de arrancar, así se puede encolar mientras
# otra muele.
#
# Uso (en el worker):
# scripts/farm/tandas.sh "gui:pixman,cairo,pango" "kernels:linux,linux-generic"
# Desde el hub:
# ssh root@<ip> 'systemd-run --unit=tandas --working-directory=/opt/takana \
# /opt/takana/scripts/farm/tandas.sh "gui:pixman,cairo" …'
# ssh root@<ip> 'tail -f /var/log/tandas.log'
set -u
HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/takana}}"
cd "$HAMMER_DIR"
LOG="${LOG:-/var/log/tandas.log}"
ESPERA="${ESPERA:-30}"
ts() { date -u +%FT%TZ; }
[ $# -gt 0 ] || { echo "uso: tandas.sh <nombre:receta1,receta2,…> […]" >&2; exit 2; }
# No solaparse con una campaña previa (ni con otra corrida de este mismo script).
while pgrep -f 'campana-deuda\.s[h]' >/dev/null 2>&1; do
echo "$(ts) esperando a que termine la campaña en vuelo…" | tee -a "$LOG"
sleep "$ESPERA"
done
echo "$(ts) ═══ tandas arranca: $# tanda(s)" | tee -a "$LOG"
resumen=""
for spec in "$@"; do
nombre="${spec%%:*}"
lista="$(echo "${spec#*:}" | tr ',' ' ')"
n=$(echo "$lista" | wc -w)
echo "$(ts) ── TANDA '$nombre' ($n recetas)" | tee -a "$LOG"
# campana-deuda.sh ya trae el PATH del go del store, el heartbeat del dead-man y el log por receta.
LOG="/var/log/tanda-$nombre.log" scripts/farm/campana-deuda.sh $lista 2>&1 | tee -a "$LOG"
ok=$(grep -c '✓ ' "/var/log/tanda-$nombre.log" 2>/dev/null || echo 0)
ko=$(grep -c '✗ ' "/var/log/tanda-$nombre.log" 2>/dev/null || echo 0)
resumen="$resumen\n $nombre: $ok selladas, $ko fallidas (de $n)"
done
echo "$(ts) ═══ tandas fin" | tee -a "$LOG"
printf "%b\n" "$resumen" | tee -a "$LOG"