gioser

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 Sutichaykuna

⎇ aacee245d63a789009844ead49b21492960f996b scripts/farm/harkaq-campana-vol.sh Shell · 87 siq'ikuna · 4.3 KB Ñawpa willay ch'uya

takana: el worker pasa a /opt/takana y takana-farm.service aacee245d · Sergio ·

1#!/bin/sh
2# harkaq-campana-vol.sh <mi-nombre> — bucle de medición con VOLUMEN + AUTO-SHUTDOWN.
3#
4# Igual que harkaq-campana.sh, con dos cambios que cierran los dos huecos de la 1ª campaña:
5#   1. Escribe cada veredicto al VOLUMEN (/mnt/cosecha/verdicts), que sobrevive a la destrucción
6#      del worker ⇒ no dependo de estar viva para no perder el trabajo.
7#   2. AUTO-SHUTDOWN: tras IDLE_CICLOS ciclos con 0 mediciones nuevas, el worker SE AUTO-ELIMINA.
8#      En Hetzner un server apagado sigue cobrando ⇒ apagar de verdad es `hcloud server delete`.
9#      Es lo que la 1ª campaña NO tenía: quedó idle ~4h cobrando sin producir.
10set -u
11
12MI_NOMBRE="${1:?uso: harkaq-campana-vol.sh <mi-nombre>}"
13HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/takana}}"
14cd "$HAMMER_DIR"
15LISTA="${LISTA:-work/harkaq-cola.txt}"
16VOL_OUT="/mnt/cosecha"
17OUT="work/harkaq-campana"        # local (rápido); se COPIA al volumen tras cada medición
18BIN="${HARKAQ_BIN:-/root/.cache/harkaq}"
19IDLE_SLEEP="${IDLE_SLEEP:-300}"
20POR_RECETA="${POR_RECETA:-900}"
21IDLE_CICLOS="$(cat /etc/harkaq-idle-ciclos 2>/dev/null || echo 3)"
22mkdir -p "$OUT" "$VOL_OUT/verdicts" "$VOL_OUT/logs"
23
24export HARKAQ=1 HARKAQ_BIN="$BIN" HARKAQ_BASE="${HARKAQ_BASE:-$BIN/base.policy}"
25export HARKAQ_TIMEOUT="${HARKAQ_TIMEOUT:-300}"
26
27# Los dos gates de siempre: ABI>=7 y el binario CON jaula. Sin ellos la campaña muele y produce
28# SinEvidencia (o cero) en silencio — el falso `Hermetico` de D9 mudado al orquestador.
29abi=$(python3 -c 'import ctypes;print(ctypes.CDLL("libc.so.6").syscall(444,None,0,1))' 2>/dev/null)
30[ "${abi:-0}" -ge 7 ] || { echo "ABORTO: Landlock ABI ${abi:-?} < 7"; exit 4; }
31strings ./target/release/takana 2>/dev/null | grep -q harkaq || { echo "ABORTO: el binario no tiene la jaula"; exit 4; }
32echo "$(date -u +%FT%TZ) campaña-vol: ABI $abi, jaula ✓, auto-shutdown tras $IDLE_CICLOS ciclos idle"
33
34autodestruir() {
35    echo "$(date -u +%FT%TZ) $MI_NOMBRE: $IDLE_CICLOS ciclos idle ⇒ AUTO-ELIMINACIÓN. Cosechas en el volumen."
36    cp -f /var/log/harkaq-vol.log "$VOL_OUT/logs/$MI_NOMBRE.log" 2>/dev/null || true
37    sync
38    # API REST con curl, NO el CLI de hcloud: la golden (Ubuntu base) no trae hcloud, y depender de
39    # instalarlo haría fallar la pieza central. curl + el metadata service SIEMPRE están. El ID
40    # propio se saca del metadata (169.254.169.254), no del nombre — más robusto ante renombrados.
41    id=$(curl -sf http://169.254.169.254/hetzner/v1/metadata/instance-id 2>/dev/null)
42    tok=$(cat /root/.hcloud-token 2>/dev/null)
43    if [ -n "$id" ] && [ -n "$tok" ]; then
44        curl -sf -X DELETE -H "Authorization: Bearer $tok" \
45            "https://api.hetzner.cloud/v1/servers/$id" >/dev/null 2>&1 &
46    fi
47    # Fallback si la API no responde: apagar. Sigue cobrando (Hetzner cobra el server apagado) pero
48    # al menos deja de moler en vano; el `status` mostrará el server off para borrarlo a mano.
49    sleep 45; poweroff
50}
51
52idle=0
53while :; do
54    nuevas=0
55    while IFS= read -r n; do
56        [ -n "$n" ] || continue
57        [ -f "recipes/$n.toml" ] || continue
58        [ -s "$VOL_OUT/verdicts/$n.verdicts" ] && continue   # ya medida (en el volumen)
59
60        tmp="recipes/.hk-$n.toml"
61        sed "s/^name *= *\"$n\"/name = \"$n-hkm\"/" "recipes/$n.toml" > "$tmp"
62        timeout "$POR_RECETA" ./target/release/takana build "$tmp" --store "$PWD/store" \
63            > "$OUT/$n.log" 2>&1
64        rm -f "$tmp"
65        # El sufijo -hkm sella un artefacto que después pega en caché y bloquea la re-medición
66        # (envenenó bash/binutils en la 1ª campaña). Se borra tras medir.
67        rm -rf store/*-"$n"-hkm 2>/dev/null || true
68        grep '^\[harkaq\] {' "$OUT/$n.log" | sed 's/^\[harkaq\] //' > "$OUT/$n.verdicts"
69        if [ -s "$OUT/$n.verdicts" ]; then
70            cp -f "$OUT/$n.verdicts" "$VOL_OUT/verdicts/$n.verdicts"; sync
71            nuevas=$((nuevas + 1))
72            echo "$(date -u +%FT%TZ) ++ $n → volumen"
73        else
74            echo "sin-veredicto" > "$VOL_OUT/verdicts/$n.skip"
75            echo "$(date -u +%FT%TZ) ?? $n — sin veredicto"
76        fi
77    done < "$LISTA"
78
79    if [ "$nuevas" -eq 0 ]; then
80        idle=$((idle + 1))
81        echo "$(date -u +%FT%TZ) ciclo idle $idle/$IDLE_CICLOS"
82        [ "$idle" -ge "$IDLE_CICLOS" ] && { autodestruir; exit 0; }
83    else
84        idle=0
85    fi
86    sleep "$IDLE_SLEEP"
87done