APT's Default-Release setting (aka apt-get
--target-release
) is useful if your /etc/apt/sources.list file contains
exactly 2 releases (such as stable and testing, or testing and
unstable). If you want to track more than 2 releases (stable, testing,
and unstable, or two of those plus a non-Debian source), it has
problems. This document explains how to do better. Updates can be
found at http://www.argon.org/~roderick/apt-pinning.html.
First, here are some reasonable /etc/apt/preferences
files for the common cases. The rest of this document describes what
these are doing.
Explanation: see http://www.argon.org/~roderick/apt-pinning.html Package: * Pin: release o=Debian,a=stable Pin-Priority: 900 Package: * Pin: release o=Debian,a=testing Pin-Priority: 400 Package: * Pin: release o=Debian,a=unstable Pin-Priority: 300 Package: * Pin: release o=Debian Pin-Priority: -1
Explanation: see http://www.argon.org/~roderick/apt-pinning.html Package: * Pin: release o=Debian,a=testing Pin-Priority: 900 Package: * Pin: release o=Debian,a=unstable Pin-Priority: 300 Package: * Pin: release o=Debian Pin-Priority: -1
When you run "apt-get -t unstable install foo", this sets APT::Default-Release for this invocation of apt-get, but it doesn't affect future runs. This is useful in some circumstances, but problematic in others.
Say you've got testing and unstable in your sources.list, an APT::Default-Release of "testing" in apt.conf, no /etc/apt/preferences, and a package foo which is available from the releases like this:
release | version | priority | ||
---|---|---|---|---|
no -t switch | -t unstable | |||
testing | 1.1 | 990 | 500 | |
unstable | 1.2 | 500 | 990 |
If foo isn't installed and you run "apt-get install foo" you get version 1.1 from testing, since that version has the highest priority.
If you run "apt-get -t unstable install foo" instead you get version 1.2 from unstable, since the -t switch temporarily causes that version to have the highest priority.
foo will temporarily track unstable. If version 1.3 is uploaded to unstable while 1.1 is still in testing, we have:
release | version | priority |
---|---|---|
installed | 1.2 | 100 |
testing | 1.1 | 990 |
unstable | 1.3 | 500 |
The highest priority version is 1.1, but this is lower than the installed 1.2. Since the priority of 1.1 is 990 (which is lower than 1000), apt-get will not downgrade to it. The next highest priority is 1.3 at 500. Since this is greater than the installed 1.2, it is selected.
foo will stop tracking unstable as soon as testing gets a version which is as new as the version which is currently installed. Say that version 1.3 migrates from unstable to testing, and then 1.4 is uploaded to unstable:
release | version | priority |
---|---|---|
installed | 1.3 | 100 |
testing | 1.3 | 990 |
unstable | 1.4 | 500 |
Since the unstable 1.4 version now has a lower priority than the installed version, foo is not upgraded to it. Often this is what you want.
APT::Default-Release's behavior works well when you're only tracking two different releases, but with 3 or more it starts to go wrong. When you install a package from 1 of the non-default releases, it can be immediately replaced with a newer version from another of them.
Consider:
release | version | priority | ||
---|---|---|---|---|
APT::Default-Release | above /etc/apt/preferences | |||
stable | 1.0 | 990 | 900 | |
testing | 1.1 | 500 | 400 | |
unstable | 1.2 | 500 | 300 |
With an APT::Default-Release of "stable" and no /etc/apt/preferences, if you install the package with "apt-get -t testing install foo" you'll get version 1.1 from testing.
The big problem happens when you run "apt-get upgrade": Version 1.2 from unstable has the same priority as the 1.1 just installed, so 1.1 (testing) is replaced with 1.2 (unstable)!
I fix this problem by giving testing and unstable different priorities. With the explicit PINs from the above /etc/apt/preferences, version 1.2 from unstable has priority 300 compared to testing's 400, so the version from testing remains installed.
The pin of other Debian releases at priority -1 is only a bit of defensiveness. This doesn't affect any Debian sources that I know of (since they're all stable, testing, or unstable), so if a new Debian source is added I'll have to decide what priority to give it. Without this pin it'd come in at the default priority of 500.
If you're using non-Debian sources, you've got the same problem, only more so because there's no natural ordering as there is with Debian's stable -> testing -> unstable. Without explicitly listing them in /etc/apt/preferences, they're all at priority 500, so a package installed from one source can be replaced by a higher version supplied by a different source.
A partial fix for this is to pin each source at a different priority. Eg,
Package: * Pin: origin www.debian-multimedia.org Pin-Priority: 600 Package: * Pin: origin www.ibiblio.org Pin-Priority: 610 Package: * Pin: origin www.argon.org Pin-Priority: 620
These settings would mean that a package installed from www.argon.org wouldn't automatically be replaced with one from the other two, and one from www.ibiblio.org wouldn't be replaced with one from www.debian-multimedia.org.
Working in the other direction the packages would still be replaced, however: If you've installed a package from www.ibiblio.org and a newer version becomes available from www.argon.org, apt-get will upgrade to it. The only way I know of to prevent that is to explicitly pin the package to the source via /etc/apt/preferences.
Roderick Schertler <roderick@argon.org>
http://www.argon.org/~roderick/