yum! RPMs!

The content of this article will be very bland if you’re not regularly on a linux machine and, in particular, a Red Hat based machine. I am goign to write about RPMs, so if this is of interest to you, congrats reader, read on!

Preliminaries

This guide is pretty specific to Fedora. To follow along, you must be inside a Fedora machine with the fedora-packager package installed from yum,

sudo yum install fedora-packager

If you do not have access to a fedora machine, I can provide one for you.

Meat and Potatoes

How do you typically install software from source? The ./configure, make, and make install pattern is pretty ubiquitous and most people are familiar with it.

There are two common problems to this process:

RPMs

RPMs are a package format that attempts to solve those two problems from installing new software. It offers a user a way to specify dependencies as well as keep track of installed files.

Yum is related to RPM in that it is an RPM package manager. When you download an RPM and need to install it, but it has dependencies, an RPM by itself does not know where to look for those dependencies. That is where yum comes in to save the day.

A Hello World Example

Starting off in a clean directory, we are goign to create a couple files. First file will be the spec file, SPECS/helloworld.spec:

Name: helloworld
Version:  0.0.1
Release:  1%{?dist}
Summary:  Quick RPM example

License:  BSD
URL:  http://intranet/~rbruns/

Source0:  helloworld.conf

BuildArch:  noarch

%description
A very complicated shell script that prints out the string "hello
world".

%prep
cp %SOURCE0 .

%build
cat <<EOF >%{name}
#!/bin/sh
. %{_sysconfdir}/%{name}.conf
echo \$HELLO
EOF

%install
install -pDm644 %{name}.conf %{buildroot}%{_sysconfdir}/%{name}.conf
install -pDm644 %{name} %{buildroot}%{_bindir}/%{name}

%files
%config %attr(0644, root, root) %{_sysconfdir}/%{name}.conf
%attr(0755, root, root) %{_bindir}/%{name}

%changelog
* Fri Dec 05 2014 Renning Bruns <rbruns@ixl.com>
- initial creation

We have also specified a source file which contains our config in SOURCES/helloworld.conf:

HELLO="hello world"

So our directory tree now looks like:

$ find .
.
./SOURCES
./SOURCES/helloworld.conf
./SPECS
./SPECS/helloworld.spec

And to build the RPM,

$ rpmbuild --define "_topdir $(pwd)" -bb SPECS/helloworld.spec

Note the use of --define "_topdir $(pwd)". This single-handedly made creating RPMs not as painful as many of the guides available online which required first creating a non-privileged user, then creating a chroot to jail in the process, and using those to create your RPMs. While there are some security benefits in doing that, they are terribly inpractical. Not doing that lets us easily script out the creation of RPMs.

Everything should build successfully, and if it does, our new RPM lives somewhere inside the RPMS directory. We can install it with yum now.

$ sudo yum install RPMS/noarch/helloworld-0.0.1-1.fc20.noarch.rpm

Sections

There are Four important sections:

The main reason for the separation of these sections and steps is that there are also some convenience macros to help make writing the spec file for simple projects much quicker.

There are also a handful of other sections that are of use. For example sections to run before and after installing or uninstalling a package to create users, groups, and upstart/systemd files. All of these are detailed on the How to create an RPM page.

Prep

This section is mostly for things like extracting tar balls, checking out code repositories, and copying source files to the current work space.

Those things are not necessary, but essentially this is where all the “prep work” that you need done can safely happen.

Build

This section does all the compilation. Following the typical pattern of building source code, this sections corresponds to the the

./configure
make

portion of installing software.

Install

This section is where things get a little different. Instead of installing things as you normally would, you must prefix the destination of the files you install to first go into %{buildroot}.

This is so that the RPM can neatly archive up all the files to be installed.

Files

This section may seem to be made redundant but here you list all of the files installed as well as any permissions and user ownership.

Macros

Each section can employ different RPM macros to help shorten up some more common tasks. The Fedora project has a list of macros available to them.

Examples In The Wild

You can view actual spec files used in almost all of the packages available through yum to fedora users. For instance, I looked at the redis package to get an idea of how to create a spec file with an updated copy of that package for Fedora 14 (which does not exist in the yum repository).