Преглед изворни кода

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
David Kalnischkies пре 10 година
родитељ
комит
e8e5d46462

+ 1 - 2
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;

+ 29 - 11
apt-pkg/deb/debmetaindex.cc

@@ -147,7 +147,7 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI,
       DefKeepCompressedAs += "uncompressed";
    }
 
-   std::vector<std::string> const NativeArchs = { _config->Find("APT::Architecture"), "all" };
+   std::vector<std::string> const NativeArchs = { _config->Find("APT::Architecture"), "implicit:all" };
    bool const GzipIndex = _config->FindB("Acquire::GzipIndexes", false);
    for (std::vector<debReleaseIndexPrivate::debSectionEntry>::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<std::string> 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<std::string> parsePlusMinusTargetOptions(char const * const Name,
 	 std::map<std::string, std::string> const &Options)

+ 32 - 0
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 ''; }

+ 3 - 3
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

+ 3 - 0
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'