diff options
author | David Kalnischkies <david@kalnischkies.de> | 2021-09-04 02:22:24 +0200 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2021-09-04 15:35:15 +0200 |
commit | 79a675ddf3320bf640d130e592c86fefd1a460e1 (patch) | |
tree | 231c38e1e422624c8a5f2061b7c2d5aecf11ca88 | |
parent | 20745375afb333fd3d442006f3c6ebbebe195dab (diff) |
Barbarian M-A:allowed don't satisfy :any deps of other archs
What does a M-A:allowed package from non-native/non-foreign architecture
provide? If we look at M-A:foreign, such a package satisfies
dependencies within its own architecture, but not in other
architectures, so the same should apply to :any dependencies on
M-A:allowed packages, but we have a problem: While unqualified package
names are architecture-specific, the virtual package name qualified with
:any is not (see 3addaba1ff).
We could of course make it architecture-specific now, but that would
introduce many virtual packages for this relatively minor usecase and
would reintroduce a need for special display handling.
So, we pull a trick here: Barbarian M-A:allowed packages do not provide
the architecture-independent :any package anymore, but only a specific
one and every :any dependency from a barbarian package is rewritten to
an or-group of the specific and the independent :any package.
References: 3addaba1ff
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 17 | ||||
-rwxr-xr-x | test/integration/test-multiarch-barbarian | 243 |
2 files changed, 256 insertions, 4 deletions
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 966246ca7..2f0ebaa7b 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -823,6 +823,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver, return true; string const pkgArch = Ver.Arch(); + bool const barbarianArch = not APT::Configuration::checkArchitecture(pkgArch); while (1) { @@ -843,7 +844,14 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver, } else if (Package.substr(found) == ":any") { - if (NewDepends(Ver,Package,"any",Version,Op,Type) == false) + if (barbarianArch) + { + if (not NewDepends(Ver, Package, "any", Version, Op | pkgCache::Dep::Or, Type)) + return false; + if (not NewDepends(Ver, Package.substr(0, found), pkgArch, Version, Op, Type)) + return false; + } + else if (not NewDepends(Ver, Package, "any", Version, Op, Type)) return false; } else @@ -888,6 +896,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) } string const Arch = Ver.Arch(); + bool const barbarianArch = not APT::Configuration::checkArchitecture(Arch); const char *Start; const char *Stop; if (Section.Find(pkgTagSection::Key::Provides,Start,Stop) == true) @@ -914,7 +923,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) if (NewProvides(Ver, Package, "any", Version, pkgCache::Flag::ArchSpecific) == false) return false; } else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) { - if (APT::Configuration::checkArchitecture(Arch)) + if (not barbarianArch) { if (NewProvidesAllArch(Ver, Package, Version, 0) == false) return false; @@ -922,7 +931,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) else if (NewProvides(Ver, Package, Arch, Version, 0) == false) return false; } else { - if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed) + if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed && not barbarianArch) { if (NewProvides(Ver, Package.to_string().append(":any"), "any", Version, pkgCache::Flag::MultiArchImplicit) == false) return false; @@ -945,7 +954,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) } while (Start != Stop); } - if (APT::Configuration::checkArchitecture(Arch)) + if (not barbarianArch) { if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed) { diff --git a/test/integration/test-multiarch-barbarian b/test/integration/test-multiarch-barbarian new file mode 100755 index 000000000..293f22735 --- /dev/null +++ b/test/integration/test-multiarch-barbarian @@ -0,0 +1,243 @@ +#!/bin/sh +set -e + +TESTDIR="$(readlink -f "$(dirname "$0")")" +. "$TESTDIR/framework" + +setupenvironment +configarchitecture 'amd64' 'i386' + +buildsimplenativepackage 'foreign-foo' 'amd64,i386' '1' 'stable' 'Multi-Arch: foreign +Provides: foreign-bar' +buildsimplenativepackage 'allowed-foo' 'amd64,i386' '1' 'stable' 'Multi-Arch: allowed +Provides: allowed-bar' +buildsimplenativepackage 'needs-foreign-foo' 'amd64,i386' '1' 'stable' 'Depends: foreign-foo' +buildsimplenativepackage 'needs-foreign-bar' 'amd64,i386' '1' 'stable' 'Depends: foreign-bar' +buildsimplenativepackage 'needs-allowed-foo' 'amd64,i386' '1' 'stable' 'Depends: allowed-foo' +buildsimplenativepackage 'needs-allowed-bar' 'amd64,i386' '1' 'stable' 'Depends: allowed-bar' +buildsimplenativepackage 'needs-allowed-foo-any' 'amd64,i386' '1' 'stable' 'Depends: allowed-foo:any' +buildsimplenativepackage 'needs-allowed-bar-any' 'amd64,i386' '1' 'stable' 'Depends: allowed-bar:any' + +setupaptarchive + +simulateinstall() { + testsuccessequal "Reading package lists... +Building dependency tree... +The following additional packages will be installed: + $1-foo +The following NEW packages will be installed: + $1-foo needs-$1-$2 +0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. +Inst $1-foo (1 stable [amd64]) +Inst needs-$1-$2 (1 stable [amd64]) +Conf $1-foo (1 stable [amd64]) +Conf needs-$1-$2 (1 stable [amd64])" apt install needs-$1-$2 -s +} +simulateinstall 'foreign' 'foo' +simulateinstall 'foreign' 'bar' +simulateinstall 'allowed' 'foo' +simulateinstall 'allowed' 'bar' +simulateinstall 'allowed' 'foo-any' +simulateinstall 'allowed' 'bar-any' + +# install a barbaric architecture which wont do +insertinstalledpackage 'foreign-foo' 'armel' '1' 'Multi-Arch: foreign +Provides: foreign-bar' +insertinstalledpackage 'allowed-foo' 'armel' '1' 'Multi-Arch: allowed +Provides: allowed-bar' +testdpkginstalled foreign-foo:armel allowed-foo:armel + +runandsimulateaptinstall() { + local MSG="$1" + shift + testsuccessequal "$MSG" apt install -s "$@" + testsuccess apt install -y "$@" +} + +runandsimulateaptinstall 'Reading package lists... +Building dependency tree... +The following additional packages will be installed: + allowed-foo foreign-foo +The following packages will be REMOVED: + allowed-foo:armel foreign-foo:armel +The following NEW packages will be installed: + allowed-foo foreign-foo needs-allowed-bar-any needs-allowed-foo-any + needs-foreign-bar needs-foreign-foo +0 upgraded, 6 newly installed, 2 to remove and 0 not upgraded. +Remv allowed-foo:armel [1] +Remv foreign-foo:armel [1] +Inst allowed-foo (1 stable [amd64]) +Inst foreign-foo (1 stable [amd64]) +Inst needs-allowed-bar-any (1 stable [amd64]) +Inst needs-allowed-foo-any (1 stable [amd64]) +Inst needs-foreign-bar (1 stable [amd64]) +Inst needs-foreign-foo (1 stable [amd64]) +Conf allowed-foo (1 stable [amd64]) +Conf foreign-foo (1 stable [amd64]) +Conf needs-allowed-bar-any (1 stable [amd64]) +Conf needs-allowed-foo-any (1 stable [amd64]) +Conf needs-foreign-bar (1 stable [amd64]) +Conf needs-foreign-foo (1 stable [amd64])' needs-foreign-foo needs-foreign-bar needs-allowed-foo-any needs-allowed-bar-any +runandsimulateaptinstall 'Reading package lists... +Building dependency tree... +Reading state information... +The following NEW packages will be installed: + needs-allowed-bar needs-allowed-foo +0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. +Inst needs-allowed-bar (1 stable [amd64]) +Inst needs-allowed-foo (1 stable [amd64]) +Conf needs-allowed-bar (1 stable [amd64]) +Conf needs-allowed-foo (1 stable [amd64])' needs-allowed-foo needs-allowed-bar +testdpkginstalled foreign-foo:amd64 allowed-foo:amd64 needs-foreign-foo needs-foreign-bar needs-allowed-foo-any needs-allowed-bar-any +testempty dpkg -C + +# check if dependencies between barbarians work +testsuccess aptget check +configarchitecture 'i386' +testsuccess aptget check +configarchitecture 'amd64' 'i386' + +testsuccess apt purge -y needs-foreign-foo needs-foreign-bar needs-allowed-foo-any needs-allowed-bar-any +testdpkgnotinstalled foreign-foo:armel allowed-foo:armel needs-foreign-foo needs-foreign-bar needs-allowed-foo-any needs-allowed-bar-any +testdpkginstalled foreign-foo:amd64 allowed-foo:amd64 needs-allowed-foo needs-allowed-bar + +runandsimulateaptinstall 'Reading package lists... +Building dependency tree... +Reading state information... +The following additional packages will be installed: + allowed-foo:i386 foreign-foo:i386 +The following packages will be REMOVED: + allowed-foo foreign-foo needs-allowed-bar needs-allowed-foo +The following NEW packages will be installed: + allowed-foo:i386 foreign-foo:i386 needs-allowed-bar-any + needs-allowed-foo-any needs-foreign-bar needs-foreign-foo +0 upgraded, 6 newly installed, 4 to remove and 0 not upgraded. +Remv needs-allowed-foo [1] +Remv needs-allowed-bar [1] +Remv allowed-foo [1] +Remv foreign-foo [1] +Inst allowed-foo:i386 (1 stable [i386]) +Inst foreign-foo:i386 (1 stable [i386]) +Inst needs-allowed-bar-any (1 stable [amd64]) +Inst needs-allowed-foo-any (1 stable [amd64]) +Inst needs-foreign-bar (1 stable [amd64]) +Inst needs-foreign-foo (1 stable [amd64]) +Conf allowed-foo:i386 (1 stable [i386]) +Conf foreign-foo:i386 (1 stable [i386]) +Conf needs-allowed-bar-any (1 stable [amd64]) +Conf needs-allowed-foo-any (1 stable [amd64]) +Conf needs-foreign-bar (1 stable [amd64]) +Conf needs-foreign-foo (1 stable [amd64])' needs-foreign-foo needs-foreign-bar needs-allowed-foo-any needs-allowed-bar-any foreign-foo:amd64- allowed-foo:amd64- + +runandsimulateaptinstall 'Reading package lists... +Building dependency tree... +Reading state information... +The following packages will be REMOVED: + needs-allowed-bar-any needs-allowed-foo-any needs-foreign-bar + needs-foreign-foo +The following NEW packages will be installed: + needs-allowed-bar-any:i386 needs-allowed-foo-any:i386 needs-foreign-bar:i386 + needs-foreign-foo:i386 +0 upgraded, 4 newly installed, 4 to remove and 0 not upgraded. +Remv needs-allowed-bar-any [1] +Remv needs-allowed-foo-any [1] +Remv needs-foreign-bar [1] +Remv needs-foreign-foo [1] +Inst needs-allowed-bar-any:i386 (1 stable [i386]) +Inst needs-allowed-foo-any:i386 (1 stable [i386]) +Inst needs-foreign-bar:i386 (1 stable [i386]) +Inst needs-foreign-foo:i386 (1 stable [i386]) +Conf needs-allowed-bar-any:i386 (1 stable [i386]) +Conf needs-allowed-foo-any:i386 (1 stable [i386]) +Conf needs-foreign-bar:i386 (1 stable [i386]) +Conf needs-foreign-foo:i386 (1 stable [i386])' needs-foreign-foo:i386 needs-foreign-bar:i386 needs-allowed-foo-any:i386 needs-allowed-bar-any:i386 + +runandsimulateaptinstall 'Reading package lists... +Building dependency tree... +Reading state information... +The following packages will be REMOVED: + allowed-foo:i386 foreign-foo:i386 +The following NEW packages will be installed: + allowed-foo foreign-foo +0 upgraded, 2 newly installed, 2 to remove and 0 not upgraded. +Remv allowed-foo:i386 [1] [needs-allowed-bar-any:i386 needs-allowed-foo-any:i386 ] +Inst allowed-foo (1 stable [amd64]) +Remv foreign-foo:i386 [1] [needs-foreign-bar:i386 needs-foreign-foo:i386 ] +Inst foreign-foo (1 stable [amd64]) +Conf allowed-foo (1 stable [amd64]) +Conf foreign-foo (1 stable [amd64])' foreign-foo:amd64 allowed-foo:amd64 +testdpkginstalled foreign-foo:amd64 needs-foreign-foo:i386 needs-foreign-bar:i386 + +testsuccessequal 'Reading package lists... +Building dependency tree... +Reading state information... +The following additional packages will be installed: + allowed-foo:i386 +The following packages will be REMOVED: + allowed-foo +The following NEW packages will be installed: + allowed-foo:i386 needs-allowed-bar:i386 needs-allowed-foo:i386 +0 upgraded, 3 newly installed, 1 to remove and 0 not upgraded. +Remv allowed-foo [1] [needs-allowed-bar-any:i386 needs-allowed-foo-any:i386 ] +Inst allowed-foo:i386 (1 stable [i386]) +Inst needs-allowed-bar:i386 (1 stable [i386]) +Inst needs-allowed-foo:i386 (1 stable [i386]) +Conf allowed-foo:i386 (1 stable [i386]) +Conf needs-allowed-bar:i386 (1 stable [i386]) +Conf needs-allowed-foo:i386 (1 stable [i386])' apt install needs-allowed-foo:i386 needs-allowed-bar:i386 -s + +testsuccess aptget check +# make amd64 packages barbaric: the needs are i386 native, the providers amd64 barbaric! +configarchitecture 'i386' +testfailureequal "Reading package lists... +Building dependency tree... +Reading state information... +You might want to run 'apt --fix-broken install' to correct these. +The following packages have unmet dependencies: + needs-allowed-bar-any : Depends: allowed-bar:any + needs-allowed-foo-any : Depends: allowed-foo:any + needs-foreign-bar : Depends: foreign-bar + needs-foreign-foo : Depends: foreign-foo but it is not installed +E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution)." aptget check + +# make i386 packages barbaric, so the providers are now native +configarchitecture 'amd64' +testsuccess aptget check + +testsuccess apt install -y needs-allowed-foo needs-allowed-bar +testsuccess dpkg --remove --force-depends foreign-foo:amd64 allowed-foo:amd64 +testdpkginstalled needs-foreign-foo:i386 needs-foreign-bar:i386 needs-allowed-foo needs-allowed-bar needs-allowed-foo-any:i386 needs-allowed-bar-any:i386 +testfailure aptget check + +testsuccessequal 'Reading package lists... +Building dependency tree... +Reading state information... +Correcting dependencies... Done +The following additional packages will be installed: + allowed-foo foreign-foo +The following NEW packages will be installed: + allowed-foo foreign-foo +0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. +Inst allowed-foo (1 stable [amd64]) [needs-foreign-bar:i386 needs-foreign-foo:i386 ] +Inst foreign-foo (1 stable [amd64]) +Conf allowed-foo (1 stable [amd64]) +Conf foreign-foo (1 stable [amd64])' apt install --fix-broken -s +# note that dpkg would not accept this as its a barbaric arch, +# but it is the easiest to try if the dependencies as such work in apt +testsuccessequal "Reading package lists... +Building dependency tree... +Reading state information... +Correcting dependencies... Done +Note, selecting 'foreign-foo:i386' instead of './incoming/foreign-foo_1_i386.deb' +Note, selecting 'allowed-foo:i386' instead of './incoming/allowed-foo_1_i386.deb' +The following packages will be REMOVED: + needs-allowed-bar needs-allowed-foo +The following NEW packages will be installed: + allowed-foo:i386 foreign-foo:i386 +0 upgraded, 2 newly installed, 2 to remove and 0 not upgraded. +Remv needs-allowed-bar [1] [needs-foreign-bar:i386 needs-foreign-foo:i386 needs-allowed-bar-any:i386 needs-allowed-foo-any:i386 needs-allowed-foo:amd64 ] +Remv needs-allowed-foo [1] [needs-foreign-bar:i386 needs-foreign-foo:i386 needs-allowed-bar-any:i386 needs-allowed-foo-any:i386 ] +Inst allowed-foo:i386 (1 local-deb [i386]) [needs-foreign-bar:i386 needs-foreign-foo:i386 ] +Inst foreign-foo:i386 (1 local-deb [i386]) +Conf allowed-foo:i386 (1 local-deb [i386]) +Conf foreign-foo:i386 (1 local-deb [i386])" apt install --fix-broken -s ./incoming/foreign-foo_1_i386.deb ./incoming/allowed-foo_1_i386.deb |