Module Context

A module stream can be built in/for several different environments. Each of those environments has its own configuration. We call this configuration a context configuration or a context for short.

Example 1. input modulemd file context configuration of a perl:5.32 module stream
    .
    .
    .
    configurations:
        - context: '866eb18a' (1)
          platform: f34 (2)
          buildrequires: (3)
              perl-bootstrap: ['5.32']
          buildopts: (4)
              rpms:
                  macros: |
                      %_with_perl_enables_groff 1
                      %_without_perl_enables_syslog_test 1
                      %_with_perl_enables_systemtap 1
                    ⋮
        - context: 'ab7e7bfe'
          platform: f35
          buildrequires:
              perl-bootstrap: ['5.32']
          buildopts:
              rpms:
                  macros: |
                      %_with_perl_enables_groff 1
                      %_without_perl_enables_syslog_test 1
                      %_with_perl_enables_systemtap 1
                    ⋮
        - context: '553f8e7a'
          platform: f36
          buildrequires:
              perl-bootstrap: ['5.32']
          buildopts:
              rpms:
                  macros: |
                      %_with_perl_enables_groff 1
                      %_without_perl_enables_syslog_test 1
                      %_with_perl_enables_systemtap 1
                    ⋮
        - context: 'd5eb079e'
          platform: eln
          buildrequires:
              perl-bootstrap: ['5.32']
          buildopts:
              rpms:
                  macros: |
                      %_with_perl_enables_groff 1
                      %_without_perl_enables_syslog_test 1
                      %_with_perl_enables_systemtap 1
                    ⋮
    ⋮
1 name of the context
2 platform describes for which release you are building the context
3 modular dependencies of a context
4 build options which you want to enable in the buildroot of your context

Context name

The name of the context specifically identifies a module stream. The name of the context is specified by the packager of the module stream. The name of the context should be the same during the whole lifetime of a module stream. If you change the name of an existing context it will automatically be considered as a new context within a module stream and there will be no connection between the new and the old context. This means that the upgrade path will end with the old context. The new context will be its own entity independent of the old context.

Static vs Dynamic context

When modularity was released the context configuration was generated automatically by the build system. In the modulemd-packager version 2 the name of a context was not present in the input modulemd YAML file. The context name was a hash which was generated by the build system from the modular buildrequires and requires of a module stream. The context name, modular dependencies and the number of resulting context combinations was known and added to the output modulemd YAML file post build. This had the benefit that the YAML file was concise and short. Also you did not need to know which platforms are available in the build pipeline or the specific names of module streams. The build system did that for you.

But there were several issues with the dynamic context. First the modulemd YAML file did not reflect how a module stream should be built as the context configuration will be known after the build has taken place. Second issue was that you were totally reliant on a build pipeline of a distribution. The whole implementation was tightly coupled with the pipeline which led to an implicit behavior of the technology (i. e. users did not know what was going on if they did not possess intricate knowledge of modularity.) Third issue with dynamic context was that every time you changed your modular requires or buildrequires the name of the context was also changed. This led to a broken upgrade path between the old and new dynamic context names. DNF then could not identify precisely which module stream’s context name is the continuation of the old context.

To fix this issue we introduced the idea of a static context configuration with the modulemd-packager version 3. The static context configuration needs to be precisely specified by the packager for every context. No automation is done by the pipeline. The context name is now an arbitrary string. For more information on the changes please check the modulemd spec files.

Platform

The platform property of the context configuration represents a specific configuration for the Module Build System (MBS). The platform is also known as a virtual module stream. This defines for which release or specific target a module should be built. After the context configurations of a module stream are processed by the build system, the platform module stream can then be found in the dependencies section of the modulemd output file.

Example 2. output modulemd of the perl:5.32:3520210922083143:ab7e7bfe module stream with platform virtual module stream as dependency
---
document: modulemd
version: 2
data:
  name: perl
  stream: "5.32"
  version: 3520210922083143
  context: ab7e7bfe
  static_context: true
  arch: x86_64
  summary: Practical Extraction and Report Language
  description: >
    Perl is a high-level programming language with roots in C, sed, awk and shell
    scripting. Perl is good at handling processes and files, and is especially good
    at handling text. Perl's hallmarks are practicality and efficiency. While it is
    used to do a lot of different things, Perl's most common applications are system
    administration utilities and web programming.
  license:
    module:
    - MIT
    content:
    - (Copyright only) and (Artistic or GPL+)
    - (GPL+ or Artistic) and (GPLv2+ or Artistic) and MIT
    - (GPL+ or Artistic) and Artistic 2.0 and UCD
    ⋮
  xmd: {}
  dependencies:
  - buildrequires:
      perl-bootstrap: [5.32]
      platform: [f35]
    requires:
      platform: [f35]
⋮

Modular dependencies

Each context configuration can have its own modular dependencies. This means that a module stream can depend on other module streams during build-time or run-time. The modular dependencies are defined by the packager in the modulemd-packager version 3.

Modular dependencies are another reason why module binary RPMs files can not be installed without modular metadata and why the modularitylabel flag exists. The information about modular dependencies is not included in the headers of RPM files.

The buildrequires section of a context configuration can specify module streams which need to be enabled in a buildroot to be available for all of the components of a module stream. This can replace non-modular packages with their modular counterparts or introduce new packages which are not provided by the distribution itself.

The same goes for the requires section of the context configuration. But those module streams need to be enabled during runtime so they can satisfy runtime dependencies of your module stream during installation.