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.
103 lines
6.0 KiB
Bash
Executable File
103 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# takana-install.sh — Etapa E2: instalador a disco. Vuelca el `product-rootfs` (lean: 4/4 + userland
|
|
# Rust + sshd) sobre un DISCO destino (block device real `/dev/sdX`, o un fichero pre-dimensionado para
|
|
# pruebas) con el mismo layout GPT + GRUB BIOS de la imagen E1, pero IN-PLACE sobre el target. Tras
|
|
# instalar, el disco arranca solo (SeaBIOS → GRUB → kernel → arje-zero PID1 → hammerd+getty+sshd).
|
|
#
|
|
# Es la contraparte "a disco real" de scripts/product-image.sh (que produce un fichero imagen portátil):
|
|
# la lógica de particionado/format/GRUB es la misma (delegada a install-image.sh); sólo cambia el target.
|
|
#
|
|
# Uso:
|
|
# sudo PRODUCT=<hash> AUTHKEYS=~/.ssh/id_ed25519.pub FORCE=1 ./scripts/hammer-install.sh /dev/sdX
|
|
# # prueba sin hardware (fichero pre-dimensionado, se valida el camino in-place + boot SSH):
|
|
# PRODUCT=<hash> TESTKEY=1 BOOT=1 ./scripts/hammer-install.sh work/target.img
|
|
#
|
|
# Variables:
|
|
# PRODUCT product-rootfs sellado (hash/prefijo; default: el más reciente del store)
|
|
# AUTHKEYS fichero authorized_keys a instalar para root (recomendado en instalación real)
|
|
# TESTKEY 1 ⇒ genera un par efímero y usa su pubkey como authorized_keys (para validar por SSH)
|
|
# FORCE 1 ⇒ requerido para escribir sobre un BLOCK DEVICE (seguridad anti-pisada)
|
|
# KERNEL bzImage a embeber (default store/*-linux/boot/bzImage)
|
|
# ROOT_SIZE/STORE_SIZE/STATE_SIZE MiB de cada partición (default 1024/512/512)
|
|
# BOOT 1 ⇒ tras instalar, arranca el target con QEMU (útil sólo para fichero/imagen) + handshake
|
|
# KVM/MEM/PORT/DEADLINE passthrough del arranque de prueba
|
|
set -euo pipefail
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
|
|
TARGET="${1:-}"
|
|
[ -n "$TARGET" ] || { echo "uso: $0 <device|imagen> (p.ej. /dev/sdX o work/target.img)"; exit 2; }
|
|
WORK="$ROOT/work/hammer-install"; RFS="$WORK/rootfs"
|
|
|
|
# --- resolver product-rootfs sellado ---
|
|
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"
|
|
echo "==> target: $TARGET"
|
|
|
|
# --- guardas de seguridad para un disco real ---
|
|
PREALLOC=0
|
|
if [ -b "$TARGET" ]; then
|
|
[ "${FORCE:-0}" = 1 ] || { echo "!! $TARGET es un BLOCK DEVICE — exijo FORCE=1 para escribirlo (borra datos)"; exit 1; }
|
|
if mount | grep -q "^$TARGET"; then echo "!! $TARGET (o una partición) está MONTADO — desmontá antes"; exit 1; fi
|
|
echo "==> escritura sobre block device REAL (FORCE=1)"
|
|
elif [ -e "$TARGET" ]; then
|
|
PREALLOC=1 # fichero existente ⇒ in-place (no truncar): exactamente el camino de un device
|
|
echo "==> target fichero pre-dimensionado ⇒ instalación in-place (PREALLOC)"
|
|
else
|
|
echo "==> target fichero nuevo ⇒ install-image lo crea (truncate)"
|
|
fi
|
|
|
|
# --- copia escribible del product-rootfs + provisión de authorized_keys ---
|
|
rm -rf "$WORK"; mkdir -p "$WORK"
|
|
cp -a "$PDIR"/. "$RFS"/; chmod -R u+w "$RFS"; rm -rf "$RFS/.hammer"
|
|
install -d -m 0700 "$RFS/root/.ssh"
|
|
if [ "${TESTKEY:-0}" = 1 ]; then
|
|
"$(ls store/*-openssh/usr/bin/ssh-keygen | head -1)" -t ed25519 -N '' -f "$WORK/clientkey" -q
|
|
cat "$WORK/clientkey.pub" > "$RFS/root/.ssh/authorized_keys"
|
|
echo "==> authorized_keys: llave de prueba efímera ($WORK/clientkey)"
|
|
elif [ -n "${AUTHKEYS:-}" ] && [ -f "$AUTHKEYS" ]; then
|
|
cat "$AUTHKEYS" > "$RFS/root/.ssh/authorized_keys"
|
|
echo "==> authorized_keys: $AUTHKEYS"
|
|
else
|
|
echo "==> (sin authorized_keys: nadie podrá entrar por SSH hasta provisionarlas; usá AUTHKEYS= o TESTKEY=1)"
|
|
fi
|
|
chmod 0600 "$RFS/root/.ssh/authorized_keys" 2>/dev/null || true
|
|
|
|
# --- delegar particionado/format/GRUB a install-image.sh, apuntando al target (IN-PLACE si aplica) ---
|
|
echo "==> instalando sobre $TARGET (GPT + ext4 + GRUB BIOS, in-place=$PREALLOC)"
|
|
ROOTFS="$RFS" IMG="$TARGET" PREALLOC="$PREALLOC" BOOT=0 \
|
|
ROOT_SIZE="${ROOT_SIZE:-1024}" STORE_SIZE="${STORE_SIZE:-512}" STATE_SIZE="${STATE_SIZE:-512}" \
|
|
sh ./scripts/install-image.sh
|
|
echo "==> instalado. El disco arranca solo (SeaBIOS → GRUB → arje-zero)."
|
|
|
|
[ "${BOOT:-0}" = 1 ] || { echo " (set BOOT=1 para arrancar el target y probar SSH)"; exit 0; }
|
|
[ "${TESTKEY:-0}" = 1 ] || { echo " BOOT=1 sin TESTKEY=1: no tengo llave para el handshake; omito."; exit 0; }
|
|
|
|
# --- arranque de prueba del target (sólo fichero/imagen) + handshake SSH ---
|
|
KVM="${KVM:-1}"; MEM="${MEM:-2048}"; PORT="${PORT:-2225}"; DEADLINE="${DEADLINE:-150}"
|
|
accel=(-cpu Broadwell); { [ "$KVM" = 1 ] && [ -w /dev/kvm ]; } && accel=(-enable-kvm -cpu host)
|
|
echo "==> AUTO-BOOT del target (sin -kernel) + hostfwd :$PORT->:22"
|
|
qemu-system-x86_64 -m "$MEM" -no-reboot -nographic "${accel[@]}" \
|
|
-drive file="$TARGET",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 instalado (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 INSTALLED_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 DISCO INSTALADO ========="; echo "$out"; echo "================================================="
|
|
echo "$out" | grep -q INSTALLED_DISK_SSH_OK && ok=1; break
|
|
fi
|
|
sleep 3
|
|
done
|
|
echo "---- consola (cola) ----"; tail -12 "$WORK/console.log" 2>/dev/null
|
|
[ "$ok" = 1 ] && { echo; echo "*** HAMMER INSTALL OK — disco instalado in-place arranca solo y sirve SSH ***"; exit 0; }
|
|
echo; echo "*** HAMMER INSTALL FALLÓ — ver $WORK/console.log ***"; exit 1
|