HowTo Build a partial Backport mirror with package aproval (with reprepro) [work in progress]

Introduction

Consider the following situation: You have a couple of Debian systems running Debian Stable. The stable branch is a fine thing, but at some point in the lifetime cycle of a stable release you often need backports of newer software (either because they fix bugs or because they have features on which you and/or your users cannot abdicate to). Thats were backports.debian.org comes in. The problem with it is that you do not want to use every single backport available, because under normal circumstances you don't want to departure from stable packages to much. So you need to use pinning to tell apt which packages you want to approve. That means rolling out a preferences file to every system on your network. Thats okay, but as we have another complication (we use Debian packages to define system profiles which is hard if your system profiles depend on backports from backports.debian.org and therefore on a changed preferences file which then can't be part of the system profile), we wanted to have another solution, which I will introduce here.

Solution:

A partial mirror of the backport.org service, which only includes packages that you explicitly added to it, but always updated with newer versions from backport.org. The trivial part is to create an apt-gettable archive, which contains backport packages. You could use any archive software you like (reprepro is my choice, but debarchiver or alike would suffice). The problem with it is that you then have packages for which you don't receive updates anymore. Of course its wise to check the quality of every new backport version, but with this you won't even notice them (unless you are tracking updates to backports.debian.org in another way). So what we want is an archive which does update itself with new packages from backports.debian.org. I'm sure it would also be possible to use debmirror but I already use reprepro to create a local archive of custom packages so I intended to make use of its update feature, which should make possible excactly what I want. Setting it up

Getting things done

Pre-requisites

You will have to decide where to place files. I have some scripts around reprepro that manage by repository which leads to my choices:

- Configuration files (for reprepro): /etc/imr-repository - Output Directory: /srv/imr-archive (is made available via lighty)

- Database Directory (for reprepro): /var/lib/imr-repository - Logfiles (optional): /var/log/imr-repository

When you decided where to place files then you should create the appropriate directories and give permissions to whoever will call reprepro in the future to at least write to Output and Database directory (only read permissions on config files). Its also wise to define some alias that you will call instead of reprepro with appropriate parameters to reflect your configuration. My reprepro alias looks like this:

reprepro --outdir /srv/imr-archive --confdir /etc/imr-repository \
--logdir /var/log/imr-repository --dbdir /var/lib/imr-repository 

Note that some of these options don't work with the stable reprepro version. I use a backport of reprepro. I will refer to the reprepro call as above by using $REPREPRO in the following part of the article.

Create a distribution

You need to configure a distribution for reprepro. This is done in a file calleddistributionsin the confdir. Mine looks like this:

Origin: in-medias-res
Label: in-medias-res etch backports
Suite: stable-backports
Codename: etch-backports
Version: 4.0
Architectures: i386 all
Components: main
Update: etch-backports
Description: in medias res approved etch backports

Note the 'Update: ' line. It defines how this distribution is beeing updated if $REPREPRO update is called. The 'etch-backports' line does refer to a update definition that is beeing made in a second file called 'updates'

Define the update method:

Looking like this:

Name: etch-backports
Method: http://backports.debian.org/debian-backports/
Architectures: i386
Suite: etch-backports
FilterList: deinstall /var/lib/imr-repository/etch-backports.list

Its not that great magic. It just defines that an APT-Mirror is used for updating. Suite on the mirror is set to etch-backports. The important part is the ?FilterList line. It defines a list that is used to filter the packages that are installed in the local archive when running $REPREPRO. By default reprepro would update every package (at least it seemed so from my test runs), this way it won't. Instead it will update every package found in the file at/var/lib/imr-repository/etch-backports.list. This file is a list in the format of dpkg --get-selections: One package a line, with an action. As the default action is deinstall, every line in this file is "package\tinstall". It might seem complex to do it this way instead of using debmirror and define regexes. But it isn't because I do create the list file by a script that does nothing else then scanning what is already in the local archive and base the list on this. This way packages need to be accepted only once and will be updated automatically with$REPREPRO updatewhich is called from cron.

Now you'd want to add a cron job which calls $REPREPRO update and probably updates this list.

Thats it. Now basically all you need to do is add a package to the reprepro archive via

$REPREPRO include etch-backports <package>.deb

and configure the mirror in your clients. They will install the packages automatically, because the bpo version is usually higher as the one in Stable. If you configured cron you will receive updates automaticallly. This can be paired with CRON-APT for example.