Skip to content

Commit

Permalink
sourcesink
Browse files Browse the repository at this point in the history
  • Loading branch information
thesayyn committed Mar 18, 2024
1 parent 4c4c94c commit 2d2b853
Show file tree
Hide file tree
Showing 15 changed files with 144 additions and 142 deletions.
2 changes: 1 addition & 1 deletion cmd/crane/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func New(use, short string, options []crane.Option) *cobra.Command {
}
if uselocal != "" {
p, _ := layout.FromPath(uselocal)
options = append(options, crane.WithPuller(layout.NewPuller(p)), crane.WithPusher(layout.NewPusher(p)))
options = append(options, crane.WithSource(layout.NewSource(p)), crane.WithSink(layout.NewSink(p)))
}
if Version != "" {
binary := "crane"
Expand Down
3 changes: 1 addition & 2 deletions pkg/crane/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"fmt"

"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
)

// Delete deletes the remote reference at src.
Expand All @@ -29,5 +28,5 @@ func Delete(src string, opt ...Option) error {
return fmt.Errorf("parsing reference %q: %w", src, err)
}

return remote.Delete(ref, o.Remote...)
return o.sink.Delete(o.ctx, ref)
}
4 changes: 2 additions & 2 deletions pkg/crane/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func getArtifact(r string, opt ...Option) (partial.Artifact, error) {
if err != nil {
return nil, fmt.Errorf("parsing reference %q: %w", r, err)
}
return remote.Artifact(ref, o.Remote...)
return o.source.Artifact(o.ctx, ref)
}

// Get calls remote.Get and returns an uninterpreted response.
Expand All @@ -58,5 +58,5 @@ func Head(r string, opt ...Option) (*v1.Descriptor, error) {
if err != nil {
return nil, err
}
return remote.Head(ref, o.Remote...)
return o.source.Head(o.ctx, ref)
}
24 changes: 18 additions & 6 deletions pkg/crane/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/sourcesink"
)

// Options hold the options that crane uses when calling other packages.
Expand All @@ -38,6 +39,9 @@ type Options struct {
jobs int
noclobber bool
ctx context.Context

sink sourcesink.Sink
source sourcesink.Source
}

// GetOptions exposes the underlying []remote.Option, []name.Option, and
Expand All @@ -62,6 +66,14 @@ func makeOptions(opts ...Option) Options {
o(&opt)
}

// By default use remote source and sink
if opt.sink == nil {
opt.sink, _ = remote.NewPusher(opt.Remote...)
}
if opt.source == nil {
opt.source, _ = remote.NewPuller(opt.Remote...)
}

// Allow for untrusted certificates if the user
// passed Insecure but no custom transport.
if opt.insecure && opt.Transport == nil {
Expand Down Expand Up @@ -177,16 +189,16 @@ func WithNoClobber(noclobber bool) Option {
}
}

