@@ -24,11 +24,14 @@ import (
24
24
"io"
25
25
"path"
26
26
"sort"
27
+ "strings"
27
28
28
29
"github.com/containerd/containerd/v2/content"
29
30
"github.com/containerd/containerd/v2/errdefs"
30
31
"github.com/containerd/containerd/v2/images"
32
+ "github.com/containerd/containerd/v2/labels"
31
33
"github.com/containerd/containerd/v2/platforms"
34
+ "github.com/containerd/log"
32
35
digest "github.com/opencontainers/go-digest"
33
36
ocispecs "github.com/opencontainers/image-spec/specs-go"
34
37
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -191,6 +194,23 @@ func addNameAnnotation(name string, base map[string]string) map[string]string {
191
194
return annotations
192
195
}
193
196
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
+
194
214
// ContentProvider provides both content and info about content
195
215
type ContentProvider interface {
196
216
content.Provider
@@ -208,13 +228,22 @@ func Export(ctx context.Context, store ContentProvider, writer io.Writer, opts .
208
228
209
229
records := []tarRecord {
210
230
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 )
212
241
}
213
242
214
243
algorithms := map [string ]struct {}{}
215
244
dManifests := map [digest.Digest ]* exportManifest {}
216
245
resolvedIndex := map [digest.Digest ]digest.Digest {}
217
- for _ , desc := range eo . manifests {
246
+ for _ , desc := range manifests {
218
247
if images .IsManifestType (desc .MediaType ) {
219
248
mt , ok := dManifests [desc .Digest ]
220
249
if ! ok {
@@ -304,6 +333,8 @@ func Export(ctx context.Context, store ContentProvider, writer io.Writer, opts .
304
333
}
305
334
}
306
335
336
+ records = append (records , ociIndexRecord (manifests ))
337
+
307
338
if ! eo .skipDockerManifest && len (dManifests ) > 0 {
308
339
tr , err := manifestsRecord (ctx , store , dManifests )
309
340
if err != nil {
0 commit comments