1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
package networking
import (
"context"
"testing"
"time"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/integration/internal/container"
"github.com/docker/docker/testutil"
"github.com/docker/docker/testutil/daemon"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/skip"
)
// Check that the '/etc/hosts' file in a container is created according to
// whether the container supports IPv6.
// Regression test for https://github.com/moby/moby/issues/35954
func TestEtcHostsIpv6(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType == "windows")
ctx := setupTest(t)
d := daemon.New(t)
d.StartWithBusybox(ctx, t,
"--ipv6",
"--fixed-cidr-v6=fdc8:ffe2:d8d7:1234::/64")
defer d.Stop(t)
c := d.NewClientT(t)
defer c.Close()
testcases := []struct {
name string
sysctls map[string]string
expIPv6Enabled bool
expEtcHosts string
}{
{
// Create a container with no overrides, on the IPv6-enabled default bridge.
// Expect the container to have a working '::1' address, on the assumption
// the test host's kernel supports IPv6 - and for its '/etc/hosts' file to
// include IPv6 addresses.
name: "IPv6 enabled",
expIPv6Enabled: true,
expEtcHosts: `127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
`,
},
{
// Create a container in the same network, with IPv6 disabled. Expect '::1'
// not to be pingable, and no IPv6 addresses in its '/etc/hosts'.
name: "IPv6 disabled",
sysctls: map[string]string{"net.ipv6.conf.all.disable_ipv6": "1"},
expIPv6Enabled: false,
expEtcHosts: "127.0.0.1\tlocalhost\n",
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
ctx := testutil.StartSpan(ctx, t)
ctrId := container.Run(ctx, t, c,
container.WithName("etchosts_"+sanitizeCtrName(t.Name())),
container.WithImage("busybox:latest"),
container.WithCmd("top"),
container.WithSysctls(tc.sysctls),
)
defer func() {
c.ContainerRemove(ctx, ctrId, containertypes.RemoveOptions{Force: true})
}()
runCmd := func(ctrId string, cmd []string, expExitCode int) string {
t.Helper()
execCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
res, err := container.Exec(execCtx, c, ctrId, cmd)
assert.Check(t, is.Nil(err))
assert.Check(t, is.Equal(res.ExitCode, expExitCode))
return res.Stdout()
}
// Check that IPv6 is/isn't enabled, as expected.
var expPingExitStatus int
if !tc.expIPv6Enabled {
expPingExitStatus = 1
}
runCmd(ctrId, []string{"ping", "-6", "-c1", "-W3", "::1"}, expPingExitStatus)
// Check the contents of /etc/hosts.
stdout := runCmd(ctrId, []string{"cat", "/etc/hosts"}, 0)
// Append the container's own addresses/name to the expected hosts file content.
inspect := container.Inspect(ctx, t, c, ctrId)
exp := tc.expEtcHosts + inspect.NetworkSettings.IPAddress + "\t" + inspect.Config.Hostname + "\n"
if tc.expIPv6Enabled {
exp += inspect.NetworkSettings.GlobalIPv6Address + "\t" + inspect.Config.Hostname + "\n"
}
assert.Check(t, is.Equal(stdout, exp))
})
}
}
|