1package tarball
2
3import (
4	"crypto/sha1"
5	"fmt"
6	"os"
7	"path/filepath"
8
9	bosherr "github.com/cloudfoundry/bosh-utils/errors"
10	boshfu "github.com/cloudfoundry/bosh-utils/fileutil"
11	boshlog "github.com/cloudfoundry/bosh-utils/logger"
12	boshsys "github.com/cloudfoundry/bosh-utils/system"
13)
14
15type Cache interface {
16	Get(source Source) (path string, found bool)
17	Path(source Source) (path string)
18	Save(sourcePath string, source Source) error
19}
20
21type cache struct {
22	basePath string
23	fs       boshsys.FileSystem
24	logger   boshlog.Logger
25	logTag   string
26}
27
28func NewCache(basePath string, fs boshsys.FileSystem, logger boshlog.Logger) Cache {
29	return &cache{
30		basePath: basePath,
31		fs:       fs,
32		logger:   logger,
33		logTag:   "tarballCache",
34	}
35}
36
37func (c *cache) Get(source Source) (string, bool) {
38	cachedPath := c.Path(source)
39	if c.fs.FileExists(cachedPath) {
40		c.logger.Debug(c.logTag, "Found cached tarball at: '%s'", cachedPath)
41		return cachedPath, true
42	}
43
44	return "", false
45}
46
47func (c *cache) Save(sourcePath string, source Source) error {
48	err := c.fs.MkdirAll(c.basePath, os.FileMode(0766))
49	if err != nil {
50		return bosherr.WrapErrorf(err, "Failed to create cache directory '%s'", c.basePath)
51	}
52
53	err = boshfu.NewFileMover(c.fs).Move(sourcePath, c.Path(source))
54	if err != nil {
55		return bosherr.WrapErrorf(err, "Failed to save tarball path '%s' in cache", sourcePath)
56	}
57
58	c.logger.Debug(c.logTag, "Saving tarball in cache at: '%s'", c.Path(source))
59	return nil
60}
61
62func (c *cache) Path(source Source) string {
63	urlSHA1 := sha1.Sum([]byte(source.GetURL()))
64	filename := fmt.Sprintf("%x-%s", string(urlSHA1[:]), source.GetSHA1())
65	return filepath.Join(c.basePath, filename)
66}
67