Signed-off-by: Mauricio Garavaglia <mauriciogaravaglia@gmail.com>
| ... | ... |
@@ -127,6 +127,7 @@ func (d Docker) Release(sessionID string, activeImages []string) {
|
| 127 | 127 |
func (d Docker) Copy(c *daemon.Container, destPath string, src builder.FileInfo, decompress bool) error {
|
| 128 | 128 |
srcPath := src.Path() |
| 129 | 129 |
destExists := true |
| 130 |
+ destDir := false |
|
| 130 | 131 |
rootUID, rootGID := d.Daemon.GetRemappedUIDGID() |
| 131 | 132 |
|
| 132 | 133 |
// Work in daemon-local OS specific file paths |
| ... | ... |
@@ -140,6 +141,7 @@ func (d Docker) Copy(c *daemon.Container, destPath string, src builder.FileInfo, |
| 140 | 140 |
// Preserve the trailing slash |
| 141 | 141 |
// TODO: why are we appending another path separator if there was already one? |
| 142 | 142 |
if strings.HasSuffix(destPath, string(os.PathSeparator)) || destPath == "." {
|
| 143 |
+ destDir = true |
|
| 143 | 144 |
dest += string(os.PathSeparator) |
| 144 | 145 |
} |
| 145 | 146 |
|
| ... | ... |
@@ -182,7 +184,7 @@ func (d Docker) Copy(c *daemon.Container, destPath string, src builder.FileInfo, |
| 182 | 182 |
} |
| 183 | 183 |
|
| 184 | 184 |
// only needed for fixPermissions, but might as well put it before CopyFileWithTar |
| 185 |
- if destExists && destStat.IsDir() {
|
|
| 185 |
+ if destDir || (destExists && destStat.IsDir()) {
|
|
| 186 | 186 |
destPath = filepath.Join(destPath, src.Name()) |
| 187 | 187 |
} |
| 188 | 188 |
|
| ... | ... |
@@ -3252,6 +3252,46 @@ func (s *DockerSuite) TestBuildAddFileNotFound(c *check.C) {
|
| 3252 | 3252 |
} |
| 3253 | 3253 |
} |
| 3254 | 3254 |
|
| 3255 |
+func (s *DockerSuite) TestBuildAddChangeOwnership(c *check.C) {
|
|
| 3256 |
+ testRequires(c, DaemonIsLinux) |
|
| 3257 |
+ name := "testbuildaddown" |
|
| 3258 |
+ |
|
| 3259 |
+ ctx := func() *FakeContext {
|
|
| 3260 |
+ dockerfile := ` |
|
| 3261 |
+ FROM busybox |
|
| 3262 |
+ ADD foo /bar/ |
|
| 3263 |
+ RUN [ $(stat -c %U:%G "/bar") = 'root:root' ] |
|
| 3264 |
+ RUN [ $(stat -c %U:%G "/bar/foo") = 'root:root' ] |
|
| 3265 |
+ ` |
|
| 3266 |
+ tmpDir, err := ioutil.TempDir("", "fake-context")
|
|
| 3267 |
+ c.Assert(err, check.IsNil) |
|
| 3268 |
+ testFile, err := os.Create(filepath.Join(tmpDir, "foo")) |
|
| 3269 |
+ if err != nil {
|
|
| 3270 |
+ c.Fatalf("failed to create foo file: %v", err)
|
|
| 3271 |
+ } |
|
| 3272 |
+ defer testFile.Close() |
|
| 3273 |
+ |
|
| 3274 |
+ chownCmd := exec.Command("chown", "daemon:daemon", "foo")
|
|
| 3275 |
+ chownCmd.Dir = tmpDir |
|
| 3276 |
+ out, _, err := runCommandWithOutput(chownCmd) |
|
| 3277 |
+ if err != nil {
|
|
| 3278 |
+ c.Fatal(err, out) |
|
| 3279 |
+ } |
|
| 3280 |
+ |
|
| 3281 |
+ if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
|
|
| 3282 |
+ c.Fatalf("failed to open destination dockerfile: %v", err)
|
|
| 3283 |
+ } |
|
| 3284 |
+ return fakeContextFromDir(tmpDir) |
|
| 3285 |
+ }() |
|
| 3286 |
+ |
|
| 3287 |
+ defer ctx.Close() |
|
| 3288 |
+ |
|
| 3289 |
+ if _, err := buildImageFromContext(name, ctx, true); err != nil {
|
|
| 3290 |
+ c.Fatalf("build failed to complete for TestBuildAddChangeOwnership: %v", err)
|
|
| 3291 |
+ } |
|
| 3292 |
+ |
|
| 3293 |
+} |
|
| 3294 |
+ |
|
| 3255 | 3295 |
func (s *DockerSuite) TestBuildInheritance(c *check.C) {
|
| 3256 | 3296 |
testRequires(c, DaemonIsLinux) |
| 3257 | 3297 |
name := "testbuildinheritance" |