bootstrap: builder rootfs — ensambla el rebuild in-rootfs (Stage 2 pleno, §7)
El único sub-ítem que le quedaba a Stage 2: el rebuild *dentro* del rootfs. El Stage 1 que booteamos es runtime (musl+busybox+hammerd+arje-zero), sin compilador — no puede reconstruirse. El builder rootfs es Stage 1 + el toolchain adentro. Implementa `hammer_bootstrap::builder_rootfs` (variante a pragmática, SDD 11 §7.2): sobre el Stage 1 rootfs hidratado monta /toolchain (rootfs Alpine = sandbox de build), /store con la semilla replicada (el hammer de adentro resuelve zig por hash), /usr/bin/hammer + /etc/hammer/recipes, y el driver /usr/bin/rebuild-stage1 que apunta HAMMER_ROOTFS=/toolchain, corre `bootstrap stage1` y compara stage1' contra la referencia con `stage2 --verify` (lee SEED_HASH/SEED_KIND/REF_CONTENT de /etc/hammer/rebuild.env). - BuilderSpec/BuilderReport + builder_hash lógico (insumos: stage1+semilla+ recetas+binario+tag toolchain+driver) — reproducible y auditable sin hashear el árbol Alpine; anota línea stage 2 en el manifiesto. - link_or_copy_tree (hardlink-or-copy, sin chmod: no toca permisos del .dev-fs). - El builder no se sella (toolchain Alpine no es content-addressed); se ensambla en out_dir para empaquetar como initramfs. - CLI `hammer bootstrap builder --stage1 H --seed-hash H [--hammer-bin] [--toolchain] [--ref-content] [--work-cache] [--out]`. +4 tests (assemble, hash determinista, sin-ref, stage1 no sellado). Validado contra el store real: Stage 1 73d7a9be… + semilla 3ce721ec… ⇒ builder 81dad3d9… (1.2 GB con el toolchain). Lo que queda es operacional: bootear en la VM y correr rebuild-stage1 — runbook §8c documenta la receta (hammer estático musl, initramfs, qemu -cpu Broadwell, --work-cache para rebuild offline). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
731d4f6ffc
commit
f17a8fa301
@@ -266,6 +266,58 @@ Con ambos, `musl` y `busybox` reconstruyen **bit-idéntico**. Sumados `hammerd`
|
||||
queda a Stage 2 es el rebuild *dentro* de un **builder rootfs** (un Stage 1 que incluya el
|
||||
toolchain) — el auto-alojamiento pleno, un hito propio (el Stage 1 mínimo es runtime, sin compilador).
|
||||
|
||||
## 8c. Builder rootfs — el rebuild in-rootfs (auto-alojamiento, SDD 11 §7)
|
||||
|
||||
El **ensamblado** del builder ya está implementado (`hammer bootstrap builder`, [SDD 11 §7.4](../11-bootstrap.md);
|
||||
variante a, toolchain desde Alpine). Produce, sobre el Stage 1 rootfs, una imagen con el toolchain
|
||||
adentro lista para reconstruirse a sí misma. Receta operacional:
|
||||
|
||||
**1. Binario `hammer` estático (musl).** El builder lo bootea como PID-algo en la VM, así que debe
|
||||
ser autocontenido (como hammerd/arje-zero, crt-static — §7):
|
||||
|
||||
```sh
|
||||
cargo build --release --target x86_64-unknown-linux-musl -p hammer-cli
|
||||
# (o cargo rustc -- -C target-feature=+crt-static, según el camino de oro del boot)
|
||||
```
|
||||
|
||||
**2. Ensamblar el builder** anclando la referencia `of_tree(stage1)` (la que imprimió `stage2`):
|
||||
|
||||
```sh
|
||||
hammer --store store bootstrap builder \
|
||||
--stage1 b3:<STAGE1> --seed-hash b3:<SEED> \
|
||||
--hammer-bin target/x86_64-unknown-linux-musl/release/hammer \
|
||||
--toolchain .dev-fs/alpine --toolchain-tag alpine-3.23.4 \
|
||||
--ref-content b3:<OF_TREE_STAGE1> \
|
||||
--work-cache work \
|
||||
--out work/builder-rootfs
|
||||
```
|
||||
|
||||
`--work-cache work` embebe los mirrors git / tarballs ya fetcheados en `/work` ⇒ rebuild **offline y
|
||||
determinista** en la VM (sin él, el rebuild fetchea por red; la seed card trae `networking: full`).
|
||||
|
||||
**3. Empaquetar como initramfs y bootear** (igual que §4/§7, `-cpu Broadwell` por AVX):
|
||||
|
||||
```sh
|
||||
( cd work/builder-rootfs && find . | cpio -o -H newc | gzip ) > builder.cpio.gz
|
||||
qemu-system-x86_64 -m 1024 -no-reboot -nographic -cpu Broadwell \
|
||||
-kernel <vmlinuz> -initrd builder.cpio.gz -append "console=ttyS0 rdinit=/sbin/init"
|
||||
```
|
||||
|
||||
**4. Dentro de la VM**, desde la shell de la consola, correr el driver embebido:
|
||||
|
||||
```sh
|
||||
rebuild-stage1
|
||||
# >> rebuild stage1 (toolchain in-rootfs, semilla b3:3ce721ec…)
|
||||
# >> stage1' = b3:…
|
||||
# ✓ REPRODUCIBLE: stage1' == stage1 (auto-alojado bit a bit) ← of_tree(stage1')==REF_CONTENT
|
||||
```
|
||||
|
||||
`rebuild-stage1` apunta `HAMMER_ROOTFS=/toolchain`, corre `hammer bootstrap stage1` con la semilla y
|
||||
las recetas de adentro, y compara con `stage2 --verify $REF_CONTENT`. **✓ REPRODUCIBLE** cierra el
|
||||
auto-alojamiento end-to-end de la variante (a); **✗ DIVERGENTE** caza un no-determinismo nuevo
|
||||
([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.
|
||||
|
||||
## 9. Cross-check opcional — `arje-packager`
|
||||
|
||||
arje trae su propio empaquetador (`03_ukupacha/arje/init/arje-packager`):
|
||||
|
||||
Reference in New Issue
Block a user