Local package pool and local publishing rewritten with new constraints

Local package pool now implements more generic package pool API.
The base idea is to never expose full paths to files, so that other
kinds of package pools (e.g. package pool in S3) could be used to implement
the same interface.

Files get into the pool only using `Import` method. `Import` method is
now more smart, it supports moving files into the pool, it can detect if
files reside on the same filesystem and use hardlinking instead of copying.
This will make direct mirror downloads still as fast as they were with previous
version which was performing download directly to package pool.

New package pool doesn't have two things implemented yet:

1. New file placement according to SHA256 or other configured hash

2. Calculate at least SHA256/MD5 for each imported files.
MD5 would be required for S3/Swift publishing
This commit is contained in:
Andrey Smirnov
2017-04-06 20:06:15 +03:00
parent 94b49818a1
commit 7bad358408
4 changed files with 294 additions and 106 deletions
+32 -8
View File
@@ -114,13 +114,11 @@ func (storage *PublishedStorage) RemoveDirs(path string, progress aptly.Progress
//
// publishedDirectory is desired location in pool (like prefix/pool/component/liba/libav/)
// sourcePool is instance of aptly.PackagePool
// sourcePath is filepath to package file in package pool
// sourcePath is a relative path to package file in package pool
//
// LinkFromPool returns relative path for the published file to be included in package index
func (storage *PublishedStorage) LinkFromPool(publishedDirectory string, sourcePool aptly.PackagePool,
sourcePath string, sourceChecksums utils.ChecksumInfo, force bool) error {
// verify that package pool is local pool is filesystem pool
_ = sourcePool.(*PackagePool)
baseName := filepath.Base(sourcePath)
poolPath := filepath.Join(storage.rootPath, publishedDirectory)
@@ -135,7 +133,7 @@ func (storage *PublishedStorage) LinkFromPool(publishedDirectory string, sourceP
dstStat, err = os.Stat(filepath.Join(poolPath, baseName))
if err == nil {
// already exists, check source file
srcStat, err = os.Stat(sourcePath)
srcStat, err = sourcePool.Stat(sourcePath)
if err != nil {
// source file doesn't exist? problem!
return err
@@ -184,13 +182,39 @@ func (storage *PublishedStorage) LinkFromPool(publishedDirectory string, sourceP
}
}
// destination doesn't exist (or forced), create link
// destination doesn't exist (or forced), create link or copy
if storage.linkMethod == LinkMethodCopy {
err = utils.CopyFile(sourcePath, filepath.Join(poolPath, baseName))
var r aptly.ReadSeekerCloser
r, err = sourcePool.Open(sourcePath)
if err != nil {
return err
}
var dst *os.File
dst, err = os.Create(filepath.Join(poolPath, baseName))
if err != nil {
r.Close()
return err
}
_, err = io.Copy(dst, r)
if err != nil {
r.Close()
dst.Close()
return err
}
err = r.Close()
if err != nil {
dst.Close()
return err
}
err = dst.Close()
} else if storage.linkMethod == LinkMethodSymLink {
err = os.Symlink(sourcePath, filepath.Join(poolPath, baseName))
err = sourcePool.(aptly.LocalPackagePool).Symlink(sourcePath, filepath.Join(poolPath, baseName))
} else {
err = os.Link(sourcePath, filepath.Join(poolPath, baseName))
err = sourcePool.(aptly.LocalPackagePool).Link(sourcePath, filepath.Join(poolPath, baseName))
}
return err