NAME

RPM::Make - cleanly generate an RPM

SYNOPSIS

    use RPM::Make;

    # The "Manifest": list of files that will comprise the software package.
    my @filelist=('tmproot/file1.txt',
		  'tmproot/file2.txt',
		  'tmproot/file3.txt',
		  'tmproot/file4.txt');

    my %doc; my %conf; my %confnoreplace; my %metadata;

    # Define special handling of files.
    $doc{'tmproot/file1.txt'}=1;
    $conf{'tmproot/file2.txt'}=1;
    $confnoreplace{'tmproot/file3.txt'}=1;

    # Bare minimum metadata (descriptive data of the software package).
    my $pathprefix='tmproot'; # Location of files to be included in package.
    my $tag='Test'; # Default name of the software package.
    my $version='0.1'; # Version number.
    my $release='1'; # Release number (versions can have multiple releases).

    # Highly descriptive metadata.
    %metadata=(
	       'vendor'=>'Excellence in Perl Laboratory',
	       'summary'=>'Test Software Package',
	       'name'=>$tag,
	       'copyrightname'=>'...',
	       'group'=>'Utilities/System',
	       'AutoReqProv'=>'no',
	       'requires'=>[('PreReq: setup',
			     'PreReq: passwd',
			     'PreReq: util-linux'
			     )],
	       'description'=>'This package is generated by RPM::Make. '.
                      'This implements the '.$tag.' software package',
        'pre'=>'echo "You are installing a package built by RPM::Make; '.
                      'RPM::Make is available at https://www.cpan.org/."',
 	       );

    # Temporary "sandbox" (this should not be /tmp because this is deleted!).
    my $buildloc='TempBuildLoc';

    # The "execute" subroutine coordinates all of the RPM building steps.
    RPM::Make::execute($tag,$version,$release,$arch,$buildloc,$pathprefix,
		       \@filelist,\%doc,\%conf,\%confnoreplace,
		       \%metadata);

    # You can also build an RPM in more atomic steps; these three smaller
    # steps are equivalent to the execute command.

    # Step 1: Generate the rpm source location.
    RPM::Make::rpmsrc($tag,$version,$release,$buildloc,$pathprefix,
 	              \@filelist,\%doc,\%conf,\%confnoreplace,
		      \%metadata);

    # Step 2: Build the rpm and copy into the invoking directory.
    RPM::Make::compilerpm($buildloc,$metadata{'name'},$version,
			  $release,$arch,
			  $currentdir,$invokingdir);

    # Step 3: Clean the location used to gather and build the rpm.
    RPM::Make::cleanbuildloc($buildloc);

SUBROUTINES

RPM::Make::testsystem()

Check to see if RPM builder application is available.

INPUT

n/a

OUTPUT

n/a

ERROR

If /usr/lib/rpm/rpmrc does not exist, then print error and exit.

NOTE

To date, this testing action has been fully adequate, though imperfect.

RPM::Make::execute($tag,$version,$release,$arch,$buildloc,$pathprefix,\@filelist,\%doc,\%conf,\%confnoreplace,\%metadata);

Build the RPM in one clean sweep.

INPUT

6 scalar strings, 1 array reference, and 4 hash references.

OUTPUT

n/a

ERROR

Errors are monitored by the other subroutines that are called.

NOTE

First calls &rpmsrc, then &compilerpm, then &cleanbuildloc.

RPM::Make::rpmsrc($tag,$version,$release,$buildloc,$pathprefix,\@filelist,\%doc,\%conf,\%confnoreplace,\%metadata);

Properly assemble the RPM source location (prior to building).

INPUT

5 scalar strings, 1 array reference, and 4 hash references.

OUTPUT

n/a

ERROR

$version, $release, and $buildloc variables need to have a string length greater than zero, else the module causes an exit(1).

$tag must only consist of alphanumeric characters and dash signs '-', else the module causes an exit(1).

NOTE

Should be called before &compilerpm and &cleanbuildloc.

RPM::Make::compilerpm($buildloc,$name,$version,$release,$arch,$currentdir,$invokingdir);

Properly assemble the RPM source location (prior to building).

INPUT

7 scalar strings

OUTPUT

n/a

ERROR

If one "rpm" command syntax fails, then try another. If all "rpm" command syntaxes fail, then print error and exit.

