In Debian and Ubuntu (and other Debian based distributions) you can use the /etc/apt/preferences file to maintain the various repositories. In the preferences file you can define whether packages should be installed from a certain repository defined in /etc/apt/sources.list and/or /etc/apt/sources.list.d/*.list. I will use Debian in my examples and will mention Ubuntu if it requires some extra attention.
Why would one use the preferences file?
Good question. I started using it when I wanted to install a teamspeak server on Debian Etch (the stable release back then) and the package was only available in Debian Lenny (testing). I do not download packages manually, I prefer apt to take care of it. But when I added the Lenny repositories I would upgrade my machine to testing, which is something I did not want to do. The preferences file allows you to mix your system, or to tell apt in which cases may be upgraded (or not).
How does it work?
Normally, without a preferences file all packages/repositories have a priority of 500, installed packages have a priority of a 100.
In Debian you can define a default/target release, eg lenny, APT::Default-Release “lenny”;. This will make sure packages from that release get a priority of 990. You can set the default release in /etc/apt/apt.conf. Doing this in Ubuntu is rather useless. The Ubuntu repositories are CODENAME-(updates|security|proposed|backports), and the default release doesn’t include these repositories. Because of this I don’t use this directive. I set the 990 priority in my preferences file (more on these numbers later).
You can look at the priorities of your repositories by running apt-cache policy or apt-cache policy packagename.
$ apt-cache policy hello hello: Installed: (none) Candidate: 2.2-2 Version table: 2.4-3 0 500 ftp://ftp.nl.debian.org testing/main Packages 500 ftp://ftp.nl.debian.org unstable/main Packages 2.2-2 0 990 ftp://ftp.nl.debian.org lenny/main Packages
How does this influence package installations?
Apt determines normally based on the version of a package whether it should be installed. So if you have a repository which has an higher version of an installed package it will install that package. But now we have told apt what our default release is, apt will only update/install packages from that repository with the exception of packages which are not present on your default release repositories. If you track multiple repositories the default release alone will not be enough, and that is where the preferences files comes in. You can find the preferences file at /etc/apt/preferences, or not since it is doesn’t exist by default. In newer versions of apt you can also find the /etc/apt/preferences.d/ directory. The concept is similar to /etc/apt/sources.list and /etc/apt/sources.list.d. If you are using aptitude, please be aware that /etc/apt/preferences.d/* is ignored. The bug is now resolved in aptitude version 0.6.3-3.2 (
apt-cache policy aptitude will show you the installed version) which is available in Debian Squeeze and Ubuntu Natty (11.04).
In the preferences file you can tell apt how to deal with various repositories, eg mixing releases or using PPA’s with Ubuntu.
This would be my default preferences file if I would be running Debian stable. Please note that apt now supports # as comments, normally one would use Explanation: .
# Give preference to stable, then testing and finally unstable # a=stable,n=lenny could also be a=stable, but you don't want to upgrade # stable once testing becomes stable without you knowing about it. # If you use testing/unstable feel free to pick any # # Ubuntu users can use a=CODENAME, where codename is # dapper, hardy, intrepid, jaunty, karmic and all CODENAME-repos, # eg hardy-updates, hardy-security, hardy-backports and hardy-proposed # Package: * Pin: release a=stable,n=lenny Pin-Priority: 990 Package: * Pin: release a=testing Pin-Priority: 600 Package: * Pin: release a=unstable Pin-Priority: 300
When running testing, I would set lenny to 300, testing to 990 and unstable to 600. If you wonder what the numbers mean, I’ve copied this from the apt_preferences(5) man page
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
You can also pin packages from specific releases or versions.
Package: hello Pin: release n=lenny Pin-Priority: 995 # Or to a specific version Package: hello Pin: version 2.2-2 Pin-Priority: 990 # Or to anything in version 2.2, eg 2.2-4 Package: hello Pin: version 2.2* Pin-Priority: 990
You can see this here:
hello: Installed: (none) Candidate: 2.2-2 Package pin: 2.2-2 Version table: 2.4-3 990 600 ftp://ftp.nl.debian.org testing/main Packages 990 ftp://ftp.nl.debian.org unstable/main Packages 2.2-2 990 990 ftp://ftp.nl.debian.org lenny/main Packages
Setting a package to a Pin-Priority above 1000 you will force a downgrade of a package when the version you want to be installed has a lower version then the currently installed package. If you do this, please execute aptitude -s install PACKAGENAME to see the consequences of that action. Please note that the package version pin preference is present on all versions, see this debian bug comment for more information.
Third party repositories could interfere with your regular preferences file, it will update packages which you don’t want to update. To remedy this, you can use apt-cache policy to determine some information about the repository.
$ apt-cache policy # truncated for readability 500 http://ppa.launchpad.net jaunty/main Packages release v=9.04,o=LP-PPA-ultrafredde,a=jaunty,n=jaunty,l=Ubuntu,c=main origin ppa.launchpad.net
# Everything from launchpad Package: * Pin: origin ppa.launchpad.net Pin-Priority: 600 # One particular PPA Package: * Pin: release o=LP-PPA-ultrafredde Pin-Priority: 600
You can now install packages and be sure they are not upgraded when you don’t want them to. Just fiddle with your preferences file and you can mix and match your system to your liking.
If you want to install packages which would normally not be installed, you can force aptitude to install other versions:
# Based on version, will install regardless of preferences file (assume prio 999) aptitude install hello=2.4-3 # Based on release, will install with prio 990 aptitude install -t stable hello # Based on release, will install regardless of preferences file (assume prio 999) aptitude install hello/testing
We are now going to deny package installations from all launchpad origins but allow task to be installed. Task comes from a launchpad PPA.
# Deny everything from launchpad Package: * Pin: origin ppa.launchpad.net Pin-Priority: -10 # Allow task Package: task Pin: origin ppa.launchpad.net Pin-priority: 990 # Or based on the PPA itself: Package: task Pin: release o=LP-PPA-ultrafredde Pin-priority: 990
With 3 small lines you can maintain a mixed system, Ubuntu 8.10 mixed with some 9.04 or Debian testing with unstable, or the otherway around. You can add PPA’s without having to worry about if it will update packages that you don’t want to be upgraded.