el TLS arreglado en la caja, la distro con nombre, y el ENOSPC que no era de la raíz
**curl ya valida**: `ca-certificates` re-sellado con **119 hash-links en el capath**, generados en el build, y la caja baja por HTTPS sin apaño (200). Tardó tres intentos y los dos primeros los cazó la guarda de la propia receta: `c_rehash` no estaba en el PATH (lo instala esa misma receta en `/out/usr/bin`) y los certificados no están sueltos en `usr/share/ca-certificates/` sino en `mozilla/`, así que sólo veía el bundle y lo saltaba —correctamente— con «does not contain exactly one certificate». Sin la guarda habría sellado un capath vacío las tres veces. **fastfetch 2.68.1 corre en la caja** (pedido del usuario) y al correrlo destapó que **`/etc/os-release` no existía**: la distro era anónima para cualquier programa que no fuera suyo. Ahora `OS: takana x86_64`. Va como receta propia (`source.dir`) y no como constante de `takana-bootstrap`: meterlo ahí re-sellaría el product-rootfs —el baseline del selfhost— por cinco líneas. Sin VERSION_ID ni fecha: un sello con la fecha del build cambiaría el hash cada día sin motivo, y con él la clausura de toda imagen que lo lleve. 🧨 Y el hallazgo estructural: `upgrade apply` falló dos veces con **No space left on device teniendo 3 G libres en la raíz**. No era `/` ni los inodos (9%): el estado de generaciones vive en **`/var/lib/hammer`, que es sda3 y mide 487 MB** — la partición «estado» del layout. Cada generación guarda una copia del árbol aplicado (272 MB el nuestro), así que dos no caben. Movido a `/work` por symlink, igual que qorpa, y la generación 6 entró. El layout de la imagen necesita revisión: 512 MB no alcanzan para un mecanismo que guarda un árbol por generación, y el síntoma apunta al sitio equivocado. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Tf9T4vGzsMoT7eS8YzMFn
This commit is contained in:
@@ -1406,6 +1406,42 @@ está instalado. ⇒ `qorpa pull` tiene que descomprimir con `zstd -dc | tar -x`
|
||||
alternativa es una imagen `.tar.gz` (Ubuntu base) — que además obliga a reinstalar las deps del venv,
|
||||
porque el de gioser trae extensiones de **CPython 3.14** y Ubuntu 24.04 lleva 3.12.
|
||||
|
||||
### 6.24 El TLS arreglado, la distro con nombre, y **por qué `upgrade` se quedaba sin espacio**
|
||||
|
||||
**El `curl` ya valida.** Con `ca-certificates` re-sellado —**119 hash-links en el capath**, generados
|
||||
en el build— la caja baja por HTTPS **sin ningún apaño**: `curl -I https://…` → **200**. El arreglo
|
||||
tardó tres intentos y los dos primeros los cazó la guarda que puse en la propia receta: primero
|
||||
`c_rehash` no estaba en el `PATH` (lo instala esa misma receta en `/out/usr/bin`), y después los
|
||||
certificados **no estaban sueltos** en `usr/share/ca-certificates/` sino en su subdirectorio
|
||||
`mozilla/`, así que `c_rehash` sólo veía el bundle y lo saltaba —correctamente— con «does not
|
||||
contain exactly one certificate». Sin la guarda, las tres veces habría sellado un capath vacío.
|
||||
|
||||
**`fastfetch` (2.68.1) corre en la caja** — y al correrlo apareció otra ausencia:
|
||||
|
||||
```
|
||||
OS: takana x86_64 ← ahora
|
||||
Host: vServer (20171111)
|
||||
Kernel: Linux 7.1.2 · CPU: AMD EPYC-Rome (4) · Memory: 393 MiB / 7.58 GiB
|
||||
```
|
||||
|
||||
…porque **`/etc/os-release` NO EXISTÍA**. La distro era anónima para cualquier programa que no fuera
|
||||
suyo. Se resolvió con una receta propia (`os-release`, `source.dir`) en vez de una constante en
|
||||
`takana-bootstrap`: meterlo ahí re-sellaría el `product-rootfs` —el baseline del selfhost— por cinco
|
||||
líneas. Sin `VERSION_ID` ni fecha a propósito: un sello con la fecha del build cambiaría el hash del
|
||||
artefacto, y con él la clausura de toda imagen que lo lleve, cada día y sin motivo.
|
||||
|
||||
#### 🧨 `/var/lib/hammer` es una partición de 487 MB — y ahí viven las generaciones
|
||||
|
||||
`upgrade apply` falló dos veces con `No space left on device` teniendo **3 G libres en la raíz**. Ni
|
||||
el espacio de `/` ni los inodos (9% usados): el estado de generaciones vive en
|
||||
**`/var/lib/hammer`, que es `sda3` y mide 487 MB** (la partición «estado» del layout). Cada
|
||||
generación guarda una copia del árbol aplicado — el nuestro son **272 MB** — así que **dos no caben**.
|
||||
|
||||
⇒ El estado se movió a `/work` por symlink, igual que `qorpa`. Tras eso: `✓ generación 6 aplicada`.
|
||||
**El layout de la imagen necesita revisión**: 512 MB de «estado» no alcanzan para un mecanismo que
|
||||
guarda un árbol entero por generación, y el síntoma (`ENOSPC` con la raíz medio vacía) apunta al
|
||||
sitio equivocado.
|
||||
|
||||
## 7. Reusar los scripts que ya existen, y no escribir de nuevo
|
||||
|
||||
Pedido explícito del usuario. El inventario de lo que ya hace el trabajo:
|
||||
|
||||
@@ -102,6 +102,11 @@ hereda = ["base"]
|
||||
# declara abajo es el subconjunto que ya estaba sellado y que un usuario de esta capa espera
|
||||
# encontrar — cero recetas nuevas, cero builds: sólo dejan de ser invisibles.
|
||||
paquetes = [
|
||||
# `os-release` (2026-09-14): la IDENTIDAD del sistema, que no existía. Se descubrió al meter
|
||||
# fastfetch: la caja decía «Host: vServer» y ni una palabra de takana, porque `/etc/os-release` no
|
||||
# estaba. Lo lee todo el que quiera saber en qué distro corre — sin él, la distro es anónima para
|
||||
# cualquier programa que no sea suyo.
|
||||
"os-release",
|
||||
# `fastfetch` (2026-09-14, pedido del usuario): la tarjeta de presentación del sistema. En una
|
||||
# distro propia es lo primero que contesta «¿qué estoy corriendo?» sin leer tres ficheros de
|
||||
# `/proc`, y en una caja recién instalada distingue «arrancó» de «arrancó lo que yo creía».
|
||||
|
||||
@@ -83,7 +83,12 @@ make install DESTDIR="/out"
|
||||
# ⚠ `c_rehash` lo compila e instala ESTA receta (`install -m755 c_rehash /out/usr/bin`), así que
|
||||
# no está en el `PATH` del sandbox: hay que invocarlo por su ruta de destino. La primera versión
|
||||
# lo llamaba por nombre, no lo encontraba, y la guarda de abajo cazó el silencio.
|
||||
cp "/out"/usr/share/ca-certificates/*.crt "/out"/etc/ssl/certs/ 2>/dev/null || true
|
||||
# ⚠ Los certificados NO están sueltos en `usr/share/ca-certificates/`: cuelgan de un
|
||||
# subdirectorio (`mozilla/`). El primer intento copiaba `…/ca-certificates/*.crt`, no casaba con
|
||||
# nada, y `c_rehash` sólo encontraba el bundle — que salta con «does not contain exactly one
|
||||
# certificate», que es correcto y parecía el problema cuando el problema era que no había nada
|
||||
# más que mirar.
|
||||
find "/out"/usr/share/ca-certificates -name '*.crt' -exec cp {} "/out"/etc/ssl/certs/ \;
|
||||
"/out"/usr/bin/c_rehash "/out"/etc/ssl/certs || ./c_rehash "/out"/etc/ssl/certs || true
|
||||
# Falla ruidosamente si el rehash no produjo NADA: un capath sin enlaces es exactamente el bug
|
||||
# que esto viene a cerrar, y sellarlo en silencio lo devolvería intacto.
|
||||
|
||||
@@ -33,6 +33,12 @@ flags = []
|
||||
build = ["cmake", "linux-headers"]
|
||||
|
||||
[build.phases]
|
||||
configure = "cmake -S . -B build -DCMAKE_LINK_DEPENDS_USE_LINKER=OFF -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DENABLE_SYSTEM_YYJSON=OFF -DENABLE_VULKAN=OFF -DENABLE_OPENCL=OFF -DENABLE_X11=OFF -DENABLE_XRANDR=OFF -DENABLE_WAYLAND=OFF -DENABLE_DCONF=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_CHAFA=OFF -DENABLE_DBUS=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_LIBNM=OFF -DENABLE_LIBZFS=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OSMESA=OFF -DENABLE_DRM=OFF -DENABLE_ELF=OFF -DENABLE_LIBCJSON=OFF"
|
||||
# ⚠ `-Wno-error=date-time`: `version.c` usa `__DATE__`/`__TIME__` y el lab compila con
|
||||
# `-Werror=date-time` —la política de reproducibilidad del sandbox, que aquí hizo exactamente su
|
||||
# trabajo y paró el build—. Desactivarlo es SEGURO **porque el sandbox exporta `SOURCE_DATE_EPOCH`**:
|
||||
# con esa variable definida, clang hace que `__DATE__`/`__TIME__` rindan esa fecha fija en vez de la
|
||||
# del reloj, así que el binario sigue siendo determinista. Sin `SOURCE_DATE_EPOCH` esto sería
|
||||
# hornear la hora del build dentro del artefacto, que es justo lo que el warning previene.
|
||||
configure = "cmake -S . -B build -DCMAKE_C_FLAGS=-Wno-error=date-time -DCMAKE_LINK_DEPENDS_USE_LINKER=OFF -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DENABLE_SYSTEM_YYJSON=OFF -DENABLE_VULKAN=OFF -DENABLE_OPENCL=OFF -DENABLE_X11=OFF -DENABLE_XRANDR=OFF -DENABLE_WAYLAND=OFF -DENABLE_DCONF=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_CHAFA=OFF -DENABLE_DBUS=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_LIBNM=OFF -DENABLE_LIBZFS=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OSMESA=OFF -DENABLE_DRM=OFF -DENABLE_ELF=OFF -DENABLE_LIBCJSON=OFF"
|
||||
compile = "cmake --build build"
|
||||
install = "DESTDIR=/out cmake --install build"
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# os-release — la identidad del sistema, que hasta hoy NO EXISTÍA.
|
||||
#
|
||||
# Se descubrió al meter `fastfetch` (2026-09-14): en la caja de producción decía
|
||||
#
|
||||
# Host: vServer (20171111)
|
||||
# Kernel: Linux 7.1.2
|
||||
#
|
||||
# …y ni una palabra de takana, porque `/etc/os-release` no está. No es cosmético: ese fichero es lo
|
||||
# que TODO el mundo lee para saber en qué distro corre — fastfetch, los instaladores de terceros, los
|
||||
# scripts de CI, el propio `qorpa` el día que quiera distinguir anfitrión de huésped. Una distro sin
|
||||
# `os-release` es anónima para cualquier programa que no sea suyo.
|
||||
#
|
||||
# ══ POR QUÉ UNA RECETA Y NO UNA CONSTANTE EN `takana-bootstrap` ════════════════════════════════
|
||||
# El `/etc/passwd` del producto SÍ es una constante de Rust, y esa decisión ya costó: para añadir un
|
||||
# usuario había que recompilar takana (lo arregló `[[user]]`). Meter `os-release` ahí re-sellaría el
|
||||
# `product-rootfs`, que es el **baseline del selfhost**, por un fichero de cinco líneas. Como receta
|
||||
# entra por perfil, se edita sin tocar el bootstrap y su radio es cero.
|
||||
#
|
||||
# ⚠ SIN VERSIÓN NI FECHA, a propósito. Un `VERSION_ID` con la fecha del build haría que este
|
||||
# artefacto —y con él la clausura de toda imagen que lo lleve— cambiara de hash cada día sin que
|
||||
# nada haya cambiado. La versión de una distro de árbol único es el hash de su imagen, que ya existe.
|
||||
name = "os-release"
|
||||
version = "1"
|
||||
license = "MIT"
|
||||
|
||||
[source]
|
||||
dir = "os-release/tree"
|
||||
|
||||
[build]
|
||||
compiler = "zig-cc"
|
||||
target = "x86_64-linux-musl"
|
||||
link = "static"
|
||||
flags = []
|
||||
|
||||
[build.phases]
|
||||
configure = "true"
|
||||
compile = "true"
|
||||
install = "mkdir -p /out/etc && cp /src/etc/os-release /out/etc/os-release && mkdir -p /out/usr/lib && ln -sf ../../etc/os-release /out/usr/lib/os-release"
|
||||
@@ -0,0 +1,5 @@
|
||||
NAME="takana"
|
||||
ID=takana
|
||||
PRETTY_NAME="takana"
|
||||
HOME_URL="https://git.gioser.net/sergio/takana"
|
||||
ANSI_COLOR="0;36"
|
||||
Reference in New Issue
Block a user