Skip to content

Commit 9a84135

Browse files
authored
Merge pull request moby#51615 from akerouanton/revert-51507
Revert "libnet: setupDNS: don't overwrite user-modified resolv.conf"
2 parents 710302e + 56e8e43 commit 9a84135

4 files changed

Lines changed: 15 additions & 117 deletions

File tree

daemon/libnetwork/sandbox_dns_unix.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -264,17 +264,8 @@ func (sb *Sandbox) loadResolvConf(path string) (*resolvconf.ResolvConf, error) {
264264
// be a copy of the host's file, with overrides for nameservers, options and search
265265
// domains applied.
266266
func (sb *Sandbox) setupDNS() error {
267-
sb.restoreResolvConfPath()
268-
269-
// When the container is restarted, a new Sandbox is created but the same resolv.conf is re-used. If it was
270-
// user-modified, do not attempt to overwrite it.
271-
if !sb.config.useDefaultSandBox {
272-
if mod, err := resolvconf.UserModified(sb.config.resolvConfPath, sb.config.resolvConfHashFile); err != nil || mod {
273-
return err
274-
}
275-
}
276-
277267
// Make sure the directory exists.
268+
sb.restoreResolvConfPath()
278269
dir, _ := filepath.Split(sb.config.resolvConfPath)
279270
if err := createBasePath(dir); err != nil {
280271
return err
@@ -338,7 +329,15 @@ func (sb *Sandbox) rebuildDNS() error {
338329
// upstream nameservers.
339330
sb.setExternalResolvers(extNameServers)
340331

341-
return rc.WriteFile(sb.config.resolvConfPath, sb.config.resolvConfHashFile, filePerm)
332+
// Write the file for the container - preserving old behaviour, not updating the
333+
// hash file (so, no further updates will be made).
334+
// TODO(robmry) - I think that's probably accidental, I can't find a reason for it,
335+
// and the old resolvconf.Build() function wrote the file but not the hash, which
336+
// is surprising. But, before fixing it, a guard/flag needs to be added to
337+
// sb.updateDNS() to make sure that when an endpoint joins a sandbox that already
338+
// has an internal resolver, the container's resolv.conf is still (re)configured
339+
// for an internal resolver.
340+
return rc.WriteFile(sb.config.resolvConfPath, "", filePerm)
342341
}
343342

344343
func createBasePath(dir string) error {

daemon/libnetwork/sandbox_dns_unix_test.go

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,12 @@ import (
1414
is "gotest.tools/v3/assert/cmp"
1515
)
1616

17-
func getResolvConf(t *testing.T, rcPath string) resolvconf.ResolvConf {
17+
func getResolvConfOptions(t *testing.T, rcPath string) []string {
1818
t.Helper()
1919
resolv, err := os.ReadFile(rcPath)
2020
assert.NilError(t, err)
2121
rc, err := resolvconf.Parse(bytes.NewBuffer(resolv), "")
2222
assert.NilError(t, err)
23-
return rc
24-
}
25-
26-
func getResolvConfOptions(t *testing.T, rcPath string) []string {
27-
rc := getResolvConf(t, rcPath)
2823
return rc.Options()
2924
}
3025

@@ -95,60 +90,3 @@ func TestDNSOptions(t *testing.T) {
9590
dnsOptionsList = getResolvConfOptions(t, sb2.config.resolvConfPath)
9691
assert.Check(t, is.DeepEqual([]string{"ndots:0"}, dnsOptionsList))
9792
}
98-
99-
func TestNonHostNetDNSRestart(t *testing.T) {
100-
c, err := New(context.Background(), config.OptionDataDir(t.TempDir()))
101-
assert.NilError(t, err)
102-
103-
// Step 1: Create initial sandbox (simulating first container start)
104-
sb, err := c.NewSandbox(context.Background(), "cnt1")
105-
assert.NilError(t, err)
106-
107-
defer func() {
108-
_ = sb.Delete(context.Background())
109-
}()
110-
111-
sb.startResolver(false)
112-
113-
err = sb.setupDNS()
114-
assert.NilError(t, err)
115-
err = sb.rebuildDNS()
116-
assert.NilError(t, err)
117-
118-
// Step 2: Simulate user manually overwriting the container's resolv.conf
119-
resolvConfPath := sb.config.resolvConfPath
120-
modifiedContent := []byte(`nameserver 1.1.1.1`)
121-
err = os.WriteFile(resolvConfPath, modifiedContent, 0644)
122-
assert.NilError(t, err)
123-
124-
// Step 3: Delete the sandbox (simulating container stop)
125-
err = sb.Delete(context.Background())
126-
assert.NilError(t, err)
127-
128-
// Step 4: Create a new sandbox (simulating container restart)
129-
sbRestart, err := c.NewSandbox(context.Background(), "cnt1",
130-
OptionResolvConfPath(resolvConfPath),
131-
)
132-
assert.NilError(t, err)
133-
defer func() {
134-
if err := sbRestart.Delete(context.Background()); err != nil {
135-
t.Error(err)
136-
}
137-
}()
138-
139-
sbRestart.startResolver(false)
140-
141-
// Step 5: Call setupDNS on restart - should preserve user modifications
142-
err = sbRestart.setupDNS()
143-
assert.NilError(t, err)
144-
145-
rc := getResolvConf(t, sbRestart.config.resolvConfPath)
146-
assert.Check(t, is.Equal("1.1.1.1", rc.NameServers()[0].String()))
147-
148-
// Step 6: Call rebuildDNS on restart - should preserve user modifications
149-
err = sbRestart.rebuildDNS()
150-
assert.NilError(t, err)
151-
152-
rc = getResolvConf(t, sbRestart.config.resolvConfPath)
153-
assert.Check(t, is.Equal("1.1.1.1", rc.NameServers()[0].String()))
154-
}

daemon/libnetwork/sandbox_linux.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -366,11 +366,6 @@ func (sb *Sandbox) populateNetworkResourcesOS(ctx context.Context, ep *Endpoint)
366366

367367
if ep.needResolver() {
368368
sb.startResolver(false)
369-
} else {
370-
// Make sure /etc/resolv.conf is set up.
371-
if err := sb.updateDNS(ep.getNetwork().enableIPv6); err != nil {
372-
return err
373-
}
374369
}
375370

376371
if i != nil && i.srcName != "" {
@@ -453,6 +448,10 @@ func (sb *Sandbox) populateNetworkResourcesOS(ctx context.Context, ep *Endpoint)
453448
}
454449

455450
sb.addHostsEntries(ctx, ep.getEtcHostsAddrs())
451+
// Make sure /etc/resolv.conf is set up.
452+
if err := sb.updateDNS(ep.getNetwork().enableIPv6); err != nil {
453+
return err
454+
}
456455

457456
// Populate load balancer only after updating all the other
458457
// information including gateway and other routes so that

integration/networking/resolvconf_test.go

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -212,41 +212,3 @@ func TestNslookupWindows(t *testing.T) {
212212
// can only be changed in daemon.json using feature flag "windows-dns-proxy".
213213
assert.Check(t, is.Contains(res.Stdout.String(), "Addresses:"))
214214
}
215-
216-
// TestResolvConfPreservedOnRestart verifies that external modifications to
217-
// /etc/resolv.conf are preserved when a non-host network container is restarted.
218-
// Regression test for https://github.com/moby/moby/issues/51490
219-
func TestResolvConfPreservedOnRestart(t *testing.T) {
220-
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "No /etc/resolv.conf on Windows")
221-
222-
ctx := setupTest(t)
223-
224-
d := daemon.New(t, daemon.WithResolvConf(network.GenResolvConf("8.8.8.8")))
225-
d.StartWithBusybox(ctx, t)
226-
defer d.Stop(t)
227-
228-
c := d.NewClientT(t)
229-
defer c.Close()
230-
231-
const ctrName = "test-resolvconf-preserved-on-restart"
232-
id := container.Run(ctx, t, c, container.WithName(ctrName))
233-
defer c.ContainerRemove(ctx, id, client.ContainerRemoveOptions{Force: true})
234-
235-
appendContent := `# hello`
236-
res, err := container.Exec(ctx, c, ctrName, []string{
237-
"sh", "-c",
238-
"echo '" + appendContent + "' >> /etc/resolv.conf",
239-
})
240-
assert.NilError(t, err)
241-
assert.Check(t, is.Equal(res.ExitCode, 0))
242-
243-
// Restart the container.
244-
_, err = c.ContainerRestart(ctx, ctrName, client.ContainerRestartOptions{})
245-
assert.Assert(t, is.Nil(err))
246-
247-
// Verify the modification was preserved
248-
res, err = container.Exec(ctx, c, ctrName, []string{"tail", "-n", "1", "/etc/resolv.conf"})
249-
assert.NilError(t, err)
250-
assert.Check(t, is.Equal(res.ExitCode, 0))
251-
assert.Check(t, is.Contains(res.Stdout(), appendContent))
252-
}

0 commit comments

Comments
 (0)