From 7cf894ce1013e5843d5c151f24520b51d34515d0 Mon Sep 17 00:00:00 2001 From: Aaron Lehmann Date: Tue, 15 Mar 2016 11:10:03 -0700 Subject: [PATCH] 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 --- distribution/xfer/download.go | 6 ++++- integration-cli/docker_cli_pull_local_test.go | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/distribution/xfer/download.go b/distribution/xfer/download.go index f8898a07cb..739c427c66 100644 --- a/distribution/xfer/download.go +++ b/distribution/xfer/download.go @@ -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 diff --git a/integration-cli/docker_cli_pull_local_test.go b/integration-cli/docker_cli_pull_local_test.go index 54b5b9ef90..a9614fdcd2 100644 --- a/integration-cli/docker_cli_pull_local_test.go +++ b/integration-cli/docker_cli_pull_local_test.go @@ -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)