github.com/drone/drone-cache-lib@v0.0.0-20200806063744-981868645a25/cache/cache.go (about) 1 package cache 2 3 import ( 4 "io" 5 6 log "github.com/sirupsen/logrus" 7 "github.com/drone/drone-cache-lib/archive" 8 "github.com/drone/drone-cache-lib/archive/tar" 9 "github.com/drone/drone-cache-lib/storage" 10 ) 11 12 // Cache defines a basic cache object. 13 type Cache struct { 14 s storage.Storage 15 a archive.Archive 16 } 17 18 // New creates a new cache object. 19 func New(s storage.Storage, a archive.Archive) Cache { 20 return Cache{s: s, a: a} 21 } 22 23 // NewDefault creates a new cache object with tar format. 24 func NewDefault(s storage.Storage) Cache { 25 // Return default Cache that uses tar and flushes items after 7 days 26 return New(s, tar.New()) 27 } 28 29 // Rebuild rebuilds the new cache. 30 func (c Cache) Rebuild(srcs []string, dst string) error { 31 return rebuildCache(srcs, dst, c.s, c.a) 32 } 33 34 // Restore restores the existing cache. 35 func (c Cache) Restore(src string, fallback string) error { 36 err := restoreCache(src, c.s, c.a) 37 38 if err != nil && fallback != "" && fallback != src { 39 log.Warnf("Failed to retrieve %s, trying %s", src, fallback) 40 err = restoreCache(fallback, c.s, c.a) 41 } 42 43 // Cache plugin should print an error but it should not return it 44 // this is so the build continues even if the cache cant be restored 45 if err != nil { 46 log.Warnf("Cache could not be restored %s", err) 47 } 48 49 return nil 50 } 51 52 func restoreCache(src string, s storage.Storage, a archive.Archive) error { 53 reader, writer := io.Pipe() 54 55 cw := make(chan error, 1) 56 defer close(cw) 57 58 go func() { 59 defer writer.Close() 60 61 cw <- s.Get(src, writer) 62 }() 63 64 err := a.Unpack("", reader) 65 werr := <-cw 66 67 if werr != nil { 68 return werr 69 } 70 71 return err 72 } 73 74 func rebuildCache(srcs []string, dst string, s storage.Storage, a archive.Archive) error { 75 log.Infof("Rebuilding cache at %s to %s", srcs, dst) 76 77 reader, writer := io.Pipe() 78 defer reader.Close() 79 80 cw := make(chan error, 1) 81 defer close(cw) 82 83 go func() { 84 defer writer.Close() 85 86 cw <- a.Pack(srcs, writer) 87 }() 88 89 err := s.Put(dst, reader) 90 werr := <-cw 91 92 if werr != nil { 93 return werr 94 } 95 96 return err 97 }