April 16, 2012

Managing mixed Debian packages using APT pinning

I use Debian “stable” as my primary Linux OS. Anyone using Debian stable would know that getting the latest and greatest package you need is a bit of a nuisance. If you are in this situation, i.e. looking to upgrade just a package from a different repository, here is how to do it.

APT pinning is a way to have a mixed package system (i.e. packages installed from different repositories) and provide an easy upgrade path to those packages in an automated and predictable way.

If you are doing this on a production box, make sure you have tried it somewhere else, as you might put your system in disarray if you are not cautious.

  1. /etc/apt - main location for everything related to APT

  2. /etc/apt/apt.conf - main configuration file. Note: This could not be on your system if you are not adventurous enough. If it doesn’t exist, go ahead and create it. APT reads this file if it’s present.

  3. /etc/apt/sources.list - repository configuration is kept in this file.

  4. /etc/apt/apt.conf.d/* - split configuration files added by individual programs. This is to separate things specific to the program, which was added to help with easy upgrade paths.

  5. /etc/apt/preferences - main preference file. Note: This could not be on your system. Again, this is read if it’s present.

  6. /etc/apt/preferences.d/* - split preference file could be for each package or each repository, again, it’s up to you on how you would like to manage.

I would be explaining APT pinning with an example, as it makes for a better understanding.  Here is my scenario: I would like to update a package forked-daapd from version 0.12 in Debian stable at the time of this writing to version 0.19 from backports. In addition to that, I would like all new versions of “forked-daapd” (from backports) to be upgraded as part of my normal system upgrade process.

forked-daapd is a DAAP streaming server to stream media to any DAAP compatible player (iTunes) or a device.

Since we are upgrading from a backport, we would be pulling only the package forked-daapd, and the rest of the dependencies will be satisfied by the stable repository. This might not be the case with the package you are looking to upgrade, so check your package dependencies and make sure it won’t be upgrading the ones that are already installed on your system.

rant

Most packages on Linux are built with some sort of dependent libraries. The majority of libraries are installed and managed independently of the application that uses them, and hence upgrading just the library to a newer version might break the existing application. For example, say we install an application ‘A’ which depends on a library ‘L’. So when application ‘A’ is being installed, library ‘L’ would be installed as a dependency. Later down the line, if we want to install another application, say ‘B’, which also depends on the same library as application ‘A’. During the installation of ‘B’, APT sees that the library ‘L’ is installed already and skips the installation of the library. So at this point, you have two applications, ‘A’ & ‘B’, depending on the same library ‘L’. If at this point, the library ‘L’ is being upgraded because of the installation of a new package from a different source, chances are it would break the existing applications ‘A’ & ‘B’ (assuming that there is no backwards compatibility in the upgraded versions of the library). Hence, it’s advisable to check each dependency that’s being pulled from another repository during APT pinning.

Here are the steps to achieve the described scenario

  1. Add backports repository to /etc/apt/sources.list
    # squeeze backports  
    deb http://www.backports.org/debian/ squeeze-backports main contrib non-free

Defines the backports repository. As a rule, remember to run update (see next step) after changing the sources.list to get the latest indexes from the predefined repository and update the local cache.

  1. Let’s update to make APT aware of the latest packages and their sources
    $ apt-get update
  1. Verify APT can see both versions of the package, i.e. 0.12 and 0.19
    $ apt-cache show forked-daapd
  1. Amend /etc/apt/apt.conf and comment out the line beginning with APT::Default-Release, this is to make sure the priorities that we define work as it should. If the apt.conf file doesn’t exist, then don’t bother with this step.

It’s recommended to comment the line APT::Default-Release, which interferes with our priorities in case we have more than 2 repositories defined. In a default stable install, we usually get two repositories defined for us, i.e. stable and stable-updates. Adding the backports becomes third and hence it’s better to control priorities ourselves rather than the tool (assuming we know what we are doing). I had a lot of grief having this option, hence, I prefer controlling through preferences.

  1. Manually define our release priorities by adding the following line to /etc/apt/preferences file
    Package: *  
    Pin: release o=Debian,a=stable  
    Pin-Priority: 900  
    Package: *  
    Pin: release o=Debian,a=stable-updates  
    Pin-Priority: 900  
    Package: *  
    Pin: release a=squeeze-backports  
    Pin-Priority: 890

Lays out preferences for each release. Again, the higher the number, the higher the priority, basic stuff.

  1. Create a new file forked-daapd under /etc/preferences.d/ with the following content
    Package: forked-daapd  
    Pin: release a=squeeze-backports  
    Pin-Priority: 910

Adding package of choice “forked-daapd” and bump up the number than the stable release number, in this case more > 900.

  1. Run update again as in Step 4 to make aware of all changes to APT

  2. Check using policy if the latest package gets picked up

    $ apt-get policy forked-daapd 
    forked-daapd:  
    Installed: (none)  
    Candidate: 0.19-1~bpo60+1  
    Package pin: 0.19-1~bpo60+1  
    Version table:  
    0.19-1~bpo60+1 910  
    890 http://www.backports.org/debian/ squeeze-backports/main amd64 Packages 
    0.12~git0.11-125-gca72ee5-3 910  
    900 http://ftp.uk.debian.org/debian/ squeeze/main amd64 Packages

Candidate line, which tells us what’s going to be installed.

  1. Install forked-daapd should install the 0.19 version of the package, and the rest of the dependencies will be pulled in from the stable release.
    $ apt-get install forked-daapd

I spent quite some time understanding APT-Pinning and hope this helps someone looking for the same. I read the following articles to better my understanding.

Further Reading:

© Nataraj Basappa 2025