]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/acquire-item.cc
Wreck validation until we can assess ecosystem :/.
[apt.git] / apt-pkg / acquire-item.cc
index 7fbbf08f81866e24e4ab48c163f730e34fd24765..663452b9f1c92451c72ac5008f46e4c0c83411f4 100644 (file)
@@ -46,6 +46,7 @@
 #include <ctime>
 #include <sstream>
 #include <numeric>
+#include <random>
 
 #include <apti18n.h>
                                                                        /*}}}*/
@@ -145,7 +146,7 @@ static void ReportMirrorFailureToCentral(pkgAcquire::Item const &I, std::string
             << FailCode << std::endl;
 #endif
    string const report = _config->Find("Methods::Mirror::ProblemReporting",
-                                "/usr/lib/apt/apt-report-mirror-failure");
+                                LIBEXEC_DIR "/apt-report-mirror-failure");
    if(!FileExists(report))
       return;
 
@@ -265,7 +266,7 @@ static bool APT_NONNULL(3, 4, 5) AllowInsecureRepositories(InsecureType const ms
 
    if (TargetIsAllowedToBe(TransactionManager->Target, msg) == true)
    {
-      MessageInsecureRepository(false, msgstr, repo);
+      //MessageInsecureRepository(false, msgstr, repo);
       return true;
    }
 
@@ -747,6 +748,18 @@ APT_CONST bool pkgAcquire::Item::IsTrusted() const                 /*{{{*/
 // ---------------------------------------------------------------------
 /* We return to an idle state if there are still other queues that could
    fetch this object */
+static void formatHashsum(std::ostream &out, HashString const &hs)
+{
+   auto const type = hs.HashType();
+   if (type == "Checksum-FileSize")
+      out << " - Filesize";
+   else
+      out << " - " << type;
+   out << ':' << hs.HashValue();
+   if (hs.usable() == false)
+      out << " [weak]";
+   out << std::endl;
+}
 void pkgAcquire::Item::Failed(string const &Message,pkgAcquire::MethodConfig const * const Cnf)
 {
    if (QueueCounter <= 1)
@@ -818,12 +831,7 @@ void pkgAcquire::Item::Failed(string const &Message,pkgAcquire::MethodConfig con
         {
            out << "Hashes of expected file:" << std::endl;
            for (auto const &hs: ExpectedHashes)
-           {
-              out << " - " << hs.toStr();
-              if (hs.usable() == false)
-                 out << " [weak]";
-              out << std::endl;
-           }
+              formatHashsum(out, hs);
         }
         if (failreason == HASHSUM_MISMATCH)
         {
@@ -833,16 +841,12 @@ void pkgAcquire::Item::Failed(string const &Message,pkgAcquire::MethodConfig con
               std::string const tagname = std::string(*type) + "-Hash";
               std::string const hashsum = LookupTag(Message, tagname.c_str());
               if (hashsum.empty() == false)
-              {
-                 auto const hs = HashString(*type, hashsum);
-                 out << " - " << hs.toStr();
-                 if (hs.usable() == false)
-                    out << " [weak]";
-                 out << std::endl;
-              }
+                 formatHashsum(out, HashString(*type, hashsum));
            }
-           out << "Last modification reported: " << LookupTag(Message, "Last-Modified", "<none>") << std::endl;
         }
+        auto const lastmod = LookupTag(Message, "Last-Modified", "");
+        if (lastmod.empty() == false)
+           out << "Last modification reported: " << lastmod << std::endl;
       }
       ErrorText = out.str();
    }
@@ -1017,6 +1021,26 @@ bool pkgAcquire::Item::IsRedirectionLoop(std::string const &NewURI)      /*{{{*/
    return false;
 }
                                                                        /*}}}*/
+int pkgAcquire::Item::Priority()                                       /*{{{*/
+{
+   // Stage 1: Meta indices and diff indices
+   // - those need to be fetched first to have progress reporting working
+   //   for the rest
+   if (dynamic_cast<pkgAcqMetaSig*>(this) != nullptr
+       || dynamic_cast<pkgAcqMetaBase*>(this) != nullptr
+       || dynamic_cast<pkgAcqDiffIndex*>(this) != nullptr)
+      return 1000;
+   // Stage 2: Diff files
+   // - fetch before complete indexes so we can apply the diffs while fetching
+   //   larger files.
+   if (dynamic_cast<pkgAcqIndexDiffs*>(this) != nullptr ||
+       dynamic_cast<pkgAcqIndexMergeDiffs*>(this) != nullptr)
+      return 800;
+
+   // Stage 3: The rest - complete index files and other stuff
+   return 500;
+}
+                                                                       /*}}}*/
 
 pkgAcqTransactionItem::pkgAcqTransactionItem(pkgAcquire * const Owner, /*{{{*/
       pkgAcqMetaClearSig * const transactionManager, IndexTarget const &target) :
