Ver Fonte

Merge pull request #11896 from vdemeester/9998-cp

Docker cp handles resolv.conf, hostname & hosts, fixes #9998
Michael Crosby há 10 anos atrás
pai
commit
b6d6ffa1dd
2 ficheiros alterados com 75 adições e 0 exclusões
  1. 11 0
      daemon/container.go
  2. 64 0
      integration-cli/docker_cli_cp_test.go

+ 11 - 0
daemon/container.go

@@ -944,6 +944,17 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) {
 		}
 	}
 
+	// Check if this is a special one (resolv.conf, hostname, ..)
+	if resource == "etc/resolv.conf" {
+		basePath = container.ResolvConfPath
+	}
+	if resource == "etc/hostname" {
+		basePath = container.HostnamePath
+	}
+	if resource == "etc/hosts" {
+		basePath = container.HostsPath
+	}
+
 	stat, err := os.Stat(basePath)
 	if err != nil {
 		container.Unmount()

+ 64 - 0
integration-cli/docker_cli_cp_test.go

@@ -384,6 +384,70 @@ func TestCpUnprivilegedUser(t *testing.T) {
 	logDone("cp - unprivileged user")
 }
 
+func TestCpSpecialFiles(t *testing.T) {
+	testRequires(t, SameHostDaemon)
+
+	outDir, err := ioutil.TempDir("", "cp-test-special-files")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(outDir)
+
+	out, exitCode, err := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "touch /foo")
+	if err != nil || exitCode != 0 {
+		t.Fatal("failed to create a container", out, err)
+	}
+
+	cleanedContainerID := stripTrailingCharacters(out)
+	defer deleteContainer(cleanedContainerID)
+
+	out, _, err = dockerCmd(t, "wait", cleanedContainerID)
+	if err != nil || stripTrailingCharacters(out) != "0" {
+		t.Fatal("failed to set up container", out, err)
+	}
+
+	// Copy actual /etc/resolv.conf
+	_, _, err = dockerCmd(t, "cp", cleanedContainerID+":/etc/resolv.conf", outDir)
+	if err != nil {
+		t.Fatalf("couldn't copy from container: %s:%s %v", cleanedContainerID, "/etc/resolv.conf", err)
+	}
+
+	expected, err := ioutil.ReadFile("/var/lib/docker/containers/" + cleanedContainerID + "/resolv.conf")
+	actual, err := ioutil.ReadFile(outDir + "/resolv.conf")
+
+	if !bytes.Equal(actual, expected) {
+		t.Fatalf("Expected copied file to be duplicate of the container resolvconf")
+	}
+
+	// Copy actual /etc/hosts
+	_, _, err = dockerCmd(t, "cp", cleanedContainerID+":/etc/hosts", outDir)
+	if err != nil {
+		t.Fatalf("couldn't copy from container: %s:%s %v", cleanedContainerID, "/etc/hosts", err)
+	}
+
+	expected, err = ioutil.ReadFile("/var/lib/docker/containers/" + cleanedContainerID + "/hosts")
+	actual, err = ioutil.ReadFile(outDir + "/hosts")
+
+	if !bytes.Equal(actual, expected) {
+		t.Fatalf("Expected copied file to be duplicate of the container hosts")
+	}
+
+	// Copy actual /etc/resolv.conf
+	_, _, err = dockerCmd(t, "cp", cleanedContainerID+":/etc/hostname", outDir)
+	if err != nil {
+		t.Fatalf("couldn't copy from container: %s:%s %v", cleanedContainerID, "/etc/hostname", err)
+	}
+
+	expected, err = ioutil.ReadFile("/var/lib/docker/containers/" + cleanedContainerID + "/hostname")
+	actual, err = ioutil.ReadFile(outDir + "/hostname")
+
+	if !bytes.Equal(actual, expected) {
+		t.Fatalf("Expected copied file to be duplicate of the container resolvconf")
+	}
+
+	logDone("cp - special files (resolv.conf, hosts, hostname)")
+}
+
 func TestCpVolumePath(t *testing.T) {
 	testRequires(t, SameHostDaemon)