diff --git a/integration/buildfile_test.go b/integration/buildfile_test.go index 95d5abb8a7..ae2282f53f 100644 --- a/integration/buildfile_test.go +++ b/integration/buildfile_test.go @@ -998,3 +998,21 @@ func TestBuildOnBuildForbiddenMaintainerTrigger(t *testing.T) { t.Fatal("Error should not be nil") } } + +// gh #2446 +func TestBuildAddToSymlinkDest(t *testing.T) { + eng := NewTestEngine(t) + defer nuke(mkRuntimeFromEngine(eng, t)) + + _, err := buildImage(testContextTemplate{` + from {IMAGE} + run mkdir /foo + run ln -s /foo /bar + add foo /bar/ + run stat /bar/foo + `, + [][2]string{{"foo", "HEYO"}}, nil}, t, eng, true) + if err != nil { + t.Fatal(err) + } +} diff --git a/server/buildfile.go b/server/buildfile.go index 5d5fda4d8e..6f95c2e593 100644 --- a/server/buildfile.go +++ b/server/buildfile.go @@ -395,9 +395,18 @@ func (b *buildFile) checkPathForAddition(orig string) error { func (b *buildFile) addContext(container *runtime.Container, orig, dest string, remote bool) error { var ( + err error origPath = path.Join(b.contextPath, orig) destPath = path.Join(container.RootfsPath(), dest) ) + + if destPath != container.RootfsPath() { + destPath, err = utils.FollowSymlinkInScope(destPath, container.RootfsPath()) + if err != nil { + return err + } + } + // Preserve the trailing '/' if strings.HasSuffix(dest, "/") { destPath = destPath + "/"