Browse code

Docker cp handles resolv.conf, hostname & hosts, fixes #9998

Add a integration test TestCpSpecialFiles

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2015/03/29 19:58:57
Showing 2 changed files
... ...
@@ -944,6 +944,17 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) {
944 944
 		}
945 945
 	}
946 946
 
947
+	// Check if this is a special one (resolv.conf, hostname, ..)
948
+	if resource == "etc/resolv.conf" {
949
+		basePath = container.ResolvConfPath
950
+	}
951
+	if resource == "etc/hostname" {
952
+		basePath = container.HostnamePath
953
+	}
954
+	if resource == "etc/hosts" {
955
+		basePath = container.HostsPath
956
+	}
957
+
947 958
 	stat, err := os.Stat(basePath)
948 959
 	if err != nil {
949 960
 		container.Unmount()
... ...
@@ -384,6 +384,70 @@ func TestCpUnprivilegedUser(t *testing.T) {
384 384
 	logDone("cp - unprivileged user")
385 385
 }
386 386
 
387
+func TestCpSpecialFiles(t *testing.T) {
388
+	testRequires(t, SameHostDaemon)
389
+
390
+	outDir, err := ioutil.TempDir("", "cp-test-special-files")
391
+	if err != nil {
392
+		t.Fatal(err)
393
+	}
394
+	defer os.RemoveAll(outDir)
395
+
396
+	out, exitCode, err := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "touch /foo")
397
+	if err != nil || exitCode != 0 {
398
+		t.Fatal("failed to create a container", out, err)
399
+	}
400
+
401
+	cleanedContainerID := stripTrailingCharacters(out)
402
+	defer deleteContainer(cleanedContainerID)
403
+
404
+	out, _, err = dockerCmd(t, "wait", cleanedContainerID)
405
+	if err != nil || stripTrailingCharacters(out) != "0" {
406
+		t.Fatal("failed to set up container", out, err)
407
+	}
408
+
409
+	// Copy actual /etc/resolv.conf
410
+	_, _, err = dockerCmd(t, "cp", cleanedContainerID+":/etc/resolv.conf", outDir)
411
+	if err != nil {
412
+		t.Fatalf("couldn't copy from container: %s:%s %v", cleanedContainerID, "/etc/resolv.conf", err)
413
+	}
414
+
415
+	expected, err := ioutil.ReadFile("/var/lib/docker/containers/" + cleanedContainerID + "/resolv.conf")
416
+	actual, err := ioutil.ReadFile(outDir + "/resolv.conf")
417
+
418
+	if !bytes.Equal(actual, expected) {
419
+		t.Fatalf("Expected copied file to be duplicate of the container resolvconf")
420
+	}
421
+
422
+	// Copy actual /etc/hosts
423
+	_, _, err = dockerCmd(t, "cp", cleanedContainerID+":/etc/hosts", outDir)
424
+	if err != nil {
425
+		t.Fatalf("couldn't copy from container: %s:%s %v", cleanedContainerID, "/etc/hosts", err)
426
+	}
427
+
428
+	expected, err = ioutil.ReadFile("/var/lib/docker/containers/" + cleanedContainerID + "/hosts")
429
+	actual, err = ioutil.ReadFile(outDir + "/hosts")
430
+
431
+	if !bytes.Equal(actual, expected) {
432
+		t.Fatalf("Expected copied file to be duplicate of the container hosts")
433
+	}
434
+
435
+	// Copy actual /etc/resolv.conf
436
+	_, _, err = dockerCmd(t, "cp", cleanedContainerID+":/etc/hostname", outDir)
437
+	if err != nil {
438
+		t.Fatalf("couldn't copy from container: %s:%s %v", cleanedContainerID, "/etc/hostname", err)
439
+	}
440
+
441
+	expected, err = ioutil.ReadFile("/var/lib/docker/containers/" + cleanedContainerID + "/hostname")
442
+	actual, err = ioutil.ReadFile(outDir + "/hostname")
443
+
444
+	if !bytes.Equal(actual, expected) {
445
+		t.Fatalf("Expected copied file to be duplicate of the container resolvconf")
446
+	}
447
+
448
+	logDone("cp - special files (resolv.conf, hosts, hostname)")
449
+}
450
+
387 451
 func TestCpVolumePath(t *testing.T) {
388 452
 	testRequires(t, SameHostDaemon)
389 453