@@ -1340,6 +1364,23 @@ void pkgAcqMetaClearSig::QueueIndexes(bool const verify)                 /*{{{*/
    if (hasReleaseFile && verify == false)
       hasHashes = std::any_of(IndexTargets.begin(), IndexTargets.end(),
            [&](IndexTarget const &Target) { return TransactionManager->MetaIndexParser->Exists(Target.MetaKey); });
+   if (_config->FindB("Acquire::IndexTargets::Randomized", true) && likely(IndexTargets.empty() == false))
+   {
+      /* For fallback handling and to have some reasonable progress information
+        we can't randomize everything, but at least the order in the same type
+        can be as we shouldn't be telling the mirrors (and everyone else watching)
+        which is native/foreign arch, specific order of preference of translations, … */
+      auto range_start = IndexTargets.begin();
+      std::random_device rd;
+      std::default_random_engine g(rd());
+      do {
+        auto const type = range_start->Option(IndexTarget::CREATED_BY);
+        auto const range_end = std::find_if_not(range_start, IndexTargets.end(),
+              [&type](IndexTarget const &T) { return type == T.Option(IndexTarget::CREATED_BY); });
+        std::shuffle(range_start, range_end, g);
+        range_start = range_end;
+      } while (range_start != IndexTargets.end());
+   }
    for (auto&& Target: IndexTargets)
    {
       // if we have seen a target which is created-by a target this one here is declared a
@@ -1518,24 +1559,6 @@ void pkgAcqMetaClearSig::QueueIndexes(bool const verify)                 /*{{{*/
                                                                        /*}}}*/
 bool pkgAcqMetaBase::VerifyVendor(string const &)                      /*{{{*/
 {
-   string Transformed = TransactionManager->MetaIndexParser->GetExpectedDist();
-
-   if (Transformed == "../project/experimental")
-   {
-      Transformed = "experimental";
-   }
-
-   auto pos = Transformed.rfind('/');
-   if (pos != string::npos)
-   {
-      Transformed = Transformed.substr(0, pos);
-   }
-
-   if (Transformed == ".")
-   {
-      Transformed = "";
-   }
-
    if (TransactionManager->MetaIndexParser->GetValidUntil() > 0)
    {
       time_t const invalid_since = time(NULL) - TransactionManager->MetaIndexParser->GetValidUntil();
@@ -1570,30 +1593,27 @@ bool pkgAcqMetaBase::VerifyVendor(string const &)                       /*{{{*/
       TransactionManager->LastMetaIndexParser = NULL;
    }
 
-   if (_config->FindB("Debug::pkgAcquire::Auth", false)) 
+   if (_config->FindB("Debug::pkgAcquire::Auth", false))
    {
       std::cerr << "Got Codename: " << TransactionManager->MetaIndexParser->GetCodename() << std::endl;
+      std::cerr << "Got Suite: " << TransactionManager->MetaIndexParser->GetSuite() << std::endl;
       std::cerr << "Expecting Dist: " << TransactionManager->MetaIndexParser->GetExpectedDist() << std::endl;
-      std::cerr << "Transformed Dist: " << Transformed << std::endl;
    }
 
-   if (TransactionManager->MetaIndexParser->CheckDist(Transformed) == false)
+   // One day that might become fatal…
+   auto const ExpectedDist = TransactionManager->MetaIndexParser->GetExpectedDist();
+   auto const NowCodename = TransactionManager->MetaIndexParser->GetCodename();
+   if (TransactionManager->MetaIndexParser->CheckDist(ExpectedDist) == false)
+      _error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"),
+           Desc.Description.c_str(), ExpectedDist.c_str(), NowCodename.c_str());
+   // might be okay, might be not
+   if (TransactionManager->LastMetaIndexParser != nullptr)
    {
-      // This might become fatal one day
-//       Status = StatAuthError;
-//       ErrorText = "Conflicting distribution; expected "
-//          + MetaIndexParser->GetExpectedDist() + " but got "
-//          + MetaIndexParser->GetCodename();
-//       return false;
-      if (!Transformed.empty())
-      {
-         _error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"),
-                         Desc.Description.c_str(),
-                         Transformed.c_str(),
-                         TransactionManager->MetaIndexParser->GetCodename().c_str());
-      }
+      auto const LastCodename = TransactionManager->LastMetaIndexParser->GetCodename();
+      if (LastCodename.empty() == false && NowCodename.empty() == false && LastCodename != NowCodename)
+        _error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"),
+              Desc.Description.c_str(), LastCodename.c_str(), NowCodename.c_str());
    }
