github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/pkg/cache/volume_cache.go (about) 1 package cache 2 3 import ( 4 "context" 5 "crypto/sha256" 6 "fmt" 7 "strings" 8 9 "github.com/docker/docker/client" 10 "github.com/google/go-containerregistry/pkg/name" 11 12 "github.com/buildpacks/pack/internal/paths" 13 ) 14 15 type VolumeCache struct { 16 docker DockerClient 17 volume string 18 } 19 20 func NewVolumeCache(imageRef name.Reference, cacheType CacheInfo, suffix string, dockerClient DockerClient) *VolumeCache { 21 var volumeName string 22 if cacheType.Source == "" { 23 sum := sha256.Sum256([]byte(imageRef.Name())) 24 vol := paths.FilterReservedNames(fmt.Sprintf("%s-%x", sanitizedRef(imageRef), sum[:6])) 25 volumeName = fmt.Sprintf("pack-cache-%s.%s", vol, suffix) 26 } else { 27 volumeName = paths.FilterReservedNames(cacheType.Source) 28 } 29 30 return &VolumeCache{ 31 volume: volumeName, 32 docker: dockerClient, 33 } 34 } 35 36 func (c *VolumeCache) Name() string { 37 return c.volume 38 } 39 40 func (c *VolumeCache) Clear(ctx context.Context) error { 41 err := c.docker.VolumeRemove(ctx, c.Name(), true) 42 if err != nil && !client.IsErrNotFound(err) { 43 return err 44 } 45 return nil 46 } 47 48 func (c *VolumeCache) Type() Type { 49 return Volume 50 } 51 52 // note image names and volume names are validated using the same restrictions: 53 // see https://github.com/moby/moby/blob/f266f13965d5bfb1825afa181fe6c32f3a597fa3/daemon/names/names.go#L5 54 func sanitizedRef(ref name.Reference) string { 55 result := strings.TrimPrefix(ref.Context().String(), ref.Context().RegistryStr()+"/") 56 result = strings.ReplaceAll(result, "/", "_") 57 return fmt.Sprintf("%s_%s", result, ref.Identifier()) 58 }