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 Definitions

⎇ main scripts/reparchar-paquete-instalador.sh Shell · 96 lines · 5.6 KB History raw

feat(instalador): la etiqueta sin e2fsprogs, que es lo que le faltaba a adoptar para arrancar f1e662831 · sergio ·

1#!/bin/sh
2# reparchar-paquete-instalador.sh — poner los GUIONES del repo dentro de un paquete ya armado.
3#
4# ── POR QUÉ EXISTE, Y QUÉ NO ES ────────────────────────────────────────────────────────────────
5# `instalador-paquete.sh` arma el paquete entero, y para eso necesita el `product-rootfs` y el
6# `linux-metal` del store. En una máquina que no tiene store —la de desarrollo— ese camino no corre,
7# y entonces un cambio en los guiones no se puede probar en metal: el paquete sigue llevando los de
8# la víspera.
9#
10# Esto hace lo único que falta en ese caso: **reemplazar los guiones**, que son texto y no dependen
11# de ningún artefacto sellado. El rootfs y el kernel del paquete quedan exactamente como estaban —
12# no se tocan, no se rearman, y por eso esto NO reemplaza a `instalador-paquete.sh`.
13#
14# Y lleva la misma comprobación que aquél, por el mismo motivo: el paquete se armó a mano dos veces
15# y a la segunda ya mentía —por fuera el script corregido, por dentro el de la víspera—. Acá, al
16# terminar, se extrae de nuevo lo que quedó adentro y se compara por sha256 contra el repo. Un
17# paquete que dice llevar el arreglo y no lo lleva es peor que uno que no lo lleva.
18#
19# Uso:  scripts/reparchar-paquete-instalador.sh <directorio-del-paquete>
20set -eu
21ROOT="$(cd "$(dirname "$0")/.." && pwd)"
22PAQ="${1:?uso: $0 <directorio del paquete>}"
23CPIO="$PAQ/takana-instalador.cpio.gz"
24[ -r "$CPIO" ] || { echo "no encuentro $CPIO" >&2; exit 1; }
25
26T="${TMPDIR:-/var/tmp}/reparchar-paquete.$$"; rm -rf "$T"; mkdir -p "$T/x"
27limpiar() { rm -rf "$T"; }
28trap limpiar EXIT
29
30echo "==> abriendo $CPIO"
31( cd "$T/x" && zcat "$CPIO" | cpio -idm --quiet )
32
33# Los guiones que viajan adentro, con su sitio. El `init` del initramfs ES `instalador-initramfs.sh`.
34copiar() {  # <origen-en-el-repo> <destino-dentro-del-cpio>
35    [ -r "$ROOT/$1" ] || { echo "falta $ROOT/$1" >&2; exit 1; }
36    mkdir -p "$(dirname "$T/x/$2")"
37    cp "$ROOT/$1" "$T/x/$2"; chmod 755 "$T/x/$2"
38    echo "    · $1 → /$2"
39}
40copiar scripts/instalador-initramfs.sh            init
41copiar scripts/takana-install-partition.sh        instalador/takana-install-partition.sh
42copiar scripts/lib/adoptar.sh                     instalador/lib/adoptar.sh
43copiar scripts/lib/usuarios-del-home.sh           instalador/lib/usuarios-del-home.sh
44copiar scripts/lib/herramientas-desde-store.sh    instalador/lib/herramientas-desde-store.sh
45# **Y el binario, que adentro del initramfs es quien pone la etiqueta** (`takana fs-label`): sin
46# e2fsprogs ahí, es el único que puede, y un paquete con el guion nuevo y el binario viejo falla
47# justo al final — con el sistema anterior ya mudado y el nuevo ya copiado.
48if [ -x "$ROOT/target/x86_64-unknown-linux-musl/release/takana" ]; then
49    cp "$ROOT/target/x86_64-unknown-linux-musl/release/takana" "$T/x/bin/takana"
50    chmod 755 "$T/x/bin/takana"
51    echo "    · target/x86_64-unknown-linux-musl/release/takana → /bin/takana"
52else
53    echo "    ⚠ no hay takana musl: el de adentro queda como estaba (sin fs-label no se adopta)" >&2
54fi
55# Y los applets que la adopción usa y no estaban enlazados: `df` mide el espacio (la guarda que
56# evita mover un sistema a un sitio donde el nuevo no entra) y `date` sella la marca de la mudanza.
57for _a in df date; do
58    [ -e "$T/x/bin/$_a" ] || { ln -sf busybox "$T/x/bin/$_a"; echo "    · /bin/$_a ⇒ busybox"; }
59done
60# Y el de afuera, que es el que mira quien abre el paquete. Que los dos sean el mismo fichero es la
61# mitad del asunto: la copia de afuera es la que se lee y la de adentro la que corre.
62cp "$ROOT/scripts/takana-install-partition.sh" "$PAQ/takana-install-partition.sh"
63mkdir -p "$PAQ/lib"
64cp "$ROOT/scripts/lib/adoptar.sh" "$ROOT/scripts/lib/usuarios-del-home.sh" \
65   "$ROOT/scripts/lib/herramientas-desde-store.sh" "$PAQ/lib/"
66
67echo "==> cerrando el paquete"
68( cd "$T/x" && find . | cpio -o -H newc --quiet | gzip -9 ) > "$T/nuevo.cpio.gz"
69mv "$T/nuevo.cpio.gz" "$CPIO"
70
71# ── LA COMPROBACIÓN: lo que quedó ADENTRO es lo del repo ───────────────────────────────────────
72echo "==> comprobando lo que quedó adentro"
73rm -rf "$T/v"; mkdir -p "$T/v"
74# Se extrae ENTERO y no por patrones: la extracción selectiva de cpio salió vacía y el banco lo
75# leyó como «el archivo no es el del repo», que es el diagnóstico contrario al verdadero. Una
76# comprobación que falla cuando no puede mirar está bien; una que falla por mirar mal, no.
77( cd "$T/v" && zcat "$CPIO" | cpio -idm --quiet )
78MAL=0
79comparar() {  # <en-el-repo> <extraído>
80    _a=$(sha256sum "$ROOT/$1" | cut -d' ' -f1)
81    _b=$(sha256sum "$T/v/$2" 2>/dev/null | cut -d' ' -f1 || echo "AUSENTE")
82    if [ "$_a" = "$_b" ]; then echo "    ✓ $2"
83    else echo "    ✗ $2 NO es el del repo ($_b)"; MAL=$((MAL+1)); fi
84}
85comparar scripts/instalador-initramfs.sh     init
86comparar scripts/takana-install-partition.sh instalador/takana-install-partition.sh
87comparar scripts/lib/adoptar.sh              instalador/lib/adoptar.sh
88comparar scripts/lib/usuarios-del-home.sh    instalador/lib/usuarios-del-home.sh
89if [ -x "$ROOT/target/x86_64-unknown-linux-musl/release/takana" ]; then
90    comparar target/x86_64-unknown-linux-musl/release/takana bin/takana
91fi
92for _a in df date; do
93    [ -e "$T/v/bin/$_a" ] && echo "    ✓ bin/$_a" || { echo "    ✗ falta bin/$_a"; MAL=$((MAL+1)); }
94done
95[ "$MAL" = "0" ] || { echo "✗ el paquete NO quedó con los guiones del repo" >&2; exit 1; }
96echo "✓ $PAQ al día ($(du -h "$CPIO" | cut -f1)) — el rootfs y el kernel quedaron intactos"