hammer-upgrade: upgrades atómicos con generaciones y rollback (Etapa E4, primer corte)
Crate hammer-upgrade + CLI 'hammer upgrade apply|rollback|status'. Aplica un árbol Stage1/producto del store sobre el FHS vivo dejando una generación (manifest + backup de bytes previos), atómico fichero-a-fichero con 'current' como commit-point. Rollback restaura EXACTO al árbol anterior (o pre-upgrades). Cada cambio al journal (HammerHydrate, replay-able). Verificación opcional del of_tree esperado (índice de mirror E3 / release firmada). Maneja ficheros + symlinks. 7 tests unitarios + scripts/upgrade-e2e-test.sh (apply v1->v2-> rollback->rollback contra el binario real). SDD 13 actualizado. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -63,7 +63,24 @@ kernel en `/boot`, los módulos GRUB en `/boot/grub/i386-pc` y los pasos `grub-m
|
||||
Endurecimiento pendiente: anclar el `of_tree` a una raíz firmada (log de transparencia `bootstrap.json` /
|
||||
atestación de Etapa D) para defenderse de un origen plenamente malicioso (hoy el invariante forzado es
|
||||
"el contenido recibido hashea a lo que el índice anuncia", que ataja corrupción de transporte).
|
||||
- **E4 — upgrades:** aplicar un nuevo árbol Stage 1 sin reinstalar — atómico vía el modelo overlay +
|
||||
el journal (D), con rollback al árbol anterior.
|
||||
- **E4 — upgrades: ✅ primer corte** (crate `hammer-upgrade` + CLI `hammer upgrade apply|rollback|status`).
|
||||
Aplica un árbol Stage1/producto **nuevo** (artefacto sellado del store, CAS BLAKE3) sobre el FHS vivo
|
||||
sin reinstalar, dejando una **generación**, y revierte exactamente al árbol anterior con `rollback`.
|
||||
**Modelo de generaciones** (inspirado en NixOS, in-place al FHS porque el boot lee el root directo, no
|
||||
un symlink indirecto): cada generación graba bajo `<state>/generations/<N>/` su `manifest.json`
|
||||
(tree_dir del store, `of_tree`, parent, lista de ficheros, cambios) y un `backup/` con los bytes
|
||||
**previos** de todo path que pisó o retiró. **Atomicidad:** proyección fichero-a-fichero (escritura a
|
||||
temporal + `rename` ⇒ cada fichero conmuta atómicamente), con `current` (id de la generación viva) como
|
||||
commit-point; un corte a mitad deja `current` en la vieja y los backups intactos ⇒ re-apply/rollback
|
||||
recuperan. **Diff vs el árbol previo:** el apply añade/pisa los ficheros del árbol nuevo y **retira** los
|
||||
que la generación viva aportaba y el nuevo no tiene. **Rollback:** deshace en orden inverso (borra lo
|
||||
añadido, restaura desde `backup/` lo pisado/retirado) y retrocede `current` al padre — restauración
|
||||
*exacta*, incluso al estado pre-upgrades. Cada cambio se registra en el [journal](05-journal.md) como
|
||||
`HammerHydrate{artifact=tree_dir}` (replay-able). Verificación opcional de integridad: si el llamador
|
||||
anuncia el `of_tree` esperado (de un índice de **mirror E3** o release firmada), el apply lo exige antes
|
||||
de tocar el root. Maneja ficheros regulares + symlinks; valida E2E en host con `scripts/upgrade-e2e-test.sh`
|
||||
(apply v1→v2→rollback→rollback contra el binario real). **Endurecimiento pendiente:** journal de
|
||||
*intención* + replay para sobrevivir un kernel-panic a media escritura; GC de generaciones viejas
|
||||
(prune); cableado del init de boot para que el rollback sea seleccionable al arranque.
|
||||
- **E5 — ISO/medio de arranque:** medio live para correr el instalador (xorriso/grub-mkrescue;
|
||||
herramental a construir).
|
||||
|
||||
Reference in New Issue
Block a user