diff --git a/pkg/sif/image.go b/pkg/sif/image.go index 3835ac3..bee9068 100644 --- a/pkg/sif/image.go +++ b/pkg/sif/image.go @@ -28,15 +28,18 @@ var ( errMultipleMatchingImages = errors.New("multiple images match criteria") ) -// Image returns a single Image stored in f, that is selected by the provided -// Matcher. If more than one image matches, or no image matches, an error is -// returned. +// Image returns a single Image stored in f, that is selected by m. If m is nil, all manifests are +// selected. If more than one image matches, or no image matches, an error is returned. func (f *OCIFileImage) Image(m match.Matcher, _ ...Option) (v1.Image, error) { ri, err := f.RootIndex() if err != nil { return nil, err } + if m == nil { + m = matchAll + } + matches, err := partial.FindImages(ri, m) if err != nil { return nil, err diff --git a/pkg/sif/image_test.go b/pkg/sif/image_test.go index c274570..433e6b8 100644 --- a/pkg/sif/image_test.go +++ b/pkg/sif/image_test.go @@ -106,6 +106,12 @@ func Test_OCIFileImage_Image(t *testing.T) { wantImage: nil, wantErr: true, }, + { + name: "NilMatcher", + matcher: nil, + wantImage: nil, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/sif/index.go b/pkg/sif/index.go index ee17ae2..480c177 100644 --- a/pkg/sif/index.go +++ b/pkg/sif/index.go @@ -72,15 +72,18 @@ var ( errMultipleMatchingIndices = errors.New("multiple indices match criteria") ) -// Index returns a single ImageIndex stored in f, that is selected by the provided -// Matcher. If more than one index matches, or no index matches, an error is -// returned. +// Index returns a single ImageIndex stored in f, that is selected by m. If m is nil, all manifests +// are selected. If more than one index matches, or no image matches, an error is returned. func (f *OCIFileImage) Index(m match.Matcher, _ ...Option) (v1.ImageIndex, error) { ri, err := f.RootIndex() if err != nil { return nil, err } + if m == nil { + m = matchAll + } + matches, err := partial.FindIndexes(ri, m) if err != nil { return nil, err diff --git a/pkg/sif/index_test.go b/pkg/sif/index_test.go index 53afe5e..fa08116 100644 --- a/pkg/sif/index_test.go +++ b/pkg/sif/index_test.go @@ -163,6 +163,12 @@ func Test_OCIFileImage_Index(t *testing.T) { wantIndex: nil, wantErr: true, }, + { + name: "NilMatcher", + matcher: nil, + wantIndex: nil, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/sif/match.go b/pkg/sif/match.go new file mode 100644 index 0000000..38eaa91 --- /dev/null +++ b/pkg/sif/match.go @@ -0,0 +1,9 @@ +// Copyright 2024 Sylabs Inc. All rights reserved. +// +// SPDX-License-Identifier: Apache-2.0 + +package sif + +import v1 "github.com/google/go-containerregistry/pkg/v1" + +func matchAll(v1.Descriptor) bool { return true } diff --git a/pkg/sif/testdata/TestRemoveManifests/NilMatcher.golden b/pkg/sif/testdata/TestRemoveManifests/NilMatcher.golden new file mode 100644 index 0000000..dc375f5 Binary files /dev/null and b/pkg/sif/testdata/TestRemoveManifests/NilMatcher.golden differ diff --git a/pkg/sif/testdata/TestReplace/ReplaceImageNilMatcher.golden b/pkg/sif/testdata/TestReplace/ReplaceImageNilMatcher.golden new file mode 100644 index 0000000..a650261 Binary files /dev/null and b/pkg/sif/testdata/TestReplace/ReplaceImageNilMatcher.golden differ diff --git a/pkg/sif/testdata/TestReplace/ReplaceIndexNilMatcher.golden b/pkg/sif/testdata/TestReplace/ReplaceIndexNilMatcher.golden new file mode 100644 index 0000000..cdec4e3 Binary files /dev/null and b/pkg/sif/testdata/TestReplace/ReplaceIndexNilMatcher.golden differ diff --git a/pkg/sif/update.go b/pkg/sif/update.go index 20fa460..d51301b 100644 --- a/pkg/sif/update.go +++ b/pkg/sif/update.go @@ -461,31 +461,40 @@ func (f *OCIFileImage) RemoveBlob(hash v1.Hash) error { sif.OptDeleteCompact(true)) } -// RemoveManifests modifies the SIF file associated with f so that its RootIndex -// no longer holds manifests selected by matcher. Any blobs in the SIF that are -// no longer referenced are removed from the SIF. +// RemoveManifests modifies the SIF file associated with f so that its +// RootIndex no longer holds manifests selected by matcher. If m is nil, all +// manifests are selected. Any blobs in the SIF that are no longer referenced +// are removed from the SIF. func (f *OCIFileImage) RemoveManifests(matcher match.Matcher) error { ri, err := f.RootIndex() if err != nil { return err } + + if matcher == nil { + matcher = matchAll + } + return f.UpdateRootIndex(mutate.RemoveManifests(ri, matcher)) } // ReplaceImage writes img to the SIF, replacing any existing manifest that is -// selected by the matcher. Any blobs in the SIF that are no longer referenced -// are removed from the SIF. +// selected by the matcher. If m is nil, all manifests are selected. Any blobs +// in the SIF that are no longer referenced are removed from the SIF. func (f *OCIFileImage) ReplaceImage(img v1.Image, matcher match.Matcher, opts ...AppendOpt) error { return f.replace(img, matcher, opts...) } // ReplaceIndex writes ii to the SIF, replacing any existing manifest that is -// selected by the matcher. Any blobs in the SIF that are no longer referenced -// are removed from the SIF. +// selected by the matcher. If m is nil, all manifests are selected. Any blobs +// in the SIF that are no longer referenced are removed from the SIF. func (f *OCIFileImage) ReplaceIndex(ii v1.ImageIndex, matcher match.Matcher, opts ...AppendOpt) error { return f.replace(ii, matcher, opts...) } +// replace writes add to the SIF, replacing any existing manifest that is +// selected by the matcher. If m is nil, all manifests are selected. Any blobs +// in the SIF that are no longer referenced are removed from the SIF. func (f *OCIFileImage) replace(add mutate.Appendable, matcher match.Matcher, opts ...AppendOpt) error { ao := appendOpts{ tempDir: os.TempDir(), @@ -496,6 +505,10 @@ func (f *OCIFileImage) replace(add mutate.Appendable, matcher match.Matcher, opt } } + if matcher == nil { + matcher = matchAll + } + ri, err := f.RootIndex() if err != nil { return err diff --git a/pkg/sif/update_test.go b/pkg/sif/update_test.go index 2cb1ca0..7000e43 100644 --- a/pkg/sif/update_test.go +++ b/pkg/sif/update_test.go @@ -404,6 +404,11 @@ func TestRemoveManifests(t *testing.T) { base: "hello-world-docker-v2-manifest-list", matcher: match.Platforms(v1.Platform{OS: "linux", Architecture: "m68k"}), }, + { + name: "NilMatcher", + base: "hello-world-docker-v2-manifest-list", + matcher: nil, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -478,6 +483,12 @@ func TestReplace(t *testing.T) { replacement: replaceImage, matcher: match.Platforms(v1.Platform{OS: "linux", Architecture: "m68k"}), }, + { + name: "ReplaceImageNilMatcher", + base: "hello-world-docker-v2-manifest", + replacement: replaceImage, + matcher: nil, + }, { name: "ReplaceIndexManifest", base: "hello-world-docker-v2-manifest", @@ -496,6 +507,12 @@ func TestReplace(t *testing.T) { replacement: replaceIndex, matcher: match.Platforms(v1.Platform{OS: "linux", Architecture: "m68k"}), }, + { + name: "ReplaceIndexNilMatcher", + base: "hello-world-docker-v2-manifest", + replacement: replaceIndex, + matcher: nil, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {