Fix pulling images that contain no layers at all

The download manager assumed there was at least one layer involved in
all images. This can be false if the image is essentially a copy of
`scratch`.

Fix a nil pointer dereference that happened in this case. Add
integration tests that involve schema1 and schema2 manifests.

Fixes #21213

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Upstream-commit: 7cf894ce1013e5843d5c151f24520b51d34515d0
Component: engine
This commit is contained in:
Aaron Lehmann
2016-03-15 11:10:03 -07:00
parent 27cea9b936
commit 66aada1792
2 changed files with 30 additions and 1 deletions
@@ -146,7 +146,11 @@ func (ldm *LayerDownloadManager) Download(ctx context.Context, initialRootFS ima
}
if topDownload == nil {
return rootFS, func() { layer.ReleaseAndLog(ldm.layerStore, topLayer) }, nil
return rootFS, func() {
if topLayer != nil {
layer.ReleaseAndLog(ldm.layerStore, topLayer)
}
}, nil
}
// Won't be using the list built up so far - will generate it
@@ -279,6 +279,31 @@ func (s *DockerSchema1RegistrySuite) TestPullIDStability(c *check.C) {
testPullIDStability(c)
}
// #21213
func testPullNoLayers(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/scratch", privateRegistryURL)
_, err := buildImage(repoName, `
FROM scratch
ENV foo bar`,
true)
if err != nil {
c.Fatal(err)
}
dockerCmd(c, "push", repoName)
dockerCmd(c, "rmi", repoName)
dockerCmd(c, "pull", repoName)
}
func (s *DockerRegistrySuite) TestPullNoLayers(c *check.C) {
testPullNoLayers(c)
}
func (s *DockerSchema1RegistrySuite) TestPullNoLayers(c *check.C) {
testPullNoLayers(c)
}
func (s *DockerRegistrySuite) TestPullManifestList(c *check.C) {
testRequires(c, NotArm)
pushDigest, err := setupImage(c)