Perl in RHEL 8

Red Hat Enterprise Linux in version 8 (RHEL 8) comes with modules, a packaging concept that allows system administrators to select the desired software version from multiple packaged versions. This article shows you how to manage Perl as a module, as well as how to manage the CPAN modules provided by Perl, in RHEL 8.

Note: The term module in this article is used for both RHEL modules and Perl modules. I will refer to the "modularity module" for the Red Hat Enterprise Linux type and the "CPAN module" for the Perl type.

Installing Perl from the default stream

Start by installing Perl in a simple manner:

# yum --allowerasing install perl
Last metadata expiration check: 1:37:36 ago on Tue 07 May 2019 04:18:01 PM CEST.
Dependencies resolved.
==========================================================================================
 Package                       Arch    Version                Repository             Size
==========================================================================================
Installing:
 perl                          x86_64  4:5.26.3-416.el8       rhel-8.0.z-appstream   72 k
Installing dependencies:
[…]
Transaction Summary
==========================================================================================
Install  147 Packages

Total download size: 21 M
Installed size: 59 M
Is this ok [y/N]: y
[…]
  perl-threads-shared-1.58-2.el8.x86_64

Complete!

Next, check which version of Perl you have:

$ perl -V:version
version='5.26.3';

The output shows that you have Perl 5.26.3. This is the default version supported for the next 10 years. If you are fine with that, then you don't need to worry about modules. But what if you want to try a different version? There are various reasons for enabling another version of your software. Most often, you might have an existing application that depends on a combination of modules, and some don't work with updated versions of Perl. Not all modules are compatible with other modules.

For the remainder of this article, we will look at how to install Perl modules using streams.

Exploring streams in RHEL 8

Find out what Perl modules are available using the yum module list command:

# yum module list
Last metadata expiration check: 1:45:10 ago on Tue 07 May 2019 04:18:01 PM CEST.
[…]
Name                 Stream           Profiles     Summary
[…]
parfait              0.5              common       Parfait Module
perl                 5.24             common [d],  Practical Extraction and Report Languag
                                      minimal      e
perl                 5.26 [d]         common [d],  Practical Extraction and Report Languag
                                      minimal      e
perl-App-cpanminus   1.7044 [d]       common [d]   Get, unpack, build and install CPAN mod
                                                   ules
perl-DBD-MySQL       4.046 [d]        common [d]   A MySQL interface for Perl
perl-DBD-Pg          3.7 [d]          common [d]   A PostgreSQL interface for Perl
perl-DBD-SQLite      1.58 [d]         common [d]   SQLite DBI driver
perl-DBI             1.641 [d]        common [d]   A database access API for Perl
perl-FCGI            0.78 [d]         common [d]   FastCGI Perl bindings
perl-YAML            1.24 [d]         common [d]   Perl parser for YAML
php                  7.2 [d]          common [d],  PHP scripting language
                                      devel, minim
                                      al
[…]

The output shows that a module is available for both Perl 5.24 and Perl 5.26. These are called streams in the modularity world, and they denote independent variants of the same software stack, usually different versions. The [d] flag marks a default stream, which is the one installed if you do not explicitly enable a different stream. So the previous output explains why yum installed Perl 5.26.3 and not one of the 5.24 micro versions.

In general, any module can have multiple streams. At most, one stream can be the default, and another stream can be enabled. An enabled stream takes precedence over a default one. If there is no enabled or a default stream, the content of the module is unavailable.

Now, let's make a few assumptions:

  • You have an old application that you are migrating from RHEL 7.
  • The application depends on the rh-perl524 Red Hat Software Collections environment.
  • You want to give it a try on RHEL 8.

Based on these assumptions, you will want to install Perl 5.24 on RHEL 8.

Enabling a stream

First, switch the Perl module to the 5.24 stream:

