Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit 7450c25

Browse files
author
Aaron Lehmann
committed
Use RootFS from image config to register layers on Windows
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
1 parent ad6c1b7 commit 7450c25

File tree

1 file changed

+44
-13
lines changed

1 file changed

+44
-13
lines changed

distribution/pull_v2.go

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,31 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
406406
descriptors = append(descriptors, layerDescriptor)
407407
}
408408

409-
rootFS, release, err := p.config.DownloadManager.Download(ctx, *image.NewRootFS(), descriptors, p.config.ProgressOutput)
409+
var (
410+
configJSON []byte // raw serialized image config
411+
unmarshalledConfig image.Image // deserialized image config
412+
downloadRootFS image.RootFS // rootFS to use for registering layers.
413+
)
414+
if runtime.GOOS == "windows" {
415+
configJSON, unmarshalledConfig, err = receiveConfig(configChan, errChan)
416+
if err != nil {
417+
return "", "", err
418+
}
419+
if unmarshalledConfig.RootFS == nil {
420+
return "", "", errors.New("image config has no rootfs section")
421+
}
422+
downloadRootFS = *unmarshalledConfig.RootFS
423+
downloadRootFS.DiffIDs = []layer.DiffID{}
424+
} else {
425+
downloadRootFS = *image.NewRootFS()
426+
}
427+
428+
rootFS, release, err := p.config.DownloadManager.Download(ctx, downloadRootFS, descriptors, p.config.ProgressOutput)
410429
if err != nil {
430+
if configJSON != nil {
431+
// Already received the config
432+
return "", "", err
433+
}
411434
select {
412435
case err = <-errChan:
413436
return "", "", err
@@ -422,23 +445,16 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
422445
}
423446
defer release()
424447

425-
var configJSON []byte
426-
select {
427-
case configJSON = <-configChan:
428-
case err = <-errChan:
429-
return "", "", err
430-
// Don't need a case for ctx.Done in the select because cancellation
431-
// will trigger an error in p.pullSchema2ImageConfig.
448+
if configJSON == nil {
449+
configJSON, unmarshalledConfig, err = receiveConfig(configChan, errChan)
450+
if err != nil {
451+
return "", "", err
452+
}
432453
}
433454

434455
// The DiffIDs returned in rootFS MUST match those in the config.
435456
// Otherwise the image config could be referencing layers that aren't
436457
// included in the manifest.
437-
var unmarshalledConfig image.Image
438-
if err = json.Unmarshal(configJSON, &unmarshalledConfig); err != nil {
439-
return "", "", err
440-
}
441-
442458
if len(rootFS.DiffIDs) != len(unmarshalledConfig.RootFS.DiffIDs) {
443459
return "", "", errRootFSMismatch
444460
}
@@ -457,6 +473,21 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
457473
return imageID, manifestDigest, nil
458474
}
459475

476+
func receiveConfig(configChan <-chan []byte, errChan <-chan error) ([]byte, image.Image, error) {
477+
select {
478+
case configJSON := <-configChan:
479+
var unmarshalledConfig image.Image
480+
if err := json.Unmarshal(configJSON, &unmarshalledConfig); err != nil {
481+
return nil, image.Image{}, err
482+
}
483+
return configJSON, unmarshalledConfig, nil
484+
case err := <-errChan:
485+
return nil, image.Image{}, err
486+
// Don't need a case for ctx.Done in the select because cancellation
487+
// will trigger an error in p.pullSchema2ImageConfig.
488+
}
489+
}
490+
460491
// pullManifestList handles "manifest lists" which point to various
461492
// platform-specifc manifests.
462493
func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mfstList *manifestlist.DeserializedManifestList) (imageID image.ID, manifestListDigest digest.Digest, err error) {

0 commit comments

Comments
 (0)