TAKANA_X con caída a HAMMER_X (ADR 0016). No es un sed: estas variables son
contrato de usuario —knobs del instalador, el entorno del worker, mirror-env.sh—
y viven en perfiles de shell y units FUERA del repo, así que un renombre duro no
falla ruidosamente: la variable no aparece, se toma el default y el build se
comporta distinto sin que nada lo diga.
Rust: takana_core::env::{var,var_os} toma el nombre canónico y deriva el viejo
cambiando el prefijo — se le pasa TAKANA_* para que un grep del nombre nuevo
encuentre todas las lecturas. 5 tests, con DOS controles negativos: sin ninguna
de las dos no hay valor, y un nombre sin prefijo no inventa una caída.
Migrados los 17 sitios directos y los indirectos que el grep no mostraba
(bases_de_mirror, las constantes de kernel_cmd, ROOT_ENV de qorpa, env_path de
recover). takana-recover lleva la caída inline: es un mini-binario que se copia
a /usr/sbin y no vale arrastrarle una dep entera por dos líneas.
Scripts: 30 lecturas pasan a default, manteniendo el
nombre INTERNO de la variable para no tocar sus 190 usos.
Y donde el script EXPORTA en vez de leer, se ponen LAS DOS (mirror-env.sh y el
fragmento in-VM de bootstrap): ahí el lector puede ser un binario viejo —worker
sin recompilar, el /usr/bin/hammer pinado del baseline— que sólo conoce HAMMER_*.
La caída sirve para lectores nuevos; los viejos necesitan que la vieja siga puesta.
Verificado de punta a punta con el binario, no sólo con unit tests: HAMMER_LAB
sigue surtiendo efecto, TAKANA_LAB hace lo mismo, y con las dos gana TAKANA_LAB.
605 tests en verde y el hash de zlib sigue en b3:dc363f26… , intacto.
Cambio de comportamiento que va aparte y hay que decir: el hostname por defecto
de una instalación nueva pasa de 'hammer' a 'takana' (sólo si no se fija ninguna
de las dos variables).
NO se tocan: las rutas /var/lib/hammer de sistemas instalados, el volid
HAMMER_LIVE del ISO, ni el namespace HARKAQ_*, que es de otro subsistema.
86 lines
4.3 KiB
Bash
Executable File
86 lines
4.3 KiB
Bash
Executable File
#!/bin/sh
|
|
# harkaq-campana.sh — bucle AUTÓNOMO del worker para la campaña harkaq. Hermano de
|
|
# farm-worker-loop.sh: muele sin esperar a nadie, 24/7, y no pregunta NADA.
|
|
#
|
|
# scripts/farm/harkaq-campana.sh [lista-de-recetas.txt]
|
|
#
|
|
# Mide, no decide: por cada receta la construye bajo la jaula y guarda los veredictos crudos en
|
|
# work/harkaq-campana/<n>.verdicts. La clasificación y la edición de recetas las hace el HUB
|
|
# (harvest-harkaq.sh, por cron), porque el store del worker es parcial y marcaría como irreducible
|
|
# lo que sí es declarable. El worker MIDE, el hub CLASIFICA.
|
|
#
|
|
# Idempotente: lo ya medido se saltea; re-correrlo sólo mide lo nuevo. Cuando no queda nada,
|
|
# duerme y re-escanea — igual que farm-worker-loop.sh.
|
|
#
|
|
# Diseñado para la NOCHE: nunca bloquea esperando una decisión. Un build que falla NO detiene la
|
|
# cola; su veredicto se guarda igual (un build que falla es justo cuando más interesa saber qué
|
|
# tocó fuera de su clausura) y se sigue. Ocho horas de idle por una pregunta es el fallo que este
|
|
# script existe para no tener.
|
|
set -u
|
|
|
|
HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
|
|
cd "$HAMMER_DIR"
|
|
LISTA="${1:-work/harkaq-cola.txt}"
|
|
OUT="work/harkaq-campana"
|
|
BIN="${HARKAQ_BIN:-/root/.cache/harkaq}"
|
|
IDLE_SLEEP="${IDLE_SLEEP:-300}"
|
|
POR_RECETA="${POR_RECETA:-900}"
|
|
mkdir -p "$OUT"
|
|
|
|
export HARKAQ=1 HARKAQ_BIN="$BIN" HARKAQ_BASE="${HARKAQ_BASE:-$BIN/base.policy}"
|
|
export HARKAQ_TIMEOUT="${HARKAQ_TIMEOUT:-300}"
|
|
|
|
# Gate 1: sin ABI>=7 el kernel no audita y TODOS los veredictos saldrían SinEvidencia. Moler la
|
|
# noche entera para producir "no sabemos" es peor que no moler.
|
|
abi=$(python3 -c 'import ctypes;print(ctypes.CDLL("libc.so.6").syscall(444,None,0,1))' 2>/dev/null)
|
|
if [ "${abi:-0}" -lt 7 ]; then
|
|
echo "ABORTO: Landlock ABI ${abi:-?} < 7 ⇒ sin audit de denegaciones. ¿La golden es la 6.17?"
|
|
exit 4
|
|
fi
|
|
|
|
# Gate 2: ¿el binario TIENE harkaq dentro? La golden hornea un `target/release/takana` viejo y el
|
|
# rsync excluye /target ⇒ si el `cargo build` del provisioning no corrió, el worker construye
|
|
# alegremente SIN LA JAULA y produce cero veredictos. Pasó: la primera corrida molió 2 recetas con
|
|
# un binario del 29/06 (0 ocurrencias de "harkaq") y las marcó "sin veredicto" como si fuera culpa
|
|
# de las recetas. Ocho horas así son la noche entera perdida — y el log diría "salteada", nunca
|
|
# "estoy ciego". Es el falso `Hermetico` de D9 mudado al orquestador: la ausencia como respuesta
|
|
# tranquilizadora.
|
|
if ! strings ./target/release/takana 2>/dev/null | grep -q harkaq; then
|
|
echo "ABORTO: ./target/release/takana NO tiene harkaq compilado (¿corrió el cargo build?)."
|
|
echo " Sin esto la campaña muele sin jaula y produce 0 veredictos, en silencio."
|
|
exit 4
|
|
fi
|
|
echo "$(date -u +%FT%TZ) campaña harkaq: ABI $abi, binario con jaula ✓, cola $LISTA"
|
|
|
|
while :; do
|
|
hechas=0; nuevas=0
|
|
while IFS= read -r n; do
|
|
[ -n "$n" ] || continue
|
|
[ -f "recipes/$n.toml" ] || continue
|
|
if [ -s "$OUT/$n.verdicts" ]; then hechas=$((hechas + 1)); continue; fi
|
|
|
|
# Forzar build real: `hammer build` pega en la caché si el artefacto ya está sellado y no
|
|
# correría nada (veredicto vacío que NO es un fallo). La copia va AL LADO del original o se
|
|
# rompe la resolución de deps.build, que son relativas al dir de la receta.
|
|
tmp="recipes/.hk-$n.toml"
|
|
sed "s/^name *= *\"$n\"/name = \"$n-hkm\"/" "recipes/$n.toml" > "$tmp"
|
|
timeout "$POR_RECETA" ./target/release/takana build "$tmp" --store "$PWD/store" \
|
|
> "$OUT/$n.log" 2>&1
|
|
rm -f "$tmp"
|
|
grep '^\[harkaq\] {' "$OUT/$n.log" | sed 's/^\[harkaq\] //' > "$OUT/$n.verdicts"
|
|
if [ -s "$OUT/$n.verdicts" ]; then
|
|
nuevas=$((nuevas + 1))
|
|
echo "$(date -u +%FT%TZ) ++ $n ($(wc -l < "$OUT/$n.verdicts") fase/s medidas)"
|
|
else
|
|
# Sin veredicto: el build ni arrancó (fetch, dep rota…). Se marca para no reintentar
|
|
# en bucle y se SIGUE — la cola no se detiene por una receta.
|
|
echo "sin-veredicto" > "$OUT/$n.skip"
|
|
rm -f "$OUT/$n.verdicts"
|
|
echo "$(date -u +%FT%TZ) ?? $n — sin veredicto, salteada (ver $OUT/$n.log)"
|
|
fi
|
|
done < "$LISTA"
|
|
|
|
echo "$(date -u +%FT%TZ) ciclo: $nuevas nuevas, $hechas ya medidas. durmiendo ${IDLE_SLEEP}s"
|
|
sleep "$IDLE_SLEEP"
|
|
done
|