Definir módulos en modulemd

Simplemente pone, modulemd es un archivo que define que paquetes se crean para que versiones. Incluye un resumen y una descripción, una lista de los paquetes RPM fuente, información de compilación, es decir, orden de compilación y macros e información de utilización, esto es perfiles de instalación y licencias.

Un ejemplo típico de modulemd

Un archivo típico modulemd se ve similar a los siguientes ejemplos. Continúe leyendo para obtener más información sobre cada parte del archivo modulemd.

No dude en copiar/pegar este ejemplo cuando cree su nuevo módulo.

document: modulemd-packager
version: 3
data:
    # === Information about this module ==================================
    # (Can be copied from the main RPM package, but doesn't need to be)
    summary: An example module
    description: >-
        A module for the demonstration of the metadata format. Also,
        it can span multiple lines.

    # === License of this modulemd file ==================================
    license:
      - MIT
    # === Module context configurations ===========================================
    # (For which Fedora releases to build?)
    configurations:
        # context:
        # A string of up to ten [a-zA-Z0-9] characters representing a
        # a build and runtime configuration for this stream. This string is
        # arbitrary but must be unique in this module stream.
        # Type: MANDATORY
      - context: CTX1
          # platform:
          # Defines the distribution and release to build on and run against.
          # Type: MANDATORY
        platform: f32
          # buildrequires:
          # A dictionary of the build-time dependencies on other module streams.
          # Each configuration may depend on a single stream of a dependency.
          # The dictionary key is the name of the module and the dictionary value
          # is a single-element list containing the name of the stream.
          #
          # Type: Optional
        buildrequires:
          appframework: [v1]
          # requires:
          # A dictionary of the run-time dependencies on other module streams.
          # Each configuration may depend on a single stream of a dependency.
          # The dictionary key is the name of the module and the dictionary value
          # is a single-element list containing the name of the stream.
          #
          # Type: Optional
        requires:
          appframework: [v1]
          # buildopts:
          # Component build options
          # Additional per component type module-wide build options.
          #
          # IMPORTANT: Due to limitations in the modulemd-stream v2 format, the
          # buildopts from the first configuration in the list will apply to
          # ALL configurations when building for modulemd-stream v2. They will
          # apply separately when building for module-stream v3.
          #
          # Type: OPTIONAL
        buildopts:
            # rpms:
            # RPM-specific build options
            #
            # Type: OPTIONAL
          rpms:
                # macros:
                # Additional macros that should be defined in the
                # RPM buildroot, appended to the default set.  Care should be
                # taken so that the newlines are preserved.  Literal style
                # block is recommended, with or without the trailing newline.
                #
                # Type: OPTIONAL
            macros: |
              %demomacro 1
              %demomacro2 %{demomacro}23

            # whitelist:
            # Explicit list of package build names this module will produce.
            # By default the build system only allows components listed under
            # data.components.rpms to be built as part of this module.
            # In case the expected RPM build names do not match the component
            # names, the list can be defined here.
            # This list overrides rather then just extends the default.
            # List of package build names without versions.
            #
            # Type: OPTIONAL
            whitelist:
              - fooscl-1-bar
              - fooscl-1-baz
              - xxx
              - xyz
            # arches:
            # Instructs the build system to only build the
            # module on this specific set of architectures.
            # Includes specific hardware architectures, not families.
            # See the data.arch field in the modulemd-stream spec for details.
            # Defaults to all available arches.
            #
            # Type: OPTIONAL
            arches: [i686, x86_64]

        # Alternate example with no dependencies
      - context: CTX2
        platform: f33
    # === Module API (optional, but encouraged) ==========================
    # (Which packages are API-stable?)
    api:
        rpms:
            - package-one        # <- Binary RPM package name
            - package-one-extras # <- Binary RPM package name
            - package-one-cli    # <- Binary RPM package name
            - package-one-devel  # <- Binary RPM package name
            - package-two        # <- Binary RPM package name

    # === Package filtering ==============================================
    # (Which packages should not be included into the resulting module)
    filter:
        rpms:
            - subpackage-one     # <- Binary RPM package name

    # === Installation profiles (optional, but encouraged) ===============
    # (Helping users with installation by providing predefined groups)
    profiles:
        default:  # <- Name of the profile
            description: A standard installation.
            rpms:
                - package-one         # <- Binary RPM package name
                - package-one-extras  # <- Binary RPM package name
                - package-two         # <- Binary RPM package name
        cli:      # <- Name of the profile
            description: A command-line client.
            rpms:
                - package-one-cli     # <- Binary RPM package name

    # === Packages in this module ========================================
    # (Referenced by their dist-git repo name + branch name)
    components:
        rpms:
            first-package:  # <- Source RPM package name
                ref: 3.0    # <- Branch name in dist-git
                rationale: Provides the core functionality.
            second-package: # <- Source RPM package name
                ref: latest # <- Branch name in dist-git
                rationale: Web UI for the first-package.

