250 líneas de comentario en 151 scripts. Control verificado: el diff no toca NI UNA línea que no empiece por #, y la sintaxis de los 151 pasa. El barrido saltea heredocs y cadenas triples, y el guardián DISPARÓ 3 veces: las tres eran el MOTD que el script escribe DENTRO de la imagen construida — texto del producto, no comentario del script. Se cambiaron aparte y a propósito, que es rebranding, no limpieza. Y el hallazgo caro: casaba contra , que es el TARGET de tracing — o sea el module_path!, o sea el nombre del crate. La etapa 4 lo movió a y el script quedó casando NADA. No fallaba: imprimía cero atribuciones, indistinguible de un log sin problemas. Comprobado con el binario (RUST_LOG=info sobre zlib), no deducido. Ahora acepta las dos, y tiene que seguir aceptándolas porque los logs viejos en disco dicen la vieja. Además 14 rutas de módulo en docs, que el barrido anterior no tocó porque no es frontera de palabra.
88 lines
4.5 KiB
Bash
88 lines
4.5 KiB
Bash
#!/usr/bin/env bash
|
|
# harkaq-trace-build.sh — orquestador del PILOTO de traza positiva (plan-freebsd T1.1+T1.3).
|
|
#
|
|
# Envuelve UN `takana build` con harkaq-trace enganchado al overlay de CADA fase: un bwrap
|
|
# por fase ⇒ una traza por fase — la misma granularidad que el veredicto de harkaq. El
|
|
# tracer marca `/proc/<pid-bwrap>/root`: el magic-link cae en el SB del OVERLAY, que es el
|
|
# único lugar desde donde los reads del build se ven (la marca sobre el fs del host NO los
|
|
# ve — ceguera-overlay, medida en el piloto; ver plan-freebsd-aprovechables.md §1). Bonus:
|
|
# los paths salen en el namespace de la jaula (/usr/include/zlib.h) — el idioma de la
|
|
# política, sin traducción host↔jaula.
|
|
#
|
|
# PILOTO, no framework: el enganche por polling tiene una ventana ciega (~decenas de ms al
|
|
# arrancar cada fase) y bwrap puede aparecer como varios pids (helpers) — trazas duplicadas
|
|
# que el normalizador colapsa, pero el conteo de "fases" puede inflarse. La integración
|
|
# real (lanzar el tracer ANTES del exec del build, sin carrera) va en el harness — carril
|
|
# de Opus, se coordina allá. Este script existe para medir HOY la señal declaradas-vs-usadas.
|
|
#
|
|
# uso: harkaq-trace-build.sh <receta.toml> [store] [outdir]
|
|
# env: HAMMER (def ./target/release/takana), TRACE (def /tmp/harkaq-trace), NORM (def
|
|
# scripts/harkaq/harkaq-trace-norm.py)
|
|
# deja en outdir: traza-fase-N.txt (crudas), canonica.txt, sello.txt, resumen.txt
|
|
set -euo pipefail
|
|
RECETA="${1:?uso: harkaq-trace-build.sh <receta.toml> [store] [outdir]}"
|
|
STORE="${2:-./store}"
|
|
OUT="${3:-/tmp/harkaq-trace-pilot}"
|
|
HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"
|
|
TRACE="${TRACE:-/tmp/harkaq-trace}"
|
|
NORM="${NORM:-scripts/harkaq/harkaq-trace-norm.py}"
|
|
mkdir -p "$OUT"; rm -f "$OUT"/traza-fase-*.txt "$OUT"/canonica.txt "$OUT"/resumen.txt
|
|
|
|
# bwraps que YA vivían (builds ajenos): fuera del piloto. El `|| true` importa: sin bwraps
|
|
# pgrep sale 1 y, bajo pipefail, mataría el script en el arranque (medido, no teórico).
|
|
YA=" $(pgrep -x bwrap 2>/dev/null | tr '\n' ' ' || true) "
|
|
|
|
"$HAMMER" --store "$STORE" build "$RECETA" > "$OUT/build.out" 2> "$OUT/build.log" &
|
|
BPID=$!
|
|
|
|
fase=0
|
|
declare -A TRAZADO
|
|
while kill -0 "$BPID" 2>/dev/null; do
|
|
for p in $(pgrep -x bwrap 2>/dev/null || true); do
|
|
case "$YA" in *" $p "*) continue ;; esac
|
|
[ -n "${TRAZADO[$p]:-}" ] && continue
|
|
TRAZADO[$p]=1; fase=$((fase + 1))
|
|
# El tracer vive lo que viva SU bwrap: el cmd interno es un latido sobre el pid.
|
|
"$TRACE" --fs "/proc/$p/root" -o "$OUT/traza-fase-$fase.txt" -- \
|
|
sh -c "while kill -0 $p 2>/dev/null; do sleep 0.1; done" 2>> "$OUT/tracer.log" &
|
|
done
|
|
sleep 0.05
|
|
done
|
|
RC=0; wait "$BPID" || RC=$?
|
|
wait || true # los tracers mueren con su bwrap y drenan la cola
|
|
|
|
cat "$OUT"/traza-fase-*.txt > "$OUT/cruda-total.txt" 2>/dev/null || : > "$OUT/cruda-total.txt"
|
|
python3 "$NORM" "$OUT/cruda-total.txt" > "$OUT/canonica.txt"
|
|
|
|
# T1.3 (sello): b3 si hay b3sum; si no, sha256 MARCADO provisional — el sello que viaja
|
|
# junto al of_tree debe ser b3 (mismo espacio de nombres del store), esto es el piloto.
|
|
if command -v b3sum >/dev/null 2>&1; then
|
|
echo "b3:$(b3sum --no-names "$OUT/canonica.txt")" > "$OUT/sello.txt"
|
|
else
|
|
echo "sha256(PROVISIONAL):$(sha256sum "$OUT/canonica.txt" | cut -d' ' -f1)" > "$OUT/sello.txt"
|
|
fi
|
|
|
|
# Declaradas vs USADAS — la señal de poda (T1.4) y el uso del runtime base (Q2 positivo).
|
|
# Cada dep aporta un árbol al overlay fundido en /: sus paths de artefacto SON los paths
|
|
# de jaula. `usadas/total` por dep; lo tocado que ninguna dep aporta = base Alpine.
|
|
deps=$(sed -n '/^\[deps\]/,/^\[.*\]/p' "$RECETA" | grep -oE '"[a-zA-Z0-9_-]+"' | tr -d '"' || true)
|
|
: > "$OUT/atribuidas.txt"
|
|
{
|
|
echo "== declaradas vs usadas ($RECETA) =="
|
|
for d in $deps; do
|
|
art=$(ls -d "$STORE"/*-"$d" 2>/dev/null | head -1) || true
|
|
if [ -z "$art" ]; then echo " ?/? $d (sin artefacto en el store)"; continue; fi
|
|
cd "$art"; find . -type f | sed 's|^\.||' | sort > /tmp/.dep-files.$$; cd - >/dev/null
|
|
n=$(comm -12 /tmp/.dep-files.$$ <(sort "$OUT/canonica.txt") | wc -l)
|
|
comm -12 /tmp/.dep-files.$$ <(sort "$OUT/canonica.txt") >> "$OUT/atribuidas.txt"
|
|
tot=$(wc -l < /tmp/.dep-files.$$)
|
|
printf "%6d/%-6d %s\n" "$n" "$tot" "$d"
|
|
rm -f /tmp/.dep-files.$$
|
|
done
|
|
base=$(comm -23 <(sort "$OUT/canonica.txt") <(sort -u "$OUT/atribuidas.txt") | wc -l)
|
|
echo " base (sin dep que lo aporte): $base paths — el runtime base de Q2, medido POSITIVO"
|
|
echo " sello: $(cat "$OUT/sello.txt")"
|
|
echo " build rc=$RC — $(tail -1 "$OUT/build.out" 2>/dev/null || echo '(sin hash)')"
|
|
} | tee "$OUT/resumen.txt"
|
|
exit "$RC"
|