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

     1  package integration
     2  
     3  import (
     4  	"fmt"
     5  
     6  	. "github.com/containers/podman/v5/test/utils"
     7  	"github.com/containers/storage/pkg/stringid"
     8  	. "github.com/onsi/ginkgo/v2"
     9  	. "github.com/onsi/gomega"
    10  	"github.com/onsi/gomega/types"
    11  )
    12  
    13  var _ = Describe("Podman network connect and disconnect", func() {
    14  
    15  	It("bad network name in disconnect should result in error", func() {
    16  		dis := podmanTest.Podman([]string{"network", "disconnect", "foobar", "test"})
    17  		dis.WaitWithDefaultTimeout()
    18  		Expect(dis).Should(ExitWithError(125, `no container with name or ID "test" found: no such container`))
    19  	})
    20  
    21  	It("bad container name in network disconnect should result in error", func() {
    22  		netName := "aliasTest" + stringid.GenerateRandomID()
    23  		session := podmanTest.Podman([]string{"network", "create", netName})
    24  		session.WaitWithDefaultTimeout()
    25  		Expect(session).Should(ExitCleanly())
    26  		defer podmanTest.removeNetwork(netName)
    27  
    28  		dis := podmanTest.Podman([]string{"network", "disconnect", netName, "foobar"})
    29  		dis.WaitWithDefaultTimeout()
    30  		Expect(dis).Should(ExitWithError(125, `no container with name or ID "foobar" found: no such container`))
    31  	})
    32  
    33  	It("network disconnect with net mode slirp4netns should result in error", func() {
    34  		netName := "slirp" + stringid.GenerateRandomID()
    35  		session := podmanTest.Podman([]string{"network", "create", netName})
    36  		session.WaitWithDefaultTimeout()
    37  		Expect(session).Should(ExitCleanly())
    38  		defer podmanTest.removeNetwork(netName)
    39  
    40  		session = podmanTest.Podman([]string{"create", "--name", "test", "--network", "slirp4netns", ALPINE})
    41  		session.WaitWithDefaultTimeout()
    42  		Expect(session).Should(ExitCleanly())
    43  		defer podmanTest.removeNetwork(netName)
    44  
    45  		con := podmanTest.Podman([]string{"network", "disconnect", netName, "test"})
    46  		con.WaitWithDefaultTimeout()
    47  		Expect(con).Should(ExitWithError(125, `"slirp4netns" is not supported: invalid network mode`))
    48  	})
    49  
    50  	It("podman network disconnect", func() {
    51  		SkipIfRootlessCgroupsV1("stats not supported under rootless CgroupsV1")
    52  		netName := "aliasTest" + stringid.GenerateRandomID()
    53  		session := podmanTest.Podman([]string{"network", "create", netName})
    54  		session.WaitWithDefaultTimeout()
    55  		Expect(session).Should(ExitCleanly())
    56  		defer podmanTest.removeNetwork(netName)
    57  
    58  		gw := podmanTest.Podman([]string{"network", "inspect", netName, "--format", "{{(index .Subnets 0).Gateway}}"})
    59  		gw.WaitWithDefaultTimeout()
    60  		Expect(gw).Should(ExitCleanly())
    61  		ns := gw.OutputToString()
    62  
    63  		ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netName, ALPINE, "top"})
    64  		ctr.WaitWithDefaultTimeout()
    65  		Expect(ctr).Should(ExitCleanly())
    66  
    67  		exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
    68  		exec.WaitWithDefaultTimeout()
    69  		Expect(exec).Should(ExitCleanly())
    70  
    71  		exec2 := podmanTest.Podman([]string{"exec", "test", "cat", "/etc/resolv.conf"})
    72  		exec2.WaitWithDefaultTimeout()
    73  		Expect(exec2).Should(ExitCleanly())
    74  		Expect(exec2.OutputToString()).To(ContainSubstring(ns))
    75  
    76  		dis := podmanTest.Podman([]string{"network", "disconnect", netName, "test"})
    77  		dis.WaitWithDefaultTimeout()
    78  		Expect(dis).Should(ExitCleanly())
    79  		Expect(dis.ErrorToString()).Should(Equal(""))
    80  
    81  		inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
    82  		inspect.WaitWithDefaultTimeout()
    83  		Expect(inspect).Should(ExitCleanly())
    84  		Expect(inspect.OutputToString()).To(Equal("0"))
    85  
    86  		exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
    87  		exec.WaitWithDefaultTimeout()
    88  		Expect(exec).Should(ExitWithError(1, "ip: can't find device 'eth0'"))
    89  
    90  		exec3 := podmanTest.Podman([]string{"exec", "test", "cat", "/etc/resolv.conf"})
    91  		exec3.WaitWithDefaultTimeout()
    92  		Expect(exec3).Should(ExitCleanly())
    93  		Expect(exec3.OutputToString()).ToNot(ContainSubstring(ns))
    94  
    95  		// make sure stats still works https://github.com/containers/podman/issues/13824
    96  		stats := podmanTest.Podman([]string{"stats", "test", "--no-stream"})
    97  		stats.WaitWithDefaultTimeout()
    98  		Expect(stats).Should(ExitCleanly())
    99  	})
   100  
   101  	It("bad network name in connect should result in error", func() {
   102  		session := podmanTest.Podman([]string{"create", "--name", "testContainer", "--network", "bridge", ALPINE})
   103  		session.WaitWithDefaultTimeout()
   104  		Expect(session).Should(ExitCleanly())
   105  
   106  		dis := podmanTest.Podman([]string{"network", "connect", "nonexistent-network", "testContainer"})
   107  		dis.WaitWithDefaultTimeout()
   108  		Expect(dis).Should(ExitWithError(125, "unable to find network with name or ID nonexistent-network: network not found"))
   109  	})
   110  
   111  	It("bad container name in network connect should result in error", func() {
   112  		netName := "aliasTest" + stringid.GenerateRandomID()
   113  		session := podmanTest.Podman([]string{"network", "create", netName})
   114  		session.WaitWithDefaultTimeout()
   115  		Expect(session).Should(ExitCleanly())
   116  		defer podmanTest.removeNetwork(netName)
   117  
   118  		dis := podmanTest.Podman([]string{"network", "connect", netName, "foobar"})
   119  		dis.WaitWithDefaultTimeout()
   120  		Expect(dis).Should(ExitWithError(125, `no container with name or ID "foobar" found: no such container`))
   121  	})
   122  
   123  	It("network connect with net mode slirp4netns should result in error", func() {
   124  		netName := "slirp" + stringid.GenerateRandomID()
   125  		session := podmanTest.Podman([]string{"network", "create", netName})
   126  		session.WaitWithDefaultTimeout()
   127  		Expect(session).Should(ExitCleanly())
   128  		defer podmanTest.removeNetwork(netName)
   129  
   130  		session = podmanTest.Podman([]string{"create", "--name", "test", "--network", "slirp4netns", ALPINE})
   131  		session.WaitWithDefaultTimeout()
   132  		Expect(session).Should(ExitCleanly())
   133  		defer podmanTest.removeNetwork(netName)
   134  
   135  		con := podmanTest.Podman([]string{"network", "connect", netName, "test"})
   136  		con.WaitWithDefaultTimeout()
   137  		Expect(con).Should(ExitWithError(125, `"slirp4netns" is not supported: invalid network mode`))
   138  	})
   139  
   140  	It("podman connect on a container that already is connected to the network should error after init", func() {
   141  		netName := "aliasTest" + stringid.GenerateRandomID()
   142  		session := podmanTest.Podman([]string{"network", "create", netName})
   143  		session.WaitWithDefaultTimeout()
   144  		Expect(session).Should(ExitCleanly())
   145  		defer podmanTest.removeNetwork(netName)
   146  
   147  		ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName, ALPINE, "top"})
   148  		ctr.WaitWithDefaultTimeout()
   149  		Expect(ctr).Should(ExitCleanly())
   150  		cid := ctr.OutputToString()
   151  
   152  		// network alias container short id is always added and shown in inspect
   153  		inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{(index .NetworkSettings.Networks \"" + netName + "\").Aliases}}"})
   154  		inspect.WaitWithDefaultTimeout()
   155  		Expect(inspect).Should(ExitCleanly())
   156  		Expect(inspect.OutputToString()).To(Equal("[" + cid[0:12] + "]"))
   157  
   158  		con := podmanTest.Podman([]string{"network", "connect", netName, "test"})
   159  		con.WaitWithDefaultTimeout()
   160  		Expect(con).Should(ExitCleanly())
   161  
   162  		init := podmanTest.Podman([]string{"init", "test"})
   163  		init.WaitWithDefaultTimeout()
   164  		Expect(init).Should(ExitCleanly())
   165  
   166  		con2 := podmanTest.Podman([]string{"network", "connect", netName, "test"})
   167  		con2.WaitWithDefaultTimeout()
   168  		if podmanTest.DatabaseBackend == "boltdb" {
   169  			Expect(con2).Should(ExitWithError(125, fmt.Sprintf("container %s is already connected to network %q: network is already connected", cid, netName)))
   170  		} else {
   171  			Expect(con2).Should(ExitWithError(125, fmt.Sprintf("container %s is already connected to network %s: network is already connected", cid, netName)))
   172  		}
   173  	})
   174  
   175  	It("podman network connect", func() {
   176  		SkipIfRootlessCgroupsV1("stats not supported under rootless CgroupsV1")
   177  		netName := "aliasTest" + stringid.GenerateRandomID()
   178  		session := podmanTest.Podman([]string{"network", "create", netName})
   179  		session.WaitWithDefaultTimeout()
   180  		Expect(session).Should(ExitCleanly())
   181  		defer podmanTest.removeNetwork(netName)
   182  
   183  		ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netName, ALPINE, "top"})
   184  		ctr.WaitWithDefaultTimeout()
   185  		Expect(ctr).Should(ExitCleanly())
   186  		cid := ctr.OutputToString()
   187  
   188  		exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
   189  		exec.WaitWithDefaultTimeout()
   190  		Expect(exec).Should(ExitCleanly())
   191  
   192  		// Create a second network
   193  		newNetName := "aliasTest" + stringid.GenerateRandomID()
   194  		session = podmanTest.Podman([]string{"network", "create", newNetName, "--subnet", "10.11.100.0/24"})
   195  		session.WaitWithDefaultTimeout()
   196  		Expect(session).Should(ExitCleanly())
   197  		defer podmanTest.removeNetwork(newNetName)
   198  
   199  		gw := podmanTest.Podman([]string{"network", "inspect", newNetName, "--format", "{{(index .Subnets 0).Gateway}}"})
   200  		gw.WaitWithDefaultTimeout()
   201  		Expect(gw).Should(ExitCleanly())
   202  		ns := gw.OutputToString()
   203  
   204  		exec2 := podmanTest.Podman([]string{"exec", "test", "cat", "/etc/resolv.conf"})
   205  		exec2.WaitWithDefaultTimeout()
   206  		Expect(exec2).Should(ExitCleanly())
   207  		Expect(exec2.OutputToString()).ToNot(ContainSubstring(ns))
   208  
   209  		ip := "10.11.100.99"
   210  		mac := "44:11:44:11:44:11"
   211  		connect := podmanTest.Podman([]string{"network", "connect", "--ip", ip, "--mac-address", mac, newNetName, "test"})
   212  		connect.WaitWithDefaultTimeout()
   213  		Expect(connect).Should(ExitCleanly())
   214  		Expect(connect.ErrorToString()).Should(Equal(""))
   215  
   216  		inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
   217  		inspect.WaitWithDefaultTimeout()
   218  		Expect(inspect).Should(ExitCleanly())
   219  		Expect(inspect.OutputToString()).To(Equal("2"))
   220  
   221  		// network alias container short id is always added and shown in inspect
   222  		inspect = podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{(index .NetworkSettings.Networks \"" + newNetName + "\").Aliases}}"})
   223  		inspect.WaitWithDefaultTimeout()
   224  		Expect(inspect).Should(ExitCleanly())
   225  		Expect(inspect.OutputToString()).To(Equal("[" + cid[0:12] + "]"))
   226  
   227  		exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth1"})
   228  		exec.WaitWithDefaultTimeout()
   229  		Expect(exec).Should(ExitCleanly())
   230  		Expect(exec.OutputToString()).Should(ContainSubstring(ip))
   231  		Expect(exec.OutputToString()).Should(ContainSubstring(mac))
   232  
   233  		exec3 := podmanTest.Podman([]string{"exec", "test", "cat", "/etc/resolv.conf"})
   234  		exec3.WaitWithDefaultTimeout()
   235  		Expect(exec3).Should(ExitCleanly())
   236  		Expect(exec3.OutputToString()).To(ContainSubstring(ns))
   237  
   238  		// make sure stats works https://github.com/containers/podman/issues/13824
   239  		stats := podmanTest.Podman([]string{"stats", "test", "--no-stream"})
   240  		stats.WaitWithDefaultTimeout()
   241  		Expect(stats).Should(ExitCleanly())
   242  
   243  		// make sure no logrus errors are shown https://github.com/containers/podman/issues/9602
   244  		rm := podmanTest.Podman([]string{"rm", "--time=0", "-f", "test"})
   245  		rm.WaitWithDefaultTimeout()
   246  		Expect(rm).Should(ExitCleanly())
   247  		Expect(rm.ErrorToString()).To(Equal(""))
   248  	})
   249  
   250  	It("podman network connect when not running", func() {
   251  		netName1 := "connect1" + stringid.GenerateRandomID()
   252  		session := podmanTest.Podman([]string{"network", "create", netName1})
   253  		session.WaitWithDefaultTimeout()
   254  		Expect(session).Should(ExitCleanly())
   255  		defer podmanTest.removeNetwork(netName1)
   256  
   257  		netName2 := "connect2" + stringid.GenerateRandomID()
   258  		session = podmanTest.Podman([]string{"network", "create", netName2})
   259  		session.WaitWithDefaultTimeout()
   260  		Expect(session).Should(ExitCleanly())
   261  		defer podmanTest.removeNetwork(netName2)
   262  
   263  		ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName1, ALPINE, "top"})
   264  		ctr.WaitWithDefaultTimeout()
   265  		Expect(ctr).Should(ExitCleanly())
   266  
   267  		dis := podmanTest.Podman([]string{"network", "connect", netName2, "test"})
   268  		dis.WaitWithDefaultTimeout()
   269  		Expect(dis).Should(ExitCleanly())
   270  
   271  		inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
   272  		inspect.WaitWithDefaultTimeout()
   273  		Expect(inspect).Should(ExitCleanly())
   274  		Expect(inspect.OutputToString()).To(Equal("2"))
   275  
   276  		start := podmanTest.Podman([]string{"start", "test"})
   277  		start.WaitWithDefaultTimeout()
   278  		Expect(start).Should(ExitCleanly())
   279  
   280  		exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
   281  		exec.WaitWithDefaultTimeout()
   282  		Expect(exec).Should(ExitCleanly())
   283  
   284  		exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth1"})
   285  		exec.WaitWithDefaultTimeout()
   286  		Expect(exec).Should(ExitCleanly())
   287  	})
   288  
   289  	It("podman network connect and run with network ID", func() {
   290  		netName := "ID" + stringid.GenerateRandomID()
   291  		session := podmanTest.Podman([]string{"network", "create", netName})
   292  		session.WaitWithDefaultTimeout()
   293  		Expect(session).Should(ExitCleanly())
   294  		defer podmanTest.removeNetwork(netName)
   295  
   296  		session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + netName})
   297  		session.WaitWithDefaultTimeout()
   298  		Expect(session).Should(ExitCleanly())
   299  		netID := session.OutputToString()
   300  
   301  		ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netID, "--network-alias", "somealias", ALPINE, "top"})
   302  		ctr.WaitWithDefaultTimeout()
   303  		Expect(ctr).Should(ExitCleanly())
   304  
   305  		exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
   306  		exec.WaitWithDefaultTimeout()
   307  		Expect(exec).Should(ExitCleanly())
   308  
   309  		// Create a second network
   310  		newNetName := "ID2" + stringid.GenerateRandomID()
   311  		session = podmanTest.Podman([]string{"network", "create", newNetName})
   312  		session.WaitWithDefaultTimeout()
   313  		Expect(session).Should(ExitCleanly())
   314  		defer podmanTest.removeNetwork(newNetName)
   315  
   316  		session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + newNetName})
   317  		session.WaitWithDefaultTimeout()
   318  		Expect(session).Should(ExitCleanly())
   319  		newNetID := session.OutputToString()
   320  
   321  		connect := podmanTest.Podman([]string{"network", "connect", "--alias", "secondalias", newNetID, "test"})
   322  		connect.WaitWithDefaultTimeout()
   323  		Expect(connect).Should(ExitCleanly())
   324  
   325  		inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{.NetworkSettings.Networks}}"})
   326  		inspect.WaitWithDefaultTimeout()
   327  		Expect(inspect).Should(ExitCleanly())
   328  		Expect(inspect.OutputToString()).To(ContainSubstring(netName))
   329  		Expect(inspect.OutputToString()).To(ContainSubstring(newNetName))
   330  
   331  		exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth1"})
   332  		exec.WaitWithDefaultTimeout()
   333  		Expect(exec).Should(ExitCleanly())
   334  	})
   335  
   336  	It("podman network disconnect when not running", func() {
   337  		netName1 := "aliasTest" + stringid.GenerateRandomID()
   338  		session := podmanTest.Podman([]string{"network", "create", netName1})
   339  		session.WaitWithDefaultTimeout()
   340  		Expect(session).Should(ExitCleanly())
   341  		defer podmanTest.removeNetwork(netName1)
   342  
   343  		netName2 := "aliasTest" + stringid.GenerateRandomID()
   344  		session2 := podmanTest.Podman([]string{"network", "create", netName2})
   345  		session2.WaitWithDefaultTimeout()
   346  		Expect(session2).Should(ExitCleanly())
   347  		defer podmanTest.removeNetwork(netName2)
   348  
   349  		ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName1 + "," + netName2, ALPINE, "top"})
   350  		ctr.WaitWithDefaultTimeout()
   351  		Expect(ctr).Should(ExitCleanly())
   352  
   353  		dis := podmanTest.Podman([]string{"network", "disconnect", netName1, "test"})
   354  		dis.WaitWithDefaultTimeout()
   355  		Expect(dis).Should(ExitCleanly())
   356  
   357  		inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
   358  		inspect.WaitWithDefaultTimeout()
   359  		Expect(inspect).Should(ExitCleanly())
   360  		Expect(inspect.OutputToString()).To(Equal("1"))
   361  
   362  		start := podmanTest.Podman([]string{"start", "test"})
   363  		start.WaitWithDefaultTimeout()
   364  		Expect(start).Should(ExitCleanly())
   365  
   366  		exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
   367  		exec.WaitWithDefaultTimeout()
   368  
   369  		// because the network interface order is not guaranteed to be the same, we have to check both eth0 and eth1.
   370  		// if eth0 did not exist, eth1 has to exist.
   371  		var exitMatcher types.GomegaMatcher = ExitWithError(1, "ip: can't find device 'eth1'")
   372  		if exec.ExitCode() > 0 {
   373  			Expect(exec).To(ExitWithError(1, "ip: can't find device 'eth0'"))
   374  			exitMatcher = ExitCleanly()
   375  		}
   376  
   377  		exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth1"})
   378  		exec.WaitWithDefaultTimeout()
   379  		Expect(exec).Should(exitMatcher)
   380  	})
   381  
   382  	It("podman network disconnect and run with network ID", func() {
   383  		netName := "aliasTest" + stringid.GenerateRandomID()
   384  		session := podmanTest.Podman([]string{"network", "create", netName})
   385  		session.WaitWithDefaultTimeout()
   386  		Expect(session).Should(ExitCleanly())
   387  		defer podmanTest.removeNetwork(netName)
   388  
   389  		session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + netName})
   390  		session.WaitWithDefaultTimeout()
   391  		Expect(session).Should(ExitCleanly())
   392  		netID := session.OutputToString()
   393  
   394  		ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netID, ALPINE, "top"})
   395  		ctr.WaitWithDefaultTimeout()
   396  		Expect(ctr).Should(ExitCleanly())
   397  
   398  		exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
   399  		exec.WaitWithDefaultTimeout()
   400  		Expect(exec).Should(ExitCleanly())
   401  
   402  		dis := podmanTest.Podman([]string{"network", "disconnect", netID, "test"})
   403  		dis.WaitWithDefaultTimeout()
   404  		Expect(dis).Should(ExitCleanly())
   405  
   406  		inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
   407  		inspect.WaitWithDefaultTimeout()
   408  		Expect(inspect).Should(ExitCleanly())
   409  		Expect(inspect.OutputToString()).To(Equal("0"))
   410  
   411  		exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
   412  		exec.WaitWithDefaultTimeout()
   413  		Expect(exec).Should(ExitWithError(1, "ip: can't find device 'eth0'"))
   414  	})
   415  })