]> git.saurik.com Git - apt.git/commitdiff
Merge remote-tracking branch 'mvo/feature/update-by-hash' into debian/experimental
authorMichael Vogt <mvo@debian.org>
Wed, 18 Jun 2014 08:46:08 +0000 (10:46 +0200)
committerMichael Vogt <mvo@debian.org>
Wed, 18 Jun 2014 08:46:08 +0000 (10:46 +0200)
apt-pkg/acquire-item.cc
apt-pkg/acquire-item.h
apt-pkg/indexrecords.cc
apt-pkg/indexrecords.h
apt-pkg/tagfile.cc
apt-pkg/tagfile.h
test/integration/test-apt-by-hash-update [new file with mode: 0755]

index 70d03b84576d8ae63ca2a4b3fb048e6756115d97..e453085574e0e505611f4d6f342e626d41b6def0 100644 (file)
@@ -1018,6 +1018,8 @@ void pkgAcqIndex::Init(string const &URI, string const &URIDesc, string const &S
       indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
       if(Record)
          FileSize = Record->Size;
+      
+      InitByHashIfNeeded(MetaKey);
    }
 
    Desc.Description = URIDesc;
@@ -1027,6 +1029,38 @@ void pkgAcqIndex::Init(string const &URI, string const &URIDesc, string const &S
    QueueURI(Desc);
 }
                                                                        /*}}}*/
+// AcqIndex::AdjustForByHash - modify URI for by-hash support          /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void pkgAcqIndex::InitByHashIfNeeded(const std::string MetaKey)
+{
+   // TODO:
+   //  - (maybe?) add support for by-hash into the sources.list as flag
+   //  - make apt-ftparchive generate the hashes (and expire?)
+   std::string HostKnob = "APT::Acquire::" + ::URI(Desc.URI).Host + "::By-Hash";
+   if(_config->FindB("APT::Acquire::By-Hash", false) == true ||
+      _config->FindB(HostKnob, false) == true ||
+      MetaIndexParser->GetSupportsAcquireByHash())
+   {
+      indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
+      if(Record)
+      {
+         // FIXME: should we really use the best hash here? or a fixed one?
+         const HashString *TargetHash = Record->Hashes.find("");
+         std::string ByHash = "/by-hash/" + TargetHash->HashType() + "/" + TargetHash->HashValue();
+         size_t trailing_slash = Desc.URI.find_last_of("/");
+         Desc.URI = Desc.URI.replace(
+            trailing_slash,
+            Desc.URI.substr(trailing_slash+1).size()+1,
+            ByHash);
+      } else {
+         _error->Warning(
+            "Fetching ByHash requested but can not find record for %s",
+            MetaKey.c_str());
+      }
+   }
+}
+                                                                       /*}}}*/
 // AcqIndex::Custom600Headers - Insert custom request headers          /*{{{*/
 // ---------------------------------------------------------------------
 /* The only header we use is the last-modified header. */
index 6e204813a7b927772912d8d2be103f6f59270d9d..b4cac2f04448b1b2a589d86ea6001b65ed36cf93 100644 (file)
@@ -713,6 +713,9 @@ class pkgAcqIndex : public pkgAcqBaseIndex
     */
    std::string CompressionExtension;
 
+   /** \brief Do the changes needed to fetch via AptByHash (if needed) */
+   void InitByHashIfNeeded(const std::string MetaKey);
+
    public:
    
    // Specialized action members
index 5dcaadd76de39de92df31e60c1120f84286694be..5b53e796d8497e534498688a765bab95c9342a7a 100644 (file)
@@ -37,6 +37,11 @@ APT_PURE string indexRecords::GetSuite() const
    return this->Suite;
 }
 
