June 1, 2007

Customize RPMs with rpmrebuild

Author: Joe 'Zonker' Brockmeier

Building packages is usually hard work, and best left to distro developers who have the time and patience to work the appropriate magic. However, if you're an admin or user with a need to rebuild existing packages, rpmrebuild takes the pain out of creating new RPMs from installed packages.

What's rpmrebuild useful for? A couple of scenarios come to mind. The first is when an RPM isn't available from the original source for some reason -- for example, if you built a custom RPM, or if you got an RPM from a third party and it's no longer available online and you want to be able to use it on other systems.

It's also useful if you want to distribute customized packages. For instance, if you wanted to distribute the OpenSSH daemon with customized configuration files, you could repackage the openssh-server package with rpmrebuild and use it instead of the stock package.

Getting started

The rpmrebuild utility should work on any recent RPM-based distro that has rpmbuild installed. If you don't have rpmbuild, you'll need to get it. I tested rpmrebuild on CentOS 5, so I used yum to grab the rpm-build package:

yum install rpm-build

After that, I grabbed the rpmrebuild RPM from the SourceForge.net download page and installed it with rpm -ivh rpmrebuild-2.1.0-1rpm4.noarch.rpm. Of course, the version number of the RPM may change over time.

We can rebuild it, we have the technology...

Now that the utility is installed, you can start rebuilding packages. The syntax for rpmrebuild is simple: rpmrebuild optionspackagename, or rpm --rebuild optionspackagename .

So, if you wanted to rebuild the openssh-server package using some customized files, you'd use:

rpmrebuild openssh-server

You'll want to run it as root, unless all of the files are accessible to non-root users. Once you run the command you'll see something similar to Figure 1:

Figure 1: rpmrebuild walks through creating a new package - click to view

The utility will ask a few questions -- whether you want to continue and whether you want to change the version number -- then tell you where it put the modified RPM. On CentOS 5, my packages were written to /usr/src/redhat/RPMS/i386/packagename.rpm. You can specify an alternate directory location for the new RPM by passing it with the -d option to rpmrebuild.

It's a little more complex if you want to add new files to a package, but only a little. Add the edit (-e) option, and you'll be given the opportunity to edit the specfile:

rpmrebuild -e packagename

You'll be dropped into the default editor, with the specfile for the package. Look for the section that starts with %files:

%config(noreplace) %attr(0644 root root) "/etc/pam.d/ssh"
%attr(0755 root root) "/etc/rc.d/init.d/sshd"
%dir %attr(0755 root root) "/etc/ssh"
%config(noreplace) %attr(0600 root root) "/etc/ssh/sshd_config"
%attr(0755 root root) "/usr/libexec/openssh/sftp-server"
%attr(0755 root root) "/usr/sbin/sshd"
%doc %attr(0644 root root) "/usr/share/man/man5/sshd_config.5.gz"

Each line has information about the type of file if necessary -- such as %dir for directory, or %doc for man pages. Regular files don't require a directive. Each line also has file permissions and ownership info, and the path of the file to be packaged. See the RPM docs for more on the file directives.

If I wanted to add a README with site-specific information, I might add a line like this:

%doc %attr(0644 root root) "/usr/local/packagename/README.local"

You can use the -e option to make other changes to the specfile; if you want to change package requirements or anything else, this would be the option to use.

If you're after a quick way to rebuild packages, rpmrebuild is the way to go. Be sure to read the manpage for additional options.

Click Here!