docs: runbook §8c — rebuild in-rootfs ejecutado, 2/4 sellados en la VM

Registra la corrida real (QEMU TCG): la cadena de muros que sólo el rebuild
DENTRO de la VM destapó y que se arreglaron en orden — toolchain sin
bwrap/git/curl, binarios dinámicos vs userland estático (shim del loader), overlay
como módulo no cargado (insmod), y ownership del initramfs (cpio --owner=root).

Resultado: musl y busybox se reconstruyeron y SELLARON dentro de la VM con el
toolchain de adentro (~35-38 min/componente bajo TCG) — auto-alojamiento probado
sobre builds reales. hammerd abortó en `cargo vendor` (deps crates.io no
provistas offline; la VM no tiene red). El 4/4 pleno necesita red en la VM o
crates vendoreadas + un host con KVM/más RAM (idealmente builder desde disco).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-06-11 17:04:33 +00:00
co-authored by Claude Opus 4.8
parent 890a37b473
commit f6dcf1028d
+32
View File
@@ -335,6 +335,38 @@ auto-alojamiento end-to-end de la variante (a); **✗ DIVERGENTE** caza un no-de
([SDD 09 §2](../09-trust-model.md)). La variante (b) — el toolchain construido por hammer desde ([SDD 09 §2](../09-trust-model.md)). La variante (b) — el toolchain construido por hammer desde
fuente — reemplaza `/toolchain` Alpine pieza a pieza, con este mismo lazo verificando cada paso. fuente — reemplaza `/toolchain` Alpine pieza a pieza, con este mismo lazo verificando cada paso.
### ✅ Rebuild in-rootfs ejecutado (2026-06-11): 2/4 componentes sellados en la VM
Corrida real (QEMU TCG, `-m 6144`, sin KVM). El driver atravesó, en orden, una cadena de muros
reales — cada uno destapado **sólo** por correr el rebuild *dentro* de la VM (justo lo que Stage 2
existe para cazar) y arreglado:
1. **Toolchain incompleto.** Traía compiladores (cargo/make/zig) pero no la orquestación del lab:
`bwrap` (anida el sandbox), `git` (`git archive` del mirror), `curl` (tarballs). En el host las
da el sistema; en la VM el toolchain es el único userland ⇒ `apk add bubblewrap git curl`.
2. **Binarios dinámicos vs userland estático.** El toolchain es Alpine dinámico; el Stage 1 es musl
estático (sin loader en `/lib`) ⇒ no corrían. Fix: **shim del loader** (`cp` del `ld-musl` a
`/lib` + `LD_LIBRARY_PATH`/`PATH`) en `rebuild-stage1`.
3. **overlay es módulo.** `CONFIG_OVERLAY_FS=m` y el initramfs arranca sin módulos ⇒ `bwrap
--tmp-overlay` daba `ENODEV`. Fix: `insmod /toolchain/lib/overlay.ko` (+ `kmod`; `overlay.ko` del
kernel destino inyectado en el builder).
4. **Ownership del initramfs.** El copy-up de overlay daba `EACCES` (`Can't mkdir /opt/zig`): los
ficheros viajaban con uid 1000, sin mapear en el userns de bwrap (mapea 0→0). Fix: empaquetar con
`cpio --owner=root:root`.
Con eso, **musl** y **busybox** se reconstruyeron y **sellaron dentro de la VM** con el toolchain de
adentro (configure→compile→install→seal; ~3538 min/componente bajo TCG). El mecanismo de
auto-alojamiento queda **probado sobre builds reales**, no sólo en diseño.
**Muro pendiente — deps Rust offline.** `hammerd` abortó en `cargo vendor` (`failed to sync`): el
`/work` embebido lleva los **mirrors git de las fuentes** (`repos/`) pero no las **dependencias
crates.io**, y la VM no tiene red. Los componentes C sellan (tarballs autocontenidos); los Rust
(`hammerd`, `arje-zero`) necesitan, para offline, **o** red en la VM (qemu `-netdev user` + NIC +
`/etc/resolv.conf`, los repos privados ya están mirroreados) **o** las crates vendoreadas en `/work`.
Sumado al coste de los builds Rust bajo TCG (horas, RAM justa ⇒ riesgo de OOM en `arje-zero`), el
veredicto pleno **4/4** se completa en un host con **KVM + más RAM** (y, idealmente, un builder
booteado desde **disco** en vez de initramfs puro, que además evita la fricción ramfs/ownership).
## 9. Cross-check opcional — `arje-packager` ## 9. Cross-check opcional — `arje-packager`
arje trae su propio empaquetador (`03_ukupacha/arje/init/arje-packager`): arje trae su propio empaquetador (`03_ukupacha/arje/init/arje-packager`):