Browse code

Merge pull request #10713 from swagiaal/pickup-created-resolvconf

Update resolv.conf in containers on file creation.

Phil Estes authored on 2015/03/05 00:21:36
Showing 2 changed files
... ...
@@ -441,7 +441,9 @@ func (daemon *Daemon) setupResolvconfWatcher() error {
441 441
 		for {
442 442
 			select {
443 443
 			case event := <-watcher.Events:
444
-				if event.Op&fsnotify.Write == fsnotify.Write {
444
+				if event.Name == "/etc/resolv.conf" &&
445
+					(event.Op&fsnotify.Write == fsnotify.Write ||
446
+						event.Op&fsnotify.Create == fsnotify.Create) {
445 447
 					// verify a real change happened before we go further--a file write may have happened
446 448
 					// without an actual change to the file
447 449
 					updatedResolvConf, newResolvConfHash, err := resolvconf.GetIfChanged()
... ...
@@ -474,7 +476,7 @@ func (daemon *Daemon) setupResolvconfWatcher() error {
474 474
 		}
475 475
 	}()
476 476
 
477
-	if err := watcher.Add("/etc/resolv.conf"); err != nil {
477
+	if err := watcher.Add("/etc"); err != nil {
478 478
 		return err
479 479
 	}
480 480
 	return nil
... ...
@@ -1600,6 +1600,14 @@ func TestRunResolvconfUpdater(t *testing.T) {
1600 1600
 		t.Fatal(err)
1601 1601
 	}
1602 1602
 
1603
+	// This test case is meant to test monitoring resolv.conf when it is
1604
+	// a regular file not a bind mount. So we unmount resolv.conf and replace
1605
+	// it with a file containing the original settings.
1606
+	cmd := exec.Command("umount", "/etc/resolv.conf")
1607
+	if _, err = runCommand(cmd); err != nil {
1608
+		t.Fatal(err)
1609
+	}
1610
+
1603 1611
 	//cleanup
1604 1612
 	defer func() {
1605 1613
 		deleteAllContainers()
... ...
@@ -1609,7 +1617,7 @@ func TestRunResolvconfUpdater(t *testing.T) {
1609 1609
 	}()
1610 1610
 
1611 1611
 	//1. test that a non-running container gets an updated resolv.conf
1612
-	cmd := exec.Command(dockerBinary, "run", "--name='first'", "busybox", "true")
1612
+	cmd = exec.Command(dockerBinary, "run", "--name='first'", "busybox", "true")
1613 1613
 	if _, err := runCommand(cmd); err != nil {
1614 1614
 		t.Fatal(err)
1615 1615
 	}
... ...
@@ -1732,6 +1740,45 @@ func TestRunResolvconfUpdater(t *testing.T) {
1732 1732
 		t.Fatalf("Container does not have cleaned/replaced DNS in resolv.conf; expected %q, got %q", expected, string(containerResolv))
1733 1733
 	}
1734 1734
 
1735
+	//6. Test that replacing (as opposed to modifying) resolv.conf triggers an update
1736
+	//   of containers' resolv.conf.
1737
+
1738
+	// Restore the original resolv.conf
1739
+	if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil {
1740
+		t.Fatal(err)
1741
+	}
1742
+
1743
+	// Run the container so it picks up the old settings
1744
+	cmd = exec.Command(dockerBinary, "run", "--name='third'", "busybox", "true")
1745
+	if _, err := runCommand(cmd); err != nil {
1746
+		t.Fatal(err)
1747
+	}
1748
+	containerID3, err := getIDByName("third")
1749
+	if err != nil {
1750
+		t.Fatal(err)
1751
+	}
1752
+
1753
+	// Create a modified resolv.conf.aside and override resolv.conf with it
1754
+	bytesResolvConf = []byte(tmpResolvConf)
1755
+	if err := ioutil.WriteFile("/etc/resolv.conf.aside", bytesResolvConf, 0644); err != nil {
1756
+		t.Fatal(err)
1757
+	}
1758
+
1759
+	err = os.Rename("/etc/resolv.conf.aside", "/etc/resolv.conf")
1760
+	if err != nil {
1761
+		t.Fatal(err)
1762
+	}
1763
+
1764
+	time.Sleep(time.Second / 2)
1765
+	// check for update in container
1766
+	containerResolv, err = readContainerFile(containerID3, "resolv.conf")
1767
+	if err != nil {
1768
+		t.Fatal(err)
1769
+	}
1770
+	if !bytes.Equal(containerResolv, bytesResolvConf) {
1771
+		t.Fatalf("Stopped container does not have updated resolv.conf; expected\n%q\n got\n%q", tmpResolvConf, string(containerResolv))
1772
+	}
1773
+
1735 1774
 	//cleanup, restore original resolv.conf happens in defer func()
1736 1775
 	logDone("run - resolv.conf updater")
1737 1776
 }