소스 검색

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>
Aaron Lehmann 9 년 전
부모
커밋
7cf894ce10
2개의 변경된 파일30개의 추가작업 그리고 1개의 파일을 삭제
  1. 5 1
      distribution/xfer/download.go
  2. 25 0
      integration-cli/docker_cli_pull_local_test.go

+ 5 - 1
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

+ 25 - 0
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)