client: Allow setting image labels on Pull() and Import()
Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
This commit is contained in:
parent
b24acea276
commit
df82159f4d
35
client.go
35
client.go
@ -178,6 +178,9 @@ type RemoteContext struct {
|
|||||||
// Snapshotter used for unpacking
|
// Snapshotter used for unpacking
|
||||||
Snapshotter string
|
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.
|
// BaseHandlers are a set of handlers which get are called on dispatch.
|
||||||
// These handlers always get called before any operation specific
|
// These handlers always get called before any operation specific
|
||||||
// handlers.
|
// handlers.
|
||||||
@ -199,7 +202,7 @@ func defaultRemoteContext() *RemoteContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pull downloads the provided content into containerd's content store
|
// 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()
|
pullCtx := defaultRemoteContext()
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
if err := o(c, pullCtx); err != nil {
|
if err := o(c, pullCtx); err != nil {
|
||||||
@ -244,6 +247,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Imag
|
|||||||
imgrec := images.Image{
|
imgrec := images.Image{
|
||||||
Name: name,
|
Name: name,
|
||||||
Target: desc,
|
Target: desc,
|
||||||
|
Labels: pullCtx.Labels,
|
||||||
}
|
}
|
||||||
|
|
||||||
is := c.ImageService()
|
is := c.ImageService()
|
||||||
@ -275,7 +279,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Imag
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Push uploads the provided content to a remote resource
|
// 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()
|
pushCtx := defaultRemoteContext()
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
if err := o(c, pushCtx); err != nil {
|
if err := o(c, pushCtx); err != nil {
|
||||||
@ -485,11 +489,38 @@ const (
|
|||||||
type importOpts struct {
|
type importOpts struct {
|
||||||
format imageFormat
|
format imageFormat
|
||||||
refObject string
|
refObject string
|
||||||
|
labels map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImportOpt allows the caller to specify import specific options
|
// ImportOpt allows the caller to specify import specific options
|
||||||
type ImportOpt func(c *importOpts) error
|
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
|
// WithOCIImportFormat sets the import format for an OCI image format
|
||||||
func WithOCIImportFormat() ImportOpt {
|
func WithOCIImportFormat() ImportOpt {
|
||||||
return func(c *importOpts) error {
|
return func(c *importOpts) error {
|
||||||
|
@ -33,25 +33,51 @@ func WithDialOpts(opts []grpc.DialOption) ClientOpt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteOpts allows the caller to set distribution options for a remote
|
// RemoteOpt allows the caller to set distribution options for a remote
|
||||||
type RemoteOpts func(*Client, *RemoteContext) error
|
type RemoteOpt func(*Client, *RemoteContext) error
|
||||||
|
|
||||||
// WithPullUnpack is used to unpack an image after pull. This
|
// WithPullUnpack is used to unpack an image after pull. This
|
||||||
// uses the snapshotter, content store, and diff service
|
// uses the snapshotter, content store, and diff service
|
||||||
// configured for the client.
|
// configured for the client.
|
||||||
func WithPullUnpack(client *Client, c *RemoteContext) error {
|
func WithPullUnpack(_ *Client, c *RemoteContext) error {
|
||||||
c.Unpack = true
|
c.Unpack = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithPullSnapshotter specifies snapshotter name used for unpacking
|
// WithPullSnapshotter specifies snapshotter name used for unpacking
|
||||||
func WithPullSnapshotter(snapshotterName string) RemoteOpts {
|
func WithPullSnapshotter(snapshotterName string) RemoteOpt {
|
||||||
return func(client *Client, c *RemoteContext) error {
|
return func(_ *Client, c *RemoteContext) error {
|
||||||
c.Snapshotter = snapshotterName
|
c.Snapshotter = snapshotterName
|
||||||
return nil
|
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
|
// WithSchema1Conversion is used to convert Docker registry schema 1
|
||||||
// manifests to oci manifests on pull. Without this option schema 1
|
// manifests to oci manifests on pull. Without this option schema 1
|
||||||
// manifests will return a not supported error.
|
// manifests will return a not supported error.
|
||||||
@ -61,7 +87,7 @@ func WithSchema1Conversion(client *Client, c *RemoteContext) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithResolver specifies the resolver to use.
|
// 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 {
|
return func(client *Client, c *RemoteContext) error {
|
||||||
c.Resolver = resolver
|
c.Resolver = resolver
|
||||||
return nil
|
return nil
|
||||||
@ -69,7 +95,7 @@ func WithResolver(resolver remotes.Resolver) RemoteOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithImageHandler adds a base handler to be called on dispatch.
|
// 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 {
|
return func(client *Client, c *RemoteContext) error {
|
||||||
c.BaseHandlers = append(c.BaseHandlers, h)
|
c.BaseHandlers = append(c.BaseHandlers, h)
|
||||||
return nil
|
return nil
|
||||||
|
@ -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'.
|
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.`,
|
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 {
|
Action: func(clicontext *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
ref = clicontext.Args().First()
|
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")
|
log.G(pctx).WithField("image", ref).Debug("fetching")
|
||||||
|
labels := labelArgs(clicontext.StringSlice("label"))
|
||||||
img, err := client.Pull(pctx, ref, containerd.WithResolver(resolver), containerd.WithImageHandler(h), containerd.WithSchema1Conversion)
|
img, err := client.Pull(pctx, ref,
|
||||||
|
containerd.WithPullLabels(labels),
|
||||||
|
containerd.WithResolver(resolver),
|
||||||
|
containerd.WithImageHandler(h),
|
||||||
|
containerd.WithSchema1Conversion,
|
||||||
|
)
|
||||||
stopProgress()
|
stopProgress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -21,12 +21,14 @@ var imagesImportCommand = cli.Command{
|
|||||||
Value: "",
|
Value: "",
|
||||||
Usage: "reference object e.g. tag@digest (default: use the object specified in ref)",
|
Usage: "reference object e.g. tag@digest (default: use the object specified in ref)",
|
||||||
},
|
},
|
||||||
|
labelFlag,
|
||||||
},
|
},
|
||||||
Action: func(clicontext *cli.Context) error {
|
Action: func(clicontext *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
ref = clicontext.Args().First()
|
ref = clicontext.Args().First()
|
||||||
in = clicontext.Args().Get(1)
|
in = clicontext.Args().Get(1)
|
||||||
refObject = clicontext.String("ref-object")
|
refObject = clicontext.String("ref-object")
|
||||||
|
labels = labelArgs(clicontext.StringSlice("label"))
|
||||||
)
|
)
|
||||||
|
|
||||||
ctx, cancel := appContext(clicontext)
|
ctx, cancel := appContext(clicontext)
|
||||||
@ -50,6 +52,7 @@ var imagesImportCommand = cli.Command{
|
|||||||
ref,
|
ref,
|
||||||
r,
|
r,
|
||||||
containerd.WithRefObject(refObject),
|
containerd.WithRefObject(refObject),
|
||||||
|
containerd.WithImportLabels(labels),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -20,7 +20,7 @@ command. As part of this process, we do the following:
|
|||||||
2. Prepare the snapshot filesystem with the pulled resources.
|
2. Prepare the snapshot filesystem with the pulled resources.
|
||||||
3. Register metadata for the image.
|
3. Register metadata for the image.
|
||||||
`,
|
`,
|
||||||
Flags: append(registryFlags, snapshotterFlags...),
|
Flags: append(registryFlags, append(snapshotterFlags, labelFlag)...),
|
||||||
Action: func(clicontext *cli.Context) error {
|
Action: func(clicontext *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
ref = clicontext.Args().First()
|
ref = clicontext.Args().First()
|
||||||
|
@ -57,6 +57,11 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
labelFlag = cli.StringSliceFlag{
|
||||||
|
Name: "label",
|
||||||
|
Usage: "labels to attach to the pulled image",
|
||||||
|
}
|
||||||
|
|
||||||
registryFlags = []cli.Flag{
|
registryFlags = []cli.Flag{
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "skip-verify,k",
|
Name: "skip-verify,k",
|
||||||
|
@ -68,6 +68,7 @@ func (c *Client) importFromOCITar(ctx context.Context, ref string, reader io.Rea
|
|||||||
imgrec := images.Image{
|
imgrec := images.Image{
|
||||||
Name: ref,
|
Name: ref,
|
||||||
Target: *desc,
|
Target: *desc,
|
||||||
|
Labels: iopts.labels,
|
||||||
}
|
}
|
||||||
is := c.ImageService()
|
is := c.ImageService()
|
||||||
if updated, err := is.Update(ctx, imgrec, "target"); err != nil {
|
if updated, err := is.Update(ctx, imgrec, "target"); err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user