If copying the built rpm fails, then print error and exit.

NOTE

Should be called after &rpmsrc and before &cleanbuildloc.

RPM::Make::cleanbuildloc($buildloc);

Clean build location - usually TempBuildLoc (all the files normally associated with a *.src.rpm file).

INPUT

1 scalar string

OUTPUT

n/a

ERROR

If the input argument is empty, then abort. Also should abort if cannot remove the location specified by the input argument.

NOTE

Should be called after &rpmsrc and after &compilerpm.

RPM::Make::find_info($file_system_location);

Recursively gather information from a directory. (Ideally, I would use the prune invocation of the find command, however older versions of 'find' do not have prune (< 4.1.7). Therefore, the work-around is to use maxdepth 0.)

INPUT

1 scalar string.

OUTPUT

n/a

ERROR

If $file_system_location is neither a directory, or softlink, or regular file, then abort.

NOTE

Called by &rpmsrc.

DESCRIPTION

Automatically generate an RPM software package from a list of files.

RPM::Make builds the RPM in a very clean and configurable fashion. (Finally! Making RPMs outside of /usr/src/redhat without a zillion file intermediates left over!)

RPM::Make should work with both rpm 3.x and rpm 4.x (it has been tested on redhat 6.x, redhat 7.x, and redhat 8.x as well as other un*x variants).

RPM::Make generates and then deletes temporary files needed to build an RPM with. It works cleanly and independently from pre-existing directory trees such as /usr/src/redhat/*.

RPM::Make accepts five kinds of information, three of which are significant:

  • (significant) a list of files that are to be part of the software package;

  • (significant) the filesystem location of these files;

  • (significant) a descriptive tag and a version tag for the naming of the RPM software package;

  • documentation and configuration files;

  • and additional metadata associated with the RPM software package.

When using RPM::Make::execute, a temporary directory named $buildloc is

  • generated under the directory from which you run your script;

  • then deleted after the *.rpm file is generated.

The RPM will typically be named "$metadata{'name'}-$version-$release.i386.rpm". If $metadata{'name'} is not specified, then $tag is used.

Here are some of the items that are generated inside the $buildloc directory during the construction of an RPM:

  • RPM .spec file (./$buildloc/SPECS/$name-$version.spec)

  • RPM Makefile (./$buildloc/SOURCES/$name-$version/Makefile)

    This is the Makefile that is called by the rpm command in building the .i386.rpm from the .src.rpm. The following directories are generated and/or used:

    • SOURCE directory: ./$buildloc/BinaryRoot/

    • TARGET directory: ./$buildloc/BuildRoot/

  • BinaryRootMakefile (./$buildloc/BinaryRootMakefile)

    This is the Makefile that this script creates and calls to build the $buildloc/BinaryRoot/ directory from the existing filesystem. The following directories are generated and/or used:

    • SOURCE directory: / (your entire filesystem)

    • TARGET directory: ./$buildloc/BinaryRoot/

The final output of RPM::Make::execute is a binary .rpm file. The ./buildloc directory is deleted (along with the .src.rpm file). The typical file name generated by RPM::Make is $tag-$version-$release.i386.rpm.

RPM::Make is compatible with either rpm version 3.* or rpm version 4.*.

README

Automatically generate an RPM software package from a list of files.

RPM::Make builds the RPM in a very clean and configurable fashion without using /usr/src/redhat or any other filesystem dependencies.

RPM::Make generates and then deletes temporary files (and binary root directory tree) to build an RPM with.

RPM::Make was originally based on a script "make_rpm.pl" available at https://www.cpan.org/scripts/.

PREREQUISITES

This script requires the strict module.

AUTHOR

Scott Harrison
[email protected]

Please let me know how/if you are finding this module useful and any/all suggestions. -Scott

LICENSE

Written by Scott Harrison, [email protected].

Copyright Michigan State University Board of Trustees

This file is part of the LearningOnline Network with CAPA (LON-CAPA).

This is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

The GNU Public License is available for review at https://www.gnu.org/copyleft/gpl.html.

For information on the LON-CAPA project, please visit https://www.lon-capa.org/.

STATUS

This module is new. It is based on a well-tested (and well-used) script that I wrote (make_rpm.pl; available at https://www.cpan.org/scripts/).

OSNAMES

Linux