diff --git a/pkg/config/config.go b/pkg/config/config.go index 1115ee6fc..2a0dbeac8 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -73,6 +73,11 @@ type ContainerdConfig struct { // NoPivot disables pivot-root (linux only), required when running a container in a RamDisk with runc // This only works for runtime type "io.containerd.runtime.v1.linux". NoPivot bool `toml:"no_pivot" json:"noPivot"` + + // DisableSnapshotAnnotations disables to pass additional annotations (image + // related information) to snapshotters. These annotations are required by + // stargz snapshotter (https://github.com/containerd/stargz-snapshotter). + DisableSnapshotAnnotations bool `toml:"disable_snapshot_annotations" json:"disableSnapshotAnnotations"` } // CniConfig contains toml config related to cni diff --git a/pkg/server/image_pull.go b/pkg/server/image_pull.go index d2457a267..e776c050e 100644 --- a/pkg/server/image_pull.go +++ b/pkg/server/image_pull.go @@ -120,6 +120,10 @@ func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest) } pullOpts = append(pullOpts, c.encryptedImagesPullOpts()...) + if !c.config.ContainerdConfig.DisableSnapshotAnnotations { + pullOpts = append(pullOpts, + containerd.WithImageHandlerWrapper(appendInfoHandlerWrapper(ref))) + } image, err := c.client.Pull(ctx, ref, pullOpts...) if err != nil { @@ -422,3 +426,42 @@ func (c *criService) encryptedImagesPullOpts() []containerd.RemoteOpt { } return nil } + +const ( + // targetRefLabel is a label which contains image reference and will be passed + // to snapshotters. + targetRefLabel = "containerd.io/snapshot/cri.image-ref" + // targetDigestLabel is a label which contains layer digest and will be passed + // to snapshotters. + targetDigestLabel = "containerd.io/snapshot/cri.layer-digest" +) + +// appendInfoHandlerWrapper makes a handler which appends some basic information +// of images to each layer descriptor as annotations during unpack. These +// annotations will be passed to snapshotters as labels. These labels will be +// used mainly by stargz-based snapshotters for querying image contents from the +// registry. +func appendInfoHandlerWrapper(ref string) func(f containerdimages.Handler) containerdimages.Handler { + return func(f containerdimages.Handler) containerdimages.Handler { + return containerdimages.HandlerFunc(func(ctx context.Context, desc imagespec.Descriptor) ([]imagespec.Descriptor, error) { + children, err := f.Handle(ctx, desc) + if err != nil { + return nil, err + } + switch desc.MediaType { + case imagespec.MediaTypeImageManifest, containerdimages.MediaTypeDockerSchema2Manifest: + for i := range children { + c := &children[i] + if containerdimages.IsLayerType(c.MediaType) { + if c.Annotations == nil { + c.Annotations = make(map[string]string) + } + c.Annotations[targetRefLabel] = ref + c.Annotations[targetDigestLabel] = c.Digest.String() + } + } + } + return children, nil + }) + } +}