@@ -131,10 +131,10 @@ type CopyGraphOptions struct {
131
131
// Returns the descriptor of the root node on successful copy.
132
132
func Copy (ctx context.Context , src ReadOnlyTarget , srcRef string , dst Target , dstRef string , opts CopyOptions ) (ocispec.Descriptor , error ) {
133
133
if src == nil {
134
- return ocispec.Descriptor {}, errors .New ("nil source target" )
134
+ return ocispec.Descriptor {}, newCopyError ( "Copy" , CopyErrorOriginSource , errors .New ("nil source target" ) )
135
135
}
136
136
if dst == nil {
137
- return ocispec.Descriptor {}, errors .New ("nil destination target" )
137
+ return ocispec.Descriptor {}, newCopyError ( "Copy" , CopyErrorOriginDestination , errors .New ("nil destination target" ) )
138
138
}
139
139
if dstRef == "" {
140
140
dstRef = srcRef
@@ -147,14 +147,14 @@ func Copy(ctx context.Context, src ReadOnlyTarget, srcRef string, dst Target, ds
147
147
proxy := cas .NewProxyWithLimit (src , cas .NewMemory (), opts .MaxMetadataBytes )
148
148
root , err := resolveRoot (ctx , src , srcRef , proxy )
149
149
if err != nil {
150
- return ocispec.Descriptor {}, fmt . Errorf ( "failed to resolve %s: %w" , srcRef , err )
150
+ return ocispec.Descriptor {}, err
151
151
}
152
152
153
153
if opts .MapRoot != nil {
154
154
proxy .StopCaching = true
155
155
root , err = opts .MapRoot (ctx , proxy , root )
156
156
if err != nil {
157
- return ocispec.Descriptor {}, err
157
+ return ocispec.Descriptor {}, newCopyError ( "MapRoot" , CopyErrorOriginSource , err )
158
158
}
159
159
proxy .StopCaching = false
160
160
}
@@ -174,6 +174,12 @@ func Copy(ctx context.Context, src ReadOnlyTarget, srcRef string, dst Target, ds
174
174
// from the source CAS to the destination CAS.
175
175
// The root node (e.g. a manifest of the artifact) is identified by a descriptor.
176
176
func CopyGraph (ctx context.Context , src content.ReadOnlyStorage , dst content.Storage , root ocispec.Descriptor , opts CopyGraphOptions ) error {
177
+ if src == nil {
178
+ return newCopyError ("CopyGraph" , CopyErrorOriginSource , errors .New ("nil source target" ))
179
+ }
180
+ if dst == nil {
181
+ return newCopyError ("CopyGraph" , CopyErrorOriginDestination , errors .New ("nil destination target" ))
182
+ }
177
183
return copyGraph (ctx , src , dst , root , nil , nil , nil , opts )
178
184
}
179
185
@@ -222,7 +228,7 @@ func copyGraph(ctx context.Context, src content.ReadOnlyStorage, dst content.Sto
222
228
// skip if a rooted sub-DAG exists
223
229
exists , err := dst .Exists (ctx , desc )
224
230
if err != nil {
225
- return err
231
+ return newCopyError ( "Exists" , CopyErrorOriginDestination , err )
226
232
}
227
233
if exists {
228
234
if opts .OnCopySkipped != nil {
@@ -236,7 +242,7 @@ func copyGraph(ctx context.Context, src content.ReadOnlyStorage, dst content.Sto
236
242
// find successors while non-leaf nodes will be fetched and cached
237
243
successors , err := opts .FindSuccessors (ctx , proxy , desc )
238
244
if err != nil {
239
- return err
245
+ return newCopyError ( "FindSuccessors" , CopyErrorOriginSource , err )
240
246
}
241
247
successors = removeForeignLayers (successors )
242
248
@@ -264,7 +270,7 @@ func copyGraph(ctx context.Context, src content.ReadOnlyStorage, dst content.Sto
264
270
265
271
exists , err = proxy .Cache .Exists (ctx , desc )
266
272
if err != nil {
267
- return err
273
+ return fmt . Errorf ( "failed to check cache existence: %s: %w" , desc . Digest , err )
268
274
}
269
275
if exists {
270
276
return copyNode (ctx , proxy .Cache , dst , desc , opts )
@@ -324,7 +330,7 @@ func mountOrCopyNode(ctx context.Context, src content.ReadOnlyStorage, dst conte
324
330
325
331
// Mount or copy
326
332
if err := mounter .Mount (ctx , desc , sourceRepository , getContent ); err != nil && ! errors .Is (err , skipSource ) {
327
- return err
333
+ return newCopyError ( "Mount" , CopyErrorOriginDestination , err )
328
334
}
329
335
330
336
if ! mountFailed {
@@ -352,12 +358,12 @@ func mountOrCopyNode(ctx context.Context, src content.ReadOnlyStorage, dst conte
352
358
func doCopyNode (ctx context.Context , src content.ReadOnlyStorage , dst content.Storage , desc ocispec.Descriptor ) error {
353
359
rc , err := src .Fetch (ctx , desc )
354
360
if err != nil {
355
- return err
361
+ return newCopyError ( "Fetch" , CopyErrorOriginSource , err )
356
362
}
357
363
defer rc .Close ()
358
364
err = dst .Push (ctx , desc , rc )
359
365
if err != nil && ! errors .Is (err , errdef .ErrAlreadyExists ) {
360
- return err
366
+ return newCopyError ( "Push" , CopyErrorOriginDestination , err )
361
367
}
362
368
return nil
363
369
}
@@ -389,13 +395,13 @@ func copyNode(ctx context.Context, src content.ReadOnlyStorage, dst content.Stor
389
395
func copyCachedNodeWithReference (ctx context.Context , src * cas.Proxy , dst registry.ReferencePusher , desc ocispec.Descriptor , dstRef string ) error {
390
396
rc , err := src .FetchCached (ctx , desc )
391
397
if err != nil {
392
- return err
398
+ return newCopyError ( "Fetch" , CopyErrorOriginSource , err )
393
399
}
394
400
defer rc .Close ()
395
401
396
402
err = dst .PushReference (ctx , desc , rc , dstRef )
397
403
if err != nil && ! errors .Is (err , errdef .ErrAlreadyExists ) {
398
- return err
404
+ return newCopyError ( "PushReference" , CopyErrorOriginDestination , err )
399
405
}
400
406
return nil
401
407
}
@@ -404,7 +410,11 @@ func copyCachedNodeWithReference(ctx context.Context, src *cas.Proxy, dst regist
404
410
func resolveRoot (ctx context.Context , src ReadOnlyTarget , srcRef string , proxy * cas.Proxy ) (ocispec.Descriptor , error ) {
405
411
refFetcher , ok := src .(registry.ReferenceFetcher )
406
412
if ! ok {
407
- return src .Resolve (ctx , srcRef )
413
+ desc , err := src .Resolve (ctx , srcRef )
414
+ if err != nil {
415
+ return ocispec.Descriptor {}, newCopyError ("Resolve" , CopyErrorOriginSource , err )
416
+ }
417
+ return desc , nil
408
418
}
409
419
410
420
// optimize performance for ReferenceFetcher targets
@@ -414,7 +424,7 @@ func resolveRoot(ctx context.Context, src ReadOnlyTarget, srcRef string, proxy *
414
424
}
415
425
root , rc , err := refProxy .FetchReference (ctx , srcRef )
416
426
if err != nil {
417
- return ocispec.Descriptor {}, err
427
+ return ocispec.Descriptor {}, newCopyError ( "FetchReference" , CopyErrorOriginSource , err )
418
428
}
419
429
defer rc .Close ()
420
430
// cache root if it is a non-leaf node
@@ -425,7 +435,7 @@ func resolveRoot(ctx context.Context, src ReadOnlyTarget, srcRef string, proxy *
425
435
return nil , errors .New ("fetching only root node expected" )
426
436
})
427
437
if _ , err = content .Successors (ctx , fetcher , root ); err != nil {
428
- return ocispec.Descriptor {}, err
438
+ return ocispec.Descriptor {}, newCopyError ( "Successors" , CopyErrorOriginSource , err )
429
439
}
430
440
431
441
// TODO: optimize special case where root is a leaf node (i.e. a blob)
@@ -434,7 +444,7 @@ func resolveRoot(ctx context.Context, src ReadOnlyTarget, srcRef string, proxy *
434
444
}
435
445
436
446
// prepareCopy prepares the hooks for copy.
437
- func prepareCopy (ctx context.Context , dst Target , dstRef string , proxy * cas.Proxy , root ocispec.Descriptor , opts * CopyOptions ) error {
447
+ func prepareCopy (_ context.Context , dst Target , dstRef string , proxy * cas.Proxy , root ocispec.Descriptor , opts * CopyOptions ) error {
438
448
if refPusher , ok := dst .(registry.ReferencePusher ); ok {
439
449
// optimize performance for ReferencePusher targets
440
450
preCopy := opts .PreCopy
@@ -467,7 +477,7 @@ func prepareCopy(ctx context.Context, dst Target, dstRef string, proxy *cas.Prox
467
477
if content .Equal (desc , root ) {
468
478
// for root node, tag it after copying it
469
479
if err := dst .Tag (ctx , root , dstRef ); err != nil {
470
- return err
480
+ return newCopyError ( "Tag" , CopyErrorOriginDestination , err )
471
481
}
472
482
}
473
483
if postCopy != nil {
@@ -499,7 +509,10 @@ func prepareCopy(ctx context.Context, dst Target, dstRef string, proxy *cas.Prox
499
509
return err
500
510
}
501
511
}
502
- return dst .Tag (ctx , root , dstRef )
512
+ if err := dst .Tag (ctx , root , dstRef ); err != nil {
513
+ return newCopyError ("Tag" , CopyErrorOriginDestination , err )
514
+ }
515
+ return nil
503
516
}
504
517
505
518
return nil
0 commit comments