github.com/uriddle/docker@v0.0.0-20210926094723-4072e6aeb013/integration-cli/docker_cli_links_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "regexp" 6 "strings" 7 8 "github.com/docker/docker/pkg/integration/checker" 9 "github.com/docker/docker/runconfig" 10 "github.com/go-check/check" 11 ) 12 13 func (s *DockerSuite) TestLinksPingUnlinkedContainers(c *check.C) { 14 testRequires(c, DaemonIsLinux) 15 _, exitCode, err := dockerCmdWithError("run", "--rm", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1") 16 17 // run ping failed with error 18 c.Assert(exitCode, checker.Equals, 1, check.Commentf("error: %v", err)) 19 } 20 21 // Test for appropriate error when calling --link with an invalid target container 22 func (s *DockerSuite) TestLinksInvalidContainerTarget(c *check.C) { 23 testRequires(c, DaemonIsLinux) 24 out, _, err := dockerCmdWithError("run", "--link", "bogus:alias", "busybox", "true") 25 26 // an invalid container target should produce an error 27 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 28 // an invalid container target should produce an error 29 c.Assert(out, checker.Contains, "Could not get container") 30 } 31 32 func (s *DockerSuite) TestLinksPingLinkedContainers(c *check.C) { 33 testRequires(c, DaemonIsLinux) 34 dockerCmd(c, "run", "-d", "--name", "container1", "--hostname", "fred", "busybox", "top") 35 dockerCmd(c, "run", "-d", "--name", "container2", "--hostname", "wilma", "busybox", "top") 36 37 runArgs := []string{"run", "--rm", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sh", "-c"} 38 pingCmd := "ping -c 1 %s -W 1 && ping -c 1 %s -W 1" 39 40 // test ping by alias, ping by name, and ping by hostname 41 // 1. Ping by alias 42 dockerCmd(c, append(runArgs, fmt.Sprintf(pingCmd, "alias1", "alias2"))...) 43 // 2. Ping by container name 44 dockerCmd(c, append(runArgs, fmt.Sprintf(pingCmd, "container1", "container2"))...) 45 // 3. Ping by hostname 46 dockerCmd(c, append(runArgs, fmt.Sprintf(pingCmd, "fred", "wilma"))...) 47 48 } 49 50 func (s *DockerSuite) TestLinksPingLinkedContainersAfterRename(c *check.C) { 51 testRequires(c, DaemonIsLinux) 52 out, _ := dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top") 53 idA := strings.TrimSpace(out) 54 out, _ = dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top") 55 idB := strings.TrimSpace(out) 56 dockerCmd(c, "rename", "container1", "container_new") 57 dockerCmd(c, "run", "--rm", "--link", "container_new:alias1", "--link", "container2:alias2", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1") 58 dockerCmd(c, "kill", idA) 59 dockerCmd(c, "kill", idB) 60 61 } 62 63 func (s *DockerSuite) TestLinksInspectLinksStarted(c *check.C) { 64 testRequires(c, DaemonIsLinux) 65 var ( 66 expected = map[string]struct{}{"/container1:/testinspectlink/alias1": {}, "/container2:/testinspectlink/alias2": {}} 67 result []string 68 ) 69 dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top") 70 dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top") 71 dockerCmd(c, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "top") 72 links, err := inspectFieldJSON("testinspectlink", "HostConfig.Links") 73 c.Assert(err, checker.IsNil) 74 75 err = unmarshalJSON([]byte(links), &result) 76 c.Assert(err, checker.IsNil) 77 78 output := convertSliceOfStringsToMap(result) 79 80 c.Assert(output, checker.DeepEquals, expected) 81 } 82 83 func (s *DockerSuite) TestLinksInspectLinksStopped(c *check.C) { 84 testRequires(c, DaemonIsLinux) 85 var ( 86 expected = map[string]struct{}{"/container1:/testinspectlink/alias1": {}, "/container2:/testinspectlink/alias2": {}} 87 result []string 88 ) 89 dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top") 90 dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top") 91 dockerCmd(c, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "true") 92 links, err := inspectFieldJSON("testinspectlink", "HostConfig.Links") 93 c.Assert(err, checker.IsNil) 94 95 err = unmarshalJSON([]byte(links), &result) 96 c.Assert(err, checker.IsNil) 97 98 output := convertSliceOfStringsToMap(result) 99 100 c.Assert(output, checker.DeepEquals, expected) 101 } 102 103 func (s *DockerSuite) TestLinksNotStartedParentNotFail(c *check.C) { 104 testRequires(c, DaemonIsLinux) 105 dockerCmd(c, "create", "--name=first", "busybox", "top") 106 dockerCmd(c, "create", "--name=second", "--link=first:first", "busybox", "top") 107 dockerCmd(c, "start", "first") 108 109 } 110 111 func (s *DockerSuite) TestLinksHostsFilesInject(c *check.C) { 112 testRequires(c, DaemonIsLinux) 113 testRequires(c, SameHostDaemon, ExecSupport) 114 115 out, _ := dockerCmd(c, "run", "-itd", "--name", "one", "busybox", "top") 116 idOne := strings.TrimSpace(out) 117 118 out, _ = dockerCmd(c, "run", "-itd", "--name", "two", "--link", "one:onetwo", "busybox", "top") 119 idTwo := strings.TrimSpace(out) 120 121 c.Assert(waitRun(idTwo), checker.IsNil) 122 123 contentOne, err := readContainerFileWithExec(idOne, "/etc/hosts") 124 c.Assert(err, checker.IsNil, check.Commentf("contentOne: %s", string(contentOne))) 125 126 contentTwo, err := readContainerFileWithExec(idTwo, "/etc/hosts") 127 c.Assert(err, checker.IsNil, check.Commentf("contentTwo: %s", string(contentTwo))) 128 // Host is not present in updated hosts file 129 c.Assert(string(contentTwo), checker.Contains, "onetwo") 130 } 131 132 func (s *DockerSuite) TestLinksUpdateOnRestart(c *check.C) { 133 testRequires(c, DaemonIsLinux) 134 testRequires(c, SameHostDaemon, ExecSupport) 135 dockerCmd(c, "run", "-d", "--name", "one", "busybox", "top") 136 out, _ := dockerCmd(c, "run", "-d", "--name", "two", "--link", "one:onetwo", "--link", "one:one", "busybox", "top") 137 id := strings.TrimSpace(string(out)) 138 139 realIP, err := inspectField("one", "NetworkSettings.Networks.bridge.IPAddress") 140 if err != nil { 141 c.Fatal(err) 142 } 143 c.Assert(err, checker.IsNil) 144 content, err := readContainerFileWithExec(id, "/etc/hosts") 145 c.Assert(err, checker.IsNil) 146 147 getIP := func(hosts []byte, hostname string) string { 148 re := regexp.MustCompile(fmt.Sprintf(`(\S*)\t%s`, regexp.QuoteMeta(hostname))) 149 matches := re.FindSubmatch(hosts) 150 c.Assert(matches, checker.NotNil, check.Commentf("Hostname %s have no matches in hosts", hostname)) 151 return string(matches[1]) 152 } 153 ip := getIP(content, "one") 154 c.Assert(ip, checker.Equals, realIP) 155 156 ip = getIP(content, "onetwo") 157 c.Assert(ip, checker.Equals, realIP) 158 159 dockerCmd(c, "restart", "one") 160 realIP, err = inspectField("one", "NetworkSettings.Networks.bridge.IPAddress") 161 c.Assert(err, checker.IsNil) 162 163 content, err = readContainerFileWithExec(id, "/etc/hosts") 164 c.Assert(err, checker.IsNil, check.Commentf("content: %s", string(content))) 165 ip = getIP(content, "one") 166 c.Assert(ip, checker.Equals, realIP) 167 168 ip = getIP(content, "onetwo") 169 c.Assert(ip, checker.Equals, realIP) 170 } 171 172 func (s *DockerSuite) TestLinksEnvs(c *check.C) { 173 testRequires(c, DaemonIsLinux) 174 dockerCmd(c, "run", "-d", "-e", "e1=", "-e", "e2=v2", "-e", "e3=v3=v3", "--name=first", "busybox", "top") 175 out, _ := dockerCmd(c, "run", "--name=second", "--link=first:first", "busybox", "env") 176 c.Assert(out, checker.Contains, "FIRST_ENV_e1=\n") 177 c.Assert(out, checker.Contains, "FIRST_ENV_e2=v2") 178 c.Assert(out, checker.Contains, "FIRST_ENV_e3=v3=v3") 179 } 180 181 func (s *DockerSuite) TestLinkShortDefinition(c *check.C) { 182 testRequires(c, DaemonIsLinux) 183 out, _ := dockerCmd(c, "run", "-d", "--name", "shortlinkdef", "busybox", "top") 184 185 cid := strings.TrimSpace(out) 186 c.Assert(waitRun(cid), checker.IsNil) 187 188 out, _ = dockerCmd(c, "run", "-d", "--name", "link2", "--link", "shortlinkdef", "busybox", "top") 189 190 cid2 := strings.TrimSpace(out) 191 c.Assert(waitRun(cid2), checker.IsNil) 192 193 links, err := inspectFieldJSON(cid2, "HostConfig.Links") 194 c.Assert(err, checker.IsNil) 195 c.Assert(links, checker.Equals, "[\"/shortlinkdef:/link2/shortlinkdef\"]") 196 } 197 198 func (s *DockerSuite) TestLinksNetworkHostContainer(c *check.C) { 199 testRequires(c, DaemonIsLinux, NotUserNamespace) 200 dockerCmd(c, "run", "-d", "--net", "host", "--name", "host_container", "busybox", "top") 201 out, _, err := dockerCmdWithError("run", "--name", "should_fail", "--link", "host_container:tester", "busybox", "true") 202 203 // Running container linking to a container with --net host should have failed 204 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 205 // Running container linking to a container with --net host should have failed 206 c.Assert(out, checker.Contains, runconfig.ErrConflictHostNetworkAndLinks.Error()) 207 } 208 209 func (s *DockerSuite) TestLinksEtcHostsRegularFile(c *check.C) { 210 testRequires(c, DaemonIsLinux, NotUserNamespace) 211 out, _ := dockerCmd(c, "run", "--net=host", "busybox", "ls", "-la", "/etc/hosts") 212 // /etc/hosts should be a regular file 213 c.Assert(out, checker.Matches, "^-.+\n") 214 } 215 216 func (s *DockerSuite) TestLinksMultipleWithSameName(c *check.C) { 217 dockerCmd(c, "run", "-d", "--name=upstream-a", "busybox", "top") 218 dockerCmd(c, "run", "-d", "--name=upstream-b", "busybox", "top") 219 dockerCmd(c, "run", "--link", "upstream-a:upstream", "--link", "upstream-b:upstream", "busybox", "sh", "-c", "ping -c 1 upstream") 220 }