Limit value size of additional annotation for avoiding unpack failure
In containerd, there is a size limit for label size (4096 chars). Currently if an image has many layers (> (4096-39)/72 > 56), `containerd.io/snapshot/cri.image-layers` will hit the limit of label size and the unpack will fail. This commit fixes this by limiting the size of the annotation. Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
This commit is contained in:
		@@ -31,6 +31,7 @@ import (
 | 
			
		||||
	"github.com/containerd/containerd"
 | 
			
		||||
	"github.com/containerd/containerd/errdefs"
 | 
			
		||||
	containerdimages "github.com/containerd/containerd/images"
 | 
			
		||||
	"github.com/containerd/containerd/labels"
 | 
			
		||||
	"github.com/containerd/containerd/log"
 | 
			
		||||
	distribution "github.com/containerd/containerd/reference/docker"
 | 
			
		||||
	"github.com/containerd/containerd/remotes/docker"
 | 
			
		||||
@@ -460,7 +461,7 @@ const (
 | 
			
		||||
	targetDigestLabel = "containerd.io/snapshot/cri.layer-digest"
 | 
			
		||||
	// targetImageLayersLabel is a label which contains layer digests contained in
 | 
			
		||||
	// the target image and will be passed to snapshotters for preparing layers in
 | 
			
		||||
	// parallel.
 | 
			
		||||
	// parallel. Skipping some layers is allowed and only affects performance.
 | 
			
		||||
	targetImageLayersLabel = "containerd.io/snapshot/cri.image-layers"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -478,15 +479,6 @@ func appendInfoHandlerWrapper(ref string) func(f containerdimages.Handler) conta
 | 
			
		||||
			}
 | 
			
		||||
			switch desc.MediaType {
 | 
			
		||||
			case imagespec.MediaTypeImageManifest, containerdimages.MediaTypeDockerSchema2Manifest:
 | 
			
		||||
				var layers string
 | 
			
		||||
				for _, c := range children {
 | 
			
		||||
					if containerdimages.IsLayerType(c.MediaType) {
 | 
			
		||||
						layers += fmt.Sprintf("%s,", c.Digest.String())
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if len(layers) >= 1 {
 | 
			
		||||
					layers = layers[:len(layers)-1]
 | 
			
		||||
				}
 | 
			
		||||
				for i := range children {
 | 
			
		||||
					c := &children[i]
 | 
			
		||||
					if containerdimages.IsLayerType(c.MediaType) {
 | 
			
		||||
@@ -495,7 +487,7 @@ func appendInfoHandlerWrapper(ref string) func(f containerdimages.Handler) conta
 | 
			
		||||
						}
 | 
			
		||||
						c.Annotations[targetRefLabel] = ref
 | 
			
		||||
						c.Annotations[targetDigestLabel] = c.Digest.String()
 | 
			
		||||
						c.Annotations[targetImageLayersLabel] = layers
 | 
			
		||||
						c.Annotations[targetImageLayersLabel] = getLayers(ctx, targetImageLayersLabel, children[i:], labels.Validate)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
@@ -503,3 +495,25 @@ func appendInfoHandlerWrapper(ref string) func(f containerdimages.Handler) conta
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getLayers returns comma-separated digests based on the passed list of
 | 
			
		||||
// descriptors. The returned list contains as many digests as possible as well
 | 
			
		||||
// as meets the label validation.
 | 
			
		||||
func getLayers(ctx context.Context, key string, descs []imagespec.Descriptor, validate func(k, v string) error) (layers string) {
 | 
			
		||||
	var item string
 | 
			
		||||
	for _, l := range descs {
 | 
			
		||||
		if containerdimages.IsLayerType(l.MediaType) {
 | 
			
		||||
			item = l.Digest.String()
 | 
			
		||||
			if layers != "" {
 | 
			
		||||
				item = "," + item
 | 
			
		||||
			}
 | 
			
		||||
			// This avoids the label hits the size limitation.
 | 
			
		||||
			if err := validate(key, layers+item); err != nil {
 | 
			
		||||
				log.G(ctx).WithError(err).WithField("label", key).Debugf("%q is omitted in the layers list", l.Digest.String())
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			layers += item
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user