+APT_PURE bool indexRecords::GetSupportsAcquireByHash() const
+{
+   return this->SupportsAcquireByHash;
+}
+
 APT_PURE bool indexRecords::CheckDist(const string MaybeDist) const
 {
    return (this->Dist == MaybeDist
@@ -86,12 +91,14 @@ bool indexRecords::Load(const string Filename)                              /*{{{*/
       strprintf(ErrorText, _("No sections in Release file %s"), Filename.c_str());
       return false;
    }
+   // FIXME: find better tag name
+   SupportsAcquireByHash = Section.FindB("Acquire-By-Hash", false);
 
    Suite = Section.FindS("Suite");
    Dist = Section.FindS("Codename");
 
-   int i;
-   for (i=0;HashString::SupportedHashes()[i] != NULL; i++)
+   bool FoundHashSum = false;
+   for (int i=0;HashString::SupportedHashes()[i] != NULL; i++)
    {
       if (!Section.Find(HashString::SupportedHashes()[i], Start, End))
         continue;
@@ -103,16 +110,20 @@ bool indexRecords::Load(const string Filename)                            /*{{{*/
       {
         if (!parseSumData(Start, End, Name, Hash, Size))
            return false;
-        indexRecords::checkSum *Sum = new indexRecords::checkSum;
-        Sum->MetaKeyFilename = Name;
-        Sum->Hashes.push_back(HashString(HashString::SupportedHashes()[i],Hash));
-        Sum->Size = Size;
-        Entries[Name] = Sum;
+
+         if (Entries.find(Name) == Entries.end())
+         {
+            indexRecords::checkSum *Sum = new indexRecords::checkSum;
+            Sum->MetaKeyFilename = Name;
+            Sum->Size = Size;
+            Entries[Name] = Sum;
+         }
+         Entries[Name]->Hashes.push_back(HashString(HashString::SupportedHashes()[i],Hash));
+         FoundHashSum = true;
       }
-      break;
    }
 
-   if(HashString::SupportedHashes()[i] == NULL)
+   if(FoundHashSum == false)
    {
       strprintf(ErrorText, _("No Hash entry in Release file %s"), Filename.c_str());
       return false;
@@ -239,6 +250,6 @@ indexRecords::indexRecords()
 }
 
 indexRecords::indexRecords(const string ExpectedDist) :
-   ExpectedDist(ExpectedDist), ValidUntil(0)
+   ExpectedDist(ExpectedDist), ValidUntil(0), SupportsAcquireByHash(false)
 {
 }
index 14b03c4d5b2fa5814e6f36f39f4966ec8ec05094..bb0fd556491476053e5079325b7833436a722cd2 100644 (file)
@@ -26,12 +26,15 @@ class indexRecords
    public:
    struct checkSum;
    std::string ErrorText;
+   // dpointer (for later9
+   void * d;
    
    protected:
    std::string Dist;
    std::string Suite;
    std::string ExpectedDist;
    time_t ValidUntil;
+   bool SupportsAcquireByHash;
 
    std::map<std::string,checkSum *> Entries;
 
@@ -49,6 +52,7 @@ class indexRecords
    virtual bool Load(std::string Filename);
    std::string GetDist() const;
    std::string GetSuite() const;
+   bool GetSupportsAcquireByHash() const;
    time_t GetValidUntil() const;
    virtual bool CheckDist(const std::string MaybeDist) const;
    std::string GetExpectedDist() const;
index 52f4da2d5864fe5dd459d568b474176e15b20931..7085e7d6968606646c26b2e5ada590784522de1c 100644 (file)
@@ -518,6 +518,17 @@ unsigned long long pkgTagSection::FindULL(const char *Tag, unsigned long long co
    return Result;
 }
                                                                        /*}}}*/
+// TagSection::FindB - Find boolean value                              /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgTagSection::FindB(const char *Tag, bool const &Default) const
+{
+   const char *Start, *Stop;
+   if (Find(Tag, Start, Stop) == false)
+      return Default;
+   return StringToBool(string(Start, Stop));
+}
+                                                                       /*}}}*/
 // TagSection::FindFlag - Locate a yes/no type flag                    /*{{{*/
 // ---------------------------------------------------------------------
 /* The bits marked in Flag are masked on/off in Flags */
index b0cfab75986edc6d769e39bfe7328ecf3460b815..db43bfbf961da1d4983595b9edc851f4161f243a 100644 (file)
@@ -62,7 +62,8 @@ class pkgTagSection
    bool Find(const char *Tag,const char *&Start, const char *&End) const;
    bool Find(const char *Tag,unsigned int &Pos) const;
    std::string FindS(const char *Tag) const;
-   signed int FindI(const char *Tag,signed long Default = 0) const ;
+   signed int FindI(const char *Tag,signed long Default = 0) const;
+   bool FindB(const char *Tag, bool const &Default = false) const;
    unsigned long long FindULL(const char *Tag, unsigned long long const &Default = 0) const;
    bool FindFlag(const char *Tag,unsigned long &Flags,
                 unsigned long Flag) const;
diff --git a/test/integration/test-apt-by-hash-update b/test/integration/test-apt-by-hash-update
new file mode 100755 (executable)
index 0000000..23282bf
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+
+setupenvironment
+configarchitecture "i386"
+
+insertpackage 'unstable' 'foo' 'all' '1.0'
+
+setupaptarchive --no-update
+
+APTARCHIVE=$(readlink -f ./aptarchive)
+
+# make Packages *only* accessable by-hash for this test
+mkdir -p aptarchive/dists/unstable/main/binary-i386/by-hash/SHA512
+(cd  aptarchive/dists/unstable/main/binary-i386/by-hash/SHA512 && 
+     mv ../../Packages* . &&
+     ln -s Packages.gz  $(sha512sum Packages.gz|cut -f1 -d' ') )
+
+# add sources
+mkdir -p aptarchive/dists/unstable/main/source/by-hash/SHA512
+(cd  aptarchive/dists/unstable/main/source/by-hash/SHA512 && 
+     ln -s ../../Sources.gz  $(sha512sum ../../Sources.gz|cut -f1 -d' ') 
+)
+
+# we moved the Packages file away, normal update won't work
+testfailure aptget upate
+
+# ensure we do not know about "foo"
+testequal "Reading package lists...
+Building dependency tree...
+E: Unable to locate package foo" aptget install -q -s foo
+
+# ensure we can apt-get update by hash
+testsuccess aptget update -o APT::Acquire::By-Hash=1
+
+# ensure it works
+testequal "Inst foo (1.0 unstable [all])
+Conf foo (1.0 unstable [all])" aptget install -qq -s foo
+
+# add magic string to Release file ...
+MAGIC="Acquire-By-Hash: true"
+sed -i "s#Suite: unstable#Suite: unstable\n$MAGIC#" aptarchive/dists/unstable/Release
+signreleasefiles
+# ... and verify that it fetches by hash now
+testsuccess aptget update
+