-
    return true;
 }
                                                                        /*}}}*/
@@ -1885,10 +1905,16 @@ void pkgAcqMetaSig::Done(string const &Message, HashStringList const &Hashes,
    }
    else if(MetaIndex->CheckAuthDone(Message) == true)
    {
-      if (TransactionManager->IMSHit == false)
+      auto const Releasegpg = GetFinalFilename();
+      auto const Release = MetaIndex->GetFinalFilename();
+      // if this is an IMS-Hit on Release ensure we also have the the Release.gpg file stored
+      // (previously an unknown pubkey) – but only if the Release file exists locally (unlikely
+      // event of InRelease removed from the mirror causing fallback but still an IMS-Hit)
+      if (TransactionManager->IMSHit == false ||
+           (FileExists(Releasegpg) == false && FileExists(Release) == true))
       {
-        TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename());
-        TransactionManager->TransactionStageCopy(MetaIndex, MetaIndex->DestFile, MetaIndex->GetFinalFilename());
+        TransactionManager->TransactionStageCopy(this, DestFile, Releasegpg);
+        TransactionManager->TransactionStageCopy(MetaIndex, MetaIndex->DestFile, Release);
       }
    }
    else if (MetaIndex->Status != StatAuthError)
@@ -2011,7 +2037,7 @@ void pkgAcqDiffIndex::QueueOnIMSHit() const                               /*{{{*/
 {
    // list cleanup needs to know that this file as well as the already
    // present index is ours, so we create an empty diff to save it for us
-   new pkgAcqIndexDiffs(Owner, TransactionManager, Target);
+   new pkgAcqIndexDiffs(Owner, TransactionManager, Target, UsedMirror, Target.URI);
 }
                                                                        /*}}}*/
 static bool RemoveFileForBootstrapLinking(bool const Debug, std::string const &For, std::string const &Boot)/*{{{*/
@@ -2047,7 +2073,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
    HashStringList ServerHashes;
    unsigned long long ServerSize = 0;
 
-   auto const &posix = std::locale("C.UTF-8");
+   auto const &posix = std::locale::classic();
    for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
    {
       std::string tagname = *type;
@@ -2387,14 +2413,26 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile)       /*{{{*/
       }
    }
 
+   std::string indexURI = Desc.URI;
+   auto const byhashidx = indexURI.find("/by-hash/");
+   if (byhashidx != std::string::npos)
+      indexURI = indexURI.substr(0, byhashidx - strlen(".diff"));
+   else
+   {
+      auto end = indexURI.length() - strlen(".diff/Index");
+      if (CurrentCompressionExtension != "uncompressed")
+        end -= (1 + CurrentCompressionExtension.length());
+      indexURI = indexURI.substr(0, end);
+   }
+
    if (pdiff_merge == false)
-      new pkgAcqIndexDiffs(Owner, TransactionManager, Target, available_patches);
+      new pkgAcqIndexDiffs(Owner, TransactionManager, Target, UsedMirror, indexURI, available_patches);
    else
    {
       diffs = new std::vector<pkgAcqIndexMergeDiffs*>(available_patches.size());
       for(size_t i = 0; i < available_patches.size(); ++i)
         (*diffs)[i] = new pkgAcqIndexMergeDiffs(Owner, TransactionManager,
-               Target,
+               Target, UsedMirror, indexURI,
               available_patches[i],
               diffs);
    }
@@ -2464,8 +2502,9 @@ pkgAcqDiffIndex::~pkgAcqDiffIndex()
 pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire * const Owner,
                                    pkgAcqMetaClearSig * const TransactionManager,
                                    IndexTarget const &Target,
+                                  std::string const &indexUsedMirror, std::string const &indexURI,
                                   vector<DiffInfo> const &diffs)
-   : pkgAcqBaseIndex(Owner, TransactionManager, Target), d(NULL),
+   : pkgAcqBaseIndex(Owner, TransactionManager, Target), indexURI(indexURI),
      available_patches(diffs)
 {
    DestFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI), Target);
@@ -2476,6 +2515,12 @@ pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire * const Owner,
    Description = Target.Description;
    Desc.ShortDesc = Target.ShortDesc;
 
+   UsedMirror = indexUsedMirror;
+   if (UsedMirror == "DIRECT")
+      UsedMirror.clear();
+   else if (UsedMirror.empty() == false && Description.find(" ") != string::npos)
+      Description.replace(0, Description.find(" "), UsedMirror);
+
    if(available_patches.empty() == true)
    {
       // we are done (yeah!), check hashes against the final file
@@ -2590,7 +2635,7 @@ bool pkgAcqIndexDiffs::QueueNextDiff()                                    /*{{{*/
    }
 
    // queue the right diff
