Refactoring: use checksums instead of MD5 for pool/published

This is related to #506

As a first step, don't pass MD5 explicitly, pass checksum info object,
so that as a next step we can choose which hash to use.

There should be no functional changes so far.

Next step: stop returning explicit paths from public package pool.
This commit is contained in:
Andrey Smirnov
2017-04-01 00:09:34 +03:00
parent 675d35c7a1
commit 50cf2b49bd
16 changed files with 77 additions and 53 deletions
+10 -7
View File
@@ -9,6 +9,7 @@ import (
"sync"
"github.com/smira/aptly/aptly"
"github.com/smira/aptly/utils"
)
// PackagePool is deduplicated storage of package files on filesystem
@@ -27,13 +28,15 @@ func NewPackagePool(root string) *PackagePool {
return &PackagePool{rootPath: filepath.Join(root, "pool")}
}
// RelativePath returns path relative to pool's root for package files given MD5 and original filename
func (pool *PackagePool) RelativePath(filename string, hashMD5 string) (string, error) {
// RelativePath returns path relative to pool's root for package files given checksum info and original filename
func (pool *PackagePool) RelativePath(filename string, checksums utils.ChecksumInfo) (string, error) {
filename = filepath.Base(filename)
if filename == "." || filename == "/" {
return "", fmt.Errorf("filename %s is invalid", filename)
}
hashMD5 := checksums.MD5
if len(hashMD5) < 4 {
return "", fmt.Errorf("unable to compute pool location for filename %v, MD5 is missing", filename)
}
@@ -41,9 +44,9 @@ func (pool *PackagePool) RelativePath(filename string, hashMD5 string) (string,
return filepath.Join(hashMD5[0:2], hashMD5[2:4], filename), nil
}
// Path returns full path to package file in pool given any name and hash of file contents
func (pool *PackagePool) Path(filename string, hashMD5 string) (string, error) {
relative, err := pool.RelativePath(filename, hashMD5)
// Path returns full path to package file in pool given filename and hash of file contents
func (pool *PackagePool) Path(filename string, checksums utils.ChecksumInfo) (string, error) {
relative, err := pool.RelativePath(filename, checksums)
if err != nil {
return "", err
}
@@ -114,7 +117,7 @@ func (pool *PackagePool) Remove(path string) (size int64, err error) {
}
// Import copies file into package pool
func (pool *PackagePool) Import(path string, hashMD5 string) error {
func (pool *PackagePool) Import(path string, checksums utils.ChecksumInfo) error {
pool.Lock()
defer pool.Unlock()
@@ -129,7 +132,7 @@ func (pool *PackagePool) Import(path string, hashMD5 string) error {
return err
}
poolPath, err := pool.Path(path, hashMD5)
poolPath, err := pool.Path(path, checksums)
if err != nil {
return err
}
+17 -12
View File
@@ -6,39 +6,44 @@ import (
"path/filepath"
"runtime"
"github.com/smira/aptly/utils"
. "gopkg.in/check.v1"
)
type PackagePoolSuite struct {
pool *PackagePool
pool *PackagePool
checksum utils.ChecksumInfo
}
var _ = Suite(&PackagePoolSuite{})
func (s *PackagePoolSuite) SetUpTest(c *C) {
s.pool = NewPackagePool(c.MkDir())
s.checksum = utils.ChecksumInfo{
MD5: "91b1a1480b90b9e269ca44d897b12575",
}
}
func (s *PackagePoolSuite) TestRelativePath(c *C) {
path, err := s.pool.RelativePath("a/b/package.deb", "91b1a1480b90b9e269ca44d897b12575")
path, err := s.pool.RelativePath("a/b/package.deb", s.checksum)
c.Assert(err, IsNil)
c.Assert(path, Equals, "91/b1/package.deb")
_, err = s.pool.RelativePath("/", "91b1a1480b90b9e269ca44d897b12575")
_, err = s.pool.RelativePath("/", s.checksum)
c.Assert(err, ErrorMatches, ".*is invalid")
_, err = s.pool.RelativePath("", "91b1a1480b90b9e269ca44d897b12575")
_, err = s.pool.RelativePath("", s.checksum)
c.Assert(err, ErrorMatches, ".*is invalid")
_, err = s.pool.RelativePath("a/b/package.deb", "9")
_, err = s.pool.RelativePath("a/b/package.deb", utils.ChecksumInfo{MD5: "9"})
c.Assert(err, ErrorMatches, ".*MD5 is missing")
}
func (s *PackagePoolSuite) TestPath(c *C) {
path, err := s.pool.Path("a/b/package.deb", "91b1a1480b90b9e269ca44d897b12575")
path, err := s.pool.Path("a/b/package.deb", s.checksum)
c.Assert(err, IsNil)
c.Assert(path, Equals, filepath.Join(s.pool.rootPath, "91/b1/package.deb"))
_, err = s.pool.Path("/", "91b1a1480b90b9e269ca44d897b12575")
_, err = s.pool.Path("/", s.checksum)
c.Assert(err, ErrorMatches, ".*is invalid")
}
@@ -91,7 +96,7 @@ func (s *PackagePoolSuite) TestImportOk(c *C) {
_, _File, _, _ := runtime.Caller(0)
debFile := filepath.Join(filepath.Dir(_File), "../system/files/libboost-program-options-dev_1.49.0.1_i386.deb")
err := s.pool.Import(debFile, "91b1a1480b90b9e269ca44d897b12575")
err := s.pool.Import(debFile, s.checksum)
c.Check(err, IsNil)
info, err := os.Stat(filepath.Join(s.pool.rootPath, "91", "b1", "libboost-program-options-dev_1.49.0.1_i386.deb"))
@@ -99,12 +104,12 @@ func (s *PackagePoolSuite) TestImportOk(c *C) {
c.Check(info.Size(), Equals, int64(2738))
// double import, should be ok
err = s.pool.Import(debFile, "91b1a1480b90b9e269ca44d897b12575")
err = s.pool.Import(debFile, s.checksum)
c.Check(err, IsNil)
}
func (s *PackagePoolSuite) TestImportNotExist(c *C) {
err := s.pool.Import("no-such-file", "91b1a1480b90b9e269ca44d897b12575")
err := s.pool.Import("no-such-file", s.checksum)
c.Check(err, ErrorMatches, ".*no such file or directory")
}
@@ -115,6 +120,6 @@ func (s *PackagePoolSuite) TestImportOverwrite(c *C) {
os.MkdirAll(filepath.Join(s.pool.rootPath, "91", "b1"), 0755)
ioutil.WriteFile(filepath.Join(s.pool.rootPath, "91", "b1", "libboost-program-options-dev_1.49.0.1_i386.deb"), []byte("1"), 0644)
err := s.pool.Import(debFile, "91b1a1480b90b9e269ca44d897b12575")
err := s.pool.Import(debFile, s.checksum)
c.Check(err, ErrorMatches, "unable to import into pool.*")
}
+2 -1
View File
@@ -8,6 +8,7 @@ import (
"syscall"
"github.com/smira/aptly/aptly"
"github.com/smira/aptly/utils"
)
// PublishedStorage abstract file system with public dirs (published repos)
@@ -81,7 +82,7 @@ func (storage *PublishedStorage) RemoveDirs(path string, progress aptly.Progress
//
// LinkFromPool returns relative path for the published file to be included in package index
func (storage *PublishedStorage) LinkFromPool(publishedDirectory string, sourcePool aptly.PackagePool,
sourcePath, sourceMD5 string, force bool) error {
sourcePath string, sourceChecksums utils.ChecksumInfo, force bool) error {
// verify that package pool is local pool is filesystem pool
_ = sourcePool.(*PackagePool)
+5 -3
View File
@@ -6,6 +6,8 @@ import (
"path/filepath"
"syscall"
"github.com/smira/aptly/utils"
. "gopkg.in/check.v1"
)
@@ -154,7 +156,7 @@ func (s *PublishedStorageSuite) TestLinkFromPool(c *C) {
err = ioutil.WriteFile(t.sourcePath, []byte("Contents"), 0644)
c.Assert(err, IsNil)
err = s.storage.LinkFromPool(filepath.Join(t.prefix, "pool", t.component, t.poolDirectory), pool, t.sourcePath, "", false)
err = s.storage.LinkFromPool(filepath.Join(t.prefix, "pool", t.component, t.poolDirectory), pool, t.sourcePath, utils.ChecksumInfo{}, false)
c.Assert(err, IsNil)
st, err := os.Stat(filepath.Join(s.storage.rootPath, t.prefix, t.expectedFilename))
@@ -172,7 +174,7 @@ func (s *PublishedStorageSuite) TestLinkFromPool(c *C) {
err = ioutil.WriteFile(sourcePath, []byte("Contents"), 0644)
c.Assert(err, IsNil)
err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, "", false)
err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, utils.ChecksumInfo{}, false)
c.Check(err, ErrorMatches, ".*file already exists and is different")
st, err := os.Stat(sourcePath)
@@ -182,7 +184,7 @@ func (s *PublishedStorageSuite) TestLinkFromPool(c *C) {
c.Check(int(info.Nlink), Equals, 1)
// linking with force
err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, "", true)
err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, utils.ChecksumInfo{}, true)
c.Check(err, IsNil)
st, err = os.Stat(sourcePath)