github.com/containers/podman/v4@v4.9.4/test/e2e/containers_conf_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "os/exec" 7 "path/filepath" 8 "strings" 9 "time" 10 11 "github.com/containers/podman/v4/libpod/define" 12 . "github.com/containers/podman/v4/test/utils" 13 . "github.com/onsi/ginkgo/v2" 14 . "github.com/onsi/gomega" 15 . "github.com/onsi/gomega/gbytes" 16 . "github.com/onsi/gomega/gexec" 17 ) 18 19 var _ = Describe("Verify podman containers.conf usage", func() { 20 21 BeforeEach(func() { 22 os.Setenv("CONTAINERS_CONF", "config/containers.conf") 23 if IsRemote() { 24 podmanTest.RestartRemoteService() 25 } 26 27 }) 28 29 It("limits test", func() { 30 SkipIfRootlessCgroupsV1("Setting limits not supported on cgroupv1 for rootless users") 31 // containers.conf is set to "nofile=500:500" 32 session := podmanTest.Podman([]string{"run", "--rm", fedoraMinimal, "ulimit", "-n"}) 33 session.WaitWithDefaultTimeout() 34 Expect(session).Should(ExitCleanly()) 35 Expect(session.OutputToString()).To(ContainSubstring("500")) 36 37 session = podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=2048:2048", fedoraMinimal, "ulimit", "-n"}) 38 session.WaitWithDefaultTimeout() 39 Expect(session).Should(ExitCleanly()) 40 Expect(session.OutputToString()).To(ContainSubstring("2048")) 41 42 // Reset CONTAINERS_CONF to "/dev/null" 43 // Local should go back to defaults but remote should be set on server side 44 os.Setenv("CONTAINERS_CONF", "/dev/null") 45 session = podmanTest.Podman([]string{"run", "--rm", fedoraMinimal, "ulimit", "-n"}) 46 session.WaitWithDefaultTimeout() 47 Expect(session).Should(ExitCleanly()) 48 if IsRemote() { 49 Expect(session.OutputToString()).To(ContainSubstring("500")) 50 } else { 51 Expect(session.OutputToString()).To(Not(Equal("500"))) 52 } 53 54 }) 55 56 It("oom-score-adj", func() { 57 SkipIfRootlessCgroupsV1("Setting limits not supported on cgroupv1 for rootless users") 58 // containers.conf is set to "oom_score_adj=999" 59 session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "cat", "/proc/self/oom_score_adj"}) 60 session.WaitWithDefaultTimeout() 61 Expect(session).Should(ExitCleanly()) 62 Expect(session.OutputToString()).To(Equal("999")) 63 64 raw, err := os.ReadFile("/proc/self/oom_score_adj") 65 Expect(err).ToNot(HaveOccurred()) 66 67 rawS := strings.TrimSuffix(string(raw), "\n") 68 69 // Reset CONTAINERS_CONF to "/dev/null" 70 // Local should go back to defaults but remote should be set on server side 71 os.Setenv("CONTAINERS_CONF", "/dev/null") 72 session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "cat", "/proc/self/oom_score_adj"}) 73 session.WaitWithDefaultTimeout() 74 Expect(session).Should(ExitCleanly()) 75 if IsRemote() { 76 Expect(session.OutputToString()).To(Equal("999")) 77 } else { 78 if isRootless() { 79 Expect(session.OutputToString()).To(ContainSubstring(rawS)) 80 } else { 81 Expect(session.OutputToString()).To(ContainSubstring("0")) 82 } 83 84 } 85 86 }) 87 88 It("cgroup_conf in containers.conf", func() { 89 if isCgroupsV1() { 90 Skip("Setting cgroup_confs not supported on cgroupv1") 91 } 92 // FIXME: Needs crun-1.8.2-2 to allow this with --cgroup-manager=cgroupfs, once this is available remove the skip below. 93 SkipIfRootless("--cgroup-manager=cgoupfs and --cgroup-conf not supported in rootless mode with crun") 94 conffile := filepath.Join(podmanTest.TempDir, "container.conf") 95 96 err := os.WriteFile(conffile, []byte("[containers]\ncgroup_conf = [\"pids.max=1234\",]\n"), 0755) 97 Expect(err).ToNot(HaveOccurred()) 98 99 os.Setenv("CONTAINERS_CONF_OVERRIDE", conffile) 100 if IsRemote() { 101 podmanTest.RestartRemoteService() 102 } 103 104 // containers.conf is set to "pids.max=1234" 105 session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "cat", "/sys/fs/cgroup/pids.max"}) 106 session.WaitWithDefaultTimeout() 107 Expect(session).Should(ExitCleanly()) 108 Expect(session.OutputToString()).To(Equal("1234")) 109 110 session = podmanTest.Podman([]string{"run", "--rm", "--cgroup-conf", "pids.max=400", ALPINE, "cat", "/sys/fs/cgroup/pids.max"}) 111 session.WaitWithDefaultTimeout() 112 Expect(session).Should(ExitCleanly()) 113 Expect(session.OutputToString()).To(Equal("400")) 114 }) 115 116 It("having additional env", func() { 117 // containers.conf default env includes foo 118 session := podmanTest.Podman([]string{"run", ALPINE, "printenv"}) 119 session.WaitWithDefaultTimeout() 120 Expect(session).Should(ExitCleanly()) 121 Expect(session.OutputToString()).To(ContainSubstring("foo=bar")) 122 }) 123 124 It("additional devices", func() { 125 // containers.conf devices includes notone 126 session := podmanTest.Podman([]string{"run", "--device", "/dev/null:/dev/bar", ALPINE, "ls", "/dev"}) 127 session.WaitWithDefaultTimeout() 128 Expect(session).Should(ExitCleanly()) 129 Expect(session.OutputToString()).To( 130 And( 131 ContainSubstring("bar"), 132 ContainSubstring("notone"), 133 )) 134 }) 135 136 It("shm-size", func() { 137 // containers.conf default sets shm-size=201k, which ends up as 200k 138 session := podmanTest.Podman([]string{"run", ALPINE, "grep", "shm", "/proc/self/mounts"}) 139 session.WaitWithDefaultTimeout() 140 Expect(session).Should(ExitCleanly()) 141 Expect(session.OutputToString()).To(ContainSubstring("size=200k")) 142 143 session = podmanTest.Podman([]string{"run", "--shm-size", "1g", ALPINE, "grep", "shm", "/proc/self/mounts"}) 144 session.WaitWithDefaultTimeout() 145 Expect(session).Should(ExitCleanly()) 146 Expect(session.OutputToString()).To(ContainSubstring("size=1048576k")) 147 }) 148 149 It("add capabilities", func() { 150 SkipIfRootlessCgroupsV1("Not supported for rootless + CGroupsV1") 151 cap := podmanTest.Podman([]string{"run", ALPINE, "grep", "CapEff", "/proc/self/status"}) 152 cap.WaitWithDefaultTimeout() 153 Expect(cap).Should(ExitCleanly()) 154 155 os.Setenv("CONTAINERS_CONF", "config/containers-ns.conf") 156 if IsRemote() { 157 podmanTest.RestartRemoteService() 158 } 159 session := podmanTest.Podman([]string{"run", BB, "grep", "CapEff", "/proc/self/status"}) 160 session.WaitWithDefaultTimeout() 161 Expect(session).Should(ExitCleanly()) 162 Expect(session.OutputToString()).ToNot(Equal(cap.OutputToString())) 163 }) 164 165 It("regular capabilities", func() { 166 setup := podmanTest.RunTopContainer("test1") 167 setup.WaitWithDefaultTimeout() 168 result := podmanTest.Podman([]string{"top", "test1", "capeff"}) 169 result.WaitWithDefaultTimeout() 170 Expect(result).Should(ExitCleanly()) 171 Expect(result.OutputToString()).To( 172 And( 173 ContainSubstring("FOWNER"), 174 ContainSubstring("SETFCAP"), 175 )) 176 }) 177 178 It("drop capabilities", func() { 179 os.Setenv("CONTAINERS_CONF", "config/containers-caps.conf") 180 if IsRemote() { 181 podmanTest.RestartRemoteService() 182 } 183 setup := podmanTest.RunTopContainer("test1") 184 setup.WaitWithDefaultTimeout() 185 result := podmanTest.Podman([]string{"container", "top", "test1", "capeff"}) 186 result.WaitWithDefaultTimeout() 187 Expect(result).Should(ExitCleanly()) 188 Expect(result.OutputToString()).ToNot( 189 And( 190 ContainSubstring("SETUID"), 191 ContainSubstring("FOWNER"), 192 )) 193 }) 194 195 verifyNSHandling := func(nspath, option string) { 196 SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1") 197 os.Setenv("CONTAINERS_CONF", "config/containers-ns.conf") 198 if IsRemote() { 199 podmanTest.RestartRemoteService() 200 } 201 // containers.conf default ipcns to default to host 202 session := podmanTest.Podman([]string{"run", ALPINE, "ls", "-l", nspath}) 203 session.WaitWithDefaultTimeout() 204 Expect(session).Should(ExitCleanly()) 205 fields := strings.Split(session.OutputToString(), " ") 206 ctrNS := strings.TrimSuffix(fields[len(fields)-1], "\n") 207 208 cmd := exec.Command("ls", "-l", nspath) 209 res, err := cmd.Output() 210 Expect(err).ToNot(HaveOccurred()) 211 fields = strings.Split(string(res), " ") 212 hostNS := strings.TrimSuffix(fields[len(fields)-1], "\n") 213 Expect(hostNS).To(Equal(ctrNS)) 214 215 session = podmanTest.Podman([]string{"run", option, "private", ALPINE, "ls", "-l", nspath}) 216 session.WaitWithDefaultTimeout() 217 Expect(session).Should(ExitCleanly()) 218 fields = strings.Split(session.OutputToString(), " ") 219 ctrNS = fields[len(fields)-1] 220 Expect(hostNS).ToNot(Equal(ctrNS)) 221 } 222 223 It("netns", func() { 224 verifyNSHandling("/proc/self/ns/net", "--network") 225 }) 226 227 It("ipcns", func() { 228 verifyNSHandling("/proc/self/ns/ipc", "--ipc") 229 }) 230 231 It("utsns", func() { 232 verifyNSHandling("/proc/self/ns/uts", "--uts") 233 }) 234 235 It("pidns", func() { 236 verifyNSHandling("/proc/self/ns/pid", "--pid") 237 }) 238 239 It("cgroupns", func() { 240 verifyNSHandling("/proc/self/ns/cgroup", "--cgroupns") 241 }) 242 243 It("using journald for container with container log_tag", func() { 244 SkipIfJournaldUnavailable() 245 os.Setenv("CONTAINERS_CONF", "config/containers-journald.conf") 246 if IsRemote() { 247 podmanTest.RestartRemoteService() 248 } 249 logc := podmanTest.Podman([]string{"run", "-d", ALPINE, "sh", "-c", "echo podman; sleep 0.1; echo podman; sleep 0.1; echo podman"}) 250 logc.WaitWithDefaultTimeout() 251 Expect(logc).Should(ExitCleanly()) 252 cid := logc.OutputToString() 253 254 wait := podmanTest.Podman([]string{"wait", cid}) 255 wait.WaitWithDefaultTimeout() 256 Expect(wait).Should(ExitCleanly()) 257 258 // Flake prevention: journalctl makes no timeliness guarantees. 259 time.Sleep(1 * time.Second) 260 cmd := exec.Command("journalctl", "--no-pager", "-o", "json", "--output-fields=CONTAINER_TAG", fmt.Sprintf("CONTAINER_ID_FULL=%s", cid)) 261 out, err := cmd.CombinedOutput() 262 Expect(err).ToNot(HaveOccurred()) 263 Expect(out).To(ContainSubstring("alpine")) 264 }) 265 266 It("add volumes", func() { 267 conffile := filepath.Join(podmanTest.TempDir, "container.conf") 268 269 volume := filepath.Join(podmanTest.TempDir, "vol") 270 err = os.MkdirAll(volume, os.ModePerm) 271 Expect(err).ToNot(HaveOccurred()) 272 err := os.WriteFile(conffile, []byte(fmt.Sprintf("[containers]\nvolumes=[\"%s:%s:Z\",]\n", volume, volume)), 0755) 273 Expect(err).ToNot(HaveOccurred()) 274 275 os.Setenv("CONTAINERS_CONF", conffile) 276 if IsRemote() { 277 podmanTest.RestartRemoteService() 278 } 279 result := podmanTest.Podman([]string{"run", ALPINE, "ls", volume}) 280 result.WaitWithDefaultTimeout() 281 Expect(result).Should(ExitCleanly()) 282 }) 283 284 It("sysctl test", func() { 285 // containers.conf is set to "net.ipv4.ping_group_range=0 1000" 286 session := podmanTest.Podman([]string{"run", "--rm", fedoraMinimal, "cat", "/proc/sys/net/ipv4/ping_group_range"}) 287 session.WaitWithDefaultTimeout() 288 Expect(session).Should(ExitCleanly()) 289 Expect(session.OutputToString()).To(ContainSubstring("1000")) 290 291 // Ignore containers.conf setting if --net=host 292 session = podmanTest.Podman([]string{"run", "--rm", "--net", "host", fedoraMinimal, "cat", "/proc/sys/net/ipv4/ping_group_range"}) 293 session.WaitWithDefaultTimeout() 294 Expect(session).Should(ExitCleanly()) 295 Expect(session.OutputToString()).ToNot(ContainSubstring("1000")) 296 }) 297 298 It("search domain", func() { 299 session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"}) 300 session.WaitWithDefaultTimeout() 301 Expect(session).Should(ExitCleanly()) 302 Expect(session.OutputToStringArray()).To(ContainElement(HavePrefix("search foobar.com"))) 303 }) 304 305 It("add dns server", func() { 306 session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"}) 307 session.WaitWithDefaultTimeout() 308 Expect(session).Should(ExitCleanly()) 309 Expect(session.OutputToStringArray()).To(ContainElement(HavePrefix("nameserver 1.2.3.4"))) 310 }) 311 312 It("add dns option", func() { 313 session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"}) 314 session.WaitWithDefaultTimeout() 315 Expect(session).Should(ExitCleanly()) 316 Expect(session.OutputToStringArray()).To(ContainElement(HavePrefix("options debug"))) 317 }) 318 319 It("remove all search domain", func() { 320 session := podmanTest.Podman([]string{"run", "--dns-search=.", ALPINE, "cat", "/etc/resolv.conf"}) 321 session.WaitWithDefaultTimeout() 322 Expect(session).Should(ExitCleanly()) 323 Expect(session.OutputToStringArray()).To(Not(ContainElement(HavePrefix("search")))) 324 }) 325 326 It("add search domain", func() { 327 session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"}) 328 session.WaitWithDefaultTimeout() 329 Expect(session).Should(ExitCleanly()) 330 Expect(session.OutputToStringArray()).To(ContainElement(HavePrefix("search"))) 331 Expect(session.OutputToString()).To( 332 And( 333 ContainSubstring("foobar.com"), 334 ContainSubstring("1.2.3.4"), 335 ContainSubstring("debug"), 336 )) 337 }) 338 339 It("add timezone", func() { 340 // containers.conf timezone set to Pacific/Honolulu 341 session := podmanTest.Podman([]string{"run", "--tz", "", ALPINE, "date", "+'%H %Z'"}) 342 session.WaitWithDefaultTimeout() 343 Expect(session).Should(ExitCleanly()) 344 Expect(session.OutputToString()).To(ContainSubstring("HST")) 345 346 // verify flag still overrides 347 session = podmanTest.Podman([]string{"run", "--tz", "EST", ALPINE, "date", "+'%H %Z'"}) 348 session.WaitWithDefaultTimeout() 349 Expect(session).Should(ExitCleanly()) 350 Expect(session.OutputToString()).To(ContainSubstring("EST")) 351 }) 352 353 It("add umask", func() { 354 // containers.conf umask set to 0002 355 if !strings.Contains(podmanTest.OCIRuntime, "crun") { 356 Skip("Test only works on crun") 357 } 358 359 session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"}) 360 session.WaitWithDefaultTimeout() 361 Expect(session).Should(ExitCleanly()) 362 Expect(session.OutputToString()).To(Equal("0002")) 363 }) 364 365 It("network slirp options to allow host loopback", func() { 366 session := podmanTest.Podman([]string{"run", "--network", "slirp4netns", ALPINE, "ping", "-c1", "10.0.2.2"}) 367 session.Wait(30) 368 Expect(session).Should(ExitCleanly()) 369 }) 370 371 It("podman-remote test localcontainers.conf", func() { 372 SkipIfNotRemote("this test is only for remote") 373 374 os.Setenv("CONTAINERS_CONF", "config/containers-remote.conf") 375 // Configuration that comes from remote server 376 // env 377 session := podmanTest.Podman([]string{"run", ALPINE, "printenv", "foo"}) 378 session.WaitWithDefaultTimeout() 379 Expect(session).Should(ExitCleanly()) 380 Expect(session.OutputToString()).To(Equal("bar")) 381 382 // dns-search, server, options 383 session = podmanTest.Podman([]string{"run", ALPINE, "cat", "/etc/resolv.conf"}) 384 session.WaitWithDefaultTimeout() 385 Expect(session).Should(ExitCleanly()) 386 Expect(session.OutputToStringArray()).To(ContainElement(HavePrefix("search"))) 387 Expect(session.OutputToString()).To( 388 And( 389 ContainSubstring("foobar.com"), 390 ContainSubstring("1.2.3.4"), 391 ContainSubstring("debug"), 392 )) 393 394 // sysctls 395 session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "cat", "/proc/sys/net/ipv4/ping_group_range"}) 396 session.WaitWithDefaultTimeout() 397 Expect(session).Should(ExitCleanly()) 398 Expect(session.OutputToString()).To(ContainSubstring("1000")) 399 400 // shm-size 401 session = podmanTest.Podman([]string{"run", ALPINE, "grep", "shm", "/proc/self/mounts"}) 402 session.WaitWithDefaultTimeout() 403 Expect(session).Should(ExitCleanly()) 404 Expect(session.OutputToString()).To(ContainSubstring("size=200k")) 405 406 // ulimits 407 session = podmanTest.Podman([]string{"run", "--rm", fedoraMinimal, "ulimit", "-n"}) 408 session.WaitWithDefaultTimeout() 409 Expect(session).Should(ExitCleanly()) 410 Expect(session.OutputToString()).To(ContainSubstring("500")) 411 412 // Configuration that comes from remote client 413 // Timezone 414 session = podmanTest.Podman([]string{"run", ALPINE, "date", "+'%H %Z'"}) 415 session.WaitWithDefaultTimeout() 416 Expect(session).Should(ExitCleanly()) 417 Expect(session.OutputToString()).To( 418 Or( 419 ContainSubstring("EST"), 420 ContainSubstring("EDT"), 421 )) 422 423 // Umask 424 session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"}) 425 session.WaitWithDefaultTimeout() 426 Expect(session).Should(ExitCleanly()) 427 Expect(session.OutputToString()).To(Equal("0022")) 428 }) 429 430 It("add annotations", func() { 431 // containers.conf is set to "run.oci.keep_original_groups=1" 432 session := podmanTest.Podman([]string{"create", "--rm", "--name", "test", fedoraMinimal}) 433 session.WaitWithDefaultTimeout() 434 Expect(session).Should(ExitCleanly()) 435 436 inspect := podmanTest.Podman([]string{"inspect", "--format", "{{ .Config.Annotations }}", "test"}) 437 inspect.WaitWithDefaultTimeout() 438 Expect(inspect.OutputToString()).To(ContainSubstring(fmt.Sprintf("%s:1", define.RunOCIKeepOriginalGroups))) 439 }) 440 441 It("--add-host and no-hosts=true fails", func() { 442 session := podmanTest.Podman([]string{"run", "-dt", "--add-host", "test1:127.0.0.1", ALPINE, "top"}) 443 session.WaitWithDefaultTimeout() 444 Expect(session).To(ExitWithError()) 445 Expect(session.ErrorToString()).To(ContainSubstring("--no-hosts and --add-host cannot be set together")) 446 447 session = podmanTest.Podman([]string{"run", "-dt", "--add-host", "test1:127.0.0.1", "--no-hosts=false", ALPINE, "top"}) 448 session.WaitWithDefaultTimeout() 449 Expect(session).Should(ExitCleanly()) 450 }) 451 452 It("no-hosts=true /etc/hosts does not include hostname", func() { 453 session := podmanTest.Podman([]string{"run", "--rm", "--name", "test", ALPINE, "cat", "/etc/hosts"}) 454 session.WaitWithDefaultTimeout() 455 Expect(session).Should(ExitCleanly()) 456 Expect(session.OutputToString()).ToNot(ContainSubstring("test")) 457 458 session = podmanTest.Podman([]string{"run", "--rm", "--name", "test", "--no-hosts=false", ALPINE, "cat", "/etc/hosts"}) 459 session.WaitWithDefaultTimeout() 460 Expect(session).Should(ExitCleanly()) 461 Expect(session.OutputToString()).To(ContainSubstring("test")) 462 }) 463 464 It("seccomp profile path", func() { 465 configPath := filepath.Join(podmanTest.TempDir, "containers.conf") 466 os.Setenv("CONTAINERS_CONF", configPath) 467 468 profile := filepath.Join(podmanTest.TempDir, "seccomp.json") 469 containersConf := []byte(fmt.Sprintf("[containers]\nseccomp_profile=\"%s\"", profile)) 470 err = os.WriteFile(configPath, containersConf, os.ModePerm) 471 Expect(err).ToNot(HaveOccurred()) 472 473 if IsRemote() { 474 podmanTest.RestartRemoteService() 475 } 476 477 session := podmanTest.Podman([]string{"info", "--format", "{{.Host.Security.SECCOMPProfilePath}}"}) 478 session.WaitWithDefaultTimeout() 479 Expect(session).Should(ExitCleanly()) 480 Expect(session.OutputToString()).To(Equal(profile)) 481 }) 482 483 It("add image_copy_tmp_dir", func() { 484 // Prevents overwriting of TMPDIR environment 485 if cacheDir, found := os.LookupEnv("TMPDIR"); found { 486 defer os.Setenv("TMPDIR", cacheDir) 487 os.Unsetenv("TMPDIR") 488 } else { 489 defer os.Unsetenv("TMPDIR") 490 } 491 if IsRemote() { 492 podmanTest.RestartRemoteService() 493 } 494 495 session := podmanTest.Podman([]string{"info", "--format", "{{.Store.ImageCopyTmpDir}}"}) 496 session.WaitWithDefaultTimeout() 497 Expect(session).Should(ExitCleanly()) 498 Expect(session.OutputToString()).To(Equal("/var/tmp")) 499 500 storagePath := filepath.Join(podmanTest.TempDir, "storage") 501 configPath := filepath.Join(podmanTest.TempDir, "containers.conf") 502 os.Setenv("CONTAINERS_CONF", configPath) 503 504 containersConf := []byte("[engine]\nimage_copy_tmp_dir=\"/foobar\"") 505 err = os.WriteFile(configPath, containersConf, os.ModePerm) 506 Expect(err).ToNot(HaveOccurred()) 507 508 if IsRemote() { 509 podmanTest.RestartRemoteService() 510 } 511 512 session = podmanTest.Podman([]string{"info", "--format", "{{.Store.ImageCopyTmpDir}}"}) 513 session.WaitWithDefaultTimeout() 514 Expect(session).Should(ExitCleanly()) 515 Expect(session.OutputToString()).To(Equal("/foobar")) 516 517 containersConf = []byte(fmt.Sprintf("[engine]\nimage_copy_tmp_dir=%q", storagePath)) 518 err = os.WriteFile(configPath, containersConf, os.ModePerm) 519 Expect(err).ToNot(HaveOccurred()) 520 if IsRemote() { 521 podmanTest.RestartRemoteService() 522 } 523 524 session = podmanTest.Podman([]string{"info", "--format", "{{.Store.ImageCopyTmpDir}}"}) 525 session.WaitWithDefaultTimeout() 526 Expect(session).Should(ExitCleanly()) 527 Expect(session.OutputToString()).To(ContainSubstring(storagePath)) 528 529 containersConf = []byte("[engine]\nimage_copy_tmp_dir=\"storage1\"") 530 err = os.WriteFile(configPath, containersConf, os.ModePerm) 531 Expect(err).ToNot(HaveOccurred()) 532 533 if !IsRemote() { 534 session = podmanTest.Podman([]string{"info", "--format", "{{.Store.ImageCopyTmpDir}}"}) 535 session.WaitWithDefaultTimeout() 536 Expect(session).Should(Exit(125)) 537 Expect(session.ErrorToString()).To(ContainSubstring("invalid image_copy_tmp_dir value \"storage1\" (relative paths are not accepted)")) 538 539 os.Setenv("TMPDIR", "/hoge") 540 session = podmanTest.Podman([]string{"info", "--format", "{{.Store.ImageCopyTmpDir}}"}) 541 session.WaitWithDefaultTimeout() 542 Expect(session).Should(ExitCleanly()) 543 Expect(session.OutputToString()).To(Equal("/hoge")) 544 os.Unsetenv("TMPDIR") 545 } 546 }) 547 548 // FIXME not sure why this is here 549 It("system service --help shows (default 20)", func() { 550 SkipIfRemote("system service is not supported on clients") 551 552 result := podmanTest.Podman([]string{"system", "service", "--help"}) 553 result.WaitWithDefaultTimeout() 554 Expect(result).Should(ExitCleanly()) 555 Expect(result.OutputToString()).To(ContainSubstring("(default 1234)")) 556 }) 557 558 It("bad infra_image name", func() { 559 infra1 := "i.do/not/exist:image" 560 infra2 := "i.still.do/not/exist:image" 561 errorString := "initializing source docker://" + infra1 562 error2String := "initializing source docker://" + infra2 563 configPath := filepath.Join(podmanTest.TempDir, "containers.conf") 564 os.Setenv("CONTAINERS_CONF", configPath) 565 566 containersConf := []byte("[engine]\ninfra_image=\"" + infra1 + "\"") 567 err = os.WriteFile(configPath, containersConf, os.ModePerm) 568 Expect(err).ToNot(HaveOccurred()) 569 570 if IsRemote() { 571 podmanTest.RestartRemoteService() 572 } 573 574 result := podmanTest.Podman([]string{"pod", "create", "--infra-image", infra2}) 575 result.WaitWithDefaultTimeout() 576 Expect(result).Should(Exit(125)) 577 Expect(result.ErrorToString()).To(ContainSubstring(error2String)) 578 579 result = podmanTest.Podman([]string{"pod", "create"}) 580 result.WaitWithDefaultTimeout() 581 Expect(result).Should(Exit(125)) 582 Expect(result.ErrorToString()).To(ContainSubstring(errorString)) 583 584 result = podmanTest.Podman([]string{"create", "--pod", "new:pod1", ALPINE}) 585 result.WaitWithDefaultTimeout() 586 Expect(result).Should(Exit(125)) 587 Expect(result.ErrorToString()).To(ContainSubstring(errorString)) 588 }) 589 590 It("set .engine.remote=true", func() { 591 SkipIfRemote("only meaningful when running ABI/local") 592 593 // Need to restore CONTAINERS_CONF or AfterEach() will fail 594 if path, found := os.LookupEnv("CONTAINERS_CONF"); found { 595 defer os.Setenv("CONTAINERS_CONF", path) 596 } 597 598 configPath := filepath.Join(podmanTest.TempDir, "containers-engine-remote.conf") 599 os.Setenv("CONTAINERS_CONF", configPath) 600 defer os.Remove(configPath) 601 602 err := os.WriteFile(configPath, []byte("[engine]\nremote=true"), os.ModePerm) 603 Expect(err).ToNot(HaveOccurred()) 604 605 // podmanTest.Podman() cannot be used as it was initialized remote==false 606 cmd := exec.Command(podmanTest.PodmanBinary, "info", "--format", "{{.Host.ServiceIsRemote}}") 607 session, err := Start(cmd, GinkgoWriter, GinkgoWriter) 608 Expect(err).ToNot(HaveOccurred()) 609 610 description := "Should have failed as there is no running remote API service available." 611 Eventually(session, DefaultWaitTimeout).Should(Exit(125), description) 612 Expect(session.Err).Should(Say("Error: unable to connect to Podman socket")) 613 }) 614 615 It("podman containers.conf cgroups=disabled", func() { 616 if !strings.Contains(podmanTest.OCIRuntime, "crun") { 617 // Assume this will never be fixed in runc 618 Skip("NoCgroups requires crun") 619 } 620 621 conffile := filepath.Join(podmanTest.TempDir, "container.conf") 622 err := os.WriteFile(conffile, []byte("[containers]\ncgroups=\"disabled\"\n"), 0755) 623 Expect(err).ToNot(HaveOccurred()) 624 625 result := podmanTest.Podman([]string{"create", ALPINE, "true"}) 626 result.WaitWithDefaultTimeout() 627 Expect(result).Should(ExitCleanly()) 628 629 inspect := podmanTest.Podman([]string{"inspect", "--format", "{{ .HostConfig.Cgroups }}", result.OutputToString()}) 630 inspect.WaitWithDefaultTimeout() 631 Expect(inspect.OutputToString()).ToNot(Equal("disabled")) 632 633 os.Setenv("CONTAINERS_CONF", conffile) 634 if IsRemote() { 635 podmanTest.RestartRemoteService() 636 } 637 result = podmanTest.Podman([]string{"create", ALPINE, "true"}) 638 result.WaitWithDefaultTimeout() 639 Expect(result).Should(ExitCleanly()) 640 641 inspect = podmanTest.Podman([]string{"inspect", "--format", "{{ .HostConfig.Cgroups }}", result.OutputToString()}) 642 inspect.WaitWithDefaultTimeout() 643 Expect(inspect.OutputToString()).To(Equal("disabled")) 644 645 // Check we can also create a pod when cgroups=disabled 646 result = podmanTest.Podman([]string{"pod", "create"}) 647 result.WaitWithDefaultTimeout() 648 Expect(result).Should(ExitCleanly()) 649 }) 650 651 It("podman containers.conf runtime", func() { 652 SkipIfRemote("--runtime option is not available for remote commands") 653 conffile := filepath.Join(podmanTest.TempDir, "container.conf") 654 err := os.WriteFile(conffile, []byte("[engine]\nruntime=\"testruntime\"\n"), 0755) 655 Expect(err).ToNot(HaveOccurred()) 656 657 os.Setenv("CONTAINERS_CONF", conffile) 658 result := podmanTest.Podman([]string{"--help"}) 659 result.WaitWithDefaultTimeout() 660 Expect(result).Should(ExitCleanly()) 661 Expect(result.OutputToString()).To(ContainSubstring("Path to the OCI-compatible binary used to run containers. (default \"testruntime\")")) 662 }) 663 664 It("podman default_rootless_network_cmd", func() { 665 SkipIfNotRootless("default_rootless_network_cmd is only used rootless") 666 667 for _, mode := range []string{"pasta", "slirp4netns", "invalid"} { 668 conffile := filepath.Join(podmanTest.TempDir, "container.conf") 669 content := "[network]\ndefault_rootless_network_cmd=\"" + mode + "\"\n" 670 err := os.WriteFile(conffile, []byte(content), 0755) 671 Expect(err).ToNot(HaveOccurred()) 672 673 os.Setenv("CONTAINERS_CONF_OVERRIDE", conffile) 674 if IsRemote() { 675 podmanTest.RestartRemoteService() 676 } 677 678 podman := podmanTest.Podman([]string{"create", "--name", mode, ALPINE, "ip", "addr"}) 679 podman.WaitWithDefaultTimeout() 680 681 if mode == "invalid" { 682 Expect(podman).Should(Exit(125)) 683 Expect(podman.ErrorToString()).Should(ContainSubstring("invalid default_rootless_network_cmd option \"invalid\"")) 684 continue 685 } 686 Expect(podman).Should(ExitCleanly()) 687 688 inspect := podmanTest.Podman([]string{"inspect", "--format", "{{.HostConfig.NetworkMode}}", mode}) 689 inspect.WaitWithDefaultTimeout() 690 Expect(inspect).Should(ExitCleanly()) 691 Expect(inspect.OutputToString()).Should(Equal(mode)) 692 } 693 }) 694 })