Skip to content

Commit 980646e

Browse files
authored
Merge pull request #6024 from estesp/cp-6012
[release/1.5] cherry-pick: Enable image config labels in ctr and CRI container creation
2 parents 00e5fbe + 6bfd09f commit 980646e

8 files changed

Lines changed: 78 additions & 10 deletions

File tree

cmd/ctr/commands/run/run.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,16 @@ func fullID(ctx context.Context, c containerd.Container) string {
247247
}
248248
return fmt.Sprintf("%s-%s", ns, id)
249249
}
250+
251+
// buildLabel builds the labels from command line labels and the image labels
252+
func buildLabels(cmdLabels, imageLabels map[string]string) map[string]string {
253+
labels := make(map[string]string)
254+
for k, v := range imageLabels {
255+
labels[k] = v
256+
}
257+
// labels from the command line will override image and the initial image config labels
258+
for k, v := range cmdLabels {
259+
labels[k] = v
260+
}
261+
return labels
262+
}

cmd/ctr/commands/run/run_unix.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
9494
spec containerd.NewContainerOpts
9595
)
9696

97-
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
9897
if config {
98+
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("labels"))))
9999
opts = append(opts, oci.WithSpecFromFile(context.String("config")))
100100
} else {
101101
var (
@@ -116,6 +116,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
116116
return nil, err
117117
}
118118
opts = append(opts, oci.WithRootFSPath(rootfs))
119+
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("labels"))))
119120
} else {
120121
snapshotter := context.String("snapshotter")
121122
var image containerd.Image
@@ -142,9 +143,12 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
142143
return nil, err
143144
}
144145
}
146+
labels := buildLabels(commands.LabelArgs(context.StringSlice("label")), image.Labels())
145147
opts = append(opts, oci.WithImageConfig(image))
146148
cOpts = append(cOpts,
147149
containerd.WithImage(image),
150+
containerd.WithImageConfigLabels(image),
151+
containerd.WithAdditionalContainerLabels(labels),
148152
containerd.WithSnapshotter(snapshotter))
149153
if uidmap, gidmap := context.String("uidmap"), context.String("gidmap"); uidmap != "" && gidmap != "" {
150154
uidMap, err := parseIDMapping(uidmap)

cmd/ctr/commands/run/run_windows.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
5151
if config {
5252
id = context.Args().First()
5353
opts = append(opts, oci.WithSpecFromFile(context.String("config")))
54+
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
5455
} else {
5556
var (
5657
ref = context.Args().First()
@@ -88,9 +89,13 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
8889
}
8990
}
9091
opts = append(opts, oci.WithImageConfig(image))
91-
cOpts = append(cOpts, containerd.WithImage(image))
92-
cOpts = append(cOpts, containerd.WithSnapshotter(snapshotter))
93-
cOpts = append(cOpts, containerd.WithNewSnapshot(id, image))
92+
labels := buildLabels(commands.LabelArgs(context.StringSlice("label")), image.Labels())
93+
cOpts = append(cOpts,
94+
containerd.WithImage(image),
95+
containerd.WithImageConfigLabels(image),
96+
containerd.WithSnapshotter(snapshotter),
97+
containerd.WithNewSnapshot(id, image),
98+
containerd.WithAdditionalContainerLabels(labels))
9499

95100
if len(args) > 0 {
96101
opts = append(opts, oci.WithProcessArgs(args...))
@@ -124,7 +129,6 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
124129
}
125130
}
126131

127-
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
128132
runtime := context.String("runtime")
129133
var runtimeOpts interface{}
130134
if runtime == "io.containerd.runhcs.v1" {

container_opts.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,19 @@ package containerd
1818

1919
import (
2020
"context"
21+
"encoding/json"
22+
"fmt"
2123

2224
"github.com/containerd/containerd/containers"
25+
"github.com/containerd/containerd/content"
2326
"github.com/containerd/containerd/errdefs"
27+
"github.com/containerd/containerd/images"
2428
"github.com/containerd/containerd/oci"
2529
"github.com/containerd/containerd/snapshots"
2630
"github.com/containerd/typeurl"
2731
"github.com/gogo/protobuf/types"
2832
"github.com/opencontainers/image-spec/identity"
33+
v1 "github.com/opencontainers/image-spec/specs-go/v1"
2934
"github.com/pkg/errors"
3035
)
3136

@@ -95,6 +100,39 @@ func WithContainerLabels(labels map[string]string) NewContainerOpts {
95100
}
96101
}
97102

