package integration import ( "fmt" "io/ioutil" "os" "path/filepath" "strings" "time" "github.com/containers/podman/v2/pkg/rootless" . "github.com/containers/podman/v2/test/utils" "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func writeConf(conf []byte, confPath string) { if err := ioutil.WriteFile(confPath, conf, 777); err != nil { fmt.Println(err) } } func removeConf(confPath string) { if err := os.Remove(confPath); err != nil { fmt.Println(err) } } // generateNetworkConfig generates a cni config with a random name // it returns the network name and the filepath func generateNetworkConfig(p *PodmanTestIntegration) (string, string) { // generate a random name to prevent conflicts with other tests name := "net" + stringid.GenerateNonCryptoID() path := filepath.Join(p.CNIConfigDir, fmt.Sprintf("%s.conflist", name)) conf := fmt.Sprintf(`{ "cniVersion": "0.3.0", "name": "%s", "plugins": [ { "type": "bridge", "bridge": "cni1", "isGateway": true, "ipMasq": true, "ipam": { "type": "host-local", "subnet": "10.99.0.0/16", "routes": [ { "dst": "0.0.0.0/0" } ] } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] }`, name) writeConf([]byte(conf), path) return name, path } var _ = Describe("Podman network", func() { var ( tempdir string err error podmanTest *PodmanTestIntegration ) BeforeEach(func() { tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) } podmanTest = PodmanTestCreate(tempdir) podmanTest.Setup() }) AfterEach(func() { podmanTest.Cleanup() f := CurrentGinkgoTestDescription() processTestResult(f) }) It("podman network list", func() { name, path := generateNetworkConfig(podmanTest) defer removeConf(path) session := podmanTest.Podman([]string{"network", "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.LineInOutputContains(name)).To(BeTrue()) }) It("podman network list -q", func() { name, path := generateNetworkConfig(podmanTest) defer removeConf(path) session := podmanTest.Podman([]string{"network", "ls", "--quiet"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.LineInOutputContains(name)).To(BeTrue()) }) It("podman network list --filter success", func() { name, path := generateNetworkConfig(podmanTest) defer removeConf(path) session := podmanTest.Podman([]string{"network", "ls", "--filter", "plugin=bridge"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.LineInOutputContains(name)).To(BeTrue()) }) It("podman network list --filter failure", func() { name, path := generateNetworkConfig(podmanTest) defer removeConf(path) session := podmanTest.Podman([]string{"network", "ls", "--filter", "plugin=test"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.LineInOutputContains(name)).To(BeFalse()) }) It("podman network rm no args", func() { session := podmanTest.Podman([]string{"network", "rm"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).ToNot(BeZero()) }) It("podman network rm", func() { SkipIfRootless("FIXME: This one is definitely broken in rootless mode") name, path := generateNetworkConfig(podmanTest) defer removeConf(path) session := podmanTest.Podman([]string{"network", "ls", "--quiet"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.LineInOutputContains(name)).To(BeTrue()) rm := podmanTest.Podman([]string{"network", "rm", name}) rm.WaitWithDefaultTimeout() Expect(rm.ExitCode()).To(BeZero()) results := podmanTest.Podman([]string{"network", "ls", "--quiet"}) results.WaitWithDefaultTimeout() Expect(results.ExitCode()).To(Equal(0)) Expect(results.LineInOutputContains(name)).To(BeFalse()) }) It("podman network inspect no args", func() { session := podmanTest.Podman([]string{"network", "inspect"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).ToNot(BeZero()) }) It("podman network inspect", func() { name, path := generateNetworkConfig(podmanTest) defer removeConf(path) expectedNetworks := []string{name} if !rootless.IsRootless() { // rootful image contains "podman/cni/87-podman-bridge.conflist" for "podman" network expectedNetworks = append(expectedNetworks, "podman") } session := podmanTest.Podman(append([]string{"network", "inspect"}, expectedNetworks...)) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.IsJSONOutputValid()).To(BeTrue()) }) It("podman network inspect", func() { name, path := generateNetworkConfig(podmanTest) defer removeConf(path) session := podmanTest.Podman([]string{"network", "inspect", name, "--format", "{{.cniVersion}}"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.LineInOutputContains("0.3.0")).To(BeTrue()) }) It("podman inspect container single CNI network", func() { netName := "testNetSingleCNI" network := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.50.0/24", netName}) network.WaitWithDefaultTimeout() Expect(network.ExitCode()).To(BeZero()) defer podmanTest.removeCNINetwork(netName) ctrName := "testCtr" container := podmanTest.Podman([]string{"run", "-dt", "--network", netName, "--name", ctrName, ALPINE, "top"}) container.WaitWithDefaultTimeout() Expect(container.ExitCode()).To(BeZero()) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(BeZero()) conData := inspect.InspectContainerToJSON() Expect(len(conData)).To(Equal(1)) Expect(len(conData[0].NetworkSettings.Networks)).To(Equal(1)) net, ok := conData[0].NetworkSettings.Networks[netName] Expect(ok).To(BeTrue()) Expect(net.NetworkID).To(Equal(netName)) Expect(net.IPPrefixLen).To(Equal(24)) Expect(strings.HasPrefix(net.IPAddress, "10.50.50.")).To(BeTrue()) // Necessary to ensure the CNI network is removed cleanly rmAll := podmanTest.Podman([]string{"rm", "-f", ctrName}) rmAll.WaitWithDefaultTimeout() Expect(rmAll.ExitCode()).To(BeZero()) }) It("podman inspect container two CNI networks (container not running)", func() { netName1 := "testNetThreeCNI1" network1 := podmanTest.Podman([]string{"network", "create", netName1}) network1.WaitWithDefaultTimeout() Expect(network1.ExitCode()).To(BeZero()) defer podmanTest.removeCNINetwork(netName1) netName2 := "testNetThreeCNI2" network2 := podmanTest.Podman([]string{"network", "create", netName2}) network2.WaitWithDefaultTimeout() Expect(network2.ExitCode()).To(BeZero()) defer podmanTest.removeCNINetwork(netName2) ctrName := "testCtr" container := podmanTest.Podman([]string{"create", "--network", fmt.Sprintf("%s,%s", netName1, netName2), "--name", ctrName, ALPINE, "top"}) container.WaitWithDefaultTimeout() Expect(container.ExitCode()).To(BeZero()) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(BeZero()) conData := inspect.InspectContainerToJSON() Expect(len(conData)).To(Equal(1)) Expect(len(conData[0].NetworkSettings.Networks)).To(Equal(2)) net1, ok := conData[0].NetworkSettings.Networks[netName1] Expect(ok).To(BeTrue()) Expect(net1.NetworkID).To(Equal(netName1)) net2, ok := conData[0].NetworkSettings.Networks[netName2] Expect(ok).To(BeTrue()) Expect(net2.NetworkID).To(Equal(netName2)) // Necessary to ensure the CNI network is removed cleanly rmAll := podmanTest.Podman([]string{"rm", "-f", ctrName}) rmAll.WaitWithDefaultTimeout() Expect(rmAll.ExitCode()).To(BeZero()) }) It("podman inspect container two CNI networks", func() { netName1 := "testNetTwoCNI1" network1 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.0/25", netName1}) network1.WaitWithDefaultTimeout() Expect(network1.ExitCode()).To(BeZero()) defer podmanTest.removeCNINetwork(netName1) netName2 := "testNetTwoCNI2" network2 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.128/26", netName2}) network2.WaitWithDefaultTimeout() Expect(network2.ExitCode()).To(BeZero()) defer podmanTest.removeCNINetwork(netName2) ctrName := "testCtr" container := podmanTest.Podman([]string{"run", "-dt", "--network", fmt.Sprintf("%s,%s", netName1, netName2), "--name", ctrName, ALPINE, "top"}) container.WaitWithDefaultTimeout() Expect(container.ExitCode()).To(BeZero()) inspect := podmanTest.Podman([]string{"inspect", ctrName}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(BeZero()) conData := inspect.InspectContainerToJSON() Expect(len(conData)).To(Equal(1)) Expect(len(conData[0].NetworkSettings.Networks)).To(Equal(2)) net1, ok := conData[0].NetworkSettings.Networks[netName1] Expect(ok).To(BeTrue()) Expect(net1.NetworkID).To(Equal(netName1)) Expect(net1.IPPrefixLen).To(Equal(25)) Expect(strings.HasPrefix(net1.IPAddress, "10.50.51.")).To(BeTrue()) net2, ok := conData[0].NetworkSettings.Networks[netName2] Expect(ok).To(BeTrue()) Expect(net2.NetworkID).To(Equal(netName2)) Expect(net2.IPPrefixLen).To(Equal(26)) Expect(strings.HasPrefix(net2.IPAddress, "10.50.51.")).To(BeTrue()) // Necessary to ensure the CNI network is removed cleanly rmAll := podmanTest.Podman([]string{"rm", "-f", ctrName}) rmAll.WaitWithDefaultTimeout() Expect(rmAll.ExitCode()).To(BeZero()) }) It("podman network remove bogus", func() { session := podmanTest.Podman([]string{"network", "rm", "bogus"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(1)) }) It("podman network remove --force with pod", func() { netName := "testnet" session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) defer podmanTest.removeCNINetwork(netName) session = podmanTest.Podman([]string{"pod", "create", "--network", netName}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) podID := session.OutputToString() session = podmanTest.Podman([]string{"create", "--pod", podID, ALPINE}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) session = podmanTest.Podman([]string{"network", "rm", netName}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(2)) session = podmanTest.Podman([]string{"network", "rm", "--force", netName}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) // check if pod is deleted session = podmanTest.Podman([]string{"pod", "exists", podID}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(1)) // check if net is deleted session = podmanTest.Podman([]string{"network", "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) Expect(session.OutputToString()).To(Not(ContainSubstring(netName))) }) It("podman network remove with two networks", func() { netName1 := "net1" session := podmanTest.Podman([]string{"network", "create", netName1}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) defer podmanTest.removeCNINetwork(netName1) netName2 := "net2" session = podmanTest.Podman([]string{"network", "create", netName2}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) defer podmanTest.removeCNINetwork(netName2) session = podmanTest.Podman([]string{"network", "rm", netName1, netName2}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) lines := session.OutputToStringArray() Expect(lines[0]).To(Equal(netName1)) Expect(lines[1]).To(Equal(netName2)) }) It("podman network with multiple aliases", func() { Skip("Until DNSName is updated on our CI images") var worked bool netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) defer podmanTest.removeCNINetwork(netName) top := podmanTest.Podman([]string{"run", "-dt", "--name=web", "--network=" + netName, "--network-alias=web1", "--network-alias=web2", nginx}) top.WaitWithDefaultTimeout() Expect(top.ExitCode()).To(BeZero()) interval := time.Duration(250 * time.Millisecond) // Wait for the nginx service to be running for i := 0; i < 6; i++ { // Test curl against the container's name c1 := podmanTest.Podman([]string{"run", "--network=" + netName, nginx, "curl", "web"}) c1.WaitWithDefaultTimeout() worked = Expect(c1.ExitCode()).To(BeZero()) if worked { break } time.Sleep(interval) interval *= 2 } Expect(worked).To(BeTrue()) // Nginx is now running so no need to do a loop // Test against the first alias c2 := podmanTest.Podman([]string{"run", "--network=" + netName, nginx, "curl", "web1"}) c2.WaitWithDefaultTimeout() Expect(c2.ExitCode()).To(BeZero()) // Test against the second alias c3 := podmanTest.Podman([]string{"run", "--network=" + netName, nginx, "curl", "web2"}) c3.WaitWithDefaultTimeout() Expect(c3.ExitCode()).To(BeZero()) }) })