diff options
author | David Kalnischkies <david@kalnischkies.de> | 2023-12-04 19:49:33 +0000 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2023-12-04 23:35:04 +0000 |
commit | 0abf584b283e3e0f040b9ec0e7153c6e52291b2a (patch) | |
tree | e97833157e694787a53c0a637fe09ecd1ff6c89c | |
parent | 4e344a4c1d2862b7cdb900a20222bc22ac5edcf7 (diff) |
Have Grp.FindPreferredPkg return very foreign pkgs as last resort
Usually this method will return the package in the most preferred
architecture (e.g. native) as that is usually what the user talks about
and also information wise for our internal usage the most dense.
Early on in parsing Packages files through it can happen that we
encounter stanzas about packages in architectures we are not even
configured to know about – we have to collect them anyhow as we might be
requested to show info about them or they could be in the status file
and we can't ignore stanzas in the status file… trouble is that this
method used to not return anything if only such an architecture was
present if we later discover other architectures which causes Provides
and Conflicts which are added lazily on discovery of an architecture
to not be added correctly.
The result is like in the testcase that apt could be instructed to
install a package without respecting its negative dependencies, which is
bad even if its discovered by dpkg and refused. It does only happen with
unknown architectures through which mostly happens if you are unlucky
(amd64 users tend to be very lucky as that sorts early) and use
flat-style repositories containing multiple architectures.
Reported-By: Tianyu Chen (billchenchina) on IRC
-rw-r--r-- | apt-pkg/pkgcache.cc | 20 | ||||
-rw-r--r-- | doc/examples/configure-index | 2 | ||||
-rwxr-xr-x | test/integration/test-dont-forget-conflicts-via-unknown-architectures | 43 |
3 files changed, 59 insertions, 6 deletions
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 0d18c6cf8..76336b9b3 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -393,11 +393,17 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg(bool const &Prefer pkgCache::PkgIterator Pkg = FindPkg(StringView("native", 6)); if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0)) return Pkg; - - std::vector<std::string> const archs = APT::Configuration::getArchitectures(); - for (std::vector<std::string>::const_iterator a = archs.begin(); - a != archs.end(); ++a) { - Pkg = FindPkg(*a); + // native and foreign + for (auto const &a : APT::Configuration::getArchitectures()) + { + Pkg = FindPkg(a); + if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0)) + return Pkg; + } + // very foreign/barbarian + for (auto const &a : _config->FindVector("APT::BarbarianArchitectures")) + { + Pkg = FindPkg(a); if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0)) return Pkg; } @@ -405,6 +411,10 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg(bool const &Prefer Pkg = FindPkg(StringView("none", 4)); if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0)) return Pkg; + // the "rest" we somehow know about (+ those we tried already again as skipping is hard) + for (Pkg = PackageList(); not Pkg.end(); Pkg = NextPkg(Pkg)) + if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0)) + return Pkg; if (PreferNonVirtual == true) return FindPreferredPkg(false); diff --git a/doc/examples/configure-index b/doc/examples/configure-index index 6a168192c..0d4dd31a5 100644 --- a/doc/examples/configure-index +++ b/doc/examples/configure-index @@ -540,7 +540,7 @@ DPkg // controls if apt will apport on the first dpkg error or if it // tries to install as many packages as possible - StopOnError "true"; + StopOnError "<BOOL>"; Progress-Fancy { progress-fg "<STRING>"; diff --git a/test/integration/test-dont-forget-conflicts-via-unknown-architectures b/test/integration/test-dont-forget-conflicts-via-unknown-architectures new file mode 100755 index 000000000..07d5d8f84 --- /dev/null +++ b/test/integration/test-dont-forget-conflicts-via-unknown-architectures @@ -0,0 +1,43 @@ +#!/bin/sh +set -e + +TESTDIR="$(readlink -f "$(dirname "$0")")" +. "$TESTDIR/framework" +setupenvironment +configarchitecture 'arm64' +configdpkgnoopchroot + +buildsimplenativepackage 'pkga' 'arm64' '1' 'stable' +buildsimplenativepackage 'pkgb' 'arm64' '1' 'stable' + +cd aptarchive +aptftparchive packages ../incoming > Packages +cd .. +generatereleasefiles +signreleasefiles +setupflataptarchive +testsuccess apt update + +testsuccess apt install pkga pkgb -y +testdpkginstalled 'pkga' 'pkgb' + +rm -rf aptarchive incoming + +buildsimplenativepackage 'pkga' 'arm64,amd64' '2' 'unstable' 'Provides: pkgb +Breaks: pkgb (<< 1+) +Replaces: pkgb (<< 1+)' + +mkdir aptarchive +cd aptarchive +aptftparchive packages ../incoming > Packages +cd .. +generatereleasefiles +signreleasefiles +setupflataptarchive +testsuccess apt update + +#apt upgrade pkga -o Debug::pkgDpkgPm=1 -y -o Dpkg::use-pty=0 +rm -f rootdir/var/cache/apt/*.bin +testsuccess apt upgrade pkga -y +testdpkginstalled 'pkga' +testdpkgnotinstalled 'pkgb' |