diff options
-rw-r--r-- | apt-pkg/packagemanager.cc | 41 | ||||
-rw-r--r-- | apt-pkg/packagemanager.h | 1 | ||||
-rwxr-xr-x | test/integration/test-bug-796070-downgrade-realpkg | 23 | ||||
-rwxr-xr-x | test/integration/test-bug-796070-downgrade-simulate (renamed from test/integration/skip-bug-796070-downgrade) | 4 |
4 files changed, 64 insertions, 5 deletions
diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 06ec986ed..ceeb60a03 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -268,6 +268,33 @@ bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D, return true; } /*}}}*/ +// PM::CheckRBreaks - Look for reverse breaks /*{{{*/ +bool pkgPackageManager::CheckRBreaks(PkgIterator const &Pkg, DepIterator D, + const char * const Ver) +{ + for (;D.end() == false; ++D) + { + if (D->Type != pkgCache::Dep::DpkgBreaks) + continue; + + PkgIterator const DP = D.ParentPkg(); + if (Cache[DP].Delete() == false) + continue; + + // Ignore self conflicts, ignore conflicts from irrelevant versions + if (D.IsIgnorable(Pkg) || D.ParentVer() != DP.CurrentVer()) + continue; + + if (Cache.VS().CheckDep(Ver, D->CompareOp, D.TargetVer()) == false) + continue; + + // no earlyremove() here as user has already agreed to the permanent removal + if (SmartRemove(DP) == false) + return _error->Error("Internal Error, Could not early remove %s (%d)",DP.FullName().c_str(), 4); + } + return true; +} + /*}}}*/ // PM::ConfigureAll - Run the all out configuration /*{{{*/ // --------------------------------------------------------------------- /* This configures every package. It is assumed they are all unpacked and @@ -561,6 +588,14 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth) if (Bad == true) return _error->Error(_("Could not configure '%s'. "),Pkg.FullName().c_str()); + // Check for reverse conflicts. + if (CheckRBreaks(Pkg,Pkg.RevDependsList(), instVer.VerStr()) == false) + return false; + + for (PrvIterator P = instVer.ProvidesList(); P.end() == false; ++P) + if (Pkg->Group != P.OwnerPkg()->Group) + CheckRBreaks(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); + if (PkgLoop) return true; static std::string const conf = _config->Find("PackageManager::Configure","all"); @@ -847,7 +882,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c clog << OutputInDepth(Depth) << "Because of conflict knot, removing " << ConflictPkg.FullName() << " temporarily" << endl; } if (EarlyRemove(ConflictPkg, &End) == false) - return _error->Error("Internal Error, Could not early remove %s (2)",ConflictPkg.FullName().c_str()); + return _error->Error("Internal Error, Could not early remove %s (%d)",ConflictPkg.FullName().c_str(), 3); SomethingBad = true; continue; } @@ -889,7 +924,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c if (Debug) clog << OutputInDepth(Depth) << "So temprorary remove/deconfigure " << ConflictPkg.FullName() << " to satisfy " << End << endl; if (EarlyRemove(ConflictPkg, &End) == false) - return _error->Error("Internal Error, Could not early remove %s (2)",ConflictPkg.FullName().c_str()); + return _error->Error("Internal Error, Could not early remove %s (%d)",ConflictPkg.FullName().c_str(), 2); } } else @@ -901,7 +936,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c clog << OutputInDepth(Depth) << "Removing " << ConflictPkg.FullName() << " now to avoid " << End << endl; // no earlyremove() here as user has already agreed to the permanent removal if (SmartRemove(Pkg) == false) - return _error->Error("Internal Error, Could not early remove %s (1)",ConflictPkg.FullName().c_str()); + return _error->Error("Internal Error, Could not early remove %s (%d)",ConflictPkg.FullName().c_str(), 1); } } } diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 8de6ab3ad..e4d20fff4 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -76,6 +76,7 @@ class pkgPackageManager : protected pkgCache::Namespace void ImmediateAdd(PkgIterator P, bool UseInstallVer, unsigned const int &Depth = 0); virtual OrderResult OrderInstall(); bool CheckRConflicts(PkgIterator Pkg,DepIterator Dep,const char *Ver); + bool CheckRBreaks(PkgIterator const &Pkg,DepIterator Dep,const char * const Ver); bool CreateOrderList(); // Analysis helpers diff --git a/test/integration/test-bug-796070-downgrade-realpkg b/test/integration/test-bug-796070-downgrade-realpkg new file mode 100755 index 000000000..3ad4fda3e --- /dev/null +++ b/test/integration/test-bug-796070-downgrade-realpkg @@ -0,0 +1,23 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture 'i386' + +buildsimplenativepackage 'apt' 'all' '1.0.10.1' 'stable' 'Depends: libapt-pkg4.16 (>= 1.0.10.1)' +buildsimplenativepackage 'libapt-pkg4.16' 'all' '1.0.10.1' 'stable' 'Breaks: apt (<< 0.9.4~), libapt-inst1.5 (<< 0.9.9~)' +buildsimplenativepackage 'libapt-pkg5.0' 'all' '1.1~exp9' 'unstable' 'Breaks: apt (<< 1.1~exp4), libapt-inst1.5 (<< 0.9.9~)' +buildsimplenativepackage 'apt' 'all' '1.1~exp9' 'unstable' 'Depends: libapt-pkg5.0' + +setupaptarchive + +# Check with the APT name, aka essential +testsuccess aptget install apt -t stable -y +testsuccess aptget dist-upgrade -y + +testsuccess aptget install apt/stable -y --allow-downgrades -o Debug::pkgPackageManager=1 #-o Debug::pkgDpkgPM=1 +testdpkginstalled apt libapt-pkg4.16 +testdpkgnotinstalled libapt-pkg5.0 diff --git a/test/integration/skip-bug-796070-downgrade b/test/integration/test-bug-796070-downgrade-simulate index a435cfbf1..0b4817d39 100755 --- a/test/integration/skip-bug-796070-downgrade +++ b/test/integration/test-bug-796070-downgrade-simulate @@ -49,8 +49,8 @@ The following packages will be REMOVED: The following packages will be DOWNGRADED: eapt 0 upgraded, 0 newly installed, 1 downgraded, 1 to remove and 0 not upgraded. +Inst eapt [1.1~exp9] (1.0.10.1 unstable [all]) [elibapt-pkg5.0:i386 on eapt:i386] [elibapt-pkg5.0:i386 ] Remv elibapt-pkg5.0 [1.1~exp9] -Inst eapt [1.1~exp9] (1.0.10.1 unstable [all]) Conf eapt (1.0.10.1 unstable [all])' apt install -s eapt=1.0.10.1 @@ -62,6 +62,6 @@ The following packages will be REMOVED: The following packages will be DOWNGRADED: apt 0 upgraded, 0 newly installed, 1 downgraded, 1 to remove and 0 not upgraded. +Inst apt [1.1~exp9] (1.0.10.1 unstable [all]) [libapt-pkg5.0:i386 on apt:i386] [libapt-pkg5.0:i386 ] Remv libapt-pkg5.0 [1.1~exp9] -Inst apt [1.1~exp9] (1.0.10.1 unstable [all]) Conf apt (1.0.10.1 unstable [all])' apt install -s apt=1.0.10.1 |