Browse Source

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.
tags/debian/1.8.0_rc1
Julian Andres Klode 2 years ago
parent
commit
8bb2a91a07
2 changed files with 82 additions and 6 deletions
  1. +20
    -3
      apt-pkg/policy.cc
  2. +62
    -3
      test/integration/test-policy-pinning

+ 20
- 3
apt-pkg/policy.cc View File

@@ -38,6 +38,8 @@

using namespace std;

constexpr 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
@@ -107,7 +109,7 @@ bool pkgPolicy::InitDefaults()
pkgVersionMatch Match(I->Data,I->Type);
for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
{
if (Fixed[F->ID] == false && Match.FileMatch(F) == true)
if ((Fixed[F->ID] == false || I->Priority == NEVER_PIN) && PFPriority[F->ID] != NEVER_PIN && Match.FileMatch(F) == true)
{
PFPriority[F->ID] = I->Priority;

@@ -271,7 +273,14 @@ APT_PURE signed short pkgPolicy::GetPriority(pkgCache::PkgIterator const &Pkg)
APT_PURE signed short pkgPolicy::GetPriority(pkgCache::VerIterator const &Ver, bool ConsiderFiles)
{
if (VerPins[Ver->ID].Type != pkgVersionMatch::None)
return VerPins[Ver->ID].Priority;
{
// If all sources are never pins, the never pin wins.
if (VerPins[Ver->ID].Priority == NEVER_PIN)
return NEVER_PIN;
for (pkgCache::VerFileIterator file = Ver.FileList(); file.end() == false; file++)
if (GetPriority(file.File()) != NEVER_PIN)
return VerPins[Ver->ID].Priority;
}
if (!ConsiderFiles)
return 0;

@@ -388,9 +397,17 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
for (; Word != End && isspace(*Word) != 0; Word++);

_error->PushToStack();
int const priority = Tags.FindI("Pin-Priority", 0);
std::string sPriority = Tags.FindS("Pin-Priority");
int priority = sPriority == "never" ? NEVER_PIN : Tags.FindI("Pin-Priority", 0);
bool const newError = _error->PendingError();
_error->MergeWithStack();

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 < std::numeric_limits<short>::min() ||
priority > std::numeric_limits<short>::max() ||
newError) {


+ 62
- 3
test/integration/test-policy-pinning View File

@@ -315,15 +315,16 @@ testsuccessequal "coolstuff:
Installed: 2.0~bpo1
Candidate: $2
Version table:
2.0~bpo2 $1
$1 file:${tmppath}/aptarchive backports/main all Packages
2.0~bpo2 ${3:-$1}
${3:-$1} file:${tmppath}/aptarchive backports/main all Packages
*** 2.0~bpo1 100
100 ${tmppath}/rootdir/var/lib/dpkg/status
1.0 500
500 file:${tmppath}/aptarchive stable/main all Packages" apt policy coolstuff
}
currentpin '32767' '2.0~bpo2'
currentpin '-32768' '2.0~bpo1'
currentpin '-32768' '2.0~bpo1' '-32767'
currentpin '-32767' '2.0~bpo1' '-32767'

# Check for 0
echo "Package: coolstuff
@@ -359,3 +360,61 @@ testsuccessequal "coolstuff:
100 ${tmppath}/rootdir/var/lib/dpkg/status
1.0 500
500 file:${tmppath}/aptarchive stable/main all Packages" aptcache policy coolstuff


# Check for override pins

# 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
Version table:
2.0~bpo2 990
100 file:${tmppath}/aptarchive backports/main all Packages
*** 2.0~bpo1 100
100 ${tmppath}/rootdir/var/lib/dpkg/status
1.0 500
500 file:${tmppath}/aptarchive stable/main all Packages" aptcache policy coolstuff


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
Version table:
2.0~bpo2 -32768
-32768 file:${tmppath}/aptarchive backports/main all Packages
*** 2.0~bpo1 100
100 ${tmppath}/rootdir/var/lib/dpkg/status
1.0 500
500 file:${tmppath}/aptarchive stable/main all Packages" aptcache policy coolstuff




# Check for 0
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

Loading…
Cancel
Save