Enable image config labels in ctr and CRI container creation
Signed-off-by: Phil Estes <estesp@amazon.com>
This commit is contained in:
parent
d081457ba4
commit
f40df3d72b
@ -249,3 +249,16 @@ func fullID(ctx context.Context, c containerd.Container) string {
|
|||||||
}
|
}
|
||||||
return fmt.Sprintf("%s-%s", ns, id)
|
return fmt.Sprintf("%s-%s", ns, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// buildLabel builds the labels from command line labels and the image labels
|
||||||
|
func buildLabels(cmdLabels, imageLabels map[string]string) map[string]string {
|
||||||
|
labels := make(map[string]string)
|
||||||
|
for k, v := range imageLabels {
|
||||||
|
labels[k] = v
|
||||||
|
}
|
||||||
|
// labels from the command line will override image and the initial image config labels
|
||||||
|
for k, v := range cmdLabels {
|
||||||
|
labels[k] = v
|
||||||
|
}
|
||||||
|
return labels
|
||||||
|
}
|
||||||
|
@ -103,8 +103,8 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
spec containerd.NewContainerOpts
|
spec containerd.NewContainerOpts
|
||||||
)
|
)
|
||||||
|
|
||||||
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
|
|
||||||
if config {
|
if config {
|
||||||
|
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("labels"))))
|
||||||
opts = append(opts, oci.WithSpecFromFile(context.String("config")))
|
opts = append(opts, oci.WithSpecFromFile(context.String("config")))
|
||||||
} else {
|
} else {
|
||||||
var (
|
var (
|
||||||
@ -125,6 +125,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
opts = append(opts, oci.WithRootFSPath(rootfs))
|
opts = append(opts, oci.WithRootFSPath(rootfs))
|
||||||
|
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("labels"))))
|
||||||
} else {
|
} else {
|
||||||
snapshotter := context.String("snapshotter")
|
snapshotter := context.String("snapshotter")
|
||||||
var image containerd.Image
|
var image containerd.Image
|
||||||
@ -151,9 +152,12 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
labels := buildLabels(commands.LabelArgs(context.StringSlice("label")), image.Labels())
|
||||||
opts = append(opts, oci.WithImageConfig(image))
|
opts = append(opts, oci.WithImageConfig(image))
|
||||||
cOpts = append(cOpts,
|
cOpts = append(cOpts,
|
||||||
containerd.WithImage(image),
|
containerd.WithImage(image),
|
||||||
|
containerd.WithImageConfigLabels(image),
|
||||||
|
containerd.WithAdditionalContainerLabels(labels),
|
||||||
containerd.WithSnapshotter(snapshotter))
|
containerd.WithSnapshotter(snapshotter))
|
||||||
if uidmap, gidmap := context.String("uidmap"), context.String("gidmap"); uidmap != "" && gidmap != "" {
|
if uidmap, gidmap := context.String("uidmap"), context.String("gidmap"); uidmap != "" && gidmap != "" {
|
||||||
uidMap, err := parseIDMapping(uidmap)
|
uidMap, err := parseIDMapping(uidmap)
|
||||||
|
@ -51,6 +51,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
if config {
|
if config {
|
||||||
id = context.Args().First()
|
id = context.Args().First()
|
||||||
opts = append(opts, oci.WithSpecFromFile(context.String("config")))
|
opts = append(opts, oci.WithSpecFromFile(context.String("config")))
|
||||||
|
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
|
||||||
} else {
|
} else {
|
||||||
var (
|
var (
|
||||||
ref = context.Args().First()
|
ref = context.Args().First()
|
||||||
@ -88,9 +89,13 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
opts = append(opts, oci.WithImageConfig(image))
|
opts = append(opts, oci.WithImageConfig(image))
|
||||||
cOpts = append(cOpts, containerd.WithImage(image))
|
labels := buildLabels(commands.LabelArgs(context.StringSlice("label")), image.Labels())
|
||||||
cOpts = append(cOpts, containerd.WithSnapshotter(snapshotter))
|
cOpts = append(cOpts,
|
||||||
cOpts = append(cOpts, containerd.WithNewSnapshot(id, image))
|
containerd.WithImage(image),
|
||||||
|
containerd.WithImageConfigLabels(image),
|
||||||
|
containerd.WithSnapshotter(snapshotter),
|
||||||
|
containerd.WithNewSnapshot(id, image),
|
||||||
|
containerd.WithAdditionalContainerLabels(labels))
|
||||||
|
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
opts = append(opts, oci.WithProcessArgs(args...))
|
opts = append(opts, oci.WithProcessArgs(args...))
|
||||||
@ -124,7 +129,6 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
|
|
||||||
runtime := context.String("runtime")
|
runtime := context.String("runtime")
|
||||||
var runtimeOpts interface{}
|
var runtimeOpts interface{}
|
||||||
if runtime == "io.containerd.runhcs.v1" {
|
if runtime == "io.containerd.runhcs.v1" {
|
||||||
|
@ -18,14 +18,19 @@ package containerd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/containerd/containerd/containers"
|
"github.com/containerd/containerd/containers"
|
||||||
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
|
"github.com/containerd/containerd/images"
|
||||||
"github.com/containerd/containerd/oci"
|
"github.com/containerd/containerd/oci"
|
||||||
"github.com/containerd/containerd/snapshots"
|
"github.com/containerd/containerd/snapshots"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
"github.com/gogo/protobuf/types"
|
"github.com/gogo/protobuf/types"
|
||||||
"github.com/opencontainers/image-spec/identity"
|
"github.com/opencontainers/image-spec/identity"
|
||||||
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -95,6 +100,39 @@ func WithContainerLabels(labels map[string]string) NewContainerOpts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithImageConfigLabels sets the image config labels on the container.
|
||||||
|
// The existing labels are cleared as this is expected to be the first
|
||||||
|
// operation in setting up a container's labels. Use WithAdditionalContainerLabels
|
||||||
|
// to add/overwrite the existing image config labels.
|
||||||
|
func WithImageConfigLabels(image Image) NewContainerOpts {
|
||||||
|
return func(ctx context.Context, _ *Client, c *containers.Container) error {
|
||||||
|
ic, err := image.Config(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
ociimage v1.Image
|
||||||
|
config v1.ImageConfig
|
||||||
|
)
|
||||||
|
switch ic.MediaType {
|
||||||
|
case v1.MediaTypeImageConfig, images.MediaTypeDockerSchema2Config:
|
||||||
|
p, err := content.ReadBlob(ctx, image.ContentStore(), ic)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(p, &ociimage); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config = ociimage.Config
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown image config media type %s", ic.MediaType)
|
||||||
|
}
|
||||||
|
c.Labels = config.Labels
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithAdditionalContainerLabels adds the provided labels to the container
|
// WithAdditionalContainerLabels adds the provided labels to the container
|
||||||
// The existing labels are preserved as long as they do not conflict with the added labels.
|
// The existing labels are preserved as long as they do not conflict with the added labels.
|
||||||
func WithAdditionalContainerLabels(labels map[string]string) NewContainerOpts {
|
func WithAdditionalContainerLabels(labels map[string]string) NewContainerOpts {
|
||||||
|
@ -230,7 +230,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
|
|||||||
return nil, errors.Wrap(err, "failed to get container spec opts")
|
return nil, errors.Wrap(err, "failed to get container spec opts")
|
||||||
}
|
}
|
||||||
|
|
||||||
containerLabels := buildLabels(config.Labels, containerKindContainer)
|
containerLabels := buildLabels(config.Labels, image.ImageSpec.Config.Labels, containerKindContainer)
|
||||||
|
|
||||||
runtimeOptions, err := getRuntimeOptions(sandboxInfo)
|
runtimeOptions, err := getRuntimeOptions(sandboxInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -283,8 +283,12 @@ func filterLabel(k, v string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// buildLabel builds the labels from config to be passed to containerd
|
// buildLabel builds the labels from config to be passed to containerd
|
||||||
func buildLabels(configLabels map[string]string, containerType string) map[string]string {
|
func buildLabels(configLabels, imageConfigLabels map[string]string, containerType string) map[string]string {
|
||||||
labels := make(map[string]string)
|
labels := make(map[string]string)
|
||||||
|
for k, v := range imageConfigLabels {
|
||||||
|
labels[k] = v
|
||||||
|
}
|
||||||
|
// labels from the CRI request (config) will override labels in the image config
|
||||||
for k, v := range configLabels {
|
for k, v := range configLabels {
|
||||||
labels[k] = v
|
labels[k] = v
|
||||||
}
|
}
|
||||||
|
@ -118,14 +118,19 @@ func TestGetRepoDigestAndTag(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildLabels(t *testing.T) {
|
func TestBuildLabels(t *testing.T) {
|
||||||
|
imageConfigLabels := map[string]string{
|
||||||
|
"a": "z",
|
||||||
|
"d": "y",
|
||||||
|
}
|
||||||
configLabels := map[string]string{
|
configLabels := map[string]string{
|
||||||
"a": "b",
|
"a": "b",
|
||||||
"c": "d",
|
"c": "d",
|
||||||
}
|
}
|
||||||
newLabels := buildLabels(configLabels, containerKindSandbox)
|
newLabels := buildLabels(configLabels, imageConfigLabels, containerKindSandbox)
|
||||||
assert.Len(t, newLabels, 3)
|
assert.Len(t, newLabels, 4)
|
||||||
assert.Equal(t, "b", newLabels["a"])
|
assert.Equal(t, "b", newLabels["a"])
|
||||||
assert.Equal(t, "d", newLabels["c"])
|
assert.Equal(t, "d", newLabels["c"])
|
||||||
|
assert.Equal(t, "y", newLabels["d"])
|
||||||
assert.Equal(t, containerKindSandbox, newLabels[containerKindLabel])
|
assert.Equal(t, containerKindSandbox, newLabels[containerKindLabel])
|
||||||
|
|
||||||
newLabels["a"] = "e"
|
newLabels["a"] = "e"
|
||||||
|
@ -198,7 +198,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
|
|||||||
return nil, errors.Wrap(err, "failed to generate sanbdox container spec options")
|
return nil, errors.Wrap(err, "failed to generate sanbdox container spec options")
|
||||||
}
|
}
|
||||||
|
|
||||||
sandboxLabels := buildLabels(config.Labels, containerKindSandbox)
|
sandboxLabels := buildLabels(config.Labels, image.ImageSpec.Config.Labels, containerKindSandbox)
|
||||||
|
|
||||||
runtimeOpts, err := generateRuntimeOptions(ociRuntime, c.config)
|
runtimeOpts, err := generateRuntimeOptions(ociRuntime, c.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user