What are source RPMs?
A package is a collection of binaries, scripts, and associated data that is installed by your package manager.
Packages are typically generated from source code and a set of a metadata written by the package maintainer. Occasionally, the source may by patched by the package maintainer at build time.
A source RPM captures the source code and patches as they were at RPM build time.
On RPM-based systems (CentOS, Red Hat Enterprise Linux, Oracle Linux, and many more) source RPMs are RPM files that contain a tarball of source code, patches, auxiliary files that are used during the build process, and a .spec file for generating the RPM.
Why are source RPMs useful?
Source RPMs are extremely useful for:
- Regenerating binary packages
- Debugging issues with applications and libraries
- Modifying existing applications to add additional logging
- Confirming whether or not a particular security fix has been applied to the source
We strongly recommend that people and organizations running applications in production on RPM-based systems become familiar with RPM source packages so that when a bug appears, system operators and developers will have the tools to quickly and easily obtain the source and debug the issue.
Working with source RPMs
If you intend to rebuild or modify a source RPM, it is strongly recommended that you install the yum-utils
and rpm-build
packages which contains many useful tools for working with yum
and RPMs:
Getting Source RPMs
Getting the source for an RPM package is not as straight-forward as obtaining source packages for other systems.
Start by using yumdownloader
which is part of the yum-utils
package. This program will download the source RPM for the named package.
For example, to get the source RPM for redis
run:
This will download the redis
source RPM file in the current working directory.
Next, you must install the source RPM. When a source RPM is installed, the source tarballs, patches, and auxilliary files will be installed under a top level directory. This directory is called topdir
. You can get the current value of topdir
by checking the output of rpm --showrc | grep topdir
. On many systems, the default value is rpmbuild
in the current user’s home directory.
You can set your own topdir
by creating a file named .rpmmacros
in your home directory like this:
This sample .rpmmacros
file will cause source RPMs installed by you to be written to my-rpm-build-dir
in your home directory.
You can now install the source RPM:
This will write the source tarballs, patches, and other files to the SOURCES
directory under your specified topdir
. The RPM spec file will be written to SPECS
.
Install Source RPM build dependencies
You should now install the source RPM’s build dependencies by using yum-builddep
:
Preparing the source
Now, that you’ve installed the source RPM and build dependencies, you can prepare the source so that all patches are applied. This brings the source into the state it was in when the RPM was built.
Begin by switching to the SPECS
directory under your topdir
:
Next, prepare the source using the rpmbuild
program, passing the -bp
flag, and specifying the spec filename:
Now, you can examine the source. It is found in the BUILD
directory under topdir
:
Now, you can look through the source code for Redis precisely as it was when Redis was compiled and put into the package that you have installed on your system.
Modifying the source and applying patches
Patches are applied to source code during the RPM build process by listing patches in the RPM spec file, and then applied during the build process.
For example, in redis.spec
, a patch is specified like this:
The actual application happens before the %build
step:
Updating the RPM package version number
Updating the RPM package version number is done by modifying the Release
field found in the RPM spec file.
Typically, the Version
field is set to the version of the source itself whereas the Release
field is incremented for each RPM packaging related change.
Rebuilding the package
Now, you are ready to rebuild the RPM package!
You can do this by running the following command in the SPECS
directory:
This will build and write a source RPM and a binary RPM in the SRPMS
and RPMS
directories, respectively.
Upload Source RPMs to packagecloud.io
You can now upload your source RPMs to packagecloud.
You simply push the source RPM just as you would any other RPM with the package_cloud
CLI.
For example, to upload a source RPM to CentOS 7:
The packagecloud command line client uses the package create API to upload the source RPM file.
Conclusion
The RPM package toolchain enables users to quickly and easily recreate the source tree for a package as it was at build time. This is incredibly useful for debugging strange application behavior and for adding additional logging output to applications that aren’t telling you what you need to know when they run.
Becoming familiar with the workflow of obtaining source code via the package manager is essential for debugging and administering infrastructure of any size.