@@ -45,6 +45,7 @@ import (
4545 "github.com/containerd/containerd/log"
4646 "github.com/containerd/containerd/pkg/cri/annotations"
4747 criconfig "github.com/containerd/containerd/pkg/cri/config"
48+ crilabels "github.com/containerd/containerd/pkg/cri/labels"
4849 snpkg "github.com/containerd/containerd/pkg/snapshotters"
4950 distribution "github.com/containerd/containerd/reference/docker"
5051 "github.com/containerd/containerd/remotes/docker"
@@ -154,12 +155,15 @@ func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest)
154155 tracing .Attribute ("image.ref" , ref ),
155156 tracing .Attribute ("snapshotter.name" , snapshotter ),
156157 )
158+
159+ labels := c .getLabels (ctx , ref )
160+
157161 pullOpts := []containerd.RemoteOpt {
158162 containerd .WithSchema1Conversion , //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility.
159163 containerd .WithResolver (resolver ),
160164 containerd .WithPullSnapshotter (snapshotter ),
161165 containerd .WithPullUnpack ,
162- containerd .WithPullLabel ( imageLabelKey , imageLabelValue ),
166+ containerd .WithPullLabels ( labels ),
163167 containerd .WithMaxConcurrentDownloads (c .config .MaxConcurrentDownloads ),
164168 containerd .WithImageHandler (imageHandler ),
165169 containerd .WithUnpackOpts ([]containerd.UnpackOpt {
@@ -198,7 +202,7 @@ func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest)
198202 if r == "" {
199203 continue
200204 }
201- if err := c .createImageReference (ctx , r , image .Target ()); err != nil {
205+ if err := c .createImageReference (ctx , r , image .Target (), labels ); err != nil {
202206 return nil , fmt .Errorf ("failed to create image reference %q: %w" , r , err )
203207 }
204208 // Update image store to reflect the newest state in containerd.
@@ -266,26 +270,44 @@ func ParseAuth(auth *runtime.AuthConfig, host string) (string, string, error) {
266270// Note that because create and update are not finished in one transaction, there could be race. E.g.
267271// the image reference is deleted by someone else after create returns already exists, but before update
268272// happens.
269- func (c * criService ) createImageReference (ctx context.Context , name string , desc imagespec.Descriptor ) error {
273+ func (c * criService ) createImageReference (ctx context.Context , name string , desc imagespec.Descriptor , labels map [ string ] string ) error {
270274 img := containerdimages.Image {
271275 Name : name ,
272276 Target : desc ,
273277 // Add a label to indicate that the image is managed by the cri plugin.
274- Labels : map [ string ] string { imageLabelKey : imageLabelValue } ,
278+ Labels : labels ,
275279 }
276280 // TODO(random-liu): Figure out which is the more performant sequence create then update or
277281 // update then create.
278282 oldImg , err := c .client .ImageService ().Create (ctx , img )
279283 if err == nil || ! errdefs .IsAlreadyExists (err ) {
280284 return err
281285 }
282- if oldImg .Target .Digest == img .Target .Digest && oldImg .Labels [imageLabelKey ] == imageLabelValue {
286+ if oldImg .Target .Digest == img .Target .Digest && oldImg .Labels [crilabels . ImageLabelKey ] == labels [ crilabels . ImageLabelKey ] {
283287 return nil
284288 }
285- _ , err = c .client .ImageService ().Update (ctx , img , "target" , "labels." + imageLabelKey )
289+ _ , err = c .client .ImageService ().Update (ctx , img , "target" , "labels." + crilabels . ImageLabelKey )
286290 return err
287291}
288292
293+ // getLabels get image labels to be added on CRI image
294+ func (c * criService ) getLabels (ctx context.Context , name string ) map [string ]string {
295+ labels := map [string ]string {crilabels .ImageLabelKey : crilabels .ImageLabelValue }
296+ configSandboxImage := c .config .SandboxImage
297+ // parse sandbox image
298+ sandboxNamedRef , err := distribution .ParseDockerRef (configSandboxImage )
299+ if err != nil {
300+ log .G (ctx ).Errorf ("failed to parse sandbox image from config %s" , sandboxNamedRef )
301+ return nil
302+ }
303+ sandboxRef := sandboxNamedRef .String ()
304+ // Adding pinned image label to sandbox image
305+ if sandboxRef == name {
306+ labels [crilabels .PinnedImageLabelKey ] = crilabels .PinnedImageLabelValue
307+ }
308+ return labels
309+ }
310+
289311// updateImage updates image store to reflect the newest state of an image reference
290312// in containerd. If the reference is not managed by the cri plugin, the function also
291313// generates necessary metadata for the image and make it managed.
@@ -294,22 +316,23 @@ func (c *criService) updateImage(ctx context.Context, r string) error {
294316 if err != nil && ! errdefs .IsNotFound (err ) {
295317 return fmt .Errorf ("get image by reference: %w" , err )
296318 }
297- if err == nil && img .Labels ()[imageLabelKey ] != imageLabelValue {
319+ if err == nil && img .Labels ()[crilabels . ImageLabelKey ] != crilabels . ImageLabelValue {
298320 // Make sure the image has the image id as its unique
299321 // identifier that references the image in its lifetime.
300322 configDesc , err := img .Config (ctx )
301323 if err != nil {
302324 return fmt .Errorf ("get image id: %w" , err )
303325 }
304326 id := configDesc .Digest .String ()
305- if err := c .createImageReference (ctx , id , img .Target ()); err != nil {
327+ labels := c .getLabels (ctx , id )
328+ if err := c .createImageReference (ctx , id , img .Target (), labels ); err != nil {
306329 return fmt .Errorf ("create image id reference %q: %w" , id , err )
307330 }
308331 if err := c .imageStore .Update (ctx , id ); err != nil {
309332 return fmt .Errorf ("update image store for %q: %w" , id , err )
310333 }
311334 // The image id is ready, add the label to mark the image as managed.
312- if err := c .createImageReference (ctx , r , img .Target ()); err != nil {
335+ if err := c .createImageReference (ctx , r , img .Target (), labels ); err != nil {
313336 return fmt .Errorf ("create managed label: %w" , err )
314337 }
315338 }
0 commit comments