Use RootFS from image config to register layers on Windows
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
parent
ad6c1b7649
commit
7450c258ab
|
@ -406,8 +406,31 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
|
|||
descriptors = append(descriptors, layerDescriptor)
|
||||
}
|
||||
|
||||
rootFS, release, err := p.config.DownloadManager.Download(ctx, *image.NewRootFS(), descriptors, p.config.ProgressOutput)
|
||||
var (
|
||||
configJSON []byte // raw serialized image config
|
||||
unmarshalledConfig image.Image // deserialized image config
|
||||
downloadRootFS image.RootFS // rootFS to use for registering layers.
|
||||
)
|
||||
if runtime.GOOS == "windows" {
|
||||
configJSON, unmarshalledConfig, err = receiveConfig(configChan, errChan)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if unmarshalledConfig.RootFS == nil {
|
||||
return "", "", errors.New("image config has no rootfs section")
|
||||
}
|
||||
downloadRootFS = *unmarshalledConfig.RootFS
|
||||
downloadRootFS.DiffIDs = []layer.DiffID{}
|
||||
} else {
|
||||
downloadRootFS = *image.NewRootFS()
|
||||
}
|
||||
|
||||
rootFS, release, err := p.config.DownloadManager.Download(ctx, downloadRootFS, descriptors, p.config.ProgressOutput)
|
||||
if err != nil {
|
||||
if configJSON != nil {
|
||||
// Already received the config
|
||||
return "", "", err
|
||||
}
|
||||
select {
|
||||
case err = <-errChan:
|
||||
return "", "", err
|
||||
|
@ -422,23 +445,16 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
|
|||
}
|
||||
defer release()
|
||||
|
||||
var configJSON []byte
|
||||
select {
|
||||
case configJSON = <-configChan:
|
||||
case err = <-errChan:
|
||||
return "", "", err
|
||||
// Don't need a case for ctx.Done in the select because cancellation
|
||||
// will trigger an error in p.pullSchema2ImageConfig.
|
||||
if configJSON == nil {
|
||||
configJSON, unmarshalledConfig, err = receiveConfig(configChan, errChan)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
}
|
||||
|
||||
// The DiffIDs returned in rootFS MUST match those in the config.
|
||||
// Otherwise the image config could be referencing layers that aren't
|
||||
// included in the manifest.
|
||||
var unmarshalledConfig image.Image
|
||||
if err = json.Unmarshal(configJSON, &unmarshalledConfig); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if len(rootFS.DiffIDs) != len(unmarshalledConfig.RootFS.DiffIDs) {
|
||||
return "", "", errRootFSMismatch
|
||||
}
|
||||
|
@ -457,6 +473,21 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
|
|||
return imageID, manifestDigest, nil
|
||||
}
|
||||
|
||||
func receiveConfig(configChan <-chan []byte, errChan <-chan error) ([]byte, image.Image, error) {
|
||||
select {
|
||||
case configJSON := <-configChan:
|
||||
var unmarshalledConfig image.Image
|
||||
if err := json.Unmarshal(configJSON, &unmarshalledConfig); err != nil {
|
||||
return nil, image.Image{}, err
|
||||
}
|
||||
return configJSON, unmarshalledConfig, nil
|
||||
case err := <-errChan:
|
||||
return nil, image.Image{}, err
|
||||
// Don't need a case for ctx.Done in the select because cancellation
|
||||
// will trigger an error in p.pullSchema2ImageConfig.
|
||||
}
|
||||
}
|
||||
|
||||
// pullManifestList handles "manifest lists" which point to various
|
||||
// platform-specifc manifests.
|
||||
func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mfstList *manifestlist.DeserializedManifestList) (imageID image.ID, manifestListDigest digest.Digest, err error) {
|
||||
|
|
Loading…
Reference in New Issue