Repository: moby/moby
File: integration/network/dns_test.go (Go)

Code before:
				container.WithDNS(tc.extServers),
				container.WithCmd("nslookup", "docker.com"),
			)
			defer c.ContainerRemove(ctx, res.ContainerID, containertypes.RemoveOptions{Force: true})

			assert.Check(t, is.Equal(res.ExitCode, tc.expExitCode))
			assert.Check(t, is.Contains(res.Stdout.String(), tc.expStdout))
		})
	}
}

// TestExtDNSInIPv6OnlyNw checks that an IPv6-only bridge network has external
// DNS access.
func TestExtDNSInIPv6OnlyNw(t *testing.T) {
	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "No IPv6 Windows")
	skip.If(t, testEnv.IsRootless, "Can't use resolver on host in rootless mode")
	ctx := setupTest(t)

	// Start a DNS server on the loopback interface.
	network.StartDaftDNS(t, "127.0.0.1")

	// Set up a temp resolv.conf pointing at that DNS server, and a daemon using it.
	d := daemon.New(t,
		daemon.WithResolvConf(network.WriteTempResolvConf(t, "127.0.0.1")),
		daemon.WithExperimental(),
	)
	d.StartWithBusybox(ctx, t)
	defer d.Stop(t)

	c := d.NewClientT(t)
	defer c.Close()

	netName := "v6only"
	network.CreateNoError(ctx, t, c, netName,
		network.WithDriver("bridge"),
		network.WithIPv4(false),
		network.WithIPv6(),
	)
	defer network.RemoveNoError(ctx, t, c, netName)

	ctrId := container.Run(ctx, t, c, container.WithNetworkMode(netName))
	defer c.ContainerRemove(ctx, ctrId, containertypes.RemoveOptions{Force: true})

	res, err := container.Exec(ctx, c, ctrId, []string{"nslookup", "test.example"})
	assert.NilError(t, err)
	assert.Check(t, is.Equal(res.ExitCode, 0))
	assert.Check(t, is.Contains(res.Stdout(), network.DNSRespAddr))
}


Review comment (security):
Heh,  this now makes it really tempting to combine those (not sure if we should), as it looks like `WriteTempResolvConf` is always used in combination with `daemon.WithResolvConf`

```go
daemon.WithResolver(t, "127.0.0.1")
```

There is some special handling in that utility for permissions; https://github.com/moby/moby/blob/f95e4b3d22260eb3322b4be13d391b8db2d4199f/integration/internal/network/dns.go#L20-L24


I wonder if (as we're passing the `Daemon` struct to these options) if putting it somewhere inside the daemon's storage location would work for that; in that case, we'd keep all things related to that daemon instance together;
https://github.com/moby/moby/blob/f95e4b3d22260eb3322b4be13d391b8db2d4199f/testutil/daemon/daemon.go#L200-L204

https://github.com/moby/moby/blob/f95e4b3d22260eb3322b4be13d391b8db2d4199f/testutil/daemon/daemon.go#L106-L122



Code after:
				container.WithDNS(tc.extServers),
				container.WithCmd("nslookup", "docker.com"),
			)
			defer c.ContainerRemove(ctx, res.ContainerID, containertypes.RemoveOptions{Force: true})

			assert.Check(t, is.Equal(res.ExitCode, tc.expExitCode))
			assert.Check(t, is.Contains(res.Stdout.String(), tc.expStdout))
		})
	}
}

// TestExtDNSInIPv6OnlyNw checks that an IPv6-only bridge network has external
// DNS access.
func TestExtDNSInIPv6OnlyNw(t *testing.T) {
	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "No IPv6 Windows")
	skip.If(t, testEnv.IsRootless, "Can't use resolver on host in rootless mode")
	ctx := setupTest(t)

	// Start a DNS server on the loopback interface.
	network.StartDaftDNS(t, "127.0.0.1")

	// Set up a temp resolv.conf pointing at that DNS server, and a daemon using it.
	d := daemon.New(t,
		daemon.WithResolvConf(network.GenResolvConf("127.0.0.1")),
		daemon.WithExperimental(),
	)
	d.StartWithBusybox(ctx, t)
	defer d.Stop(t)

	c := d.NewClientT(t)
	defer c.Close()

	netName := "v6only"
	network.CreateNoError(ctx, t, c, netName,
		network.WithDriver("bridge"),
		network.WithIPv4(false),
		network.WithIPv6(),
	)
	defer network.RemoveNoError(ctx, t, c, netName)

	ctrId := container.Run(ctx, t, c, container.WithNetworkMode(netName))
	defer c.ContainerRemove(ctx, ctrId, containertypes.RemoveOptions{Force: true})

	res, err := container.Exec(ctx, c, ctrId, []string{"nslookup", "test.example"})
	assert.NilError(t, err)
	assert.Check(t, is.Equal(res.ExitCode, 0))
	assert.Check(t, is.Contains(res.Stdout(), network.DNSRespAddr))
}