qorpa D3: packages se instala solo — el manifiesto deja de ser un adorno

Hasta acá el ADR afirmaba «el manifiesto es la verdad, el upper es caché»
mientras `recreate` confesaba en su propia salida que «instalarlos todavía es a
mano». Con eso el `upper` SÍ era el activo: un blob irreemplazable, que es justo
lo que hammer existe para no tener.

`hammer qorpa provision <id>` instala lo declarado, y **`recreate` lo llama
solo** (`--no-provision` para saltarlo).

Cuatro decisiones, cada una con su porqué:

- **El gestor se DETECTA** en la vista merged (apt, pacman, dnf, apk), no se
  configura: cada imagen trae el suyo. Y no se multiplexa detrás de un comando
  único —el `pmm` de Bedrock que el ADR rechaza—: se elige cuál correr.
- **`provision` ensancha la política y lo dice en la cara.** Instalar pide las
  tres cosas que una instancia bien declarada no tiene: red, root y la imagen
  sin sellar. Se ensancha SÓLO durante esa operación, el manifiesto no se toca
  y el siguiente `run` vuelve a lo escrito. En silencio sería lo que D7 prohíbe.
- **El registro vive FUERA del `upper`** (`provisioned.toml`): dentro se iría
  con la capa. Por eso `recreate` lo borra — un registro que afirma paquetes
  sobre una capa recién vaciada es la forma más pura del error de la regla 3.
- **Los nombres se validan y se comillan**: salen de un fichero que escribe una
  persona, así que `strace; rm -rf /` no llega al guión.

**Las dos manías que sólo salen provisionando de verdad:** el bootstrap de Arch
trae la mirrorlist ENTERA comentada (pacman muere con «no servers configured») y
el llavero sin inicializar (toda firma inválida). El guión pone el mirror geo
oficial avisando cuál, y hace `pacman-key --init && --populate` sólo si falta.
`apt` no necesita ni un workaround: es el dividendo del rango de subuid.

Probado de punta a punta en los dos gestores —apt sobre Ubuntu base, pacman
sobre el bootstrap de Arch—: instalan, el binario corre después con la red
apagada, y un `recreate` tira la capa y la deja igual. 27 tests verdes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QZjGRqvjWij9dew7NVFu4Q
This commit is contained in:
Sergio
2026-09-03 21:00:10 +00:00
co-authored by Claude Opus 5
parent 7e1474d135
commit 50d1dbcc31
2 changed files with 314 additions and 14 deletions
+23
View File
@@ -156,6 +156,29 @@ Consecuencias que se caen solas:
`/var/lib/hammer/qorpa/instances/*/upper` y eso es correcto, no un olvido.
- La poda tiene una regla trivial: **un `upper` siempre se puede borrar.**
**✅ COMPLETADO 2026-09-03 — hasta acá `packages` era una lista que nadie leía.** Durante unas
horas el ADR afirmaba las cuatro consecuencias de arriba mientras `recreate` confesaba en su propia
salida que «instalarlos todavía es a mano»: o sea que el `upper` **sí** era el activo y el
manifiesto un adorno. Ahora `hammer qorpa provision <id>` instala lo declarado, y **`recreate` lo
llama solo** (`--no-provision` para no hacerlo).
| decisión | por qué |
|---|---|
| el gestor se **detecta** (`apt`, `pacman`, `dnf`, `apk`), no se configura | cada imagen trae el suyo. Y **no se multiplexa**: el ADR rechaza un comando único al estilo `pmm` de Bedrock; acá se elige cuál correr, no se inventa una interfaz que los tape |
| `provision` **ensancha la política y lo dice en la cara** | instalar pide las tres cosas que una instancia bien declarada no tiene —red, root y la imagen sin sellar—. Se ensancha sólo durante esa operación, el manifiesto **no se toca**, y el siguiente `run` vuelve a lo escrito. Ensancharlo en silencio sería exactamente lo que D7 prohíbe |
| el registro (`provisioned.toml`) vive **fuera** del `upper` | si viviera dentro se iría con la capa y nadie sabría qué había. Por eso `recreate` lo borra a mano: un registro que afirma paquetes sobre una capa recién vaciada es la forma más pura del error de la regla 3 |
| los nombres de paquete se **validan y se comillan** | salen del manifiesto, que lo escribe una persona; `strace; rm -rf /` no llega al guión |
**Las dos manías que sólo aparecen provisionando de verdad** (medidas, no leídas): el bootstrap de
Arch trae la **mirrorlist entera comentada**`pacman` muere con «no servers configured»— y el
**llavero sin inicializar**, con lo que toda firma es inválida; el guión pone el mirror geo oficial
**avisando cuál**, y corre `pacman-key --init && --populate` sólo si falta. `apt`, en cambio, no
necesita ni un workaround: es el dividendo del rango de subuid.
**Probado de punta a punta en los dos gestores**: `apt` sobre Ubuntu base y `pacman` sobre el
bootstrap de Arch instalan, el binario corre después con la red apagada otra vez, y un `recreate`
tira la capa y la deja igual — que es la prueba de esta sección entera.
### D4 — Granularidad: cuatro tipos, no uno
| tipo | qué es | mutable | ¿sellable? | para qué |