github.com/containers/podman/v5@v5.1.0-rc1/test/e2e/network_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"path/filepath"
     7  	"time"
     8  
     9  	"github.com/containers/podman/v5/pkg/domain/entities"
    10  	. "github.com/containers/podman/v5/test/utils"
    11  	"github.com/containers/storage/pkg/stringid"
    12  	. "github.com/onsi/ginkgo/v2"
    13  	. "github.com/onsi/gomega"
    14  	. "github.com/onsi/gomega/gexec"
    15  )
    16  
    17  var _ = Describe("Podman network", func() {
    18  
    19  	It("podman --cni-config-dir backwards compat", func() {
    20  		SkipIfRemote("--cni-config-dir only works locally")
    21  		netDir := filepath.Join(podmanTest.TempDir, "networks123")
    22  		session := podmanTest.Podman([]string{"--cni-config-dir", netDir, "network", "ls", "--noheading"})
    23  		session.WaitWithDefaultTimeout()
    24  		Expect(session).Should(ExitCleanly())
    25  		// default network always exists
    26  		Expect(session.OutputToStringArray()).To(HaveLen(1))
    27  	})
    28  
    29  	It("podman network list", func() {
    30  		name, path := generateNetworkConfig(podmanTest)
    31  		defer removeConf(path)
    32  
    33  		session := podmanTest.Podman([]string{"network", "ls"})
    34  		session.WaitWithDefaultTimeout()
    35  		Expect(session).Should(ExitCleanly())
    36  		Expect(session.OutputToString()).To(ContainSubstring(name))
    37  	})
    38  
    39  	It("podman network list -q", func() {
    40  		name, path := generateNetworkConfig(podmanTest)
    41  		defer removeConf(path)
    42  
    43  		session := podmanTest.Podman([]string{"network", "ls", "--quiet"})
    44  		session.WaitWithDefaultTimeout()
    45  		Expect(session).Should(ExitCleanly())
    46  		Expect(session.OutputToString()).To(ContainSubstring(name))
    47  	})
    48  
    49  	It("podman network list --filter success", func() {
    50  		name, path := generateNetworkConfig(podmanTest)
    51  		defer removeConf(path)
    52  
    53  		session := podmanTest.Podman([]string{"network", "ls", "--filter", "driver=bridge"})
    54  		session.WaitWithDefaultTimeout()
    55  		// Cannot ExitCleanly(): "stat ~/.config/.../*.conflist: ENOENT"
    56  		Expect(session).Should(Exit(0))
    57  		Expect(session.OutputToString()).To(ContainSubstring(name))
    58  	})
    59  
    60  	It("podman network list --filter driver and name", func() {
    61  		name, path := generateNetworkConfig(podmanTest)
    62  		defer removeConf(path)
    63  
    64  		session := podmanTest.Podman([]string{"network", "ls", "--filter", "driver=bridge", "--filter", "name=" + name})
    65  		session.WaitWithDefaultTimeout()
    66  		Expect(session).Should(ExitCleanly())
    67  		Expect(session.OutputToString()).To(ContainSubstring(name))
    68  	})
    69  
    70  	It("podman network list --filter two names", func() {
    71  		name1, path1 := generateNetworkConfig(podmanTest)
    72  		defer removeConf(path1)
    73  
    74  		name2, path2 := generateNetworkConfig(podmanTest)
    75  		defer removeConf(path2)
    76  
    77  		session := podmanTest.Podman([]string{"network", "ls", "--filter", "name=" + name1, "--filter", "name=" + name2})
    78  		session.WaitWithDefaultTimeout()
    79  		Expect(session).Should(ExitCleanly())
    80  		Expect(session.OutputToString()).To(ContainSubstring(name1))
    81  		Expect(session.OutputToString()).To(ContainSubstring(name2))
    82  	})
    83  
    84  	It("podman network list --filter labels", func() {
    85  		net1 := "labelnet" + stringid.GenerateRandomID()
    86  		label1 := "testlabel1=abc"
    87  		label2 := "abcdef"
    88  		session := podmanTest.Podman([]string{"network", "create", "--label", label1, net1})
    89  		session.WaitWithDefaultTimeout()
    90  		defer podmanTest.removeNetwork(net1)
    91  		Expect(session).Should(ExitCleanly())
    92  
    93  		net2 := "labelnet" + stringid.GenerateRandomID()
    94  		session = podmanTest.Podman([]string{"network", "create", "--label", label1, "--label", label2, net2})
    95  		session.WaitWithDefaultTimeout()
    96  		defer podmanTest.removeNetwork(net2)
    97  		Expect(session).Should(ExitCleanly())
    98  
    99  		session = podmanTest.Podman([]string{"network", "ls", "--filter", "label=" + label1})
   100  		session.WaitWithDefaultTimeout()
   101  		Expect(session).Should(ExitCleanly())
   102  		Expect(session.OutputToString()).To(ContainSubstring(net1))
   103  		Expect(session.OutputToString()).To(ContainSubstring(net2))
   104  
   105  		session = podmanTest.Podman([]string{"network", "ls", "--filter", "label=" + label1, "--filter", "label=" + label2})
   106  		session.WaitWithDefaultTimeout()
   107  		Expect(session).Should(ExitCleanly())
   108  		Expect(session.OutputToString()).ToNot(ContainSubstring(net1))
   109  		Expect(session.OutputToString()).To(ContainSubstring(net2))
   110  	})
   111  
   112  	It("podman network list --filter invalid value", func() {
   113  		net := "net" + stringid.GenerateRandomID()
   114  		session := podmanTest.Podman([]string{"network", "create", net})
   115  		session.WaitWithDefaultTimeout()
   116  		defer podmanTest.removeNetwork(net)
   117  		Expect(session).Should(ExitCleanly())
   118  
   119  		session = podmanTest.Podman([]string{"network", "ls", "--filter", "namr=ab"})
   120  		session.WaitWithDefaultTimeout()
   121  		Expect(session).To(ExitWithError(125, `invalid filter "namr"`))
   122  	})
   123  
   124  	It("podman network list --filter failure", func() {
   125  		name, path := generateNetworkConfig(podmanTest)
   126  		defer removeConf(path)
   127  
   128  		session := podmanTest.Podman([]string{"network", "ls", "--filter", "label=abc"})
   129  		session.WaitWithDefaultTimeout()
   130  		Expect(session).Should(ExitCleanly())
   131  		Expect(session.OutputToString()).To(Not(ContainSubstring(name)))
   132  	})
   133  
   134  	It("podman network list --filter dangling", func() {
   135  		name, path := generateNetworkConfig(podmanTest)
   136  		defer removeConf(path)
   137  
   138  		session := podmanTest.Podman([]string{"network", "ls", "--filter", "dangling=true"})
   139  		session.WaitWithDefaultTimeout()
   140  		Expect(session).Should(ExitCleanly())
   141  		Expect(session.OutputToString()).To(ContainSubstring(name))
   142  
   143  		session = podmanTest.Podman([]string{"network", "ls", "--filter", "dangling=false"})
   144  		session.WaitWithDefaultTimeout()
   145  		Expect(session).Should(ExitCleanly())
   146  		Expect(session.OutputToString()).NotTo(ContainSubstring(name))
   147  
   148  		session = podmanTest.Podman([]string{"network", "ls", "--filter", "dangling=foo"})
   149  		session.WaitWithDefaultTimeout()
   150  		Expect(session).To(ExitWithError(125, `invalid dangling filter value "foo"`))
   151  	})
   152  
   153  	It("podman network ID test", func() {
   154  		net := "networkIDTest"
   155  		// the network id should be the sha256 hash of the network name
   156  		netID := "6073aefe03cdf8f29be5b23ea9795c431868a3a22066a6290b187691614fee84"
   157  		session := podmanTest.Podman([]string{"network", "create", net})
   158  		session.WaitWithDefaultTimeout()
   159  		defer podmanTest.removeNetwork(net)
   160  		Expect(session).Should(ExitCleanly())
   161  
   162  		if podmanTest.NetworkBackend == Netavark {
   163  			// netavark uses a different algo for determining the id and it is not repeatable
   164  			getid := podmanTest.Podman([]string{"network", "inspect", net, "--format", "{{.ID}}"})
   165  			getid.WaitWithDefaultTimeout()
   166  			Expect(getid).Should(ExitCleanly())
   167  			netID = getid.OutputToString()
   168  		}
   169  		// Tests Default Table Output
   170  		session = podmanTest.Podman([]string{"network", "ls", "--filter", "id=" + netID})
   171  		session.WaitWithDefaultTimeout()
   172  		Expect(session).Should(ExitCleanly())
   173  		expectedTable := "NETWORK ID NAME DRIVER"
   174  		Expect(session.OutputToString()).To(ContainSubstring(expectedTable))
   175  
   176  		session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}} {{.ID}}", "--filter", "id=" + netID})
   177  		session.WaitWithDefaultTimeout()
   178  		Expect(session).Should(ExitCleanly())
   179  		Expect(session.OutputToString()).To(ContainSubstring(net + " " + netID[:12]))
   180  
   181  		session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}} {{.ID}}", "--filter", "id=" + netID[:50], "--no-trunc"})
   182  		session.WaitWithDefaultTimeout()
   183  		Expect(session).Should(ExitCleanly())
   184  		Expect(session.OutputToString()).To(ContainSubstring(net + " " + netID))
   185  
   186  		session = podmanTest.Podman([]string{"network", "inspect", netID[:40]})
   187  		session.WaitWithDefaultTimeout()
   188  		Expect(session).Should(ExitCleanly())
   189  		Expect(session.OutputToString()).To(ContainSubstring(net))
   190  
   191  		session = podmanTest.Podman([]string{"network", "inspect", netID[1:]})
   192  		session.WaitWithDefaultTimeout()
   193  		expectMessage := fmt.Sprintf("network %s: ", netID[1:])
   194  		// FIXME-someday: figure out why this part does not show up in remote
   195  		if !IsRemote() {
   196  			expectMessage += fmt.Sprintf("unable to find network with name or ID %s: ", netID[1:])
   197  		}
   198  		expectMessage += "network not found"
   199  		Expect(session).Should(ExitWithError(125, expectMessage))
   200  
   201  		session = podmanTest.Podman([]string{"network", "rm", netID})
   202  		session.WaitWithDefaultTimeout()
   203  		Expect(session).Should(ExitCleanly())
   204  	})
   205  
   206  	rmFunc := func(rm string) {
   207  		It(fmt.Sprintf("podman network %s no args", rm), func() {
   208  			session := podmanTest.Podman([]string{"network", rm})
   209  			session.WaitWithDefaultTimeout()
   210  			Expect(session).Should(ExitWithError(125, "requires at least 1 arg(s), only received 0"))
   211  
   212  		})
   213  
   214  		It(fmt.Sprintf("podman network %s", rm), func() {
   215  			name, path := generateNetworkConfig(podmanTest)
   216  			defer removeConf(path)
   217  
   218  			session := podmanTest.Podman([]string{"network", "ls", "--quiet"})
   219  			session.WaitWithDefaultTimeout()
   220  			Expect(session).Should(ExitCleanly())
   221  			Expect(session.OutputToString()).To(ContainSubstring(name))
   222  
   223  			rm := podmanTest.Podman([]string{"network", rm, name})
   224  			rm.WaitWithDefaultTimeout()
   225  			Expect(rm).Should(ExitCleanly())
   226  
   227  			results := podmanTest.Podman([]string{"network", "ls", "--quiet"})
   228  			results.WaitWithDefaultTimeout()
   229  			Expect(results).Should(ExitCleanly())
   230  			Expect(results.OutputToString()).To(Not(ContainSubstring(name)))
   231  		})
   232  	}
   233  
   234  	rmFunc("rm")
   235  	rmFunc("remove")
   236  
   237  	It("podman network inspect no args", func() {
   238  		session := podmanTest.Podman([]string{"network", "inspect"})
   239  		session.WaitWithDefaultTimeout()
   240  		Expect(session).Should(ExitWithError(125, "requires at least 1 arg(s), only received 0"))
   241  	})
   242  
   243  	It("podman network inspect", func() {
   244  		name, path := generateNetworkConfig(podmanTest)
   245  		defer removeConf(path)
   246  
   247  		expectedNetworks := []string{name}
   248  		if !isRootless() {
   249  			// rootful image contains "podman/cni/87-podman-bridge.conflist" for "podman" network
   250  			expectedNetworks = append(expectedNetworks, "podman")
   251  		}
   252  		session := podmanTest.Podman(append([]string{"network", "inspect"}, expectedNetworks...))
   253  		session.WaitWithDefaultTimeout()
   254  		Expect(session).Should(ExitCleanly())
   255  		Expect(session.OutputToString()).To(BeValidJSON())
   256  	})
   257  
   258  	It("podman network inspect", func() {
   259  		name, path := generateNetworkConfig(podmanTest)
   260  		defer removeConf(path)
   261  
   262  		session := podmanTest.Podman([]string{"network", "inspect", name, "--format", "{{.Driver}}"})
   263  		session.WaitWithDefaultTimeout()
   264  		Expect(session).Should(ExitCleanly())
   265  		Expect(session.OutputToString()).To(ContainSubstring("bridge"))
   266  	})
   267  
   268  	It("podman inspect container single CNI network", func() {
   269  		netName := "net-" + stringid.GenerateRandomID()
   270  		network := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.50.0/24", netName})
   271  		network.WaitWithDefaultTimeout()
   272  		defer podmanTest.removeNetwork(netName)
   273  		Expect(network).Should(ExitCleanly())
   274  
   275  		ctrName := "testCtr"
   276  		container := podmanTest.Podman([]string{"run", "-dt", "--network", netName, "--name", ctrName, ALPINE, "top"})
   277  		container.WaitWithDefaultTimeout()
   278  		Expect(container).Should(ExitCleanly())
   279  
   280  		inspect := podmanTest.Podman([]string{"inspect", ctrName})
   281  		inspect.WaitWithDefaultTimeout()
   282  		Expect(inspect).Should(ExitCleanly())
   283  		conData := inspect.InspectContainerToJSON()
   284  		Expect(conData).To(HaveLen(1))
   285  		Expect(conData[0].NetworkSettings.Networks).To(HaveLen(1))
   286  		Expect(conData[0].NetworkSettings.Networks).To(HaveKey(netName))
   287  		net := conData[0].NetworkSettings.Networks[netName]
   288  		Expect(net).To(HaveField("NetworkID", netName))
   289  		Expect(net).To(HaveField("IPPrefixLen", 24))
   290  		Expect(net.IPAddress).To(HavePrefix("10.50.50."))
   291  
   292  		// Necessary to ensure the CNI network is removed cleanly
   293  		rmAll := podmanTest.Podman([]string{"rm", "-t", "0", "-f", ctrName})
   294  		rmAll.WaitWithDefaultTimeout()
   295  		Expect(rmAll).Should(ExitCleanly())
   296  	})
   297  
   298  	It("podman inspect container two CNI networks (container not running)", func() {
   299  		netName1 := "net1-" + stringid.GenerateRandomID()
   300  		network1 := podmanTest.Podman([]string{"network", "create", netName1})
   301  		network1.WaitWithDefaultTimeout()
   302  		defer podmanTest.removeNetwork(netName1)
   303  		Expect(network1).Should(ExitCleanly())
   304  
   305  		netName2 := "net2-" + stringid.GenerateRandomID()
   306  		network2 := podmanTest.Podman([]string{"network", "create", netName2})
   307  		network2.WaitWithDefaultTimeout()
   308  		defer podmanTest.removeNetwork(netName2)
   309  		Expect(network2).Should(ExitCleanly())
   310  
   311  		ctrName := "testCtr"
   312  		container := podmanTest.Podman([]string{"create", "--network", fmt.Sprintf("%s,%s", netName1, netName2), "--name", ctrName, ALPINE, "top"})
   313  		container.WaitWithDefaultTimeout()
   314  		Expect(container).Should(ExitCleanly())
   315  
   316  		inspect := podmanTest.Podman([]string{"inspect", ctrName})
   317  		inspect.WaitWithDefaultTimeout()
   318  		Expect(inspect).Should(ExitCleanly())
   319  		conData := inspect.InspectContainerToJSON()
   320  		Expect(conData).To(HaveLen(1))
   321  		Expect(conData[0].NetworkSettings.Networks).To(HaveLen(2))
   322  		Expect(conData[0].NetworkSettings.Networks).To(HaveKey(netName1))
   323  		Expect(conData[0].NetworkSettings.Networks).To(HaveKey(netName2))
   324  		net1 := conData[0].NetworkSettings.Networks[netName1]
   325  		Expect(net1).To(HaveField("NetworkID", netName1))
   326  		net2 := conData[0].NetworkSettings.Networks[netName2]
   327  		Expect(net2).To(HaveField("NetworkID", netName2))
   328  
   329  		// Necessary to ensure the CNI network is removed cleanly
   330  		rmAll := podmanTest.Podman([]string{"rm", "-t", "0", "-f", ctrName})
   331  		rmAll.WaitWithDefaultTimeout()
   332  		Expect(rmAll).Should(ExitCleanly())
   333  	})
   334  
   335  	It("podman inspect container two CNI networks", func() {
   336  		netName1 := "net1-" + stringid.GenerateRandomID()
   337  		network1 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.0/25", netName1})
   338  		network1.WaitWithDefaultTimeout()
   339  		defer podmanTest.removeNetwork(netName1)
   340  		Expect(network1).Should(ExitCleanly())
   341  
   342  		netName2 := "net2-" + stringid.GenerateRandomID()
   343  		network2 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.128/26", netName2})
   344  		network2.WaitWithDefaultTimeout()
   345  		defer podmanTest.removeNetwork(netName2)
   346  		Expect(network2).Should(ExitCleanly())
   347  
   348  		ctrName := "testCtr"
   349  		container := podmanTest.Podman([]string{"run", "-dt", "--network", fmt.Sprintf("%s,%s", netName1, netName2), "--name", ctrName, ALPINE, "top"})
   350  		container.WaitWithDefaultTimeout()
   351  		Expect(container).Should(ExitCleanly())
   352  
   353  		inspect := podmanTest.Podman([]string{"inspect", ctrName})
   354  		inspect.WaitWithDefaultTimeout()
   355  		Expect(inspect).Should(ExitCleanly())
   356  		conData := inspect.InspectContainerToJSON()
   357  		Expect(conData).To(HaveLen(1))
   358  		Expect(conData[0].NetworkSettings.Networks).To(HaveLen(2))
   359  		Expect(conData[0].NetworkSettings.Networks).To(HaveKey(netName1))
   360  		Expect(conData[0].NetworkSettings.Networks).To(HaveKey(netName2))
   361  		net1 := conData[0].NetworkSettings.Networks[netName1]
   362  		Expect(net1).To(HaveField("NetworkID", netName1))
   363  		Expect(net1).To(HaveField("IPPrefixLen", 25))
   364  		Expect(net1.IPAddress).To(HavePrefix("10.50.51."))
   365  		net2 := conData[0].NetworkSettings.Networks[netName2]
   366  		Expect(net2).To(HaveField("NetworkID", netName2))
   367  		Expect(net2).To(HaveField("IPPrefixLen", 26))
   368  		Expect(net2.IPAddress).To(HavePrefix("10.50.51."))
   369  
   370  		// Necessary to ensure the CNI network is removed cleanly
   371  		rmAll := podmanTest.Podman([]string{"rm", "-t", "0", "-f", ctrName})
   372  		rmAll.WaitWithDefaultTimeout()
   373  		Expect(rmAll).Should(ExitCleanly())
   374  	})
   375  
   376  	It("podman network remove after disconnect when container initially created with the network", func() {
   377  		container := "test"
   378  		network := "foo" + stringid.GenerateRandomID()
   379  
   380  		session := podmanTest.Podman([]string{"network", "create", network})
   381  		session.WaitWithDefaultTimeout()
   382  		defer podmanTest.removeNetwork(network)
   383  		Expect(session).Should(ExitCleanly())
   384  
   385  		session = podmanTest.Podman([]string{"run", "--name", container, "--network", network, "-d", ALPINE, "top"})
   386  		session.WaitWithDefaultTimeout()
   387  		Expect(session).Should(ExitCleanly())
   388  
   389  		session = podmanTest.Podman([]string{"network", "disconnect", network, container})
   390  		session.WaitWithDefaultTimeout()
   391  		Expect(session).Should(ExitCleanly())
   392  
   393  		session = podmanTest.Podman([]string{"network", "rm", network})
   394  		session.WaitWithDefaultTimeout()
   395  		Expect(session).Should(ExitCleanly())
   396  	})
   397  
   398  	It("podman network remove bogus", func() {
   399  		session := podmanTest.Podman([]string{"network", "rm", "bogus"})
   400  		session.WaitWithDefaultTimeout()
   401  		Expect(session).Should(ExitWithError(1, "unable to find network with name or ID bogus: network not found"))
   402  	})
   403  
   404  	It("podman network remove --force with pod", func() {
   405  		netName := "net-" + stringid.GenerateRandomID()
   406  		session := podmanTest.Podman([]string{"network", "create", netName})
   407  		session.WaitWithDefaultTimeout()
   408  		defer podmanTest.removeNetwork(netName)
   409  		Expect(session).Should(ExitCleanly())
   410  
   411  		session = podmanTest.Podman([]string{"pod", "create", "--network", netName})
   412  		session.WaitWithDefaultTimeout()
   413  		Expect(session).Should(ExitCleanly())
   414  		podID := session.OutputToString()
   415  
   416  		session = podmanTest.Podman([]string{"create", "--pod", podID, ALPINE})
   417  		session.WaitWithDefaultTimeout()
   418  		Expect(session).Should(ExitCleanly())
   419  
   420  		session = podmanTest.Podman([]string{"network", "rm", netName})
   421  		session.WaitWithDefaultTimeout()
   422  		Expect(session).Should(ExitWithError(2, fmt.Sprintf(`"%s" has associated containers with it. Use -f to forcibly delete containers and pods: network is being used`, netName)))
   423  
   424  		session = podmanTest.Podman([]string{"network", "rm", "-t", "0", "--force", netName})
   425  		session.WaitWithDefaultTimeout()
   426  		Expect(session).Should(ExitCleanly())
   427  
   428  		// check if pod is deleted
   429  		session = podmanTest.Podman([]string{"pod", "exists", podID})
   430  		session.WaitWithDefaultTimeout()
   431  		Expect(session).Should(Exit(1))
   432  		Expect(session.ErrorToString()).To(Equal(""))
   433  
   434  		// check if net is deleted
   435  		session = podmanTest.Podman([]string{"network", "ls"})
   436  		session.WaitWithDefaultTimeout()
   437  		Expect(session).Should(ExitCleanly())
   438  		Expect(session.OutputToString()).To(Not(ContainSubstring(netName)))
   439  	})
   440  
   441  	It("podman network remove with two networks", func() {
   442  		netName1 := "net1-" + stringid.GenerateRandomID()
   443  		session := podmanTest.Podman([]string{"network", "create", netName1})
   444  		session.WaitWithDefaultTimeout()
   445  		defer podmanTest.removeNetwork(netName1)
   446  		Expect(session).Should(ExitCleanly())
   447  
   448  		netName2 := "net2-" + stringid.GenerateRandomID()
   449  		session = podmanTest.Podman([]string{"network", "create", netName2})
   450  		session.WaitWithDefaultTimeout()
   451  		defer podmanTest.removeNetwork(netName2)
   452  		Expect(session).Should(ExitCleanly())
   453  
   454  		session = podmanTest.Podman([]string{"network", "rm", netName1, netName2})
   455  		session.WaitWithDefaultTimeout()
   456  		Expect(session).Should(ExitCleanly())
   457  		lines := session.OutputToStringArray()
   458  		Expect(lines[0]).To(Equal(netName1))
   459  		Expect(lines[1]).To(Equal(netName2))
   460  	})
   461  
   462  	It("podman network with multiple aliases", func() {
   463  		var worked bool
   464  		netName := createNetworkName("aliasTest")
   465  		session := podmanTest.Podman([]string{"network", "create", netName})
   466  		session.WaitWithDefaultTimeout()
   467  		defer podmanTest.removeNetwork(netName)
   468  		Expect(session).Should(ExitCleanly())
   469  
   470  		interval := 250 * time.Millisecond
   471  		for i := 0; i < 6; i++ {
   472  			n := podmanTest.Podman([]string{"network", "exists", netName})
   473  			n.WaitWithDefaultTimeout()
   474  			worked = n.ExitCode() == 0
   475  			if worked {
   476  				break
   477  			}
   478  			time.Sleep(interval)
   479  			interval *= 2
   480  		}
   481  
   482  		top := podmanTest.Podman([]string{"run", "-dt", "--name=web", "--network=" + netName, "--network-alias=web1", "--network-alias=web2", NGINX_IMAGE})
   483  		top.WaitWithDefaultTimeout()
   484  		Expect(top).Should(ExitCleanly())
   485  		interval = 250 * time.Millisecond
   486  		// Wait for the nginx service to be running
   487  		for i := 0; i < 6; i++ {
   488  			// Test curl against the container's name
   489  			c1 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, NGINX_IMAGE, "curl", "web"})
   490  			c1.WaitWithDefaultTimeout()
   491  			worked = c1.ExitCode() == 0
   492  			if worked {
   493  				break
   494  			}
   495  			time.Sleep(interval)
   496  			interval *= 2
   497  		}
   498  		Expect(worked).To(BeTrue(), "nginx came up")
   499  
   500  		// Nginx is now running so no need to do a loop
   501  		// Test against the first alias
   502  		c2 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, NGINX_IMAGE, "curl", "-s", "web1"})
   503  		c2.WaitWithDefaultTimeout()
   504  		Expect(c2).Should(ExitCleanly())
   505  
   506  		// Test against the second alias
   507  		c3 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, NGINX_IMAGE, "curl", "-s", "web2"})
   508  		c3.WaitWithDefaultTimeout()
   509  		Expect(c3).Should(ExitCleanly())
   510  	})
   511  
   512  	It("podman network create/remove macvlan", func() {
   513  		net := "macvlan" + stringid.GenerateRandomID()
   514  		nc := podmanTest.Podman([]string{"network", "create", "--macvlan", "lo", net})
   515  		nc.WaitWithDefaultTimeout()
   516  		defer podmanTest.removeNetwork(net)
   517  		// Cannot ExitCleanly(): "The --macvlan option is deprecated..."
   518  		Expect(nc).Should(Exit(0))
   519  
   520  		nc = podmanTest.Podman([]string{"network", "rm", net})
   521  		nc.WaitWithDefaultTimeout()
   522  		Expect(nc).Should(ExitCleanly())
   523  	})
   524  
   525  	It("podman network create/remove macvlan as driver (-d) no device name", func() {
   526  		net := "macvlan" + stringid.GenerateRandomID()
   527  		nc := podmanTest.Podman([]string{"network", "create", "-d", "macvlan", net})
   528  		nc.WaitWithDefaultTimeout()
   529  		defer podmanTest.removeNetwork(net)
   530  		Expect(nc).Should(ExitCleanly())
   531  
   532  		inspect := podmanTest.Podman([]string{"network", "inspect", net})
   533  		inspect.WaitWithDefaultTimeout()
   534  		Expect(inspect).Should(ExitCleanly())
   535  
   536  		// JSON the network configuration into something usable
   537  		var results []entities.NetworkInspectReport
   538  		err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
   539  		Expect(err).ToNot(HaveOccurred())
   540  		Expect(results).To(HaveLen(1))
   541  		result := results[0]
   542  		Expect(result).To(HaveField("NetworkInterface", ""))
   543  		Expect(result.IPAMOptions).To(HaveKeyWithValue("driver", "dhcp"))
   544  
   545  		nc = podmanTest.Podman([]string{"network", "rm", net})
   546  		nc.WaitWithDefaultTimeout()
   547  		Expect(nc).Should(ExitCleanly())
   548  	})
   549  
   550  	for _, opt := range []string{"-o=parent=lo", "--interface-name=lo"} {
   551  		opt := opt
   552  		It(fmt.Sprintf("podman network create/remove macvlan as driver (-d) with %s", opt), func() {
   553  			net := "macvlan" + stringid.GenerateRandomID()
   554  			nc := podmanTest.Podman([]string{"network", "create", "-d", "macvlan", opt, net})
   555  			nc.WaitWithDefaultTimeout()
   556  			defer podmanTest.removeNetwork(net)
   557  			Expect(nc).Should(ExitCleanly())
   558  
   559  			inspect := podmanTest.Podman([]string{"network", "inspect", net})
   560  			inspect.WaitWithDefaultTimeout()
   561  			Expect(inspect).Should(ExitCleanly())
   562  
   563  			var results []entities.NetworkInspectReport
   564  			err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
   565  			Expect(err).ToNot(HaveOccurred())
   566  			Expect(results).To(HaveLen(1))
   567  			result := results[0]
   568  
   569  			Expect(result).To(HaveField("Driver", "macvlan"))
   570  			Expect(result).To(HaveField("NetworkInterface", "lo"))
   571  			Expect(result.IPAMOptions).To(HaveKeyWithValue("driver", "dhcp"))
   572  			Expect(result.Subnets).To(BeEmpty())
   573  
   574  			nc = podmanTest.Podman([]string{"network", "rm", net})
   575  			nc.WaitWithDefaultTimeout()
   576  			Expect(nc).Should(ExitCleanly())
   577  		})
   578  	}
   579  
   580  	It("podman network create/remove ipvlan as driver (-d) with device name", func() {
   581  		net := "ipvlan" + stringid.GenerateRandomID()
   582  		nc := podmanTest.Podman([]string{"network", "create", "-d", "ipvlan", "-o", "parent=lo", "--subnet", "10.0.2.0/24", net})
   583  		nc.WaitWithDefaultTimeout()
   584  		defer podmanTest.removeNetwork(net)
   585  		Expect(nc).Should(ExitCleanly())
   586  
   587  		inspect := podmanTest.Podman([]string{"network", "inspect", net})
   588  		inspect.WaitWithDefaultTimeout()
   589  		Expect(inspect).Should(ExitCleanly())
   590  
   591  		var results []entities.NetworkInspectReport
   592  		err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
   593  		Expect(err).ToNot(HaveOccurred())
   594  		Expect(results).To(HaveLen(1))
   595  		result := results[0]
   596  
   597  		Expect(result).To(HaveField("Driver", "ipvlan"))
   598  		Expect(result).To(HaveField("NetworkInterface", "lo"))
   599  		Expect(result.IPAMOptions).To(HaveKeyWithValue("driver", "host-local"))
   600  		Expect(result.Subnets).To(HaveLen(1))
   601  
   602  		nc = podmanTest.Podman([]string{"network", "rm", net})
   603  		nc.WaitWithDefaultTimeout()
   604  		Expect(nc).Should(ExitCleanly())
   605  	})
   606  
   607  	It("podman network exists", func() {
   608  		net := "net" + stringid.GenerateRandomID()
   609  		session := podmanTest.Podman([]string{"network", "create", net})
   610  		session.WaitWithDefaultTimeout()
   611  		defer podmanTest.removeNetwork(net)
   612  		Expect(session).Should(ExitCleanly())
   613  
   614  		session = podmanTest.Podman([]string{"network", "exists", net})
   615  		session.WaitWithDefaultTimeout()
   616  		Expect(session).Should(ExitCleanly())
   617  
   618  		session = podmanTest.Podman([]string{"network", "exists", stringid.GenerateRandomID()})
   619  		session.WaitWithDefaultTimeout()
   620  		Expect(session).Should(Exit(1))
   621  		Expect(session.ErrorToString()).To(Equal(""))
   622  	})
   623  
   624  	It("podman network create macvlan with network info and options", func() {
   625  		net := "macvlan" + stringid.GenerateRandomID()
   626  		nc := podmanTest.Podman([]string{"network", "create", "-d", "macvlan", "-o", "parent=lo", "-o", "mtu=1500", "--gateway", "192.168.1.254", "--subnet", "192.168.1.0/24", net})
   627  		nc.WaitWithDefaultTimeout()
   628  		defer podmanTest.removeNetwork(net)
   629  		Expect(nc).Should(ExitCleanly())
   630  
   631  		inspect := podmanTest.Podman([]string{"network", "inspect", net})
   632  		inspect.WaitWithDefaultTimeout()
   633  		Expect(inspect).Should(ExitCleanly())
   634  
   635  		var results []entities.NetworkInspectReport
   636  		err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
   637  		Expect(err).ToNot(HaveOccurred())
   638  		Expect(results).To(HaveLen(1))
   639  		result := results[0]
   640  
   641  		Expect(result.Options).To(HaveKeyWithValue("mtu", "1500"))
   642  		Expect(result).To(HaveField("Driver", "macvlan"))
   643  		Expect(result).To(HaveField("NetworkInterface", "lo"))
   644  		Expect(result.IPAMOptions).To(HaveKeyWithValue("driver", "host-local"))
   645  
   646  		Expect(result.Subnets).To(HaveLen(1))
   647  		Expect(result.Subnets[0].Subnet.String()).To(Equal("192.168.1.0/24"))
   648  		Expect(result.Subnets[0].Gateway.String()).To(Equal("192.168.1.254"))
   649  
   650  		nc = podmanTest.Podman([]string{"network", "rm", net})
   651  		nc.WaitWithDefaultTimeout()
   652  		Expect(nc).Should(ExitCleanly())
   653  	})
   654  
   655  	It("podman network prune --filter", func() {
   656  		useCustomNetworkDir(podmanTest, tempdir)
   657  		net1 := "macvlan" + stringid.GenerateRandomID() + "net1"
   658  
   659  		nc := podmanTest.Podman([]string{"network", "create", net1})
   660  		nc.WaitWithDefaultTimeout()
   661  		defer podmanTest.removeNetwork(net1)
   662  		Expect(nc).Should(ExitCleanly())
   663  
   664  		list := podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"})
   665  		list.WaitWithDefaultTimeout()
   666  		Expect(list).Should(ExitCleanly())
   667  		Expect(list.OutputToStringArray()).Should(HaveLen(2))
   668  
   669  		Expect(list.OutputToStringArray()).Should(ContainElement(net1))
   670  		Expect(list.OutputToStringArray()).Should(ContainElement("podman"))
   671  
   672  		// -f needed only to skip y/n question
   673  		prune := podmanTest.Podman([]string{"network", "prune", "-f", "--filter", "until=50"})
   674  		prune.WaitWithDefaultTimeout()
   675  		Expect(prune).Should(ExitCleanly())
   676  
   677  		listAgain := podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"})
   678  		listAgain.WaitWithDefaultTimeout()
   679  		Expect(listAgain).Should(ExitCleanly())
   680  		Expect(listAgain.OutputToStringArray()).Should(HaveLen(2))
   681  
   682  		Expect(listAgain.OutputToStringArray()).Should(ContainElement(net1))
   683  		Expect(listAgain.OutputToStringArray()).Should(ContainElement("podman"))
   684  
   685  		// -f needed only to skip y/n question
   686  		prune = podmanTest.Podman([]string{"network", "prune", "-f", "--filter", "until=5000000000000"})
   687  		prune.WaitWithDefaultTimeout()
   688  		Expect(prune).Should(ExitCleanly())
   689  
   690  		listAgain = podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"})
   691  		listAgain.WaitWithDefaultTimeout()
   692  		Expect(listAgain).Should(ExitCleanly())
   693  		Expect(listAgain.OutputToStringArray()).Should(HaveLen(1))
   694  
   695  		Expect(listAgain.OutputToStringArray()).ShouldNot(ContainElement(net1))
   696  		Expect(listAgain.OutputToStringArray()).Should(ContainElement("podman"))
   697  	})
   698  
   699  	It("podman network prune", func() {
   700  		useCustomNetworkDir(podmanTest, tempdir)
   701  		// Create two networks
   702  		// Check they are there
   703  		// Run a container on one of them
   704  		// Network Prune
   705  		// Check that one has been pruned, other remains
   706  		net := "macvlan" + stringid.GenerateRandomID()
   707  		net1 := net + "1"
   708  		net2 := net + "2"
   709  		nc := podmanTest.Podman([]string{"network", "create", net1})
   710  		nc.WaitWithDefaultTimeout()
   711  		defer podmanTest.removeNetwork(net1)
   712  		Expect(nc).Should(ExitCleanly())
   713  
   714  		nc2 := podmanTest.Podman([]string{"network", "create", net2})
   715  		nc2.WaitWithDefaultTimeout()
   716  		defer podmanTest.removeNetwork(net2)
   717  		Expect(nc2).Should(ExitCleanly())
   718  
   719  		list := podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"})
   720  		list.WaitWithDefaultTimeout()
   721  		Expect(list.OutputToStringArray()).Should(HaveLen(3))
   722  
   723  		Expect(list.OutputToStringArray()).Should(ContainElement(net1))
   724  		Expect(list.OutputToStringArray()).Should(ContainElement(net2))
   725  		Expect(list.OutputToStringArray()).Should(ContainElement("podman"))
   726  
   727  		session := podmanTest.Podman([]string{"run", "-dt", "--net", net2, ALPINE, "top"})
   728  		session.WaitWithDefaultTimeout()
   729  		Expect(session).Should(ExitCleanly())
   730  
   731  		prune := podmanTest.Podman([]string{"network", "prune", "-f"})
   732  		prune.WaitWithDefaultTimeout()
   733  		Expect(prune).Should(ExitCleanly())
   734  
   735  		listAgain := podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"})
   736  		listAgain.WaitWithDefaultTimeout()
   737  		Expect(listAgain).Should(ExitCleanly())
   738  		Expect(listAgain.OutputToStringArray()).Should(HaveLen(2))
   739  
   740  		Expect(listAgain.OutputToStringArray()).ShouldNot(ContainElement(net1))
   741  		Expect(listAgain.OutputToStringArray()).Should(ContainElement(net2))
   742  		Expect(listAgain.OutputToStringArray()).Should(ContainElement("podman"))
   743  	})
   744  })