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 815Rust 56Shell 37Markdown 291229 Definiciones

⎇ 36152da9284ad15039abe44e3cb91ef42aa43bb7 scripts/instalador-paquete.sh Shell · 102 líneas · 6.5 KB Historia crudo

primero se elige, después se salta — y sólo si hace falta (SDD 32) 36152da92 · Sergio ·

1#!/bin/sh
2# instalador-paquete.sh — arma el PAQUETE que se copia a la máquina donde se va a instalar.
3#
4# ══ POR QUÉ EXISTE ════════════════════════════════════════════════════════════════════════════
5# El paquete se armó a mano dos veces y a la segunda ya mentía: por fuera llevaba el
6# `takana-install-partition.sh` corregido y por dentro —dentro del initramfs, que es el que de
7# verdad corre— el de la víspera. **Un paquete que se arma a mano deriva de sus piezas en silencio**,
8# y la parte que deriva es justamente la que nadie mira porque está comprimida.
9#
10# Acá se arma entero y se COMPRUEBA que lo de adentro y lo de afuera sean el mismo fichero.
11#
12# ── LAS DOS PIEDRAS DEL HUB, QUE NO SON DE ESTE SCRIPT ─────────────────────────────────────────
13#   · `install-image-efi.sh` busca el rootfs y el kernel en `store/` —el enlace del clon, que en
14#     este hub está VACÍO— y no en `/store`, que es donde están. Por eso acá se resuelven y se
15#     pasan explícitos.
16#   · el staging ENLAZA desde el rootfs y `linkat()` no cruza un punto de montaje: con el rootfs en
17#     `/store` y el stage en `/work` sale EXDEV. Se copia el rootfs una vez a este lado.
18#
19# Uso:  scripts/instalador-paquete.sh [--salida <dir>]
20# Vars: ROOTFS KERNEL (si se saben) · SALIDA (def work/instalador-salida)
21set -eu
22ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
23SALIDA="${SALIDA:-work/instalador-salida}"
24[ "${1:-}" = "--salida" ] && { SALIDA="${2:?}"; shift 2; }
25
26TAKANA="${TAKANA:-$ROOT/target/release/takana}"
27[ -x "$TAKANA" ] || { echo "no hay binario en $TAKANA (cargo build --release -p takana-cli)" >&2; exit 1; }
28
29# ── el rootfs y el kernel, resueltos a este lado del montaje ──────────────────────────────────
30if [ -z "${ROOTFS:-}" ]; then
31    _src=$(ls -dt /store/*-product-rootfs store/*-product-rootfs 2>/dev/null | head -1)
32    [ -n "${_src:-}" ] || { echo "no encuentro ningún product-rootfs (set ROOTFS=)" >&2; exit 1; }
33    ROOTFS="work/.rootfs-local/$(basename "$_src")"
34    if [ ! -d "$ROOTFS" ]; then
35        echo "==> copiando $_src → $ROOTFS (una vez, por EXDEV)"
36        mkdir -p work/.rootfs-local; cp -a "$_src" "$ROOTFS"
37    fi
38fi
39if [ -z "${KERNEL:-}" ]; then
40    KERNEL=$(ls -dt /store/*-linux-metal/boot/bzImage store/*-linux-metal/boot/bzImage 2>/dev/null | head -1)
41    [ -n "${KERNEL:-}" ] || { echo "no encuentro un bzImage de linux-metal (set KERNEL=)" >&2; exit 1; }
42fi
43echo "==> rootfs: $ROOTFS"
44echo "==> kernel: $KERNEL"
45
46mkdir -p "$SALIDA/kernel/boot" "$SALIDA/lib"
47
48# ── 1) el instalador en RAM (es lo caro: arma el stage y comprime ~130 M) ──────────────────────
49echo "==> initramfs del instalador"
50ROOTFS="$ROOTFS" KERNEL="$KERNEL" OUT="$SALIDA/takana-instalador.cpio.gz" ./scripts/instalador-initramfs.sh
51
52# ── 2) lo que va al lado ──────────────────────────────────────────────────────────────────────
53# `rm -f` antes de cada `cp`: lo que sale del store viene en modo 0444 y un `cp` encima falla con
54# «Permission denied», que en un script de empaquetado se lee como un problema de permisos del
55# usuario y no como lo que es — el fichero de la corrida anterior, que es de sólo lectura.
56poner() { rm -f "$2"; cp "$1" "$2"; chmod "${3:-0644}" "$2"; }
57poner "$TAKANA" "$SALIDA/takana" 0755
58poner "$KERNEL" "$SALIDA/kernel/boot/bzImage"
59poner scripts/takana-install-partition.sh "$SALIDA/takana-install-partition.sh" 0755
60poner scripts/lib/herramientas-desde-store.sh "$SALIDA/lib/herramientas-desde-store.sh"
61# `busybox` viaja suelto en el paquete —2 MiB— y no es redundante: es con lo que se desempaqueta el
62# árbol a instalar cuando NO hace falta saltar. El host puede no tener `cpio` ni `gzip` (en las tres
63# máquinas de este proyecto no hay `cpio`), así que depender de los del sistema ajeno es depender de
64# algo que ya sabemos que falta.
65_bb="${IRD_TREE:-work/.instalador-initramfs-tree}/bin/busybox"
66[ -r "$_bb" ] || { echo "no encuentro busybox en $_bb" >&2; exit 1; }
67poner "$_bb" "$SALIDA/busybox" 0755
68
69# ── 3) la comprobación que justifica este script ──────────────────────────────────────────────
70# El censo que el usuario corre ANTES de saltar (`takana metal survey`, el de afuera) y el que
71# corre el instalador DESPUÉS del salto (el de adentro del initramfs) tienen que ser el mismo
72# fichero. Si divergen, el usuario elige mirando una clasificación y el instalador formatea según
73# otra — y el que decide es el de adentro, que es el que nadie miró.
74echo "==> coherencia: el censo de afuera y el de adentro"
75. "$(dirname "$0")/lib/herramientas-desde-store.sh"
76CPIO=$(herramienta libarchive usr/bin/bsdcpio cpio) || exit 1
77GZIP=$(herramienta gzip bin/gzip gzip)              || exit 1
78_tmp="work/.paquete-verif"; rm -rf "$_tmp"; mkdir -p "$_tmp"
79( cd "$_tmp" && "$GZIP" -d -c "$ROOT/$SALIDA/takana-instalador.cpio.gz" 2>/dev/null \
80    | "$CPIO" -i -d --quiet '*takana-install-partition.sh' 2>/dev/null ) || true
81# `-d` (crear directorios) no es opcional: sin él bsdcpio contesta «Can't create
82# 'instalador/takana-install-partition.sh'» porque el directorio no existe, y con `2>/dev/null`
83# eso se ve exactamente igual que un archivo que no trae el fichero.
84_dentro="$_tmp/instalador/takana-install-partition.sh"
85if [ ! -r "$_dentro" ]; then
86    echo "   ✗ no pude sacar el censo de adentro del initramfs — no puedo afirmar que coincidan" >&2
87    rm -rf "$_tmp"; exit 1
88fi
89_a=$(sha256sum "$_dentro" | cut -d' ' -f1)
90_b=$(sha256sum scripts/takana-install-partition.sh | cut -d' ' -f1)
91rm -rf "$_tmp"
92[ "$_a" = "$_b" ] || {
93    echo "   ✗ el censo de adentro del initramfs NO es el del repo ($(echo "$_a"|cut -c1-12) vs $(echo "$_b"|cut -c1-12))" >&2
94    echo "     El instalador decidiría con una clasificación distinta de la que el usuario vio." >&2
95    exit 1; }
96echo "   ✓ el mismo fichero adentro y afuera ($(echo "$_a" | cut -c1-12))"
97
98echo
99echo "✓ paquete en $SALIDA  ($(du -sm "$SALIDA" | cut -f1) MiB)"
100ls -l "$SALIDA"
101echo
102echo "En la máquina donde se instala:  sudo ./takana metal check → survey → install"