push: always inherit distribution sources from parent

Propagate parent distribution source labels to each of its children even
if they're not missing. This allows to cross-repo mount blobs when the
child content has different distribution source label from its
parent manifest/index. This could happen when different parts of image
were fetched from different sources.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
Paweł Gronowski 2023-10-20 18:11:15 +02:00
parent 349c8d12c8
commit c51d4f9b69
No known key found for this signature in database
GPG Key ID: B85EFCFE26DEF92A

View File

@ -342,8 +342,15 @@ func annotateDistributionSourceHandler(f images.HandlerFunc, provider content.In
return children, nil return children, nil
} }
// parentInfo can be used to inherit info for non-existent blobs parentSourceAnnotations := desc.Annotations
var parentInfo *content.Info var parentLabels map[string]string
if pi, err := provider.Info(ctx, desc.Digest); err != nil {
if !errdefs.IsNotFound(err) {
return nil, err
}
} else {
parentLabels = pi.Labels
}
for i := range children { for i := range children {
child := children[i] child := children[i]
@ -353,32 +360,35 @@ func annotateDistributionSourceHandler(f images.HandlerFunc, provider content.In
if !errdefs.IsNotFound(err) { if !errdefs.IsNotFound(err) {
return nil, err return nil, err
} }
if parentInfo == nil {
pi, err := provider.Info(ctx, desc.Digest)
if err != nil {
return nil, err
}
parentInfo = &pi
}
// Blob may not exist locally, annotate with parent labels for cross repo
// mount or fetch. Parent sources may apply to all children since most
// registries enforce that children exist before the manifests.
info = *parentInfo
} }
copyDistributionSourceLabels(info.Labels, &child)
for k, v := range info.Labels { // Annotate with parent labels for cross repo mount or fetch.
if !strings.HasPrefix(k, labels.LabelDistributionSource+".") { // Parent sources may apply to all children since most registries
continue // enforce that children exist before the manifests.
} copyDistributionSourceLabels(parentSourceAnnotations, &child)
copyDistributionSourceLabels(parentLabels, &child)
if child.Annotations == nil {
child.Annotations = map[string]string{}
}
child.Annotations[k] = v
}
children[i] = child children[i] = child
} }
return children, nil return children, nil
} }
} }
func copyDistributionSourceLabels(from map[string]string, to *ocispec.Descriptor) {
for k, v := range from {
if !strings.HasPrefix(k, labels.LabelDistributionSource+".") {
continue
}
if to.Annotations == nil {
to.Annotations = make(map[string]string)
} else {
// Only propagate the parent label if the child doesn't already have it.
if _, has := to.Annotations[k]; has {
continue
}
}
to.Annotations[k] = v
}
}