# yum module enable perl:5.24
Last metadata expiration check: 2:03:16 ago on Tue 07 May 2019 04:18:01 PM CEST.
Problems in request:
Modular dependency problems with Defaults:

 Problem 1: conflicting requests
  - module freeradius:3.0:8000020190425181943:75ec4169-0.x86_64 requires module(perl:5.26), but none of the providers can be installed
  - module perl:5.26:820181219174508:9edba152-0.x86_64 conflicts with module(perl:5.24) provided by perl:5.24:820190207164249:ee766497-0.x86_64
  - module perl:5.24:820190207164249:ee766497-0.x86_64 conflicts with module(perl:5.26) provided by perl:5.26:820181219174508:9edba152-0.x86_64
 Problem 2: conflicting requests
  - module freeradius:3.0:820190131191847:fbe42456-0.x86_64 requires module(perl:5.26), but none of the providers can be installed
  - module perl:5.26:820181219174508:9edba152-0.x86_64 conflicts with module(perl:5.24) provided by perl:5.24:820190207164249:ee766497-0.x86_64
  - module perl:5.24:820190207164249:ee766497-0.x86_64 conflicts with module(perl:5.26) provided by perl:5.26:820181219174508:9edba152-0.x86_64
Dependencies resolved.
==========================================================================================
 Package              Arch                Version              Repository            Size
==========================================================================================
Enabling module streams:
 perl                                     5.24

Transaction Summary
==========================================================================================

Is this ok [y/N]: y
Complete!

Switching module streams does not alter installed packages (see 'module enable' in dnf(8)
for details)

We get a warning that the freeradius:3.0 stream is not compatible with perl:5.24. That's because FreeRADIUS was built for Perl 5.26 only. Let's assume that your application fortunately doesn't require FreeRADIUS.

Next, the command displays a confirmation that it is enabling the Perl 5.24 stream. And, finally, there is another warning about installed packages. The last warning means that the system might still contain RPM packages from the Perl 5.26 stream, and you need to explicitly sort them out.

If you happen to receive the following error message instead, you have already enabled the perl:5.26 stream and yum does not allow you to switch a module away from an already enabled stream for safety reasons:

The operation would result in switching of module 'perl' stream '5.26' to stream '5.24'
Error: It is not possible to switch enabled streams of a module unless explicitly enabled via configuration option module_stream_switch.
It is recommended to rather remove all installed content from the module, and reset the module using 'yum module reset <module_name>' command. After you reset the module, you can install the other stream.

To recover from the safety block, follow the recommendation in the message and reset the perl module with the yum module reset perl command. Then you will be able to enable the perl:5.24 stream.

Changing modules and changing packages are two separate phases. You can fix it by synchronizing the distribution content like this:

# yum --allowerasing distrosync
Last metadata expiration check: 0:00:56 ago on Tue 07 May 2019 06:33:36 PM CEST.
Modular dependency problems:

 Problem 1: module freeradius:3.0:8000020190425181943:75ec4169-0.x86_64 requires module(perl:5.26), but none of the providers can be installed
  - module perl:5.26:820181219174508:9edba152-0.x86_64 conflicts with module(perl:5.24) provided by perl:5.24:820190207164249:ee766497-0.x86_64
  - module perl:5.24:820190207164249:ee766497-0.x86_64 conflicts with module(perl:5.26) provided by perl:5.26:820181219174508:9edba152-0.x86_64
  - conflicting requests
 Problem 2: module freeradius:3.0:820190131191847:fbe42456-0.x86_64 requires module(perl:5.26), but none of the providers can be installed
  - module perl:5.26:820181219174508:9edba152-0.x86_64 conflicts with module(perl:5.24) provided by perl:5.24:820190207164249:ee766497-0.x86_64
  - module perl:5.24:820190207164249:ee766497-0.x86_64 conflicts with module(perl:5.26) provided by perl:5.26:820181219174508:9edba152-0.x86_64
  - conflicting requests
Dependencies resolved.
==========================================================================================
 Package           Arch   Version                              Repository            Size
==========================================================================================
[…]
Downgrading:
 perl              x86_64 4:5.24.4-403.module+el8+2770+c759b41a
                                                               rhel-8.0.z-appstream 6.1 M
[…]
Transaction Summary
==========================================================================================
Upgrade    69 Packages
Downgrade  66 Packages

Total download size: 20 M
Is this ok [y/N]: y
[…]
Complete!

Check your version with the perl command again:

$ perl -V:version
version='5.24.4';

Great! Installing the non-default module worked. The desired version of Perl is installed to a standard path (/usr/bin/perl) and is therefore invoked with the perl command. No scl enable incantation is needed, in contrast to a requirement associated with the old software collections.

