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)