La siembra de código hub→worker de `cosecha-cron` corre con `--delete` cada 30 minutos. Las copias del experimento viven en `recipes/` por obligación (takana resuelve las deps relativas al directorio de la receta), así que una tanda larga en el worker las vería desaparecer a mitad. Con `REC` se apunta a una copia entera de `recipes/` fuera del árbol sembrado y el problema no existe.
66 lines
3.7 KiB
Bash
Executable File
66 lines
3.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# exp-ec.sh — el experimento del ADR 0020: ¿cuántas recetas dejan de construir si las fases
|
|
# corriesen con `sh -ec` en vez de `sh -c`?
|
|
#
|
|
# ── POR QUÉ NO SELLA NADA, Y POR QUÉ ESO IMPORTA ───────────────────────────────────────────────
|
|
# Modificar una receta le cambia el `ArtifactHash`, así que medir esto a lo bruto dejaría un
|
|
# duplicado basura en el store POR CADA receta que pase — en un store que se respalda. En vez de eso
|
|
# se inyecta `set -e` al principio de cada fase Y un `exit 77` al final de la última, de modo que el
|
|
# build SIEMPRE falla y nunca sella. El veredicto se lee en el código que reporta takana:
|
|
#
|
|
# · falló con 77 ⇒ las fases corrieron ENTERAS bajo set -e ⇒ SOBREVIVE a `-ec`
|
|
# · falló con ≠77 ⇒ una orden intermedia falla y hoy se traga ⇒ SE ROMPE con `-ec`
|
|
#
|
|
# Las copias se escriben en `recipes/exp-ec-*.toml` —tienen que vivir ahí porque takana resuelve las
|
|
# deps RELATIVAS al directorio de la receta— y se barren al terminar.
|
|
#
|
|
# ⚠ El lock se toma POR RECETA, no por tanda. La regla 1 de CLAUDE.md dice lo contrario para las
|
|
# tandas normales, y con razón; acá es al revés a propósito: una tanda de éstas puede durar horas y
|
|
# retener `work/.farm-build.lock` todo ese tiempo pararía la cosecha del latido.
|
|
#
|
|
# Uso: MUESTRA=/ruta/lista.txt scripts/farm/exp-ec.sh (una receta por línea, p.ej. recipes/gzip.toml)
|
|
cd "$(dirname "$0")/../.."
|
|
TMP=${TMPDIR:-/tmp}/exp-ec
|
|
# REC se puede apuntar a una COPIA de recipes/: en el worker, la siembra de la cosecha corre con
|
|
# `rsync --delete` cada 30 min y barrería las copias del experimento a mitad de una tanda larga.
|
|
REC=${REC:-$(cd "$(dirname "$0")/../.." && pwd)/recipes}
|
|
mkdir -p "$TMP"; OUT="$TMP/resultados.tsv"; : > "$OUT"
|
|
|
|
# El lock va RELATIVO a la raíz del repo, que es donde CLAUDE.md lo define (`work/.farm-build.lock`).
|
|
# En la caja `work` es un symlink a /work y en el worker es un directorio de verdad: cablear la ruta
|
|
# absoluta de una máquina rompe en la otra con `flock: cannot open lock file`.
|
|
LOCK=${LOCK:-work/.farm-build.lock}
|
|
# Y `takana` no está en el PATH del worker — allá se invoca por su ruta dentro del árbol.
|
|
TAKANA=${TAKANA:-$(command -v takana 2>/dev/null || echo ./target/release/takana)}
|
|
# Techo por receta. 420 s alcanza para las ligeras; la cola pesada (llvm, firefox, kernels) pide
|
|
# mucho más y se le pasa TLIMITE por entorno. Un timeout NO es un veredicto: se cuenta aparte.
|
|
TLIMITE=${TLIMITE:-420}
|
|
|
|
while read -r r; do
|
|
[ -f "$r" ] || continue
|
|
n=$(basename "$r" .toml)
|
|
awk '
|
|
/^(compile|install|configure|check|prepare) = .{3}$/ { print; print "set -e"; inb=1; next }
|
|
{ print }
|
|
' "$r" > "$REC/exp-ec-$n.toml"
|
|
# `exit 77` como última línea de la última fase del fichero
|
|
last=$(grep -n "^'''$" "$REC/exp-ec-$n.toml" | tail -1 | cut -d: -f1)
|
|
[ -n "$last" ] && sed -i "${last}i exit 77" "$REC/exp-ec-$n.toml"
|
|
|
|
log="$TMP/$n.log"
|
|
timeout "$TLIMITE" flock -o "$LOCK" "$TAKANA" build "$REC/exp-ec-$n.toml" > "$log" 2>&1
|
|
rc=$?
|
|
if grep -q "exit 77" "$log"; then v="SOBREVIVE"
|
|
elif [ $rc -eq 124 ]; then v="TIMEOUT"
|
|
elif grep -qE "build phase falló \(exit [0-9]+\)" "$log"; then v="SE-ROMPE"
|
|
else v="OTRO"; fi
|
|
det=$(grep -oE "build phase falló \(exit [0-9]+\): .*" "$log" | head -1 | cut -c1-90)
|
|
printf '%s\t%s\t%s\n' "$n" "$v" "$det" >> "$OUT"
|
|
echo "[$v] $n"
|
|
done < ${MUESTRA:?hace falta MUESTRA=<fichero con una receta por línea>}
|
|
|
|
echo "════ RESUMEN ════"
|
|
for v in SOBREVIVE SE-ROMPE TIMEOUT OTRO; do echo "$v: $(grep -c " $v " "$OUT")"; done
|
|
rm -f "$REC"/exp-ec-*.toml
|
|
echo "copias de experimento barridas de recipes/: $(ls "$REC"/exp-ec-*.toml 2>/dev/null | wc -l) quedan"
|