Skip to content

Commit 01d570a

Browse files
author
Josh Hawn
committed
[api/client] Fix build when context dir is symlink
Symbolic links in the context directory path are now evaluated. Docker-DCO-1.1-Signed-off-by: Josh Hawn <[email protected]> (github: jlhawn)
1 parent d021537 commit 01d570a

2 files changed

Lines changed: 54 additions & 0 deletions

File tree

api/client/build.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,22 @@ func getDockerfileRelPath(givenContextDir, givenDockerfile string) (absContextDi
302302
return "", "", fmt.Errorf("unable to get absolute context directory: %v", err)
303303
}
304304

305+
// The context dir might be a symbolic link, so follow it to the actual
306+
// target directory.
307+
absContextDir, err = filepath.EvalSymlinks(absContextDir)
308+
if err != nil {
309+
return "", "", fmt.Errorf("unable to evaluate symlinks in context path: %v", err)
310+
}
311+
312+
stat, err := os.Lstat(absContextDir)
313+
if err != nil {
314+
return "", "", fmt.Errorf("unable to stat context directory %q: %v", absContextDir, err)
315+
}
316+
317+
if !stat.IsDir() {
318+
return "", "", fmt.Errorf("context must be a directory: %s", absContextDir)
319+
}
320+
305321
absDockerfile := givenDockerfile
306322
if absDockerfile == "" {
307323
// No -f/--file was specified so use the default relative to the

integration-cli/docker_cli_build_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5394,3 +5394,41 @@ func (s *DockerTrustSuite) TestTrustedBuildUntrustedTag(c *check.C) {
53945394
c.Fatalf("Unexpected output on trusted build with untrusted tag:\n%s", out)
53955395
}
53965396
}
5397+
5398+
func (s *DockerTrustSuite) TestBuildContextDirIsSymlink(c *check.C) {
5399+
tempDir, err := ioutil.TempDir("", "test-build-dir-is-symlink-")
5400+
if err != nil {
5401+
c.Fatal(err)
5402+
}
5403+
defer os.RemoveAll(tempDir)
5404+
5405+
// Make a real context directory in this temp directory with a simple
5406+
// Dockerfile.
5407+
realContextDirname := filepath.Join(tempDir, "context")
5408+
if err := os.Mkdir(realContextDirname, os.FileMode(0755)); err != nil {
5409+
c.Fatal(err)
5410+
}
5411+
5412+
if err = ioutil.WriteFile(
5413+
filepath.Join(realContextDirname, "Dockerfile"),
5414+
[]byte(`
5415+
FROM busybox
5416+
RUN echo hello world
5417+
`),
5418+
os.FileMode(0644),
5419+
); err != nil {
5420+
c.Fatal(err)
5421+
}
5422+
5423+
// Make a symlink to the real context directory.
5424+
contextSymlinkName := filepath.Join(tempDir, "context_link")
5425+
if err := os.Symlink(realContextDirname, contextSymlinkName); err != nil {
5426+
c.Fatal(err)
5427+
}
5428+
5429+
// Executing the build with the symlink as the specified context should
5430+
// *not* fail.
5431+
if out, exitStatus := dockerCmd(c, "build", contextSymlinkName); exitStatus != 0 {
5432+
c.Fatalf("build failed with exit status %d: %s", exitStatus, out)
5433+
}
5434+
}

0 commit comments

Comments
 (0)