summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2016-11-23 19:02:51 +0100
committerJulian Andres Klode <jak@debian.org>2017-02-22 16:53:45 +0100
commit44c0cf26f9768787ae2ba3e981e862f497c3df30 (patch)
tree0042027d986951259f84259fb858203928a0332f
parentb75c6dc6018ce22a7419911a66e994e502c4497f (diff)
don't perform implicit crossgrades involving M-A:same
dpkg stumbles over these (#844300) and we haven't dropped 'easier' removes to be implicit and to be scheduled by dpkg by default so far so we shouldn't push the decision in such cases to dpkg either. (cherry picked from commit 53f3fc59f4eb37eea57bbde53fb75f2e15af0378)
-rw-r--r--apt-pkg/deb/dpkgpm.cc25
-rwxr-xr-xtest/integration/test-crossgrades32
2 files changed, 50 insertions, 7 deletions
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index abf91fe2a..d76b59449 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -1525,11 +1525,30 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
continue;
auto const Grp = I->Pkg.Group();
- size_t installedInstances = 0;
+ size_t installedInstances = 0, wannabeInstances = 0;
+ bool multiArchInstances = false;
for (auto Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg))
- if (Pkg->CurrentVer != 0 || Cache[Pkg].Install())
+ {
+ if (Pkg->CurrentVer != 0)
+ {
++installedInstances;
- if (installedInstances == 2)
+ if (Cache[Pkg].Delete() == false)
+ ++wannabeInstances;
+ }
+ else if (PackageOps.find(Pkg.FullName()) != PackageOps.end())
+ ++wannabeInstances;
+ if (multiArchInstances == false)
+ {
+ auto const V = Cache[Pkg].InstVerIter(Cache);
+ if (V.end() == false && (Pkg->CurrentVer == 0 || V != Pkg.CurrentVer()))
+ multiArchInstances = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same);
+ }
+ }
+ /* theoretically the installed check would be enough as some wannabe will
+ be first and hence be the crossgrade we were looking for, but #844300
+ prevents this so we keep these situations explicit removes.
+ It is also the reason why neither of them can be a M-A:same package */
+ if (installedInstances == 1 && wannabeInstances == 1 && multiArchInstances == false)
{
auto const FirstInstall = std::find_if_not(I, List.end(),
[](Item const &i) { return i.Op == Item::Remove || i.Op == Item::Purge; });
diff --git a/test/integration/test-crossgrades b/test/integration/test-crossgrades
index 30195d30f..6398e7e7f 100755
--- a/test/integration/test-crossgrades
+++ b/test/integration/test-crossgrades
@@ -26,8 +26,24 @@ singleinstance() {
testdpkgnotinstalled 'crosser:i386' 'unrelated'
testdpkginstalled 'crosser:amd64'
- testsuccess apt purge crosser:amd64 -y --planner $1
- testdpkgnotinstalled 'crosser:amd64'
+ testsuccess apt install crosser:armel=3 -y -o Debug::pkgDpkgPm=1 -o Dpkg::Use-Pty=0 --purge --planner $1
+ cp -a rootdir/tmp/testsuccess.output crosser.output
+ testsuccess grep -- '--remove.*crosser.*' crosser.output
+ testsuccess grep -- '--purge' crosser.output
+ testsuccess apt install crosser:armel=3 -y -o Debug::pkgDPkgProgressReporting=1 -o Dpkg::Use-Pty=0 --purge --planner $1
+ testdpkgnotinstalled 'crosser:i386' 'crosser:amd64' 'unrelated'
+ testdpkginstalled 'crosser:armel'
+
+ testsuccess apt install crosser=1 -y -o Debug::pkgDpkgPm=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades
+ cp -a rootdir/tmp/testsuccess.output crosser.output
+ testsuccess grep -- '--remove.*crosser.*' crosser.output
+ testsuccess grep -- '--purge' crosser.output
+ testsuccess apt install crosser=1 -y -o Debug::pkgDPkgProgressReporting=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades
+ testdpkgnotinstalled 'crosser:armel' 'crosser:amd64' 'unrelated'
+ testdpkginstalled 'crosser:i386'
+
+ testsuccess apt purge crosser:i386 -y --planner $1
+ testdpkgnotinstalled 'crosser:i386'
}
singleinstance 'internal'
singleinstance 'apt'
@@ -52,7 +68,15 @@ multiinstance() {
testdpkgnotinstalled 'crosser:amd64' 'unrelated'
testdpkginstalled 'crosser:i386' 'crosser:armel'
- testsuccess apt purge crosser:i386 crosser:armel -y --planner $1
- testdpkgnotinstalled 'crosser:i386' 'crosser:armel' 'unrelated'
+ testsuccess apt install crosser:i386- crosser:armel=1 -y -o Debug::pkgDpkgPm=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades
+ cp -a rootdir/tmp/testsuccess.output crosser.output
+ testsuccess grep -- '--remove.*crosser.*' crosser.output
+ testsuccess grep -- '--purge' crosser.output
+ testsuccess apt install crosser:i386- crosser:armel=1 -y -o Debug::pkgDPkgProgressReporting=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades
+ testdpkgnotinstalled 'crosser:amd64' 'crosser:i386' 'unrelated'
+ testdpkginstalled 'crosser:armel'
+
+ testsuccess apt purge crosser:armel -y --planner $1 -o Debug::pkgDPkgProgressReporting=1
+ testdpkgnotinstalled 'crosser:i386' 'crosser:armel' 'crosser:amd64' 'unrelated'
}
multiinstance 'internal'