diff --git a/internal/cache/volume_cache.go b/internal/cache/volume_cache.go index 25abd7f3db..fa0124e50a 100644 --- a/internal/cache/volume_cache.go +++ b/internal/cache/volume_cache.go @@ -4,6 +4,7 @@ import ( "context" "crypto/sha256" "fmt" + "strings" "github.com/docker/docker/client" "github.com/google/go-containerregistry/pkg/name" @@ -19,7 +20,7 @@ type VolumeCache struct { func NewVolumeCache(imageRef name.Reference, suffix string, dockerClient client.CommonAPIClient) *VolumeCache { sum := sha256.Sum256([]byte(imageRef.Name())) - vol := paths.FilterReservedNames(fmt.Sprintf("%x", sum[:6])) + vol := paths.FilterReservedNames(fmt.Sprintf("%s-%x", sanitizedRef(imageRef), sum[:6])) return &VolumeCache{ volume: fmt.Sprintf("pack-cache-%s.%s", vol, suffix), docker: dockerClient, @@ -41,3 +42,11 @@ func (c *VolumeCache) Clear(ctx context.Context) error { func (c *VolumeCache) Type() Type { return Volume } + +// note image names and volume names are validated using the same restrictions: +// see https://github.com/moby/moby/blob/f266f13965d5bfb1825afa181fe6c32f3a597fa3/daemon/names/names.go#L5 +func sanitizedRef(ref name.Reference) string { + result := strings.TrimPrefix(ref.Context().String(), ref.Context().RegistryStr()+"/") + result = strings.ReplaceAll(result, "/", "_") + return fmt.Sprintf("%s_%s", result, ref.Identifier()) +} diff --git a/internal/cache/volume_cache_test.go b/internal/cache/volume_cache_test.go index 2f1388fe8b..9a36489ce9 100644 --- a/internal/cache/volume_cache_test.go +++ b/internal/cache/volume_cache_test.go @@ -10,6 +10,7 @@ import ( "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" + "github.com/docker/docker/daemon/names" "github.com/google/go-containerregistry/pkg/name" "github.com/heroku/color" "github.com/sclevine/spec" @@ -108,6 +109,16 @@ func testCache(t *testing.T, when spec.G, it spec.S) { expected := cache.NewVolumeCache(ref, "some-suffix", dockerClient) h.AssertEq(t, subject.Name(), expected.Name()) }) + + it("includes human readable information", func() { + ref, err := name.ParseReference("myregistryhost:5000/fedora/httpd:version1.0", name.WeakValidation) + h.AssertNil(t, err) + + subject := cache.NewVolumeCache(ref, "some-suffix", dockerClient) + + h.AssertContains(t, subject.Name(), "fedora_httpd_version1.0") + h.AssertTrue(t, names.RestrictedNamePattern.MatchString(subject.Name())) + }) }) when("#Clear", func() {