Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

How to patch modules in Red Hat Enterprise Linux

August 3, 2021
Petr Pisar
Related topics:
LinuxOpen source
Related products:
Red Hat Enterprise Linux

Share:

    Red Hat Enterprise Linux (RHEL), in version 8, introduced modules as a higher-level concept for packaging software stacks. Modules enable new features such as adding alternative versions of stacks, called streams. That's great, but what if you want to patch a stream? Is it possible? It is. Is it more difficult than patching non-modular software? Slightly. This article shows you how to patch a module stream while avoiding the invisible package problem.

    Patching a module in RHEL

    Red Hat Enterprise Linux is open source. That means you can take the code sources, change them, recompile them, and use or redistribute the modified software. As an example, we can change the HTTPD web server to report a different server name in the HTTP response headers.

    To get started, install an httpd RPM package, start the HTTPD server, and check the server name. I have highlighted the relevant lines from the output in bold:

    # yum install httpd
    Last metadata expiration check: 0:03:40 ago on Fri 16 Jul 2021 12:51:49 PM CEST.
    Dependencies resolved.
    ==========================================================================================
     Package        Arch   Version                                 Repository            Size
    ==========================================================================================
    Installing:
     httpd          x86_64 2.4.37-40.module+el8.5.0+11022+1c90597b rhel-8.5.0-appstream 1.4 M
    Installing dependencies:
     httpd-filesystem
                    noarch 2.4.37-40.module+el8.5.0+11022+1c90597b rhel-8.5.0-appstream  39 k
     httpd-tools    x86_64 2.4.37-40.module+el8.5.0+11022+1c90597b rhel-8.5.0-appstream 106 k
     mod_http2      x86_64 1.15.7-3.module+el8.4.0+8625+d397f3da   pulp-appstream       154 k
     redhat-logos-httpd
                    noarch 84.5-1.el8                              rhel-8.5.0-baseos     29 k
    Enabling module streams:
     httpd                 2.4                                                               
    
    Transaction Summary
    ==========================================================================================
    Install  5 Packages
    
    Total download size: 1.7 M
    Installed size: 4.9 M
    Is this ok [y/N]: y
    […]
    Complete!
    # systemctl start httpd
    $ wget --no-proxy -S -O /dev/null http://localhost/
    --2021-07-16 12:58:54--  http://localhost/
    Resolving localhost (localhost)... ::1, 127.0.0.1
    Connecting to localhost (localhost)|::1|:80... connected.
    HTTP request sent, awaiting response... 
      HTTP/1.1 403 Forbidden
      Date: Fri, 16 Jul 2021 10:58:54 GMT
      Server: Apache/2.4.37 (Red Hat Enterprise Linux)
      Last-Modified: Mon, 12 Jul 2021 19:36:32 GMT
      ETag: "133f-5c6f23d09f000"
      Accept-Ranges: bytes
      Content-Length: 4927
      Keep-Alive: timeout=5, max=100
      Connection: Keep-Alive
      Content-Type: text/html; charset=UTF-8
    2021-07-16 12:58:54 ERROR 403: Forbidden.

    The output shows that the httpd-2.4.37-40.module+el8.5.0+11022+1c90597b RPM package was installed from the httpd:2.4 module stream and that the server reports Apache/2.4.37 (Red Hat Enterprise Linux).

    Our quest is to patch the module to report My Linux instead.

    Step 1: Build a new package

    First, obtain the source RPM package, httpd-2.4.37-40.module+el8.5.0+11022+1c90597b.src.rpm, which corresponds to our example. Unpack it and apply the following patch to a specification file, as explained in the Red Hat documentation:

    --- a/httpd.spec
    +++ b/httpd.spec
    @@ -13,7 +13,7 @@
     Summary: Apache HTTP Server
     Name: httpd
     Version: 2.4.37
    -Release: 40%{?dist}
    +Release: 41%{?dist}
     URL: https://httpd.apache.org/
     Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
     Source2: httpd.logrotate
    @@ -370,7 +370,7 @@ interface for storing and accessing per-user session data.
     %patch211 -p1 -b .CVE-2020-11984
     
     # Patch in the vendor string
    -sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h
    +sed -i '/^#define PLATFORM/s/Unix/My Linux/' os/unix/os.h
     sed -i 's/@RELEASE@/%{release}/' server/core.c
     
     # Prevent use of setcap in "install-suexec-caps" target.
    @@ -870,6 +870,9 @@ rm -rf $RPM_BUILD_ROOT
     %{_rpmconfigdir}/macros.d/macros.httpd
     
     %changelog
    +* Wed Jun 23 2021 Petr Pisar <ppisar@redhat.com> - 2.4.37-41
    +- Modified server platform
    +
     * Fri May 14 2021 Lubos Uhliarik <luhliari@redhat.com> - 2.4.37-40
     - Resolves: #1952557 - mod_proxy_wstunnel.html is a malformed XML
     - Resolves: #1937334 - SSLProtocol with based virtual hosts

    Now, build the modified package with a rpmbuild tool. This results in the following binary packages:

    $ ls
    httpd-2.4.37-41.el8.x86_64.rpm                  mod_ldap-2.4.37-41.el8.x86_64.rpm
    httpd-debuginfo-2.4.37-41.el8.x86_64.rpm        mod_ldap-debuginfo-2.4.37-41.el8.x86_64.rpm
    httpd-debugsource-2.4.37-41.el8.x86_64.rpm      mod_proxy_html-2.4.37-41.el8.x86_64.rpm
    httpd-devel-2.4.37-41.el8.x86_64.rpm            mod_proxy_html-debuginfo-2.4.37-41.el8.x86_64.rpm
    httpd-filesystem-2.4.37-41.el8.noarch.rpm       mod_session-2.4.37-41.el8.x86_64.rpm
    httpd-manual-2.4.37-41.el8.noarch.rpm           mod_session-debuginfo-2.4.37-41.el8.x86_64.rpm
    httpd-tools-2.4.37-41.el8.x86_64.rpm            mod_ssl-2.4.37-41.el8.x86_64.rpm
    httpd-tools-debuginfo-2.4.37-41.el8.x86_64.rpm  mod_ssl-debuginfo-2.4.37-41.el8.x86_64.rpm
    

    Step 2: Create a nonmodular repository

    Next, turn the directory into a YUM repository. Let's say that the repository is located in the working directory /root/repos/myhttpd, so all write operations there must be performed by a superuser:

    # createrepo_c .
    Directory walk started
    Directory walk done - 16 packages
    Temporary output repo path: ./.repodata/
    Preparing sqlite DBs
    Pool started (with 5 workers)
    Pool finished

    Register the repository to YUM under the name myhttpd by creating the /etc/yum.repos.d/devel.repo file with the following content:

    [myhttpd]
    name=myhttpd packages
    baseurl=file:///root/repos/myhttpd/
    enabled=1
    gpgcheck=0

    The invisible package problem

    Next, let's try to update the system to install the patched package:

    # yum upgrade 
    myhttpd packages                                          2.9 MB/s | 3.0 kB     00:00    
    myhttpd packages                                          2.5 MB/s |  25 kB     00:00    
    Dependencies resolved.
    Nothing to do.
    Complete!

    It doesn't work! YUM cannot see your new httpd-2.4.37-41.el8.x86_64 package. Check which packages YUM sees:

    $ repoquery httpd
    Last metadata expiration check: 0:06:19 ago on Fri 16 Jul 2021 01:31:22 PM CEST.
    httpd-0:2.4.37-10.module+el8+2764+7127e69e.x86_64
    httpd-0:2.4.37-11.module+el8.0.0+2969+90015743.x86_64
    httpd-0:2.4.37-12.module+el8.0.0+4096+eb40e6da.x86_64
    httpd-0:2.4.37-16.module+el8.1.0+4134+e6bad0ed.x86_64
    httpd-0:2.4.37-21.module+el8.2.0+5008+cca404a3.x86_64
    httpd-0:2.4.37-30.module+el8.3.0+7001+0766b9e7.x86_64
    httpd-0:2.4.37-39.module+el8.4.0+9658+b87b2deb.x86_64
    httpd-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64

    The new package isn't there, but why? Because packages belonging to an active module stream take precedence over other packages of the same name. This issue is sometimes known as the invisible package problem. We'll explore it in the next section.

    Theory of modules

    To resolve the invisible package problem, you need to understand how modules work.

    Modules are organized into streams (examples include httpd:2.4, perl:5.24, and perl:5.30; also see the yum module list command output). Each stream consists of a series of module versions (such as httpd:2.4:8040020210127115317 and httpd:2.4:8050020210517115912) and each module version lists RPM packages belonging to it (see the Artifacts section in the output from yum module info httpd:2.4).

    A module stream is active if the developer enables it explicitly, or if it is the default and has not been explicitly disabled. All packages belonging to the active stream are visible to YUM. All other packages of the same name, including packages not belonging to any module, are invisible.

    Correspondingly, when a module stream is not active (is disabled or is nondefault), its packages are invisible, while nonmodular packages with the same name are kept visible.

    In a typical Red Hat Enterprise Linux distribution, you can observe changes in visibility as follows:

    1. Enable the perl:5.24 stream by running yum enable perl:5.24.
    2. List the Perl packages in the repository by entering repoquery perl.
    3. Reset the stream through yum module reset perl.
    4. Enable perl:5.30 in a similar way.
    5. List the packages again and view the differences from the previous listing.
    6. Reset the stream to perl:5.26, or whatever the default was on your system.
    7. List the packages again.

    After each change, YUM lists different perl packages.

    Solving the invisible package problem

    In our example, the new httpd-2.4.37-41.el8.x86_64 is currently prevented from being visible. The httpd:2.4 module stream is active and lists an httpd package:

    $ yum module info httpd:2.4
    […]
    Name             : httpd
    Stream           : 2.4 [d][e][a]
    Version          : 8050020210517115912
    Context          : b4937e53
    Architecture     : x86_64
    Profiles         : common [d], devel, minimal
    Default profiles : common
    Repo             : rhel-8.5.0-appstream
    Summary          : Apache HTTP Server
    Description      : Apache httpd is a powerful, efficient, and extensible HTTP server.
    Requires         : platform:[el8]
    Artifacts        : httpd-0:2.4.37-40.module+el8.5.0+11022+1c90597b.src
                     : httpd-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
    […]

    To patch the module, you need to define a new httpd:2.4 module version, list the new httpd-2.4.37-41.el8.x86_64 package there, and add the new module version definition to the repository. After you've done that, YUM will recognize the new package as belonging to the httpd:2.4 stream, and you can continue to the next step.

    Step 3: Make the repository modular

    Now comes a step specific to modules: Changing a nonmodular repository into a modular one. Copy the httpd:2.4:8050020210517115912:b4937e53:x86_64 module definition from the original repository to the modules.yaml file in the directory with the new package:

    # zcat /var/cache/dnf/rhel-8.5.0-appstream-801b3acbf7fb96cf/repodata/7642b0bd7a55141335285144eb537352c85f336de8187ad14aa40b0dbf532463-modules.yaml.gz > modules.yaml

    I took the file from a local YUM cache. But you can also find files with names matching *-modules.yaml* on repository mirrors.

    Now, locate the module build definition inside the file and delete everything else:

    ---
    document: modulemd
    version: 2
    data:
      name: httpd
      stream: "2.4"
      version: 8050020210517115912
      context: b4937e53
      arch: x86_64
      […]
      artifacts:
        rpms:
        - httpd-0:2.4.37-40.module+el8.5.0+11022+1c90597b.src
        - httpd-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - httpd-debuginfo-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - httpd-debugsource-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - httpd-devel-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - httpd-filesystem-0:2.4.37-40.module+el8.5.0+11022+1c90597b.noarch
        - httpd-manual-0:2.4.37-40.module+el8.5.0+11022+1c90597b.noarch
        - httpd-tools-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - httpd-tools-debuginfo-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - mod_http2-0:1.15.7-3.module+el8.4.0+8625+d397f3da.src
        - mod_http2-0:1.15.7-3.module+el8.4.0+8625+d397f3da.x86_64
        - mod_http2-debuginfo-0:1.15.7-3.module+el8.4.0+8625+d397f3da.x86_64
        - mod_http2-debugsource-0:1.15.7-3.module+el8.4.0+8625+d397f3da.x86_64
        - mod_ldap-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - mod_ldap-debuginfo-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - mod_md-1:2.0.8-8.module+el8.3.0+6814+67d1e611.src
        - mod_md-1:2.0.8-8.module+el8.3.0+6814+67d1e611.x86_64
        - mod_md-debuginfo-1:2.0.8-8.module+el8.3.0+6814+67d1e611.x86_64
        - mod_md-debugsource-1:2.0.8-8.module+el8.3.0+6814+67d1e611.x86_64
        - mod_proxy_html-1:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - mod_proxy_html-debuginfo-1:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - mod_session-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - mod_session-debuginfo-0:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - mod_ssl-1:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
        - mod_ssl-debuginfo-1:2.4.37-40.module+el8.5.0+11022+1c90597b.x86_64
    ...

    Update the RPM package list in the /data/artifacts/rpms YAML node to match your new RPM builds:

    # sed -i -e 's/-40\.module+el8\.5\.0+11022+1c90597b\./-41.el8./' modules.yaml
    

    Increment the module build version; for example, from 8050020210517115912 to 8050020210517115913:

    ---
    document: modulemd
    version: 2
    data:
      name: httpd
      stream: "2.4"
      version: 8050020210517115913
      context: b4937e53
      arch: x86_64
    [...]
      artifacts:
        rpms:
        - httpd-0:2.4.37-41.el8.src
        - httpd-0:2.4.37-41.el8.x86_64
        - httpd-debuginfo-0:2.4.37-41.el8.x86_64
        - httpd-debugsource-0:2.4.37-41.el8.x86_64
        - httpd-devel-0:2.4.37-41.el8.x86_64
        - httpd-filesystem-0:2.4.37-41.el8.noarch
        - httpd-manual-0:2.4.37-41.el8.noarch
        - httpd-tools-0:2.4.37-41.el8.x86_64
        - httpd-tools-debuginfo-0:2.4.37-41.el8.x86_64
        - mod_http2-0:1.15.7-3.module+el8.4.0+8625+d397f3da.src
        - mod_http2-0:1.15.7-3.module+el8.4.0+8625+d397f3da.x86_64
        - mod_http2-debuginfo-0:1.15.7-3.module+el8.4.0+8625+d397f3da.x86_64
        - mod_http2-debugsource-0:1.15.7-3.module+el8.4.0+8625+d397f3da.x86_64
        - mod_ldap-0:2.4.37-41.el8.x86_64
        - mod_ldap-debuginfo-0:2.4.37-41.el8.x86_64
        - mod_md-1:2.0.8-8.module+el8.3.0+6814+67d1e611.src
        - mod_md-1:2.0.8-8.module+el8.3.0+6814+67d1e611.x86_64
        - mod_md-debuginfo-1:2.0.8-8.module+el8.3.0+6814+67d1e611.x86_64
        - mod_md-debugsource-1:2.0.8-8.module+el8.3.0+6814+67d1e611.x86_64
        - mod_proxy_html-1:2.4.37-41.el8.x86_64
        - mod_proxy_html-debuginfo-1:2.4.37-41.el8.x86_64
        - mod_session-0:2.4.37-41.el8.x86_64
        - mod_session-debuginfo-0:2.4.37-41.el8.x86_64
        - mod_ssl-1:2.4.37-41.el8.x86_64
        - mod_ssl-debuginfo-1:2.4.37-41.el8.x86_64
    ...

    If the module lists other packages, you can delete them.

    Finally, regenerate the repository metadata so that it picks up the new module definition from the modules.yaml file in the local directory:

    # createrepo_c .
    Directory walk started
    Directory walk done - 16 packages
    Temporary output repo path: ./.repodata/
    Preparing sqlite DBs
    Pool started (with 5 workers)
    Pool finished

    You can check that the module definition was imported under the known *-module.yaml.* filename:

    $ ls repodata/
    733d406732770bce66f8b790a92e933559903e7c3360a1bada3de366c130fc7c-other.sqlite.bz2
    a99faa19e499bec174b3c3c682d150715fc66015da00511aa9f78691a3670708-other.xml.gz
    aaffc762d36b0389d602c9c37db74242cae8d37ea89d3aa3e4ca2b4cc4099b0d-primary.sqlite.bz2
    d10db6feb91cc5f185218367162cdbab49780343a82efe23e6d8c0e14f4effcb-filelists.xml.gz
    e51d17bf9000bd130f99edd8ff2923977c8c74a0b5829116e36299fb46a440e9-primary.xml.gz
    f98a57f75a9fb84f1ce0313ee22e435eebb6134a28f7568ad8b8b4e14be38285-filelists.sqlite.bz2
    ff2b17e5a515266023ccc983a8cf12401ae4d2c2049683e76ad09f6b5cea48ba-modules.yaml.gz
    repomd.xml

    Now you can delete the ./modules.yaml file. You don't need it anymore. The repository is now modular.

    Note: Importing modular metadata from a modules.yaml file is a new feature of createrepo-c-0.16.2. If you have an older version, you need to use the modifyrepo_c tool after running createrepo_c.

    Step 4: Install the package from the modular repository

    We are nearly done. Try updating the system again:

    # yum upgrade
    myhttpd packages                                          1.4 MB/s |  26 kB     00:00    
    Dependencies resolved.
    ==========================================================================================
     Package                   Architecture    Version                 Repository        Size
    ==========================================================================================
    Upgrading:
     httpd                     x86_64          2.4.37-41.el8           myhttpd          1.4 M
     httpd-filesystem          noarch          2.4.37-41.el8           myhttpd           37 k
     httpd-tools               x86_64          2.4.37-41.el8           myhttpd          104 k
    
    Transaction Summary
    ==========================================================================================
    Upgrade  3 Packages
    
    Total size: 1.5 M
    Is this ok [y/N]: y

    And that's it. It works. Hooray!

    Note: If YUM did not refresh the repository, it might be because you performed the steps too quickly. Clean up the cache with rm -rf /var/cache/dnf/myhttpd* and try again.

    Step 5: Verify the patched package

    Finally, you can check the Server header that the server returns:

    $ wget --no-proxy -S -O /dev/null http://localhost/
    --2021-07-16 15:15:56--  http://localhost/
    Resolving localhost (localhost)... ::1, 127.0.0.1
    Connecting to localhost (localhost)|::1|:80... connected.
    HTTP request sent, awaiting response...
      HTTP/1.1 403 Forbidden
      Date: Fri, 16 Jul 2021 13:15:56 GMT
      Server: Apache/2.4.37 (My Linux)
      Last-Modified: Mon, 12 Jul 2021 19:36:32 GMT
      ETag: "133f-5c6f23d09f000"
      Accept-Ranges: bytes
      Content-Length: 4927
      Keep-Alive: timeout=5, max=100
      Connection: Keep-Alive
      Content-Type: text/html; charset=UTF-8
    2021-07-16 15:15:56 ERROR 403: Forbidden.

    The line Server: Apache/2.4.37 (My Linux) shows that the server is running your patched module.

    Versioning patched modules and packages

    What version should you use for the patched modules? Currently, it doesn't matter much because YUM merges all module versions of a single stream together. But I recommend incrementing the last digit, as we did in our example. The module version is basically a timestamp. Incrementing the last digit means moving a second ahead. It's improbable that Red Hat would release two module versions with one-second delays. Thus, when Red Hat releases a new version, it's recognized as more recent than your version, and replaces your version.

    The version number could matter if you want to change other modular metadata, such as modular dependencies. Then the highest module version wins.

    What about the RPM version string? Inside a stream, a standard RPM epoch-version-release comparison is used to update a modular package to another modular package. If Red Hat released a new module update, the httpd package would be called something like httpd-0:2.4.37-41.module+el8.5.0+11022+1c90597b. That's fine because that would be a higher RPM version string than yours and the new update would win:

    $ rpmdev-vercmp 0:2.4.37-41.el8 0:2.4.37-41.module+el8.5.0+11022+1c90597b
    0:2.4.37-41.el8 < 0:2.4.37-41.module+el8.5.0+11022+1c90597b

    If you want your RPM package to win over future Red Hat updates, choose a reasonably high release number. The process is the same as what would you do in a nonmodular scenario.

    Special situations and warnings

    Sometimes there are multiple modules with the same version but a different context value. What does the context mean? Which context should you use? Can you change it?

    The context distinguishes modules that were built from the same sources but for different environments. For instance, the perl-DBI:1.641 modules found in Red Hat Enterprise Linux 8.3 are built three times for three different Perl versions, so there are three different contexts of them. When you patch a module, don't change the context. Copying the old value is the safest approach.

    I'll conclude by listing a few shortcuts that are not recommended for patching modules:

    • Installing from a local file. You can use yum upgrade ./httpd-*.rpm, but the results won't last long. A package installed like that won't be recognized as belonging to any module and could be expelled from future YUM transactions, resulting in a dependency conflict on an RPM level. Also, having a package outside a repository makes it difficult to deploy to multiple machines or reinstall the package.
    • Adding a module_hotfixes=true statement to a YUM configuration file for a nonmodular repository. While this technique works as a last resort for overriding any modular content, the hammer is too big for the nail. It does not play nicely when multiple module streams provide the same package, or if all the streams are disabled.
    • Omitting the zero epoch from an artifacts list in the module definition. Don't do it. YUM won't understand it. If your RPM package has no epoch number, write 0. You can use rpm -q --qf '%{NAME}-%{EPOCHNUM}:%{VERSION}-%{RELEASE}.%{ARCH}\n' -p httpd-2.4.37-41.el8.x86_64.rpm to obtain the right value: httpd-0:2.4.37-41.el8.x86_64.

    References

    I recommend reading the module definition format.

    Last updated: October 8, 2024

    Related Posts

    • Modular Perl in Red Hat Enterprise Linux 8

    • Red Hat Enterprise Linux 8 developer cheat sheet

    • Introducing Application Streams in RHEL 8

    Recent Posts

    • How Kafka improves agentic AI

    • How to use service mesh to improve AI model security

    • How to run AI models in cloud development environments

    • How Trilio secures OpenShift virtual machines and containers

    • How to implement observability with Node.js and Llama Stack

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue