Docker-DCO-1.1-Signed-off-by: Erik Hollensbe <github@hollensbe.org> (github: erikh)
| ... | ... |
@@ -43,15 +43,30 @@ func prepareVolumesForContainer(container *Container) error {
|
| 43 | 43 |
|
| 44 | 44 |
func setupMountsForContainer(container *Container) error {
|
| 45 | 45 |
mounts := []execdriver.Mount{
|
| 46 |
- {container.ResolvConfPath, "/etc/resolv.conf", true, true},
|
|
| 46 |
+ {
|
|
| 47 |
+ Source: container.ResolvConfPath, |
|
| 48 |
+ Destination: "/etc/resolv.conf", |
|
| 49 |
+ Writable: true, |
|
| 50 |
+ Slave: true, |
|
| 51 |
+ }, |
|
| 47 | 52 |
} |
| 48 | 53 |
|
| 49 | 54 |
if container.HostnamePath != "" {
|
| 50 |
- mounts = append(mounts, execdriver.Mount{container.HostnamePath, "/etc/hostname", true, true})
|
|
| 55 |
+ mounts = append(mounts, execdriver.Mount{
|
|
| 56 |
+ Source: container.HostnamePath, |
|
| 57 |
+ Destination: "/etc/hostname", |
|
| 58 |
+ Writable: true, |
|
| 59 |
+ Private: true, |
|
| 60 |
+ }) |
|
| 51 | 61 |
} |
| 52 | 62 |
|
| 53 | 63 |
if container.HostsPath != "" {
|
| 54 |
- mounts = append(mounts, execdriver.Mount{container.HostsPath, "/etc/hosts", true, true})
|
|
| 64 |
+ mounts = append(mounts, execdriver.Mount{
|
|
| 65 |
+ Source: container.HostsPath, |
|
| 66 |
+ Destination: "/etc/hosts", |
|
| 67 |
+ Writable: true, |
|
| 68 |
+ Slave: true, |
|
| 69 |
+ }) |
|
| 55 | 70 |
} |
| 56 | 71 |
|
| 57 | 72 |
// Mount user specified volumes |
| ... | ... |
@@ -59,7 +74,11 @@ func setupMountsForContainer(container *Container) error {
|
| 59 | 59 |
// volumes. For instance if you use -v /usr:/usr and the host later mounts /usr/share you |
| 60 | 60 |
// want this new mount in the container |
| 61 | 61 |
for r, v := range container.Volumes {
|
| 62 |
- mounts = append(mounts, execdriver.Mount{v, r, container.VolumesRW[r], false})
|
|
| 62 |
+ mounts = append(mounts, execdriver.Mount{
|
|
| 63 |
+ Source: v, |
|
| 64 |
+ Destination: r, |
|
| 65 |
+ Writable: container.VolumesRW[r], |
|
| 66 |
+ }) |
|
| 63 | 67 |
} |
| 64 | 68 |
|
| 65 | 69 |
container.command.Mounts = mounts |
| ... | ... |
@@ -1749,27 +1749,103 @@ func TestBindMounts(t *testing.T) {
|
| 1749 | 1749 |
logDone("run - bind mounts")
|
| 1750 | 1750 |
} |
| 1751 | 1751 |
|
| 1752 |
-func TestHostsLinkedContainerUpdate(t *testing.T) {
|
|
| 1753 |
- tmpdir, err := ioutil.TempDir("", "docker-integration")
|
|
| 1754 |
- if err != nil {
|
|
| 1755 |
- t.Fatal(err) |
|
| 1752 |
+func TestMutableNetworkFiles(t *testing.T) {
|
|
| 1753 |
+ defer deleteAllContainers() |
|
| 1754 |
+ |
|
| 1755 |
+ for _, fn := range []string{"resolv.conf", "hosts"} {
|
|
| 1756 |
+ deleteAllContainers() |
|
| 1757 |
+ |
|
| 1758 |
+ out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "c1", "busybox", "sh", "-c", fmt.Sprintf("echo success >/etc/%s; while true; do sleep 1; done", fn)))
|
|
| 1759 |
+ if err != nil {
|
|
| 1760 |
+ t.Fatal(err, out) |
|
| 1761 |
+ } |
|
| 1762 |
+ |
|
| 1763 |
+ time.Sleep(1 * time.Second) |
|
| 1764 |
+ |
|
| 1765 |
+ contID := strings.TrimSpace(out) |
|
| 1766 |
+ |
|
| 1767 |
+ f, err := os.Open(filepath.Join("/var/lib/docker/containers", contID, fn))
|
|
| 1768 |
+ if err != nil {
|
|
| 1769 |
+ t.Fatal(err) |
|
| 1770 |
+ } |
|
| 1771 |
+ |
|
| 1772 |
+ content, err := ioutil.ReadAll(f) |
|
| 1773 |
+ f.Close() |
|
| 1774 |
+ |
|
| 1775 |
+ if strings.TrimSpace(string(content)) != "success" {
|
|
| 1776 |
+ t.Fatal("Content was not what was modified in the container", string(content))
|
|
| 1777 |
+ } |
|
| 1778 |
+ |
|
| 1779 |
+ out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "c2", "busybox", "sh", "-c", fmt.Sprintf("while true; do cat /etc/%s; sleep 1; done", fn)))
|
|
| 1780 |
+ if err != nil {
|
|
| 1781 |
+ t.Fatal(err) |
|
| 1782 |
+ } |
|
| 1783 |
+ |
|
| 1784 |
+ contID = strings.TrimSpace(out) |
|
| 1785 |
+ |
|
| 1786 |
+ resolvConfPath := filepath.Join("/var/lib/docker/containers", contID, fn)
|
|
| 1787 |
+ |
|
| 1788 |
+ f, err = os.OpenFile(resolvConfPath, os.O_WRONLY|os.O_SYNC|os.O_APPEND, 0644) |
|
| 1789 |
+ if err != nil {
|
|
| 1790 |
+ t.Fatal(err) |
|
| 1791 |
+ } |
|
| 1792 |
+ |
|
| 1793 |
+ if _, err := f.Seek(0, 0); err != nil {
|
|
| 1794 |
+ f.Close() |
|
| 1795 |
+ t.Fatal(err) |
|
| 1796 |
+ } |
|
| 1797 |
+ |
|
| 1798 |
+ if err := f.Truncate(0); err != nil {
|
|
| 1799 |
+ f.Close() |
|
| 1800 |
+ t.Fatal(err) |
|
| 1801 |
+ } |
|
| 1802 |
+ |
|
| 1803 |
+ if _, err := f.Write([]byte("success2\n")); err != nil {
|
|
| 1804 |
+ f.Close() |
|
| 1805 |
+ t.Fatal(err) |
|
| 1806 |
+ } |
|
| 1807 |
+ |
|
| 1808 |
+ f.Close() |
|
| 1809 |
+ |
|
| 1810 |
+ time.Sleep(2 * time.Second) // don't race sleep |
|
| 1811 |
+ |
|
| 1812 |
+ out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "logs", "c2")) |
|
| 1813 |
+ if err != nil {
|
|
| 1814 |
+ t.Fatal(err) |
|
| 1815 |
+ } |
|
| 1816 |
+ |
|
| 1817 |
+ lines := strings.Split(out, "\n") |
|
| 1818 |
+ if strings.TrimSpace(lines[len(lines)-2]) != "success2" {
|
|
| 1819 |
+ t.Fatalf("Did not find the correct output in /etc/%s: %s %#v", fn, out, lines)
|
|
| 1820 |
+ } |
|
| 1756 | 1821 |
} |
| 1757 |
- defer os.RemoveAll(tmpdir) |
|
| 1822 |
+} |
|
| 1758 | 1823 |
|
| 1759 |
- out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "c1", "busybox", "sleep", "5")) |
|
| 1824 |
+func TestHostsLinkedContainerUpdate(t *testing.T) {
|
|
| 1825 |
+ deleteAllContainers() |
|
| 1826 |
+ out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "c1", "busybox", "sh", "-c", "while true; do sleep 1; done")) |
|
| 1760 | 1827 |
if err != nil {
|
| 1761 | 1828 |
t.Fatal(err, out) |
| 1762 | 1829 |
} |
| 1763 | 1830 |
|
| 1764 | 1831 |
// TODO fix docker cp and /etc/hosts |
| 1765 |
- out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--link", "c1:c1", "--name", "c2", "busybox", "sh", "-c", "while true;do cp /etc/hosts /hosts; done")) |
|
| 1832 |
+ out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--link", "c1:c1", "--name", "c2", "busybox", "sh", "-c", "while true;do sleep 1; done")) |
|
| 1766 | 1833 |
if err != nil {
|
| 1767 | 1834 |
t.Fatal(err, out) |
| 1768 | 1835 |
} |
| 1769 | 1836 |
|
| 1770 |
- out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "cp", "c2:/hosts", tmpdir+"/1")) |
|
| 1837 |
+ contID := strings.TrimSpace(out) |
|
| 1838 |
+ |
|
| 1839 |
+ f, err := os.Open(filepath.Join("/var/lib/docker/containers", contID, "hosts"))
|
|
| 1771 | 1840 |
if err != nil {
|
| 1772 |
- t.Fatal(err, out) |
|
| 1841 |
+ t.Fatal(err) |
|
| 1842 |
+ } |
|
| 1843 |
+ |
|
| 1844 |
+ originalContent, err := ioutil.ReadAll(f) |
|
| 1845 |
+ f.Close() |
|
| 1846 |
+ |
|
| 1847 |
+ if err != nil {
|
|
| 1848 |
+ t.Fatal(err) |
|
| 1773 | 1849 |
} |
| 1774 | 1850 |
|
| 1775 | 1851 |
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "restart", "-t", "0", "c1")) |
| ... | ... |
@@ -1777,17 +1853,19 @@ func TestHostsLinkedContainerUpdate(t *testing.T) {
|
| 1777 | 1777 |
t.Fatal(err, out) |
| 1778 | 1778 |
} |
| 1779 | 1779 |
|
| 1780 |
- out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "cp", "c2:/hosts", tmpdir+"/2")) |
|
| 1780 |
+ f, err = os.Open(filepath.Join("/var/lib/docker/containers", contID, "hosts"))
|
|
| 1781 | 1781 |
if err != nil {
|
| 1782 |
- t.Fatal(err, out) |
|
| 1782 |
+ t.Fatal(err) |
|
| 1783 | 1783 |
} |
| 1784 | 1784 |
|
| 1785 |
- out, _, _, err = runCommandWithStdoutStderr(exec.Command("diff", tmpdir+"/1", tmpdir+"/2"))
|
|
| 1786 |
- if err == nil {
|
|
| 1787 |
- t.Fatalf("Expecting error, got none")
|
|
| 1785 |
+ newContent, err := ioutil.ReadAll(f) |
|
| 1786 |
+ f.Close() |
|
| 1787 |
+ |
|
| 1788 |
+ if err != nil {
|
|
| 1789 |
+ t.Fatal(err) |
|
| 1788 | 1790 |
} |
| 1789 |
- out = stripTrailingCharacters(out) |
|
| 1790 |
- if out == "" {
|
|
| 1791 |
+ |
|
| 1792 |
+ if strings.TrimSpace(string(originalContent)) == strings.TrimSpace(string(newContent)) {
|
|
| 1791 | 1793 |
t.Fatalf("expected /etc/hosts to be updated, but wasn't")
|
| 1792 | 1794 |
} |
| 1793 | 1795 |
|