13
"github.com/containers/common/pkg/cgroups"
14
"github.com/containers/common/pkg/config"
15
"github.com/containers/podman/v5/libpod/define"
16
. "github.com/containers/podman/v5/test/utils"
17
"github.com/containers/storage/pkg/stringid"
18
. "github.com/onsi/ginkgo/v2"
19
. "github.com/onsi/gomega"
20
. "github.com/onsi/gomega/gexec"
23
var _ = Describe("Podman run", func() {
25
It("podman run a container based on local image", func() {
26
session := podmanTest.Podman([]string{"run", ALPINE, "ls"})
27
session.WaitWithDefaultTimeout()
28
Expect(session).Should(ExitCleanly())
31
// This test may seem entirely pointless, it is not. Due to compatibility
32
// and historical reasons, the container name generator uses a globally
33
// scoped RNG, seeded from a global state. An easy way to check if its
34
// been initialized properly (i.e. pseudo-non-deterministically) is
35
// checking if the name-generator spits out the same name twice. Because
36
// existing containers are checked when generating names, the test must ensure
37
// the first container is removed before creating a second.
38
It("podman generates different names for successive containers", func() {
41
for i := range names {
42
session := podmanTest.Podman([]string{"create", ALPINE, "true"})
43
session.WaitWithDefaultTimeout()
44
Expect(session).Should(ExitCleanly())
45
cid := session.OutputToString()
46
Expect(cid).To(Not(Equal("")))
48
session = podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Name}}", cid})
49
session.WaitWithDefaultTimeout()
50
Expect(session).Should(ExitCleanly())
51
names[i] = session.OutputToString()
52
Expect(names[i]).To(Not(Equal("")))
54
session = podmanTest.Podman([]string{"rm", cid})
55
session.WaitWithDefaultTimeout()
56
Expect(session).Should(ExitCleanly())
58
Expect(names[0]).ToNot(Equal(names[1]), "Podman generated duplicate successive container names, has the global RNG been seeded correctly?")
61
It("podman run check /run/.containerenv", func() {
62
session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/run/.containerenv"})
63
session.WaitWithDefaultTimeout()
64
Expect(session).Should(ExitCleanly())
65
Expect(session.OutputToString()).To(Equal(""))
67
session = podmanTest.Podman([]string{"run", "--privileged", "--name=test1", ALPINE, "cat", "/run/.containerenv"})
68
session.WaitWithDefaultTimeout()
69
Expect(session).Should(ExitCleanly())
70
Expect(session.OutputToString()).To(ContainSubstring("name=\"test1\""))
71
Expect(session.OutputToString()).To(ContainSubstring("image=\"" + ALPINE + "\""))
73
session = podmanTest.Podman([]string{"run", "-v", "/:/host", ALPINE, "cat", "/run/.containerenv"})
74
session.WaitWithDefaultTimeout()
75
Expect(session).Should(ExitCleanly())
76
Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1"))
78
session = podmanTest.Podman([]string{"run", "-v", "/:/host", "--privileged", ALPINE, "cat", "/run/.containerenv"})
79
session.WaitWithDefaultTimeout()
80
Expect(session).Should(ExitCleanly())
81
Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1"))
84
It("podman run from manifest list", func() {
85
session := podmanTest.Podman([]string{"manifest", "create", "localhost/test:latest"})
86
session.WaitWithDefaultTimeout()
87
Expect(session).Should(ExitCleanly())
89
session = podmanTest.Podman([]string{"build", "-q", "-f", "build/Containerfile.with-platform", "--platform", "linux/amd64,linux/arm64", "--manifest", "localhost/test:latest"})
90
session.WaitWithDefaultTimeout()
91
Expect(session).Should(ExitCleanly())
93
session = podmanTest.Podman([]string{"run", "--platform", "linux/arm64", "localhost/test", "uname", "-a"})
94
session.WaitWithDefaultTimeout()
95
exitCode := session.ExitCode()
96
// CI could either support requested platform or not, if it supports then output should contain `aarch64`
97
// if not run should fail with a very specific error i.e `Exec format error` anything other than this should
98
// be marked as failure of test.
100
Expect(session.OutputToString()).To(ContainSubstring("aarch64"))
102
// crun says 'Exec', runc says 'exec'. Handle either.
103
Expect(session.ErrorToString()).To(ContainSubstring("xec format error"))
107
It("podman run a container based on a complex local image name", func() {
108
imageName := strings.TrimPrefix(NGINX_IMAGE, "quay.io/")
109
session := podmanTest.Podman([]string{"run", imageName, "ls"})
110
session.WaitWithDefaultTimeout()
111
Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
112
Expect(session).Should(ExitCleanly())
115
It("podman run --signature-policy", func() {
116
session := podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/no/such/file", ALPINE})
117
session.WaitWithDefaultTimeout()
118
Expect(session).To(ExitWithError())
120
session = podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/etc/containers/policy.json", ALPINE})
121
session.WaitWithDefaultTimeout()
123
Expect(session).To(ExitWithError())
124
Expect(session.ErrorToString()).To(ContainSubstring("unknown flag"))
126
Expect(session).Should(Exit(0))
127
Expect(session.ErrorToString()).To(ContainSubstring("Getting image source signatures"))
131
It("podman run --rm with --restart", func() {
132
session := podmanTest.Podman([]string{"run", "--rm", "--restart", "", ALPINE})
133
session.WaitWithDefaultTimeout()
134
Expect(session).Should(ExitCleanly())
136
session = podmanTest.Podman([]string{"run", "--rm", "--restart", "no", ALPINE})
137
session.WaitWithDefaultTimeout()
138
Expect(session).Should(ExitCleanly())
140
session = podmanTest.Podman([]string{"run", "--rm", "--restart", "on-failure", ALPINE})
141
session.WaitWithDefaultTimeout()
142
Expect(session).Should(ExitCleanly())
144
session = podmanTest.Podman([]string{"run", "--rm", "--restart", "always", ALPINE})
145
session.WaitWithDefaultTimeout()
146
Expect(session).To(ExitWithError())
148
session = podmanTest.Podman([]string{"run", "--rm", "--restart", "unless-stopped", ALPINE})
149
session.WaitWithDefaultTimeout()
150
Expect(session).To(ExitWithError())
153
It("podman run a container based on on a short name with localhost", func() {
154
tag := podmanTest.Podman([]string{"tag", NGINX_IMAGE, "localhost/libpod/alpine_nginx:latest"})
155
tag.WaitWithDefaultTimeout()
157
rmi := podmanTest.Podman([]string{"rmi", NGINX_IMAGE})
158
rmi.WaitWithDefaultTimeout()
160
session := podmanTest.Podman([]string{"run", "libpod/alpine_nginx:latest", "ls"})
161
session.WaitWithDefaultTimeout()
162
Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
163
Expect(session).Should(ExitCleanly())
166
It("podman container run a container based on on a short name with localhost", func() {
167
tag := podmanTest.Podman([]string{"image", "tag", NGINX_IMAGE, "localhost/libpod/alpine_nginx:latest"})
168
tag.WaitWithDefaultTimeout()
170
rmi := podmanTest.Podman([]string{"image", "rm", NGINX_IMAGE})
171
rmi.WaitWithDefaultTimeout()
173
session := podmanTest.Podman([]string{"container", "run", "libpod/alpine_nginx:latest", "ls"})
174
session.WaitWithDefaultTimeout()
175
Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
176
Expect(session).Should(ExitCleanly())
179
It("podman run a container based on local image with short options", func() {
180
session := podmanTest.Podman([]string{"run", "-dt", ALPINE, "ls"})
181
session.WaitWithDefaultTimeout()
182
Expect(session).Should(ExitCleanly())
185
It("podman run a container based on local image with short options and args", func() {
186
// regression test for #714
187
session := podmanTest.Podman([]string{"run", ALPINE, "find", "/etc", "-name", "hosts"})
188
session.WaitWithDefaultTimeout()
189
Expect(session).Should(ExitCleanly())
190
Expect(session.OutputToString()).To(ContainSubstring("/etc/hosts"))
193
It("podman run --name X --hostname Y, both X and Y in /etc/hosts", func() {
194
name := "test_container"
195
hostname := "test_hostname"
196
session := podmanTest.Podman([]string{"run", "--rm", "--name", name, "--hostname", hostname, ALPINE, "cat", "/etc/hosts"})
197
session.WaitWithDefaultTimeout()
198
Expect(session).Should(ExitCleanly())
199
Expect(session.OutputToString()).To(ContainSubstring(name))
200
Expect(session.OutputToString()).To(ContainSubstring(hostname))
203
It("podman run a container based on remote image", func() {
204
// Pick any image that is not in our cache
205
session := podmanTest.Podman([]string{"run", "-dt", BB_GLIBC, "ls"})
206
session.WaitWithDefaultTimeout()
207
Expect(session).Should(Exit(0))
208
Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull " + BB_GLIBC))
209
Expect(session.ErrorToString()).To(ContainSubstring("Writing manifest to image destination"))
213
It("podman run --tls-verify", func() {
214
// 5000 is marked insecure in registries.conf, so --tls-verify=false
215
// is a NOP. Pick any other port.
217
lock := GetPortLock(port)
219
session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", port + ":5000", REGISTRY_IMAGE, "/entrypoint.sh", "/etc/docker/registry/config.yml"})
220
session.WaitWithDefaultTimeout()
221
Expect(session).Should(ExitCleanly())
223
if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) {
224
Fail("Cannot start docker registry.")
227
pushedImage := "localhost:" + port + "/pushed" + strings.ToLower(RandomString(5)) + ":" + RandomString(8)
228
push := podmanTest.Podman([]string{"push", "--tls-verify=false", ALPINE, pushedImage})
229
push.WaitWithDefaultTimeout()
230
Expect(push).To(Exit(0))
231
Expect(push.ErrorToString()).To(ContainSubstring("Writing manifest to image destination"))
233
run := podmanTest.Podman([]string{"run", pushedImage, "date"})
234
run.WaitWithDefaultTimeout()
235
Expect(run).Should(Exit(125))
236
Expect(run.ErrorToString()).To(ContainSubstring("pinging container registry localhost:" + port))
237
Expect(run.ErrorToString()).To(ContainSubstring("http: server gave HTTP response to HTTPS client"))
239
run = podmanTest.Podman([]string{"run", "--tls-verify=false", pushedImage, "echo", "got here"})
240
run.WaitWithDefaultTimeout()
241
Expect(run).Should(Exit(0))
242
Expect(run.OutputToString()).To(Equal("got here"))
243
Expect(run.ErrorToString()).To(ContainSubstring("Trying to pull " + pushedImage))
246
It("podman run a container with a --rootfs", func() {
247
rootfs := filepath.Join(tempdir, "rootfs")
248
uls := filepath.Join("/", "usr", "local", "share")
249
uniqueString := stringid.GenerateRandomID()
250
testFilePath := filepath.Join(uls, uniqueString)
251
tarball := filepath.Join(tempdir, "rootfs.tar")
253
err := os.Mkdir(rootfs, 0770)
254
Expect(err).ShouldNot(HaveOccurred())
256
// Change image in predictable way to validate export
257
csession := podmanTest.Podman([]string{"run", "--name", uniqueString, ALPINE,
258
"/bin/sh", "-c", fmt.Sprintf("echo %s > %s", uniqueString, testFilePath)})
259
csession.WaitWithDefaultTimeout()
260
Expect(csession).Should(ExitCleanly())
262
// Export from working container image guarantees working root
263
esession := podmanTest.Podman([]string{"export", "--output", tarball, uniqueString})
264
esession.WaitWithDefaultTimeout()
265
Expect(esession).Should(ExitCleanly())
266
Expect(tarball).Should(BeARegularFile())
268
// N/B: This will lose any extended attributes like SELinux types
269
GinkgoWriter.Printf("Extracting container root tarball\n")
270
tarsession := SystemExec("tar", []string{"xf", tarball, "-C", rootfs})
271
Expect(tarsession).Should(ExitCleanly())
272
Expect(filepath.Join(rootfs, uls)).Should(BeADirectory())
274
// Other tests confirm SELinux types, just confirm --rootfs is working.
275
session := podmanTest.Podman([]string{"run", "-i", "--security-opt", "label=disable",
276
"--rootfs", rootfs, "cat", testFilePath})
277
session.WaitWithDefaultTimeout()
278
Expect(session).Should(ExitCleanly())
280
// Validate changes made in original container and export
281
stdoutLines := session.OutputToStringArray()
282
Expect(stdoutLines).Should(HaveLen(1))
283
Expect(stdoutLines[0]).Should(Equal(uniqueString))
285
// The rest of these tests only work locally and not containerized
286
if IsRemote() || os.Getenv("container") != "" {
287
GinkgoWriter.Println("Bypassing subsequent tests due to remote or container environment")
290
// Test --rootfs with an external overlay
291
// use --rm to remove container and confirm if we did not leak anything
292
osession := podmanTest.Podman([]string{"run", "-i", "--rm", "--security-opt", "label=disable",
293
"--rootfs", rootfs + ":O", "cat", testFilePath})
294
osession.WaitWithDefaultTimeout()
295
Expect(osession).Should(ExitCleanly())
296
Expect(osession.OutputToString()).To(Equal(uniqueString))
298
// Test podman start stop with overlay
299
osession = podmanTest.Podman([]string{"run", "--name", "overlay-foo", "--security-opt", "label=disable",
300
"--rootfs", rootfs + ":O", "echo", "hello"})
301
osession.WaitWithDefaultTimeout()
302
Expect(osession).Should(ExitCleanly())
303
Expect(osession.OutputToString()).To(Equal("hello"))
305
podmanTest.StopContainer("overlay-foo")
307
startsession := podmanTest.Podman([]string{"start", "--attach", "overlay-foo"})
308
startsession.WaitWithDefaultTimeout()
309
Expect(startsession).Should(ExitCleanly())
310
Expect(startsession.OutputToString()).To(Equal("hello"))
312
// remove container for above test overlay-foo
313
osession = podmanTest.Podman([]string{"rm", "overlay-foo"})
314
osession.WaitWithDefaultTimeout()
315
Expect(osession).Should(ExitCleanly())
317
// Test --rootfs with an external overlay with --uidmap
318
osession = podmanTest.Podman([]string{"run", "--uidmap", "0:1234:5678", "--rm", "--security-opt", "label=disable",
319
"--rootfs", rootfs + ":O", "cat", "/proc/self/uid_map"})
320
osession.WaitWithDefaultTimeout()
321
Expect(osession).Should(ExitCleanly())
322
Expect(osession.OutputToString()).To(Equal("0 1234 5678"))
325
It("podman run a container with --init", func() {
326
session := podmanTest.Podman([]string{"run", "--name", "test", "--init", ALPINE, "ls"})
327
session.WaitWithDefaultTimeout()
328
Expect(session).Should(ExitCleanly())
329
result := podmanTest.Podman([]string{"inspect", "test"})
330
result.WaitWithDefaultTimeout()
331
Expect(result).Should(ExitCleanly())
332
conData := result.InspectContainerToJSON()
333
Expect(conData[0]).To(HaveField("Path", define.ContainerInitPath))
334
Expect(conData[0].Config.Annotations).To(HaveKeyWithValue("io.podman.annotations.init", "TRUE"))
337
It("podman run a container with --init and --init-path", func() {
338
// Also bind-mount /dev (#14251).
339
session := podmanTest.Podman([]string{"run", "-v", "/dev:/dev", "--name", "test", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"})
340
session.WaitWithDefaultTimeout()
341
Expect(session).Should(ExitCleanly())
342
result := podmanTest.Podman([]string{"inspect", "test"})
343
result.WaitWithDefaultTimeout()
344
Expect(result).Should(ExitCleanly())
345
conData := result.InspectContainerToJSON()
346
Expect(conData[0]).To(HaveField("Path", define.ContainerInitPath))
347
Expect(conData[0].Config.Annotations).To(HaveKeyWithValue("io.podman.annotations.init", "TRUE"))
350
It("podman run a container without --init", func() {
351
session := podmanTest.Podman([]string{"run", "--name", "test", ALPINE, "ls"})
352
session.WaitWithDefaultTimeout()
353
Expect(session).Should(ExitCleanly())
354
result := podmanTest.Podman([]string{"inspect", "test"})
355
result.WaitWithDefaultTimeout()
356
Expect(result).Should(ExitCleanly())
357
conData := result.InspectContainerToJSON()
358
Expect(conData[0]).To(HaveField("Path", "ls"))
359
Expect(conData[0].Config.Annotations).To(Not(HaveKey("io.podman.annotations.init")))
362
forbidLinkSeccompProfile := func() string {
363
in := []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"link","action":"SCMP_ACT_ERRNO"}]}`)
364
jsonFile, err := podmanTest.CreateSeccompJSON(in)
366
GinkgoWriter.Println(err)
367
Skip("Failed to prepare seccomp.json for test.")
372
It("podman run default mask test", func() {
373
session := podmanTest.Podman([]string{"run", "-d", "--name=maskCtr", ALPINE, "sleep", "200"})
374
session.WaitWithDefaultTimeout()
375
Expect(session).Should(ExitCleanly())
376
for _, mask := range config.DefaultMaskedPaths {
377
if st, err := os.Stat(mask); err == nil {
379
session = podmanTest.Podman([]string{"exec", "maskCtr", "ls", mask})
380
session.WaitWithDefaultTimeout()
381
Expect(session).Should(ExitCleanly())
382
Expect(session.OutputToString()).To(BeEmpty())
384
session = podmanTest.Podman([]string{"exec", "maskCtr", "cat", mask})
385
session.WaitWithDefaultTimeout()
386
// Call can fail with permission denied, ignoring error or Not exist.
387
// key factor is there is no information leak
388
Expect(session.OutputToString()).To(BeEmpty())
392
for _, mask := range config.DefaultReadOnlyPaths {
393
if _, err := os.Stat(mask); err == nil {
394
session = podmanTest.Podman([]string{"exec", "maskCtr", "touch", mask})
395
session.WaitWithDefaultTimeout()
396
Expect(session).Should(Exit(1))
397
Expect(session.ErrorToString()).To(Equal(fmt.Sprintf("touch: %s: Read-only file system", mask)))
402
It("podman run mask and unmask path test", func() {
403
session := podmanTest.Podman([]string{"run", "-d", "--name=maskCtr1", "--security-opt", "unmask=ALL", "--security-opt", "mask=/proc/acpi", ALPINE, "sleep", "200"})
404
session.WaitWithDefaultTimeout()
405
Expect(session).Should(ExitCleanly())
406
session = podmanTest.Podman([]string{"exec", "maskCtr1", "ls", "/sys/firmware"})
407
session.WaitWithDefaultTimeout()
408
Expect(session.OutputToString()).To(Not(BeEmpty()))
409
Expect(session).Should(ExitCleanly())
410
session = podmanTest.Podman([]string{"exec", "maskCtr1", "ls", "/proc/acpi"})
411
session.WaitWithDefaultTimeout()
412
Expect(session.OutputToString()).To(BeEmpty())
414
session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr2", "--security-opt", "unmask=/proc/acpi:/sys/firmware", ALPINE, "sleep", "200"})
415
session.WaitWithDefaultTimeout()
416
Expect(session).Should(ExitCleanly())
417
session = podmanTest.Podman([]string{"exec", "maskCtr2", "ls", "/sys/firmware"})
418
session.WaitWithDefaultTimeout()
419
Expect(session.OutputToString()).To(Not(BeEmpty()))
420
Expect(session).Should(ExitCleanly())
421
session = podmanTest.Podman([]string{"exec", "maskCtr2", "ls", "/proc/acpi"})
422
session.WaitWithDefaultTimeout()
423
Expect(session.OutputToString()).To(Not(BeEmpty()))
424
Expect(session).Should(ExitCleanly())
426
session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr3", "--security-opt", "mask=/sys/power/disk", ALPINE, "sleep", "200"})
427
session.WaitWithDefaultTimeout()
428
Expect(session).Should(ExitCleanly())
429
session = podmanTest.Podman([]string{"exec", "maskCtr3", "cat", "/sys/power/disk"})
430
session.WaitWithDefaultTimeout()
431
Expect(session.OutputToString()).To(BeEmpty())
432
Expect(session).Should(ExitCleanly())
434
session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr4", "--security-opt", "systempaths=unconfined", ALPINE, "sleep", "200"})
435
session.WaitWithDefaultTimeout()
436
Expect(session).Should(ExitCleanly())
437
session = podmanTest.Podman([]string{"exec", "maskCtr4", "ls", "/sys/firmware"})
438
session.WaitWithDefaultTimeout()
439
Expect(session.OutputToString()).To(Not(BeEmpty()))
440
Expect(session).Should(ExitCleanly())
442
session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr5", "--security-opt", "systempaths=unconfined", ALPINE, "grep", "/proc", "/proc/self/mounts"})
443
session.WaitWithDefaultTimeout()
444
Expect(session).Should(ExitCleanly())
445
Expect(session.OutputToStringArray()).Should(HaveLen(1))
447
session = podmanTest.Podman([]string{"run", "-d", "--security-opt", "unmask=/proc/*", ALPINE, "grep", "/proc", "/proc/self/mounts"})
448
session.WaitWithDefaultTimeout()
449
Expect(session).Should(ExitCleanly())
450
Expect(session.OutputToStringArray()).Should(HaveLen(1))
452
session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/proc/a*", ALPINE, "ls", "/proc/acpi"})
453
session.WaitWithDefaultTimeout()
454
Expect(session).Should(ExitCleanly())
455
Expect(session.OutputToString()).To(Not(BeEmpty()))
458
It("podman run powercap is masked", func() {
459
Skip("CI VMs do not have access to powercap")
461
testCtr1 := "testctr"
462
run := podmanTest.Podman([]string{"run", "-d", "--name", testCtr1, ALPINE, "top"})
463
run.WaitWithDefaultTimeout()
464
Expect(run).Should(ExitCleanly())
466
exec := podmanTest.Podman([]string{"exec", "-ti", testCtr1, "ls", "/sys/devices/virtual/powercap"})
467
exec.WaitWithDefaultTimeout()
468
Expect(exec).To(ExitWithError())
470
testCtr2 := "testctr2"
471
run2 := podmanTest.Podman([]string{"run", "-d", "--privileged", "--name", testCtr2, ALPINE, "top"})
472
run2.WaitWithDefaultTimeout()
473
Expect(run2).Should(ExitCleanly())
475
exec2 := podmanTest.Podman([]string{"exec", "-ti", testCtr2, "ls", "/sys/devices/virtual/powercap"})
476
exec2.WaitWithDefaultTimeout()
477
Expect(exec2).Should(ExitCleanly())
478
Expect(exec2.OutputToString()).Should(Not(BeEmpty()))
481
It("podman run security-opt unmask on /sys/fs/cgroup", func() {
483
SkipIfCgroupV1("podman umask on /sys/fs/cgroup will fail with cgroups V1")
484
SkipIfRootless("/sys/fs/cgroup rw access is needed")
485
rwOnCgroups := "/sys/fs/cgroup cgroup2 rw"
486
session := podmanTest.Podman([]string{"run", "--security-opt", "unmask=ALL", "--security-opt", "mask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"})
487
session.WaitWithDefaultTimeout()
488
Expect(session).Should(ExitCleanly())
489
Expect(session.OutputToString()).To(ContainSubstring(rwOnCgroups))
491
session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"})
492
session.WaitWithDefaultTimeout()
493
Expect(session).Should(ExitCleanly())
494
Expect(session.OutputToString()).To(ContainSubstring(rwOnCgroups))
496
session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup///", ALPINE, "cat", "/proc/mounts"})
497
session.WaitWithDefaultTimeout()
498
Expect(session).Should(ExitCleanly())
499
Expect(session.OutputToString()).To(ContainSubstring(rwOnCgroups))
501
session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=ALL", ALPINE, "cat", "/proc/mounts"})
502
session.WaitWithDefaultTimeout()
503
Expect(session).Should(ExitCleanly())
504
Expect(session.OutputToString()).To(ContainSubstring(rwOnCgroups))
506
session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", "--security-opt", "mask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"})
507
session.WaitWithDefaultTimeout()
508
Expect(session).Should(ExitCleanly())
509
Expect(session.OutputToString()).To(ContainSubstring(rwOnCgroups))
511
session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", ALPINE, "ls", "/sys/fs/cgroup"})
512
session.WaitWithDefaultTimeout()
513
Expect(session).Should(ExitCleanly())
514
Expect(session.OutputToString()).ToNot(BeEmpty())
517
It("podman run seccomp test", func() {
518
secOpts := []string{"--security-opt", strings.Join([]string{"seccomp=", forbidLinkSeccompProfile()}, "")}
519
cmd := []string{ALPINE, "ln", "/etc/motd", "/linkNotAllowed"}
521
// Without seccomp, this should succeed
522
session := podmanTest.Podman(append([]string{"run"}, cmd...))
523
session.WaitWithDefaultTimeout()
524
Expect(session).To(ExitCleanly())
526
// With link syscall blocked, should fail
527
cmd = append(secOpts, cmd...)
528
session = podmanTest.Podman(append([]string{"run"}, cmd...))
529
session.WaitWithDefaultTimeout()
530
Expect(session).To(Exit(1))
531
Expect(session.ErrorToString()).To(ContainSubstring("ln: /linkNotAllowed: Operation not permitted"))
533
// ...even with --privileged
534
cmd = append([]string{"--privileged"}, cmd...)
535
session = podmanTest.Podman(append([]string{"run"}, cmd...))
536
session.WaitWithDefaultTimeout()
537
Expect(session).To(Exit(1))
538
Expect(session.ErrorToString()).To(ContainSubstring("ln: /linkNotAllowed: Operation not permitted"))
541
It("podman run seccomp test --privileged no profile should be unconfined", func() {
542
session := podmanTest.Podman([]string{"run", "--privileged", ALPINE, "grep", "Seccomp", "/proc/self/status"})
543
session.WaitWithDefaultTimeout()
544
Expect(session.OutputToString()).To(ContainSubstring("0"))
545
Expect(session).Should(ExitCleanly())
548
It("podman run seccomp test no profile should be default", func() {
549
session := podmanTest.Podman([]string{"run", ALPINE, "grep", "Seccomp", "/proc/self/status"})
550
session.WaitWithDefaultTimeout()
551
Expect(session.OutputToString()).To(ContainSubstring("2"))
552
Expect(session).Should(ExitCleanly())
555
It("podman run capabilities test", func() {
556
session := podmanTest.Podman([]string{"run", "--rm", "--cap-add", "all", ALPINE, "cat", "/proc/self/status"})
557
session.WaitWithDefaultTimeout()
558
Expect(session).Should(ExitCleanly())
560
session = podmanTest.Podman([]string{"run", "--rm", "--cap-add", "sys_admin", ALPINE, "cat", "/proc/self/status"})
561
session.WaitWithDefaultTimeout()
562
Expect(session).Should(ExitCleanly())
564
session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "all", ALPINE, "cat", "/proc/self/status"})
565
session.WaitWithDefaultTimeout()
566
Expect(session).Should(ExitCleanly())
568
session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "setuid", ALPINE, "cat", "/proc/self/status"})
569
session.WaitWithDefaultTimeout()
570
Expect(session).Should(ExitCleanly())
573
It("podman run user capabilities test", func() {
574
// We need to ignore the containers.conf on the test distribution for this test
575
os.Setenv("CONTAINERS_CONF", "/dev/null")
577
podmanTest.RestartRemoteService()
579
session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapBnd", "/proc/self/status"})
580
session.WaitWithDefaultTimeout()
581
Expect(session).Should(ExitCleanly())
582
Expect(session.OutputToString()).To(ContainSubstring("00000000800405fb"))
584
session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapEff", "/proc/self/status"})
585
session.WaitWithDefaultTimeout()
586
Expect(session).Should(ExitCleanly())
587
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
589
session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapInh", "/proc/self/status"})
590
session.WaitWithDefaultTimeout()
591
Expect(session).Should(ExitCleanly())
592
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
594
session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapBnd", "/proc/self/status"})
595
session.WaitWithDefaultTimeout()
596
Expect(session).Should(ExitCleanly())
597
Expect(session.OutputToString()).To(ContainSubstring("00000000800405fb"))
599
session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapEff", "/proc/self/status"})
600
session.WaitWithDefaultTimeout()
601
Expect(session).Should(ExitCleanly())
602
Expect(session.OutputToString()).To(ContainSubstring("00000000800405fb"))
604
session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapInh", "/proc/self/status"})
605
session.WaitWithDefaultTimeout()
606
Expect(session).Should(ExitCleanly())
607
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
609
session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapBnd", "/proc/self/status"})
610
session.WaitWithDefaultTimeout()
611
Expect(session).Should(ExitCleanly())
612
Expect(session.OutputToString()).To(ContainSubstring("00000000800405fb"))
614
session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapEff", "/proc/self/status"})
615
session.WaitWithDefaultTimeout()
616
Expect(session).Should(ExitCleanly())
617
Expect(session.OutputToString()).To(ContainSubstring("00000000800405fb"))
619
session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
620
session.WaitWithDefaultTimeout()
621
Expect(session).Should(ExitCleanly())
622
Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
624
session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"})
625
session.WaitWithDefaultTimeout()
626
Expect(session).Should(ExitCleanly())
627
Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
629
session = podmanTest.Podman([]string{"run", "--user=0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
630
session.WaitWithDefaultTimeout()
631
Expect(session).Should(ExitCleanly())
632
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
634
session = podmanTest.Podman([]string{"run", "--user=0:0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
635
session.WaitWithDefaultTimeout()
636
Expect(session).Should(ExitCleanly())
637
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
639
session = podmanTest.Podman([]string{"run", "--user=0:0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"})
640
session.WaitWithDefaultTimeout()
641
Expect(session).Should(ExitCleanly())
642
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
644
session = podmanTest.Podman([]string{"run", "--user=1:1", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapEff", "/proc/self/status"})
645
session.WaitWithDefaultTimeout()
646
Expect(session).Should(ExitCleanly())
647
Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
650
if os.Getenv("SKIP_USERNS") != "" {
651
GinkgoWriter.Println("Bypassing subsequent tests due to $SKIP_USERNS")
654
if _, err := os.Stat("/proc/self/uid_map"); err != nil {
655
GinkgoWriter.Println("Bypassing subsequent tests due to no /proc/self/uid_map")
658
session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
659
session.WaitWithDefaultTimeout()
660
Expect(session).Should(ExitCleanly())
661
Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
663
session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--privileged", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"})
664
session.WaitWithDefaultTimeout()
665
Expect(session).Should(ExitCleanly())
666
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
668
session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"})
669
session.WaitWithDefaultTimeout()
670
Expect(session).Should(ExitCleanly())
671
Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
675
It("podman run user capabilities test with image", func() {
676
// We need to ignore the containers.conf on the test distribution for this test
677
os.Setenv("CONTAINERS_CONF", "/dev/null")
679
podmanTest.RestartRemoteService()
681
dockerfile := fmt.Sprintf(`FROM %s
683
podmanTest.BuildImage(dockerfile, "test", "false")
684
session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapBnd", "/proc/self/status"})
685
session.WaitWithDefaultTimeout()
686
Expect(session).Should(ExitCleanly())
687
Expect(session.OutputToString()).To(ContainSubstring("00000000800405fb"))
689
session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapEff", "/proc/self/status"})
690
session.WaitWithDefaultTimeout()
691
Expect(session).Should(ExitCleanly())
692
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
695
It("podman run limits test", func() {
696
SkipIfRootlessCgroupsV1("Setting limits not supported on cgroupv1 for rootless users")
699
session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "rtprio=99", "--cap-add=sys_nice", fedoraMinimal, "cat", "/proc/self/sched"})
700
session.WaitWithDefaultTimeout()
701
Expect(session).Should(ExitCleanly())
704
session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=2048:2048", fedoraMinimal, "ulimit", "-n"})
705
session.WaitWithDefaultTimeout()
706
Expect(session).Should(ExitCleanly())
707
Expect(session.OutputToString()).To(ContainSubstring("2048"))
709
session = podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=1024:1028", fedoraMinimal, "ulimit", "-n"})
710
session.WaitWithDefaultTimeout()
711
Expect(session).Should(ExitCleanly())
712
Expect(session.OutputToString()).To(ContainSubstring("1024"))
715
// --oom-kill-disable not supported on cgroups v2.
716
session = podmanTest.Podman([]string{"run", "--rm", "--oom-kill-disable=true", fedoraMinimal, "echo", "memory-hog"})
717
session.WaitWithDefaultTimeout()
718
Expect(session).Should(ExitCleanly())
721
session = podmanTest.Podman([]string{"run", "--rm", "--oom-score-adj=111", fedoraMinimal, "cat", "/proc/self/oom_score_adj"})
722
session.WaitWithDefaultTimeout()
723
Expect(session).Should(ExitCleanly())
724
Expect(session.OutputToString()).To(Equal("111"))
726
currentOOMScoreAdj, err := os.ReadFile("/proc/self/oom_score_adj")
727
Expect(err).ToNot(HaveOccurred())
728
name := "ctr-with-oom-score"
729
session = podmanTest.Podman([]string{"create", "--name", name, fedoraMinimal, "cat", "/proc/self/oom_score_adj"})
730
session.WaitWithDefaultTimeout()
731
Expect(session).Should(ExitCleanly())
733
for i := 0; i < 2; i++ {
734
session = podmanTest.Podman([]string{"start", "-a", name})
735
session.WaitWithDefaultTimeout()
736
Expect(session).Should(ExitCleanly())
737
Expect(session.OutputToString()).To(Equal(strings.TrimRight(string(currentOOMScoreAdj), "\n")))
741
It("podman run limits host test", func() {
742
SkipIfRemote("This can only be used for local tests")
746
err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l)
747
Expect(err).ToNot(HaveOccurred())
749
session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "host", fedoraMinimal, "ulimit", "-Hn"})
750
session.WaitWithDefaultTimeout()
751
Expect(session).Should(ExitCleanly())
753
ulimitCtrStr := strings.TrimSpace(session.OutputToString())
754
ulimitCtr, err := strconv.ParseUint(ulimitCtrStr, 10, 0)
755
Expect(err).ToNot(HaveOccurred())
757
Expect(ulimitCtr).Should(BeNumerically(">=", l.Max))
760
It("podman run with cidfile", func() {
761
cidFile := filepath.Join(tempdir, "cidfile")
762
session := podmanTest.Podman([]string{"run", "--name", "cidtest", "--cidfile", cidFile, CITEST_IMAGE, "ls"})
763
session.WaitWithDefaultTimeout()
764
Expect(session).Should(ExitCleanly())
766
cidFromFile, err := os.ReadFile(cidFile)
767
Expect(err).ToNot(HaveOccurred())
769
session = podmanTest.Podman([]string{"inspect", "--format", "{{.Id}}", "cidtest"})
770
session.WaitWithDefaultTimeout()
771
Expect(session).Should(ExitCleanly())
773
Expect(string(cidFromFile)).To(Equal(session.OutputToString()), "CID from cidfile == CID from podman inspect")
776
It("podman run sysctl test", func() {
777
SkipIfRootless("Network sysctls are not available root rootless")
778
session := podmanTest.Podman([]string{"run", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"})
779
session.WaitWithDefaultTimeout()
780
Expect(session).Should(ExitCleanly())
781
Expect(session.OutputToString()).To(ContainSubstring("net.core.somaxconn = 65535"))
783
// network sysctls should fail if --net=host is set
784
session = podmanTest.Podman([]string{"run", "--net", "host", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"})
785
session.WaitWithDefaultTimeout()
786
Expect(session).Should(Exit(125))
789
It("podman run blkio-weight test", func() {
790
SkipIfRootlessCgroupsV1("Setting blkio-weight not supported on cgroupv1 for rootless users")
791
SkipIfRootless("By default systemd doesn't delegate io to rootless users")
793
if _, err := os.Stat("/sys/fs/cgroup/io.stat"); os.IsNotExist(err) {
794
Skip("Kernel does not have io.stat")
796
if _, err := os.Stat("/sys/fs/cgroup/system.slice/io.bfq.weight"); os.IsNotExist(err) {
797
Skip("Kernel does not support BFQ IO scheduler")
799
session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/io.bfq.weight"})
800
session.WaitWithDefaultTimeout()
801
Expect(session).Should(ExitCleanly())
802
// there was a documentation issue in the kernel that reported a different range [1-10000] for the io controller.
803
// older versions of crun/runc used it. For the time being allow both versions to pass the test.
804
// FIXME: drop "|51" once all the runtimes we test have the fix in place.
805
Expect(strings.Replace(session.OutputToString(), "default ", "", 1)).To(MatchRegexp("15|51"))
807
if _, err := os.Stat("/sys/fs/cgroup/blkio/blkio.weight"); os.IsNotExist(err) {
808
Skip("Kernel does not support blkio.weight")
810
session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.weight"})
811
session.WaitWithDefaultTimeout()
812
Expect(session).Should(ExitCleanly())
813
Expect(session.OutputToString()).To(ContainSubstring("15"))
817
It("podman run device-read-bps test", func() {
818
SkipIfRootless("Setting device-read-bps not supported for rootless users")
820
var session *PodmanSessionIntegration
823
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
825
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"})
828
session.WaitWithDefaultTimeout()
829
Expect(session).Should(ExitCleanly())
830
if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
831
Expect(session.OutputToString()).To(ContainSubstring("1048576"))
835
It("podman run device-write-bps test", func() {
836
SkipIfRootless("Setting device-write-bps not supported for rootless users")
838
var session *PodmanSessionIntegration
841
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
843
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_bps_device"})
845
session.WaitWithDefaultTimeout()
846
Expect(session).Should(ExitCleanly())
847
if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
848
Expect(session.OutputToString()).To(ContainSubstring("1048576"))
852
It("podman run device-read-iops test", func() {
853
SkipIfRootless("Setting device-read-iops not supported for rootless users")
854
var session *PodmanSessionIntegration
857
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
859
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_iops_device"})
862
session.WaitWithDefaultTimeout()
863
Expect(session).Should(ExitCleanly())
864
if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
865
Expect(session.OutputToString()).To(ContainSubstring("100"))
869
It("podman run device-write-iops test", func() {
870
SkipIfRootless("Setting device-write-iops not supported for rootless users")
871
var session *PodmanSessionIntegration
874
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
876
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_iops_device"})
879
session.WaitWithDefaultTimeout()
880
Expect(session).Should(ExitCleanly())
881
if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
882
Expect(session.OutputToString()).To(ContainSubstring("100"))
886
It("podman run notify_socket", func() {
887
SkipIfRemote("This can only be used for local tests")
889
host := GetHostDistributionInfo()
890
if host.Distribution != "rhel" && host.Distribution != "centos" && host.Distribution != "fedora" {
891
Skip("this test requires a working runc")
893
sock := filepath.Join(podmanTest.TempDir, "notify")
894
addr := net.UnixAddr{
898
socket, err := net.ListenUnixgram("unixgram", &addr)
899
Expect(err).ToNot(HaveOccurred())
900
defer os.Remove(sock)
903
os.Setenv("NOTIFY_SOCKET", sock)
904
defer os.Unsetenv("NOTIFY_SOCKET")
906
session := podmanTest.Podman([]string{"run", ALPINE, "printenv", "NOTIFY_SOCKET"})
907
session.WaitWithDefaultTimeout()
908
Expect(session).Should(ExitCleanly())
909
Expect(session.OutputToStringArray()).ToNot(BeEmpty())
912
It("podman run log-opt", func() {
913
log := filepath.Join(podmanTest.TempDir, "/container.log")
914
session := podmanTest.Podman([]string{"run", "--rm", "--log-driver", "k8s-file", "--log-opt", fmt.Sprintf("path=%s", log), ALPINE, "ls"})
915
session.WaitWithDefaultTimeout()
916
Expect(session).Should(ExitCleanly())
917
_, err := os.Stat(log)
918
Expect(err).ToNot(HaveOccurred())
922
It("podman run tagged image", func() {
923
podmanTest.AddImageToRWStore(BB)
924
tag := podmanTest.Podman([]string{"tag", BB, "bb"})
925
tag.WaitWithDefaultTimeout()
926
Expect(tag).Should(ExitCleanly())
928
session := podmanTest.Podman([]string{"run", "--rm", "bb", "ls"})
929
session.WaitWithDefaultTimeout()
930
Expect(session).Should(ExitCleanly())
933
It("podman test hooks", func() {
934
SkipIfRemote("--hooks-dir does not work with remote")
935
hooksDir := filepath.Join(tempdir, "hooks,withcomma")
936
err := os.Mkdir(hooksDir, 0755)
937
Expect(err).ToNot(HaveOccurred())
938
hookJSONPath := filepath.Join(hooksDir, "checkhooks.json")
939
hookScriptPath := filepath.Join(hooksDir, "checkhooks.sh")
940
targetFile := filepath.Join(hooksDir, "target")
942
hookJSON := fmt.Sprintf(`{
945
"stage" : [ "prestart" ]
948
err = os.WriteFile(hookJSONPath, []byte(hookJSON), 0644)
949
Expect(err).ToNot(HaveOccurred())
951
random := stringid.GenerateRandomID()
953
hookScript := fmt.Sprintf(`#!/bin/sh
955
`, random, targetFile)
956
err = os.WriteFile(hookScriptPath, []byte(hookScript), 0755)
957
Expect(err).ToNot(HaveOccurred())
959
session := podmanTest.Podman([]string{"--hooks-dir", hooksDir, "run", ALPINE, "ls"})
961
Expect(session).Should(ExitCleanly())
963
b, err := os.ReadFile(targetFile)
964
Expect(err).ToNot(HaveOccurred())
965
Expect(string(b)).To(Equal(random))
968
It("podman run with subscription secrets", func() {
969
SkipIfRemote("--default-mount-file option is not supported in podman-remote")
970
containersDir := filepath.Join(podmanTest.TempDir, "containers")
971
err := os.MkdirAll(containersDir, 0755)
972
Expect(err).ToNot(HaveOccurred())
974
secretsDir := filepath.Join(podmanTest.TempDir, "rhel", "secrets")
975
err = os.MkdirAll(secretsDir, 0755)
976
Expect(err).ToNot(HaveOccurred())
978
mountsFile := filepath.Join(containersDir, "mounts.conf")
979
mountString := secretsDir + ":/run/secrets"
980
err = os.WriteFile(mountsFile, []byte(mountString), 0755)
981
Expect(err).ToNot(HaveOccurred())
983
secretsFile := filepath.Join(secretsDir, "test.txt")
984
secretsString := "Testing secrets mount. I am mounted!"
985
err = os.WriteFile(secretsFile, []byte(secretsString), 0755)
986
Expect(err).ToNot(HaveOccurred())
988
targetDir := filepath.Join(tempdir, "symlink/target")
989
err = os.MkdirAll(targetDir, 0755)
990
Expect(err).ToNot(HaveOccurred())
991
keyFile := filepath.Join(targetDir, "key.pem")
992
err = os.WriteFile(keyFile, []byte(mountString), 0755)
993
Expect(err).ToNot(HaveOccurred())
994
execSession := SystemExec("ln", []string{"-s", targetDir, filepath.Join(secretsDir, "mysymlink")})
995
Expect(execSession).Should(ExitCleanly())
997
session := podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "cat", "/run/secrets/test.txt"})
998
session.WaitWithDefaultTimeout()
999
Expect(session).Should(ExitCleanly())
1000
Expect(session.OutputToString()).To(Equal(secretsString))
1002
session = podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "ls", "/run/secrets/mysymlink"})
1003
session.WaitWithDefaultTimeout()
1004
Expect(session).Should(ExitCleanly())
1005
Expect(session.OutputToString()).To(ContainSubstring("key.pem"))
1008
It("podman run with FIPS mode secrets", func() {
1009
SkipIfRootless("rootless can not manipulate system-fips file")
1010
fipsFile := "/etc/system-fips"
1011
err = os.WriteFile(fipsFile, []byte{}, 0755)
1012
Expect(err).ToNot(HaveOccurred())
1014
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "ls", "/run/secrets"})
1015
session.WaitWithDefaultTimeout()
1016
Expect(session).Should(ExitCleanly())
1017
Expect(session.OutputToString()).To(ContainSubstring("system-fips"))
1019
err = os.Remove(fipsFile)
1020
Expect(err).ToNot(HaveOccurred())
1023
It("podman run without group-add", func() {
1024
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"})
1025
session.WaitWithDefaultTimeout()
1026
Expect(session).Should(ExitCleanly())
1027
Expect(session.OutputToString()).To(Not(ContainSubstring("27(video),777,65533(nogroup)")))
1030
It("podman run with group-add", func() {
1031
session := podmanTest.Podman([]string{"run", "--rm", "--group-add=audio", "--group-add=nogroup", "--group-add=777", ALPINE, "id"})
1032
session.WaitWithDefaultTimeout()
1033
Expect(session).Should(ExitCleanly())
1034
Expect(session.OutputToString()).To(ContainSubstring("777,65533(nogroup)"))
1037
It("podman run with user (default)", func() {
1038
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"})
1039
session.WaitWithDefaultTimeout()
1040
Expect(session).Should(ExitCleanly())
1041
Expect(session.OutputToString()).To(ContainSubstring("uid=0(root) gid=0(root)"))
1044
It("podman run with user (integer, not in /etc/passwd)", func() {
1045
session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "id"})
1046
session.WaitWithDefaultTimeout()
1047
Expect(session).Should(ExitCleanly())
1048
Expect(session.OutputToString()).To(Equal("uid=1234(1234) gid=0(root) groups=0(root)"))
1051
It("podman run with user (integer, in /etc/passwd)", func() {
1052
session := podmanTest.Podman([]string{"run", "--rm", "--user=8", ALPINE, "id"})
1053
session.WaitWithDefaultTimeout()
1054
Expect(session).Should(ExitCleanly())
1055
Expect(session.OutputToString()).To(ContainSubstring("uid=8(mail) gid=12(mail)"))
1058
It("podman run with user (username)", func() {
1059
session := podmanTest.Podman([]string{"run", "--rm", "--user=mail", ALPINE, "id"})
1060
session.WaitWithDefaultTimeout()
1061
Expect(session).Should(ExitCleanly())
1062
Expect(session.OutputToString()).To(ContainSubstring("uid=8(mail) gid=12(mail)"))
1065
It("podman run with user:group (username:integer)", func() {
1066
session := podmanTest.Podman([]string{"run", "--rm", "--user=mail:21", ALPINE, "id"})
1067
session.WaitWithDefaultTimeout()
1068
Expect(session).Should(ExitCleanly())
1069
Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp) groups=21(ftp)"))
1072
It("podman run with user:group (integer:groupname)", func() {
1073
session := podmanTest.Podman([]string{"run", "--rm", "--user=8:ftp", ALPINE, "id"})
1074
session.WaitWithDefaultTimeout()
1075
Expect(session).Should(ExitCleanly())
1076
Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp) groups=21(ftp)"))
1079
It("podman run with user, verify caps dropped", func() {
1080
session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "grep", "CapEff", "/proc/self/status"})
1081
session.WaitWithDefaultTimeout()
1082
Expect(session).Should(ExitCleanly())
1083
capEff := strings.Split(session.OutputToString(), " ")
1084
Expect("0000000000000000").To(Equal(capEff[1]))
1087
It("podman run with user, verify group added", func() {
1088
session := podmanTest.Podman([]string{"run", "--rm", "--user=1000:1000", ALPINE, "grep", "Groups:", "/proc/self/status"})
1089
session.WaitWithDefaultTimeout()
1090
Expect(session).Should(ExitCleanly())
1091
groups := strings.Split(session.OutputToString(), " ")[1]
1092
Expect("1000").To(Equal(groups))
1095
It("podman run with attach stdin outputs container ID", func() {
1096
session := podmanTest.Podman([]string{"run", "--attach", "stdin", ALPINE, "printenv"})
1097
session.WaitWithDefaultTimeout()
1098
Expect(session).Should(ExitCleanly())
1099
ps := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc"})
1100
ps.WaitWithDefaultTimeout()
1101
Expect(ps).Should(ExitCleanly())
1102
Expect(ps.OutputToString()).To(ContainSubstring(session.OutputToString()))
1105
It("podman run with attach stdout does not print stderr", func() {
1106
session := podmanTest.Podman([]string{"run", "--rm", "--attach", "stdout", ALPINE, "ls", "/doesnotexist"})
1107
session.WaitWithDefaultTimeout()
1108
Expect(session.OutputToString()).To(Equal(""))
1111
It("podman run with attach stderr does not print stdout", func() {
1112
session := podmanTest.Podman([]string{"run", "--rm", "--attach", "stderr", ALPINE, "ls", "/"})
1113
session.WaitWithDefaultTimeout()
1114
Expect(session).Should(ExitCleanly())
1115
Expect(session.OutputToString()).To(Equal(""))
1118
It("podman run attach nonsense errors", func() {
1119
session := podmanTest.Podman([]string{"run", "--rm", "--attach", "asdfasdf", ALPINE, "ls", "/"})
1120
session.WaitWithDefaultTimeout()
1121
Expect(session).Should(Exit(125))
1124
It("podman run exit code on failure to exec", func() {
1125
session := podmanTest.Podman([]string{"run", ALPINE, "/etc"})
1126
session.WaitWithDefaultTimeout()
1127
Expect(session).Should(Exit(126))
1130
It("podman run error on exec", func() {
1131
session := podmanTest.Podman([]string{"run", ALPINE, "sh", "-c", "exit 100"})
1132
session.WaitWithDefaultTimeout()
1133
Expect(session).Should(Exit(100))
1136
It("podman run with named volume", func() {
1137
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "stat", "-c", "%a %Y", "/var/tmp"})
1138
session.WaitWithDefaultTimeout()
1139
Expect(session).Should(ExitCleanly())
1140
perms := session.OutputToString()
1142
session = podmanTest.Podman([]string{"run", "--rm", "-v", "test:/var/tmp", ALPINE, "stat", "-c", "%a %Y", "/var/tmp"})
1143
session.WaitWithDefaultTimeout()
1144
Expect(session).Should(ExitCleanly())
1145
Expect(session.OutputToString()).To(Equal(perms))
1148
It("podman run with built-in volume image", func() {
1149
session := podmanTest.Podman([]string{"run", "--rm", REDIS_IMAGE, "ls"})
1150
session.WaitWithDefaultTimeout()
1151
Expect(session).Should(ExitCleanly())
1153
dockerfile := fmt.Sprintf(`FROM %s
1154
RUN mkdir -p /myvol/data && chown -R mail.0 /myvol
1155
VOLUME ["/myvol/data"]
1158
podmanTest.BuildImage(dockerfile, "test", "false")
1159
session = podmanTest.Podman([]string{"run", "--rm", "test", "ls", "-al", "/myvol/data"})
1160
session.WaitWithDefaultTimeout()
1161
Expect(session).Should(ExitCleanly())
1162
Expect(session.OutputToString()).To(ContainSubstring("mail root"))
1165
It("podman run --volumes-from flag", func() {
1166
vol := filepath.Join(podmanTest.TempDir, "vol-test")
1167
err := os.MkdirAll(vol, 0755)
1168
Expect(err).ToNot(HaveOccurred())
1170
filename := "test.txt"
1171
volFile := filepath.Join(vol, filename)
1172
data := "Testing --volumes-from!!!"
1173
err = os.WriteFile(volFile, []byte(data), 0755)
1174
Expect(err).ToNot(HaveOccurred())
1175
mountpoint := "/myvol/"
1177
session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint + ":z", ALPINE, "cat", mountpoint + filename})
1178
session.WaitWithDefaultTimeout()
1179
Expect(session).Should(ExitCleanly())
1180
ctrID := session.OutputToString()
1182
session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "cat", mountpoint + filename})
1183
session.WaitWithDefaultTimeout()
1184
Expect(session).Should(ExitCleanly())
1185
Expect(session.OutputToString()).To(Equal(data))
1187
session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "sh", "-c", "echo test >> " + mountpoint + filename})
1188
session.WaitWithDefaultTimeout()
1189
Expect(session).Should(ExitCleanly())
1191
session = podmanTest.Podman([]string{"start", "--attach", ctrID})
1192
session.WaitWithDefaultTimeout()
1193
Expect(session).Should(ExitCleanly())
1194
Expect(session.OutputToString()).To(Equal(data + "test"))
1197
It("podman run --volumes-from flag options", func() {
1198
vol := filepath.Join(podmanTest.TempDir, "vol-test")
1199
err := os.MkdirAll(vol, 0755)
1200
Expect(err).ToNot(HaveOccurred())
1202
filename := "test.txt"
1203
volFile := filepath.Join(vol, filename)
1204
data := "Testing --volumes-from!!!"
1205
err = os.WriteFile(volFile, []byte(data), 0755)
1206
Expect(err).ToNot(HaveOccurred())
1207
mountpoint := "/myvol/"
1209
session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint, ALPINE, "cat", mountpoint + filename})
1210
session.WaitWithDefaultTimeout()
1211
Expect(session).Should(ExitCleanly())
1212
ctrID := session.OutputToString()
1214
// check that the read-only option works
1215
session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro", ALPINE, "touch", mountpoint + "abc.txt"})
1216
session.WaitWithDefaultTimeout()
1217
Expect(session).Should(Exit(1))
1218
Expect(session.ErrorToString()).To(ContainSubstring("Read-only file system"))
1220
// check that both z and ro options work
1221
session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro,z", ALPINE, "cat", mountpoint + filename})
1222
session.WaitWithDefaultTimeout()
1223
Expect(session).Should(ExitCleanly())
1224
Expect(session.OutputToString()).To(Equal(data))
1226
// check that multiple ro/rw are not working
1227
session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro,rw", ALPINE, "cat", mountpoint + filename})
1228
session.WaitWithDefaultTimeout()
1229
Expect(session).Should(Exit(125))
1230
Expect(session.ErrorToString()).To(ContainSubstring("cannot set ro or rw options more than once"))
1232
// check that multiple z options are not working
1233
session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":z,z,ro", ALPINE, "cat", mountpoint + filename})
1234
session.WaitWithDefaultTimeout()
1235
Expect(session).Should(Exit(125))
1236
Expect(session.ErrorToString()).To(ContainSubstring("cannot set :z more than once in mount options"))
1238
// create new read-only volume
1239
session = podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint + ":ro", ALPINE, "cat", mountpoint + filename})
1240
session.WaitWithDefaultTimeout()
1241
Expect(session).Should(ExitCleanly())
1242
ctrID = session.OutputToString()
1244
// check if the original volume was mounted as read-only that --volumes-from also mount it as read-only
1245
session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "touch", mountpoint + "abc.txt"})
1246
session.WaitWithDefaultTimeout()
1247
Expect(session).Should(Exit(1))
1248
Expect(session.ErrorToString()).To(ContainSubstring("Read-only file system"))
1251
It("podman run --volumes-from flag with built-in volumes", func() {
1252
session := podmanTest.Podman([]string{"create", REDIS_IMAGE, "sh"})
1253
session.WaitWithDefaultTimeout()
1254
Expect(session).Should(ExitCleanly())
1255
ctrID := session.OutputToString()
1257
session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "ls"})
1258
session.WaitWithDefaultTimeout()
1259
Expect(session).Should(ExitCleanly())
1260
Expect(session.OutputToString()).To(ContainSubstring("data"))
1263
It("podman run --volumes-from flag mount conflicts with image volume", func() {
1264
volPathOnHost := filepath.Join(podmanTest.TempDir, "myvol")
1265
err := os.MkdirAll(volPathOnHost, 0755)
1266
Expect(err).ToNot(HaveOccurred())
1268
imgName := "testimg"
1269
volPath := "/myvol/mypath"
1270
dockerfile := fmt.Sprintf(`FROM %s
1272
VOLUME %s`, ALPINE, volPath, volPath)
1273
podmanTest.BuildImage(dockerfile, imgName, "false")
1276
run1 := podmanTest.Podman([]string{"run", "-d", "-v", fmt.Sprintf("%s:%s:z", volPathOnHost, volPath), "--name", ctr1, ALPINE, "top"})
1277
run1.WaitWithDefaultTimeout()
1278
Expect(run1).Should(ExitCleanly())
1280
testFile := "testfile1"
1281
ctr1Exec := podmanTest.Podman([]string{"exec", "-t", ctr1, "touch", fmt.Sprintf("%s/%s", volPath, testFile)})
1282
ctr1Exec.WaitWithDefaultTimeout()
1283
Expect(ctr1Exec).Should(ExitCleanly())
1285
run2 := podmanTest.Podman([]string{"run", "--volumes-from", ctr1, imgName, "ls", volPath})
1286
run2.WaitWithDefaultTimeout()
1287
Expect(run2).Should(ExitCleanly())
1288
Expect(run2.OutputToString()).To(Equal(testFile))
1291
It("podman run --volumes flag with multiple volumes", func() {
1292
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
1293
err := os.MkdirAll(vol1, 0755)
1294
Expect(err).ToNot(HaveOccurred())
1295
vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
1296
err = os.MkdirAll(vol2, 0755)
1297
Expect(err).ToNot(HaveOccurred())
1299
session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", ALPINE, "touch", "/myvol2/foo.txt"})
1300
session.WaitWithDefaultTimeout()
1301
Expect(session).Should(ExitCleanly())
1304
It("podman run --volumes flag with empty host dir", func() {
1305
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
1306
err := os.MkdirAll(vol1, 0755)
1307
Expect(err).ToNot(HaveOccurred())
1309
session := podmanTest.Podman([]string{"run", "--volume", ":/myvol1:z", ALPINE, "touch", "/myvol2/foo.txt"})
1310
session.WaitWithDefaultTimeout()
1311
Expect(session).To(ExitWithError())
1312
Expect(session.ErrorToString()).To(ContainSubstring("directory cannot be empty"))
1313
session = podmanTest.Podman([]string{"run", "--volume", vol1 + ":", ALPINE, "touch", "/myvol2/foo.txt"})
1314
session.WaitWithDefaultTimeout()
1315
Expect(session).To(ExitWithError())
1316
Expect(session.ErrorToString()).To(ContainSubstring("directory cannot be empty"))
1319
It("podman run --mount flag with multiple mounts", func() {
1320
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
1321
err := os.MkdirAll(vol1, 0755)
1322
Expect(err).ToNot(HaveOccurred())
1323
vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
1324
err = os.MkdirAll(vol2, 0755)
1325
Expect(err).ToNot(HaveOccurred())
1327
session := podmanTest.Podman([]string{"run", "--mount", "type=bind,src=" + vol1 + ",target=/myvol1,z", "--mount", "type=bind,src=" + vol2 + ",target=/myvol2,z", ALPINE, "touch", "/myvol2/foo.txt"})
1328
session.WaitWithDefaultTimeout()
1329
Expect(session).Should(ExitCleanly())
1332
It("podman run findmnt nothing shared", func() {
1333
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
1334
err := os.MkdirAll(vol1, 0755)
1335
Expect(err).ToNot(HaveOccurred())
1336
vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
1337
err = os.MkdirAll(vol2, 0755)
1338
Expect(err).ToNot(HaveOccurred())
1340
session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", fedoraMinimal, "findmnt", "-o", "TARGET,PROPAGATION"})
1341
session.WaitWithDefaultTimeout()
1342
Expect(session).Should(ExitCleanly())
1343
Expect(session.OutputToString()).To(Not(ContainSubstring("shared")))
1346
It("podman run findmnt shared", func() {
1347
vol := filepath.Join(podmanTest.TempDir, "vol-test")
1348
err := os.MkdirAll(vol, 0755)
1349
Expect(err).ToNot(HaveOccurred())
1351
session := podmanTest.Podman([]string{"run", "--volume", vol + ":/myvol:z", fedoraMinimal, "findmnt", "-no", "PROPAGATION", "/myvol"})
1352
session.WaitWithDefaultTimeout()
1353
Expect(session).Should(ExitCleanly())
1354
Expect(session.OutputToString()).To(Equal("private"))
1356
session = podmanTest.Podman([]string{"run", "--volume", vol + ":/myvol:shared,z", fedoraMinimal, "findmnt", "-no", "PROPAGATION", "/myvol"})
1357
session.WaitWithDefaultTimeout()
1358
Expect(session).Should(ExitCleanly())
1361
// we need to relax the rootless test because it can be "shared" only when the user owns the outer mount namespace.
1362
Expect(session.OutputToString()).To(ContainSubstring("shared"))
1364
// make sure it's only shared (and not 'shared,*')
1365
Expect(session.OutputToString()).To(Equal("shared"))
1369
It("podman run --security-opts proc-opts=", func() {
1370
session := podmanTest.Podman([]string{"run", "--security-opt", "proc-opts=nosuid,exec", fedoraMinimal, "findmnt", "-noOPTIONS", "/proc"})
1371
session.WaitWithDefaultTimeout()
1372
Expect(session).Should(ExitCleanly())
1373
output := session.OutputToString()
1374
Expect(output).To(ContainSubstring("nosuid"))
1375
Expect(output).To(Not(ContainSubstring("exec")))
1378
It("podman run --mount type=bind,bind-nonrecursive", func() {
1379
SkipIfRootless("FIXME: rootless users are not allowed to mount bind-nonrecursive")
1380
session := podmanTest.Podman([]string{"run", "--mount", "type=bind,bind-nonrecursive,private,src=/sys,target=/host-sys", fedoraMinimal, "findmnt", "-nR", "/host-sys"})
1381
session.WaitWithDefaultTimeout()
1382
Expect(session).Should(ExitCleanly())
1383
Expect(session.OutputToStringArray()).To(HaveLen(1))
1386
It("podman run --mount type=devpts,target=/foo/bar", func() {
1387
session := podmanTest.Podman([]string{"run", "--mount", "type=devpts,target=/foo/bar", fedoraMinimal, "stat", "-f", "-c%T", "/foo/bar"})
1388
session.WaitWithDefaultTimeout()
1389
Expect(session).Should(ExitCleanly())
1390
Expect(session.OutputToString()).To(ContainSubstring(define.TypeDevpts))
1393
It("podman run --mount type=devpts,target=/dev/pts with uid, gid and mode", func() {
1394
// runc doesn't seem to honor uid= so avoid testing it
1395
session := podmanTest.Podman([]string{"run", "-t", "--mount", "type=devpts,target=/dev/pts,uid=1000,gid=1001,mode=123", fedoraMinimal, "stat", "-c%g-%a", "/dev/pts/0"})
1396
session.WaitWithDefaultTimeout()
1397
Expect(session).Should(ExitCleanly())
1398
Expect(session.OutputToString()).To(ContainSubstring("1001-123"))
1401
It("podman run --pod automatically", func() {
1402
session := podmanTest.Podman([]string{"run", "-d", "--pod", "new:foobar", ALPINE, "nc", "-l", "-p", "8686"})
1403
session.WaitWithDefaultTimeout()
1404
Expect(session).Should(ExitCleanly())
1406
session = podmanTest.Podman([]string{"run", "--pod", "foobar", ALPINE, "/bin/sh", "-c", "echo test | nc -w 1 127.0.0.1 8686"})
1407
session.WaitWithDefaultTimeout()
1408
Expect(session).Should(ExitCleanly())
1410
check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"})
1411
check.WaitWithDefaultTimeout()
1412
Expect(check.OutputToString()).To(ContainSubstring("foobar"))
1415
It("podman run --pod new with hostname", func() {
1417
session := podmanTest.Podman([]string{"run", "--pod", "new:foobar", "--hostname", hostname, ALPINE, "cat", "/etc/hostname"})
1418
session.WaitWithDefaultTimeout()
1419
Expect(session).Should(ExitCleanly())
1420
Expect(session.OutputToString()).To(ContainSubstring(hostname))
1423
It("podman run --rm should work", func() {
1424
session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "ls"})
1425
session.WaitWithDefaultTimeout()
1426
Expect(session).Should(ExitCleanly())
1427
session = podmanTest.Podman([]string{"wait", "test"})
1428
session.WaitWithDefaultTimeout()
1429
Expect(session).To(ExitWithError())
1431
numContainers := podmanTest.NumberOfContainers()
1432
Expect(numContainers).To(Equal(0))
1435
It("podman run --rm failed container should delete itself", func() {
1436
session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "foo"})
1437
session.WaitWithDefaultTimeout()
1438
Expect(session).To(ExitWithError())
1439
session = podmanTest.Podman([]string{"wait", "test"})
1440
session.WaitWithDefaultTimeout()
1441
Expect(session).To(ExitWithError())
1443
numContainers := podmanTest.NumberOfContainers()
1444
Expect(numContainers).To(Equal(0))
1447
It("podman run failed container should NOT delete itself", func() {
1448
session := podmanTest.Podman([]string{"run", ALPINE, "foo"})
1449
session.WaitWithDefaultTimeout()
1450
Expect(session).To(ExitWithError())
1451
// If remote we could have a race condition
1452
session = podmanTest.Podman([]string{"wait", "test"})
1453
session.WaitWithDefaultTimeout()
1454
Expect(session).To(ExitWithError())
1456
numContainers := podmanTest.NumberOfContainers()
1457
Expect(numContainers).To(Equal(1))
1459
It("podman run readonly container should NOT mount /dev/shm read/only", func() {
1460
session := podmanTest.Podman([]string{"run", "--read-only", ALPINE, "mount"})
1461
session.WaitWithDefaultTimeout()
1462
Expect(session).Should(ExitCleanly())
1464
Expect(session.OutputToString()).To(Not(ContainSubstring("/dev/shm type tmpfs (ro,")))
1467
It("podman run readonly container should NOT mount /run noexec", func() {
1468
session := podmanTest.Podman([]string{"run", "--read-only", ALPINE, "sh", "-c", "mount | grep \"/run \""})
1469
session.WaitWithDefaultTimeout()
1470
Expect(session).Should(ExitCleanly())
1472
Expect(session.OutputToString()).To(Not(ContainSubstring("noexec")))
1475
It("podman run with bad healthcheck retries", func() {
1476
session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-retries", "0", ALPINE, "top"})
1478
Expect(session).To(ExitWithError())
1479
Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-retries must be greater than 0"))
1482
It("podman run with bad healthcheck timeout", func() {
1483
session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "foo", "--health-timeout", "0s", ALPINE, "top"})
1484
session.WaitWithDefaultTimeout()
1485
Expect(session).To(ExitWithError())
1486
Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-timeout must be at least 1 second"))
1489
It("podman run with bad healthcheck start-period", func() {
1490
session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "foo", "--health-start-period", "-1s", ALPINE, "top"})
1491
session.WaitWithDefaultTimeout()
1492
Expect(session).To(ExitWithError())
1493
Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-start-period must be 0 seconds or greater"))
1496
It("podman run with --add-host and --no-hosts fails", func() {
1497
session := podmanTest.Podman([]string{"run", "-dt", "--add-host", "test1:127.0.0.1", "--no-hosts", ALPINE, "top"})
1498
session.WaitWithDefaultTimeout()
1499
Expect(session).To(ExitWithError())
1502
It("podman run with restart-policy always restarts containers", func() {
1503
testDir := filepath.Join(podmanTest.RunRoot, "restart-test")
1504
err := os.MkdirAll(testDir, 0755)
1505
Expect(err).ToNot(HaveOccurred())
1507
aliveFile := filepath.Join(testDir, "running")
1508
file, err := os.Create(aliveFile)
1509
Expect(err).ToNot(HaveOccurred())
1512
session := podmanTest.Podman([]string{"run", "-dt", "--restart", "always", "-v", fmt.Sprintf("%s:/tmp/runroot:Z", testDir), ALPINE, "sh", "-c", "touch /tmp/runroot/ran && while test -r /tmp/runroot/running; do sleep 0.1s; done"})
1515
testFile := filepath.Join(testDir, "ran")
1516
for i := 0; i < 30; i++ {
1517
time.Sleep(1 * time.Second)
1518
if _, err := os.Stat(testFile); err == nil {
1520
err = os.Remove(testFile)
1521
Expect(err).ToNot(HaveOccurred())
1525
Expect(found).To(BeTrue(), "found expected /ran file")
1527
err = os.Remove(aliveFile)
1528
Expect(err).ToNot(HaveOccurred())
1530
session.WaitWithDefaultTimeout()
1532
// 10 seconds to restart the container
1534
for i := 0; i < 10; i++ {
1535
time.Sleep(1 * time.Second)
1536
if _, err := os.Stat(testFile); err == nil {
1541
Expect(found).To(BeTrue(), "found /ran file after restart")
1544
It("podman run with restart policy does not restart on manual stop", func() {
1545
ctrName := "testCtr"
1546
ctr := podmanTest.Podman([]string{"run", "-dt", "--restart=always", "--name", ctrName, ALPINE, "top"})
1547
ctr.WaitWithDefaultTimeout()
1548
Expect(ctr).Should(ExitCleanly())
1550
podmanTest.StopContainer(ctrName)
1552
// This is ugly, but I don't see a better way
1553
time.Sleep(10 * time.Second)
1555
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
1558
It("podman run with cgroups=split", func() {
1559
SkipIfNotSystemd(podmanTest.CgroupManager, "do not test --cgroups=split if not running on systemd")
1560
SkipIfRootlessCgroupsV1("Disable cgroups not supported on cgroupv1 for rootless users")
1561
SkipIfRemote("--cgroups=split cannot be used in remote mode")
1563
checkLines := func(lines []string) {
1565
for _, line := range lines {
1566
parts := strings.SplitN(line, ":", 3)
1571
// ignore unified on cgroup v1.
1572
// both runc and crun do not set it.
1573
// crun does not set named hierarchies.
1574
if parts[1] == "" || strings.Contains(parts[1], "name=") {
1578
if parts[2] == "/" {
1585
Expect(cgroup).To(Equal(parts[2]))
1589
container := podmanTest.PodmanSystemdScope([]string{"run", "--rm", "--cgroups=split", ALPINE, "cat", "/proc/self/cgroup"})
1590
container.WaitWithDefaultTimeout()
1591
Expect(container).Should(Exit(0))
1592
checkLines(container.OutputToStringArray())
1593
Expect(container.ErrorToString()).To(Or(
1594
ContainSubstring("Running scope as unit: "), // systemd < 255
1595
ContainSubstring("Running as unit: "))) // systemd >= 255
1597
// check that --cgroups=split is honored also when a container runs in a pod
1598
container = podmanTest.PodmanSystemdScope([]string{"run", "--rm", "--pod", "new:split-test-pod", "--cgroups=split", ALPINE, "cat", "/proc/self/cgroup"})
1599
container.WaitWithDefaultTimeout()
1600
Expect(container).Should(Exit(0))
1601
checkLines(container.OutputToStringArray())
1602
Expect(container.ErrorToString()).To(Or(
1603
ContainSubstring("Running scope as unit: "), // systemd < 255
1604
ContainSubstring("Running as unit: "))) // systemd >= 255
1607
It("podman run with cgroups=disabled runs without cgroups", func() {
1608
SkipIfRootlessCgroupsV1("Disable cgroups not supported on cgroupv1 for rootless users")
1609
// Only works on crun
1610
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
1611
Skip("Test only works on crun")
1614
ownsCgroup, err := cgroups.UserOwnsCurrentSystemdCgroup()
1615
Expect(err).ShouldNot(HaveOccurred())
1617
// Podman moves itself to a new cgroup if it doesn't own the current cgroup
1618
Skip("Test only works when Podman owns the current cgroup")
1621
trim := func(i string) string {
1622
return strings.TrimSuffix(i, "\n")
1625
curCgroupsBytes, err := os.ReadFile("/proc/self/cgroup")
1626
Expect(err).ShouldNot(HaveOccurred())
1627
curCgroups := trim(string(curCgroupsBytes))
1628
GinkgoWriter.Printf("Output:\n%s\n", curCgroups)
1629
Expect(curCgroups).ToNot(Equal(""))
1631
container := podmanTest.Podman([]string{"run", "--cgroupns=host", "--cgroups=disabled", ALPINE, "cat", "/proc/self/cgroup"})
1632
container.WaitWithDefaultTimeout()
1633
Expect(container).Should(ExitCleanly())
1635
ctrCgroups := trim(container.OutputToString())
1636
GinkgoWriter.Printf("Output\n:%s\n", ctrCgroups)
1638
Expect(ctrCgroups).To(Equal(curCgroups))
1641
It("podman run with cgroups=enabled makes cgroups", func() {
1642
SkipIfRootlessCgroupsV1("Enable cgroups not supported on cgroupv1 for rootless users")
1643
// Only works on crun
1644
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
1645
Skip("Test only works on crun")
1648
curCgroupsBytes, err := os.ReadFile("/proc/self/cgroup")
1649
Expect(err).ToNot(HaveOccurred())
1650
var curCgroups = string(curCgroupsBytes)
1651
GinkgoWriter.Printf("Output:\n%s\n", curCgroups)
1652
Expect(curCgroups).To(Not(Equal("")))
1654
ctrName := "testctr"
1655
container := podmanTest.Podman([]string{"run", "--name", ctrName, "-d", "--cgroups=enabled", ALPINE, "top"})
1656
container.WaitWithDefaultTimeout()
1657
Expect(container).Should(ExitCleanly())
1659
// Get PID and get cgroups of that PID
1660
inspectOut := podmanTest.InspectContainer(ctrName)
1661
Expect(inspectOut).To(HaveLen(1))
1662
pid := inspectOut[0].State.Pid
1663
Expect(pid).To(Not(Equal(0)))
1665
ctrCgroupsBytes, err := os.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid))
1666
Expect(err).ToNot(HaveOccurred())
1667
var ctrCgroups = string(ctrCgroupsBytes)
1668
GinkgoWriter.Printf("Output\n:%s\n", ctrCgroups)
1669
Expect(curCgroups).To(Not(Equal(ctrCgroups)))
1672
It("podman run with cgroups=garbage errors", func() {
1673
session := podmanTest.Podman([]string{"run", "-d", "--cgroups=garbage", ALPINE, "top"})
1674
session.WaitWithDefaultTimeout()
1675
Expect(session).To(ExitWithError())
1678
It("podman run should fail with nonexistent authfile", func() {
1679
session := podmanTest.Podman([]string{"run", "--authfile", "/tmp/nonexistent", ALPINE, "ls"})
1680
session.WaitWithDefaultTimeout()
1681
Expect(session).To(ExitWithError())
1684
It("podman run --device-cgroup-rule", func() {
1685
SkipIfRootless("rootless users are not allowed to mknod")
1686
deviceCgroupRule := "c 42:* rwm"
1687
session := podmanTest.Podman([]string{"run", "--cap-add", "mknod", "--name", "test", "-d", "--device-cgroup-rule", deviceCgroupRule, ALPINE, "top"})
1688
session.WaitWithDefaultTimeout()
1689
Expect(session).Should(ExitCleanly())
1690
session = podmanTest.Podman([]string{"exec", "test", "mknod", "newDev", "c", "42", "1"})
1691
session.WaitWithDefaultTimeout()
1692
Expect(session).Should(ExitCleanly())
1695
It("podman run --replace", func() {
1696
// Make sure we error out with --name.
1697
session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"})
1698
session.WaitWithDefaultTimeout()
1699
Expect(session).Should(Exit(125))
1700
Expect(session.ErrorToString()).To(ContainSubstring("cannot replace container without --name being set"))
1702
// Run and replace 5 times in a row the "same" container.
1703
ctrName := "testCtr"
1704
for i := 0; i < 5; i++ {
1705
session := podmanTest.Podman([]string{"run", "--detach", "--replace", "--name", ctrName, ALPINE, "top"})
1706
session.WaitWithDefaultTimeout()
1707
// FIXME - #20196: Cannot use ExitCleanly()
1708
Expect(session).Should(Exit(0))
1710
// make sure Podman prints only one ID
1711
Expect(session.OutputToString()).To(HaveLen(64))
1715
It("podman run --preserve-fds", func() {
1716
devNull, err := os.Open("/dev/null")
1717
Expect(err).ToNot(HaveOccurred())
1718
defer devNull.Close()
1719
files := []*os.File{
1722
session := podmanTest.PodmanExtraFiles([]string{"run", "--preserve-fds", "1", ALPINE, "ls"}, files)
1723
session.WaitWithDefaultTimeout()
1724
Expect(session).Should(ExitCleanly())
1727
It("podman run --preserve-fds invalid fd", func() {
1728
session := podmanTest.Podman([]string{"run", "--preserve-fds", "2", ALPINE})
1729
session.WaitWithDefaultTimeout()
1730
Expect(session).To(ExitWithError())
1731
Expect(session.ErrorToString()).To(ContainSubstring("file descriptor 3 is not available"))
1734
It("podman run --privileged and --group-add", func() {
1736
session := podmanTest.Podman([]string{"run", "--group-add", groupName, "--privileged", fedoraMinimal, "groups"})
1737
session.WaitWithDefaultTimeout()
1738
Expect(session).Should(ExitCleanly())
1739
Expect(session.OutputToString()).To(ContainSubstring(groupName))
1742
It("podman run --tz", func() {
1743
testDir := filepath.Join(podmanTest.RunRoot, "tz-test")
1744
err := os.MkdirAll(testDir, 0755)
1745
Expect(err).ToNot(HaveOccurred())
1747
tzFile := filepath.Join(testDir, "tzfile.txt")
1748
file, err := os.Create(tzFile)
1749
Expect(err).ToNot(HaveOccurred())
1750
defer os.Remove(tzFile)
1752
_, err = file.WriteString("Hello")
1753
Expect(err).ToNot(HaveOccurred())
1756
badTZFile := fmt.Sprintf("../../../%s", tzFile)
1757
session := podmanTest.Podman([]string{"run", "--tz", badTZFile, "--rm", ALPINE, "date"})
1758
session.WaitWithDefaultTimeout()
1759
Expect(session).To(ExitWithError())
1760
Expect(session.ErrorToString()).To(
1761
Equal("Error: running container create option: finding timezone: time: invalid location name"))
1763
session = podmanTest.Podman([]string{"run", "--tz", "Pacific/Honolulu", "--rm", ALPINE, "date", "+'%H %Z'"})
1764
session.WaitWithDefaultTimeout()
1765
Expect(session).Should(ExitCleanly())
1766
Expect(session.OutputToString()).To(ContainSubstring("HST"))
1768
session = podmanTest.Podman([]string{"run", "--tz", "local", "--rm", ALPINE, "date", "+'%H %Z'"})
1769
session.WaitWithDefaultTimeout()
1770
Expect(session).Should(ExitCleanly())
1773
h := strconv.Itoa(t.Hour())
1774
Expect(session.OutputToString()).To(ContainSubstring(z))
1775
Expect(session.OutputToString()).To(ContainSubstring(h))
1779
It("podman run verify pids-limit", func() {
1780
SkipIfCgroupV1("pids-limit not supported on cgroup V1")
1782
session := podmanTest.Podman([]string{"run", "--pids-limit", limit, "--net=none", "--rm", ALPINE, "cat", "/sys/fs/cgroup/pids.max"})
1783
session.WaitWithDefaultTimeout()
1784
Expect(session).Should(ExitCleanly())
1785
Expect(session.OutputToString()).To(ContainSubstring(limit))
1788
It("podman run umask", func() {
1789
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
1790
Skip("Test only works on crun")
1793
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"})
1794
session.WaitWithDefaultTimeout()
1795
Expect(session).Should(ExitCleanly())
1796
Expect(session.OutputToString()).To(Equal("0022"))
1798
session = podmanTest.Podman([]string{"run", "--umask", "0002", "--rm", ALPINE, "sh", "-c", "umask"})
1799
session.WaitWithDefaultTimeout()
1800
Expect(session).Should(ExitCleanly())
1801
Expect(session.OutputToString()).To(Equal("0002"))
1803
session = podmanTest.Podman([]string{"run", "--umask", "0077", "--rm", fedoraMinimal, "umask"})
1804
session.WaitWithDefaultTimeout()
1805
Expect(session).Should(ExitCleanly())
1806
Expect(session.OutputToString()).To(Equal("0077"))
1808
session = podmanTest.Podman([]string{"run", "--umask", "22", "--rm", ALPINE, "sh", "-c", "umask"})
1809
session.WaitWithDefaultTimeout()
1810
Expect(session).Should(ExitCleanly())
1811
Expect(session.OutputToString()).To(Equal("0022"))
1813
session = podmanTest.Podman([]string{"run", "--umask", "9999", "--rm", ALPINE, "sh", "-c", "umask"})
1814
session.WaitWithDefaultTimeout()
1815
Expect(session).To(ExitWithError())
1816
Expect(session.ErrorToString()).To(ContainSubstring("invalid umask"))
1819
It("podman run makes workdir from image", func() {
1820
// BuildImage does not seem to work remote
1821
dockerfile := fmt.Sprintf(`FROM %s
1822
WORKDIR /madethis`, BB)
1823
podmanTest.BuildImage(dockerfile, "test", "false")
1824
session := podmanTest.Podman([]string{"run", "--rm", "test", "pwd"})
1825
session.WaitWithDefaultTimeout()
1826
Expect(session).Should(ExitCleanly())
1827
Expect(session.OutputToString()).To(ContainSubstring("/madethis"))
1830
It("podman run --entrypoint does not use image command", func() {
1831
session := podmanTest.Podman([]string{"run", "--entrypoint", "/bin/echo", ALPINE})
1832
session.WaitWithDefaultTimeout()
1833
Expect(session).Should(ExitCleanly())
1834
// We can't guarantee the output is completely empty, some
1835
// nonprintables seem to work their way in.
1836
Expect(session.OutputToString()).To(Not(ContainSubstring("/bin/sh")))
1839
It("podman run a container with log-level (lower case)", func() {
1840
session := podmanTest.Podman([]string{"--log-level=info", "run", ALPINE, "ls"})
1841
session.WaitWithDefaultTimeout()
1842
Expect(session).Should(Exit(0))
1843
Expect(session.ErrorToString()).To(ContainSubstring(" level=info "))
1846
It("podman run a container with log-level (upper case)", func() {
1847
session := podmanTest.Podman([]string{"--log-level=INFO", "run", ALPINE, "ls"})
1848
session.WaitWithDefaultTimeout()
1849
Expect(session).Should(Exit(0))
1850
Expect(session.ErrorToString()).To(ContainSubstring(" level=info "))
1853
It("podman run a container with --pull never should fail if no local store", func() {
1854
session := podmanTest.Podman([]string{"run", "--pull", "never", "docker.io/library/debian:latest", "ls"})
1855
session.WaitWithDefaultTimeout()
1856
Expect(session).Should(Exit(125))
1859
It("podman run container with --pull missing and only pull once", func() {
1860
session := podmanTest.Podman([]string{"run", "--pull", "missing", CIRROS_IMAGE, "ls"})
1861
session.WaitWithDefaultTimeout()
1862
Expect(session).Should(Exit(0))
1863
Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
1865
session = podmanTest.Podman([]string{"run", "--pull", "missing", CIRROS_IMAGE, "ls"})
1866
session.WaitWithDefaultTimeout()
1867
Expect(session).Should(ExitCleanly())
1870
It("podman run container with --pull missing should pull image multiple times", func() {
1871
session := podmanTest.Podman([]string{"run", "--pull", "always", CIRROS_IMAGE, "ls"})
1872
session.WaitWithDefaultTimeout()
1873
Expect(session).Should(Exit(0))
1874
Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
1876
session = podmanTest.Podman([]string{"run", "--pull", "always", CIRROS_IMAGE, "ls"})
1877
session.WaitWithDefaultTimeout()
1878
Expect(session).Should(Exit(0))
1879
Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
1882
It("podman run container with hostname and hostname environment variable", func() {
1883
hostnameEnv := "test123"
1884
session := podmanTest.Podman([]string{"run", "--hostname", "testctr", "--env", fmt.Sprintf("HOSTNAME=%s", hostnameEnv), ALPINE, "printenv", "HOSTNAME"})
1885
session.WaitWithDefaultTimeout()
1886
Expect(session).Should(ExitCleanly())
1887
Expect(session.OutputToString()).To(ContainSubstring(hostnameEnv))
1890
It("podman run --secret", func() {
1891
secretsString := "somesecretdata"
1892
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
1893
err := os.WriteFile(secretFilePath, []byte(secretsString), 0755)
1894
Expect(err).ToNot(HaveOccurred())
1896
session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
1897
session.WaitWithDefaultTimeout()
1898
Expect(session).Should(ExitCleanly())
1900
session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"})
1901
session.WaitWithDefaultTimeout()
1902
Expect(session).Should(ExitCleanly())
1903
Expect(session.OutputToString()).To(Equal(secretsString))
1905
session = podmanTest.Podman([]string{"inspect", "secr", "--format", " {{(index .Config.Secrets 0).Name}}"})
1906
session.WaitWithDefaultTimeout()
1907
Expect(session).Should(ExitCleanly())
1908
Expect(session.OutputToString()).To(ContainSubstring("mysecret"))
1912
It("podman run --secret source=mysecret,type=mount", func() {
1913
secretsString := "somesecretdata"
1914
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
1915
err := os.WriteFile(secretFilePath, []byte(secretsString), 0755)
1916
Expect(err).ToNot(HaveOccurred())
1918
session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
1919
session.WaitWithDefaultTimeout()
1920
Expect(session).Should(ExitCleanly())
1922
session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"})
1923
session.WaitWithDefaultTimeout()
1924
Expect(session).Should(ExitCleanly())
1925
Expect(session.OutputToString()).To(Equal(secretsString))
1927
session = podmanTest.Podman([]string{"inspect", "secr", "--format", " {{(index .Config.Secrets 0).Name}}"})
1928
session.WaitWithDefaultTimeout()
1929
Expect(session).Should(ExitCleanly())
1930
Expect(session.OutputToString()).To(ContainSubstring("mysecret"))
1934
It("podman run --secret source=mysecret,type=mount with target", func() {
1935
secretsString := "somesecretdata"
1936
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
1937
err := os.WriteFile(secretFilePath, []byte(secretsString), 0755)
1938
Expect(err).ToNot(HaveOccurred())
1940
session := podmanTest.Podman([]string{"secret", "create", "mysecret_target", secretFilePath})
1941
session.WaitWithDefaultTimeout()
1942
Expect(session).Should(ExitCleanly())
1944
session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret_target,type=mount,target=hello", "--name", "secr_target", ALPINE, "cat", "/run/secrets/hello"})
1945
session.WaitWithDefaultTimeout()
1946
Expect(session).Should(ExitCleanly())
1947
Expect(session.OutputToString()).To(Equal(secretsString))
1949
session = podmanTest.Podman([]string{"inspect", "secr_target", "--format", " {{(index .Config.Secrets 0).Name}}"})
1950
session.WaitWithDefaultTimeout()
1951
Expect(session).Should(ExitCleanly())
1952
Expect(session.OutputToString()).To(ContainSubstring("mysecret_target"))
1956
It("podman run --secret source=mysecret,type=mount with target at /tmp", func() {
1957
secretsString := "somesecretdata"
1958
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
1959
err := os.WriteFile(secretFilePath, []byte(secretsString), 0755)
1960
Expect(err).ToNot(HaveOccurred())
1962
session := podmanTest.Podman([]string{"secret", "create", "mysecret_target2", secretFilePath})
1963
session.WaitWithDefaultTimeout()
1964
Expect(session).Should(ExitCleanly())
1966
session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret_target2,type=mount,target=/tmp/hello", "--name", "secr_target2", ALPINE, "cat", "/tmp/hello"})
1967
session.WaitWithDefaultTimeout()
1968
Expect(session).Should(ExitCleanly())
1969
Expect(session.OutputToString()).To(Equal(secretsString))
1971
session = podmanTest.Podman([]string{"inspect", "secr_target2", "--format", " {{(index .Config.Secrets 0).Name}}"})
1972
session.WaitWithDefaultTimeout()
1973
Expect(session).Should(ExitCleanly())
1974
Expect(session.OutputToString()).To(ContainSubstring("mysecret_target2"))
1978
It("podman run --secret source=mysecret,type=env", func() {
1979
secretsString := "somesecretdata"
1980
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
1981
err := os.WriteFile(secretFilePath, []byte(secretsString), 0755)
1982
Expect(err).ToNot(HaveOccurred())
1984
session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
1985
session.WaitWithDefaultTimeout()
1986
Expect(session).Should(ExitCleanly())
1988
session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env", "--name", "secr", ALPINE, "printenv", "mysecret"})
1989
session.WaitWithDefaultTimeout()
1990
Expect(session).Should(ExitCleanly())
1991
Expect(session.OutputToString()).To(Equal(secretsString))
1994
It("podman run --secret target option", func() {
1995
secretsString := "somesecretdata"
1996
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
1997
err := os.WriteFile(secretFilePath, []byte(secretsString), 0755)
1998
Expect(err).ToNot(HaveOccurred())
2000
session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
2001
session.WaitWithDefaultTimeout()
2002
Expect(session).Should(ExitCleanly())
2004
session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env,target=anotherplace", "--name", "secr", ALPINE, "printenv", "anotherplace"})
2005
session.WaitWithDefaultTimeout()
2006
Expect(session).Should(ExitCleanly())
2007
Expect(session.OutputToString()).To(Equal(secretsString))
2010
It("podman run --secret mount with uid, gid, mode options", func() {
2011
secretsString := "somesecretdata"
2012
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
2013
err := os.WriteFile(secretFilePath, []byte(secretsString), 0755)
2014
Expect(err).ToNot(HaveOccurred())
2016
session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
2017
session.WaitWithDefaultTimeout()
2018
Expect(session).Should(ExitCleanly())
2020
// check default permissions
2021
session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "secr", ALPINE, "ls", "-l", "/run/secrets/mysecret"})
2022
session.WaitWithDefaultTimeout()
2023
Expect(session).Should(ExitCleanly())
2024
output := session.OutputToString()
2025
Expect(output).To(ContainSubstring("-r--r--r--"))
2026
Expect(output).To(ContainSubstring("root"))
2028
session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount,uid=1000,gid=1001,mode=777", "--name", "secr2", ALPINE, "ls", "-ln", "/run/secrets/mysecret"})
2029
session.WaitWithDefaultTimeout()
2030
Expect(session).Should(ExitCleanly())
2031
output = session.OutputToString()
2032
Expect(output).To(ContainSubstring("-rwxrwxrwx"))
2033
Expect(output).To(ContainSubstring("1000"))
2034
Expect(output).To(ContainSubstring("1001"))
2037
It("podman run --secret with --user", func() {
2038
secretsString := "somesecretdata"
2039
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
2040
err := os.WriteFile(secretFilePath, []byte(secretsString), 0755)
2041
Expect(err).ToNot(HaveOccurred())
2043
session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
2044
session.WaitWithDefaultTimeout()
2045
Expect(session).Should(ExitCleanly())
2047
session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "nonroot", "--user", "200:200", ALPINE, "cat", "/run/secrets/mysecret"})
2048
session.WaitWithDefaultTimeout()
2049
Expect(session).Should(ExitCleanly())
2050
Expect(session.OutputToString()).To(Equal(secretsString))
2053
It("podman run invalid secret option", func() {
2054
secretsString := "somesecretdata"
2055
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
2056
err := os.WriteFile(secretFilePath, []byte(secretsString), 0755)
2057
Expect(err).ToNot(HaveOccurred())
2059
session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
2060
session.WaitWithDefaultTimeout()
2061
Expect(session).Should(ExitCleanly())
2064
session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=other", "--name", "secr", ALPINE, "printenv", "mysecret"})
2065
session.WaitWithDefaultTimeout()
2066
Expect(session).To(ExitWithError())
2069
session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,invalid=invalid", "--name", "secr", ALPINE, "printenv", "mysecret"})
2070
session.WaitWithDefaultTimeout()
2071
Expect(session).To(ExitWithError())
2073
// Option syntax not valid
2074
session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type", "--name", "secr", ALPINE, "printenv", "mysecret"})
2075
session.WaitWithDefaultTimeout()
2076
Expect(session).To(ExitWithError())
2078
// mount option with env type
2079
session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env,uid=1000", "--name", "secr", ALPINE, "printenv", "mysecret"})
2080
session.WaitWithDefaultTimeout()
2081
Expect(session).To(ExitWithError())
2084
session = podmanTest.Podman([]string{"run", "--secret", "type=env", "--name", "secr", ALPINE, "printenv", "mysecret"})
2085
session.WaitWithDefaultTimeout()
2086
Expect(session).To(ExitWithError())
2089
It("podman run --requires", func() {
2091
depContainer := podmanTest.Podman([]string{"create", "--name", depName, ALPINE, "top"})
2092
depContainer.WaitWithDefaultTimeout()
2093
Expect(depContainer).Should(ExitCleanly())
2096
mainContainer := podmanTest.Podman([]string{"run", "--name", mainName, "--requires", depName, "-d", ALPINE, "top"})
2097
mainContainer.WaitWithDefaultTimeout()
2098
Expect(mainContainer).Should(ExitCleanly())
2100
podmanTest.StopContainer("--all")
2102
start := podmanTest.Podman([]string{"start", mainName})
2103
start.WaitWithDefaultTimeout()
2104
Expect(start).Should(ExitCleanly())
2106
running := podmanTest.Podman([]string{"ps", "-q"})
2107
running.WaitWithDefaultTimeout()
2108
Expect(running).Should(ExitCleanly())
2109
Expect(running.OutputToStringArray()).To(HaveLen(2))
2112
It("podman run with pidfile", func() {
2113
SkipIfRemote("pidfile not handled by remote")
2114
pidfile := filepath.Join(tempdir, "pidfile")
2115
session := podmanTest.Podman([]string{"run", "--pidfile", pidfile, ALPINE, "ls"})
2116
session.WaitWithDefaultTimeout()
2117
Expect(session).Should(ExitCleanly())
2118
readFirstLine := func(path string) string {
2119
content, err := os.ReadFile(path)
2120
Expect(err).ToNot(HaveOccurred())
2121
return strings.Split(string(content), "\n")[0]
2123
containerPID := readFirstLine(pidfile)
2124
_, err = strconv.Atoi(containerPID) // Make sure it's a proper integer
2125
Expect(err).ToNot(HaveOccurred())
2128
It("podman run check personality support", func() {
2129
// TODO: Remove this as soon as this is merged and made available in our CI https://github.com/opencontainers/runc/pull/3126.
2130
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
2131
Skip("Test only works on crun")
2133
session := podmanTest.Podman([]string{"run", "--personality=LINUX32", "--name=testpersonality", ALPINE, "uname", "-a"})
2134
session.WaitWithDefaultTimeout()
2135
Expect(session).Should(ExitCleanly())
2136
Expect(session.OutputToString()).To(ContainSubstring("i686"))
2139
It("podman run /dev/shm has nosuid,noexec,nodev", func() {
2140
session := podmanTest.Podman([]string{"run", ALPINE, "grep", "/dev/shm", "/proc/self/mountinfo"})
2141
session.WaitWithDefaultTimeout()
2142
Expect(session).Should(ExitCleanly())
2143
output := session.OutputToString()
2144
Expect(output).To(ContainSubstring("nosuid"))
2145
Expect(output).To(ContainSubstring("noexec"))
2146
Expect(output).To(ContainSubstring("nodev"))
2149
It("podman run and decrypt from local registry", func() {
2150
SkipIfRemote("Remote run does not support decryption")
2152
if podmanTest.Host.Arch == "ppc64le" {
2153
Skip("No registry image for ppc64le")
2156
podmanTest.AddImageToRWStore(ALPINE)
2158
lock := GetPortLock("5006")
2160
session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5006:5000", REGISTRY_IMAGE, "/entrypoint.sh", "/etc/docker/registry/config.yml"})
2161
session.WaitWithDefaultTimeout()
2162
Expect(session).Should(ExitCleanly())
2164
if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) {
2165
Fail("Cannot start docker registry.")
2169
keyFileName := filepath.Join(podmanTest.TempDir, "key,withcomma")
2170
publicKeyFileName, privateKeyFileName, err := WriteRSAKeyPair(keyFileName, bitSize)
2171
Expect(err).ToNot(HaveOccurred())
2173
imgPath := "localhost:5006/my-alpine"
2174
session = podmanTest.Podman([]string{"push", "--encryption-key", "jwe:" + publicKeyFileName, "--tls-verify=false", "--remove-signatures", ALPINE, imgPath})
2175
session.WaitWithDefaultTimeout()
2177
session = podmanTest.Podman([]string{"rmi", ALPINE})
2178
session.WaitWithDefaultTimeout()
2179
Expect(session).Should(ExitCleanly())
2181
// Must fail without --decryption-key
2182
session = podmanTest.Podman([]string{"run", "--tls-verify=false", imgPath})
2183
session.WaitWithDefaultTimeout()
2184
Expect(session).Should(Exit(125))
2185
Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull " + imgPath))
2186
Expect(session.ErrorToString()).To(ContainSubstring("invalid tar header"))
2189
session = podmanTest.Podman([]string{"run", "--tls-verify=false", "--decryption-key", privateKeyFileName, imgPath})
2190
session.WaitWithDefaultTimeout()
2191
Expect(session).Should(Exit(0))
2192
Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull " + imgPath))
2195
It("podman run --shm-size-systemd", func() {
2196
ctrName := "testShmSizeSystemd"
2197
run := podmanTest.Podman([]string{"run", "--name", ctrName, "--shm-size-systemd", "10mb", "-d", SYSTEMD_IMAGE, "/sbin/init"})
2198
run.WaitWithDefaultTimeout()
2199
Expect(run).Should(ExitCleanly())
2201
logs := podmanTest.Podman([]string{"logs", ctrName})
2202
logs.WaitWithDefaultTimeout()
2203
Expect(logs).Should(ExitCleanly())
2205
mount := podmanTest.Podman([]string{"exec", ctrName, "mount"})
2206
mount.WaitWithDefaultTimeout()
2207
Expect(mount).Should(ExitCleanly())
2208
t, strings := mount.GrepString("tmpfs on /run/lock")
2209
Expect(t).To(BeTrue(), "found /run/lock")
2210
Expect(strings[0]).Should(ContainSubstring("size=10240k"))
2213
It("podman run does not preserve image annotations", func() {
2214
annoName := "test.annotation.present"
2215
annoValue := "annovalue"
2216
imgName := "basicalpine"
2217
build := podmanTest.Podman([]string{"build", "-f", "build/basicalpine/Containerfile.with_label", "--annotation", fmt.Sprintf("%s=%s", annoName, annoValue), "-t", imgName})
2218
build.WaitWithDefaultTimeout()
2219
Expect(build).Should(ExitCleanly())
2220
Expect(build.ErrorToString()).To(BeEmpty(), "build error logged")
2223
run := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, imgName, "top"})
2224
run.WaitWithDefaultTimeout()
2225
Expect(run).Should(ExitCleanly())
2226
Expect(run.ErrorToString()).To(BeEmpty(), "run error logged")
2228
inspect := podmanTest.Podman([]string{"inspect", ctrName})
2229
inspect.WaitWithDefaultTimeout()
2230
Expect(inspect).Should(ExitCleanly())
2231
Expect(inspect.ErrorToString()).To(BeEmpty(), "inspect error logged")
2233
inspectData := inspect.InspectContainerToJSON()
2234
Expect(inspectData).To(HaveLen(1))
2235
Expect(inspectData[0].Config.Annotations).To(Not(HaveKey(annoName)))
2236
Expect(inspectData[0].Config.Annotations).To(Not(HaveKey("testlabel")))