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.
66 lines
4.3 KiB
Bash
Executable File
66 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# product-image-from-repo.sh — CIERRE DEL LAZO Etapa F+G: arma una imagen de producto AUTO-BOOTEABLE
|
|
# cuyo USERLAND CLI se hidrata desde el REPO FIRMADO (no del bootstrap hardcodeado). Pipeline:
|
|
# 1. base = product-rootfs del store (init arje-zero + musl/busybox + servicios).
|
|
# 2. hidrata el userland rico vía `takana install --repo --prefix --require-signed` (product-userland-from-repo.sh).
|
|
# 3. arma el disco GRUB-booteable (install-image.sh) y, con BOOT=1, lo arranca en QEMU + handshake SSH.
|
|
#
|
|
# Uso: ./scripts/product-image-from-repo.sh # crea work/hammer-product-repo.img
|
|
# BOOT=1 ./scripts/product-image-from-repo.sh # además auto-bootea + prueba SSH (los tools del repo)
|
|
# Vars: PRODUCT (hash base; def el más reciente del store) PKGS (set de userland; def el de la script)
|
|
# KERNEL (def store/*-linux/boot/bzImage) IMG KVM(1) MEM(2048) PORT(2225) DEADLINE(180)
|
|
set -euo pipefail
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
|
|
IMG="${IMG:-work/hammer-product-repo.img}"; KVM="${KVM:-1}"; MEM="${MEM:-2048}"; PORT="${PORT:-2225}"
|
|
DEADLINE="${DEADLINE:-180}"; WORK="$ROOT/work/product-from-repo"; RFS="$WORK/rootfs"
|
|
KERNEL="${KERNEL:-$(ls store/*-linux/boot/bzImage 2>/dev/null | head -1)}"
|
|
|
|
# 1. base
|
|
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 base (corré 'hammer bootstrap product')"; exit 1; }
|
|
echo "==> base product-rootfs: $PDIR"
|
|
rm -rf "$WORK"; mkdir -p "$WORK"
|
|
cp -a "$PDIR" "$RFS"; chmod -R u+w "$RFS"; rm -rf "$RFS/.hammer"
|
|
|
|
# 2. userland rico desde el repo firmado, hidratado SOBRE la base
|
|
OVER="$RFS" scripts/product-userland-from-repo.sh
|
|
echo "==> rootfs ensamblado: $(ls "$RFS"/usr/bin | wc -l) binarios en /usr/bin (base + repo)"
|
|
|
|
# 3. admin key de prueba (lo único no horneado)
|
|
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"
|
|
[ -d "$RFS/store" ] || mkdir -p "$RFS/store" # install-image puebla la partición store desde acá
|
|
|
|
# 4. disco GRUB-booteable (sin auto-boot acá; lo hacemos nosotros con red)
|
|
echo "==> armando imagen GRUB-booteable"
|
|
ROOTFS="$RFS" IMG="$IMG" KERNEL="$KERNEL" BOOT=0 ROOT_SIZE="${ROOT_SIZE:-1280}" STORE_SIZE="${STORE_SIZE:-256}" \
|
|
STATE_SIZE="${STATE_SIZE:-256}" sh ./scripts/install-image.sh
|
|
echo "==> imagen: $IMG"
|
|
[ "${BOOT:-0}" = 1 ] || { echo "(set BOOT=1 para auto-bootear + probar los tools del repo por SSH)"; exit 0; }
|
|
|
|
# 5. auto-boot (GRUB del disco, sin -kernel) + red + handshake que CORRE los tools del repo
|
|
accel=(-cpu Broadwell); { [ "$KVM" = 1 ] && [ -w /dev/kvm ]; } && accel=(-enable-kvm -cpu host)
|
|
echo "==> AUTO-BOOT + 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 (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_REPO_OK; bat --version 2>/dev/null | head -1; fd --version 2>/dev/null; jq --version 2>/dev/null; eza --version 2>/dev/null | head -1' 2>/dev/null); then
|
|
echo "===== TOOLS DEL REPO CORRIENDO EN EL PRODUCTO ====="; echo "$out"; echo "==================================================="
|
|
echo "$out" | grep -q PRODUCT_REPO_OK && ok=1; break
|
|
fi
|
|
sleep 3
|
|
done
|
|
tail -12 "$WORK/console.log" 2>/dev/null
|
|
[ "$ok" = 1 ] && { echo; echo "*** LAZO CERRADO — producto auto-booteable corre userland del REPO FIRMADO ***"; exit 0; }
|
|
echo; echo "*** boot/SSH falló — ver $WORK/console.log ***"; exit 1
|