diff --git a/pkg/v1/cache/cache.go b/pkg/v1/cache/cache.go index 83040767d..31d9c935c 100644 --- a/pkg/v1/cache/cache.go +++ b/pkg/v1/cache/cache.go @@ -156,3 +156,39 @@ func (i *image) LayerByDiffID(h v1.Hash) (v1.Layer, error) { } return l, err } + +// ImageIndex returns a new ImageIndex which wraps the given ImageIndex's +// children with either Image(child, c) or ImageIndex(child, c) depending on type. +func ImageIndex(ii v1.ImageIndex, c Cache) v1.ImageIndex { + return &imageIndex{ + inner: ii, + c: c, + } +} + +type imageIndex struct { + inner v1.ImageIndex + c Cache +} + +func (ii *imageIndex) MediaType() (types.MediaType, error) { return ii.inner.MediaType() } +func (ii *imageIndex) Digest() (v1.Hash, error) { return ii.inner.Digest() } +func (ii *imageIndex) Size() (int64, error) { return ii.inner.Size() } +func (ii *imageIndex) IndexManifest() (*v1.IndexManifest, error) { return ii.inner.IndexManifest() } +func (ii *imageIndex) RawManifest() ([]byte, error) { return ii.inner.RawManifest() } + +func (ii *imageIndex) Image(h v1.Hash) (v1.Image, error) { + i, err := ii.inner.Image(h) + if err != nil { + return nil, err + } + return Image(i, ii.c), nil +} + +func (ii *imageIndex) ImageIndex(h v1.Hash) (v1.ImageIndex, error) { + idx, err := ii.inner.ImageIndex(h) + if err != nil { + return nil, err + } + return ImageIndex(idx, ii.c), nil +} diff --git a/pkg/v1/cache/cache_test.go b/pkg/v1/cache/cache_test.go index fe7727007..d232564b1 100644 --- a/pkg/v1/cache/cache_test.go +++ b/pkg/v1/cache/cache_test.go @@ -21,6 +21,7 @@ import ( "testing" v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/mutate" "github.com/google/go-containerregistry/pkg/v1/random" "github.com/google/go-containerregistry/pkg/v1/validate" ) @@ -42,6 +43,30 @@ func TestImage(t *testing.T) { } } +func TestImageIndex(t *testing.T) { + // ImageIndex with child Image and ImageIndex manifests. + ii, err := random.Index(1024, 5, 2) + if err != nil { + t.Fatalf("random.Index: %v", err) + } + iiChild, err := random.Index(1024, 5, 2) + if err != nil { + t.Fatalf("random.Index: %v", err) + } + ii = mutate.AppendManifests(ii, mutate.IndexAddendum{Add: iiChild}) + + m := &memcache{map[v1.Hash]v1.Layer{}} + ii = ImageIndex(ii, m) + + // Validate twice to hit the cache. + if err := validate.Index(ii); err != nil { + t.Errorf("Validate: %v", err) + } + if err := validate.Index(ii); err != nil { + t.Errorf("Validate: %v", err) + } +} + func TestLayersLazy(t *testing.T) { img, err := random.Image(1024, 5) if err != nil {