Definiciones comunes de modulemd

Estas son las partes comunes de un archivo modulemd, usadas en el ejemplo anterior. Las definiciones avanzadas, incluyendo un complejo ejemplo de Module Stream Expansion (Módulo de Expansión de Flujo) (MSE), están hacia el final de esta página.

Cabecera del documento

Cada modulemd empieza con estas tres líneas:

document: modulemd-packager
version: 3
data:
    ... (1)
1 Todas las siguientes definiciones van aquí, bajo data.

Información sobre este módulo

Les dice a los usuarios lo que este módulo representa escribiendo un resumen y una descripción.

    summary: An example module
    description: >-  (1)
        A module for the demonstration of the metadata format. Also,
        it can span multiple lines.
1 >- significa nueva línea en YAML. ¡Útil para los bloques de texto más largos, como la descripción!

Licencia para este archivo modulemd

Esta es una licencia de este mismo archivo modulemd y no es necesario modificarlo. El sistema de compilación añade licencias de todos los paquetes a esta lista automáticamente.

    license:
      - MIT  (1)
1 Una licencia para este archivo modulemd. Contenido de Fedora, como archivos SPEC o parches no incluidos por el desarrollador, usa de modo predeterminado la licencia MIT, a menos que el empaquetador del componente declare lo contrario.

Configuraciones de contexto del módulo

Cada configuración de contexto describe como un flujo de módulo y sus componentes se deberían compilar y ejecutar. Un ejemplo de contexto sencillo:

    configurations:
      - context: CTX1   (1)
        platform: f32   (2)
        buildrequires:
          appframework: [v1]    (3)
        requires:
          appframework: [v1]    (4)
1 Un nombre de contexto para la sencilla configuración.
2 Se creará un identificador de una versión importante de una distribución en este contexto y se ejecutará.
3 Flujos de módulos para habilitar al construir este contexto (dependencias modulares en tiempo de compilación).
4 Flujos de módulos para habilitar al instalar este contexto (dependencias modulares en tiempo de ejecución).

El campo context es obligatorio y debe ser único dentro de un único flujo. El valor es una cadena arbitraria con una longitud y un alfabeto limitados. El valor de contexto se usa por DNF para establecer una ruta de actualización entre múltiples versiones de módulos y contextos. Por lo tanto, una vez establecido el valor, no debería cambiar.

El identificador de la plataforma es obligatorio y coincide con una versión Fedora. Por ejemplo`f32` significa Fedora 32. Rawhide usa también un valor numérico. Técnicamente, es un hilo del módulo platform.

Las dependencias modulares en tiempo de ejecución pueden diferir de las de tiempo de compilación. Puede haber varios módulos enumerados, pero siempre exactamente una secuencia. Por ejemplo, appframework: [v1] significa el flujo de módulo appframework:v1.

A continuación se muestra un complejo ejemplo con múltiples contextos:

    configurations:
      - context: CTX1
        platform: f32
        buildrequires:
          appframework: [v1]
        requires:
          appframework: [v1]
          frameworkext: [v3]
      - context: CTX2
        platform: f33
        buildrequires:
          appframework: [v1]
        requires:
          appframework: [v1]
          frameworkext: [v3]
      - context: CTX3
        platform: f33
        buildrequires:
          appframework: [v2]
        requires:
          appframework: [v2]

