Ir al contenido

Estado de la compilación

Ditana mantiene su propio repositorio de pacman sobre Arch: 59 paquetes, enumerados en su totalidad en cada ejecución que llegó a su fin. Una ejecución que se detuvo enumera aquellos a los que había llegado. Cada noche, un servidor de compilación obtiene la receta de cada paquete, decide qué hay que recompilar y lo compila en un contenedor limpio. La regla que determina lo que ocurre a continuación es la única que importa aquí:

Si un solo paquete no se puede compilar, o no se pueden verificar sus fuentes, no se publica nada.

No «se publica el resto y ese se vuelve a intentar mañana». Nada. El repositorio desde el que usted instala es, o bien el conjunto completo y coherente entre sí que salió de una ejecución, o bien el conjunto completo y coherente entre sí de ayer. Un repositorio más pequeño puede prometer eso; uno grande, que se actualiza paquete por paquete, no puede, y por eso Ditana mantiene el suyo lo bastante pequeño como para responder por él como un único conjunto.

Una afirmación así vale exactamente lo que valen sus pruebas, por eso el historial que aparece más abajo lo escribe la propia canalización, incluidas las ejecuciones en las que no se publicó nada. Esa canalización es ditana-build y es pública: el control de revisión es bin/pkgbuild-review-gate, y la prueba de instalación es bin/test-install-in-qemu.

Cargando el historial de compilaciones…

Cada ejecución pasa por las mismas etapas, y su outcome indica a cuál llegó. Estos son los cuatro estados, y los colores de arriba:

outcome Qué significa para usted
released Esto es lo que usted instala. Todos los paquetes se compilaron, todas las firmas se verificaron y el conjunto completo reemplazó al repositorio desde el que se actualiza su sistema.
in-testing Compilado y firmado, en un repositorio de pruebas aparte mientras se comprueba. Su sistema sigue instalando la versión anterior.
built El servidor de compilación terminó, pero no tiene ninguna clave de firma: la firma se hace después en otra máquina. Todavía no se ha movido nada.
held-back Algo no superó las comprobaciones, así que no se publicó nada en absoluto. El repositorio desde el que usted instala está intacto y sigue siendo coherente.

Solo released significa que los paquetes llegaron hasta usted. Los otros tres son etapas del camino, o una detención.

Dentro de una ejecución, cada paquete recibe un status:

status Significado
current La receta no ha cambiado desde que se compiló el paquete existente y, en el caso de un paquete -git, el commit del proyecto original tampoco ha avanzado. No hay nada que hacer.
rebuilt Las fuentes se descargaron y verificaron en el servidor, y luego el paquete se compiló en un contenedor nuevo.
review-stopped La receta cambió de una forma que tiene que revisar una persona. La ejecución termina aquí.
build-failed El paquete no compiló o no produjo ningún artefacto. La ejecución termina aquí.

Los dos últimos son el motivo por el que una ejecución termina como held-back: basta con un paquete.

La mayor parte de lo que Ditana recompila son recetas del AUR de terceros, empaquetadas en un repositorio en el que sus usuarios confían mediante la configuración de firmas de pacman. El AUR es una cadena de suministro, y como tal ha sido atacado: se adoptaron paquetes huérfanos y se les añadieron commits maliciosos; por eso el AUR desactivó la adopción y los envíos de cambios en agosto de 2026.

Por eso cada git pull de la canalización se clasifica antes de compilar nada. Los incrementos de versión, los comentarios, los espacios en blanco y las sumas de comprobación que acompañan a un cambio de versión se dejan pasar. Un cambio en source=, en una url=, en una revisión del VCS, en cualquier cosa dentro de una función, en install=, en provides=, conflicts=, replaces= o validpgpkeys=, una suma de comprobación que cambia sin que cambie la versión, una dependencia nueva que pacman no conoce, una línea # Maintainer: modificada o vaciada: cada una de estas cosas detiene la ejecución. Para ello, la receta nunca se carga en un shell: ejecutar el archivo sospechoso es precisamente lo que hay que evitar, así que el análisis es estático y, ante la duda, falla en modo cerrado.

Medido con el historial real de paquetes de los últimos doce meses, esto detiene una ejecución aproximadamente una vez cada tres días y medio. No es un defecto que haya que eliminar con ajustes; es el precio de la regla de todo o nada, pagado por adelantado.

Algunas de las recetas que Ditana recompila no tienen ningún mantenedor original: su línea # Maintainer: está vacía. Por eso una línea de mantenedor vaciada detiene la ejecución en lugar de dejarse pasar: una receta huérfana es precisamente la que cualquiera puede adoptar.

La revisión abarca los metadatos de empaquetado, no el código fuente del proyecto original. Cuando una receta compila a partir de una revisión de git, nada en esta canalización revisa el contenido de esa revisión. La ventaja de Ditana frente a un servicio de recompilación sin revisión es real pero limitada, y declarar ese límite forma parte de la afirmación.

