github.com/mgoltzsche/ctnr@v0.7.1-alpha/image/builder/buildcache.go (about) 1 package builder 2 3 import ( 4 "fmt" 5 "path/filepath" 6 7 exterrors "github.com/mgoltzsche/ctnr/pkg/errors" 8 "github.com/mgoltzsche/ctnr/pkg/fs/source" 9 "github.com/mgoltzsche/ctnr/pkg/log" 10 digest "github.com/opencontainers/go-digest" 11 "github.com/pkg/errors" 12 ) 13 14 type ImageBuildCache interface { 15 GetCachedImageId(parent *digest.Digest, uniqHistoryEntry string) (digest.Digest, error) 16 PutCachedImageId(parent *digest.Digest, uniqHistoryEntry string, child digest.Digest) error 17 HttpHeaderCache(image *digest.Digest) source.HttpHeaderCache 18 // TODO: add HttpEtagCache 19 } 20 21 type noOpCache string 22 23 func (_ noOpCache) GetCachedImageId(parent *digest.Digest, uniqHistoryEntry string) (d digest.Digest, err error) { 24 err = exterrors.Typed(errCacheKeyNotExist, "image build cache is disabled") 25 return 26 } 27 28 func (_ noOpCache) PutCachedImageId(parent *digest.Digest, uniqHistoryEntry string, child digest.Digest) error { 29 return nil 30 } 31 32 func (_ noOpCache) HttpHeaderCache(image *digest.Digest) source.HttpHeaderCache { 33 return source.NoopHttpHeaderCache("NoopHttpHeaderCache") 34 } 35 36 func NewNoOpCache() ImageBuildCache { 37 return noOpCache("image build cache disabled") 38 } 39 40 type imageBuildCache struct { 41 dir string 42 warn log.FieldLogger 43 } 44 45 func NewImageBuildCache(dir string, warn log.FieldLogger) ImageBuildCache { 46 return &imageBuildCache{dir, warn} 47 } 48 49 func (s *imageBuildCache) GetCachedImageId(parent *digest.Digest, uniqHistoryEntry string) (child digest.Digest, err error) { 50 c := s.cache(parent, uniqHistoryEntry) 51 cached, err := c.Get(uniqHistoryEntry) 52 if err == nil { 53 if child, err = digest.Parse(cached); err == nil { 54 if err = child.Validate(); err != nil { 55 msg := fmt.Sprintf("invalid cache value %q found in %s: %s", child, c.file, err) 56 s.warn.Println(msg) 57 err = exterrors.Typed(errCacheKeyNotExist, msg) 58 child = digest.Digest("") 59 } 60 } 61 } 62 return child, errors.Wrap(err, "build cache: get imageId") 63 } 64 65 func (s *imageBuildCache) PutCachedImageId(parent *digest.Digest, uniqHistoryEntry string, child digest.Digest) (err error) { 66 c := s.cache(parent, uniqHistoryEntry) 67 err = c.Put(uniqHistoryEntry, child.String()) 68 return errors.Wrap(err, "build cache: put imageId") 69 } 70 71 func (s *imageBuildCache) cache(image *digest.Digest, uniqHistoryEntry string) CacheFile { 72 var file string 73 d := digest.SHA256.FromString(uniqHistoryEntry) 74 warn := s.warn 75 if image == nil { 76 file = filepath.Join(s.dir, "default", uniqHistoryEntry, d.Algorithm().String(), d.Hex()) 77 } else { 78 warn = s.warn.WithField("image", image.String()) 79 file = filepath.Join(s.dir, (*image).Algorithm().String(), (*image).Hex(), d.Algorithm().String(), d.Hex()) 80 } 81 return NewCacheFile(file, warn) 82 } 83 84 func (s *imageBuildCache) HttpHeaderCache(image *digest.Digest) source.HttpHeaderCache { 85 var dir string 86 if image == nil { 87 dir = filepath.Join(s.dir, "default") 88 } else { 89 dir = filepath.Join(s.dir, (*image).Algorithm().String(), (*image).Hex(), "http") 90 } 91 return source.NewHttpHeaderCache(dir) 92 }