From 8cddb5f91d8055747b497d4e7639367af1436ff0 Mon Sep 17 00:00:00 2001 From: Maksym Pavlenko Date: Mon, 2 Mar 2020 13:18:21 -0800 Subject: [PATCH] Pass snapshotter opts during Pull For remote snapshotter cases it's quite often there is need to pass extra info from client (for instance - registry URL to query remote layer from, credentials, etc). This commit slightly extends WithPullSnapshotter to pass extra labels to a snapshotter. Signed-off-by: Maksym Pavlenko --- client.go | 3 +++ client_opts.go | 7 +++++-- pull.go | 2 +- snapshots/snapshotter.go | 11 +++++++++-- unpacker.go | 22 ++++++++++++++++------ 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/client.go b/client.go index 1987e45c0a44..bf2dc2b85ffd 100644 --- a/client.go +++ b/client.go @@ -319,6 +319,9 @@ type RemoteContext struct { // Snapshotter used for unpacking Snapshotter string + // SnapshotterOpts are additional options to be passed to a snapshotter during pull + SnapshotterOpts []snapshots.Opt + // Labels to be applied to the created image Labels map[string]string diff --git a/client_opts.go b/client_opts.go index 860461efa4b7..d0f884f83355 100644 --- a/client_opts.go +++ b/client_opts.go @@ -22,6 +22,8 @@ import ( "github.com/containerd/containerd/images" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/remotes" + "github.com/containerd/containerd/snapshots" + "google.golang.org/grpc" ) @@ -138,10 +140,11 @@ func WithUnpackOpts(opts []UnpackOpt) RemoteOpt { } } -// WithPullSnapshotter specifies snapshotter name used for unpacking -func WithPullSnapshotter(snapshotterName string) RemoteOpt { +// WithPullSnapshotter specifies snapshotter name used for unpacking. +func WithPullSnapshotter(snapshotterName string, opts ...snapshots.Opt) RemoteOpt { return func(_ *Client, c *RemoteContext) error { c.Snapshotter = snapshotterName + c.SnapshotterOpts = opts return nil } } diff --git a/pull.go b/pull.go index c4cd919b559f..f1ee7ff6709c 100644 --- a/pull.go +++ b/pull.go @@ -72,7 +72,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima if err != nil { return nil, errors.Wrap(err, "create unpacker") } - unpackWrapper, unpackEg = u.handlerWrapper(ctx, &unpacks) + unpackWrapper, unpackEg = u.handlerWrapper(ctx, pullCtx, &unpacks) defer func() { if err := unpackEg.Wait(); err != nil { if retErr == nil { diff --git a/snapshots/snapshotter.go b/snapshots/snapshotter.go index edf29d89e6d1..168560e1425d 100644 --- a/snapshots/snapshotter.go +++ b/snapshots/snapshotter.go @@ -355,10 +355,17 @@ type Cleaner interface { // Opt allows setting mutable snapshot properties on creation type Opt func(info *Info) error -// WithLabels adds labels to a created snapshot +// WithLabels appends labels to a created snapshot func WithLabels(labels map[string]string) Opt { return func(info *Info) error { - info.Labels = labels + if info.Labels == nil { + info.Labels = make(map[string]string) + } + + for k, v := range labels { + info.Labels[k] = v + } + return nil } } diff --git a/unpacker.go b/unpacker.go index 8377349824d5..eb6981b28598 100644 --- a/unpacker.go +++ b/unpacker.go @@ -72,7 +72,13 @@ func (c *Client) newUnpacker(ctx context.Context, rCtx *RemoteContext) (*unpacke }, nil } -func (u *unpacker) unpack(ctx context.Context, h images.Handler, config ocispec.Descriptor, layers []ocispec.Descriptor) error { +func (u *unpacker) unpack( + ctx context.Context, + rCtx *RemoteContext, + h images.Handler, + config ocispec.Descriptor, + layers []ocispec.Descriptor, +) error { p, err := content.ReadBlob(ctx, u.c.ContentStore(), config) if err != nil { return err @@ -123,17 +129,17 @@ EachLayer: labels = make(map[string]string) } labels[labelSnapshotRef] = chainID - labelOpt := snapshots.WithLabels(labels) var ( key string mounts []mount.Mount + opts = append(rCtx.SnapshotterOpts, snapshots.WithLabels(labels)) ) for try := 1; try <= 3; try++ { // Prepare snapshot with from parent, label as root key = fmt.Sprintf("extract-%s %s", uniquePart(), chainID) - mounts, err = sn.Prepare(ctx, key, parent.String(), labelOpt) + mounts, err = sn.Prepare(ctx, key, parent.String(), opts...) if err != nil { if errdefs.IsAlreadyExists(err) { if _, err := sn.Stat(ctx, chainID); err != nil { @@ -201,7 +207,7 @@ EachLayer: return errors.Errorf("wrong diff id calculated on extraction %q", diffIDs[i]) } - if err = sn.Commit(ctx, chainID, key, labelOpt); err != nil { + if err = sn.Commit(ctx, chainID, key, opts...); err != nil { abort() if errdefs.IsAlreadyExists(err) { continue @@ -271,7 +277,11 @@ func (u *unpacker) fetch(ctx context.Context, h images.Handler, layers []ocispec return eg.Wait() } -func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(images.Handler) images.Handler, *errgroup.Group) { +func (u *unpacker) handlerWrapper( + uctx context.Context, + rCtx *RemoteContext, + unpacks *int32, +) (func(images.Handler) images.Handler, *errgroup.Group) { eg, uctx := errgroup.WithContext(uctx) return func(f images.Handler) images.Handler { var ( @@ -313,7 +323,7 @@ func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(im if len(l) > 0 { atomic.AddInt32(unpacks, 1) eg.Go(func() error { - return u.unpack(uctx, f, desc, l) + return u.unpack(uctx, rCtx, f, desc, l) }) } }