Update resolv.conf in containers on file creation.
| ... | ... |
@@ -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 |
} |