From e8e5d464623f1c2e1ef96b14e622728bbf4b89af Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 20 Jul 2016 09:03:09 +0200 Subject: allow arch=all to override No-Support-for-Architecture-all If a user explicitly requests the download of arch:all apt shouldn't get in the way and perform its detection dance if arch:all packages are (also) in arch:any files or not. This e.g. allows setting arch=all on a source with such a field (or one which doesn't support all at all, but has the arch:all files like Debian itself ATM) to get only the arch:all packages from there instead of behaving like a no-op. Reported-By: Helmut Grohne on IRC --- apt-pkg/acquire-item.cc | 3 +- apt-pkg/deb/debmetaindex.cc | 40 ++++++++++++++++------ test/integration/test-acquire-binary-all | 32 +++++++++++++++++ test/integration/test-apt-sources-deb822 | 6 ++-- .../test-sourceslist-arch-plusminus-options | 3 ++ 5 files changed, 68 insertions(+), 16 deletions(-) diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 71cb18811..208b84c64 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -1311,8 +1311,7 @@ void pkgAcqMetaClearSig::QueueIndexes(bool const verify) /*{{{*/ // than invent an entirely new flag we would need to carry for all of eternity. if (hasReleaseFile && Target.Option(IndexTarget::ARCHITECTURE) == "all") { - if (TransactionManager->MetaIndexParser->IsArchitectureSupported("all") == false || - TransactionManager->MetaIndexParser->IsArchitectureAllSupportedFor(Target) == false) + if (TransactionManager->MetaIndexParser->IsArchitectureAllSupportedFor(Target) == false) { new CleanupItem(Owner, TransactionManager, Target); continue; diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index e88126807..8d84409a1 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -147,7 +147,7 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI, DefKeepCompressedAs += "uncompressed"; } - std::vector const NativeArchs = { _config->Find("APT::Architecture"), "all" }; + std::vector const NativeArchs = { _config->Find("APT::Architecture"), "implicit:all" }; bool const GzipIndex = _config->FindB("Acquire::GzipIndexes", false); for (std::vector::const_iterator E = entries.begin(); E != entries.end(); ++E) { @@ -210,15 +210,15 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI, Options.insert(std::make_pair("SITE", Site)); Options.insert(std::make_pair("RELEASE", Release)); if (tplMetaKey.find("$(COMPONENT)") != std::string::npos) - Options.insert(std::make_pair("COMPONENT", E->Name)); + Options.emplace("COMPONENT", E->Name); if (tplMetaKey.find("$(LANGUAGE)") != std::string::npos) - Options.insert(std::make_pair("LANGUAGE", *L)); + Options.emplace("LANGUAGE", *L); if (tplMetaKey.find("$(ARCHITECTURE)") != std::string::npos) - Options.insert(std::make_pair("ARCHITECTURE", *A)); + Options.emplace("ARCHITECTURE", (*A == "implicit:all") ? "all" : *A); else if (tplMetaKey.find("$(NATIVE_ARCHITECTURE)") != std::string::npos) - Options.insert(std::make_pair("ARCHITECTURE", NativeArch)); + Options.emplace("ARCHITECTURE", (NativeArch == "implicit:all") ? "all" : NativeArch); if (tplMetaKey.find("$(NATIVE_ARCHITECTURE)") != std::string::npos) - Options.insert(std::make_pair("NATIVE_ARCHITECTURE", NativeArch)); + Options.emplace("NATIVE_ARCHITECTURE", (NativeArch == "implicit:all") ? "all" : NativeArch); std::string MetaKey = tplMetaKey; std::string ShortDesc = tplShortDesc; @@ -299,11 +299,16 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI, Options.insert(std::make_pair("SOURCESENTRY", E->sourcesEntry)); bool IsOpt = IsOptional; - if (IsOpt == false) { auto const arch = Options.find("ARCHITECTURE"); if (arch != Options.end() && arch->second == "all") - IsOpt = true; + { + // one of them must be implicit:all then + if (*A != "all" && NativeArch != "all") + IsOpt = true; + else // user used arch=all explicitly + Options.emplace("Force-Support-For-All", "yes"); + } } IndexTarget Target( @@ -719,6 +724,10 @@ bool debReleaseIndex::IsArchitectureSupported(std::string const &arch) const/*{{ /*}}}*/ bool debReleaseIndex::IsArchitectureAllSupportedFor(IndexTarget const &target) const/*{{{*/ { + if (target.Options.find("Force-Support-For-All") != target.Options.end()) + return true; + if (IsArchitectureSupported("all") == false) + return false; if (d->NoSupportForAll.empty()) return true; return std::find(d->NoSupportForAll.begin(), d->NoSupportForAll.end(), target.Option(IndexTarget::CREATED_BY)) == d->NoSupportForAll.end(); @@ -896,9 +905,18 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ { auto Values = getDefaultSetOf(Name, Options, APT::Configuration::getArchitectures()); // all is a very special architecture users shouldn't be concerned with explicitly - if (Name == "arch" && std::find(Values.begin(), Values.end(), "all") == Values.end()) - Values.push_back("all"); - return applyPlusMinusOptions(Name, Options, std::move(Values)); + // but if the user does, do not override the choice + auto const val = Options.find(Name + "-"); + if (val != Options.end()) + { + std::vector const minus = VectorizeString(val->second, ','); + if (std::find(minus.begin(), minus.end(), "all") != minus.end()) + return applyPlusMinusOptions(Name, Options, std::move(Values)); + } + Values = applyPlusMinusOptions(Name, Options, std::move(Values)); + if (std::find(Values.begin(), Values.end(), "all") == Values.end()) + Values.push_back("implicit:all"); + return Values; } static std::vector parsePlusMinusTargetOptions(char const * const Name, std::map const &Options) diff --git a/test/integration/test-acquire-binary-all b/test/integration/test-acquire-binary-all index d428c106d..ba47eddc2 100755 --- a/test/integration/test-acquire-binary-all +++ b/test/integration/test-acquire-binary-all @@ -18,6 +18,7 @@ Acquire::IndexTargets::deb::Contents { KeepCompressed "true"; }; EOF +cp -a rootdir/etc/apt/sources.list.d rootdir/etc/apt/sources.list.d.bak msgmsg 'Releasefile with Architectures field and all included' testsuccess apt update @@ -38,6 +39,16 @@ testfileequal lists.before "$(listcurrentlistsdirectory)" testequal 'foo-1 foo-2' aptcache pkgnames foo- +rm -rf rootdir/var/lib/apt/lists +msgmsg 'Releasefile with Architectures field and all included, but arch-=all' +sed -i 's#^deb\(-src\)\? #deb\1 [arch-=all] #' rootdir/etc/apt/sources.list.d/* +testsuccesswithnotice apt update +cp -a rootdir/etc/apt/sources.list.d.bak/* rootdir/etc/apt/sources.list.d/ +cp rootdir/tmp/testsuccess.output aptupdate.output +testfailure grep '^Get.* all Packages ' aptupdate.output +testfailure grep '^Get.* all Contents ' aptupdate.output +testequal 'foo-2' aptcache pkgnames foo- + rm -rf rootdir/var/lib/apt/lists msgmsg 'Releasefile has all, but forbids its usage' configarchitecture 'amd64' @@ -50,6 +61,16 @@ testfailure grep '^Get.* all Packages ' aptupdate.output testsuccess grep '^Get.* all Contents ' aptupdate.output sed -i '/^No-Support-for-Architecture-all: / d' $(find ./aptarchive -name 'Release') +rm -rf rootdir/var/lib/apt/lists +msgmsg 'Releasefile has all, forbids its usage, but it is forced with arch=all' +sed -i 's#^deb\(-src\)\? #deb\1 [arch=all] #' rootdir/etc/apt/sources.list.d/* +testsuccess apt update +cp -a rootdir/etc/apt/sources.list.d.bak/* rootdir/etc/apt/sources.list.d/ +cp rootdir/tmp/testsuccess.output aptupdate.output +testsuccess grep '^Get.* all Packages ' aptupdate.output +testsuccess grep '^Get.* all Contents ' aptupdate.output +testequal 'foo-1' aptcache pkgnames foo- + rm -rf rootdir/var/lib/apt/lists msgmsg 'Releasefile with Architectures field but without all' configarchitecture 'amd64' 'i386' @@ -69,6 +90,17 @@ testfailure grep '^Get.* all Packages ' aptupdate.output testfailure grep '^Get.* all Contents ' aptupdate.output testequal 'foo-2' aptcache pkgnames foo- +rm -rf rootdir/var/lib/apt/lists +msgmsg 'Releasefile with Architectures field but without all forced with arch+=all' +sed -i 's#^deb\(-src\)\? #deb\1 [arch+=all] #' rootdir/etc/apt/sources.list.d/* +testsuccess apt update +cp -a rootdir/etc/apt/sources.list.d.bak/* rootdir/etc/apt/sources.list.d/ +cp rootdir/tmp/testsuccess.output aptupdate.output +testsuccess grep '^Get.* all Packages ' aptupdate.output +testsuccess grep '^Get.* all Contents ' aptupdate.output +testequal 'foo-1 +foo-2' aptcache pkgnames foo- + rm -rf rootdir/var/lib/apt/lists msgmsg 'Releasefile without Architectures field' getarchitecturesfromreleasefile() { echo -n ''; } diff --git a/test/integration/test-apt-sources-deb822 b/test/integration/test-apt-sources-deb822 index 9f761cb1c..abb31b793 100755 --- a/test/integration/test-apt-sources-deb822 +++ b/test/integration/test-apt-sources-deb822 @@ -66,9 +66,9 @@ msgcleantest 'Test sources.list' 'old style with options' echo "deb [trusted=yes arch+=armel,powerpc] http://ftp.debian.org/debian stable main" > $LISTS testsuccessequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0 'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.xz' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0 -'http://ftp.debian.org/debian/dists/stable/main/binary-all/Packages.xz' ftp.debian.org_debian_dists_stable_main_binary-all_Packages 0 'http://ftp.debian.org/debian/dists/stable/main/binary-armel/Packages.xz' ftp.debian.org_debian_dists_stable_main_binary-armel_Packages 0 'http://ftp.debian.org/debian/dists/stable/main/binary-powerpc/Packages.xz' ftp.debian.org_debian_dists_stable_main_binary-powerpc_Packages 0 +'http://ftp.debian.org/debian/dists/stable/main/binary-all/Packages.xz' ftp.debian.org_debian_dists_stable_main_binary-all_Packages 0 'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.xz' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris msgcleantest 'Test sources.list' 'old style with comments' @@ -197,5 +197,5 @@ echo "Languages-Remove: en" >> $SOURCES echo "Architectures-Add: armel" >> $SOURCES testsuccessequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0 'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.xz' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0 -'http://ftp.debian.org/debian/dists/stable/main/binary-all/Packages.xz' ftp.debian.org_debian_dists_stable_main_binary-all_Packages 0 -'http://ftp.debian.org/debian/dists/stable/main/binary-armel/Packages.xz' ftp.debian.org_debian_dists_stable_main_binary-armel_Packages 0 " aptget update --print-uris +'http://ftp.debian.org/debian/dists/stable/main/binary-armel/Packages.xz' ftp.debian.org_debian_dists_stable_main_binary-armel_Packages 0 +'http://ftp.debian.org/debian/dists/stable/main/binary-all/Packages.xz' ftp.debian.org_debian_dists_stable_main_binary-all_Packages 0 " aptget update --print-uris diff --git a/test/integration/test-sourceslist-arch-plusminus-options b/test/integration/test-sourceslist-arch-plusminus-options index 0ce4aa9f1..fdf33cc8c 100755 --- a/test/integration/test-sourceslist-arch-plusminus-options +++ b/test/integration/test-sourceslist-arch-plusminus-options @@ -89,3 +89,6 @@ testbinaries 'substract all from arch-set' 'i386' echo 'deb [arch=i386 arch+=all] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list testbinaries 'useless addition of all' 'i386' 'all' + +echo 'deb [arch=all] http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list +testbinaries 'explicit all' 'all' -- cgit v1.2.3