瀏覽代碼

Merge pull request #15039 from jlhawn/fix_build_context_is_symlink

[api/client] Fix build when context dir is symlink
Michael Crosby 10 年之前
父節點
當前提交
bdc55be9b4
共有 2 個文件被更改,包括 54 次插入0 次删除
  1. 16 0
      api/client/build.go
  2. 38 0
      integration-cli/docker_cli_build_test.go

+ 16 - 0
api/client/build.go

@@ -302,6 +302,22 @@ func getDockerfileRelPath(givenContextDir, givenDockerfile string) (absContextDi
 		return "", "", fmt.Errorf("unable to get absolute context directory: %v", err)
 	}
 
+	// The context dir might be a symbolic link, so follow it to the actual
+	// target directory.
+	absContextDir, err = filepath.EvalSymlinks(absContextDir)
+	if err != nil {
+		return "", "", fmt.Errorf("unable to evaluate symlinks in context path: %v", err)
+	}
+
+	stat, err := os.Lstat(absContextDir)
+	if err != nil {
+		return "", "", fmt.Errorf("unable to stat context directory %q: %v", absContextDir, err)
+	}
+
+	if !stat.IsDir() {
+		return "", "", fmt.Errorf("context must be a directory: %s", absContextDir)
+	}
+
 	absDockerfile := givenDockerfile
 	if absDockerfile == "" {
 		// No -f/--file was specified so use the default relative to the

+ 38 - 0
integration-cli/docker_cli_build_test.go

@@ -5394,3 +5394,41 @@ func (s *DockerTrustSuite) TestTrustedBuildUntrustedTag(c *check.C) {
 		c.Fatalf("Unexpected output on trusted build with untrusted tag:\n%s", out)
 	}
 }
+
+func (s *DockerTrustSuite) TestBuildContextDirIsSymlink(c *check.C) {
+	tempDir, err := ioutil.TempDir("", "test-build-dir-is-symlink-")
+	if err != nil {
+		c.Fatal(err)
+	}
+	defer os.RemoveAll(tempDir)
+
+	// Make a real context directory in this temp directory with a simple
+	// Dockerfile.
+	realContextDirname := filepath.Join(tempDir, "context")
+	if err := os.Mkdir(realContextDirname, os.FileMode(0755)); err != nil {
+		c.Fatal(err)
+	}
+
+	if err = ioutil.WriteFile(
+		filepath.Join(realContextDirname, "Dockerfile"),
+		[]byte(`
+			FROM busybox
+			RUN echo hello world
+		`),
+		os.FileMode(0644),
+	); err != nil {
+		c.Fatal(err)
+	}
+
+	// Make a symlink to the real context directory.
+	contextSymlinkName := filepath.Join(tempDir, "context_link")
+	if err := os.Symlink(realContextDirname, contextSymlinkName); err != nil {
+		c.Fatal(err)
+	}
+
+	// Executing the build with the symlink as the specified context should
+	// *not* fail.
+	if out, exitStatus := dockerCmd(c, "build", contextSymlinkName); exitStatus != 0 {
+		c.Fatalf("build failed with exit status %d: %s", exitStatus, out)
+	}
+}