Note: A future yum update will clean up the unnecessary warning about FreeRADIUS. I'll show some Perl-ish modules that are compatible with any Perl stream later in this article.

Dependent modules

Let's suppose that the old application mentioned earlier uses the DBD::SQLite Perl CPAN module. So, let's install it. Yum can search for a CPAN module within a modularity module, so give the following a try:

# yum --allowerasing install 'perl(DBD::SQLite)'
[…]
Dependencies resolved.
==========================================================================================
 Package          Arch    Version                             Repository             Size
==========================================================================================
Installing:
 perl-DBD-SQLite  x86_64  1.58-1.module+el8+2519+e351b2a7     rhel-8.0.z-appstream  186 k
Installing dependencies:
 perl-DBI         x86_64  1.641-2.module+el8+2701+78cee6b5    rhel-8.0.z-appstream  739 k
Enabling module streams:
 perl-DBD-SQLite          1.58
 perl-DBI                 1.641

Transaction Summary
==========================================================================================
Install  2 Packages

Total download size: 924 k
Installed size: 2.3 M
Is this ok [y/N]: y
[…]
Installed:
  perl-DBD-SQLite-1.58-1.module+el8+2519+e351b2a7.x86_64
  perl-DBI-1.641-2.module+el8+2701+78cee6b5.x86_64

Complete!

The DBD::SQLite CPAN module was found in the perl-DBD-SQLite RPM package that's part of perl-DBD-SQLite:1.58 modularity module. It apparently requires some dependencies from the perl-DBI:1.641 modularity module too. After asking for confirmation, yum enabled the necessary streams and installed the packages.

Before playing with DBD::SQLite under Perl 5.24, take a look at the listing of the modularity modules and compare it with what we got the first time:

# yum module list
[…]
parfait              0.5              common       Parfait Module
perl                 5.24 [e]         common [d],  Practical Extraction and Report Languag
                                      minimal      e
perl                 5.26 [d]         common [d],  Practical Extraction and Report Languag
                                      minimal      e
perl-App-cpanminus   1.7044 [d]       common [d]   Get, unpack, build and install CPAN mod
                                                   ules
perl-DBD-MySQL       4.046 [d]        common [d]   A MySQL interface for Perl
perl-DBD-Pg          3.7 [d]          common [d]   A PostgreSQL interface for Perl
perl-DBD-SQLite      1.58 [d][e]      common [d]   SQLite DBI driver
perl-DBI             1.641 [d][e]     common [d]   A database access API for Perl
perl-FCGI            0.78 [d]         common [d]   FastCGI Perl bindings
perl-YAML            1.24 [d]         common [d]   Perl parser for YAML
php                  7.2 [d]          common [d],  PHP scripting language
                                      devel, minim
                                      al
[…]

Notice that perl:5.24 is enabled ([e]) and thus takes precedence over perl:5.26, which would otherwise be a default stream ([d]). Other enabled modularity modules are perl-DBD-SQLite:1.58 and perl-DBI:1.641. Those were enabled when you installed DBD::SQLite. These two modules have no other streams.

Note: If you need for some reason to disable a stream, even a default one, use the yum module disable <module>:<stream> command.

Back to some productive work. You are ready to test the DBD::SQLite CPAN module. Let's create a test database containing a foo table with one textual column called bar, and store a row containing the string Hello there:

$ perl -MDBI -e '$dbh=DBI->connect(q{dbi:SQLite:dbname=test});
    $dbh->do(q{CREATE TABLE foo (bar text)});
    $sth=$dbh->prepare(q{INSERT INTO foo(bar) VALUES(?)});
    $sth->execute(q{Hello})'

Next, verify that the Hello string was indeed stored by querying the database:

$ perl -MDBI -e '$dbh=DBI->connect(q{dbi:SQLite:dbname=test}); print $dbh->selectrow_array(q{SELECT bar FROM foo}), qq{\n}'
Hello

The output shows that DBD::SQLite works.

Installing non-modular packages with non-default streams

So far, everything we want is working. But now let's see what happens if you try to install incompatible RPM packages:

