4
. "github.com/containers/podman/v5/test/utils"
5
"github.com/containers/storage/pkg/stringid"
6
. "github.com/onsi/ginkgo/v2"
7
. "github.com/onsi/gomega"
8
. "github.com/onsi/gomega/gexec"
9
"github.com/onsi/gomega/types"
12
var _ = Describe("Podman network connect and disconnect", func() {
14
It("bad network name in disconnect should result in error", func() {
15
dis := podmanTest.Podman([]string{"network", "disconnect", "foobar", "test"})
16
dis.WaitWithDefaultTimeout()
17
Expect(dis).Should(ExitWithError())
20
It("bad container name in network disconnect should result in error", func() {
21
netName := "aliasTest" + stringid.GenerateRandomID()
22
session := podmanTest.Podman([]string{"network", "create", netName})
23
session.WaitWithDefaultTimeout()
24
Expect(session).Should(ExitCleanly())
25
defer podmanTest.removeNetwork(netName)
27
dis := podmanTest.Podman([]string{"network", "disconnect", netName, "foobar"})
28
dis.WaitWithDefaultTimeout()
29
Expect(dis).Should(ExitWithError())
32
It("network disconnect with net mode slirp4netns should result in error", func() {
33
netName := "slirp" + stringid.GenerateRandomID()
34
session := podmanTest.Podman([]string{"network", "create", netName})
35
session.WaitWithDefaultTimeout()
36
Expect(session).Should(ExitCleanly())
37
defer podmanTest.removeNetwork(netName)
39
session = podmanTest.Podman([]string{"create", "--name", "test", "--network", "slirp4netns", ALPINE})
40
session.WaitWithDefaultTimeout()
41
Expect(session).Should(ExitCleanly())
42
defer podmanTest.removeNetwork(netName)
44
con := podmanTest.Podman([]string{"network", "disconnect", netName, "test"})
45
con.WaitWithDefaultTimeout()
46
Expect(con).Should(ExitWithError())
47
Expect(con.ErrorToString()).To(ContainSubstring(`"slirp4netns" is not supported: invalid network mode`))
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)
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()
63
ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netName, ALPINE, "top"})
64
ctr.WaitWithDefaultTimeout()
65
Expect(ctr).Should(ExitCleanly())
67
exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
68
exec.WaitWithDefaultTimeout()
69
Expect(exec).Should(ExitCleanly())
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))
76
dis := podmanTest.Podman([]string{"network", "disconnect", netName, "test"})
77
dis.WaitWithDefaultTimeout()
78
Expect(dis).Should(ExitCleanly())
79
Expect(dis.ErrorToString()).Should(Equal(""))
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"))
86
exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
87
exec.WaitWithDefaultTimeout()
88
Expect(exec).Should(ExitWithError())
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))
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())
101
It("bad network name in connect should result in error", func() {
102
dis := podmanTest.Podman([]string{"network", "connect", "foobar", "test"})
103
dis.WaitWithDefaultTimeout()
104
Expect(dis).Should(ExitWithError())
107
It("bad container name in network connect should result in error", func() {
108
netName := "aliasTest" + stringid.GenerateRandomID()
109
session := podmanTest.Podman([]string{"network", "create", netName})
110
session.WaitWithDefaultTimeout()
111
Expect(session).Should(ExitCleanly())
112
defer podmanTest.removeNetwork(netName)
114
dis := podmanTest.Podman([]string{"network", "connect", netName, "foobar"})
115
dis.WaitWithDefaultTimeout()
116
Expect(dis).Should(ExitWithError())
119
It("network connect with net mode slirp4netns should result in error", func() {
120
netName := "slirp" + stringid.GenerateRandomID()
121
session := podmanTest.Podman([]string{"network", "create", netName})
122
session.WaitWithDefaultTimeout()
123
Expect(session).Should(ExitCleanly())
124
defer podmanTest.removeNetwork(netName)
126
session = podmanTest.Podman([]string{"create", "--name", "test", "--network", "slirp4netns", ALPINE})
127
session.WaitWithDefaultTimeout()
128
Expect(session).Should(ExitCleanly())
129
defer podmanTest.removeNetwork(netName)
131
con := podmanTest.Podman([]string{"network", "connect", netName, "test"})
132
con.WaitWithDefaultTimeout()
133
Expect(con).Should(ExitWithError())
134
Expect(con.ErrorToString()).To(ContainSubstring(`"slirp4netns" is not supported: invalid network mode`))
137
It("podman connect on a container that already is connected to the network should error after init", func() {
138
netName := "aliasTest" + stringid.GenerateRandomID()
139
session := podmanTest.Podman([]string{"network", "create", netName})
140
session.WaitWithDefaultTimeout()
141
Expect(session).Should(ExitCleanly())
142
defer podmanTest.removeNetwork(netName)
144
ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName, ALPINE, "top"})
145
ctr.WaitWithDefaultTimeout()
146
Expect(ctr).Should(ExitCleanly())
147
cid := ctr.OutputToString()
149
// network alias container short id is always added and shown in inspect
150
inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{(index .NetworkSettings.Networks \"" + netName + "\").Aliases}}"})
151
inspect.WaitWithDefaultTimeout()
152
Expect(inspect).Should(ExitCleanly())
153
Expect(inspect.OutputToString()).To(Equal("[" + cid[0:12] + "]"))
155
con := podmanTest.Podman([]string{"network", "connect", netName, "test"})
156
con.WaitWithDefaultTimeout()
157
Expect(con).Should(ExitCleanly())
159
init := podmanTest.Podman([]string{"init", "test"})
160
init.WaitWithDefaultTimeout()
161
Expect(init).Should(ExitCleanly())
163
con2 := podmanTest.Podman([]string{"network", "connect", netName, "test"})
164
con2.WaitWithDefaultTimeout()
165
Expect(con2).Should(ExitWithError())
168
It("podman network connect", func() {
169
SkipIfRootlessCgroupsV1("stats not supported under rootless CgroupsV1")
170
netName := "aliasTest" + stringid.GenerateRandomID()
171
session := podmanTest.Podman([]string{"network", "create", netName})
172
session.WaitWithDefaultTimeout()
173
Expect(session).Should(ExitCleanly())
174
defer podmanTest.removeNetwork(netName)
176
ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netName, ALPINE, "top"})
177
ctr.WaitWithDefaultTimeout()
178
Expect(ctr).Should(ExitCleanly())
179
cid := ctr.OutputToString()
181
exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
182
exec.WaitWithDefaultTimeout()
183
Expect(exec).Should(ExitCleanly())
185
// Create a second network
186
newNetName := "aliasTest" + stringid.GenerateRandomID()
187
session = podmanTest.Podman([]string{"network", "create", newNetName, "--subnet", "10.11.100.0/24"})
188
session.WaitWithDefaultTimeout()
189
Expect(session).Should(ExitCleanly())
190
defer podmanTest.removeNetwork(newNetName)
192
gw := podmanTest.Podman([]string{"network", "inspect", newNetName, "--format", "{{(index .Subnets 0).Gateway}}"})
193
gw.WaitWithDefaultTimeout()
194
Expect(gw).Should(ExitCleanly())
195
ns := gw.OutputToString()
197
exec2 := podmanTest.Podman([]string{"exec", "test", "cat", "/etc/resolv.conf"})
198
exec2.WaitWithDefaultTimeout()
199
Expect(exec2).Should(ExitCleanly())
200
Expect(exec2.OutputToString()).ToNot(ContainSubstring(ns))
203
mac := "44:11:44:11:44:11"
204
connect := podmanTest.Podman([]string{"network", "connect", "--ip", ip, "--mac-address", mac, newNetName, "test"})
205
connect.WaitWithDefaultTimeout()
206
Expect(connect).Should(ExitCleanly())
207
Expect(connect.ErrorToString()).Should(Equal(""))
209
inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
210
inspect.WaitWithDefaultTimeout()
211
Expect(inspect).Should(ExitCleanly())
212
Expect(inspect.OutputToString()).To(Equal("2"))
214
// network alias container short id is always added and shown in inspect
215
inspect = podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{(index .NetworkSettings.Networks \"" + newNetName + "\").Aliases}}"})
216
inspect.WaitWithDefaultTimeout()
217
Expect(inspect).Should(ExitCleanly())
218
Expect(inspect.OutputToString()).To(Equal("[" + cid[0:12] + "]"))
220
exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth1"})
221
exec.WaitWithDefaultTimeout()
222
Expect(exec).Should(ExitCleanly())
223
Expect(exec.OutputToString()).Should(ContainSubstring(ip))
224
Expect(exec.OutputToString()).Should(ContainSubstring(mac))
226
exec3 := podmanTest.Podman([]string{"exec", "test", "cat", "/etc/resolv.conf"})
227
exec3.WaitWithDefaultTimeout()
228
Expect(exec3).Should(ExitCleanly())
229
Expect(exec3.OutputToString()).To(ContainSubstring(ns))
231
// make sure stats works https://github.com/containers/podman/issues/13824
232
stats := podmanTest.Podman([]string{"stats", "test", "--no-stream"})
233
stats.WaitWithDefaultTimeout()
234
Expect(stats).Should(ExitCleanly())
236
// make sure no logrus errors are shown https://github.com/containers/podman/issues/9602
237
rm := podmanTest.Podman([]string{"rm", "--time=0", "-f", "test"})
238
rm.WaitWithDefaultTimeout()
239
Expect(rm).Should(ExitCleanly())
240
Expect(rm.ErrorToString()).To(Equal(""))
243
It("podman network connect when not running", func() {
244
netName1 := "connect1" + stringid.GenerateRandomID()
245
session := podmanTest.Podman([]string{"network", "create", netName1})
246
session.WaitWithDefaultTimeout()
247
Expect(session).Should(ExitCleanly())
248
defer podmanTest.removeNetwork(netName1)
250
netName2 := "connect2" + stringid.GenerateRandomID()
251
session = podmanTest.Podman([]string{"network", "create", netName2})
252
session.WaitWithDefaultTimeout()
253
Expect(session).Should(ExitCleanly())
254
defer podmanTest.removeNetwork(netName2)
256
ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName1, ALPINE, "top"})
257
ctr.WaitWithDefaultTimeout()
258
Expect(ctr).Should(ExitCleanly())
260
dis := podmanTest.Podman([]string{"network", "connect", netName2, "test"})
261
dis.WaitWithDefaultTimeout()
262
Expect(dis).Should(ExitCleanly())
264
inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
265
inspect.WaitWithDefaultTimeout()
266
Expect(inspect).Should(ExitCleanly())
267
Expect(inspect.OutputToString()).To(Equal("2"))
269
start := podmanTest.Podman([]string{"start", "test"})
270
start.WaitWithDefaultTimeout()
271
Expect(start).Should(ExitCleanly())
273
exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
274
exec.WaitWithDefaultTimeout()
275
Expect(exec).Should(ExitCleanly())
277
exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth1"})
278
exec.WaitWithDefaultTimeout()
279
Expect(exec).Should(ExitCleanly())
282
It("podman network connect and run with network ID", func() {
283
netName := "ID" + stringid.GenerateRandomID()
284
session := podmanTest.Podman([]string{"network", "create", netName})
285
session.WaitWithDefaultTimeout()
286
Expect(session).Should(ExitCleanly())
287
defer podmanTest.removeNetwork(netName)
289
session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + netName})
290
session.WaitWithDefaultTimeout()
291
Expect(session).Should(ExitCleanly())
292
netID := session.OutputToString()
294
ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netID, "--network-alias", "somealias", ALPINE, "top"})
295
ctr.WaitWithDefaultTimeout()
296
Expect(ctr).Should(ExitCleanly())
298
exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
299
exec.WaitWithDefaultTimeout()
300
Expect(exec).Should(ExitCleanly())
302
// Create a second network
303
newNetName := "ID2" + stringid.GenerateRandomID()
304
session = podmanTest.Podman([]string{"network", "create", newNetName})
305
session.WaitWithDefaultTimeout()
306
Expect(session).Should(ExitCleanly())
307
defer podmanTest.removeNetwork(newNetName)
309
session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + newNetName})
310
session.WaitWithDefaultTimeout()
311
Expect(session).Should(ExitCleanly())
312
newNetID := session.OutputToString()
314
connect := podmanTest.Podman([]string{"network", "connect", "--alias", "secondalias", newNetID, "test"})
315
connect.WaitWithDefaultTimeout()
316
Expect(connect).Should(ExitCleanly())
318
inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{.NetworkSettings.Networks}}"})
319
inspect.WaitWithDefaultTimeout()
320
Expect(inspect).Should(ExitCleanly())
321
Expect(inspect.OutputToString()).To(ContainSubstring(netName))
322
Expect(inspect.OutputToString()).To(ContainSubstring(newNetName))
324
exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth1"})
325
exec.WaitWithDefaultTimeout()
326
Expect(exec).Should(ExitCleanly())
329
It("podman network disconnect when not running", func() {
330
netName1 := "aliasTest" + stringid.GenerateRandomID()
331
session := podmanTest.Podman([]string{"network", "create", netName1})
332
session.WaitWithDefaultTimeout()
333
Expect(session).Should(ExitCleanly())
334
defer podmanTest.removeNetwork(netName1)
336
netName2 := "aliasTest" + stringid.GenerateRandomID()
337
session2 := podmanTest.Podman([]string{"network", "create", netName2})
338
session2.WaitWithDefaultTimeout()
339
Expect(session2).Should(ExitCleanly())
340
defer podmanTest.removeNetwork(netName2)
342
ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName1 + "," + netName2, ALPINE, "top"})
343
ctr.WaitWithDefaultTimeout()
344
Expect(ctr).Should(ExitCleanly())
346
dis := podmanTest.Podman([]string{"network", "disconnect", netName1, "test"})
347
dis.WaitWithDefaultTimeout()
348
Expect(dis).Should(ExitCleanly())
350
inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
351
inspect.WaitWithDefaultTimeout()
352
Expect(inspect).Should(ExitCleanly())
353
Expect(inspect.OutputToString()).To(Equal("1"))
355
start := podmanTest.Podman([]string{"start", "test"})
356
start.WaitWithDefaultTimeout()
357
Expect(start).Should(ExitCleanly())
359
exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
360
exec.WaitWithDefaultTimeout()
362
// because the network interface order is not guaranteed to be the same we have to check both eth0 and eth1
363
// if eth0 did not exists eth1 has to exists
364
var exitMatcher types.GomegaMatcher = ExitWithError()
365
if exec.ExitCode() > 0 {
366
exitMatcher = Exit(0)
369
exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth1"})
370
exec.WaitWithDefaultTimeout()
371
Expect(exec).Should(exitMatcher)
374
It("podman network disconnect and run with network ID", func() {
375
netName := "aliasTest" + stringid.GenerateRandomID()
376
session := podmanTest.Podman([]string{"network", "create", netName})
377
session.WaitWithDefaultTimeout()
378
Expect(session).Should(ExitCleanly())
379
defer podmanTest.removeNetwork(netName)
381
session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + netName})
382
session.WaitWithDefaultTimeout()
383
Expect(session).Should(ExitCleanly())
384
netID := session.OutputToString()
386
ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netID, ALPINE, "top"})
387
ctr.WaitWithDefaultTimeout()
388
Expect(ctr).Should(ExitCleanly())
390
exec := podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
391
exec.WaitWithDefaultTimeout()
392
Expect(exec).Should(ExitCleanly())
394
dis := podmanTest.Podman([]string{"network", "disconnect", netID, "test"})
395
dis.WaitWithDefaultTimeout()
396
Expect(dis).Should(ExitCleanly())
398
inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
399
inspect.WaitWithDefaultTimeout()
400
Expect(inspect).Should(ExitCleanly())
401
Expect(inspect.OutputToString()).To(Equal("0"))
403
exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth0"})
404
exec.WaitWithDefaultTimeout()
405
Expect(exec).Should(ExitWithError())