Skip to content

Commit b9af453

Browse files
committed
export: Copy distribution source labels to manifest annotations
Persist manifest/indexes distribution source labels as annotations in the index.json. This could allow the importer to fetch the missing blobs from the external repository. These can't really be persisted directly in blob descriptors because that would alter the digests. Signed-off-by: Paweł Gronowski <[email protected]>
1 parent 61a7c49 commit b9af453

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

images/archive/exporter.go

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,14 @@ import (
2424
"io"
2525
"path"
2626
"sort"
27+
"strings"
2728

2829
"github.com/containerd/containerd/v2/content"
2930
"github.com/containerd/containerd/v2/errdefs"
3031
"github.com/containerd/containerd/v2/images"
32+
"github.com/containerd/containerd/v2/labels"
3133
"github.com/containerd/containerd/v2/platforms"
34+
"github.com/containerd/log"
3235
digest "github.com/opencontainers/go-digest"
3336
ocispecs "github.com/opencontainers/image-spec/specs-go"
3437
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -191,6 +194,23 @@ func addNameAnnotation(name string, base map[string]string) map[string]string {
191194
return annotations
192195
}
193196

197+
func copySourceLabels(ctx context.Context, infoProvider content.InfoProvider, desc ocispec.Descriptor) (ocispec.Descriptor, error) {
198+
info, err := infoProvider.Info(ctx, desc.Digest)
199+
if err != nil {
200+
return desc, err
201+
}
202+
for k, v := range info.Labels {
203+
if strings.HasPrefix(k, labels.LabelDistributionSource) {
204+
if desc.Annotations == nil {
205+
desc.Annotations = map[string]string{k: v}
206+
} else {
207+
desc.Annotations[k] = v
208+
}
209+
}
210+
}
211+
return desc, nil
212+
}
213+
194214
// ContentProvider provides both content and info about content
195215
type ContentProvider interface {
196216
content.Provider
@@ -208,13 +228,22 @@ func Export(ctx context.Context, store ContentProvider, writer io.Writer, opts .
208228

209229
records := []tarRecord{
210230
ociLayoutFile(""),
211-
ociIndexRecord(eo.manifests),
231+
}
232+
233+
manifests := make([]ocispec.Descriptor, 0, len(eo.manifests))
234+
for _, desc := range eo.manifests {
235+
d, err := copySourceLabels(ctx, store, desc)
236+
if err != nil {
237+
log.G(ctx).WithError(err).WithField("desc", desc).Warn("failed to copy distribution.source labels")
238+
continue
239+
}
240+
manifests = append(manifests, d)
212241
}
213242

214243
algorithms := map[string]struct{}{}
215244
dManifests := map[digest.Digest]*exportManifest{}
216245
resolvedIndex := map[digest.Digest]digest.Digest{}
217-
for _, desc := range eo.manifests {
246+
for _, desc := range manifests {
218247
if images.IsManifestType(desc.MediaType) {
219248
mt, ok := dManifests[desc.Digest]
220249
if !ok {
@@ -304,6 +333,8 @@ func Export(ctx context.Context, store ContentProvider, writer io.Writer, opts .
304333
}
305334
}
306335

336+
records = append(records, ociIndexRecord(manifests))
337+
307338
if !eo.skipDockerManifest && len(dManifests) > 0 {
308339
tr, err := manifestsRecord(ctx, store, dManifests)
309340
if err != nil {

0 commit comments

Comments
 (0)