Browse code

Fix files ownership when ADD is used

Signed-off-by: Mauricio Garavaglia <mauriciogaravaglia@gmail.com>

Mauricio Garavaglia authored on 2015/11/23 14:22:22
Showing 2 changed files
... ...
@@ -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"