summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vogt <mvo@debian.org>2014-06-18 10:46:08 +0200
committerMichael Vogt <mvo@debian.org>2014-06-18 10:46:08 +0200
commitb6fea8bbe25e3c0312de72c99b0d49c699d02b7b (patch)
treee0f1b5f51e568be9370dece04ede0352ee37684a
parentda029b0aaebdc64a3a9f6b7012213539421c934b (diff)
parent59194959326dbf114a5c894e4279c04844b4a793 (diff)
Merge remote-tracking branch 'mvo/feature/update-by-hash' into debian/experimental
-rw-r--r--apt-pkg/acquire-item.cc34
-rw-r--r--apt-pkg/acquire-item.h3
-rw-r--r--apt-pkg/indexrecords.cc31
-rw-r--r--apt-pkg/indexrecords.h4
-rw-r--r--apt-pkg/tagfile.cc11
-rw-r--r--apt-pkg/tagfile.h3
-rwxr-xr-xtest/integration/test-apt-by-hash-update49
7 files changed, 124 insertions, 11 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 70d03b845..e45308557 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -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. */
diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h
index 6e204813a..b4cac2f04 100644
--- a/apt-pkg/acquire-item.h
+++ b/apt-pkg/acquire-item.h
@@ -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
diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc
index 5dcaadd76..5b53e796d 100644
--- a/apt-pkg/indexrecords.cc
+++ b/apt-pkg/indexrecords.cc
@@ -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)
{
}
diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h
index 14b03c4d5..bb0fd5564 100644
--- a/apt-pkg/indexrecords.h
+++ b/apt-pkg/indexrecords.h
@@ -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;
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index 52f4da2d5..7085e7d69 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -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 */
diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h
index b0cfab759..db43bfbf9 100644
--- a/apt-pkg/tagfile.h
+++ b/apt-pkg/tagfile.h
@@ -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
index 000000000..23282bf86
--- /dev/null
+++ b/test/integration/test-apt-by-hash-update
@@ -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
+