github.com/containers/podman/v5@v5.1.0-rc1/test/e2e/run_networking_test.go (about) 1 package integration 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net" 7 "os" 8 "strconv" 9 "strings" 10 "syscall" 11 12 "github.com/containernetworking/plugins/pkg/ns" 13 "github.com/containers/podman/v5/pkg/domain/entities" 14 . "github.com/containers/podman/v5/test/utils" 15 "github.com/containers/storage/pkg/stringid" 16 . "github.com/onsi/ginkgo/v2" 17 . "github.com/onsi/gomega" 18 . "github.com/onsi/gomega/gexec" 19 "github.com/vishvananda/netlink" 20 ) 21 22 var _ = Describe("Podman run networking", func() { 23 24 hostname, _ := os.Hostname() 25 26 It("podman verify network scoped DNS server and also verify updating network dns server", func() { 27 // Following test is only functional with netavark and aardvark 28 SkipIfCNI(podmanTest) 29 net := createNetworkName("IntTest") 30 session := podmanTest.Podman([]string{"network", "create", net, "--dns", "1.1.1.1"}) 31 session.WaitWithDefaultTimeout() 32 defer podmanTest.removeNetwork(net) 33 Expect(session).Should(ExitCleanly()) 34 35 session = podmanTest.Podman([]string{"network", "inspect", net}) 36 session.WaitWithDefaultTimeout() 37 defer podmanTest.removeNetwork(net) 38 Expect(session).Should(ExitCleanly()) 39 var results []entities.NetworkInspectReport 40 err := json.Unmarshal([]byte(session.OutputToString()), &results) 41 Expect(err).ToNot(HaveOccurred()) 42 Expect(results).To(HaveLen(1)) 43 result := results[0] 44 Expect(result.Subnets).To(HaveLen(1)) 45 aardvarkDNSGateway := result.Subnets[0].Gateway.String() 46 Expect(result.NetworkDNSServers).To(Equal([]string{"1.1.1.1"})) 47 48 session = podmanTest.Podman([]string{"run", "-d", "--name", "con1", "--network", net, "busybox", "top"}) 49 session.WaitWithDefaultTimeout() 50 Expect(session).Should(ExitCleanly()) 51 52 session = podmanTest.Podman([]string{"exec", "con1", "nslookup", "google.com", aardvarkDNSGateway}) 53 session.WaitWithDefaultTimeout() 54 Expect(session).Should(ExitCleanly()) 55 Expect(session.OutputToString()).To(ContainSubstring("Non-authoritative answer: Name: google.com Address:")) 56 57 // Update to a bad DNS Server 58 session = podmanTest.Podman([]string{"network", "update", net, "--dns-add", "127.0.0.255"}) 59 session.WaitWithDefaultTimeout() 60 Expect(session).Should(ExitCleanly()) 61 62 // Remove good DNS server 63 session = podmanTest.Podman([]string{"network", "update", net, "--dns-drop=1.1.1.1"}) 64 session.WaitWithDefaultTimeout() 65 Expect(session).Should(ExitCleanly()) 66 67 session = podmanTest.Podman([]string{"exec", "con1", "nslookup", "google.com", aardvarkDNSGateway}) 68 session.WaitWithDefaultTimeout() 69 Expect(session).Should(Exit(1)) 70 Expect(session.OutputToString()).To(ContainSubstring(";; connection timed out; no servers could be reached")) 71 }) 72 73 It("podman network dns multiple servers", func() { 74 // Following test is only functional with netavark and aardvark 75 SkipIfCNI(podmanTest) 76 net := createNetworkName("IntTest") 77 session := podmanTest.Podman([]string{"network", "create", net, "--dns", "1.1.1.1,8.8.8.8", "--dns", "8.4.4.8"}) 78 session.WaitWithDefaultTimeout() 79 defer podmanTest.removeNetwork(net) 80 Expect(session).Should(ExitCleanly()) 81 82 session = podmanTest.Podman([]string{"network", "inspect", net}) 83 session.WaitWithDefaultTimeout() 84 defer podmanTest.removeNetwork(net) 85 Expect(session).Should(ExitCleanly()) 86 var results []entities.NetworkInspectReport 87 err := json.Unmarshal([]byte(session.OutputToString()), &results) 88 Expect(err).ToNot(HaveOccurred()) 89 Expect(results).To(HaveLen(1)) 90 result := results[0] 91 Expect(result.Subnets).To(HaveLen(1)) 92 aardvarkDNSGateway := result.Subnets[0].Gateway.String() 93 Expect(result.NetworkDNSServers).To(Equal([]string{"1.1.1.1", "8.8.8.8", "8.4.4.8"})) 94 95 session = podmanTest.Podman([]string{"run", "-d", "--name", "con1", "--network", net, "busybox", "top"}) 96 session.WaitWithDefaultTimeout() 97 Expect(session).Should(ExitCleanly()) 98 99 session = podmanTest.Podman([]string{"exec", "con1", "nslookup", "google.com", aardvarkDNSGateway}) 100 session.WaitWithDefaultTimeout() 101 Expect(session).Should(ExitCleanly()) 102 Expect(session.OutputToString()).To(ContainSubstring("Non-authoritative answer: Name: google.com Address:")) 103 104 // Update DNS server 105 session = podmanTest.Podman([]string{"network", "update", net, "--dns-drop=1.1.1.1,8.8.8.8", 106 "--dns-drop", "8.4.4.8", "--dns-add", "127.0.0.253,127.0.0.254", "--dns-add", "127.0.0.255"}) 107 session.WaitWithDefaultTimeout() 108 Expect(session).Should(ExitCleanly()) 109 110 session = podmanTest.Podman([]string{"network", "inspect", net}) 111 session.WaitWithDefaultTimeout() 112 defer podmanTest.removeNetwork(net) 113 Expect(session).Should(ExitCleanly()) 114 err = json.Unmarshal([]byte(session.OutputToString()), &results) 115 Expect(err).ToNot(HaveOccurred()) 116 Expect(results).To(HaveLen(1)) 117 Expect(results[0].NetworkDNSServers).To(Equal([]string{"127.0.0.253", "127.0.0.254", "127.0.0.255"})) 118 119 session = podmanTest.Podman([]string{"exec", "con1", "nslookup", "google.com", aardvarkDNSGateway}) 120 session.WaitWithDefaultTimeout() 121 Expect(session).Should(Exit(1)) 122 Expect(session.OutputToString()).To(ContainSubstring(";; connection timed out; no servers could be reached")) 123 }) 124 125 It("podman run network connection with default bridge", func() { 126 session := podmanTest.RunContainerWithNetworkTest("") 127 session.WaitWithDefaultTimeout() 128 Expect(session).Should(ExitCleanly()) 129 }) 130 131 It("podman run network connection with host", func() { 132 session := podmanTest.RunContainerWithNetworkTest("host") 133 session.WaitWithDefaultTimeout() 134 Expect(session).Should(ExitCleanly()) 135 }) 136 137 It("podman run network connection with default", func() { 138 session := podmanTest.RunContainerWithNetworkTest("default") 139 session.WaitWithDefaultTimeout() 140 Expect(session).Should(ExitCleanly()) 141 }) 142 143 It("podman run network connection with none", func() { 144 session := podmanTest.RunContainerWithNetworkTest("none") 145 session.WaitWithDefaultTimeout() 146 if _, found := os.LookupEnv("http_proxy"); found { 147 Expect(session).Should(ExitWithError(5, "Could not resolve proxy:")) 148 } else { 149 Expect(session).Should(ExitWithError(6, "Could not resolve host: www.redhat.com")) 150 } 151 }) 152 153 It("podman run network connection with private", func() { 154 session := podmanTest.RunContainerWithNetworkTest("private") 155 session.WaitWithDefaultTimeout() 156 Expect(session).Should(ExitCleanly()) 157 }) 158 159 It("podman verify resolv.conf with --dns + --network", func() { 160 // Following test is only functional with netavark and aardvark 161 // since new behaviour depends upon output from of statusBlock 162 SkipIfCNI(podmanTest) 163 net := createNetworkName("IntTest") 164 session := podmanTest.Podman([]string{"network", "create", net}) 165 session.WaitWithDefaultTimeout() 166 defer podmanTest.removeNetwork(net) 167 Expect(session).Should(ExitCleanly()) 168 169 session = podmanTest.Podman([]string{"run", "--name", "con1", "--dns", "1.1.1.1", "--network", net, ALPINE, "cat", "/etc/resolv.conf"}) 170 session.WaitWithDefaultTimeout() 171 Expect(session).Should(ExitCleanly()) 172 // Must not contain custom dns server in containers 173 // `/etc/resolv.conf` since custom dns-server is 174 // already expected to be present and processed by 175 // Podman's DNS resolver i.e ( aarvark-dns or dnsname ). 176 Expect(session.OutputToString()).ToNot(ContainSubstring("nameserver 1.1.1.1")) 177 // But /etc/resolve.conf must contain other nameserver 178 // i.e dns server configured for network. 179 Expect(session.OutputToString()).To(ContainSubstring("nameserver")) 180 181 session = podmanTest.Podman([]string{"run", "--name", "con2", "--dns", "1.1.1.1", ALPINE, "cat", "/etc/resolv.conf"}) 182 session.WaitWithDefaultTimeout() 183 Expect(session).Should(ExitCleanly()) 184 // All the networks being used by following container 185 // don't have dns_enabled in such scenario `/etc/resolv.conf` 186 // must contain nameserver which were specified via `--dns`. 187 Expect(session.OutputToString()).To(ContainSubstring("nameserver 1.1.1.1")) 188 }) 189 190 It("podman run network expose port 222", func() { 191 SkipIfRootless("iptables is not supported for rootless users") 192 session := podmanTest.Podman([]string{"run", "-dt", "--expose", "222-223", "-P", ALPINE, "/bin/sh"}) 193 session.WaitWithDefaultTimeout() 194 Expect(session).Should(ExitCleanly()) 195 results := SystemExec("iptables", []string{"-t", "nat", "-nvL"}) 196 Expect(results).Should(ExitCleanly()) 197 Expect(results.OutputToString()).To(ContainSubstring("222")) 198 Expect(results.OutputToString()).To(ContainSubstring("223")) 199 }) 200 201 It("podman run -p 80", func() { 202 name := "testctr" 203 session := podmanTest.Podman([]string{"create", "-t", "-p", "80", "--name", name, ALPINE, "/bin/sh"}) 204 session.WaitWithDefaultTimeout() 205 inspectOut := podmanTest.InspectContainer(name) 206 Expect(inspectOut).To(HaveLen(1)) 207 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 208 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"]).To(HaveLen(1)) 209 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0].HostPort).To(Not(Equal("80"))) 210 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 211 }) 212 213 It("podman run -p 80-82 -p 8090:8090", func() { 214 name := "testctr" 215 session := podmanTest.Podman([]string{"create", "-t", "-p", "80-82", "-p", "8090:8090", "--name", name, ALPINE, "/bin/sh"}) 216 session.WaitWithDefaultTimeout() 217 inspectOut := podmanTest.InspectContainer(name) 218 Expect(inspectOut).To(HaveLen(1)) 219 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(4)) 220 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"]).To(HaveLen(1)) 221 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0].HostPort).To(Not(Equal("80"))) 222 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 223 Expect(inspectOut[0].NetworkSettings.Ports["81/tcp"]).To(HaveLen(1)) 224 Expect(inspectOut[0].NetworkSettings.Ports["81/tcp"][0].HostPort).To(Not(Equal("81"))) 225 Expect(inspectOut[0].NetworkSettings.Ports["81/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 226 Expect(inspectOut[0].NetworkSettings.Ports["82/tcp"]).To(HaveLen(1)) 227 Expect(inspectOut[0].NetworkSettings.Ports["82/tcp"][0].HostPort).To(Not(Equal("82"))) 228 Expect(inspectOut[0].NetworkSettings.Ports["82/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 229 Expect(inspectOut[0].NetworkSettings.Ports["8090/tcp"]).To(HaveLen(1)) 230 Expect(inspectOut[0].NetworkSettings.Ports["8090/tcp"][0]).To(HaveField("HostPort", "8090")) 231 Expect(inspectOut[0].NetworkSettings.Ports["8090/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 232 }) 233 234 It("podman run -p 80-81 -p 8180-8181", func() { 235 name := "testctr" 236 session := podmanTest.Podman([]string{"create", "-t", "-p", "80-81", "-p", "8180-8181", "--name", name, ALPINE, "/bin/sh"}) 237 session.WaitWithDefaultTimeout() 238 inspectOut := podmanTest.InspectContainer(name) 239 Expect(inspectOut).To(HaveLen(1)) 240 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(4)) 241 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"]).To(HaveLen(1)) 242 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0].HostPort).To(Not(Equal("80"))) 243 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 244 Expect(inspectOut[0].NetworkSettings.Ports["81/tcp"]).To(HaveLen(1)) 245 Expect(inspectOut[0].NetworkSettings.Ports["81/tcp"][0].HostPort).To(Not(Equal("81"))) 246 Expect(inspectOut[0].NetworkSettings.Ports["81/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 247 Expect(inspectOut[0].NetworkSettings.Ports["8180/tcp"]).To(HaveLen(1)) 248 Expect(inspectOut[0].NetworkSettings.Ports["8180/tcp"][0].HostPort).To(Not(Equal("8180"))) 249 Expect(inspectOut[0].NetworkSettings.Ports["8180/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 250 Expect(inspectOut[0].NetworkSettings.Ports["8181/tcp"]).To(HaveLen(1)) 251 Expect(inspectOut[0].NetworkSettings.Ports["8181/tcp"][0].HostPort).To(Not(Equal("8181"))) 252 Expect(inspectOut[0].NetworkSettings.Ports["8181/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 253 }) 254 255 It("podman run -p 80 -p 8280-8282:8280-8282", func() { 256 name := "testctr" 257 session := podmanTest.Podman([]string{"create", "-t", "-p", "80", "-p", "8280-8282:8280-8282", "--name", name, ALPINE, "/bin/sh"}) 258 session.WaitWithDefaultTimeout() 259 inspectOut := podmanTest.InspectContainer(name) 260 Expect(inspectOut).To(HaveLen(1)) 261 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(4)) 262 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"]).To(HaveLen(1)) 263 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0].HostPort).To(Not(Equal("80"))) 264 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 265 Expect(inspectOut[0].NetworkSettings.Ports["8280/tcp"]).To(HaveLen(1)) 266 Expect(inspectOut[0].NetworkSettings.Ports["8280/tcp"][0]).To(HaveField("HostPort", "8280")) 267 Expect(inspectOut[0].NetworkSettings.Ports["8280/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 268 Expect(inspectOut[0].NetworkSettings.Ports["8281/tcp"]).To(HaveLen(1)) 269 Expect(inspectOut[0].NetworkSettings.Ports["8281/tcp"][0]).To(HaveField("HostPort", "8281")) 270 Expect(inspectOut[0].NetworkSettings.Ports["8281/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 271 Expect(inspectOut[0].NetworkSettings.Ports["8282/tcp"]).To(HaveLen(1)) 272 Expect(inspectOut[0].NetworkSettings.Ports["8282/tcp"][0]).To(HaveField("HostPort", "8282")) 273 Expect(inspectOut[0].NetworkSettings.Ports["8282/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 274 }) 275 276 It("podman run -p 8380:80", func() { 277 name := "testctr" 278 session := podmanTest.Podman([]string{"create", "-t", "-p", "8380:80", "--name", name, ALPINE, "/bin/sh"}) 279 session.WaitWithDefaultTimeout() 280 inspectOut := podmanTest.InspectContainer(name) 281 Expect(inspectOut).To(HaveLen(1)) 282 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 283 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"]).To(HaveLen(1)) 284 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostPort", "8380")) 285 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 286 }) 287 288 It("podman run -p 8480:80/TCP", func() { 289 name := "testctr" 290 // "TCP" in upper characters 291 session := podmanTest.Podman([]string{"create", "-t", "-p", "8480:80/TCP", "--name", name, ALPINE, "/bin/sh"}) 292 session.WaitWithDefaultTimeout() 293 inspectOut := podmanTest.InspectContainer(name) 294 Expect(inspectOut).To(HaveLen(1)) 295 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 296 // "tcp" in lower characters 297 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"]).To(HaveLen(1)) 298 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostPort", "8480")) 299 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 300 }) 301 302 It("podman run -p 80/udp", func() { 303 name := "testctr" 304 session := podmanTest.Podman([]string{"create", "-t", "-p", "80/udp", "--name", name, ALPINE, "/bin/sh"}) 305 session.WaitWithDefaultTimeout() 306 inspectOut := podmanTest.InspectContainer(name) 307 Expect(inspectOut).To(HaveLen(1)) 308 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 309 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"]).To(HaveLen(1)) 310 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"][0].HostPort).To(Not(Equal("80"))) 311 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"][0]).To(HaveField("HostIP", "0.0.0.0")) 312 }) 313 314 It("podman run -p 127.0.0.1:8580:80", func() { 315 name := "testctr" 316 session := podmanTest.Podman([]string{"create", "-t", "-p", "127.0.0.1:8580:80", "--name", name, ALPINE, "/bin/sh"}) 317 session.WaitWithDefaultTimeout() 318 inspectOut := podmanTest.InspectContainer(name) 319 Expect(inspectOut).To(HaveLen(1)) 320 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 321 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"]).To(HaveLen(1)) 322 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostPort", "8580")) 323 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostIP", "127.0.0.1")) 324 }) 325 326 It("podman run -p 127.0.0.1:8680:80/udp", func() { 327 name := "testctr" 328 session := podmanTest.Podman([]string{"create", "-t", "-p", "127.0.0.1:8680:80/udp", "--name", name, ALPINE, "/bin/sh"}) 329 session.WaitWithDefaultTimeout() 330 inspectOut := podmanTest.InspectContainer(name) 331 Expect(inspectOut).To(HaveLen(1)) 332 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 333 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"]).To(HaveLen(1)) 334 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"][0]).To(HaveField("HostPort", "8680")) 335 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"][0]).To(HaveField("HostIP", "127.0.0.1")) 336 }) 337 338 It("podman run -p [::1]:8780:80/udp", func() { 339 name := "testctr" 340 session := podmanTest.Podman([]string{"create", "-t", "-p", "[::1]:8780:80/udp", "--name", name, ALPINE, "/bin/sh"}) 341 session.WaitWithDefaultTimeout() 342 inspectOut := podmanTest.InspectContainer(name) 343 Expect(inspectOut).To(HaveLen(1)) 344 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 345 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"]).To(HaveLen(1)) 346 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"][0]).To(HaveField("HostPort", "8780")) 347 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"][0]).To(HaveField("HostIP", "::1")) 348 }) 349 350 It("podman run -p [::1]:8880:80/tcp", func() { 351 name := "testctr" 352 session := podmanTest.Podman([]string{"create", "-t", "-p", "[::1]:8880:80/tcp", "--name", name, ALPINE, "/bin/sh"}) 353 session.WaitWithDefaultTimeout() 354 inspectOut := podmanTest.InspectContainer(name) 355 Expect(inspectOut).To(HaveLen(1)) 356 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 357 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"]).To(HaveLen(1)) 358 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostPort", "8880")) 359 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostIP", "::1")) 360 }) 361 362 It("podman run --expose 80 -P", func() { 363 name := "testctr" 364 session := podmanTest.Podman([]string{"create", "-t", "--expose", "80", "-P", "--name", name, ALPINE, "/bin/sh"}) 365 session.WaitWithDefaultTimeout() 366 inspectOut := podmanTest.InspectContainer(name) 367 Expect(inspectOut).To(HaveLen(1)) 368 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 369 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"]).To(HaveLen(1)) 370 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0].HostPort).To(Not(Equal("0"))) 371 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 372 }) 373 374 It("podman run --expose 80/udp -P", func() { 375 name := "testctr" 376 session := podmanTest.Podman([]string{"create", "-t", "--expose", "80/udp", "-P", "--name", name, ALPINE, "/bin/sh"}) 377 session.WaitWithDefaultTimeout() 378 inspectOut := podmanTest.InspectContainer(name) 379 Expect(inspectOut).To(HaveLen(1)) 380 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 381 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"]).To(HaveLen(1)) 382 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"][0].HostPort).To(Not(Equal("0"))) 383 Expect(inspectOut[0].NetworkSettings.Ports["80/udp"][0]).To(HaveField("HostIP", "0.0.0.0")) 384 }) 385 386 It("podman run --expose 80 -p 80", func() { 387 name := "testctr" 388 session := podmanTest.Podman([]string{"create", "-t", "--expose", "80", "-p", "80", "--name", name, ALPINE, "/bin/sh"}) 389 session.WaitWithDefaultTimeout() 390 inspectOut := podmanTest.InspectContainer(name) 391 Expect(inspectOut).To(HaveLen(1)) 392 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 393 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"]).To(HaveLen(1)) 394 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0].HostPort).To(Not(Equal("80"))) 395 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 396 }) 397 398 It("podman run --publish-all with EXPOSE port ranges in Dockerfile", func() { 399 // Test port ranges, range with protocol and with an overlapping port 400 podmanTest.AddImageToRWStore(ALPINE) 401 dockerfile := fmt.Sprintf(`FROM %s 402 EXPOSE 2002 403 EXPOSE 2001-2003 404 EXPOSE 2004-2005/tcp`, ALPINE) 405 imageName := "testimg" 406 podmanTest.BuildImage(dockerfile, imageName, "false") 407 408 // Verify that the buildah is just passing through the EXPOSE keys 409 inspect := podmanTest.Podman([]string{"inspect", imageName}) 410 inspect.WaitWithDefaultTimeout() 411 image := inspect.InspectImageJSON() 412 Expect(image).To(HaveLen(1)) 413 Expect(image[0].Config.ExposedPorts).To(HaveLen(3)) 414 Expect(image[0].Config.ExposedPorts).To(HaveKey("2002/tcp")) 415 Expect(image[0].Config.ExposedPorts).To(HaveKey("2001-2003/tcp")) 416 Expect(image[0].Config.ExposedPorts).To(HaveKey("2004-2005/tcp")) 417 418 containerName := "testcontainer" 419 session := podmanTest.Podman([]string{"create", "--publish-all", "--name", containerName, imageName, "true"}) 420 session.WaitWithDefaultTimeout() 421 inspectOut := podmanTest.InspectContainer(containerName) 422 Expect(inspectOut).To(HaveLen(1)) 423 424 // Inspect the network settings with available ports to be mapped to the host 425 // Don't need to verity HostConfig.PortBindings since we used --publish-all 426 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(5)) 427 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveKey("2001/tcp")) 428 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveKey("2002/tcp")) 429 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveKey("2003/tcp")) 430 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveKey("2004/tcp")) 431 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveKey("2005/tcp")) 432 Expect(inspectOut[0].HostConfig.PublishAllPorts).To(BeTrue()) 433 }) 434 435 It("podman run -p 127.0.0.1::8980/udp", func() { 436 name := "testctr" 437 session := podmanTest.Podman([]string{"create", "-t", "-p", "127.0.0.1::8980/udp", "--name", name, ALPINE, "/bin/sh"}) 438 session.WaitWithDefaultTimeout() 439 inspectOut := podmanTest.InspectContainer(name) 440 Expect(inspectOut).To(HaveLen(1)) 441 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 442 Expect(inspectOut[0].NetworkSettings.Ports["8980/udp"]).To(HaveLen(1)) 443 Expect(inspectOut[0].NetworkSettings.Ports["8980/udp"][0].HostPort).To(Not(Equal("8980"))) 444 Expect(inspectOut[0].NetworkSettings.Ports["8980/udp"][0]).To(HaveField("HostIP", "127.0.0.1")) 445 }) 446 447 It("podman run -p :8181", func() { 448 name := "testctr" 449 session := podmanTest.Podman([]string{"create", "-t", "-p", ":8181", "--name", name, ALPINE, "/bin/sh"}) 450 session.WaitWithDefaultTimeout() 451 inspectOut := podmanTest.InspectContainer(name) 452 Expect(inspectOut).To(HaveLen(1)) 453 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 454 Expect(inspectOut[0].NetworkSettings.Ports["8181/tcp"]).To(HaveLen(1)) 455 Expect(inspectOut[0].NetworkSettings.Ports["8181/tcp"][0].HostPort).To(Not(Equal("8181"))) 456 Expect(inspectOut[0].NetworkSettings.Ports["8181/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 457 }) 458 459 It("podman run -p xxx:8080 -p yyy:8080", func() { 460 name := "testctr" 461 session := podmanTest.Podman([]string{"create", "-t", "-p", "4444:8080", "-p", "5555:8080", "--name", name, ALPINE, "/bin/sh"}) 462 session.WaitWithDefaultTimeout() 463 inspectOut := podmanTest.InspectContainer(name) 464 Expect(inspectOut).To(HaveLen(1)) 465 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 466 Expect(inspectOut[0].NetworkSettings.Ports["8080/tcp"]).To(HaveLen(2)) 467 468 hp1 := inspectOut[0].NetworkSettings.Ports["8080/tcp"][0].HostPort 469 hp2 := inspectOut[0].NetworkSettings.Ports["8080/tcp"][1].HostPort 470 471 // We can't guarantee order 472 Expect((hp1 == "4444" && hp2 == "5555") || (hp1 == "5555" && hp2 == "4444")).To(BeTrue()) 473 }) 474 475 It("podman run -p 0.0.0.0:9280:80", func() { 476 name := "testctr" 477 session := podmanTest.Podman([]string{"create", "-t", "-p", "0.0.0.0:9280:80", "--name", name, ALPINE, "/bin/sh"}) 478 session.WaitWithDefaultTimeout() 479 inspectOut := podmanTest.InspectContainer(name) 480 Expect(inspectOut).To(HaveLen(1)) 481 Expect(inspectOut[0].NetworkSettings.Ports).To(HaveLen(1)) 482 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"]).To(HaveLen(1)) 483 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostPort", "9280")) 484 Expect(inspectOut[0].NetworkSettings.Ports["80/tcp"][0]).To(HaveField("HostIP", "0.0.0.0")) 485 }) 486 487 It("podman run network expose host port 80 to container port", func() { 488 SkipIfRootless("iptables is not supported for rootless users") 489 port1 := GetPort() 490 port2 := GetPort() 491 session := podmanTest.Podman([]string{"run", "-dt", "-p", fmt.Sprintf("%d:%d", port1, port2), ALPINE, "/bin/sh"}) 492 session.WaitWithDefaultTimeout() 493 Expect(session).Should(ExitCleanly()) 494 results := SystemExec("iptables", []string{"-t", "nat", "-nvL"}) 495 Expect(results).Should(ExitCleanly()) 496 Expect(results.OutputToString()).To(ContainSubstring(strconv.Itoa(port2))) 497 498 ncBusy := SystemExec("nc", []string{"-l", "-p", strconv.Itoa(port1)}) 499 Expect(ncBusy).To(ExitWithError(2, fmt.Sprintf("Ncat: bind to 0.0.0.0:%d: Address already in use. QUITTING.", port1))) 500 }) 501 502 It("podman run network expose host port 18081 to container port 8000 using rootlesskit port handler", func() { 503 port1 := GetPort() 504 port2 := GetPort() 505 session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:port_handler=rootlesskit", "-dt", "-p", fmt.Sprintf("%d:%d", port2, port1), ALPINE, "/bin/sh"}) 506 session.WaitWithDefaultTimeout() 507 Expect(session).Should(ExitCleanly()) 508 509 ncBusy := SystemExec("nc", []string{"-l", "-p", strconv.Itoa(port2)}) 510 Expect(ncBusy).To(ExitWithError(2, fmt.Sprintf("Ncat: bind to [::]:%d: Address already in use. QUITTING.", port2))) 511 }) 512 513 It("podman run slirp4netns verify net.ipv6.conf.default.accept_dad=0", func() { 514 session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:enable_ipv6=true", ALPINE, "ip", "addr"}) 515 session.WaitWithDefaultTimeout() 516 Expect(session).Should(ExitCleanly()) 517 // check the ipv6 setup id done without delay (https://github.com/containers/podman/issues/11062) 518 Expect(session.OutputToString()).To(ContainSubstring("inet6 fd00::")) 519 520 const ipv6ConfDefaultAcceptDadSysctl = "/proc/sys/net/ipv6/conf/all/accept_dad" 521 522 cat := SystemExec("cat", []string{ipv6ConfDefaultAcceptDadSysctl}) 523 cat.WaitWithDefaultTimeout() 524 Expect(cat).Should(ExitCleanly()) 525 sysctlValue := cat.OutputToString() 526 527 session = podmanTest.Podman([]string{"run", "--network", "slirp4netns:enable_ipv6=true", ALPINE, "cat", ipv6ConfDefaultAcceptDadSysctl}) 528 session.WaitWithDefaultTimeout() 529 Expect(session).Should(ExitCleanly()) 530 Expect(session.OutputToString()).To(Equal(sysctlValue)) 531 }) 532 533 It("podman run network expose host port 8080 to container port 8000 using invalid port handler", func() { 534 session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:port_handler=invalid", "-dt", "-p", "8080:8000", ALPINE, "/bin/sh"}) 535 session.WaitWithDefaultTimeout() 536 Expect(session).To(ExitWithError(126, `unknown port_handler for slirp4netns: "invalid"`)) 537 }) 538 539 It("podman run slirp4netns network with host loopback", func() { 540 session := podmanTest.Podman([]string{"run", "--cap-add", "net_raw", "--network", "slirp4netns:allow_host_loopback=true", ALPINE, "ping", "-c1", "10.0.2.2"}) 541 session.WaitWithDefaultTimeout() 542 Expect(session).Should(ExitCleanly()) 543 }) 544 545 It("podman run slirp4netns network with mtu", func() { 546 session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:mtu=9000", ALPINE, "ip", "addr"}) 547 session.Wait(30) 548 Expect(session).Should(ExitCleanly()) 549 Expect(session.OutputToString()).To(ContainSubstring("mtu 9000")) 550 }) 551 552 It("podman run slirp4netns network with different cidr", func() { 553 slirp4netnsHelp := SystemExec("slirp4netns", []string{"--help"}) 554 Expect(slirp4netnsHelp).Should(ExitCleanly()) 555 556 networkConfiguration := "slirp4netns:cidr=192.168.0.0/24,allow_host_loopback=true" 557 session := podmanTest.Podman([]string{"run", "--cap-add", "net_raw", "--network", networkConfiguration, ALPINE, "ping", "-c1", "192.168.0.2"}) 558 session.Wait(30) 559 560 if strings.Contains(slirp4netnsHelp.OutputToString(), "cidr") { 561 Expect(session).Should(ExitCleanly()) 562 } else { 563 Expect(session).To(ExitWithError(125, "cidr not supported")) 564 } 565 }) 566 567 It("podman run network bind to 127.0.0.1", func() { 568 slirp4netnsHelp := SystemExec("slirp4netns", []string{"--help"}) 569 Expect(slirp4netnsHelp).Should(ExitCleanly()) 570 networkConfiguration := "slirp4netns:outbound_addr=127.0.0.1,allow_host_loopback=true" 571 port := strconv.Itoa(GetPort()) 572 573 if strings.Contains(slirp4netnsHelp.OutputToString(), "outbound-addr") { 574 ncListener := StartSystemExec("nc", []string{"-v", "-n", "-l", "-p", port}) 575 session := podmanTest.Podman([]string{"run", "--network", networkConfiguration, "-dt", ALPINE, "nc", "-w", "2", "10.0.2.2", port}) 576 session.WaitWithDefaultTimeout() 577 ncListener.WaitWithDefaultTimeout() 578 579 Expect(session).Should(ExitCleanly()) 580 Expect(ncListener).Should(Exit(0)) 581 Expect(ncListener.ErrorToString()).To(ContainSubstring("Connection from 127.0.0.1")) 582 } else { 583 session := podmanTest.Podman([]string{"run", "--network", networkConfiguration, "-dt", ALPINE, "nc", "-w", "2", "10.0.2.2", port}) 584 session.WaitWithDefaultTimeout() 585 Expect(session).To(ExitWithError(125, "outbound_addr not supported")) 586 } 587 }) 588 589 It("podman run network bind to HostIP", func() { 590 // Determine our likeliest outgoing IP address 591 conn, err := net.Dial("udp", "8.8.8.8:80") 592 Expect(err).ToNot(HaveOccurred()) 593 594 defer conn.Close() 595 ip := conn.LocalAddr().(*net.UDPAddr).IP 596 port := strconv.Itoa(GetPort()) 597 598 slirp4netnsHelp := SystemExec("slirp4netns", []string{"--help"}) 599 Expect(slirp4netnsHelp).Should(ExitCleanly()) 600 networkConfiguration := fmt.Sprintf("slirp4netns:outbound_addr=%s,allow_host_loopback=true", ip.String()) 601 602 if strings.Contains(slirp4netnsHelp.OutputToString(), "outbound-addr") { 603 ncListener := StartSystemExec("nc", []string{"-v", "-n", "-l", "-p", port}) 604 session := podmanTest.Podman([]string{"run", "--network", networkConfiguration, ALPINE, "nc", "-w", "2", "10.0.2.2", port}) 605 session.Wait(30) 606 ncListener.Wait(30) 607 608 Expect(session).Should(ExitCleanly()) 609 Expect(ncListener).Should(Exit(0)) 610 Expect(ncListener.ErrorToString()).To(ContainSubstring("Connection from " + ip.String())) 611 } else { 612 session := podmanTest.Podman([]string{"run", "--network", networkConfiguration, ALPINE, "nc", "-w", "2", "10.0.2.2", port}) 613 session.Wait(30) 614 Expect(session).To(ExitWithError(125, "outbound_addr not supported")) 615 } 616 }) 617 618 It("podman run network expose ports in image metadata", func() { 619 session := podmanTest.Podman([]string{"create", "--name", "test", "-t", "-P", NGINX_IMAGE}) 620 session.WaitWithDefaultTimeout() 621 Expect(session).Should(ExitCleanly()) 622 results := podmanTest.Podman([]string{"inspect", "test"}) 623 results.WaitWithDefaultTimeout() 624 Expect(results).Should(ExitCleanly()) 625 Expect(results.OutputToString()).To(ContainSubstring(`"80/tcp":`)) 626 }) 627 628 It("podman run network expose duplicate host port results in error", func() { 629 port := "8190" // Make sure this isn't used anywhere else 630 631 session := podmanTest.Podman([]string{"run", "--name", "test", "-dt", "-p", port, ALPINE, "/bin/sh"}) 632 session.WaitWithDefaultTimeout() 633 Expect(session).Should(ExitCleanly()) 634 635 inspect := podmanTest.Podman([]string{"inspect", "test"}) 636 inspect.WaitWithDefaultTimeout() 637 Expect(inspect).Should(ExitCleanly()) 638 639 containerConfig := inspect.InspectContainerToJSON() 640 Expect(containerConfig[0].NetworkSettings.Ports).To(Not(BeNil())) 641 Expect(containerConfig[0].NetworkSettings.Ports).To(HaveKeyWithValue(port+"/tcp", Not(BeNil()))) 642 Expect(containerConfig[0].NetworkSettings.Ports[port+"/tcp"][0].HostPort).ToNot(Equal(port)) 643 }) 644 645 It("podman run forward sctp protocol", func() { 646 SkipIfRootless("sctp protocol only works as root") 647 session := podmanTest.Podman([]string{"--log-level=info", "run", "--name=test", "-p", "80/sctp", "-p", "81/sctp", ALPINE}) 648 session.WaitWithDefaultTimeout() 649 Expect(session).Should(Exit(0)) 650 // we can only check logrus on local podman 651 if !IsRemote() { 652 // check that the info message for sctp protocol is only displayed once 653 Expect(strings.Count(session.ErrorToString(), "Port reservation for SCTP is not supported")).To(Equal(1), "`Port reservation for SCTP is not supported` is not displayed exactly one time in the logrus logs") 654 } 655 results := podmanTest.Podman([]string{"inspect", "test"}) 656 results.WaitWithDefaultTimeout() 657 Expect(results).Should(ExitCleanly()) 658 Expect(results.OutputToString()).To(ContainSubstring(`"80/sctp":`)) 659 Expect(results.OutputToString()).To(ContainSubstring(`"81/sctp":`)) 660 }) 661 662 It("podman run hostname test", func() { 663 session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "printenv", "HOSTNAME"}) 664 session.WaitWithDefaultTimeout() 665 Expect(session).Should(ExitCleanly()) 666 Expect(session.OutputToString()).To(Not(ContainSubstring(hostname))) 667 }) 668 669 It("podman run --net host hostname test", func() { 670 session := podmanTest.Podman([]string{"run", "--rm", "--net", "host", ALPINE, "printenv", "HOSTNAME"}) 671 session.WaitWithDefaultTimeout() 672 Expect(session).Should(ExitCleanly()) 673 Expect(session.OutputToString()).To(ContainSubstring(hostname)) 674 }) 675 It("podman run --net host --uts host hostname test", func() { 676 session := podmanTest.Podman([]string{"run", "--rm", "--net", "host", "--uts", "host", ALPINE, "printenv", "HOSTNAME"}) 677 session.WaitWithDefaultTimeout() 678 Expect(session).Should(ExitCleanly()) 679 Expect(session.OutputToString()).To(ContainSubstring(hostname)) 680 }) 681 It("podman run --uts host hostname test", func() { 682 session := podmanTest.Podman([]string{"run", "--rm", "--uts", "host", ALPINE, "printenv", "HOSTNAME"}) 683 session.WaitWithDefaultTimeout() 684 Expect(session).Should(ExitCleanly()) 685 Expect(session.OutputToString()).To(ContainSubstring(hostname)) 686 }) 687 688 It("podman run --net host --hostname ... hostname test", func() { 689 session := podmanTest.Podman([]string{"run", "--rm", "--net", "host", "--hostname", "foobar", ALPINE, "printenv", "HOSTNAME"}) 690 session.WaitWithDefaultTimeout() 691 Expect(session).Should(ExitCleanly()) 692 Expect(session.OutputToString()).To(ContainSubstring("foobar")) 693 }) 694 695 It("podman run --hostname ... hostname test", func() { 696 session := podmanTest.Podman([]string{"run", "--rm", "--hostname", "foobar", ALPINE, "printenv", "HOSTNAME"}) 697 session.WaitWithDefaultTimeout() 698 Expect(session).Should(ExitCleanly()) 699 Expect(session.OutputToString()).To(ContainSubstring("foobar")) 700 }) 701 702 It("podman run --net container: and --uts container:", func() { 703 ctrName := "ctrToJoin" 704 ctr1 := podmanTest.RunTopContainer(ctrName) 705 ctr1.WaitWithDefaultTimeout() 706 Expect(ctr1).Should(ExitCleanly()) 707 708 ctr2 := podmanTest.Podman([]string{"run", "-d", "--net=container:" + ctrName, "--uts=container:" + ctrName, ALPINE, "true"}) 709 ctr2.WaitWithDefaultTimeout() 710 Expect(ctr2).Should(ExitCleanly()) 711 }) 712 713 It("podman run --net container: and --add-host should fail", func() { 714 ctrName := "ctrToJoin" 715 ctr1 := podmanTest.RunTopContainer(ctrName) 716 ctr1.WaitWithDefaultTimeout() 717 Expect(ctr1).Should(ExitCleanly()) 718 719 ctr2 := podmanTest.Podman([]string{"run", "-d", "--net=container:" + ctrName, "--add-host", "host1:127.0.0.1", ALPINE, "true"}) 720 ctr2.WaitWithDefaultTimeout() 721 Expect(ctr2).Should(ExitWithError(125, "cannot set extra host entries when the container is joined to another containers network namespace: invalid configuration")) 722 }) 723 724 It("podman run --net container: copies hosts and resolv", func() { 725 ctrName := "ctr1" 726 ctr1 := podmanTest.RunTopContainer(ctrName) 727 ctr1.WaitWithDefaultTimeout() 728 Expect(ctr1).Should(ExitCleanly()) 729 730 // Exec in and modify /etc/resolv.conf and /etc/hosts 731 exec1 := podmanTest.Podman([]string{"exec", ctrName, "sh", "-c", "echo nameserver 192.0.2.1 > /etc/resolv.conf"}) 732 exec1.WaitWithDefaultTimeout() 733 Expect(exec1).Should(ExitCleanly()) 734 735 exec2 := podmanTest.Podman([]string{"exec", ctrName, "sh", "-c", "echo 192.0.2.2 test1 > /etc/hosts"}) 736 exec2.WaitWithDefaultTimeout() 737 Expect(exec2).Should(ExitCleanly()) 738 739 ctrName2 := "ctr2" 740 ctr2 := podmanTest.Podman([]string{"run", "-d", "--net=container:" + ctrName, "--name", ctrName2, ALPINE, "top"}) 741 ctr2.WaitWithDefaultTimeout() 742 Expect(ctr2).Should(ExitCleanly()) 743 744 exec3 := podmanTest.Podman([]string{"exec", ctrName2, "cat", "/etc/resolv.conf"}) 745 exec3.WaitWithDefaultTimeout() 746 Expect(exec3).Should(ExitCleanly()) 747 Expect(exec3.OutputToString()).To(ContainSubstring("nameserver 192.0.2.1")) 748 749 exec4 := podmanTest.Podman([]string{"exec", ctrName2, "cat", "/etc/hosts"}) 750 exec4.WaitWithDefaultTimeout() 751 Expect(exec4).Should(ExitCleanly()) 752 Expect(exec4.OutputToString()).To(ContainSubstring("192.0.2.2 test1")) 753 }) 754 755 It("podman run /etc/hosts contains --hostname", func() { 756 session := podmanTest.Podman([]string{"run", "--rm", "--hostname", "foohostname", ALPINE, "grep", "foohostname", "/etc/hosts"}) 757 session.WaitWithDefaultTimeout() 758 Expect(session).Should(ExitCleanly()) 759 }) 760 761 It("podman run --uidmap /etc/hosts contains --hostname", func() { 762 SkipIfRootless("uidmap population of cninetworks not supported for rootless users") 763 session := podmanTest.Podman([]string{"run", "--uidmap", "0:100000:1000", "--rm", "--hostname", "foohostname", ALPINE, "grep", "foohostname", "/etc/hosts"}) 764 session.WaitWithDefaultTimeout() 765 Expect(session).Should(ExitCleanly()) 766 767 session = podmanTest.Podman([]string{"run", "--uidmap", "0:100000:1000", "--rm", "--hostname", "foohostname", "-v", "/etc/hosts:/etc/hosts", ALPINE, "grep", "foohostname", "/etc/hosts"}) 768 session.WaitWithDefaultTimeout() 769 Expect(session).Should(Exit(1)) 770 }) 771 772 It("podman run network in user created network namespace", func() { 773 SkipIfRootless("ip netns is not supported for rootless users") 774 if Containerized() { 775 Skip("Cannot be run within a container.") 776 } 777 addXXX := SystemExec("ip", []string{"netns", "add", "xxx"}) 778 Expect(addXXX).Should(ExitCleanly()) 779 defer func() { 780 delXXX := SystemExec("ip", []string{"netns", "delete", "xxx"}) 781 Expect(delXXX).Should(ExitCleanly()) 782 }() 783 784 session := podmanTest.Podman([]string{"run", "-dt", "--net", "ns:/run/netns/xxx", ALPINE, "wget", "www.redhat.com"}) 785 session.Wait(90) 786 Expect(session).Should(ExitCleanly()) 787 }) 788 789 It("podman run n user created network namespace with resolv.conf", func() { 790 SkipIfRootless("ip netns is not supported for rootless users") 791 if Containerized() { 792 Skip("Cannot be run within a container.") 793 } 794 addXXX2 := SystemExec("ip", []string{"netns", "add", "xxx2"}) 795 Expect(addXXX2).Should(ExitCleanly()) 796 defer func() { 797 delXXX2 := SystemExec("ip", []string{"netns", "delete", "xxx2"}) 798 Expect(delXXX2).Should(ExitCleanly()) 799 }() 800 801 mdXXX2 := SystemExec("mkdir", []string{"-p", "/etc/netns/xxx2"}) 802 Expect(mdXXX2).Should(ExitCleanly()) 803 defer os.RemoveAll("/etc/netns/xxx2") 804 805 nsXXX2 := SystemExec("bash", []string{"-c", "echo nameserver 11.11.11.11 > /etc/netns/xxx2/resolv.conf"}) 806 Expect(nsXXX2).Should(ExitCleanly()) 807 808 session := podmanTest.Podman([]string{"run", "--net", "ns:/run/netns/xxx2", ALPINE, "cat", "/etc/resolv.conf"}) 809 session.Wait(90) 810 Expect(session).Should(ExitCleanly()) 811 Expect(session.OutputToString()).To(ContainSubstring("11.11.11.11")) 812 }) 813 814 addAddr := func(cidr string, containerInterface netlink.Link) error { 815 _, ipnet, err := net.ParseCIDR(cidr) 816 Expect(err).ToNot(HaveOccurred()) 817 addr := &netlink.Addr{IPNet: ipnet, Label: ""} 818 if err := netlink.AddrAdd(containerInterface, addr); err != nil && err != syscall.EEXIST { 819 return err 820 } 821 return nil 822 } 823 824 loopbackup := func() { 825 lo, err := netlink.LinkByName("lo") 826 Expect(err).ToNot(HaveOccurred()) 827 err = netlink.LinkSetUp(lo) 828 Expect(err).ToNot(HaveOccurred()) 829 } 830 831 linkup := func(name string, mac string, addresses []string) { 832 linkAttr := netlink.NewLinkAttrs() 833 linkAttr.Name = name 834 m, err := net.ParseMAC(mac) 835 Expect(err).ToNot(HaveOccurred()) 836 linkAttr.HardwareAddr = m 837 eth := &netlink.Dummy{LinkAttrs: linkAttr} 838 err = netlink.LinkAdd(eth) 839 Expect(err).ToNot(HaveOccurred()) 840 err = netlink.LinkSetUp(eth) 841 Expect(err).ToNot(HaveOccurred()) 842 for _, address := range addresses { 843 err := addAddr(address, eth) 844 Expect(err).ToNot(HaveOccurred()) 845 } 846 } 847 848 routeAdd := func(gateway string) { 849 gw := net.ParseIP(gateway) 850 route := &netlink.Route{Dst: nil, Gw: gw} 851 err = netlink.RouteAdd(route) 852 Expect(err).ToNot(HaveOccurred()) 853 } 854 855 setupNetworkNs := func(networkNSName string) { 856 _ = ns.WithNetNSPath("/run/netns/"+networkNSName, func(_ ns.NetNS) error { 857 loopbackup() 858 linkup("eth0", "46:7f:45:6e:4f:c8", []string{"10.25.40.0/24", "fd04:3e42:4a4e:3381::/64"}) 859 linkup("eth1", "56:6e:35:5d:3e:a8", []string{"10.88.0.0/16"}) 860 861 routeAdd("10.25.40.0") 862 return nil 863 }) 864 } 865 866 checkNetworkNsInspect := func(name string) { 867 inspectOut := podmanTest.InspectContainer(name) 868 Expect(inspectOut[0].NetworkSettings).To(HaveField("IPAddress", "10.25.40.0")) 869 Expect(inspectOut[0].NetworkSettings).To(HaveField("IPPrefixLen", 24)) 870 Expect(inspectOut[0].NetworkSettings.SecondaryIPAddresses).To(HaveLen(1)) 871 Expect(inspectOut[0].NetworkSettings.SecondaryIPAddresses[0]).To(HaveField("Addr", "10.88.0.0")) 872 Expect(inspectOut[0].NetworkSettings.SecondaryIPAddresses[0]).To(HaveField("PrefixLength", 16)) 873 Expect(inspectOut[0].NetworkSettings).To(HaveField("GlobalIPv6Address", "fd04:3e42:4a4e:3381::")) 874 Expect(inspectOut[0].NetworkSettings).To(HaveField("GlobalIPv6PrefixLen", 64)) 875 Expect(inspectOut[0].NetworkSettings.SecondaryIPv6Addresses).To(BeEmpty()) 876 Expect(inspectOut[0].NetworkSettings).To(HaveField("MacAddress", "46:7f:45:6e:4f:c8")) 877 Expect(inspectOut[0].NetworkSettings.AdditionalMacAddresses).To(HaveLen(1)) 878 Expect(inspectOut[0].NetworkSettings.AdditionalMacAddresses[0]).To(Equal("56:6e:35:5d:3e:a8")) 879 Expect(inspectOut[0].NetworkSettings).To(HaveField("Gateway", "10.25.40.0")) 880 881 } 882 883 It("podman run network inspect fails gracefully on non-reachable network ns", func() { 884 SkipIfRootless("ip netns is not supported for rootless users") 885 886 networkNSName := RandomString(12) 887 addNamedNetwork := SystemExec("ip", []string{"netns", "add", networkNSName}) 888 Expect(addNamedNetwork).Should(ExitCleanly()) 889 890 setupNetworkNs(networkNSName) 891 892 name := RandomString(12) 893 session := podmanTest.Podman([]string{"run", "-d", "--name", name, "--net", "ns:/run/netns/" + networkNSName, ALPINE, "top"}) 894 session.WaitWithDefaultTimeout() 895 896 // delete the named network ns before inspect 897 delNetworkNamespace := SystemExec("ip", []string{"netns", "delete", networkNSName}) 898 Expect(delNetworkNamespace).Should(ExitCleanly()) 899 900 inspectOut := podmanTest.InspectContainer(name) 901 Expect(inspectOut[0].NetworkSettings).To(HaveField("IPAddress", "")) 902 Expect(inspectOut[0].NetworkSettings.Networks).To(BeEmpty()) 903 }) 904 905 It("podman inspect can handle joined network ns with multiple interfaces", func() { 906 SkipIfRootless("ip netns is not supported for rootless users") 907 908 networkNSName := RandomString(12) 909 addNamedNetwork := SystemExec("ip", []string{"netns", "add", networkNSName}) 910 Expect(addNamedNetwork).Should(ExitCleanly()) 911 defer func() { 912 delNetworkNamespace := SystemExec("ip", []string{"netns", "delete", networkNSName}) 913 Expect(delNetworkNamespace).Should(ExitCleanly()) 914 }() 915 setupNetworkNs(networkNSName) 916 917 name := RandomString(12) 918 session := podmanTest.Podman([]string{"run", "--name", name, "--net", "ns:/run/netns/" + networkNSName, ALPINE}) 919 session.WaitWithDefaultTimeout() 920 921 session = podmanTest.Podman([]string{"container", "rm", name}) 922 session.WaitWithDefaultTimeout() 923 924 // no network teardown should touch joined network ns interfaces 925 session = podmanTest.Podman([]string{"run", "-d", "--replace", "--name", name, "--net", "ns:/run/netns/" + networkNSName, ALPINE, "top"}) 926 session.WaitWithDefaultTimeout() 927 928 checkNetworkNsInspect(name) 929 }) 930 931 It("podman do not tamper with joined network ns interfaces", func() { 932 SkipIfRootless("ip netns is not supported for rootless users") 933 934 networkNSName := RandomString(12) 935 addNamedNetwork := SystemExec("ip", []string{"netns", "add", networkNSName}) 936 Expect(addNamedNetwork).Should(ExitCleanly()) 937 defer func() { 938 delNetworkNamespace := SystemExec("ip", []string{"netns", "delete", networkNSName}) 939 Expect(delNetworkNamespace).Should(ExitCleanly()) 940 }() 941 942 setupNetworkNs(networkNSName) 943 944 name := RandomString(12) 945 session := podmanTest.Podman([]string{"run", "--name", name, "--net", "ns:/run/netns/" + networkNSName, ALPINE}) 946 session.WaitWithDefaultTimeout() 947 948 checkNetworkNsInspect(name) 949 950 name = RandomString(12) 951 session = podmanTest.Podman([]string{"run", "--name", name, "--net", "ns:/run/netns/" + networkNSName, ALPINE}) 952 session.WaitWithDefaultTimeout() 953 954 checkNetworkNsInspect(name) 955 956 // delete container, the network inspect should not change 957 session = podmanTest.Podman([]string{"container", "rm", name}) 958 session.WaitWithDefaultTimeout() 959 960 session = podmanTest.Podman([]string{"run", "-d", "--replace", "--name", name, "--net", "ns:/run/netns/" + networkNSName, ALPINE, "top"}) 961 session.WaitWithDefaultTimeout() 962 963 checkNetworkNsInspect(name) 964 }) 965 966 It("podman run network in bogus user created network namespace", func() { 967 session := podmanTest.Podman([]string{"run", "-dt", "--net", "ns:/run/netns/xxy", ALPINE, "wget", "www.redhat.com"}) 968 session.Wait(90) 969 Expect(session).To(ExitWithError(125, "faccessat /run/netns/xxy: no such file or directory")) 970 }) 971 972 It("podman run in custom CNI network with --static-ip", func() { 973 netName := stringid.GenerateRandomID() 974 ipAddr := "10.25.30.128" 975 create := podmanTest.Podman([]string{"network", "create", "--subnet", "10.25.30.0/24", netName}) 976 create.WaitWithDefaultTimeout() 977 Expect(create).Should(ExitCleanly()) 978 defer podmanTest.removeNetwork(netName) 979 980 run := podmanTest.Podman([]string{"run", "--rm", "--net", netName, "--ip", ipAddr, ALPINE, "ip", "addr"}) 981 run.WaitWithDefaultTimeout() 982 Expect(run).Should(ExitCleanly()) 983 Expect(run.OutputToString()).To(ContainSubstring(ipAddr)) 984 }) 985 986 It("podman network works across user ns", func() { 987 netName := createNetworkName("") 988 create := podmanTest.Podman([]string{"network", "create", netName}) 989 create.WaitWithDefaultTimeout() 990 Expect(create).Should(ExitCleanly()) 991 defer podmanTest.removeNetwork(netName) 992 993 name := "nc-server" 994 run := podmanTest.Podman([]string{"run", "--log-driver", "k8s-file", "-d", "--name", name, "--net", netName, ALPINE, "nc", "-l", "-p", "9480"}) 995 run.WaitWithDefaultTimeout() 996 Expect(run).Should(ExitCleanly()) 997 998 // NOTE: we force the k8s-file log driver to make sure the 999 // tests are passing inside a container. 1000 // "sleep" needed to give aardvark-dns time to come up; #16272 1001 run = podmanTest.Podman([]string{"run", "--log-driver", "k8s-file", "--rm", "--net", netName, "--uidmap", "0:1:4096", ALPINE, "sh", "-c", fmt.Sprintf("sleep 2;echo podman | nc -w 1 %s.dns.podman 9480", name)}) 1002 run.WaitWithDefaultTimeout() 1003 Expect(run).Should(ExitCleanly()) 1004 1005 log := podmanTest.Podman([]string{"logs", name}) 1006 log.WaitWithDefaultTimeout() 1007 Expect(log).Should(ExitCleanly()) 1008 Expect(log.OutputToString()).To(Equal("podman")) 1009 }) 1010 1011 It("podman run with new:pod and static-ip", func() { 1012 netName := stringid.GenerateRandomID() 1013 ipAddr := "10.25.40.128" 1014 podname := "testpod" 1015 create := podmanTest.Podman([]string{"network", "create", "--subnet", "10.25.40.0/24", netName}) 1016 create.WaitWithDefaultTimeout() 1017 Expect(create).Should(ExitCleanly()) 1018 defer podmanTest.removeNetwork(netName) 1019 1020 run := podmanTest.Podman([]string{"run", "--rm", "--pod", "new:" + podname, "--net", netName, "--ip", ipAddr, ALPINE, "ip", "addr"}) 1021 run.WaitWithDefaultTimeout() 1022 Expect(run).Should(ExitCleanly()) 1023 Expect(run.OutputToString()).To(ContainSubstring(ipAddr)) 1024 1025 podrm := podmanTest.Podman([]string{"pod", "rm", "-t", "0", "-f", podname}) 1026 podrm.WaitWithDefaultTimeout() 1027 Expect(podrm).Should(ExitCleanly()) 1028 }) 1029 1030 It("podman run with --net=host and --hostname sets correct hostname", func() { 1031 hostname := "testctr" 1032 run := podmanTest.Podman([]string{"run", "--net=host", "--hostname", hostname, ALPINE, "hostname"}) 1033 run.WaitWithDefaultTimeout() 1034 Expect(run).Should(ExitCleanly()) 1035 Expect(run.OutputToString()).To(ContainSubstring(hostname)) 1036 }) 1037 1038 It("podman run with --net=none sets hostname", func() { 1039 hostname := "testctr" 1040 run := podmanTest.Podman([]string{"run", "--net=none", "--hostname", hostname, ALPINE, "hostname"}) 1041 run.WaitWithDefaultTimeout() 1042 Expect(run).Should(ExitCleanly()) 1043 Expect(run.OutputToString()).To(ContainSubstring(hostname)) 1044 }) 1045 1046 It("podman run with --net=none adds hostname to /etc/hosts", func() { 1047 hostname := "testctr" 1048 run := podmanTest.Podman([]string{"run", "--net=none", "--hostname", hostname, ALPINE, "cat", "/etc/hosts"}) 1049 run.WaitWithDefaultTimeout() 1050 Expect(run).Should(ExitCleanly()) 1051 Expect(run.OutputToString()).To(ContainSubstring(hostname)) 1052 }) 1053 1054 It("podman run with pod does not add extra 127 entry to /etc/hosts", func() { 1055 pod := "testpod" 1056 hostname := "test-hostname" 1057 run := podmanTest.Podman([]string{"pod", "create", "--hostname", hostname, "--name", pod}) 1058 run.WaitWithDefaultTimeout() 1059 Expect(run).Should(ExitCleanly()) 1060 run = podmanTest.Podman([]string{"run", "--pod", pod, ALPINE, "cat", "/etc/hosts"}) 1061 run.WaitWithDefaultTimeout() 1062 Expect(run).Should(ExitCleanly()) 1063 Expect(run.OutputToString()).ToNot(ContainSubstring("127.0.0.1 %s", hostname)) 1064 }) 1065 1066 pingTest := func(netns string) { 1067 hostname := "testctr" 1068 run := podmanTest.Podman([]string{"run", netns, "--cap-add", "net_raw", "--hostname", hostname, ALPINE, "ping", "-c", "1", hostname}) 1069 run.WaitWithDefaultTimeout() 1070 Expect(run).Should(ExitCleanly()) 1071 1072 run = podmanTest.Podman([]string{"run", netns, "--cap-add", "net_raw", "--hostname", hostname, "--name", "test", ALPINE, "ping", "-c", "1", "test"}) 1073 run.WaitWithDefaultTimeout() 1074 Expect(run).Should(ExitCleanly()) 1075 } 1076 1077 It("podman attempt to ping container name and hostname --net=none", func() { 1078 pingTest("--net=none") 1079 }) 1080 1081 It("podman attempt to ping container name and hostname --net=private", func() { 1082 pingTest("--net=private") 1083 }) 1084 1085 It("podman run check dns", func() { 1086 SkipIfCNI(podmanTest) 1087 pod := "testpod" 1088 session := podmanTest.Podman([]string{"pod", "create", "--name", pod}) 1089 session.WaitWithDefaultTimeout() 1090 Expect(session).Should(ExitCleanly()) 1091 1092 net := createNetworkName("IntTest") 1093 session = podmanTest.Podman([]string{"network", "create", net}) 1094 session.WaitWithDefaultTimeout() 1095 defer podmanTest.removeNetwork(net) 1096 Expect(session).Should(ExitCleanly()) 1097 1098 pod2 := "testpod2" 1099 hostname := "hostn1" 1100 session = podmanTest.Podman([]string{"pod", "create", "--network", net, "--name", pod2, "--hostname", hostname}) 1101 session.WaitWithDefaultTimeout() 1102 Expect(session).Should(ExitCleanly()) 1103 1104 session = podmanTest.Podman([]string{"run", "--name", "con1", "--network", net, CITEST_IMAGE, "nslookup", "con1"}) 1105 session.WaitWithDefaultTimeout() 1106 Expect(session).Should(ExitCleanly()) 1107 1108 session = podmanTest.Podman([]string{"run", "--name", "con2", "--pod", pod, "--network", net, CITEST_IMAGE, "nslookup", "con2"}) 1109 session.WaitWithDefaultTimeout() 1110 Expect(session).Should(ExitCleanly()) 1111 1112 session = podmanTest.Podman([]string{"run", "--name", "con3", "--pod", pod2, CITEST_IMAGE, "nslookup", "con1"}) 1113 session.WaitWithDefaultTimeout() 1114 Expect(session).Should(Exit(1)) 1115 Expect(session.OutputToString()).To(ContainSubstring("server can't find con1.dns.podman: NXDOMAIN")) 1116 1117 session = podmanTest.Podman([]string{"run", "--name", "con4", "--network", net, CITEST_IMAGE, "nslookup", pod2 + ".dns.podman"}) 1118 session.WaitWithDefaultTimeout() 1119 Expect(session).Should(ExitCleanly()) 1120 1121 session = podmanTest.Podman([]string{"run", "--network", net, CITEST_IMAGE, "nslookup", hostname}) 1122 session.WaitWithDefaultTimeout() 1123 Expect(session).Should(ExitCleanly()) 1124 }) 1125 1126 It("podman network adds dns search domain with dns", func() { 1127 net := createNetworkName("dnsname") 1128 session := podmanTest.Podman([]string{"network", "create", net}) 1129 session.WaitWithDefaultTimeout() 1130 defer podmanTest.removeNetwork(net) 1131 Expect(session).Should(ExitCleanly()) 1132 1133 session = podmanTest.Podman([]string{"run", "--network", net, ALPINE, "cat", "/etc/resolv.conf"}) 1134 session.WaitWithDefaultTimeout() 1135 Expect(session).Should(ExitCleanly()) 1136 Expect(session.OutputToString()).To(ContainSubstring("search dns.podman")) 1137 }) 1138 1139 It("Rootless podman run with --net=bridge works and connects to default network", func() { 1140 // This is harmless when run as root, so we'll just let it run. 1141 ctrName := "testctr" 1142 ctr := podmanTest.Podman([]string{"run", "-d", "--net=bridge", "--name", ctrName, ALPINE, "top"}) 1143 ctr.WaitWithDefaultTimeout() 1144 Expect(ctr).Should(ExitCleanly()) 1145 1146 inspectOut := podmanTest.InspectContainer(ctrName) 1147 Expect(inspectOut).To(HaveLen(1)) 1148 Expect(inspectOut[0].NetworkSettings.Networks).To(HaveLen(1)) 1149 Expect(inspectOut[0].NetworkSettings.Networks).To(HaveKey("podman")) 1150 }) 1151 1152 // see https://github.com/containers/podman/issues/12972 1153 It("podman run check network-alias works on networks without dns", func() { 1154 net := "dns" + stringid.GenerateRandomID() 1155 session := podmanTest.Podman([]string{"network", "create", "--disable-dns", net}) 1156 session.WaitWithDefaultTimeout() 1157 defer podmanTest.removeNetwork(net) 1158 Expect(session).Should(ExitCleanly()) 1159 1160 session = podmanTest.Podman([]string{"run", "--network", net, "--network-alias", "abcdef", ALPINE, "true"}) 1161 session.WaitWithDefaultTimeout() 1162 Expect(session).Should(ExitCleanly()) 1163 }) 1164 1165 It("podman run with ipam none driver", func() { 1166 net := "ipam" + stringid.GenerateRandomID() 1167 session := podmanTest.Podman([]string{"network", "create", "--ipam-driver=none", net}) 1168 session.WaitWithDefaultTimeout() 1169 defer podmanTest.removeNetwork(net) 1170 Expect(session).Should(ExitCleanly()) 1171 1172 session = podmanTest.Podman([]string{"run", "--network", net, ALPINE, "ip", "addr", "show", "eth0"}) 1173 session.WaitWithDefaultTimeout() 1174 Expect(session).Should(ExitCleanly()) 1175 Expect(session.OutputToStringArray()).To(HaveLen(4), "output should only show link local address") 1176 }) 1177 1178 It("podman run with macvlan network", func() { 1179 net := "mv-" + stringid.GenerateRandomID() 1180 session := podmanTest.Podman([]string{"network", "create", "-d", "macvlan", "--subnet", "10.10.0.0/24", net}) 1181 session.WaitWithDefaultTimeout() 1182 defer podmanTest.removeNetwork(net) 1183 Expect(session).Should(ExitCleanly()) 1184 1185 // use options and search to make sure we get the same resolv.conf everywhere 1186 run := podmanTest.Podman([]string{"run", "--network", net, "--dns", "127.0.0.128", 1187 "--dns-option", "ndots:1", "--dns-search", ".", ALPINE, "cat", "/etc/resolv.conf"}) 1188 run.WaitWithDefaultTimeout() 1189 Expect(run).Should(ExitCleanly()) 1190 Expect(string(run.Out.Contents())).To(Equal(`nameserver 127.0.0.128 1191 options ndots:1 1192 `)) 1193 }) 1194 })