From 11c7c9710a670ad1f49de8f2814caa51d2f7adb6 Mon Sep 17 00:00:00 2001 From: Sami Wagiaalla Date: Wed, 11 Feb 2015 15:01:30 -0500 Subject: [PATCH] Update resolve.conf in containers on file creation. NetworkManager updates resolve.conf by replacing the current file with an updated one. This change enables docker to listen for these events. Signed-off-by: Sami Wagiaalla --- daemon/daemon.go | 6 ++-- integration-cli/docker_cli_run_test.go | 49 +++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/daemon/daemon.go b/daemon/daemon.go index e23193e2b8..aeaf9126ea 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -440,7 +440,9 @@ func (daemon *Daemon) setupResolvconfWatcher() error { for { select { case event := <-watcher.Events: - if event.Op&fsnotify.Write == fsnotify.Write { + if event.Name == "/etc/resolv.conf" && + (event.Op&fsnotify.Write == fsnotify.Write || + event.Op&fsnotify.Create == fsnotify.Create) { // verify a real change happened before we go further--a file write may have happened // without an actual change to the file updatedResolvConf, newResolvConfHash, err := resolvconf.GetIfChanged() @@ -473,7 +475,7 @@ func (daemon *Daemon) setupResolvconfWatcher() error { } }() - if err := watcher.Add("/etc/resolv.conf"); err != nil { + if err := watcher.Add("/etc"); err != nil { return err } return nil diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index d96d2192ad..b3f4e7a76f 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -1598,6 +1598,14 @@ func TestRunResolvconfUpdater(t *testing.T) { t.Fatal(err) } + // This test case is meant to test monitoring resolv.conf when it is + // a regular file not a bind mount. So we unmount resolv.conf and replace + // it with a file containing the original settings. + cmd := exec.Command("umount", "/etc/resolv.conf") + if _, err = runCommand(cmd); err != nil { + t.Fatal(err) + } + //cleanup defer func() { deleteAllContainers() @@ -1607,7 +1615,7 @@ func TestRunResolvconfUpdater(t *testing.T) { }() //1. test that a non-running container gets an updated resolv.conf - cmd := exec.Command(dockerBinary, "run", "--name='first'", "busybox", "true") + cmd = exec.Command(dockerBinary, "run", "--name='first'", "busybox", "true") if _, err := runCommand(cmd); err != nil { t.Fatal(err) } @@ -1730,6 +1738,45 @@ func TestRunResolvconfUpdater(t *testing.T) { t.Fatalf("Container does not have cleaned/replaced DNS in resolv.conf; expected %q, got %q", expected, string(containerResolv)) } + //6. Test that replacing (as opposed to modifying) resolv.conf triggers an update + // of containers' resolv.conf. + + // Restore the original resolv.conf + if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil { + t.Fatal(err) + } + + // Run the container so it picks up the old settings + cmd = exec.Command(dockerBinary, "run", "--name='third'", "busybox", "true") + if _, err := runCommand(cmd); err != nil { + t.Fatal(err) + } + containerID3, err := getIDByName("third") + if err != nil { + t.Fatal(err) + } + + // Create a modified resolv.conf.aside and override resolv.conf with it + bytesResolvConf = []byte(tmpResolvConf) + if err := ioutil.WriteFile("/etc/resolv.conf.aside", bytesResolvConf, 0644); err != nil { + t.Fatal(err) + } + + err = os.Rename("/etc/resolv.conf.aside", "/etc/resolv.conf") + if err != nil { + t.Fatal(err) + } + + time.Sleep(time.Second / 2) + // check for update in container + containerResolv, err = readContainerFile(containerID3, "resolv.conf") + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(containerResolv, bytesResolvConf) { + t.Fatalf("Stopped container does not have updated resolv.conf; expected\n%q\n got\n%q", tmpResolvConf, string(containerResolv)) + } + //cleanup, restore original resolv.conf happens in defer func() logDone("run - resolv.conf updater") }