Skip to content

Commit

Permalink
feat: AppendImage/Index with optional name.Reference
Browse files Browse the repository at this point in the history
Adds `f.AppendImage` and `f.AppendIndex`, which append a `v1.Image` or a
`v1.ImageIndex` to the SIF, respectively.

The `OptAppendReference` functional option can be used to provide a
`name.Reference` that will be stored as an annotation against the new
descriptor in the RootIndex, with the key
`org.opencontainers.image.ref.name`, as is convention for associating
references with items stored in an OCI layout.

Fixes #83
Fixes #81
  • Loading branch information
dtrudg committed Sep 27, 2024
1 parent f6e9323 commit cd3697a
Showing 1 changed file with 68 additions and 0 deletions.
68 changes: 68 additions & 0 deletions pkg/sif/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (
"path/filepath"
"slices"

"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/google/go-containerregistry/pkg/v1/types"
"github.com/sylabs/sif/v2/pkg/sif"
)
Expand Down Expand Up @@ -330,3 +332,69 @@ func selectBlobsExcept(keep []v1.Hash) sif.DescriptorSelectorFunc {
return false, nil
}
}

// appendOpts accumulates append options.
type appendOpts struct {
tempDir string
ref name.Reference
}

// AppendOpt are used to specify options to apply when appending to a SIF.
type AppendOpt func(*appendOpts) error

// OptAppendTempDir sets the directory to use for temporary files. If not set, the
// directory returned by os.TempDir is used.
func OptAppendTempDir(d string) AppendOpt {
return func(c *appendOpts) error {
c.tempDir = d
return nil
}
}

// OptAppendReference sets the reference to be set for the appended item in the
// RootIndex. The reference is added as an `org.opencontainers.image.ref.name`
// in the RootIndex.
func OptAppendReference(r name.Reference) AppendOpt {
return func(c *appendOpts) error {
c.ref = r
return nil
}
}

// AppendImage appends an image to the SIF f, updating the RootIndex to
// reference it.
func (f *OCIFileImage) AppendImage(img v1.Image, opts ...AppendOpt) error {
return f.append(img, opts...)
}

// AppendIndex appends an index to the SIF f, updating the RootIndex to
// reference it.
func (f *OCIFileImage) AppendIndex(ii v1.ImageIndex, opts ...AppendOpt) error {
return f.append(ii, opts...)
}

func (f *OCIFileImage) append(add mutate.Appendable, opts ...AppendOpt) error {
ao := appendOpts{
tempDir: os.TempDir(),
}
for _, opt := range opts {
if err := opt(&ao); err != nil {
return err
}
}

ri, err := f.RootIndex()
if err != nil {
return err
}

ia := mutate.IndexAddendum{Add: add}
if ao.ref != nil {
ia.Annotations = map[string]string{
"org.opencontainers.image.ref.name": ao.ref.Name(),
}
}
ri = mutate.AppendManifests(ri, ia)

return f.UpdateRootIndex(ri, OptUpdateTempDir(ao.tempDir))
}

0 comments on commit cd3697a

Please sign in to comment.