Man wrapping RPM packages

Updating RPMs with newer upstream source releases – for beginners

Is your RPM based Linux distribution slow at updating your favorite package? Are you really impatient for the new hotness in a recently released version of a software of which you simply must have the latest version? Here is a quick-guide for rebuilding an RPM with up-to-date upstream sources.

You can follow along in this tutorial using the package that you want to update. I’ve used nginx as an example package throughout the tutorial, but you can use any other package that already exist in your distribution’s package repository. Depending on the complexity of the RPM package and how agreeable upstream are, you should have no problem updating it yourself. You’ll not potentially break your system (well, the package you’re updating) until the very last step of the tutorial. You can follow along and consider how comfortable you feel with installing your own RPM package at the very end.

I’ll refer to Fedora and the Fedora repository in this tutorial, but there is very little here that don’t also apply to other RPM based distributions such as CentOS, openSUSE, and Qubes OS. You may need to supplement the dnf command with your distribution’s equivalent.

Prerequisites

You’ll need to meet the following prerequisites to proceed.

  • Your distro already provides an RPM package for the software you want to update out-of-cycle.
  • Your distro provides up-to-date versions of all build dependencies needed by the new software version.
  • A little faith in your own abilities to solve problems.

You’ll also need to install some build tool and dependency packages as the root user. When you’re done with the two commands below, drop out of the root shell and use an un unprivileged user for the rest of this tutorial. You’ll not need root access again until the very end of this tutorial. I’ll use the nginx package throughout this tutorial, marked with an underline in all code examples. Supplement nginx for the name of the package you want to update.

dnf install rpm-build rpmdevtools
dnf builddep nginx

Now you’ve got an RPM build-capable environment for your package. Congratulations! Now, let’s get started.

Getting the RPM spec and current sources from the repository

We next need to setup the RPM development directory tree. You’ll end up with a new ~/rpmbuild/ directory in your home folder. Next, you’ll populate it with the sources for the package you want to update.

rpmdev-setuptree
cd ~/rpmbuild/
dnf download --source nginx
rpm -ivh ./nginx-*.src.rpm

Your ~/rpmbuild/ directory should now contain folders with the source of nginx. You may get a bunch of warnings about missing something called “mockbuild”, but you can safely ignore these.

If you want to test and verify that you can build the current version of the source RPM, then skip over the next section and proceed to the one after it. After completing that section, you can return to the following section.

Updating the RPM spec file version and obtaining the new sources

Open up the spec file, located in ~/rpmbuild/SPEC/nginx.spec in your favorite editor. You’ll need to make the following two changes to the file:

  • Update the Version field to match the new upstream version number exactly.
  • Change the Release field to 0. When your distrobution release an updated version of the package in their repository, it will be given a release number of 1 or higher. Setting your home-brewed RPM package to a lower number ensures you’ll get updates from your distribution’s repository as they become available in the future.

Now, assuming you’re building a package for your own environment and assuming nothing too much has changed upstream. This is actually all you need to do! Run the following command to attempt to download the new sources from upstream.

spectool -g -R ~/rpmbuild/SPECS/nginx.spec

Did the command succeed? Proceed to the next section. If not read on in this section for the most common troubleshooting tips.

Double check the Version field number in the spec file. Locate the upstream source tarball from their website. Look for the version number in the file name.

Check to see if there is a Source# field that provides a link to the upstream sources. If not, then this is a special package that requires manual changes to update. This tutorial doesn’t cover such packages.

Check the URL Source# field. You’ll see that the version number is substituted from the Version field. Is this the correct download path? If not, you may cheat a bit and set this address manually.

Building the binary RPM

Before building the sources, you’ll need to apply any patches from your distribution that was included with source RPM package from the previous version to the updated source version. These patches help ensure the software runs smoothly on your distribution and integrates with the rest of the system.

rpmbuild -bp ~/rpmbuild/SPECS/nginx.spec

If all patches applied correctly, then you’re ready to attempt to build. (Feeling a bit excited? That is normal at this stage.) The command for building is almost the same, differences highlighted in bold, as for applying patches:

rpmbuild -bb ~/rpmbuild/SPECS/nginx.spec

You may have a bunch of working RPMs at this point, or building may have failed entirely.

It’s out of scope for this tutorial to handle cover how you debug a failing build or old patches that no longer will apply cleanly. You’ll need to review the source and patches yourself to make any headway at this point.

Testing!

Since you’re doing all the work yourself, you’ve also volunteered to test the new package and to become your own one-man quality assurance department. Maybe you didn’t realize that this what what you signed up for when you started, but here we are.

But how exactly do you test your own RPM package? You should install and test that it works, of course. You can install it and make sure everything got installed in the correct locations. You should also test that the software works as expected.

You probably want to perform the testing in a disposable virtual machine from your own PC, or possibly on a cheap pay-by-the-hour virtual private server provider like Linode. This isolates your main machine if there were any unintended problems with the new version.

Installing the final product

You install or uninstall it just like you do with any other package.

dnf install ~/rpmbuild/RPMS/nginx-*.rpm

Did you have fun along the way? Your distribution is more than likely very interested in having you along as a contributor to the packaging process. You can help by testing and verifying new package versions, or by updating existing packages, or packaging new software. Ask on your distribution’s IRC channel for where your time and contributions would be most useful.

Sources

  • dnf man page
  • rpmbuild man page
  • spectool man page