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 1181Shell 82Rust 62Markdown 521515 Definitions

⎇ 2f9253886ff843d9701ac61a9c3ff4f2cd43ef33 scripts/repo-perfil.sh Shell · 83 lines · 4.1 KB History raw

repo: clave de release ESTABLE y un publicador por perfil — se acabó firmar con una clave efímera c0545ea40 · Sergio ·

1#!/bin/sh
2# repo-perfil.sh — publica en un REPOSITORIO FIRMADO la clausura entera de un perfil de
3# `targets.toml`, y verifica la firma antes de darla por buena.
4#
5# ── EN QUÉ SE DIFERENCIA DE `build-repo.sh` ─────────────────────────────────────────────────────
6# `build-repo.sh` recorre las 869 recetas del corpus con `cargo run` por cada una: sirve para el
7# dogfood del corpus completo, no para publicar UNA imagen. Acá el conjunto sale de la misma fuente
8# que la imagen —`yupana.membresia()` sobre `targets.toml`— así que **el repo y la imagen no pueden
9# divergir**: son la misma lista.
10#
11# ── LA CLAVE NO SE INVENTA ──────────────────────────────────────────────────────────────────────
12# `build-repo.sh` genera una clave EFÍMERA si no se le pasa `KEY=`. Un índice firmado con una clave
13# que nadie conoce y que cambia en cada corrida no lo verifica nadie: es decoración (SDD 19 §3.2,
14# «la firma sin gestión de claves es teatro»). Acá, si no está la clave, se ABORTA.
15#
16# Uso:   ./scripts/repo-perfil.sh [perfil]
17# Env:   PERFIL (def servidor) · STORE (def ./store) · REPO (def dist/repo)
18#        KEY (def ~/.config/takana/keys/release.ed25519) · TRUST (def ./trust) · DISTRO (def dev)
19set -eu
20ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
21
22PERFIL="${1:-${PERFIL:-servidor}}"
23STORE="${STORE:-./store}"
24REPO="${REPO:-dist/repo}"
25KEY="${KEY:-$HOME/.config/takana/keys/release.ed25519}"
26TRUST="${TRUST:-./trust}"
27DISTRO="${DISTRO:-dev}"
28TAKANA="$ROOT/target/release/takana"
29
30[ -x "$TAKANA" ] || { echo "!! falta $TAKANA (cargo build --release)" >&2; exit 2; }
31[ -r "$KEY" ] || {
32    echo "!! no encuentro la clave de firma: $KEY" >&2
33    echo "   NO se genera una efímera a propósito: un índice firmado con una clave que nadie" >&2
34    echo "   conoce no lo verifica nadie. Generá la del proyecto una sola vez con:" >&2
35    echo "     takana keygen release --out ~/.config/takana/keys" >&2
36    echo "   y publicá la .pub en $TRUST/ (ver trust/README.md)." >&2
37    exit 2
38}
39
40# El conjunto sale de targets.toml, igual que la imagen.
41LISTA=$(python3 - "$PERFIL" <<'PY'
42import sys, os
43sys.path.insert(0, os.path.abspath("scripts"))
44import yupana, targets as targets_mod
45perfil = sys.argv[1]
46perfiles = targets_mod.load()
47if perfil not in perfiles:
48    sys.exit("perfil desconocido: %s" % perfil)
49memb = yupana.membresia(yupana.cargar_colas(), perfiles)
50for cola, nombre in sorted(n for n, ps in memb.items() if perfil in ps and n[0] != "wanted"):
51    if cola == "corpus":
52        print(nombre)
53PY
54)
55total=$(printf '%s\n' "$LISTA" | grep -c .)
56echo "==> perfil '$PERFIL': $total paquetes en la clausura → $REPO"
57
58rm -rf "$REPO"; mkdir -p "$REPO"
59anclados=0; sin_ancla=0; fallaron=""
60for n in $LISTA; do
61    r="recipes/$n.toml"
62    [ -r "$r" ] || { fallaron="$fallaron $n(sin-receta)"; continue; }
63    if "$TAKANA" --store "$STORE" pack "$r" --repo "$REPO" --distro-version "$DISTRO" --build >/dev/null 2>&1; then
64        anclados=$((anclados + 1))
65    elif "$TAKANA" --store "$STORE" pack "$r" --repo "$REPO" --distro-version "$DISTRO" >/dev/null 2>&1; then
66        sin_ancla=$((sin_ancla + 1))
67    else
68        fallaron="$fallaron $n"
69    fi
70done
71
72echo "==> firmando el índice con $KEY"
73"$TAKANA" --store "$STORE" repo sign --repo "$REPO" --key "$KEY" >/dev/null
74
75# ── la guarda: que la firma VERIFIQUE, y que una alterada NO ────────────────────────────────────
76"$TAKANA" --store "$STORE" repo verify --repo "$REPO" --trust "$TRUST" >/dev/null 2>&1 \
77    || { echo "!! el índice NO verifica contra $TRUST — la clave publicada no es la que firmó" >&2; exit 1; }
78echo "==> ✓ el índice verifica contra $TRUST"
79
80echo
81echo "publicado: $anclados con expected_hash anclado, $sin_ancla sin ancla.${fallaron:+ FALLARON:$fallaron}"
82echo "repo firmado en $REPO"
83echo "  consumir:  takana install <nombre> --repo <url> --trust <trust> --require-signed"