makesrpm: Support custom version strings 16/14116/16
authorMichael Meffie <>
Fri, 1 May 2020 18:05:24 +0000 (14:05 -0400)
committerBenjamin Kaduk <>
Fri, 4 Sep 2020 14:02:38 +0000 (10:02 -0400)
The script generates a source RPM by creating a temporary
rpmbuild workspace, populating the SOURCES and SPECS directories in that
workspace, running rpmbuild to build the source RPM, and finally copying
the resulting source RPM out of the temporary workspace.

The name of the source RPM file created by rpmbuild depends on the
package version and release strings. Unfortunately, the format of the
source RPM file name changed around OpenAFS 1.6.0, so has
special logic to find the version string and extra code depending on the
detected OpenAFS version.

Instead of trying to predict the name of the resulting source RPM file
from the OpenAFS version string, and having different logic for old
versions of OpenAFS, use a filename glob to find resulting source RPM
file name in the temporary rpmbuild workspace.

Remove the major, minor, and patch level variables, which were only used
to guess the name of the resulting source RPM file name.

Convert '-' characters to '_' in the package version and package
release, since the '-' character is reserved by rpm as a field

While here, add the --dir option to specify the path of the generated
source RPM, and change the 'srpm' makefile target to use the new --dir
option, instead of changing the current directory before running  Also, add a dependency on the 'dist' makefile target,
since the the source and document tarballs are required to build the
source RPM.

Add pod documentation and add the --help (-h) option to print a brief
help message, and add the --man option to print the full man page.

With this change, we can build a source RPM even when the .version file
in the file has a custom format or was created from a
checkout of the master branch or other non-release reference.

Change-Id: I7320afe6ac1f77d4dd38fcc194d41678fde5c950
Tested-by: BuildBot <>
Reviewed-by: Andrew Deason <>
Reviewed-by: Cheyenne Wills <>
Reviewed-by: Benjamin Kaduk <>

index c647888..72014bc 100644 (file)
@@ -783,8 +783,10 @@ clean2:
        ./build-tools/make-release --dir=packages HEAD
-       (cd packages && ../src/packaging/RedHat/ *-src.tar.bz2 *-doc.tar.bz2)
+srpm: dist
+       ./src/packaging/RedHat/ --dir=packages \
+         packages/openafs-*-src.tar.bz2 \
+         packages/openafs-*-doc.tar.bz2
        if test "x$(DOXYGEN)" != "x"; then \
index 7744d5d..7d6e1a9 100755 (executable)
@@ -3,24 +3,39 @@
 use strict;
 use warnings;
+use Getopt::Long;
+use Pod::Usage;
 use IO::Dir;
 use IO::File;
 use File::Path;
 use File::Copy;
 use File::Temp;
+use File::Basename;
+use File::Spec;
 # Build an SRPM for OpenAFS, given a src and doc tarball, release notes,
 # and ChangeLog.
+my $help = 0;
+my $man = 0;
+my $dir = ".";
+    "help|?" => \$help,
+    "man" => \$man,
+    "dir=s" => \$dir,
+) or pod2usage(-exitval => 1, -verbose => 1);
+pod2usage(-exitval => 0, -verbose => 1) if $help;
+pod2usage(-exitval => 0, -verbose => 2, -noperldoc => 1) if $man;
 my $srcball = shift;
 my $docball = shift;
 my $relnotes = shift;
 my $changelog = shift;
 my $cellservdb = shift;
-if (!$srcball && !$docball) {
-  printf "Usage:  makesrpm <src.tar.bz2> <doc.tar.bz2> [<relnotes> [<changelog> [<cellservdb>]]]\n";
-  exit(1);
+if (!defined($srcball) || !defined($docball)) {
+    pod2usage(-exitval => 1, -verbose => 1);
 if (! -f $srcball) {
@@ -77,15 +92,12 @@ if ($afsversion=~m/(.*)-([0-9]+)-(g[a-f0-9]+)$/) {
-print "Linux release is $linuxrel\n";
-print "Linux version is $linuxver\n";
+# Avoid illegal characters in RPM package version and release strings.
+$linuxver =~ s/-/_/g;
+$linuxrel =~ s/-/_/g;
-# Figure out a major, minor and release so that we know which version we're
-# building, and therefore what the srpm is going to be called
-my $major = $1;
-my $minor = $2;
-my $patchlevel = $3;
+print "Package version is $linuxver\n";
+print "Package release is $linuxrel\n";
 # Build the RPM root
@@ -165,18 +177,49 @@ system("rpmbuild -bs --nodeps --define \"dist %undefined\" ".
   or die "rpmbuild failed : $!\n";
 # Copy it out to somewhere useful
-if (!defined($major) || $major > 1 || ($major == 1 && $minor >= 6)) {
-  File::Copy::copy("$tmpdir/rpmdir/SRPMS/openafs-$linuxver-$linuxrel.src.rpm",
-                  "openafs-$linuxver-$linuxrel.src.rpm")
-    or die "Unable to copy output RPM : $!\n";
+my @srpms = glob("$tmpdir/rpmdir/SRPMS/*.src.rpm");
+if (scalar(@srpms) != 1) {
+    die "Generated SRPM file not found.\n";
+my $filename = File::Basename::fileparse($srpms[0]);
+my $srpm = File::Spec->rel2abs("$dir/$filename");
+File::Copy::copy($srpms[0], $srpm)
+    or die "Failed to copy '$srpms[0]' to '$srpm': $!\n";
+print "SRPM is $srpm\n";
-  print "SRPM is openafs-$linuxver-$linuxrel.src.rpm\n";
-} else {
-  File::Copy::copy("$tmpdir/rpmdir/SRPMS/openafs-$linuxver-1.$linuxrel.src.rpm",
-                  "openafs-$linuxver-1.$linuxrel.src.rpm")
-    or die "Unable to copy output RPM : $!\n";
-  print "SRPM is openafs-$linuxver-1.$linuxrel.src.rpm\n";
+=head1 NAME
+ - Build the SRPM for OpenAFS from source distibution files
+=head1 SYNOPSIS
+ [options] <src.tar.bz2> <doc.tar.bz2> [<relnotes> [<changelog> [<cellservdb>]]]
+Build the SRPM for OpenAFS from source distibution files. Generate empty RELNOTES
+and ChangeLog files if not provided. Download the CellServDB file from if one is not provided.
+=head1 OPTIONS
+=over 4
+=item B<--help>
+Print help message and exit.
+=item B<--man>
+Print full man page and exit.
+=item B<--dir> I<path>
+Place the generated SRPM file in I<path> instead of the current directory.