Skip to content

Commit 69dff41

Browse files
authored
Merge pull request containerd#9732 from henry118/big9726
bug fix: make sure cri image is pinned when it is pulled outside cri
2 parents ff464f3 + 1eaf0c1 commit 69dff41

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

integration/containerd_image_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,35 @@ func TestContainerdSandboxImage(t *testing.T) {
237237
assert.True(t, pimg.Pinned)
238238
}
239239

240+
func TestContainerdSandboxImagePulledOutsideCRI(t *testing.T) {
241+
var pauseImage = images.Get(images.Pause)
242+
ctx := context.Background()
243+
244+
t.Log("make sure the pause image does not exist")
245+
imageService.RemoveImage(&runtime.ImageSpec{Image: pauseImage})
246+
247+
t.Log("pull pause image")
248+
_, err := containerdClient.Pull(ctx, pauseImage)
249+
assert.NoError(t, err)
250+
251+
t.Log("pause image should be seen by cri plugin")
252+
var pimg *runtime.Image
253+
require.NoError(t, Eventually(func() (bool, error) {
254+
pimg, err = imageService.ImageStatus(&runtime.ImageSpec{Image: pauseImage})
255+
return pimg != nil, err
256+
}, time.Second, 10*time.Second))
257+
258+
t.Log("verify pinned field is set for pause image")
259+
assert.True(t, pimg.Pinned)
260+
261+
t.Log("make sure the pause image exist")
262+
pauseImg, err := containerdClient.GetImage(ctx, pauseImage)
263+
require.NoError(t, err)
264+
265+
t.Log("ensure correct labels are set on pause image")
266+
assert.Equal(t, "pinned", pauseImg.Labels()["io.cri-containerd.pinned"])
267+
}
268+
240269
func TestContainerdImageWithDockerSchema1(t *testing.T) {
241270
if goruntime.GOOS == "windows" {
242271
t.Skip("Skipped on Windows because the test image is not a multi-platform one.")

internal/cri/server/images/image_pull.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,16 +319,30 @@ func (c *CRIImageService) createImageReference(ctx context.Context, name string,
319319
// TODO(random-liu): Figure out which is the more performant sequence create then update or
320320
// update then create.
321321
// TODO: Call CRIImageService directly
322-
oldImg, err := c.images.Create(ctx, img)
322+
_, err := c.images.Create(ctx, img)
323323
if err == nil {
324324
return nil
325325
} else if !errdefs.IsAlreadyExists(err) {
326326
return err
327327
}
328-
if oldImg.Target.Digest == img.Target.Digest && oldImg.Labels[crilabels.ImageLabelKey] == labels[crilabels.ImageLabelKey] {
328+
// Retrieve oldImg from image store here because Create routine returns an
329+
// empty image on ErrAlreadyExists
330+
oldImg, err := c.images.Get(ctx, name)
331+
if err != nil {
332+
return err
333+
}
334+
fieldpaths := []string{"target"}
335+
if oldImg.Labels[crilabels.ImageLabelKey] != labels[crilabels.ImageLabelKey] {
336+
fieldpaths = append(fieldpaths, "labels."+crilabels.ImageLabelKey)
337+
}
338+
if oldImg.Labels[crilabels.PinnedImageLabelKey] != labels[crilabels.PinnedImageLabelKey] &&
339+
labels[crilabels.PinnedImageLabelKey] == crilabels.PinnedImageLabelValue {
340+
fieldpaths = append(fieldpaths, "labels."+crilabels.PinnedImageLabelKey)
341+
}
342+
if oldImg.Target.Digest == img.Target.Digest && len(fieldpaths) < 2 {
329343
return nil
330344
}
331-
_, err = c.images.Update(ctx, img, "target", "labels."+crilabels.ImageLabelKey)
345+
_, err = c.images.Update(ctx, img, fieldpaths...)
332346
return err
333347
}
334348

@@ -360,7 +374,7 @@ func (c *CRIImageService) UpdateImage(ctx context.Context, r string) error {
360374
return fmt.Errorf("get image id: %w", err)
361375
}
362376
id := configDesc.Digest.String()
363-
labels := c.getLabels(ctx, id)
377+
labels := c.getLabels(ctx, r)
364378
if err := c.createImageReference(ctx, id, img.Target(), labels); err != nil {
365379
return fmt.Errorf("create image id reference %q: %w", id, err)
366380
}

0 commit comments

Comments
 (0)