Skip to content

Commit 8bc330d

Browse files
committed
Docker cp handles resolv.conf, hostname & hosts, fixes moby#9998
Add a integration test TestCpSpecialFiles Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 1f27ebc commit 8bc330d

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

daemon/container.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,17 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) {
944944
}
945945
}
946946

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+
947958
stat, err := os.Stat(basePath)
948959
if err != nil {
949960
container.Unmount()

integration-cli/docker_cli_cp_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,70 @@ func TestCpUnprivilegedUser(t *testing.T) {
384384
logDone("cp - unprivileged user")
385385
}
386386

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+
387451
func TestCpVolumePath(t *testing.T) {
388452
testRequires(t, SameHostDaemon)
389453

0 commit comments

Comments
 (0)