@@ -534,15 +534,18 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
534
534
}
535
535
536
536
configChan := make (chan []byte , 1 )
537
- errChan := make (chan error , 1 )
537
+ configErrChan := make (chan error , 1 )
538
+ layerErrChan := make (chan error , 1 )
539
+ downloadsDone := make (chan struct {})
538
540
var cancel func ()
539
541
ctx , cancel = context .WithCancel (ctx )
542
+ defer cancel ()
540
543
541
544
// Pull the image config
542
545
go func () {
543
546
configJSON , err := p .pullSchema2Config (ctx , target .Digest )
544
547
if err != nil {
545
- errChan <- ImageConfigPullError {Err : err }
548
+ configErrChan <- ImageConfigPullError {Err : err }
546
549
cancel ()
547
550
return
548
551
}
@@ -553,6 +556,7 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
553
556
configJSON []byte // raw serialized image config
554
557
downloadedRootFS * image.RootFS // rootFS from registered layers
555
558
configRootFS * image.RootFS // rootFS from configuration
559
+ release func () // release resources from rootFS download
556
560
)
557
561
558
562
// https://github.com/docker/docker/issues/24766 - Err on the side of caution,
@@ -564,7 +568,7 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
564
568
// check to block Windows images being pulled on Linux is implemented, it
565
569
// may be necessary to perform the same type of serialisation.
566
570
if runtime .GOOS == "windows" {
567
- configJSON , configRootFS , err = receiveConfig (p .config .ImageStore , configChan , errChan )
571
+ configJSON , configRootFS , err = receiveConfig (p .config .ImageStore , configChan , configErrChan )
568
572
if err != nil {
569
573
return "" , "" , err
570
574
}
@@ -575,41 +579,52 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
575
579
}
576
580
577
581
if p .config .DownloadManager != nil {
578
- downloadRootFS := * image .NewRootFS ()
579
- rootFS , release , err := p .config .DownloadManager .Download (ctx , downloadRootFS , descriptors , p .config .ProgressOutput )
580
- if err != nil {
581
- if configJSON != nil {
582
- // Already received the config
583
- return "" , "" , err
584
- }
585
- select {
586
- case err = <- errChan :
587
- return "" , "" , err
588
- default :
589
- cancel ()
590
- select {
591
- case <- configChan :
592
- case <- errChan :
593
- }
594
- return "" , "" , err
582
+ go func () {
583
+ var (
584
+ err error
585
+ rootFS image.RootFS
586
+ )
587
+ downloadRootFS := * image .NewRootFS ()
588
+ rootFS , release , err = p .config .DownloadManager .Download (ctx , downloadRootFS , descriptors , p .config .ProgressOutput )
589
+ if err != nil {
590
+ // Intentionally do not cancel the config download here
591
+ // as the error from config download (if there is one)
592
+ // is more interesting than the layer download error
593
+ layerErrChan <- err
594
+ return
595
595
}
596
- }
597
- if release != nil {
598
- defer release ()
599
- }
600
596
601
- downloadedRootFS = & rootFS
597
+ downloadedRootFS = & rootFS
598
+ close (downloadsDone )
599
+ }()
600
+ } else {
601
+ // We have nothing to download
602
+ close (downloadsDone )
602
603
}
603
604
604
605
if configJSON == nil {
605
- configJSON , configRootFS , err = receiveConfig (p .config .ImageStore , configChan , errChan )
606
+ configJSON , configRootFS , err = receiveConfig (p .config .ImageStore , configChan , configErrChan )
607
+ if err == nil && configRootFS == nil {
608
+ err = errRootFSInvalid
609
+ }
606
610
if err != nil {
611
+ cancel ()
612
+ select {
613
+ case <- downloadsDone :
614
+ case <- layerErrChan :
615
+ }
607
616
return "" , "" , err
608
617
}
618
+ }
609
619
610
- if configRootFS == nil {
611
- return "" , "" , errRootFSInvalid
612
- }
620
+ select {
621
+ case <- downloadsDone :
622
+ case err = <- layerErrChan :
623
+ return "" , "" , err
624
+ }
625
+
626
+ if release != nil {
627
+ defer release ()
613
628
}
614
629
615
630
if downloadedRootFS != nil {
0 commit comments