A Short Introduction To Apt-Pinning

Version 1.0
Author: Falko Timme
Last edited 03/08/2009

This article is a short overview of how to use apt-pinning on Debian and Debian-based distributions (like Ubuntu). Apt-Pinning allows you to use multiple releases (e.g. stable, testing, and unstable) on your system and to specify when to install a package from which release. That way you can run a system based mostly on the stable release, but also install some newer packages from testing or unstable (or third-party repositories).

I do not issue any guarantee that this will work for you!

 

1 Preliminary Note

I'm using a Debian Lenny (stable) system here. I will explain apt-pinning on the basis of the package phpmyadmin which is available in three different versions in the stable, testing, and unstable repositories (at the time of this writing) - see http://packages.debian.org/search?keywords=phpmyadmin&searchon=names&suite=all&section=all:

  • lenny (stable): version 4:2.11.8.1-5
  • squeeze (testing): version 4:3.1.2-2
  • sid (unstable): version 4:3.1.3-1

 

2 My sources.list

I add the testing and unstable repositories to my /etc/apt/sources.list so that it looks as follows:

vi /etc/apt/sources.list

deb http://volatile.debian.org/debian-volatile lenny/volatile main
deb-src http://volatile.debian.org/debian-volatile lenny/volatile main

## Lenny / Stable
deb http://ftp2.de.debian.org/debian/ lenny main
deb-src http://ftp2.de.debian.org/debian/ lenny main

deb http://security.debian.org/ lenny/updates main
deb-src http://security.debian.org/ lenny/updates main

## Squeeze / Testing
deb http://ftp2.de.debian.org/debian/ squeeze main
deb-src http://ftp2.de.debian.org/debian/ squeeze main

deb http://security.debian.org/ squeeze/updates main
deb-src http://security.debian.org/ squeeze/updates main

## Sid / Unstable
deb http://ftp2.de.debian.org/debian/ sid main
deb-src http://ftp2.de.debian.org/debian/ sid main

Open /etc/apt/apt.conf...

vi /etc/apt/apt.conf

... and put the following line into it:

APT::Cache-Limit "100000000";

(Otherwise you might get an error like this one when running apt-get update:

E: Dynamic MMap ran out of room

)

Then run

apt-get update

to update the package database.

With the current version, apt would always try to install the newest version of a package which usually comes from unstable or testing - this could lead to a messed-up system. With apt-pinning, we can define priorities so that a package gets installed from unstable or testing only if there's no such package from stable.

We can check apt priorities as follows:

apt-cache policy

server1:~# apt-cache policy
Package files:
 100 /var/lib/dpkg/status
     release a=now
 500 http://volatile.debian.org lenny/volatile/main Packages
     release o=volatile.debian.org,a=stable,l=debian-volatile,c=main
     origin volatile.debian.org
 500 http://ftp2.de.debian.org sid/main Packages
     release o=Debian,a=unstable,l=Debian,c=main
     origin ftp2.de.debian.org
 500 http://security.debian.org squeeze/updates/main Packages
     release v=None,o=Debian,a=testing,l=Debian-Security,c=main
     origin security.debian.org
 500 http://ftp2.de.debian.org squeeze/main Packages
     release o=Debian,a=testing,l=Debian,c=main
     origin ftp2.de.debian.org
 500 http://security.debian.org lenny/updates/main Packages
     release v=5.0,o=Debian,a=stable,l=Debian-Security,c=main
     origin security.debian.org
 500 http://ftp2.de.debian.org lenny/main Packages
     release v=5.0,o=Debian,a=stable,l=Debian,c=main
     origin ftp2.de.debian.org
Pinned packages:
server1:~#

As you see, stable, testing, and unstable all have the same priority (500) which means that the newest version of a package would be installed. In the case of our phpmyadmin package this is version 4:3.1.3-1 which is from unstable:

apt-cache policy phpmyadmin

The Candidate: line shows the version that would be installed:

server1:~# apt-cache policy phpmyadmin
phpmyadmin:
  Installed: (none)
  Candidate: 4:3.1.3-1
  Version table:
     4:3.1.3-1 0
        500 http://ftp2.de.debian.org sid/main Packages
     4:3.1.2-2 0
        500 http://ftp2.de.debian.org squeeze/main Packages
     4:2.11.8.1-5 0
        500 http://ftp2.de.debian.org lenny/main Packages
server1:~#

This is how priorities are defined (see

man 5 apt_preferences

):

P > 1000
    causes a version to be installed even if this constitutes a downgrade of the package

990 < P <=1000
    causes a version to be installed even if it does not come from the target release, unless the installed version is more recent

500 < P <=990
    causes a version to be installed unless there is a version available belonging to the target release or the installed version is more recent

100 < P <=500
    causes a version to be installed unless there is a version available belonging to some other distribution or the installed version is more recent

0 < P <=100
    causes a version to be installed only if there is no installed version of the package

P < 0
    prevents the version from being installed

Share this page:

3 Comment(s)

Add comment

Comments

From: Anonymous at: 2010-06-04 15:53:06

I'd just like to point out that if you have set APT::Default-Release in apt.conf it will prevent pinning. This behaviour was not exactly obvious to me.

 

From: Rz at: 2009-03-25 15:53:21

Excellent tutorial, very clear. Thanks.

From: Jim at: 2009-03-26 16:18:15

Hi,

One pitfall is described in the apt_preferences manpage:

"Sometimes the installed version of a package is more recent than the version belonging to the target release, but not as recent as a version belonging to some other distribution. Such a package will indeed be upgraded when apt-get install some-package or apt-get upgrade is executed, because at least one of the available versions has a higher priority than the installed version"

In other words, assume you used your priorities:

stable = 700
testing = 650
unstable = 600

Now assume you installed "foo" from unstable once, but then unstable got updated again, so the following package versions exist:

foo = 1.0 (stable)
foo = 1.1 (testing)
foo = 1.2 (installed version)
foo = 1.3 (unstable)

Now, if you do an "apt-get upgrade", you will end up installing foo from unstable, because version 1.3 has priority 600 while the installed version only has the default (unchangable) priority 100.  I never want "apt-get upgrade" to automatically go to an unstable version like this, even if I manually installed the unstable version once.  To avoid this, I like to set my priorities to something like

stable = 200
testing = 80
unstable = 50

This means: Upgrade any installed package (prio 100) to the "stable" version automatically, but never upgrade to "testing" or "unstable" unless I specify it manually.