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.
88 lines
4.3 KiB
Bash
Executable File
88 lines
4.3 KiB
Bash
Executable File
#!/bin/sh
|
|
# harkaq-campana-vol.sh <mi-nombre> — bucle de medición con VOLUMEN + AUTO-SHUTDOWN.
|
|
#
|
|
# Igual que harkaq-campana.sh, con dos cambios que cierran los dos huecos de la 1ª campaña:
|
|
# 1. Escribe cada veredicto al VOLUMEN (/mnt/cosecha/verdicts), que sobrevive a la destrucción
|
|
# del worker ⇒ no dependo de estar viva para no perder el trabajo.
|
|
# 2. AUTO-SHUTDOWN: tras IDLE_CICLOS ciclos con 0 mediciones nuevas, el worker SE AUTO-ELIMINA.
|
|
# En Hetzner un server apagado sigue cobrando ⇒ apagar de verdad es `hcloud server delete`.
|
|
# Es lo que la 1ª campaña NO tenía: quedó idle ~4h cobrando sin producir.
|
|
set -u
|
|
|
|
MI_NOMBRE="${1:?uso: harkaq-campana-vol.sh <mi-nombre>}"
|
|
HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
|
|
cd "$HAMMER_DIR"
|
|
LISTA="${LISTA:-work/harkaq-cola.txt}"
|
|
VOL_OUT="/mnt/cosecha"
|
|
OUT="work/harkaq-campana" # local (rápido); se COPIA al volumen tras cada medición
|
|
BIN="${HARKAQ_BIN:-/root/.cache/harkaq}"
|
|
IDLE_SLEEP="${IDLE_SLEEP:-300}"
|
|
POR_RECETA="${POR_RECETA:-900}"
|
|
IDLE_CICLOS="$(cat /etc/harkaq-idle-ciclos 2>/dev/null || echo 3)"
|
|
mkdir -p "$OUT" "$VOL_OUT/verdicts" "$VOL_OUT/logs"
|
|
|
|
export HARKAQ=1 HARKAQ_BIN="$BIN" HARKAQ_BASE="${HARKAQ_BASE:-$BIN/base.policy}"
|
|
export HARKAQ_TIMEOUT="${HARKAQ_TIMEOUT:-300}"
|
|
|
|
# Los dos gates de siempre: ABI>=7 y el binario CON jaula. Sin ellos la campaña muele y produce
|
|
# SinEvidencia (o cero) en silencio — el falso `Hermetico` de D9 mudado al orquestador.
|
|
abi=$(python3 -c 'import ctypes;print(ctypes.CDLL("libc.so.6").syscall(444,None,0,1))' 2>/dev/null)
|
|
[ "${abi:-0}" -ge 7 ] || { echo "ABORTO: Landlock ABI ${abi:-?} < 7"; exit 4; }
|
|
strings ./target/release/takana 2>/dev/null | grep -q harkaq || { echo "ABORTO: el binario no tiene la jaula"; exit 4; }
|
|
echo "$(date -u +%FT%TZ) campaña-vol: ABI $abi, jaula ✓, auto-shutdown tras $IDLE_CICLOS ciclos idle"
|
|
|
|
autodestruir() {
|
|
echo "$(date -u +%FT%TZ) $MI_NOMBRE: $IDLE_CICLOS ciclos idle ⇒ AUTO-ELIMINACIÓN. Cosechas en el volumen."
|
|
cp -f /var/log/harkaq-vol.log "$VOL_OUT/logs/$MI_NOMBRE.log" 2>/dev/null || true
|
|
sync
|
|
# API REST con curl, NO el CLI de hcloud: la golden (Ubuntu base) no trae hcloud, y depender de
|
|
# instalarlo haría fallar la pieza central. curl + el metadata service SIEMPRE están. El ID
|
|
# propio se saca del metadata (169.254.169.254), no del nombre — más robusto ante renombrados.
|
|
id=$(curl -sf http://169.254.169.254/hetzner/v1/metadata/instance-id 2>/dev/null)
|
|
tok=$(cat /root/.hcloud-token 2>/dev/null)
|
|
if [ -n "$id" ] && [ -n "$tok" ]; then
|
|
curl -sf -X DELETE -H "Authorization: Bearer $tok" \
|
|
"https://api.hetzner.cloud/v1/servers/$id" >/dev/null 2>&1 &
|
|
fi
|
|
# Fallback si la API no responde: apagar. Sigue cobrando (Hetzner cobra el server apagado) pero
|
|
# al menos deja de moler en vano; el `status` mostrará el server off para borrarlo a mano.
|
|
sleep 45; poweroff
|
|
}
|
|
|
|
idle=0
|
|
while :; do
|
|
nuevas=0
|
|
while IFS= read -r n; do
|
|
[ -n "$n" ] || continue
|
|
[ -f "recipes/$n.toml" ] || continue
|
|
[ -s "$VOL_OUT/verdicts/$n.verdicts" ] && continue # ya medida (en el volumen)
|
|
|
|
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"
|
|
# El sufijo -hkm sella un artefacto que después pega en caché y bloquea la re-medición
|
|
# (envenenó bash/binutils en la 1ª campaña). Se borra tras medir.
|
|
rm -rf store/*-"$n"-hkm 2>/dev/null || true
|
|
grep '^\[harkaq\] {' "$OUT/$n.log" | sed 's/^\[harkaq\] //' > "$OUT/$n.verdicts"
|
|
if [ -s "$OUT/$n.verdicts" ]; then
|
|
cp -f "$OUT/$n.verdicts" "$VOL_OUT/verdicts/$n.verdicts"; sync
|
|
nuevas=$((nuevas + 1))
|
|
echo "$(date -u +%FT%TZ) ++ $n → volumen"
|
|
else
|
|
echo "sin-veredicto" > "$VOL_OUT/verdicts/$n.skip"
|
|
echo "$(date -u +%FT%TZ) ?? $n — sin veredicto"
|
|
fi
|
|
done < "$LISTA"
|
|
|
|
if [ "$nuevas" -eq 0 ]; then
|
|
idle=$((idle + 1))
|
|
echo "$(date -u +%FT%TZ) ciclo idle $idle/$IDLE_CICLOS"
|
|
[ "$idle" -ge "$IDLE_CICLOS" ] && { autodestruir; exit 0; }
|
|
else
|
|
idle=0
|
|
fi
|
|
sleep "$IDLE_SLEEP"
|
|
done
|