Skip to content

Commit

Permalink
Enable image config labels in ctr and CRI container creation
Browse files Browse the repository at this point in the history
Signed-off-by: Phil Estes <estesp@amazon.com>
(cherry picked from commit f40df3d)
  • Loading branch information
estesp committed Sep 17, 2021
1 parent 00e5fbe commit 6bfd09f
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 10 deletions.
13 changes: 13 additions & 0 deletions cmd/ctr/commands/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,16 @@ func fullID(ctx context.Context, c containerd.Container) string {
}
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
}
6 changes: 5 additions & 1 deletion cmd/ctr/commands/run/run_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
spec containerd.NewContainerOpts
)

cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
if config {
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("labels"))))
opts = append(opts, oci.WithSpecFromFile(context.String("config")))
} else {
var (
Expand All @@ -116,6 +116,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
return nil, err
}
opts = append(opts, oci.WithRootFSPath(rootfs))
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("labels"))))
} else {
snapshotter := context.String("snapshotter")
var image containerd.Image
Expand All @@ -142,9 +143,12 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
return nil, err
}
}
labels := buildLabels(commands.LabelArgs(context.StringSlice("label")), image.Labels())
opts = append(opts, oci.WithImageConfig(image))
cOpts = append(cOpts,
containerd.WithImage(image),
containerd.WithImageConfigLabels(image),
containerd.WithAdditionalContainerLabels(labels),
containerd.WithSnapshotter(snapshotter))
if uidmap, gidmap := context.String("uidmap"), context.String("gidmap"); uidmap != "" && gidmap != "" {
uidMap, err := parseIDMapping(uidmap)
Expand Down
12 changes: 8 additions & 4 deletions cmd/ctr/commands/run/run_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
if config {
id = context.Args().First()
opts = append(opts, oci.WithSpecFromFile(context.String("config")))
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
} else {
var (
ref = context.Args().First()
Expand Down Expand Up @@ -88,9 +89,13 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
}
}
opts = append(opts, oci.WithImageConfig(image))
cOpts = append(cOpts, containerd.WithImage(image))
cOpts = append(cOpts, containerd.WithSnapshotter(snapshotter))
cOpts = append(cOpts, containerd.WithNewSnapshot(id, image))
labels := buildLabels(commands.LabelArgs(context.StringSlice("label")), image.Labels())
cOpts = append(cOpts,
containerd.WithImage(image),
containerd.WithImageConfigLabels(image),
containerd.WithSnapshotter(snapshotter),
containerd.WithNewSnapshot(id, image),
containerd.WithAdditionalContainerLabels(labels))

if len(args) > 0 {
opts = append(opts, oci.WithProcessArgs(args...))
Expand Down Expand Up @@ -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")
var runtimeOpts interface{}
if runtime == "io.containerd.runhcs.v1" {
Expand Down
38 changes: 38 additions & 0 deletions container_opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@ package containerd

import (
"context"
"encoding/json"
"fmt"

"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/oci"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/typeurl"
"github.com/gogo/protobuf/types"
"github.com/opencontainers/image-spec/identity"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -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
// The existing labels are preserved as long as they do not conflict with the added labels.
func WithAdditionalContainerLabels(labels map[string]string) NewContainerOpts {
Expand Down
2 changes: 1 addition & 1 deletion pkg/cri/server/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

containerLabels := buildLabels(config.Labels, containerKindContainer)
containerLabels := buildLabels(config.Labels, image.ImageSpec.Config.Labels, containerKindContainer)

runtimeOptions, err := getRuntimeOptions(sandboxInfo)
if err != nil {
Expand Down
6 changes: 5 additions & 1 deletion pkg/cri/server/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,12 @@ func filterLabel(k, v string) string {
}

// 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)
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 {
labels[k] = v
}
Expand Down
9 changes: 7 additions & 2 deletions pkg/cri/server/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,19 @@ func TestGetRepoDigestAndTag(t *testing.T) {
}

func TestBuildLabels(t *testing.T) {
imageConfigLabels := map[string]string{
"a": "z",
"d": "y",
}
configLabels := map[string]string{
"a": "b",
"c": "d",
}
newLabels := buildLabels(configLabels, containerKindSandbox)
assert.Len(t, newLabels, 3)
newLabels := buildLabels(configLabels, imageConfigLabels, containerKindSandbox)
assert.Len(t, newLabels, 4)
assert.Equal(t, "b", newLabels["a"])
assert.Equal(t, "d", newLabels["c"])
assert.Equal(t, "y", newLabels["d"])
assert.Equal(t, containerKindSandbox, newLabels[containerKindLabel])

newLabels["a"] = "e"
Expand Down
2 changes: 1 addition & 1 deletion pkg/cri/server/sandbox_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
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)
if err != nil {
Expand Down

0 comments on commit 6bfd09f

Please sign in to comment.