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 Definitions

farm: tandas.sh — encadenar campañas en orden, sin solaparse

En serie y no en paralelo: dos `hammer build` simultáneos compiten por el mismo work/sources y por
el watchdog de disco del worker-loop. El paralelismo vive DENTRO de cada build (-j$(nproc)).

En tandas y no en una lista plana: una tanda es una unidad topológica (la cadena GUI, el stack
wayland, los kernels). Cuando una se cae por su raíz —como pango arrastró a 7 recetas— se ve de un
vistazo en el resumen y se re-lanza sola; una lista de 40 nombres no dice nada al fallar.

Espera a que termine la campaña en vuelo, así se encola mientras otra muele.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

e09a48a69e96846b50406145316a349247faf9bb · by sergio · (3 months ago) · parent a8bb83add · browse the tree at this commit

Semantic delta

No definition changed: this change is text, documentation or data.

1 files · +53 −0

diff --git a/scripts/farm/tandas.sh b/scripts/farm/tandas.sh
new file mode 100755
index 00000000..e0fa0c68
--- /dev/null
+++ b/scripts/farm/tandas.sh
@@ -0,0 +1,53 @@
+#!/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 `hammer 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/hammer \
+#                    /opt/hammer/scripts/farm/tandas.sh "gui:pixman,cairo" …'
+#   ssh root@<ip> 'tail -f /var/log/tandas.log'
+set -u
+HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}"
+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"