diff --git a/docs/state/build-state.json b/docs/state/build-state.json index 6aa0aceb..1d76f3de 100644 --- a/docs/state/build-state.json +++ b/docs/state/build-state.json @@ -1,27 +1,24 @@ { "schema": "hammer-build-state/1", "totals": { - "recipes": 877, - "nodes": 882, - "sealed": 877, - "ajeno": 2, - "wanted": 3 + "recipes": 881, + "nodes": 883, + "sealed": 881, + "ajeno": 2 }, "by_class": { "ajeno": 2, - "c": 234, + "c": 238, "go": 362, "gui": 41, "kernel": 6, - "rust": 234, - "wanted": 3 + "rust": 234 }, "debt_by_class": {}, "by_queue": { "corpus": { - "sealed": 877, - "ajeno": 2, - "wanted": 3 + "sealed": 881, + "ajeno": 2 } }, "by_profile": { @@ -42,11 +39,11 @@ }, "servidor": { "raices": 61, - "clausura": 97, - "sealed": 97 + "clausura": 101, + "sealed": 101 } }, - "sin_perfil": 646, + "sin_perfil": 643, "orphan_deps": [], "topo_ok": true, "nodes": { @@ -1008,7 +1005,7 @@ "escritorio-sway", "servidor" ], - "dependientes_total": 48 + "dependientes_total": 52 }, "biome": { "iname": "biome", @@ -1285,7 +1282,7 @@ "escritorio-sway", "servidor" ], - "dependientes_total": 8 + "dependientes_total": 12 }, "bwrap": { "iname": "bwrap", @@ -2444,17 +2441,26 @@ }, "chrony": { "iname": "chrony", - "version": null, - "link": null, - "compiler": null, - "deps": [], - "cls": "wanted", + "version": "4.9", + "link": "static", + "compiler": "zig-cc", + "deps": [ + "binutils", + "busybox", + "libcap", + "make", + "pkgconf" + ], + "cls": "c", "queue": "corpus", - "hash": null, - "state": "wanted", + "foreign": false, + "hash": "b3:b9e26374f000ef5820bcc32bdb761b2b3e7306d1ed400c147271cfdbd77557e9", + "state": "sealed", "blocked_by": [], "unblocks": 0, - "perfiles": [], + "perfiles": [ + "servidor" + ], "dependientes_total": 0 }, "cilium-cli": { @@ -2871,17 +2877,25 @@ }, "cronie": { "iname": "cronie", - "version": null, - "link": null, - "compiler": null, - "deps": [], - "cls": "wanted", + "version": "1.7.2", + "link": "static", + "compiler": "zig-cc", + "deps": [ + "binutils", + "busybox", + "make", + "pkgconf" + ], + "cls": "c", "queue": "corpus", - "hash": null, - "state": "wanted", + "foreign": false, + "hash": "b3:387347b89b107d97febbb2692ce2d292e74bc7b1fba105676befe396cc3ebf21", + "state": "sealed", "blocked_by": [], "unblocks": 0, - "perfiles": [], + "perfiles": [ + "servidor" + ], "dependientes_total": 0 }, "crossplane-cli": { @@ -9313,7 +9327,7 @@ "escritorio-sway", "servidor" ], - "dependientes_total": 3 + "dependientes_total": 4 }, "libdisplay-info": { "iname": "libdisplay-info", @@ -10521,17 +10535,26 @@ }, "logrotate": { "iname": "logrotate", - "version": null, - "link": null, - "compiler": null, - "deps": [], - "cls": "wanted", + "version": "3.22.0", + "link": "static", + "compiler": "zig-cc", + "deps": [ + "binutils", + "busybox", + "make", + "pkgconf", + "popt" + ], + "cls": "c", "queue": "corpus", - "hash": null, - "state": "wanted", + "foreign": false, + "hash": "b3:09698cb83519dc2423b8aa1905fa5803955ee1c79598590c30ff5b5b14e5e84d", + "state": "sealed", "blocked_by": [], "unblocks": 0, - "perfiles": [], + "perfiles": [ + "servidor" + ], "dependientes_total": 0 }, "lsd": { @@ -10763,7 +10786,7 @@ "escritorio-sway", "servidor" ], - "dependientes_total": 124 + "dependientes_total": 128 }, "mako": { "iname": "mako", @@ -13127,7 +13150,7 @@ "escritorio-sway", "servidor" ], - "dependientes_total": 406 + "dependientes_total": 410 }, "plow": { "iname": "plow", @@ -13308,6 +13331,29 @@ "perfiles": [], "dependientes_total": 0 }, + "popt": { + "iname": "popt", + "version": "1.19", + "link": "static", + "compiler": "zig-cc", + "deps": [ + "binutils", + "busybox", + "make", + "pkgconf" + ], + "cls": "c", + "queue": "corpus", + "foreign": false, + "hash": "b3:7202a918f06efe0315267027b071f5380f77aa15ce59eac83b5f078e6edd24f4", + "state": "sealed", + "blocked_by": [], + "unblocks": 0, + "perfiles": [ + "servidor" + ], + "dependientes_total": 1 + }, "prek": { "iname": "prek", "version": "0.3.11", diff --git a/recipes/chrony.toml b/recipes/chrony.toml new file mode 100644 index 00000000..d2846f55 --- /dev/null +++ b/recipes/chrony.toml @@ -0,0 +1,70 @@ +# chrony 4.9 — el reloj. `targets.toml` lo declara como raíz del perfil `servidor` con un motivo que +# no es comodidad: sin NTP un reloj que deriva rompe la validación de certificados TLS y la de firmas +# con expiración, y falla con errores que NO dicen «la hora», dicen «firma inválida». Era una de las +# tres `wanted` que el grafo contaba como deuda del perfil. +# +# El `configure` de chrony NO ES AUTOTOOLS: es un script a mano que ni siquiera acepta +# `--build`/`--host` (los imprime como «Unrecognized option» y sigue). Por eso esta receta no lleva +# la línea `--build=$CBUILD --host=$CHOST` que llevan todas las demás; lo que sí acepta —y es su +# equivalente— es `--host-system`/`--host-machine`, que se pinean para que la detección no salga de +# `uname` del lab. +# +# ⚠ TODO `--without-*` DE ACÁ ABAJO ESTÁ POR LA MISMA RAZÓN, Y NO ES PROLIJIDAD. El `configure` de +# chrony PRUEBA el entorno para casi todo (`try_nettle=1`, `try_gnutls=1`, `try_libcap=-1`, +# `try_seccomp=-1`, `try_editline=1`…): lo que encuentre instalado en el LAB cambia el binario. Y el +# lab NO entra en `hash_inputs` — dos labs distintos sellarían bytes distintos en la MISMA dirección +# del store sin que nada lo note. Fijar cada palanca convierte eso en una decisión de la receta, que +# sí entra en el hash. Enumeradas: +# +# --without-nettle --without-gnutls --without-nss --without-tomcrypt --disable-nts +# NTS (NTP sobre TLS) necesita nettle o gnutls, y NINGUNA de las dos está en el corpus. Se +# apaga a propósito y queda anotado: subir NTS es su propia unidad de trabajo —entra un árbol +# de criptografía entero— no algo que se resuelve de paso. Mientras tanto chronyd hace NTP +# clásico, que es lo que la caja necesita para que TLS no falle por la hora. +# --disable-readline --without-editline +# el editor de línea de `chronyc`. Ni readline ni editline están en el corpus; sin fijarlo, un +# lab que las tuviera cambiaría el binario. +# --without-seccomp +# el filtro de syscalls (`--enable-scfilter`) viene apagado de fábrica, pero el probe de +# libseccomp corre igual. Sin scfilter, encontrarla no aporta nada y sí mueve el hash. +# +# `libcap` SÍ entra como dep, y es la decisión contraria a las de arriba: chronyd suelta privilegios +# (`--disable-privdrop` NO se pasa) y para eso necesita `cap_*`. Declararla como dep la vuelve +# presente-por-contrato en vez de presente-por-suerte-del-lab, que es exactamente el mismo problema +# visto del otro lado. El `libcap` del corpus publica sólo `.a` (`SHARED=no`), así que enlaza +# estático y no deja NEEDED colgante. +# +# **`--with-user` se deja en `root`.** Lo natural sería `chrony`, pero un chronyd que hace `setuid` +# a un usuario que no existe en `/etc/passwd` no arranca, y la distro todavía no crea usuarios de +# servicio. Cambiarlo va junto con esa decisión, no antes. +# +# **Consecuencia medida de apagar la criptografía:** el binario sale `-SECHASH`, o sea que para la +# autenticación simétrica por clave sólo queda MD5. No es un descuido: `sechash` (SHA-2 y CMAC) se +# implementa contra nettle/gnutls/nss/tomcrypt, las mismas que no están. Lo que el binario SÍ trae, +# comprobado corriéndolo: `+CMDMON +REFCLOCK +RTC +PRIVDROP +IPV6`, es decir que `libcap` entró de +# verdad — `cap_set_proc`/`cap_from_text` están en el ELF — y chronyd suelta privilegios. +# +# La reproducibilidad ya la trae upstream: el `NTP_ERA_SPLIT` —que por default es «hace 50 años» +# calculado con `date` en tiempo de configure— respeta `SOURCE_DATE_EPOCH`, que el lab exporta. Sin +# eso el binario cambiaría cada día sin tocar la receta. +name = "chrony" +version = "4.9" +license = "GPL-2.0-only" + +[source] +tarball = "https://chrony-project.org/releases/chrony-4.9.tar.gz" +sha256 = "4924c6f530105bcd5b9e9e33c48a2ae1bfd889222c8480bc41601110efc864d0" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" +flags = [] + +[build.phases] +configure = './configure --host-system=Linux --host-machine=x86_64 --prefix=/usr --sysconfdir=/etc --sbindir=/usr/sbin --bindir=/usr/bin --without-nettle --without-gnutls --without-nss --without-tomcrypt --disable-nts --disable-readline --without-editline --without-seccomp' +compile = 'make -j"$(nproc)"' +install = "make install DESTDIR=/out" + +[deps] +build = ["binutils", "busybox", "make", "pkgconf", "libcap"] diff --git a/recipes/cronie.toml b/recipes/cronie.toml new file mode 100644 index 00000000..f7f4b679 --- /dev/null +++ b/recipes/cronie.toml @@ -0,0 +1,54 @@ +# cronie 1.7.2 — el disparador periódico. Es la tercera y última de las raíces que `targets.toml` +# declaraba para el perfil `servidor` sin receta detrás. El motivo escrito allí es directo: en una +# distro sin systemd no hay timers, y el latido de la granja son tres líneas de crontab. +# +# **Y busybox YA trae un `crond` — esto no lo reemplaza por reflejo.** El artefacto sellado de +# busybox pone `crond` en `/sbin`. Lo que cronie agrega y busybox no tiene: `@reboot`, crontabs por +# usuario con `crontab -e`, `/etc/cron.d`, `cronnext`, y `anacron` para las tareas que hay que +# recuperar cuando la máquina estuvo apagada. Cuál de los dos va en cada imagen es una decisión de +# perfil, no de esta receta; lo que hacía falta era que la opción EXISTIERA en el corpus en vez de +# descubrirse ausente el día que alguien la necesite. +# +# ⚠ EL DEFAULT QUE HABÍA QUE PINEAR SÍ O SÍ: `--with-editor`. Sin él, `configure.ac` hace +# `AC_PATH_PROG([vi])` — o sea que la ruta del editor que `crontab -e` lanza SALE DE BUSCAR `vi` EN +# EL LAB, y queda grabada en el binario con `AC_DEFINE_UNQUOTED`. El lab no entra en `hash_inputs`: +# dos labs con `vi` en rutas distintas sellarían bytes distintos en la MISMA dirección del store y +# nada lo notaría. Se fija en `/bin/vi`, que además es donde busybox lo deja de verdad (comprobado +# en su artefacto sellado); el fallback de autoconf era `/usr/bin/vi`, que en esta distro no existe. +# +# Lo demás son palancas de cosas que el corpus no tiene, apagadas explícitamente por la misma razón +# —que el probe no salga del entorno— y no porque estorben: +# --without-pam no hay Linux-PAM en el corpus. La autorización de `crontab` cae entonces a +# `/etc/cron.allow` + `/etc/cron.deny`, que es el mecanismo clásico y no +# necesita nada más. +# --without-selinux la distro no lleva SELinux. +# --without-audit no hay libaudit. +# --with-inotify esto se ENCIENDE: con inotify, crond se entera de un crontab editado sin +# esperar al minuto siguiente. Es una API del kernel, no una dep nueva. +# --enable-syscrontab `/etc/crontab` y `/etc/cron.d`, que es por donde entra el latido de la granja. +# +# `link = "static"`: binarios monolíticos como el resto de las herramientas de sistema. +# +# La licencia es compuesta y no se adivina: el grueso (`src/cron.c` y compañía) es ISC de Vixie/ISC, +# y `anacron` —que se construye— trae su propio `COPYING.anacron`, GPLv2-or-later. +name = "cronie" +version = "1.7.2" +license = "ISC AND GPL-2.0-or-later" + +[source] +tarball = "https://github.com/cronie-crond/cronie/releases/download/cronie-1.7.2/cronie-1.7.2.tar.gz" +sha256 = "f1da374a15ba7605cf378347f96bc8b678d3d7c0765269c8242cfe5b0789c571" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" +flags = [] + +[build.phases] +configure = './configure --build=$CBUILD --host=$CHOST --prefix=/usr --sysconfdir=/etc --localstatedir=/var --sbindir=/usr/sbin --with-editor=/bin/vi --with-inotify --without-pam --without-selinux --without-audit --enable-syscrontab' +compile = 'make -j"$(nproc)"' +install = "make install DESTDIR=/out && find /out -name '*.la' -delete" + +[deps] +build = ["binutils", "busybox", "make", "pkgconf"] diff --git a/recipes/logrotate.toml b/recipes/logrotate.toml new file mode 100644 index 00000000..8b7e39c7 --- /dev/null +++ b/recipes/logrotate.toml @@ -0,0 +1,52 @@ +# logrotate 3.22.0 — la rotación de logs. Es la última de las tres raíces que `targets.toml` declara +# para el perfil `servidor` y que no tenían receta: el grafo las contaba como `wanted` y la deuda del +# perfil era exactamente ésa. El motivo escrito allí sigue valiendo: en una caja que sirve, el log de +# acceso crece hasta llenar el disco, y Caddy rota el suyo por configuración pero nada más lo hace. +# +# DOS DEFAULTS DE `configure` QUE SE PINEAN A PROPÓSITO, y no por prolijidad: +# +# 1. **`--with-selinux=no --with-acl=no`.** Los dos vienen con `[default=check]`, o sea que el +# contenido del binario depende de si el LAB tiene `libselinux`/`libacl` instaladas. El lab NO +# entra en `hash_inputs` (deuda conocida del repo): dos labs distintos sellarían bytes distintos +# en la MISMA dirección del store y nada lo notaría. Fijarlo en `no` lo vuelve una decisión de la +# receta —que sí entra en el hash— en vez de un accidente del entorno. Y `no` es lo correcto acá: +# la distro no lleva SELinux ni ACLs POSIX. +# +# 2. **`--with-compress-command` / `--with-uncompress-command`.** `configure.ac` elige la ruta por +# sistema operativo y en Linux fija `/usr/bin/gzip`, que en esta distro NO EXISTE: el `gzip` y el +# `gunzip` los provee busybox y quedan en `/bin` (comprobado en el artefacto sellado de busybox). +# Un logrotate con `compress` en la config fallaría en runtime buscando un binario ausente, y el +# error sería «no se pudo comprimir», no «la ruta está mal». Se pinean a `/bin/…`. +# +# **Lo que NO se pinea, y por qué se deja anotado:** el `mail command` queda en su default +# `/bin/mail`, que en esta distro NO existe — busybox provee `sendmail`, no `mail`. No se cambia a +# `/bin/sendmail` porque no es un reemplazo: logrotate lo invoca como `mail -s ` y +# la interfaz de busybox es otra. Sólo afecta a configuraciones que usen la directiva `mail`, que la +# distro hoy no tiene; queda dicho para que se descubra leyendo y no en runtime. +# +# `--with-state-file-path` se deja en su default (`/var/lib/logrotate.status`): es ruta de ESTADO en +# la máquina viva, no algo que la imagen deba decidir. +# +# `link = "static"`: binario monolítico, como el resto de las herramientas de sistema. popt publica +# sólo `.a` justo para que acá no aparezca un NEEDED colgante. +name = "logrotate" +version = "3.22.0" +license = "GPL-2.0-or-later" + +[source] +tarball = "https://github.com/logrotate/logrotate/releases/download/3.22.0/logrotate-3.22.0.tar.xz" +sha256 = "42b4080ee99c9fb6a7d12d8e787637d057a635194e25971997eebbe8d5e57618" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" +flags = [] + +[build.phases] +configure = './configure --build=$CBUILD --host=$CHOST --prefix=/usr --with-selinux=no --with-acl=no --with-compress-command=/bin/gzip --with-uncompress-command=/bin/gunzip' +compile = 'make -j"$(nproc)"' +install = "make install DESTDIR=/out && find /out -name '*.la' -delete" + +[deps] +build = ["binutils", "busybox", "make", "pkgconf", "popt"] diff --git a/recipes/popt.toml b/recipes/popt.toml new file mode 100644 index 00000000..f7f1e8f7 --- /dev/null +++ b/recipes/popt.toml @@ -0,0 +1,39 @@ +# popt 1.19 — el parser de opciones de línea de comando de rpm. Entra por UNA razón y sólo una: +# `logrotate` lo exige. Su `logrotate.c` hace `#include ` en la primera pantalla y su +# `configure` aborta sin él; no hay flag para sacarlo ni fallback interno a getopt. +# +# Es la hoja de la cadena `logrotate` del perfil `servidor`, que el grafo pedía como `wanted` desde +# que se escribió `targets.toml` y que nadie había puesto. +# +# Tarball de release y no git: el árbol de git NO trae `configure` (lo genera `autoreconf`) y el +# corpus no tiene autoconf/automake — el mismo motivo por el que entran libmnl, jq y gmp. +# +# `--disable-nls`: popt traduce sus mensajes de error con gettext, y el corpus tiene `gettext-tiny`, +# cuyo `msgfmt` muere con SIGILL en algunos catálogos (los plurales del árabe). No vale la pena +# arriesgar eso por los mensajes de error de un parser de flags que sólo ve `logrotate`. +# +# `link = "static"` y `--disable-shared`: el consumidor es un binario de sistema que queremos +# monolítico (la estrategia de hidratación primaria). Publicar sólo `.a` evita además que +# `logrotate` salga con un NEEDED de `libpopt.so.0` que después nadie provea — la familia de fallos +# de `needed-colgante`. +name = "popt" +version = "1.19" +license = "MIT" + +[source] +tarball = "http://ftp.rpm.org/popt/releases/popt-1.x/popt-1.19.tar.gz" +sha256 = "c25a4838fc8e4c1c8aacb8bd620edb3084a3d63bf8987fdad3ca2758c63240f9" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" +flags = [] + +[build.phases] +configure = './configure --build=$CBUILD --host=$CHOST --prefix=/usr --disable-shared --enable-static --disable-nls --disable-rpath' +compile = 'make -j"$(nproc)"' +install = "make install DESTDIR=/out && find /out -name '*.la' -delete" + +[deps] +build = ["binutils", "busybox", "make", "pkgconf"]