💾 Archived View for thrig.me › tech › rpm-a-directory.gmi captured on 2023-09-28 at 16:55:51. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-04-19)

-=-=-=-=-=-=-

RPM a Directory

This page details a method for having a single directory with many CPAN modules on RedHat systems, to avoid wasting time trying to build individual CPAN modules into individual RPMs.

Background

To fit round CPAN distributions into square RPM pegs takes some doing. There are rakes and many other gardening tools to step on and deal with. Maybe if you have enough people to throw at the problem? I didn't. Also there may be dependency conflicts, perhaps RHEL8 wants module version X, and the software you need module version Y, which then creates a cascade of other modules to update, and who knows if the vendor's software will still work after you've updated lots of things, and now you have a giant tree of custom RPMs to maintain. I never got that far. ELACKOFTIME.

Another method would be to install a totally new version of perl and all the modules necessary somewhere. This may be necessary if the perl version on RedHat is hopelessly out of date for your needs. This directory could also be shoved into a single RPM.

https://metacpan.org/pod/Perl::Build

My solution to the "custom RPM for Perl modules take too much time to build" problem was to use the vendor base perl, but to build a directory of modules that specific applications and services that needed up-to-date modules could use.

A Directory of Modules

This need not be a single directory; there could be multiple such directories, one for each particular application that needs particular module versions. I ran nothing so complicated, so ended up with a single directory that had all the latest things from CPAN, as distinct from whatever the base operating system was shipping with. Of course various applications and scripts will need to know about this directory.

The gist is to 1) setup cpanm and local::lib to install perl modules to somedirectory 2) maintain a cpanfile of modules for cpanm to install 3) install those modules to somedirectory 4) build somedirectory into a tarball 5) build the tarball into an RPM 6) install the RPM on target systems 7) setup the environment on the target systems to list somedirectory in PERL5LIB.

https://metacpan.org/pod/App::cpanminus

https://metacpan.org/pod/local::lib

For the initial setup, read the cpanm and notably the local::lib docs on how to make installs go to /usr/local/somedirectory, or whatever. This path should be outside of those maintained by the vendor.

To add a new module, the process could run along the lines of the following.

    echo New::Module >> cpanfile
    cpanm --installdeps .
    # ... increment the release number in the *.spec file ...
    cd /usr/local && tar czpf ~/rpmbuild/SOURCES/somedirectory.tar.gz somedirectory
    rpmbuild -ba somedirectory.spec

Then sign the RPM, etc. This should be fairly trivial to automate. Run `cpan-outdated` with somedirectory in PERL5LIB to see what updates are available on CPAN.

There is also Carton, if you need that. (I haven't, so only mention it in passing.)

https://metacpan.org/pod/Carton

Usage

The vendor scripts probably should not know about the custom module area; scripts that do need to know about it can have

    use lib qw(/usr/local/somedirectory/lib/perl5);

in them, or for a service where no vendor code is run, set

    Environment=PERL5LIB=/usr/local/somedirectory/lib/perl5

among other such methods.

Configuration Management

It is assumed that some sort of configuration management is used to install the necessary packages for the systems, because the directory of modules has no dependency information whatsoever.

somedirectory.spec

    Name:		somedirectory
    # NOTE version is tied to major Centos release, instead increment the
    # release when there are updates or new modules
    Version:	8.0
    Release:	1%{?dist}

    Summary:	All the perl modules
    Group:		Development/Tools
    License:	It's complicated

    Source0:	%{name}.tar.gz

    # TODO how also say "but not the next higher major version"? in the
    # meantime, don't copy the Centos 8 RPM into the Centos 7 tree
    Requires:	redhat-release >= %{version}

    BuildRequires:	rsync

    # we install to a non-vendor directory; do not spam the requirements
    # database with our perl modules that will then conflict with the vendor
    #Autoreq: 0
    Autoreqprov: 0
    Autoprov: 0

    %description
    The /usr/local/somedirectory directory that contains various Perl modules.

    %prep
    %setup -q -n %{name}

    %install
    rm -rf $RPM_BUILD_ROOT
    mkdir -p $RPM_BUILD_ROOT/usr/local/somedirectory
    rsync -a . $RPM_BUILD_ROOT/usr/local/somedirectory

    %files
    /usr/local/somedirectory/*

    %changelog
    TODO FIXME