Merge pull request #574 from smira/376-checksum-search-fix

Fix checksum matching from Release file
This commit is contained in:
Andrey Smirnov
2017-05-23 21:53:06 +03:00
committed by GitHub
8 changed files with 230 additions and 62 deletions

View File

@@ -7,7 +7,6 @@ import (
"net/url"
"os"
"path"
"path/filepath"
"sort"
"strconv"
"strings"
@@ -191,49 +190,49 @@ func (repo *RemoteRepo) CheckLock() error {
return nil
}
// ReleaseURL returns URL to Release* files in repo root
func (repo *RemoteRepo) ReleaseURL(name string) *url.URL {
// IndexesRootURL builds URL for various indexes
func (repo *RemoteRepo) IndexesRootURL() *url.URL {
var path *url.URL
if !repo.IsFlat() {
path = &url.URL{Path: fmt.Sprintf("dists/%s/%s", repo.Distribution, name)}
path = &url.URL{Path: fmt.Sprintf("dists/%s/", repo.Distribution)}
} else {
path = &url.URL{Path: filepath.Join(repo.Distribution, name)}
path = &url.URL{Path: fmt.Sprintf("%s", repo.Distribution)}
}
return repo.archiveRootURL.ResolveReference(path)
}
// FlatBinaryURL returns URL to Packages files for flat repo
func (repo *RemoteRepo) FlatBinaryURL() *url.URL {
path := &url.URL{Path: filepath.Join(repo.Distribution, "Packages")}
return repo.archiveRootURL.ResolveReference(path)
// ReleaseURL returns URL to Release* files in repo root
func (repo *RemoteRepo) ReleaseURL(name string) *url.URL {
return repo.IndexesRootURL().ResolveReference(&url.URL{Path: name})
}
// FlatSourcesURL returns URL to Sources files for flat repo
func (repo *RemoteRepo) FlatSourcesURL() *url.URL {
path := &url.URL{Path: filepath.Join(repo.Distribution, "Sources")}
return repo.archiveRootURL.ResolveReference(path)
// FlatBinaryPath returns path to Packages files for flat repo
func (repo *RemoteRepo) FlatBinaryPath() string {
return "Packages"
}
// BinaryURL returns URL of Packages files for given component and
// FlatSourcesPath returns path to Sources files for flat repo
func (repo *RemoteRepo) FlatSourcesPath() string {
return "Sources"
}
// BinaryPath returns path to Packages files for given component and
// architecture
func (repo *RemoteRepo) BinaryURL(component string, architecture string) *url.URL {
path := &url.URL{Path: fmt.Sprintf("dists/%s/%s/binary-%s/Packages", repo.Distribution, component, architecture)}
return repo.archiveRootURL.ResolveReference(path)
func (repo *RemoteRepo) BinaryPath(component string, architecture string) string {
return fmt.Sprintf("%s/binary-%s/Packages", component, architecture)
}
// SourcesURL returns URL of Sources files for given component
func (repo *RemoteRepo) SourcesURL(component string) *url.URL {
path := &url.URL{Path: fmt.Sprintf("dists/%s/%s/source/Sources", repo.Distribution, component)}
return repo.archiveRootURL.ResolveReference(path)
// SourcesPath returns path to Sources files for given component
func (repo *RemoteRepo) SourcesPath(component string) string {
return fmt.Sprintf("%s/source/Sources", component)
}
// UdebURL returns URL of Packages files for given component and
// UdebPath returns path of Packages files for given component and
// architecture
func (repo *RemoteRepo) UdebURL(component string, architecture string) *url.URL {
path := &url.URL{Path: fmt.Sprintf("dists/%s/%s/debian-installer/binary-%s/Packages", repo.Distribution, component, architecture)}
return repo.archiveRootURL.ResolveReference(path)
func (repo *RemoteRepo) UdebPath(component string, architecture string) string {
return fmt.Sprintf("%s/debian-installer/binary-%s/Packages", component, architecture)
}
// PackageURL returns URL of package file relative to repository root
@@ -407,30 +406,30 @@ func (repo *RemoteRepo) DownloadPackageIndexes(progress aptly.Progress, d aptly.
repo.packageList = NewPackageList()
// Download and parse all Packages & Source files
packagesURLs := [][]string{}
packagesPaths := [][]string{}
if repo.IsFlat() {
packagesURLs = append(packagesURLs, []string{repo.FlatBinaryURL().String(), PackageTypeBinary})
packagesPaths = append(packagesPaths, []string{repo.FlatBinaryPath(), PackageTypeBinary})
if repo.DownloadSources {
packagesURLs = append(packagesURLs, []string{repo.FlatSourcesURL().String(), PackageTypeSource})
packagesPaths = append(packagesPaths, []string{repo.FlatSourcesPath(), PackageTypeSource})
}
} else {
for _, component := range repo.Components {
for _, architecture := range repo.Architectures {
packagesURLs = append(packagesURLs, []string{repo.BinaryURL(component, architecture).String(), PackageTypeBinary})
packagesPaths = append(packagesPaths, []string{repo.BinaryPath(component, architecture), PackageTypeBinary})
if repo.DownloadUdebs {
packagesURLs = append(packagesURLs, []string{repo.UdebURL(component, architecture).String(), PackageTypeUdeb})
packagesPaths = append(packagesPaths, []string{repo.UdebPath(component, architecture), PackageTypeUdeb})
}
}
if repo.DownloadSources {
packagesURLs = append(packagesURLs, []string{repo.SourcesURL(component).String(), PackageTypeSource})
packagesPaths = append(packagesPaths, []string{repo.SourcesPath(component), PackageTypeSource})
}
}
}
for _, info := range packagesURLs {
url, kind := info[0], info[1]
packagesReader, packagesFile, err := http.DownloadTryCompression(d, url, repo.ReleaseFiles, ignoreMismatch, maxTries)
for _, info := range packagesPaths {
path, kind := info[0], info[1]
packagesReader, packagesFile, err := http.DownloadTryCompression(d, repo.IndexesRootURL(), path, repo.ReleaseFiles, ignoreMismatch, maxTries)
if err != nil {
return err
}

View File

@@ -157,24 +157,30 @@ func (s *RemoteRepoSuite) TestReleaseURL(c *C) {
c.Assert(s.flat.ReleaseURL("Release").String(), Equals, "http://repos.express42.com/virool/precise/Release")
}
func (s *RemoteRepoSuite) TestBinaryURL(c *C) {
c.Assert(s.repo.BinaryURL("main", "amd64").String(), Equals, "http://mirror.yandex.ru/debian/dists/squeeze/main/binary-amd64/Packages")
func (s *RemoteRepoSuite) TestIndexesRootURL(c *C) {
c.Assert(s.repo.IndexesRootURL().String(), Equals, "http://mirror.yandex.ru/debian/dists/squeeze/")
c.Assert(s.flat.IndexesRootURL().String(), Equals, "http://repos.express42.com/virool/precise/")
}
func (s *RemoteRepoSuite) TestUdebURL(c *C) {
c.Assert(s.repo.UdebURL("main", "amd64").String(), Equals, "http://mirror.yandex.ru/debian/dists/squeeze/main/debian-installer/binary-amd64/Packages")
func (s *RemoteRepoSuite) TestBinaryPath(c *C) {
c.Assert(s.repo.BinaryPath("main", "amd64"), Equals, "main/binary-amd64/Packages")
}
func (s *RemoteRepoSuite) TestSourcesURL(c *C) {
c.Assert(s.repo.SourcesURL("main").String(), Equals, "http://mirror.yandex.ru/debian/dists/squeeze/main/source/Sources")
func (s *RemoteRepoSuite) TestUdebPath(c *C) {
c.Assert(s.repo.UdebPath("main", "amd64"), Equals, "main/debian-installer/binary-amd64/Packages")
}
func (s *RemoteRepoSuite) TestFlatBinaryURL(c *C) {
c.Assert(s.flat.FlatBinaryURL().String(), Equals, "http://repos.express42.com/virool/precise/Packages")
func (s *RemoteRepoSuite) TestSourcesPath(c *C) {
c.Assert(s.repo.SourcesPath("main"), Equals, "main/source/Sources")
}
func (s *RemoteRepoSuite) TestFlatSourcesURL(c *C) {
c.Assert(s.flat.FlatSourcesURL().String(), Equals, "http://repos.express42.com/virool/precise/Sources")
func (s *RemoteRepoSuite) TestFlatBinaryPath(c *C) {
c.Assert(s.flat.FlatBinaryPath(), Equals, "Packages")
}
func (s *RemoteRepoSuite) TestFlatSourcesPath(c *C) {
c.Assert(s.flat.FlatSourcesPath(), Equals, "Sources")
}
func (s *RemoteRepoSuite) TestPackageURL(c *C) {

View File

@@ -5,6 +5,7 @@ import (
"compress/gzip"
"fmt"
"io"
"net/url"
"os"
"strings"
@@ -38,29 +39,37 @@ var compressionMethods = []struct {
// DownloadTryCompression tries to download from URL .bz2, .gz and raw extension until
// it finds existing file.
func DownloadTryCompression(downloader aptly.Downloader, url string, expectedChecksums map[string]utils.ChecksumInfo, ignoreMismatch bool, maxTries int) (io.Reader, *os.File, error) {
func DownloadTryCompression(downloader aptly.Downloader, baseURL *url.URL, path string, expectedChecksums map[string]utils.ChecksumInfo, ignoreMismatch bool, maxTries int) (io.Reader, *os.File, error) {
var err error
for _, method := range compressionMethods {
var file *os.File
tryURL := url + method.extenstion
tryPath := path + method.extenstion
foundChecksum := false
for suffix, expected := range expectedChecksums {
if strings.HasSuffix(tryURL, suffix) {
file, err = DownloadTempWithChecksum(downloader, tryURL, &expected, ignoreMismatch, maxTries)
bestSuffix := ""
for suffix := range expectedChecksums {
if strings.HasSuffix(tryPath, suffix) {
foundChecksum = true
break
if len(suffix) > len(bestSuffix) {
bestSuffix = suffix
}
}
}
if !foundChecksum {
tryURL := baseURL.ResolveReference(&url.URL{Path: tryPath})
if foundChecksum {
expected := expectedChecksums[bestSuffix]
file, err = DownloadTempWithChecksum(downloader, tryURL.String(), &expected, ignoreMismatch, maxTries)
} else {
if !ignoreMismatch {
continue
}
file, err = DownloadTemp(downloader, tryURL)
file, err = DownloadTemp(downloader, tryURL.String())
}
if err != nil {
@@ -80,7 +89,7 @@ func DownloadTryCompression(downloader aptly.Downloader, url string, expectedChe
}
if err == nil {
err = fmt.Errorf("no candidates for %s found", url)
err = fmt.Errorf("no candidates for %s found", baseURL.ResolveReference(&url.URL{Path: path}))
}
return nil, nil, err
}

View File

@@ -3,13 +3,16 @@ package http
import (
"errors"
"io"
"net/url"
"github.com/smira/aptly/utils"
. "gopkg.in/check.v1"
)
type CompressionSuite struct{}
type CompressionSuite struct {
baseURL *url.URL
}
var _ = Suite(&CompressionSuite{})
@@ -20,6 +23,10 @@ const (
rawData = "test"
)
func (s *CompressionSuite) SetUpTest(c *C) {
s.baseURL, _ = url.Parse("http://example.com/")
}
func (s *CompressionSuite) TestDownloadTryCompression(c *C) {
var buf []byte
@@ -34,7 +41,7 @@ func (s *CompressionSuite) TestDownloadTryCompression(c *C) {
buf = make([]byte, 4)
d := NewFakeDownloader()
d.ExpectResponse("http://example.com/file.bz2", bzipData)
r, file, err := DownloadTryCompression(d, "http://example.com/file", expectedChecksums, false, 1)
r, file, err := DownloadTryCompression(d, s.baseURL, "file", expectedChecksums, false, 1)
c.Assert(err, IsNil)
defer file.Close()
io.ReadFull(r, buf)
@@ -46,7 +53,7 @@ func (s *CompressionSuite) TestDownloadTryCompression(c *C) {
d = NewFakeDownloader()
d.ExpectError("http://example.com/file.bz2", &Error{Code: 404})
d.ExpectResponse("http://example.com/file.gz", gzipData)
r, file, err = DownloadTryCompression(d, "http://example.com/file", expectedChecksums, false, 1)
r, file, err = DownloadTryCompression(d, s.baseURL, "file", expectedChecksums, false, 1)
c.Assert(err, IsNil)
defer file.Close()
io.ReadFull(r, buf)
@@ -59,7 +66,7 @@ func (s *CompressionSuite) TestDownloadTryCompression(c *C) {
d.ExpectError("http://example.com/file.bz2", &Error{Code: 404})
d.ExpectError("http://example.com/file.gz", &Error{Code: 404})
d.ExpectResponse("http://example.com/file.xz", xzData)
r, file, err = DownloadTryCompression(d, "http://example.com/file", expectedChecksums, false, 1)
r, file, err = DownloadTryCompression(d, s.baseURL, "file", expectedChecksums, false, 1)
c.Assert(err, IsNil)
defer file.Close()
io.ReadFull(r, buf)
@@ -73,7 +80,7 @@ func (s *CompressionSuite) TestDownloadTryCompression(c *C) {
d.ExpectError("http://example.com/file.gz", &Error{Code: 404})
d.ExpectError("http://example.com/file.xz", &Error{Code: 404})
d.ExpectResponse("http://example.com/file", rawData)
r, file, err = DownloadTryCompression(d, "http://example.com/file", expectedChecksums, false, 1)
r, file, err = DownloadTryCompression(d, s.baseURL, "file", expectedChecksums, false, 1)
c.Assert(err, IsNil)
defer file.Close()
io.ReadFull(r, buf)
@@ -84,14 +91,35 @@ func (s *CompressionSuite) TestDownloadTryCompression(c *C) {
d = NewFakeDownloader()
d.ExpectError("http://example.com/file.bz2", &Error{Code: 404})
d.ExpectResponse("http://example.com/file.gz", "x")
_, _, err = DownloadTryCompression(d, "http://example.com/file", nil, true, 1)
_, _, err = DownloadTryCompression(d, s.baseURL, "file", nil, true, 1)
c.Assert(err, ErrorMatches, "unexpected EOF")
c.Assert(d.Empty(), Equals, true)
}
func (s *CompressionSuite) TestDownloadTryCompressionLongestSuffix(c *C) {
var buf []byte
expectedChecksums := map[string]utils.ChecksumInfo{
"file.bz2": {Size: 1},
"subdir/file.bz2": {Size: int64(len(bzipData))},
"otherdir/file.bz2": {Size: 1},
}
// longest suffix should be picked up
buf = make([]byte, 4)
d := NewFakeDownloader()
d.ExpectResponse("http://example.com/subdir/file.bz2", bzipData)
r, file, err := DownloadTryCompression(d, s.baseURL, "subdir/file", expectedChecksums, false, 1)
c.Assert(err, IsNil)
defer file.Close()
io.ReadFull(r, buf)
c.Assert(string(buf), Equals, rawData)
c.Assert(d.Empty(), Equals, true)
}
func (s *CompressionSuite) TestDownloadTryCompressionErrors(c *C) {
d := NewFakeDownloader()
_, _, err := DownloadTryCompression(d, "http://example.com/file", nil, true, 1)
_, _, err := DownloadTryCompression(d, s.baseURL, "file", nil, true, 1)
c.Assert(err, ErrorMatches, "unexpected request.*")
d = NewFakeDownloader()
@@ -99,7 +127,7 @@ func (s *CompressionSuite) TestDownloadTryCompressionErrors(c *C) {
d.ExpectError("http://example.com/file.gz", &Error{Code: 404})
d.ExpectError("http://example.com/file.xz", &Error{Code: 404})
d.ExpectError("http://example.com/file", errors.New("403"))
_, _, err = DownloadTryCompression(d, "http://example.com/file", nil, true, 1)
_, _, err = DownloadTryCompression(d, s.baseURL, "file", nil, true, 1)
c.Assert(err, ErrorMatches, "403")
d = NewFakeDownloader()
@@ -113,6 +141,6 @@ func (s *CompressionSuite) TestDownloadTryCompressionErrors(c *C) {
"file.xz": {Size: 7},
"file": {Size: 7},
}
_, _, err = DownloadTryCompression(d, "http://example.com/file", expectedChecksums, false, 1)
_, _, err = DownloadTryCompression(d, s.baseURL, "file", expectedChecksums, false, 1)
c.Assert(err, ErrorMatches, "checksums don't match.*")
}

View File

@@ -0,0 +1,98 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.13 (Darwin)
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
RiU9bhqMiXthkmmYFsCA40tGoVY39PWzZg==
=C8n/
-----END PGP PUBLIC KEY BLOCK-----

View File

@@ -136,6 +136,7 @@ class BaseTest(object):
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "debian-archive-keyring.gpg"),
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "launchpad.key"),
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "flat.key"),
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "pagerduty.key"),
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "jenkins.key")])
if hasattr(self, "fixtureCmds"):

View File

@@ -0,0 +1,11 @@
Downloading http://packages.pagerduty.com/pdagent/deb/InRelease...
Downloading http://packages.pagerduty.com/pdagent/deb/Release...
Downloading http://packages.pagerduty.com/pdagent/deb/Release.gpg...
gpgv: RSA key ID F8253540
gpgv: Good signature from "Package Maintainer (PagerDuty, Inc.) <packages@pagerduty.com>"
Downloading & parsing package files...
Downloading http://packages.pagerduty.com/pdagent/deb/Packages.gz...
Building download queue...
Download queue: 13 items (1.66 MiB)
Mirror `pagerduty` has been successfully updated.

View File

@@ -311,3 +311,19 @@ class UpdateMirror18Test(BaseTest):
super(UpdateMirror18Test, self).check()
# check pool
self.check_exists('pool/c7/6b/4bd12fd92e4dfe1b55b18a67a669_libboost-program-options-dev_1.49.0.1_i386.deb')
class UpdateMirror19Test(BaseTest):
"""
update mirrors: correct matching of Release checksums
"""
longTest = False
fixtureGpg = True
fixtureCmds = [
"aptly mirror create --keyring=aptlytest.gpg pagerduty http://packages.pagerduty.com/pdagent deb/"
]
runCmd = "aptly mirror update --keyring=aptlytest.gpg pagerduty"
outputMatchPrepare = filterOutSignature
def output_processor(self, output):
return "\n".join(line for line in output.split("\n") if ".deb" not in line)