Building RPMs with Mock
Mock is a simple chroot environment manager that allows you to manage and maintain a consistent build environment. Why should you care? Consistency. Many projects end up painting themselves into a corner with unrepeatable builds. Undocumented dependencies can quite easily be installed on a build server and are difficult to detect. These uncontrolled builds can then result embarrasment when they can’t be installed or can lead to wasted developer time trying to diagnose and debug issues. To make matters worse, if your build server were to fail, you might find yourself unable to build at all.
Building in a controlled manner in a pristine, known good, repeatable chroot environment helps you to minimize this risk. It ensures that your applications dependencies applications are explicitely defined prior to building. This is by no means the only way to accomplish this task. I’ve also worked in environments where virtualization was used for the build itself with the whole build server being reconstructed in between builds. Using chroots for this purpose is a little less radical and is likely easier to fit into your existing build process.
Building and Installing
Mock is available in RPM form. You can get set up quickly by running:
$ sudo yum install fedora-packager mock
If you want to build it for your system, the steps are fairly simple:
$ git clone git://git.fedorahosted.org/git/mock.git mock
$ ./autogen.sh
$ ./configure
$ make rpm
$ sudo rpm -i ./noarch/mock-*.noarch.rpm
Configuration
Configuration files live by default in /etc/mock. The ones you’ll want to look at specifically are /etc/mock/default.cfg and /etc/mock/site-defaults.cfg. Depending on how you want to do builds you might also need to look at /etc/pam.d/mock. It’s important to note that you should never build as root as this can do damage to your build system in the event that your build goes badly.
$ cat /etc/mock/default.cfg
config_opts['root'] = 'epel-5-x86_64'
config_opts['target_arch'] = 'x86_64'
config_opts['chroot_setup_cmd'] = 'install buildsys-build'
config_opts['dist'] = 'el5' # only useful for --resultdir variable subst
config_opts['yum.conf'] = """
[main]
cachedir=/var/cache/yum
debuglevel=1
logfile=/var/log/yum.log
reposdir=/dev/null
retries=20
obsoletes=1
gpgcheck=0
assumeyes=1
# grub/syslinux on x86_64 need glibc-devel.i386 which pulls in glibc.i386,
# need to exclude all .i?86 packages except these.
exclude=[1-9A-Za-fh-z]*.i?86 g[0-9A-Za-km-z]*.i?86 gl[0-9A-Za-hj-z]*.i?86
exclude=gli[0-9A-Zac-z]*.i?86 glib[0-9A-Za-bd-z]*.i?86
# repos
[core]
name=base
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=x86_64&repo=os
[update]
name=updates
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=x86_64&repo=updates
[otherrepos]
... <elided> ...
$ cat /etc/pam.d/mock
#%PAM-1.0
auth sufficient pam_rootok.so
auth sufficient pam_succeed_if.so user ingroup build use_uid quiet
auth include system-auth
account sufficient pam_succeed_if.so user ingroup build use_uid quiet
account include system-auth
password include system-auth
session include system-auth
session optional pam_xauth.so
This pam configuration will allow any user in the unix group ‘build’ to perform builds.
Once you’ve got things setup to your liking, building should be as simple as running:
$ mock magicalpackage-1.0-0.src.rpm --resultdir=/tmp