@@ -33,6 +33,7 @@ import (
3333 "github.com/containerd/containerd/errdefs"
3434 containerdimages "github.com/containerd/containerd/images"
3535 "github.com/containerd/containerd/log"
36+ crilabels "github.com/containerd/containerd/pkg/cri/labels"
3637 snpkg "github.com/containerd/containerd/pkg/snapshotters"
3738 distribution "github.com/containerd/containerd/reference/docker"
3839 "github.com/containerd/containerd/remotes/docker"
@@ -113,12 +114,14 @@ func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest)
113114 }
114115 )
115116
117+ labels := c .getLabels (ctx , ref )
118+
116119 pullOpts := []containerd.RemoteOpt {
117120 containerd .WithSchema1Conversion ,
118121 containerd .WithResolver (resolver ),
119122 containerd .WithPullSnapshotter (c .config .ContainerdConfig .Snapshotter ),
120123 containerd .WithPullUnpack ,
121- containerd .WithPullLabel ( imageLabelKey , imageLabelValue ),
124+ containerd .WithPullLabels ( labels ),
122125 containerd .WithMaxConcurrentDownloads (c .config .MaxConcurrentDownloads ),
123126 containerd .WithImageHandler (imageHandler ),
124127 containerd .WithUnpackOpts ([]containerd.UnpackOpt {
@@ -154,7 +157,7 @@ func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest)
154157 if r == "" {
155158 continue
156159 }
157- if err := c .createImageReference (ctx , r , image .Target ()); err != nil {
160+ if err := c .createImageReference (ctx , r , image .Target (), labels ); err != nil {
158161 return nil , fmt .Errorf ("failed to create image reference %q: %w" , r , err )
159162 }
160163 // Update image store to reflect the newest state in containerd.
@@ -219,26 +222,44 @@ func ParseAuth(auth *runtime.AuthConfig, host string) (string, string, error) {
219222// Note that because create and update are not finished in one transaction, there could be race. E.g.
220223// the image reference is deleted by someone else after create returns already exists, but before update
221224// happens.
222- func (c * criService ) createImageReference (ctx context.Context , name string , desc imagespec.Descriptor ) error {
225+ func (c * criService ) createImageReference (ctx context.Context , name string , desc imagespec.Descriptor , labels map [ string ] string ) error {
223226 img := containerdimages.Image {
224227 Name : name ,
225228 Target : desc ,
226229 // Add a label to indicate that the image is managed by the cri plugin.
227- Labels : map [ string ] string { imageLabelKey : imageLabelValue } ,
230+ Labels : labels ,
228231 }
229232 // TODO(random-liu): Figure out which is the more performant sequence create then update or
230233 // update then create.
231234 oldImg , err := c .client .ImageService ().Create (ctx , img )
232235 if err == nil || ! errdefs .IsAlreadyExists (err ) {
233236 return err
234237 }
235- if oldImg .Target .Digest == img .Target .Digest && oldImg .Labels [imageLabelKey ] == imageLabelValue {
238+ if oldImg .Target .Digest == img .Target .Digest && oldImg .Labels [crilabels . ImageLabelKey ] == labels [ crilabels . ImageLabelKey ] {
236239 return nil
237240 }
238- _ , err = c .client .ImageService ().Update (ctx , img , "target" , "labels." + imageLabelKey )
241+ _ , err = c .client .ImageService ().Update (ctx , img , "target" , "labels." + crilabels . ImageLabelKey )
239242 return err
240243}
241244
245+ // getLabels get image labels to be added on CRI image
246+ func (c * criService ) getLabels (ctx context.Context , name string ) map [string ]string {
247+ labels := map [string ]string {crilabels .ImageLabelKey : crilabels .ImageLabelValue }
248+ configSandboxImage := c .config .SandboxImage
249+ // parse sandbox image
250+ sandboxNamedRef , err := distribution .ParseDockerRef (configSandboxImage )
251+ if err != nil {
252+ log .G (ctx ).Errorf ("failed to parse sandbox image from config %s" , sandboxNamedRef )
253+ return nil
254+ }
255+ sandboxRef := sandboxNamedRef .String ()
256+ // Adding pinned image label to sandbox image
257+ if sandboxRef == name {
258+ labels [crilabels .PinnedImageLabelKey ] = crilabels .PinnedImageLabelValue
259+ }
260+ return labels
261+ }
262+
242263// updateImage updates image store to reflect the newest state of an image reference
243264// in containerd. If the reference is not managed by the cri plugin, the function also
244265// generates necessary metadata for the image and make it managed.
@@ -247,22 +268,23 @@ func (c *criService) updateImage(ctx context.Context, r string) error {
247268 if err != nil && ! errdefs .IsNotFound (err ) {
248269 return fmt .Errorf ("get image by reference: %w" , err )
249270 }
250- if err == nil && img .Labels ()[imageLabelKey ] != imageLabelValue {
271+ if err == nil && img .Labels ()[crilabels . ImageLabelKey ] != crilabels . ImageLabelValue {
251272 // Make sure the image has the image id as its unique
252273 // identifier that references the image in its lifetime.
253274 configDesc , err := img .Config (ctx )
254275 if err != nil {
255276 return fmt .Errorf ("get image id: %w" , err )
256277 }
257278 id := configDesc .Digest .String ()
258- if err := c .createImageReference (ctx , id , img .Target ()); err != nil {
279+ labels := c .getLabels (ctx , id )
280+ if err := c .createImageReference (ctx , id , img .Target (), labels ); err != nil {
259281 return fmt .Errorf ("create image id reference %q: %w" , id , err )
260282 }
261283 if err := c .imageStore .Update (ctx , id ); err != nil {
262284 return fmt .Errorf ("update image store for %q: %w" , id , err )
263285 }
264286 // The image id is ready, add the label to mark the image as managed.
265- if err := c .createImageReference (ctx , r , img .Target ()); err != nil {
287+ if err := c .createImageReference (ctx , r , img .Target (), labels ); err != nil {
266288 return fmt .Errorf ("create managed label: %w" , err )
267289 }
268290 }
0 commit comments