250 líneas de comentario en 151 scripts. Control verificado: el diff no toca NI UNA línea que no empiece por #, y la sintaxis de los 151 pasa. El barrido saltea heredocs y cadenas triples, y el guardián DISPARÓ 3 veces: las tres eran el MOTD que el script escribe DENTRO de la imagen construida — texto del producto, no comentario del script. Se cambiaron aparte y a propósito, que es rebranding, no limpieza. Y el hallazgo caro: casaba contra , que es el TARGET de tracing — o sea el module_path!, o sea el nombre del crate. La etapa 4 lo movió a y el script quedó casando NADA. No fallaba: imprimía cero atribuciones, indistinguible de un log sin problemas. Comprobado con el binario (RUST_LOG=info sobre zlib), no deducido. Ahora acepta las dos, y tiene que seguir aceptándolas porque los logs viejos en disco dicen la vieja. Además 14 rutas de módulo en docs, que el barrido anterior no tocó porque no es frontera de palabra.
70 lines
4.2 KiB
Bash
Executable File
70 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# product-image.sh — empaqueta el `product-rootfs` (lean: 4/4 + userland Rust + sshd, SIN toolchain)
|
|
# como imagen de disco AUTO-BOOTEABLE (GRUB BIOS), reusando scripts/install-image.sh. Es el cierre del
|
|
# pipeline: del artefacto sellado por `takana bootstrap product` a un disco que arranca solo en QEMU
|
|
# (`-drive file=img`, sin -kernel) y, con red, sirve SSH.
|
|
#
|
|
# A diferencia de install-image.sh (que por defecto empaqueta el BUILDER rootfs con todo el toolchain),
|
|
# acá la root es el product-rootfs lean ⇒ imagen de PRODUCTO, no de self-host.
|
|
#
|
|
# Uso: PRODUCT=<hash|prefijo> ./scripts/product-image.sh # crea work/hammer-product.img
|
|
# PRODUCT=<...> BOOT=1 ./scripts/product-image.sh # además auto-bootea + handshake SSH
|
|
# Vars: KERNEL IMG (def work/hammer-product.img) KVM (def 1) MEM (def 2048) PORT (def 2224)
|
|
# DEADLINE (def 150, sólo con BOOT=1)
|
|
set -euo pipefail
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
|
|
IMG="${IMG:-work/hammer-product.img}"; KVM="${KVM:-1}"; MEM="${MEM:-2048}"; PORT="${PORT:-2224}"
|
|
DEADLINE="${DEADLINE:-150}"; WORK="$ROOT/work/product-image"
|
|
|
|
if [ -n "${PRODUCT:-}" ]; then
|
|
PDIR=$(ls -d store/"${PRODUCT#b3:}"*-product-rootfs 2>/dev/null | head -1)
|
|
else
|
|
PDIR=$(ls -dt store/*-product-rootfs 2>/dev/null | head -1)
|
|
fi
|
|
[ -n "$PDIR" ] && [ -d "$PDIR" ] || { echo "no encuentro product-rootfs (corré 'hammer bootstrap product')"; exit 1; }
|
|
echo "==> product-rootfs: $PDIR"
|
|
|
|
# copia escribible del artefacto sellado (read-only); no tocamos el store
|
|
rm -rf "$WORK"; mkdir -p "$WORK"; RFS="$WORK/rootfs"
|
|
cp -a "$PDIR"/. "$RFS"/; chmod -R u+w "$RFS"; rm -rf "$RFS/.hammer"
|
|
|
|
# provisión de admin: authorized_keys de prueba (lo único no horneado en el producto)
|
|
KG=$(ls store/*-openssh/usr/bin/ssh-keygen | head -1)
|
|
"$KG" -t ed25519 -N '' -f "$WORK/clientkey" -q
|
|
install -d -m 0700 "$RFS/root/.ssh"
|
|
cat "$WORK/clientkey.pub" > "$RFS/root/.ssh/authorized_keys"; chmod 0600 "$RFS/root/.ssh/authorized_keys"
|
|
|
|
# delegar el armado del disco GRUB-booteable a install-image.sh. BOOT=0 EXPLÍCITO: nuestro BOOT=1 está
|
|
# en el entorno y se heredaría a install-image.sh, que haría su PROPIO `exec qemu` foreground (sin red)
|
|
# y bloquearía acá para siempre. Lo aislamos para que install-image SÓLO arme la imagen.
|
|
echo "==> armando imagen de disco (GRUB BIOS) vía install-image.sh"
|
|
ROOTFS="$RFS" IMG="$IMG" BOOT=0 ROOT_SIZE="${ROOT_SIZE:-1024}" STORE_SIZE="${STORE_SIZE:-512}" \
|
|
STATE_SIZE="${STATE_SIZE:-512}" sh ./scripts/install-image.sh
|
|
echo "==> imagen de producto: $IMG"
|
|
|
|
[ "${BOOT:-0}" = 1 ] || { echo "(set BOOT=1 para auto-bootear + probar SSH)"; exit 0; }
|
|
|
|
# auto-boot (sin -kernel, GRUB del disco) + red slirp hostfwd para el handshake
|
|
accel=(-cpu Broadwell); { [ "$KVM" = 1 ] && [ -w /dev/kvm ]; } && accel=(-enable-kvm -cpu host)
|
|
echo "==> AUTO-BOOT (sin -kernel) + hostfwd :$PORT->:22"
|
|
qemu-system-x86_64 -m "$MEM" -no-reboot -nographic "${accel[@]}" \
|
|
-drive file="$IMG",format=raw,if=virtio \
|
|
-netdev "user,id=n0,hostfwd=tcp::$PORT-:22" -device e1000,netdev=n0 > "$WORK/console.log" 2>&1 &
|
|
QPID=$!; trap 'kill $QPID 2>/dev/null || true' EXIT
|
|
SSHOPTS=(-p "$PORT" -i "$WORK/clientkey" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
|
|
-o GlobalKnownHostsFile=/dev/null -o PasswordAuthentication=no -o ConnectTimeout=4 -o LogLevel=ERROR)
|
|
echo "==> esperando handshake desde el disco auto-booteado (deadline ${DEADLINE}s)…"
|
|
start=$(date +%s); ok=0
|
|
while [ $(( $(date +%s) - start )) -lt "$DEADLINE" ]; do
|
|
kill -0 $QPID 2>/dev/null || { echo "!! QEMU murió"; break; }
|
|
if out=$(ssh "${SSHOPTS[@]}" root@localhost \
|
|
'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
|
|
echo "============ RESPUESTA DEL GUEST ============"; echo "$out"; echo "============================================="
|
|
echo "$out" | grep -q PRODUCT_DISK_SSH_OK && ok=1; break
|
|
fi
|
|
sleep 3
|
|
done
|
|
echo "---- consola (cola) ----"; tail -15 "$WORK/console.log" 2>/dev/null
|
|
[ "$ok" = 1 ] && { echo; echo "*** PRODUCT DISK OK — imagen auto-booteable (GRUB, sin -kernel) sirve SSH ***"; exit 0; }
|
|
echo; echo "*** PRODUCT DISK FALLÓ — ver $WORK/console.log ***"; exit 1
|