======================================================= Protocolo de Mantenimiento del Fork y Ciclo de Vida RPM ======================================================= --------------------------------------------------------------- Directrices de Ingesta, Ramificación, Versionamiento y Upstream --------------------------------------------------------------- :Autores: - Rénich Bon Ćirić :Organización: Fundación MxOS, A.C. :Fecha: Septiembre 2026 :Estado: Estándar Activo Introducción y Objetivos de Soberanía ===================================== La meta fundamental de la Fundación MxOS es establecer una bifurcación (*fork*) soberana, independiente y 100% reproducible a partir del ecosistema de **CentOS Stream 10**. Para mantener la interoperabilidad binaria con el estándar Enterprise Linux de Red Hat y garantizar la sostenibilidad técnica del proyecto a largo plazo, el mantenimiento de paquetes no se realiza de forma arbitraria ni aislada. Se rige por tres principios innegociables: 1. **Inmutabilidad de Upstream**: Las fuentes originales de CentOS Stream se conservan prístinas y trazables en todo momento. 2. **Historia Lineal y Rebase**: Las modificaciones propias de la distribución se mantienen como una serie limpia y reubicable de parches sobre la punta de upstream, evitando fusiones (*merge commits*) que oscurezcan el origen del código. 3. **Colaboración Upstream-First**: Todo parche o corrección de interés general se propone a upstream antes de consolidarse de forma divergente en la distribución. La Dualidad de Fuentes de CentOS Stream ======================================= Uno de los aspectos más críticos y complejos al bifurcar CentOS Stream radica en comprender que **el código fuente no proviene de un único canal**. Existe una dualidad arquitectónica entre la forja de control de versiones y el sistema de compilación: .. list-table:: :header-rows: 1 :widths: 25 35 40 * - Dimensión - GitLab (dist-git) - Koji Upstream/CBS * - **Ubicación** - ``gitlab.com/redhat/centos-stream/rpms`` - ``koji.stream.centos.org`` (Core OS) y ``cbs.centos.org`` (SIGs) * - **Contenido Principal** - Archivos ``.spec``, parches locales y metadatos ``sources`` (SHA512). - Binarios compilados, buildroots de Mock, side tags y composes. * - **Propósito** - Control de versiones declarativo y desarrollo colaborativo. - Orquestación de dependencias cíclicas y construcción determinista. GitLab dist-git --------------- Representa la intención declarativa del paquete: * Contiene las recetas de empaquetado (``.spec``) y los parches aprobados. * No almacena tarballs pesados de código fuente directamente en Git; en su lugar, utiliza un archivo de metadatos denominado ``sources`` que referencia los hashes criptográficos (SHA512) alojados en el servidor de *lookaside cache*. * Se organiza en ramas oficiales correspondientes al ciclo de vida de la distribución (por ejemplo, ``c10s`` para CentOS Stream 10). Koji Hubs y el CentOS Build System (CBS) ---------------------------------------- Representa el estado operativo real y los entornos de ejecución en los que se compilan los paquetes: * **Distinción entre Core Koji y CBS**: El núcleo de CentOS Stream 10 (BaseOS, AppStream, CRB) se compila exclusivamente en **``koji.stream.centos.org``** (Koji Hub central). El servidor **``cbs.centos.org``** (*Community Build Service*) se reserva para los *Special Interest Groups* (SIGs: Hyperscale, Cloud, Storage, Kmods). La ingesta base de MxOS interactúa con ``koji.stream.centos.org``. * **Side Tags (c10s-build-side-XXXX)**: Cuando un componente base altera su interfaz binaria (*ABI break*, tales como actualizaciones mayores de ``glibc``, ``openssl``, compiladores GCC/LLVM o runtimes como Python), no es posible compilarlo de forma aislada en la rama principal sin romper los constructores (*builders*). Los ingenieros de upstream crean un *side tag* efímero en Koji: compilan la biblioteca base en ese tag, construyen todos los paquetes dependientes contra ese entorno temporal y, una vez verificado el conjunto, fusionan atómicamente el tag completo al árbol principal. Si un mantenedor intenta reconstruir un paquete de GitLab desconociendo el side tag activo al momento de su creación, la compilación fallará por dependencias insatisfechas. * **Artefactos y Paquetes de Buildroot**: Para resolver dependencias cíclicas de arranque (*Cyclic Bootstrap*), Koji inyecta paquetes mínimos de herramientas intermedias en las raíces chroot de Mock. Muchos de estos paquetes (herramientas de generación de documentación, compiladores auxiliares y utilerías de bootstrapping) **nunca se publican en los repositorios finales BaseOS o AppStream**. Solo existen como artefactos de compilación en Koji upstream o en repositorios de desarrollo como CRB (*CodeReady Linux Builder*). * **Soberanía del Lookaside Cache**: GitLab dist-git solo preserva los metadatos de los tarballs en el archivo ``sources``. Para evitar que la purga o indisponibilidad de fuentes en ``sources.stream.centos.org`` comprometa la reproducibilidad de MxOS, la herramienta ``rpms-sync`` descarga y almacena de forma inmutable cada tarball en el servidor de fuentes de la Fundación (``sources.mx-os.mx``). Arquitectura de Ramas en Forgejo (git.mx-os.mx/rpms) ==================================================== Todos los repositorios de paquetes sincronizados se alojan en la organización ``rpms`` de nuestra forja soberana. En cada repositorio se definen dos categorías estrictas de ramas: Ramas de Upstream (Ej. c10s, c9s) --------------------------------- * Espejos exactos, sincronizados y de **solo lectura**. * Son administradas de forma desatendida por el servicio ``rpms-sync``. * **Regla estricta**: Queda terminantemente prohibido realizar commits directos, modificaciones manuales o fusiones (*merges*) sobre estas ramas. Ramas de Distribución (Ej. c10s-mxos, c9s-mxos) ----------------------------------------------- * Es la rama oficial de producción para la distribución MxOS. * Lleva obligatoriamente el sufijo ``-mxos``. * Contiene la serie lineal de parches de soberanía, personalización del archivo ``.spec``, desmarcado (*debranding*) e identidad de la Fundación. * Es una rama protegida en Forgejo: las modificaciones se incorporan mediante Pull Requests revisados o por mantenedores principales acreditados. Flujo de Trabajo Estricto Basado en Rebase ========================================== Para garantizar que la serie de modificaciones de MxOS sea auditable, limpia y exportable, **se prohíbe el uso de git merge** al incorporar actualizaciones de upstream. Se utiliza exclusivamente **git rebase**. Justificación Técnica --------------------- * El comando ``git merge origin/c10s`` introduce *merge commits* artificiales que entrelazan los historiales de desarrollo, dificultando la identificación de qué líneas pertenecen a CentOS y cuáles a MxOS. * El comando ``git rebase origin/c10s`` toma los commits propios de MxOS, los retira temporalmente, actualiza la base al último commit oficial de CentOS Stream y reaplica los cambios propios uno a uno en la punta de la historia. * Permite auditar en cualquier instante el delta exacto de la distribución mediante: .. code-block:: bash git log origin/c10s..c10s-mxos Procedimiento Paso a Paso para Colaboradores -------------------------------------------- 1. **Configuración de Entorno**: Asegurar que Git use rebase de forma predeterminada al actualizar: .. code-block:: bash git config --global pull.rebase true 2. **Obtención del Repositorio**: Clonar el paquete desde la forja de la Fundación: .. code-block:: bash git clone https://git.mx-os.mx/rpms/bash.git cd bash 3. **Creación de la Rama de Trabajo**: Partir siempre de la rama de distribución actualizada (``c10s-mxos``): .. code-block:: bash git switch c10s-mxos git pull --rebase origin c10s-mxos git switch -c fix/descripcion-del-cambio 4. **Desarrollo y Commits Atómicos**: Aplicar las modificaciones en el archivo ``.spec`` o agregar parches en formato unificado (``git format-patch``). Realizar commits con mensajes convencionales claros: .. code-block:: bash git add . git commit -s -m "fix(spec): corregir ruta de inicialización para perfiles MxOS" 5. **Sincronización Previa y Rebase**: Antes de abrir un Pull Request, rebasear contra la punta remota de MxOS: .. code-block:: bash git fetch origin git rebase origin/c10s-mxos 6. **Apertura de Pull Request**: Subir la rama a Forgejo y abrir un PR dirigido exclusivamente hacia ``c10s-mxos``: .. code-block:: bash git push -u origin fix/descripcion-del-cambio Procedimiento de Integración y Release para Mantenedores -------------------------------------------------------- Cuando upstream (CentOS Stream) publica nuevas versiones, el mantenedor sincroniza la rama de distribución y orquesta la compilación en Koji: .. code-block:: bash # 1. Asegurar copia limpia de la rama de upstream git switch c10s git fetch origin git reset --hard origin/c10s # 2. Registrar el commit base actual de la rama de distribucion para push atomico git switch c10s-mxos BASE_SHA=$(git rev-parse HEAD) # 3. Rebasear la serie de parches de MxOS sobre el nuevo upstream git rebase origin/c10s # 4. Resolver conflictos si los parches colisionan con cambios de upstream # Si un parche fue incorporado en upstream, eliminarlo manualmente: # git rm 0001-parche-obsoleto.patch # Editar el .spec para retirar la referencia PatchXXXX: git add *.spec git rebase --continue # 5. Descargar fuentes del lookaside cache antes de compilar spectool -g *.spec # 6. Validar reconstruccion binaria completa en Mock local mock -r centos-stream-10-x86_64 --spec *.spec --sources . # 7. Crear etiqueta inmutable y firmada para Koji Hub # Koji NUNCA debe compilar contra ramas rebaseables volatiles TAG_NAME="v$(rpmspec -q --queryformat '%{VERSION}-%{RELEASE}' *.spec)" git tag -s -a "${TAG_NAME}" -m "Release ${TAG_NAME} para Koji Hub" # 8. Publicar la historia rebaseada de forma segura mediante ref de control git push --force-with-lease=c10s-mxos:${BASE_SHA} origin c10s-mxos git push origin "${TAG_NAME}" # 9. Enviar la tarea de compilacion a la granja Koji de MxOS koji build c10s-mxos "git+https://git.mx-os.mx/rpms/bash.git#${TAG_NAME}" Estándares de Versionamiento RPM (Ordenabilidad EVR) ==================================================== El versionamiento de paquetes en MxOS cumple rigurosamente con las directrices de empaquetamiento de Fedora y el algoritmo de ordenamiento **Epoch:Version-Release (EVR)** de RPM. Regla Fundamental de Compatibilidad ----------------------------------- **Nunca se altera el campo Version para paquetes bifurcados de upstream.** Si se modifica la versión (por ejemplo, renombrando un paquete a ``v1.0``), se rompe de forma inmediata el grafo de dependencias de RPM de la distribución (ej. ``Requires: systemd >= 256.0``). Arquitectura de Versionamiento: Modelo Clon Prístino (Opción A) --------------------------------------------------------------- La Fundación MxOS adopta el **Modelo Clon Prístino** (análogo a Rocky Linux y a la arquitectura base de AlmaLinux), manteniendo máxima paridad con CentOS Stream 10 para minimizar la sobrecarga de mantenimiento en Git. 1. Paquetes Intactos (Rebuilds 1:1 de Upstream) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Para el 98% o más de los paquetes del sistema operativo, el archivo ``.spec`` **no se modifica en lo absoluto**. * Se compilan en la granja Koji de MxOS utilizando el macro de distribución oficial de Enterprise Linux (``%dist .el10``). * El identificador NVR (*Name-Version-Release*) se preserva idéntico a upstream. * Ejemplo: ``bash-5.2.26-1.el10.x86_64.rpm`` conserva exactamente el mismo nombre, garantizando compatibilidad total con scripts y utilerías de terceros que validan el sufijo ``.el10``. 2. Paquetes Modificados (Desmarcado, Identidad o Hotfixes) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Cuando un paquete de CentOS Stream requiere modificaciones por parte de la Fundación (ej. desmarcado de logos, temas gráficos, ajustes en Anaconda o parches de emergencia), se preserva el campo ``Version`` y se añade el calificador de MxOS al campo ``Release`` en la rama ``c10s-mxos``: * **Especificaciones Modernas con rpmautospec (%autorelease)**: La gran mayoría de los paquetes en CentOS Stream 10 utilizan ``rpmautospec``. Para incorporar la iteración de MxOS, se utiliza la bandera de sufijo extra (``-e``): .. code-block:: spec Release: %autorelease -e mxos.%{patch_iteration} En la implementación nativa de ``macros.rpmautospec`` de Fedora, la bandera ``-e`` inyecta el calificador antes del dist tag (``.%{?dist}``). Por tanto, la expansión genera: .. code-block:: text bash-5.2.26-1.mxos.1.el10.x86_64.rpm * **Especificaciones Tradicionales**: En paquetes que no utilizan ``rpmautospec``, se sigue la misma estructura anteponiendo el calificador al macro ``%{?dist}``: .. code-block:: spec Release: 1.mxos.1%{?dist} Comportamiento Matemático del Comparador EVR -------------------------------------------- Esta estructura resuelve limpiamente las reglas de ordenamiento de RPM verificadas mediante ``rpm.labelCompare``: 1. **Precedencia Local sobre Upstream Base**: ``5.2.26-1.mxos.1.el10`` > ``5.2.26-1.el10`` En igualdad de versión y release base, el calificador ``.mxos.1`` asegura que el paquete modificado de MxOS tenga precedencia sobre el binario sin modificar. 2. **Resistencia ante Erratas y Z-Streams de Upstream**: ``5.2.26-1.mxos.1.el10`` > ``5.2.26-1.el10_0.1`` Al posicionar ``mxos`` antes de ``el10``, se evita la trampa algorítmica de RPM donde los dígitos numéricos vencen a las cadenas alfabéticas. Puesto que el carácter ``'m'`` es alfabéticamente superior a ``'e'``, la versión parcheada de MxOS prevalece ante erratas menores de upstream dentro del mismo release base. 3. **Alertas de Actualización ante Nuevos Releases Upstream**: ``5.2.26-1.mxos.1.el10`` < ``5.2.26-2.el10`` Cuando Red Hat incrementa el release base a ``2``, el comparador EVR detecta matemáticamente que existe una versión superior en upstream, alertando al pipeline de ingesta (``rpms-sync``) para disparar el rebase. 4. **Iteración Interna de Parches**: ``5.2.26-1.mxos.2.el10`` > ``5.2.26-1.mxos.1.el10`` Permite al equipo de empaquetamiento publicar mejoras o correcciones a los parches propios de manera determinista. .. caution:: **Aislamiento Obligatorio de Repositorios DNF**: Las estaciones de trabajo y servidores de MxOS **nunca deben tener configurados repositorios de CentOS Stream upstream en vivo**. La Fundación MxOS compone, firma y hospeda sus propios repositorios ``BaseOS`` y ``AppStream``. Si un cliente consultara directamente a CentOS Stream, DNF actualizaría automáticamente a un nuevo release de upstream si estuviera disponible, eliminando los parches de identidad y soberanía de MxOS (*vendor clobbering*). Estructura Oficial de Repositorios DNF ====================================== MxOS adopta estrictamente la nomenclatura y jerarquía de repositorios de CentOS Stream 10 para garantizar compatibilidad con el instalador Anaconda, herramientas de gestión de paquetes y repositorios de terceros como EPEL 10: .. list-table:: :header-rows: 1 :widths: 20 25 35 20 * - Repositorio DNF - ID en Repo - Ruta en Espejo - Estado * - **BaseOS** - ``[baseos]`` - ``/10-stream/BaseOS/$basearch/os/`` - Habilitado * - **AppStream** - ``[appstream]`` - ``/10-stream/AppStream/$basearch/os/`` - Habilitado * - **CodeReady Builder** - ``[crb]`` - ``/10-stream/CRB/$basearch/os/`` - Deshabilitado * - **MxOS Nativos** - ``[mxos]`` - ``/10-stream/MxOS/$basearch/os/`` - Habilitado Distribución de Paquetes en Repositorios ---------------------------------------- * **Paquetes de Upstream Intactos y Modificados**: Se publican directamente en ``[baseos]`` o ``[appstream]`` según su clasificación original en CentOS Stream. Cuando un paquete es modificado por MxOS, su versión con release ``.mxos.X`` reemplaza a la versión upstream dentro del mismo repositorio. * **Paquetes Nativos de MxOS**: Todo software nuevo desarrollado exclusivamente por la Fundación que no existe en CentOS Stream (ej. ``mxos-release``, ``mxos-repos``, temas visuales, utilerías de soberanía y servicios propios) se aloja de forma exclusiva en el repositorio **``[mxos]``**. Configuración de Paquetes Nativos de MxOS ----------------------------------------- Para los paquetes que residen en el repositorio ``[mxos]``: * Se utiliza versionamiento semántico estricto (*SemVer*): ``Version: 1.0.0``. * El campo release sigue la convención estándar de Fedora: ``Release: 1%{?dist}``. Política y Protocolo Upstream-First =================================== La Fundación MxOS no opera como un silo aislado. La soberanía tecnológica se fortalece colaborando activamente con el ecosistema de código abierto global. Clasificación de Modificaciones ------------------------------- .. list-table:: :header-rows: 1 :widths: 20 40 40 * - Categoría - Descripción - Acción Requerida * - **Categoría A (Mejora General)** - Corrección de fallos (*bugfixes*), soporte de hardware, mejoras de compilación en GCC/Clang o parches de seguridad genéricos. - **Obligatorio Upstream-First**: Se envía un Merge Request al GitLab oficial de CentOS Stream. * - **Categoría A-Temporal (Hotfix de Emergencia)** - Corrección crítica o mitigación de vulnerabilidad (CVE) pendiente de revisión o integración por parte de Red Hat. - **Inclusión Temporal**: Se incorpora de inmediato en ``c10s-mxos`` referenciando el MR upstream y el ticket de Jira en el ``.spec``. Se retira en el siguiente ciclo de rebase tras su aprobación en upstream. * - **Categoría B (Identidad y Soberanía)** - Reemplazo de logotipos, desmarcado (*debranding*), claves GPG de la Fundación, configuración de repositorios propios (``.repo``) o perfiles institucionales. - **Permanencia en Fork**: Se conserva de forma exclusiva en la serie de parches de ``c10s-mxos``. Desacoplamiento Modular y Desmarcado Limpio ------------------------------------------- Para minimizar colisiones en futuros rebases, **se desalientan los parches invasivos en código fuente** para fines de identidad. En su lugar, se utilizan mecanismos nativos de modularidad: * Paquetes de reemplazo mediante proveedores virtuales: ``mxos-logos`` proveyendo ``Provides: system-logos`` para sustituir ``centos-logos`` sin alterar el paquete de Anaconda ni GNOME. * Archivos *drop-in* de configuración en directorios del sistema (``/usr/lib/systemd/system/*.d/``, ``/etc/profile.d/``). * Sobreescritura declarativa de GSettings mediante esquemas en ``/usr/share/glib-2.0/schemas/``. Flujo de Contribución a Upstream y Gating de Red Hat ---------------------------------------------------- Para contribuir una mejora de Categoría A a CentOS Stream, se debe cumplir con los requisitos obligatorios de *gating* de Red Hat: 1. **Apertura de Ticket en Jira**: Crear un reporte detallado en `issues.redhat.com` (proyecto ``RHEL`` o ``CENTOS``). Anotar el identificador asignado (ej. ``RHEL-12345``). 2. **Aislamiento en Rama Limpia**: Crear una rama basada en ``c10s`` prístino: .. code-block:: bash git switch -c contrib/rhel-12345-fix-glibc-buffer c10s 3. **Formato Estricto de Commits**: El commit debe incluir la directiva de Jira y la firma DCO (Developer Certificate of Origin): .. code-block:: bash git commit -s -m "mem: fix buffer overflow in network parser Resolves: RHEL-12345" 4. **Apertura del Merge Request**: Subir la rama a un fork personal en GitLab y abrir un Merge Request hacia ``gitlab.com/redhat/centos-stream/rpms/``. 5. **Protocolo en Caso de Rechazo de Upstream**: Si Red Hat declina incorporar el cambio por motivos comerciales o de alcance interno de RHEL, el equipo técnico de MxOS evalúa el impacto: si es indispensable para la soberanía o funcionalidad de la distribución, el parche se reclasifica formalmente a **Categoría B**, documentando en el archivo ``.spec`` el enlace del MR rechazado y la justificación técnica de divergencia.