-   Desc.URI = Target.URI + ".diff/" + available_patches[0].file + ".gz";
+   Desc.URI = indexURI + ".diff/" + available_patches[0].file + ".gz";
    Desc.Description = Description + " " + available_patches[0].file + string(".pdiff");
    DestFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI + ".diff/" + available_patches[0].file), Target);
 
@@ -2643,7 +2688,7 @@ void pkgAcqIndexDiffs::Done(string const &Message, HashStringList const &Hashes,
         // see if there is more to download
         if(available_patches.empty() == false)
         {
-           new pkgAcqIndexDiffs(Owner, TransactionManager, Target, available_patches);
+           new pkgAcqIndexDiffs(Owner, TransactionManager, Target, UsedMirror, indexURI, available_patches);
            Finish();
         } else {
            DestFile = PatchedFile;
@@ -2672,19 +2717,26 @@ pkgAcqIndexDiffs::~pkgAcqIndexDiffs() {}
 pkgAcqIndexMergeDiffs::pkgAcqIndexMergeDiffs(pkgAcquire * const Owner,
                                              pkgAcqMetaClearSig * const TransactionManager,
                                              IndexTarget const &Target,
+                                            std::string const &indexUsedMirror, std::string const &indexURI,
                                              DiffInfo const &patch,
                                              std::vector<pkgAcqIndexMergeDiffs*> const * const allPatches)
-  : pkgAcqBaseIndex(Owner, TransactionManager, Target), d(NULL),
-     patch(patch), allPatches(allPatches), State(StateFetchDiff)
+  : pkgAcqBaseIndex(Owner, TransactionManager, Target), indexURI(indexURI),
+    patch(patch), allPatches(allPatches), State(StateFetchDiff)
 {
    Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
 
-   Desc.Owner = this;
    Description = Target.Description;
+   UsedMirror = indexUsedMirror;
+   if (UsedMirror == "DIRECT")
+      UsedMirror.clear();
+   else if (UsedMirror.empty() == false && Description.find(" ") != string::npos)
+      Description.replace(0, Description.find(" "), UsedMirror);
+
+   Desc.Owner = this;
    Desc.ShortDesc = Target.ShortDesc;
-   Desc.URI = Target.URI + ".diff/" + patch.file + ".gz";
+   Desc.URI = indexURI + ".diff/" + patch.file + ".gz";
    Desc.Description = Description + " " + patch.file + ".pdiff";
-   DestFile = GetPartialFileNameFromURI(Desc.URI);
+   DestFile = GetPartialFileNameFromURI(Target.URI + ".diff/" + patch.file + ".gz");
 
    if(Debug)
       std::clog << "pkgAcqIndexMergeDiffs: " << Desc.URI << std::endl;
@@ -3439,7 +3491,7 @@ void pkgAcqChangelog::Init(std::string const &DestDir, std::string const &DestFi
    TemporaryDirectory = tmpname;
 
    ChangeOwnerAndPermissionOfFile("Item::QueueURI", TemporaryDirectory.c_str(),
-        SandboxUser.c_str(), "root", 0700);
+        SandboxUser.c_str(), ROOT_GROUP, 0700);
 
    DestFile = flCombine(TemporaryDirectory, DestFileName);
    if (DestDir.empty() == false)
@@ -3487,7 +3539,8 @@ std::string pkgAcqChangelog::URI(pkgCache::VerIterator const &Ver)        /*{{{*/
       pkgCache::PkgIterator const Pkg = Ver.ParentPkg();
       if (Pkg->CurrentVer != 0 && Pkg.CurrentVer() == Ver)
       {
-        std::string const basename = std::string("/usr/share/doc/") + Pkg.Name() + "/changelog";
+        std::string const root = _config->FindDir("Dir");
+        std::string const basename = root + std::string("usr/share/doc/") + Pkg.Name() + "/changelog";
         std::string const debianname = basename + ".Debian";
         if (FileExists(debianname))
            return "copy://" + debianname;
@@ -3550,7 +3603,7 @@ std::string pkgAcqChangelog::URITemplate(pkgCache::RlsFileIterator const &Rls)
         should be so this could produce request order-dependent anomalies */
       if (OpenMaybeClearSignedFile(Rls.FileName(), rf) == true)
       {
-        pkgTagFile TagFile(&rf, rf.Size());
+        pkgTagFile TagFile(&rf);
         pkgTagSection Section;
         if (TagFile.Step(Section) == true)
            server = Section.FindS("Changelogs");