// WithPuller sets the puller for remote
func WithPuller(puller remote.Puller) Option {
// WithSink sets the sink
func WithSink(sink sourcesink.Sink) Option {
return func(o *Options) {
o.Remote = append(o.Remote, remote.WithPuller(puller))
o.sink = sink
}
}

// WithPuller sets the puller for remote
func WithPusher(pusher remote.Pusher) Option {
// WithSource sets the source
func WithSource(source sourcesink.Source) Option {
return func(o *Options) {
o.Remote = append(o.Remote, remote.WithPusher(pusher))
o.source = source
}
}
6 changes: 2 additions & 4 deletions pkg/crane/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (

"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/tarball"
)

Expand Down Expand Up @@ -50,7 +49,7 @@ func Push(img v1.Image, dst string, opt ...Option) error {
if err != nil {
return fmt.Errorf("parsing reference %q: %w", dst, err)
}
return remote.Write(tag, img, o.Remote...)
return o.sink.Push(o.ctx, tag, img)
}

// Upload pushes the v1.Layer to a given repo.
Expand All @@ -60,6 +59,5 @@ func Upload(layer v1.Layer, repo string, opt ...Option) error {
if err != nil {
return fmt.Errorf("parsing repo %q: %w", repo, err)
}

return remote.WriteLayer(ref, layer, o.Remote...)
return o.sink.Upload(o.ctx, ref, layer)
}
30 changes: 14 additions & 16 deletions pkg/v1/layout/pusher.go → pkg/v1/layout/sink.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/partial"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/sourcesink"
"github.com/google/go-containerregistry/pkg/v1/stream"
"github.com/google/go-containerregistry/pkg/v1/types"
specsv1 "github.com/opencontainers/image-spec/specs-go/v1"
Expand Down Expand Up @@ -89,18 +89,16 @@ func unpackTaggable(t partial.WithRawManifest) ([]byte, *v1.Descriptor, error) {
}, nil
}

// Use partial.Artifact to unpack taggable.
// Duplication is not a concern here.
type pusher struct {
type sink struct {
path Path
}

// Delete implements remote.Pusher.
func (lp *pusher) Delete(_ context.Context, _ name.Reference) error {
func (lp *sink) Delete(_ context.Context, _ name.Reference) error {
return errors.New("unsupported operation")
}

func (lp *pusher) writeLayer(l v1.Layer) error {
func (lp *sink) writeLayer(l v1.Layer) error {
dg, err := l.Digest()
if err != nil {
return err
Expand All @@ -116,7 +114,7 @@ func (lp *pusher) writeLayer(l v1.Layer) error {
return nil
}

func (lp *pusher) writeLayers(pctx context.Context, img v1.Image) error {
func (lp *sink) writeLayers(pctx context.Context, img v1.Image) error {
ls, err := img.Layers()
if err != nil {
return err
Expand Down Expand Up @@ -155,7 +153,7 @@ func (lp *pusher) writeLayers(pctx context.Context, img v1.Image) error {
return g.Wait()
}

func (lp *pusher) writeChildren(pctx context.Context, idx v1.ImageIndex) error {
func (lp *sink) writeChildren(pctx context.Context, idx v1.ImageIndex) error {
children, err := partial.Manifests(idx)
if err != nil {
return err
Expand All @@ -173,7 +171,7 @@ func (lp *pusher) writeChildren(pctx context.Context, idx v1.ImageIndex) error {
return g.Wait()
}

func (lp *pusher) writeDeps(ctx context.Context, m partial.Artifact) error {
func (lp *sink) writeDeps(ctx context.Context, m partial.Artifact) error {
if img, ok := m.(v1.Image); ok {
return lp.writeLayers(ctx, img)
}
Expand All @@ -186,7 +184,7 @@ func (lp *pusher) writeDeps(ctx context.Context, m partial.Artifact) error {
return nil
}

func (lp *pusher) writeManifest(ctx context.Context, t partial.WithRawManifest) error {
func (lp *sink) writeManifest(ctx context.Context, t partial.WithRawManifest) error {
m, err := taggableToManifest(t)
if err != nil {
return err
Expand Down Expand Up @@ -220,7 +218,7 @@ func (lp *pusher) writeManifest(ctx context.Context, t partial.WithRawManifest)
return nil
}

func (lp *pusher) writeChild(ctx context.Context, child partial.Describable, g *errgroup.Group) error {
func (lp *sink) writeChild(ctx context.Context, child partial.Describable, g *errgroup.Group) error {
switch child := child.(type) {
case v1.ImageIndex:
// For recursive index, we want to do a depth-first launching of goroutines
Expand All @@ -244,7 +242,7 @@ func (lp *pusher) writeChild(ctx context.Context, child partial.Describable, g *
}

// Push implements remote.Pusher.
func (lp *pusher) Push(ctx context.Context, ref name.Reference, t partial.WithRawManifest) error {
func (lp *sink) Push(ctx context.Context, ref name.Reference, t partial.WithRawManifest) error {
err := lp.writeManifest(ctx, t)
if err != nil {
return err
Expand All @@ -264,7 +262,7 @@ func (lp *pusher) Push(ctx context.Context, ref name.Reference, t partial.WithRa
}

// Upload implements remote.Pusher.
func (lp *pusher) Upload(_ context.Context, _ name.Repository, l v1.Layer) error {
func (lp *sink) Upload(_ context.Context, _ name.Repository, l v1.Layer) error {
digest, err := l.Digest()
if err != nil {
return err
Expand All @@ -276,10 +274,10 @@ func (lp *pusher) Upload(_ context.Context, _ name.Repository, l v1.Layer) error
return lp.path.WriteBlob(digest, rc)
}

func NewPusher(path Path) remote.Pusher {
return &pusher{
func NewSink(path Path) sourcesink.Sink {
return &sink{
path,
}
}

var _ remote.Pusher = (*pusher)(nil)
var _ sourcesink.Sink = (*sink)(nil)
30 changes: 15 additions & 15 deletions pkg/v1/layout/pusher_test.go → pkg/v1/layout/sink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,11 @@ func TestCanPushRandomImage(t *testing.T) {
t.Fatalf("random.Image() = %v", err)
}
path := mustOCILayout(t)
pusher := NewPusher(path)
sink := NewSink(path)
ref := name.MustParseReference("local.random/image:latest")
err = pusher.Push(context.TODO(), ref, img)
err = sink.Push(context.TODO(), ref, img)
if err != nil {
t.Errorf("pusher.Push() = %v", err)
t.Errorf("sink.Push() = %v", err)
}
mustHaveManifest(t, path, "local.random/image:latest")
mustHaveBlobs(t, path, enumerateImageBlobs(t, img))
Expand All @@ -126,11 +126,11 @@ func TestCanPushRandomImageIndex(t *testing.T) {
t.Fatalf("random.Index() = %v", err)
}
path := mustOCILayout(t)
pusher := NewPusher(path)
sink := NewSink(path)
ref := name.MustParseReference("local.random/index:latest")
err = pusher.Push(context.TODO(), ref, idx)
err = sink.Push(context.TODO(), ref, idx)
if err != nil {
t.Errorf("pusher.Push() = %v", err)
t.Errorf("sink.Push() = %v", err)
}
mustHaveManifest(t, path, "local.random/index:latest")
mustHaveBlobs(t, path, enumerateImageIndexBlobs(t, idx))
Expand All @@ -147,12 +147,12 @@ func TestCanPushImageIndex(t *testing.T) {
}

path := mustOCILayout(t)
pusher := NewPusher(path)
sink := NewSink(path)
ref := name.MustParseReference("local.repo/index:latest")

err = pusher.Push(context.TODO(), ref, img)
err = sink.Push(context.TODO(), ref, img)
if err != nil {
t.Errorf("pusher.Push() = %v", err)
t.Errorf("sink.Push() = %v", err)
}
mustHaveManifest(t, path, "local.repo/index:latest")
mustHaveBlobs(t, path, enumerateImageBlobs(t, img))
Expand All @@ -169,12 +169,12 @@ func TestCanPushImage(t *testing.T) {
}

path := mustOCILayout(t)
pusher := NewPusher(path)
sink := NewSink(path)
ref := name.MustParseReference("local.repo/index:latest")

err = pusher.Push(context.TODO(), ref, img)
err = sink.Push(context.TODO(), ref, img)
if err != nil {
t.Errorf("pusher.Push() = %v", err)
t.Errorf("sink.Push() = %v", err)
}
mustHaveManifest(t, path, "local.repo/index:latest")
mustHaveBlobs(t, path, enumerateImageBlobs(t, img))
Expand All @@ -191,11 +191,11 @@ func TestCanPushImageWithLatestTag(t *testing.T) {
}

path := mustOCILayout(t)
pusher := NewPusher(path)
sink := NewSink(path)

err = pusher.Push(context.TODO(), name.MustParseReference("reg.local.repo/index"), img)
err = sink.Push(context.TODO(), name.MustParseReference("reg.local.repo/index"), img)
if err != nil {
t.Errorf("pusher.Push() = %v", err)
t.Errorf("sink.Push() = %v", err)
}
mustHaveManifest(t, path, "reg.local.repo/index:latest")
mustHaveBlobs(t, path, enumerateImageBlobs(t, img))
Expand Down
29 changes: 15 additions & 14 deletions pkg/v1/layout/puller.go → pkg/v1/layout/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,24 @@ import (

"github.com/google/go-containerregistry/pkg/v1/partial"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/sourcesink"
specsv1 "github.com/opencontainers/image-spec/specs-go/v1"
)

type puller struct {
type source struct {
path Path
}

func NewPuller(path Path) remote.Puller {
return &puller{
func NewSource(path Path) sourcesink.Source {
return &source{
path,
}
}

var _ remote.Puller = (*puller)(nil)
var _ sourcesink.Source = (*source)(nil)

// Artifact implements remote.Puller.
func (p *puller) getDescriptor(ref name.Reference) (*v1.Descriptor, error) {
func (p *source) getDescriptor(ref name.Reference) (*v1.Descriptor, error) {
idx, err := p.path.ImageIndex()
if err != nil {
return nil, err
Expand All @@ -61,7 +62,7 @@ func (p *puller) getDescriptor(ref name.Reference) (*v1.Descriptor, error) {
}

// Artifact implements remote.Puller.
func (p *puller) Artifact(_ context.Context, ref name.Reference) (partial.Artifact, error) {
func (p *source) Artifact(_ context.Context, ref name.Reference) (partial.Artifact, error) {
desc, err := p.getDescriptor(ref)
if err != nil {
return nil, err
Expand All @@ -81,12 +82,12 @@ func (p *puller) Artifact(_ context.Context, ref name.Reference) (partial.Artifa
}

// Head implements remote.Puller.
func (p *puller) Head(_ context.Context, ref name.Reference) (*v1.Descriptor, error) {
func (p *source) Head(_ context.Context, ref name.Reference) (*v1.Descriptor, error) {
return p.getDescriptor(ref)
}

// Layer implements remote.Puller.
func (p *puller) Layer(_ context.Context, ref name.Digest) (v1.Layer, error) {
func (p *source) Layer(_ context.Context, ref name.Digest) (v1.Layer, error) {
h, err := v1.NewHash(ref.Identifier())
if err != nil {
return nil, err
Expand All @@ -102,31 +103,31 @@ func (p *puller) Layer(_ context.Context, ref name.Digest) (v1.Layer, error) {
}

// List implements remote.Puller.
func (*puller) List(_ context.Context, _ name.Repository) ([]string, error) {
func (*source) List(_ context.Context, _ name.Repository) ([]string, error) {
return nil, fmt.Errorf("unsupported operation")
}

// Get implements remote.Puller.
func (*puller) Get(_ context.Context, _ name.Reference) (*remote.Descriptor, error) {
func (*source) Get(_ context.Context, _ name.Reference) (*remote.Descriptor, error) {
return nil, fmt.Errorf("unsupported operation")
}

// Lister implements remote.Puller.
func (*puller) Lister(_ context.Context, _ name.Repository) (*remote.Lister, error) {
func (*source) Lister(_ context.Context, _ name.Repository) (*remote.Lister, error) {
return nil, fmt.Errorf("unsupported operation")
}

// Catalogger implements remote.Puller.
func (*puller) Catalogger(_ context.Context, _ name.Registry) (*remote.Catalogger, error) {
func (*source) Catalogger(_ context.Context, _ name.Registry) (*remote.Catalogger, error) {
return nil, fmt.Errorf("unsupported operation")
}

// Catalog implements remote.Puller.
func (*puller) Catalog(_ context.Context, _ name.Registry) ([]string, error) {
func (*source) Catalog(_ context.Context, _ name.Registry) ([]string, error) {
return nil, fmt.Errorf("unsupported operation")
}

// Referrers implements remote.Puller.
func (*puller) Referrers(_ context.Context, _ name.Digest, _ map[string]string) (v1.ImageIndex, error) {
func (*source) Referrers(_ context.Context, _ name.Digest, _ map[string]string) (v1.ImageIndex, error) {
return nil, fmt.Errorf("unsupported operation")
}
Loading

0 comments on commit 2d2b853

Please sign in to comment.