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 1574Shell 204Rust 111Markdown 993763 Sutichaykuna

⎇ main scripts/product-image.sh Shell · 69 siq'ikuna · 4.2 KB Ñawpa willay ch'uya

takana etapa 5c: comentarios de scripts, MOTD, y un BUG que introdujo la etapa 4 476168bb0 · Sergio ·

1#!/usr/bin/env bash
2# product-image.sh — empaqueta el `product-rootfs` (lean: 4/4 + userland Rust + sshd, SIN toolchain)
3# como imagen de disco AUTO-BOOTEABLE (GRUB BIOS), reusando scripts/install-image.sh. Es el cierre del
4# pipeline: del artefacto sellado por `takana bootstrap product` a un disco que arranca solo en QEMU
5# (`-drive file=img`, sin -kernel) y, con red, sirve SSH.
6#
7# A diferencia de install-image.sh (que por defecto empaqueta el BUILDER rootfs con todo el toolchain),
8# acá la root es el product-rootfs lean ⇒ imagen de PRODUCTO, no de self-host.
9#
10# Uso:   PRODUCT=<hash|prefijo> ./scripts/product-image.sh         # crea work/hammer-product.img
11#        PRODUCT=<...> BOOT=1 ./scripts/product-image.sh            # además auto-bootea + handshake SSH
12# Vars:  KERNEL  IMG (def work/hammer-product.img)  KVM (def 1)  MEM (def 2048)  PORT (def 2224)
13#        DEADLINE (def 150, sólo con BOOT=1)
14set -euo pipefail
15ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
16IMG="${IMG:-work/hammer-product.img}"; KVM="${KVM:-1}"; MEM="${MEM:-2048}"; PORT="${PORT:-2224}"
17DEADLINE="${DEADLINE:-150}"; WORK="$ROOT/work/product-image"
18
19if [ -n "${PRODUCT:-}" ]; then
20  PDIR=$(ls -d store/"${PRODUCT#b3:}"*-product-rootfs 2>/dev/null | head -1)
21else
22  PDIR=$(ls -dt store/*-product-rootfs 2>/dev/null | head -1)
23fi
24[ -n "$PDIR" ] && [ -d "$PDIR" ] || { echo "no encuentro product-rootfs (corré 'hammer bootstrap product')"; exit 1; }
25echo "==> product-rootfs: $PDIR"
26
27# copia escribible del artefacto sellado (read-only); no tocamos el store
28rm -rf "$WORK"; mkdir -p "$WORK"; RFS="$WORK/rootfs"
29cp -a "$PDIR"/. "$RFS"/; chmod -R u+w "$RFS"; rm -rf "$RFS/.hammer"
30
31# provisión de admin: authorized_keys de prueba (lo único no horneado en el producto)
32KG=$(ls store/*-openssh/usr/bin/ssh-keygen | head -1)
33"$KG" -t ed25519 -N '' -f "$WORK/clientkey" -q
34install -d -m 0700 "$RFS/root/.ssh"
35cat "$WORK/clientkey.pub" > "$RFS/root/.ssh/authorized_keys"; chmod 0600 "$RFS/root/.ssh/authorized_keys"
36
37# delegar el armado del disco GRUB-booteable a install-image.sh. BOOT=0 EXPLÍCITO: nuestro BOOT=1 está
38# en el entorno y se heredaría a install-image.sh, que haría su PROPIO `exec qemu` foreground (sin red)
39# y bloquearía acá para siempre. Lo aislamos para que install-image SÓLO arme la imagen.
40echo "==> armando imagen de disco (GRUB BIOS) vía install-image.sh"
41ROOTFS="$RFS" IMG="$IMG" BOOT=0 ROOT_SIZE="${ROOT_SIZE:-1024}" STORE_SIZE="${STORE_SIZE:-512}" \
42  STATE_SIZE="${STATE_SIZE:-512}" sh ./scripts/install-image.sh
43echo "==> imagen de producto: $IMG"
44
45[ "${BOOT:-0}" = 1 ] || { echo "(set BOOT=1 para auto-bootear + probar SSH)"; exit 0; }
46
47# auto-boot (sin -kernel, GRUB del disco) + red slirp hostfwd para el handshake
48accel=(-cpu Broadwell); { [ "$KVM" = 1 ] && [ -w /dev/kvm ]; } && accel=(-enable-kvm -cpu host)
49echo "==> AUTO-BOOT (sin -kernel) + hostfwd :$PORT->:22"
50qemu-system-x86_64 -m "$MEM" -no-reboot -nographic "${accel[@]}" \
51  -drive file="$IMG",format=raw,if=virtio \
52  -netdev "user,id=n0,hostfwd=tcp::$PORT-:22" -device e1000,netdev=n0 > "$WORK/console.log" 2>&1 &
53QPID=$!; trap 'kill $QPID 2>/dev/null || true' EXIT
54SSHOPTS=(-p "$PORT" -i "$WORK/clientkey" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
55         -o GlobalKnownHostsFile=/dev/null -o PasswordAuthentication=no -o ConnectTimeout=4 -o LogLevel=ERROR)
56echo "==> esperando handshake desde el disco auto-booteado (deadline ${DEADLINE}s)…"
57start=$(date +%s); ok=0
58while [ $(( $(date +%s) - start )) -lt "$DEADLINE" ]; do
59  kill -0 $QPID 2>/dev/null || { echo "!! QEMU murió"; break; }
60  if out=$(ssh "${SSHOPTS[@]}" root@localhost \
61        'echo PRODUCT_DISK_SSH_OK uid=$(id -u); uname -sr; ls --version 2>&1 | head -1; df -h /store /var/lib/hammer 2>/dev/null | tail -2' 2>/dev/null); then
62    echo "============ RESPUESTA DEL GUEST ============"; echo "$out"; echo "============================================="
63    echo "$out" | grep -q PRODUCT_DISK_SSH_OK && ok=1; break
64  fi
65  sleep 3
66done
67echo "---- consola (cola) ----"; tail -15 "$WORK/console.log" 2>/dev/null
68[ "$ok" = 1 ] && { echo; echo "*** PRODUCT DISK OK — imagen auto-booteable (GRUB, sin -kernel) sirve SSH ***"; exit 0; }
69echo; echo "*** PRODUCT DISK FALLÓ — ver $WORK/console.log ***"; exit 1