Este ejemplo producirá un módulo compilado para Fedora 32 y dos compilados para Fedora 33. El módulo Fedora 32 dependerá de appframework:v1 y frameworkext:v3, mientras que el módulo Fedora 33 soportará los flujos appframework:v1` y appframework:v2. El contexto CTX3 no dependen de frameworkext:v3 porque se fusionó con appframework:v2.

Perfiles de instalación (opcional, pero recomendado)

Para ayudar a los usuarios a instalar su módulo, defina perfiles de instalación. Estos perfiles representan un caso de uso específico para su módulo. La mayoría de los módulos tienen al menos un perfil predeterminado. Pero puede especificar más. Por ejemplo, un módulo de base de datos puede tener un perfil servidor y otro cliente.

    profiles:
        default:  (1)
            description: A standard installation.  (2)
            rpms:
                - package-one         (3)
                - package-one-extras  (3)
                - package-two         (3)
        cli:
            description: A command-line client.
            rpms:
                - package-one-cli
        ...  (4)
1 Nombre del perfil.
2 Un rápido resumen del perfil.
3 Paquetes binarios a instalar con este perfil.
4 Enumere tanto perfiles como necesite.

Módulo API (Interfaz de Aplicación de Programación) (opcional, pero recomendado)

Enumere todos los paquetes RPM binarios en su módulo que considere la principal característica estable del módulo. Otros paquetes (no listados) deben considerarse no compatibles o un detalle de implementación.

    api:
        rpms:
            - package-one
            - package-one-extras
            - package-one-cli
            - package-one-devel
            - package-two

Paquetes en este módulo

Enumere todos los paquetes SRPM fuente que este módulo debería incluir, haga la referencia por su nombre de repositorio dist-git repo name + el nombre de rama.

    components:
        rpms:
            first-package:  (1)
                rationale: Provides the core functionality.  (2)
                ref: 3.0  (3)
            second-package:
                rationale: Web UI for the first-package.
                ref: latest
            ...  (4)
1 Name of the package — maps to a DistGit repository name.
2 The reason why is this package here. Mostly for humans.
3 DistGit branch, tag, or a commit — so the right version of the package gets included.
4 List as many packages as you need.

Advanced definitions

References to the upstream (optional)

You can also provide references to the upstream community, documentation, or to an issue tracker.

    references:
        community: http://www.example.com/  (1)
        documentation: http://www.example.com/  (2)
        tracker: http://www.example.com/  (3)
1 Upstream community website, if it exists.
2 Upstream documentation, if it exists.
3 Upstream bug tracker, if it exists.

Building in a specific order (optional)

Packages are built in batches. By default, all packages are part of a single group, and therefore built concurrently.

To build packages in a specific order, assign them to multiple build groups. Build groups are identified by an integer. Groups with lower number are built first. Negative values are allowed, 0 is the implicit default value.

In this specific example, first-package gets built first, and second-package gets built second.

    components:
        rpms:
            first-package:
                rationale: Provides the core functionality.
                ref: 3.0
                buildorder: 0  (1)
            second-package:
                rationale: Web UI for the first-package.
                ref: latest
                buildorder: 10  (1)
1 A number of the build group.

For even more complex scenarios, please study the modulemd-packager specification.

RPM macros (optional)

RPM packages while being built as part of a module have the following RPM macros available:

%dist .scrmod+f37+14301+76d220e4    (1)
%modularitylabel perl-Module-Install:master:3720220414092112:dd3c6e0e (2)
%_module_build 1    (3)
%_module_name perl-Module-Install   (4)
%_module_stream master  (5)
%_module_version 3720220414092112   (6)
%_module_context dd3c6e0e   (7)
1 A %dist macro of a unique value used in Release RPM specification tags. <.> An RPM tag stored into binary RPM packages. DNF uses it to distinguish modular packages from nonmodular ones. <.> A macro denoting that a modular package is being built. <.> A name of the module being built. <.> A stream of the module being built. <.> A version of the module being built. <.> A context of the module being built.

You can use these macros in RPM specification files of your RPM components to modify building of the packages.

If you need additional RPM macros, you can define them in a buildopts section of your modulemd file:

    buildopts:
        rpms:
            macros: |
                %perl_bootstrap 1

This section belongs into an item of configurations list in case of v3 modulemd format. In case of v2 format it belongs directly into data section.

Filtered Packages (optional, defaults to no filters)

The build process of a RPM packages can result in a subpackages which complement the build of the package (docs, additional build requires etc.). One source RPM package might produce multiple binary RPM packages. Those subpackages are not always desired to be shipped with the Module. Modules enable you to filter out those undesirable packages with the filter build option. After the build is finished the filtered packages will be not included in the artifacts property in the result modulemd yaml file. The artifacts property is added by the build system post build. For an example please refer to the modulemd spec files.

Filtered RPMs are still available to use as build dependencies in subsequent stages of the module build, but are not included in the composed repository for users.

    filter:
        rpms:
            - first-package-debuginfo
            - second-package-nope

Demodularized packages (optional, defaults to none)

If you decide to remove a binary package from your module stream, you will probably stop building it, or you will filter it out with a filter option. But that’s not enough if you want to move the package back to nonmodular packages: Because the package remains listed among artifacts in the previous version of the stream and a package manager could see both the updated and the historical version. (The previous version can be available in GA and updates repositories, while your updated module will first appear in an updates-testing repository.)

To return the package back to nonmodular package set, you need to write it on a list of demodularized packages. A package manager checks the demodularized list of the very latest version of the module stream over all repositories and if it only sees a package name there, it will stop hiding the same-named nonmodular packages while the stream is enabled.

The list of demodularized packages is defined in demodularized field:

    demodularized:
        rpms:
            - first-removed-package
            - second-removed-package

With this explicit mechanism, called demodularization, a package can be demoted from a module. If you ever revert your decision and make the package modular again, the only thing necessary is remove it from the demodularized list.

Creating build-only components (optional)

In addition to filtering subpackages, it’s possible to filter out all of the artifacts produced by a component in a module. This is useful in cases where your module’s primary packages have a build-time dependency that you do not want to ship. An example of such a case would be if you need to build with a specially-patched documentation-generator that would conflict with the version used as the default in Fedora.

    components:
        rpms:
            customdocgen:
                rationale: A patched version of docgen that enables an experimental feature.
                ref: experimental
                buildorder: 0
                buildonly: 1
            myapp:
                rationale: My application
                ref: latest
                buildorder: 10

In this example, customdocgen would be built first and made available in the buildroot for myapp to use during its build. Once the module build is finished and it is composed into a DNF repository, only the unfiltered artifacts from myapp will be available. All of the customdocgen artifacts will be automatically added to the data.filters.rpms section of the module metadata.

A minimal modulemd

An absolute minimum

This module includes two source RPM packages built for the Fedora 35 releases.

document: modulemd-packager
version: 3
data:
    summary: An example module
    description: >-
        A module for the demonstration of the metadata format.
    license:
        - MIT
    configurations:
      - context: CTX1
        platform: f35
    components:
        rpms:
            first-package:
                rationale: Provides the core functionality.
                ref: 3.0
            second-package:
                rationale: Web UI for the first-package.
                ref: latest

This module includes two source RPM packages built for the Fedora 35 releas. It makes clear which packages are considered the API, and helps users with installation thanks to the profiles.

document: modulemd-packager
version: 3
data:
    summary: An example module
    description: >-
        A module for the demonstration of the metadata format.
    license:
        - MIT
    configurations:
      - context: CTX1
        platform: f35
    api:
        rpms:
            - package-one
            - package-one-extras
            - package-one-cli
            - package-one-devel
            - package-two
    profiles:
        default:
            description: A standard installation.
            rpms:
                - package-one
                - package-one-extras
                - package-two
        cli:
            description: A command-line client.
            rpms:
                - package-one-cli
    components:
        rpms:
            first-package:
                rationale: Provides the core functionality.
                ref: 3.0
            second-package:
                rationale: Web UI for the first-package.
                ref: latest