summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2018-12-03 17:18:18 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2019-03-01 11:40:29 +0000
commit54e1ee73059bbad881908028abce574039ec77b9 (patch)
treeb54d002035e1cf71499221288028a99d6f6a86b9
parentdd05bdac89acbe96103b0f0ca488c9aba106d1ee (diff)
Introduce experimental 'never' pinning for sources
This allows disabling a repository by pinning it to 'never', which is internally translated to a value of -32768 (or whatever the minimum of short is). This overrides any other pin for that repository. It can be used to make sure certain sources are never used; for example, in unattended-upgrades. To prevent semantic changes to existing files, we substitute min + 1 for every pin-priority: <min>. This is a temporary solution, as we are waiting for an ABI break. To add pins with that value, the special Pin-Priority "never" may be used for now. It's unclear if that will persist, or if the interface will change eventually. (similar to commit 8bb2a91a070170d7d8e71206d1c66a26809bdbc3) LP: #1814727
-rw-r--r--apt-pkg/policy.cc44
-rw-r--r--test/integration/framework13
-rwxr-xr-xtest/integration/test-policy-pinning105
3 files changed, 159 insertions, 3 deletions
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc
index 3cfc32829..a44bd7efe 100644
--- a/apt-pkg/policy.cc
+++ b/apt-pkg/policy.cc
@@ -18,7 +18,8 @@
500 = Default package files
100 = The status file and ButAutomaticUpgrades sources
0 -> 100 = NotAutomatic sources like experimental
- -inf -> 0 = Never selected
+ -inf -> 0 = Never selected
+ –32768 = Never selected, overrides everything else
##################################################################### */
/*}}}*/
@@ -50,6 +51,8 @@
using namespace std;
+static const short NEVER_PIN = std::numeric_limits<short>::min();
+
// Policy::Init - Startup and bind to a cache /*{{{*/
// ---------------------------------------------------------------------
/* Set the defaults for operation. The default mode with no loaded policy
@@ -115,7 +118,7 @@ bool pkgPolicy::InitDefaults()
pkgVersionMatch Match(I->Data,I->Type);
for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
{
- if (Match.FileMatch(F) == true && Fixed[F->ID] == false)
+ if (Match.FileMatch(F) == true && (Fixed[F->ID] == false || I->Priority == NEVER_PIN))
{
if (I->Priority != 0 && I->Priority > 0)
Cur = I->Priority;
@@ -162,6 +165,24 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk
if (Max < 0)
return Pkg.CurrentVer();
+ // If the package specific-pin refers to a version that is only available from
+ // never sources, ignore it.
+ if (!Pref.end())
+ {
+ bool AllNever = true;
+ for (pkgCache::VerFileIterator VF = Pref.FileList(); VF.end() == false; ++VF)
+ {
+ if ((VF.File()->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource)
+ continue;
+
+ if (PFPriority[VF.File()->ID] != NEVER_PIN)
+ AllNever = false;
+ }
+
+ if (AllNever)
+ Pref = pkgCache::VerIterator(*Pkg.Cache());
+ }
+
/* Falling through to the default version.. Setting Max to zero
effectively excludes everything <= 0 which are the non-automatic
priorities.. The status file is given a prio of 100 which will exclude
@@ -194,7 +215,12 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk
instVer == false)
continue;
+
signed Prio = PFPriority[VF.File()->ID];
+
+ // A package file pinned to NEVER_PIN can never be a candidate.
+ if (Prio == NEVER_PIN && instVer == false)
+ continue;
if (Prio > Max)
{
Pref = Ver;
@@ -446,7 +472,19 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
}
for (; Word != End && isspace(*Word) != 0; Word++);
- short int priority = Tags.FindI("Pin-Priority", 0);
+ std::string sPriority = Tags.FindS("Pin-Priority");
+ short int priority = sPriority == "never" ? NEVER_PIN : Tags.FindI("Pin-Priority", 0);
+
+ if (sPriority == "never" && not Name.empty())
+ return _error->Error(_("%s: The special 'Pin-Priority: %s' can only be used for 'Package: *' records"), File.c_str(), "never");
+
+ // Silently clamp the never pin to never pin + 1
+ if (priority == NEVER_PIN && sPriority != "never")
+ priority = NEVER_PIN + 1;
+
+ if (priority == 0 && Tags.FindS("Pin-Priority") == "never") {
+ priority = NEVER_PIN;
+ }
if (priority == 0)
{
_error->Warning(_("No priority (or zero) specified for pin"));
diff --git a/test/integration/framework b/test/integration/framework
index 62d3a8386..38f08a59b 100644
--- a/test/integration/framework
+++ b/test/integration/framework
@@ -1148,6 +1148,19 @@ testfailure() {
fi
}
+testsuccessequal() {
+ local CMP="$1"
+ shift
+ testsuccess "$@"
+ testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/testsuccess.output" "$CMP"
+}
+testfailureequal() {
+ local CMP="$1"
+ shift
+ testfailure "$@"
+ testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailure.output" "$CMP"
+}
+
testwebserverlaststatuscode() {
local DOWNLOG='rootdir/tmp/webserverstatus-testfile.log'
local STATUS='rootdir/tmp/webserverstatus-statusfile.log'
diff --git a/test/integration/test-policy-pinning b/test/integration/test-policy-pinning
index 8eb4bcbad..6ee39077a 100755
--- a/test/integration/test-policy-pinning
+++ b/test/integration/test-policy-pinning
@@ -12,6 +12,7 @@ setupflataptarchive
STATUS=$(readlink -f rootdir/var/lib/dpkg/status)
APTARCHIVE=$(readlink -f aptarchive)
+tmppath=$(readlink -f .)
testequalpolicy() {
local SP="$1"
@@ -261,3 +262,107 @@ aptgetupdate
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo2" 100 500 0 "" "2.0~bpo2" -o Test=ButAutomaticUpgrades
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo2" 100 990 0 "" "2.0~bpo2" -o Test=ButAutomaticUpgrades -t stable
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo2" 990 500 0 "" "2.0~bpo2" -o Test=ButAutomaticUpgrades -t backports
+
+
+
+msgmsg "Check that short-max/min is a valid pin"
+currentpin() {
+echo "Package: *
+Pin: release n=backports
+Pin-Priority: $1
+" > rootdir/etc/apt/preferences
+testsuccessequal "coolstuff:
+ Installed: 2.0~bpo1
+ Candidate: ${2}
+ Version table:
+ 2.0~bpo2 0
+ ${3:-$1} file:${tmppath}/aptarchive/ backports/main i386 Packages
+ *** 2.0~bpo1 0
+ 100 ${tmppath}/rootdir/var/lib/dpkg/status
+ 1.0 0
+ 500 file:${tmppath}/aptarchive/ stable/main i386 Packages" aptcache policy coolstuff
+}
+
+currentpin '32767' '2.0~bpo2'
+currentpin '-32768' '2.0~bpo1' '-32767'
+currentpin '-32767' '2.0~bpo1' '-32767'
+
+
+msgmsg "Check for override pins"
+
+msgmsg "Normal pins: First one wins"
+echo "Package: coolstuff
+Pin: release n=backports
+Pin-Priority: 990
+
+Package: coolstuff
+Pin: release n=backports
+Pin-Priority: 991
+" > rootdir/etc/apt/preferences
+testsuccessequal "coolstuff:
+ Installed: 2.0~bpo1
+ Candidate: 2.0~bpo2
+ Package pin: 2.0~bpo2
+ Version table:
+ 2.0~bpo2 990
+ 100 file:${tmppath}/aptarchive/ backports/main i386 Packages
+ *** 2.0~bpo1 990
+ 100 ${tmppath}/rootdir/var/lib/dpkg/status
+ 1.0 990
+ 500 file:${tmppath}/aptarchive/ stable/main i386 Packages" aptcache policy coolstuff
+
+msgmsg "Never pins: Never wins over package-specific"
+echo "Package: coolstuff
+Pin: release n=backports
+Pin-Priority: 990
+
+Package: *
+Pin: release n=backports
+Pin-Priority: never
+" > rootdir/etc/apt/preferences
+
+testsuccessequal "coolstuff:
+ Installed: 2.0~bpo1
+ Candidate: 2.0~bpo1
+ Package pin: 2.0~bpo2
+ Version table:
+ 2.0~bpo2 990
+ -32768 file:${tmppath}/aptarchive/ backports/main i386 Packages
+ *** 2.0~bpo1 990
+ 100 ${tmppath}/rootdir/var/lib/dpkg/status
+ 1.0 990
+ 500 file:${tmppath}/aptarchive/ stable/main i386 Packages" aptcache policy coolstuff
+
+msgmsg "Never pins: Never wins over other"
+echo "Package: *
+Pin: release n=backports
+Pin-Priority: 990
+
+Package: *
+Pin: release n=backports
+Pin-Priority: never
+" > rootdir/etc/apt/preferences
+
+testsuccessequal "coolstuff:
+ Installed: 2.0~bpo1
+ Candidate: 2.0~bpo1
+ Version table:
+ 2.0~bpo2 0
+ -32768 file:${tmppath}/aptarchive/ backports/main i386 Packages
+ *** 2.0~bpo1 0
+ 100 ${tmppath}/rootdir/var/lib/dpkg/status
+ 1.0 0
+ 500 file:${tmppath}/aptarchive/ stable/main i386 Packages" aptcache policy coolstuff
+
+
+
+
+msgmsg "Check for package-specific never pin"
+echo "Package: coolstuff
+Pin: release n=backports
+Pin-Priority: never
+" > rootdir/etc/apt/preferences
+
+testfailureequal "Reading package lists...
+E: ${tmppath}/rootdir/etc/apt/preferences: The special 'Pin-Priority: never' can only be used for 'Package: *' records" \
+ aptget install -s coolstuff -o PinPriority=0