103+
// WithImageConfigLabels sets the image config labels on the container.
104+
// The existing labels are cleared as this is expected to be the first
105+
// operation in setting up a container's labels. Use WithAdditionalContainerLabels
106+
// to add/overwrite the existing image config labels.
107+
func WithImageConfigLabels(image Image) NewContainerOpts {
108+
return func(ctx context.Context, _ *Client, c *containers.Container) error {
109+
ic, err := image.Config(ctx)
110+
if err != nil {
111+
return err
112+
}
113+
var (
114+
ociimage v1.Image
115+
config v1.ImageConfig
116+
)
117+
switch ic.MediaType {
118+
case v1.MediaTypeImageConfig, images.MediaTypeDockerSchema2Config:
119+
p, err := content.ReadBlob(ctx, image.ContentStore(), ic)
120+
if err != nil {
121+
return err
122+
}
123+
124+
if err := json.Unmarshal(p, &ociimage); err != nil {
125+
return err
126+
}
127+
config = ociimage.Config
128+
default:
129+
return fmt.Errorf("unknown image config media type %s", ic.MediaType)
130+
}
131+
c.Labels = config.Labels
132+
return nil
133+
}
134+
}
135+
98136
// WithAdditionalContainerLabels adds the provided labels to the container
99137
// The existing labels are preserved as long as they do not conflict with the added labels.
100138
func WithAdditionalContainerLabels(labels map[string]string) NewContainerOpts {

pkg/cri/server/container_create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
230230
return nil, errors.Wrap(err, "failed to get container spec opts")
231231
}
232232

233-
containerLabels := buildLabels(config.Labels, containerKindContainer)
233+
containerLabels := buildLabels(config.Labels, image.ImageSpec.Config.Labels, containerKindContainer)
234234

235235
runtimeOptions, err := getRuntimeOptions(sandboxInfo)
236236
if err != nil {

pkg/cri/server/helpers.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,12 @@ func filterLabel(k, v string) string {
283283
}
284284

285285
// buildLabel builds the labels from config to be passed to containerd
286-
func buildLabels(configLabels map[string]string, containerType string) map[string]string {
286+
func buildLabels(configLabels, imageConfigLabels map[string]string, containerType string) map[string]string {
287287
labels := make(map[string]string)
288+
for k, v := range imageConfigLabels {
289+
labels[k] = v
290+
}
291+
// labels from the CRI request (config) will override labels in the image config
288292
for k, v := range configLabels {
289293
labels[k] = v
290294
}

pkg/cri/server/helpers_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,19 @@ func TestGetRepoDigestAndTag(t *testing.T) {
118118
}
119119

120120
func TestBuildLabels(t *testing.T) {
121+
imageConfigLabels := map[string]string{
122+
"a": "z",
123+
"d": "y",
124+
}
121125
configLabels := map[string]string{
122126
"a": "b",
123127
"c": "d",
124128
}
125-
newLabels := buildLabels(configLabels, containerKindSandbox)
126-
assert.Len(t, newLabels, 3)
129+
newLabels := buildLabels(configLabels, imageConfigLabels, containerKindSandbox)
130+
assert.Len(t, newLabels, 4)
127131
assert.Equal(t, "b", newLabels["a"])
128132
assert.Equal(t, "d", newLabels["c"])
133+
assert.Equal(t, "y", newLabels["d"])
129134
assert.Equal(t, containerKindSandbox, newLabels[containerKindLabel])
130135

131136
newLabels["a"] = "e"

pkg/cri/server/sandbox_run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
192192
return nil, errors.Wrap(err, "failed to generate sanbdox container spec options")
193193
}
194194

195-
sandboxLabels := buildLabels(config.Labels, containerKindSandbox)
195+
sandboxLabels := buildLabels(config.Labels, image.ImageSpec.Config.Labels, containerKindSandbox)
196196

197197
runtimeOpts, err := generateRuntimeOptions(ociRuntime, c.config)
198198
if err != nil {

0 commit comments

Comments
 (0)