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