Compilar y firmar un repositorio no es lo mismo que poder instalar desde él. Entre el repositorio de pruebas y la publicación hay un paso más: el servidor de compilación instala ese mismo repositorio en una máquina virtual propia, de forma desatendida, guiada por un archivo de respuestas en una pequeña unidad de configuración; es el mismo mecanismo que usaría un proveedor de alojamiento a través de PXE, y por eso no se simula ninguna pulsación de teclas.

Deben cumplirse dos cosas, y el historial indica a cuál de ellas se llegó.

etapa Qué había ocurrido
installing El medio está en ejecución. Todavía no se ha instalado nada.
installed El instalador llegó a su reinicio final.
booted El sistema instalado arrancó por sí solo y respondió en el puerto 22. Esto es un éxito.

La distinción importa, porque las dos formas de fracasar son errores distintos. Una ejecución que se detiene en installing produjo un repositorio desde el que nadie puede instalar. Una que se detiene en installed produjo un sistema que se escribió correctamente y no arranca, y ese es el tipo de defecto que no detecta ninguna cantidad de compilaciones.

Llegar a booted significa mucho más de lo que sugiere la expresión. Se ejecutó el cargador de arranque, el initramfs encontró e importó la agrupación (pool) ZFS, systemd llegó al modo multiusuario, la red se activó y se inició un servicio. No se inyecta nada en el invitado para provocar ninguna de estas acciones: install-openssh está activado de forma predeterminada, así que un mensaje de identificación en el puerto 22 es obra del propio sistema instalado.

Cuando la prueba falla, el historial incluye una imagen de la pantalla del invitado en el momento en que el entorno de pruebas desistió. El medio de instalación no escribe nada en una consola serie una vez que su cargador de arranque ha cedido el control, así que todo lo que dibuja el instalador está en esa pantalla y en ningún otro lugar: un instalador que espera ante una pregunta se ve ahí y en ningún registro.

Una prueba fallida no publica nada. Los paquetes se quedan en el repositorio de pruebas, y el repositorio desde el que usted instala permanece intacto.

La máquina que compila tiene una subclave de firma, no la clave principal.

Compila, firma con esa subclave, sube al repositorio de pruebas, instala ese repositorio en una máquina virtual y publica en producción solo si la instalación funcionó. Mantener la clave fuera del servidor de compilación es algo que la canalización sigue admitiendo, y así funcionó Ditana hasta agosto de 2026; se abandonó porque una publicación condicionada a una instalación de prueba tiene que ocurrir en la máquina que acaba de compilar, y la separación intercalaba una segunda máquina y un paso manual. Lo que aporta a cambio la subclave: puede revocarse y reemplazarse por separado, no puede certificar otras claves, y la huella digital con la que verifican los usuarios nunca cambia.

Lo que esto protege es la clave, no los paquetes: la máquina de firma firma lo que produjo el servidor de compilación, sin revisarlo. Lo que evita es que la máquina que ejecuta scripts de compilación ajenos pueda hacer firmar datos arbitrarios en cualquier momento.

El historial es JSON simple y no lo genera este sitio web:

  • /build-history/index.json: el índice continuo de las ejecuciones más recientes.
  • /build-history/<timestamp>.json: un archivo por ejecución, con outcome, message, counts, un objeto test-install cuando la ejecución se probó, y un arreglo packages cuyas entradas contienen name, status, seconds, cualquier detail y las rutas de los registros de ese paquete.
  • El objeto test-install contiene result, el stage al que llegó el invitado, el iso y el answer-file con los que se condujo y, si la instalación falló, una ruta screenshot bajo /build-history/logs/<timestamp>/test-install/ que contiene la pantalla del invitado en el momento en que el entorno de pruebas desistió.
  • /build-history/logs/<timestamp>/<package>/: lo que makepkg registró al compilar ese paquete, dividido por etapa (prepare, build, check, package). Cada paquete recompilado en una ejecución está enlazado desde su fila de arriba, y también se registra un paquete cuya compilación falló: ese es el que vale la pena leer.

Los nombres de servidor, las direcciones, las rutas y el nombre de inicio de sesión de la cuenta de compilación se eliminan de los historiales y de los registros antes de escribirlos. No se filtra nada más; el texto de error que usted ve es el texto de error que vio la canalización.

Cada paquete de aquí se compila a partir de una receta disponible públicamente que indica su fuente original. Licencias explica dónde encontrar ambas cosas y trata el único caso en el que la propia licencia está en disputa: los paquetes de ZFS, de los que Ditana distribuye las fuentes y las herramientas de espacio de usuario, pero nunca un módulo del kernel compilado.

Esta traducción la hizo una máquina. Los lectores la mejoran en Weblate.