# yum --allowerasing install 'perl(LWP)'
[…]
Error:
 Problem: package perl-libwww-perl-6.34-1.el8.noarch requires perl(:MODULE_COMPAT_5.26.2), but none of the providers can be installed
  - cannot install the best candidate for the job
  - package perl-libs-4:5.26.3-416.el8.i686 is excluded
  - package perl-libs-4:5.26.3-416.el8.x86_64 is excluded
(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)

Yum reports an error about perl-libwww-perl RPM package being incompatible. The LWP CPAN module that is packaged as perl-libwww-perl is built only for Perl 5.26, so RPM dependencies cannot be satisfied.

When a perl:5.24 stream is enabled, the packages from the perl:5.26 stream are masked, meaning that they become unavailable. However, this masking does not apply to non-modular packages, such as perl-libwww-perl. Many packages have not been modularized yet. If you need some of them to be available and compatible with a non-default stream (i.e., not only with Perl 5.26) do not hesitate to contact the Red Hat support team with your request. However, make sure that your desired non-default stream is still supported.

Resetting a module

Let's say you want to find out whether your existing application works with the new Perl 5.26 version. To do that, you need to switch back to the perl:5.26 stream.

Unfortunately, it's not a straightforward process to switch from an enabled stream back to a default stream or to yet another non-default stream. You'll need to perform a module reset:

# yum module reset perl
[…]
Dependencies resolved.
==========================================================================================
 Package              Arch                Version              Repository            Size
==========================================================================================
Resetting module streams:
 perl                                     5.24

Transaction Summary
==========================================================================================

Is this ok [y/N]: y
Complete!

That didn't hurt too much. Now you can synchronize the distribution again to replace the 5.24 RPM packages with 5.26 ones:

# yum --allowerasing distrosync
[…]
Transaction Summary
==========================================================================================
Upgrade    65 Packages
Downgrade  71 Packages

Total download size: 22 M
Is this ok [y/N]: y
[…]

After that, you can check the Perl version:

$ perl -V:version
version='5.26.3';

And check the enabled modules:

# yum module list
[…]
parfait              0.5              common       Parfait Module
perl                 5.24             common [d],  Practical Extraction and Report Languag
                                      minimal      e
perl                 5.26 [d]         common [d],  Practical Extraction and Report Languag
                                      minimal      e
perl-App-cpanminus   1.7044 [d]       common [d]   Get, unpack, build and install CPAN mod
                                                   ules
perl-DBD-MySQL       4.046 [d]        common [d]   A MySQL interface for Perl
perl-DBD-Pg          3.7 [d]          common [d]   A PostgreSQL interface for Perl
perl-DBD-SQLite      1.58 [d][e]      common [d]   SQLite DBI driver
perl-DBI             1.641 [d][e]     common [d]   A database access API for Perl
perl-FCGI            0.78 [d]         common [d]   FastCGI Perl bindings
perl-YAML            1.24 [d]         common [d]   Perl parser for YAML
php                  7.2 [d]          common [d],  PHP scripting language
                                      devel, minim
                                      al
[…]

You are back at square one. The perl:5.24 stream is not enabled, and perl:5.26 is the default and therefore preferred. Only the perl-DBD-SQLite:1.58 and perl-DBI:1.641 streams remained enabled, which does not matter much because those are the only streams. Nonetheless, you can reset them back using yum module reset perl-DBI perl-DBD-SQLite if you like.

Multicontextual streams

What happened with the DBD::SQLite CPAN module? It's still there and working:

$ perl -MDBI -e '$dbh=DBI->connect(q{dbi:SQLite:dbname=test}); print $dbh->selectrow_array(q{SELECT bar FROM foo}), qq{\n}'
Hello

This command works because the perl-DBD-SQLite module is built for both the 5.24 and 5.26 Perl versions. We call these modules multicontextual. That's also the case for perl-DBD-MySQL or perl-DBI, but not the case for FreeRADIUS, which explains the warning you saw earlier. If you want to see these low-level details—such as which contexts are available, which dependencies are required, or which packages are contained in a module—you can use the yum module info <module>:<stream> command.

Conclusion

I hope this tutorial has shed some light on modules, a Red Hat Enterprise Linux 8 feature that lets you install multiple versions of software on top of one Linux platform. If you need more details, please read the documentation accompanying the product (namely, the userspace component management document and the yum(8) manual page) or ask the support team for help.

Last updated: November 1, 2023