tawasuyu

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 1433Shell 145Markdown 87Rust 852973 Definitions

⎇ 46a2d777d35d5cc1d2e65861f05c04d679c91b37 scripts/hammer-live-install.sh Shell · 152 lines · 7.1 KB History raw

auto-recover al arranque: crate hammer-recover + hook /sbin/init (E4 #4b) be881ad09 · sergio ·

1#!/bin/sh
2# hammer-install — instalador a disco DESDE el medio live (Etapa E5 / refinamiento #1).
3#
4# Se inyecta en el rootfs del producto como /usr/bin/hammer-install (ver scripts/iso-image.sh
5# INSTALLER=1). Corre DENTRO del live, como root real (arje-zero es PID1) ⇒ NO necesita unshare -r
6# ni los rodeos rootless de install-image.sh: particiona, formatea, monta y copia con privilegios
7# reales, usando sólo herramientas que el producto ya trae (busybox fdisk/mke2fs/mount/dd + uutils cp).
8#
9# El sistema que se instala es EL PROPIO LIVE: la raíz en RAM se copia al disco (autoinstalador). El
10# payload de arranque (kernel + GRUB) viaja en /usr/lib/hammer/install/, armado en build-time (el host
11# tiene grub-mkimage; el live no lo necesita).
12#
13# Layout en disco (MBR, no GPT — más simple y busybox-friendly; GRUB va en el hueco post-MBR):
14#   /dev/<dev>1  /                ext2(montable ext4)   + /boot/bzImage + /boot/grub + wrapper /sbin/init
15#   /dev/<dev>2  /store           ext2
16#   /dev/<dev>3  /var/lib/hammer  ext2
17#
18# Cadena de arranque del disco resultante: BIOS → MBR (boot.img) → core.img (hueco post-MBR) →
19# (hd0,msdos1)/boot/grub/grub.cfg → linux /boot/bzImage root=/dev/<dev>1 → wrapper /sbin/init.
20#
21# Uso (en el live):  hammer-install /dev/vdb [ROOT_MB] [STORE_MB]
22set -eu
23
24DEV="${1:-/dev/vdb}"
25ROOT_MB="${2:-1500}"
26STORE_MB="${3:-400}"     # /var/lib/hammer toma el resto
27PAYLOAD=/usr/lib/hammer/install
28BB=/bin/busybox
29
30[ -b "$DEV" ] || { echo "hammer-install: $DEV no es un block device" >&2; exit 1; }
31[ -d "$PAYLOAD" ] || { echo "hammer-install: falta el payload $PAYLOAD (¿ISO sin INSTALLER=1?)" >&2; exit 1; }
32[ -r "$PAYLOAD/grub/boot.img" ] && [ -r "$PAYLOAD/grub/core.img" ] || { echo "hammer-install: payload GRUB incompleto" >&2; exit 1; }
33[ -r "$PAYLOAD/kernel/bzImage" ] || { echo "hammer-install: falta el kernel en el payload" >&2; exit 1; }
34
35echo "==> hammer-install: instalando el sistema live en $DEV (root ${ROOT_MB}M, store ${STORE_MB}M, estado=resto)"
36echo "    ¡esto BORRA $DEV!"
37
38# --- particionar MBR con busybox fdisk (3 primarias; p1 bootable) ---
39# Pasamos sectores de inicio/fin EXPLÍCITOS para las tres: busybox fdisk, al pedir el inicio por
40# defecto, ofrece el sector LIBRE MÁS BAJO (= el hueco 63..2047 que dejamos antes de p1) ⇒ con <enter>
41# colocaría p2 en ese hueco. Por eso computamos los sectores y los tecleamos.
42#   p1 ARRANCA EN 2048 (1 MiB) A PROPÓSITO: deja un hueco post-MBR de 2047 sectores para el core.img de
43#   GRUB (~281 sectores). El default CHS de busybox (sector 63 ⇒ hueco de 62) lo DESBORDA, pisando el
44#   filesystem de p1 ⇒ GRUB cae a `grub>`.
45SPM=2048
46P1S=2048;                  P1E=$(( P1S + ROOT_MB  * SPM - 1 ))
47P2S=$(( P1E + 1 ));        P2E=$(( P2S + STORE_MB * SPM - 1 ))
48P3S=$(( P2E + 1 ))         # p3 toma hasta el final del disco (último sector = default)
49echo "==> particionando $DEV (MBR: p1 ${P1S}-${P1E}, p2 ${P2S}-${P2E}, p3 ${P3S}-fin)"
50"$BB" fdisk "$DEV" >/dev/null 2>&1 <<FDISK || true
51o
52n
53p
541
55$P1S
56$P1E
57n
58p
592
60$P2S
61$P2E
62n
63p
643
65$P3S
66
67a
681
69w
70FDISK
71"$BB" partprobe "$DEV" 2>/dev/null || true
72"$BB" sync; sleep 1
73
74P1="${DEV}1"; P2="${DEV}2"; P3="${DEV}3"
75for p in "$P1" "$P2" "$P3"; do
76    [ -b "$p" ] || { echo "hammer-install: no apareció la partición $p tras particionar" >&2; exit 1; }
77done
78
79# --- formatear (busybox mke2fs = ext2; el driver ext4 del kernel lo monta) ---
80echo "==> formateando particiones (ext2, montables como ext4)"
81"$BB" mke2fs -F -L hammer-root  "$P1" >/dev/null 2>&1
82"$BB" mke2fs -F -L hammer-store "$P2" >/dev/null 2>&1
83"$BB" mke2fs -F -L hammer-state "$P3" >/dev/null 2>&1
84
85# --- copiar la raíz del live a la partición root, excluyendo virtuales + el payload ---
86MNT=/run/hammer-install
87"$BB" mkdir -p "$MNT"
88"$BB" mount -t ext4 "$P1" "$MNT"
89echo "==> copiando la raíz del live → $P1 (excluye virtuales/efímeros, /store, /var/lib/hammer y el payload)"
90# Enumeramos TODO el top-level de / y copiamos salvo lo virtual/efímero — así no se nos escapa ningún
91# dir del producto (p.ej. /ente con la seed.card, /linuxrc). uutils cp -a preserva modos/symlinks.
92for entry in /* /.[!.]*; do
93    [ -e "$entry" ] || continue
94    name="${entry##*/}"
95    case "$name" in
96        proc|sys|dev|run|tmp|store|init) continue ;;  # virtuales/efímeros + el /init marcador del live
97        *) cp -a "$entry" "$MNT/" 2>/dev/null || true ;;
98    esac
99done
100# /var sin /var/lib/hammer (estado) — se recrea vacío como mountpoint.
101"$BB" rm -rf "$MNT/var/lib/hammer" 2>/dev/null || true
102# Quitar el payload del disco instalado (sólo sirve en el live) y recrear mountpoints.
103"$BB" rm -rf "$MNT/usr/lib/hammer/install" 2>/dev/null || true
104"$BB" mkdir -p "$MNT/store" "$MNT/var/lib/hammer" "$MNT/proc" "$MNT/sys" "$MNT/dev" "$MNT/run" "$MNT/tmp" "$MNT/boot/grub/i386-pc"
105
106# --- /boot: kernel + módulos GRUB + grub.cfg, y wrapper /sbin/init (monta las particiones dedicadas) ---
107echo "==> poblando /boot (kernel + GRUB) y wrapper /sbin/init"
108cp "$PAYLOAD/kernel/bzImage" "$MNT/boot/bzImage"; "$BB" chmod 0644 "$MNT/boot/bzImage"
109cp "$PAYLOAD"/grub/i386-pc/*.mod "$MNT/boot/grub/i386-pc/" 2>/dev/null || true
110cp "$PAYLOAD"/grub/i386-pc/*.lst "$MNT/boot/grub/i386-pc/" 2>/dev/null || true
111ROOTDEV="${P1##*/}"   # p.ej. vda1 cuando el disco instalado sea el único
112cat > "$MNT/boot/grub/grub.cfg" <<CFG
113set timeout=2
114set default=0
115serial --unit=0 --speed=115200
116terminal_input serial console
117terminal_output serial console
118insmod part_msdos
119insmod ext2
120menuentry "hammer" {
121    linux /boot/bzImage console=ttyS0 root=/dev/vda1 rw rdinit=/sbin/init
122}
123CFG
124# hammer-recover: auto-sana un upgrade interrumpido al arranque (E4 #4b). Lo dejamos en /usr/sbin del
125# disco; el wrapper lo corre tras montar /store y /var/lib/hammer (que necesita) y antes de incarnar.
126if [ -x "$PAYLOAD/hammer-recover" ]; then
127    "$BB" mkdir -p "$MNT/usr/sbin"
128    cp "$PAYLOAD/hammer-recover" "$MNT/usr/sbin/hammer-recover"; "$BB" chmod 0755 "$MNT/usr/sbin/hammer-recover"
129fi
130"$BB" rm -f "$MNT/sbin/init"
131cat > "$MNT/sbin/init" <<'INIT'
132#!/bin/sh
133# Wrapper PID1: el kernel monta la partición root; montamos las dedicadas, auto-sanamos un upgrade
134# interrumpido (si lo hay) y arrancamos el init real.
135/bin/busybox mount -t ext4 /dev/vda2 /store          || echo "init: no pude montar /store (/dev/vda2)"
136/bin/busybox mount -t ext4 /dev/vda3 /var/lib/hammer  || echo "init: no pude montar /var/lib/hammer (/dev/vda3)"
137[ -x /usr/sbin/hammer-recover ] && /usr/sbin/hammer-recover || true
138exec /usr/bin/arje-zero
139INIT
140"$BB" chmod +x "$MNT/sbin/init"
141"$BB" sync
142"$BB" umount "$MNT"
143
144# --- instalar GRUB: boot.img→MBR (440 B, sin pisar la tabla de particiones) + core.img→hueco post-MBR.
145#     Con install contiguo MBR los punteros por defecto de GRUB (kernel_sector=1, blocklist=2) ya valen
146#     ⇒ NO hace falta el parcheo binario que sí pide el caso GPT de install-image.sh.
147echo "==> instalando GRUB (boot.img→MBR + core.img→hueco post-MBR)"
148"$BB" dd if="$PAYLOAD/grub/boot.img"  of="$DEV" bs=1 count=440 conv=notrunc 2>/dev/null
149"$BB" dd if="$PAYLOAD/grub/core.img"  of="$DEV" bs=512 seek=1 conv=notrunc 2>/dev/null
150"$BB" sync
151
152echo "✓ hammer-install: $DEV instalado. Reiniciá sin el medio live para arrancar del disco."