Merge pull request #1551 from mlaventure/client-pull-set-labels

client: Allow setting image labels on Pull()
This commit is contained in:
Derek McGowan 2017-09-28 10:18:11 -07:00 committed by GitHub
commit 70b353dff2
7 changed files with 84 additions and 13 deletions

View File

@ -176,6 +176,9 @@ type RemoteContext struct {
// Snapshotter used for unpacking
Snapshotter string
// Labels to be applied to the created image
Labels map[string]string
// BaseHandlers are a set of handlers which get are called on dispatch.
// These handlers always get called before any operation specific
// handlers.
@ -197,7 +200,7 @@ func defaultRemoteContext() *RemoteContext {
}
// Pull downloads the provided content into containerd's content store
func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Image, error) {
func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image, error) {
pullCtx := defaultRemoteContext()
for _, o := range opts {
if err := o(c, pullCtx); err != nil {
@ -242,6 +245,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Imag
imgrec := images.Image{
Name: name,
Target: desc,
Labels: pullCtx.Labels,
}
is := c.ImageService()
@ -273,7 +277,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Imag
}
// Push uploads the provided content to a remote resource
func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, opts ...RemoteOpts) error {
func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, opts ...RemoteOpt) error {
pushCtx := defaultRemoteContext()
for _, o := range opts {
if err := o(c, pushCtx); err != nil {
@ -483,11 +487,38 @@ const (
type importOpts struct {
format imageFormat
refObject string
labels map[string]string
}
// ImportOpt allows the caller to specify import specific options
type ImportOpt func(c *importOpts) error
// WithImportLabel sets a label to be associated with an imported image
func WithImportLabel(key, value string) ImportOpt {
return func(opts *importOpts) error {
if opts.labels == nil {
opts.labels = make(map[string]string)
}
opts.labels[key] = value
return nil
}
}
// WithImportLabels associates a set of labels to an imported image
func WithImportLabels(labels map[string]string) ImportOpt {
return func(opts *importOpts) error {
if opts.labels == nil {
opts.labels = make(map[string]string)
}
for k, v := range labels {
opts.labels[k] = v
}
return nil
}
}
// WithOCIImportFormat sets the import format for an OCI image format
func WithOCIImportFormat() ImportOpt {
return func(c *importOpts) error {

View File

@ -33,25 +33,51 @@ func WithDialOpts(opts []grpc.DialOption) ClientOpt {
}
}
// RemoteOpts allows the caller to set distribution options for a remote
type RemoteOpts func(*Client, *RemoteContext) error
// RemoteOpt allows the caller to set distribution options for a remote
type RemoteOpt func(*Client, *RemoteContext) error
// WithPullUnpack is used to unpack an image after pull. This
// uses the snapshotter, content store, and diff service
// configured for the client.
func WithPullUnpack(client *Client, c *RemoteContext) error {
func WithPullUnpack(_ *Client, c *RemoteContext) error {
c.Unpack = true
return nil
}
// WithPullSnapshotter specifies snapshotter name used for unpacking
func WithPullSnapshotter(snapshotterName string) RemoteOpts {
return func(client *Client, c *RemoteContext) error {
func WithPullSnapshotter(snapshotterName string) RemoteOpt {
return func(_ *Client, c *RemoteContext) error {
c.Snapshotter = snapshotterName
return nil
}
}
// WithPullLabel sets a label to be associated with a pulled reference
func WithPullLabel(key, value string) RemoteOpt {
return func(_ *Client, rc *RemoteContext) error {
if rc.Labels == nil {
rc.Labels = make(map[string]string)
}
rc.Labels[key] = value
return nil
}
}
// WithPullLabels associates a set of labels to a pulled reference
func WithPullLabels(labels map[string]string) RemoteOpt {
return func(_ *Client, rc *RemoteContext) error {
if rc.Labels == nil {
rc.Labels = make(map[string]string)
}
for k, v := range labels {
rc.Labels[k] = v
}
return nil
}
}
// WithSchema1Conversion is used to convert Docker registry schema 1
// manifests to oci manifests on pull. Without this option schema 1
// manifests will return a not supported error.
@ -61,7 +87,7 @@ func WithSchema1Conversion(client *Client, c *RemoteContext) error {
}
// WithResolver specifies the resolver to use.
func WithResolver(resolver remotes.Resolver) RemoteOpts {
func WithResolver(resolver remotes.Resolver) RemoteOpt {
return func(client *Client, c *RemoteContext) error {
c.Resolver = resolver
return nil
@ -69,7 +95,7 @@ func WithResolver(resolver remotes.Resolver) RemoteOpts {
}
// WithImageHandler adds a base handler to be called on dispatch.
func WithImageHandler(h images.Handler) RemoteOpts {
func WithImageHandler(h images.Handler) RemoteOpt {
return func(client *Client, c *RemoteContext) error {
c.BaseHandlers = append(c.BaseHandlers, h)
return nil

View File

@ -39,7 +39,7 @@ not use this implementation as a guide. The end goal should be having metadata,
content and snapshots ready for a direct use via the 'ctr run'.
Most of this is experimental and there are few leaps to make this work.`,
Flags: registryFlags,
Flags: append(registryFlags, labelFlag),
Action: func(clicontext *cli.Context) error {
var (
ref = clicontext.Args().First()
@ -84,8 +84,13 @@ func fetch(ctx context.Context, ref string, clicontext *cli.Context) (containerd
})
log.G(pctx).WithField("image", ref).Debug("fetching")
img, err := client.Pull(pctx, ref, containerd.WithResolver(resolver), containerd.WithImageHandler(h), containerd.WithSchema1Conversion)
labels := labelArgs(clicontext.StringSlice("label"))
img, err := client.Pull(pctx, ref,
containerd.WithPullLabels(labels),
containerd.WithResolver(resolver),
containerd.WithImageHandler(h),
containerd.WithSchema1Conversion,
)
stopProgress()
if err != nil {
return nil, err

View File

@ -21,12 +21,14 @@ var imagesImportCommand = cli.Command{
Value: "",
Usage: "reference object e.g. tag@digest (default: use the object specified in ref)",
},
labelFlag,
},
Action: func(clicontext *cli.Context) error {
var (
ref = clicontext.Args().First()
in = clicontext.Args().Get(1)
refObject = clicontext.String("ref-object")
labels = labelArgs(clicontext.StringSlice("label"))
)
ctx, cancel := appContext(clicontext)
@ -50,6 +52,7 @@ var imagesImportCommand = cli.Command{
ref,
r,
containerd.WithRefObject(refObject),
containerd.WithImportLabels(labels),
)
if err != nil {
return err

View File

@ -20,7 +20,7 @@ command. As part of this process, we do the following:
2. Prepare the snapshot filesystem with the pulled resources.
3. Register metadata for the image.
`,
Flags: append(registryFlags, snapshotterFlags...),
Flags: append(registryFlags, append(snapshotterFlags, labelFlag)...),
Action: func(clicontext *cli.Context) error {
var (
ref = clicontext.Args().First()

View File

@ -57,6 +57,11 @@ var (
},
}
labelFlag = cli.StringSliceFlag{
Name: "label",
Usage: "labels to attach to the pulled image",
}
registryFlags = []cli.Flag{
cli.BoolFlag{
Name: "skip-verify,k",

View File

@ -68,6 +68,7 @@ func (c *Client) importFromOCITar(ctx context.Context, ref string, reader io.Rea
imgrec := images.Image{
Name: ref,
Target: *desc,
Labels: iopts.labels,
}
is := c.ImageService()
if updated, err := is.Update(ctx, imgrec, "target"); err != nil {