Skip to content

Commit

Permalink
feat: accept nil match.Matcher
Browse files Browse the repository at this point in the history
Allow the caller to pass a nil value for a match.Matcher in the public
APIs, with the semantics of "match all".
  • Loading branch information
tri-adam committed Oct 7, 2024
1 parent aa3f634 commit 4bb2672
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 13 deletions.
9 changes: 6 additions & 3 deletions pkg/sif/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions pkg/sif/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
9 changes: 6 additions & 3 deletions pkg/sif/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions pkg/sif/index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
9 changes: 9 additions & 0 deletions pkg/sif/match.go
Original file line number Diff line number Diff line change
@@ -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 }
Binary file not shown.
Binary file not shown.
Binary file not shown.
27 changes: 20 additions & 7 deletions pkg/sif/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -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
Expand Down
17 changes: 17 additions & 0 deletions pkg/sif/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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",
Expand All @@ -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) {
Expand Down

0 comments on commit 4bb2672

Please sign in to comment.