github.com/containers/podman/v5@v5.1.0-rc1/test/e2e/generate_kube_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "os/user" 7 "path/filepath" 8 "strconv" 9 "strings" 10 11 "github.com/containers/podman/v5/libpod/define" 12 13 v1 "github.com/containers/podman/v5/pkg/k8s.io/api/core/v1" 14 "github.com/containers/podman/v5/pkg/util" 15 . "github.com/containers/podman/v5/test/utils" 16 . "github.com/onsi/ginkgo/v2" 17 . "github.com/onsi/gomega" 18 "sigs.k8s.io/yaml" 19 ) 20 21 var _ = Describe("Podman kube generate", func() { 22 23 It("pod on bogus object", func() { 24 session := podmanTest.Podman([]string{"generate", "kube", "foobarpod"}) 25 session.WaitWithDefaultTimeout() 26 Expect(session).To(ExitWithError(125, `name or ID "foobarpod" not found`)) 27 }) 28 29 It("service on bogus object", func() { 30 session := podmanTest.Podman([]string{"kube", "generate", "-s", "foobarservice"}) 31 session.WaitWithDefaultTimeout() 32 Expect(session).To(ExitWithError(125, `name or ID "foobarservice" not found`)) 33 }) 34 35 It("on container", func() { 36 session := podmanTest.RunTopContainer("top") 37 session.WaitWithDefaultTimeout() 38 Expect(session).Should(ExitCleanly()) 39 40 kube := podmanTest.Podman([]string{"kube", "generate", "top"}) 41 kube.WaitWithDefaultTimeout() 42 Expect(kube).Should(ExitCleanly()) 43 44 pod := new(v1.Pod) 45 err := yaml.Unmarshal(kube.Out.Contents(), pod) 46 Expect(err).ToNot(HaveOccurred()) 47 Expect(pod.Spec).To(HaveField("HostNetwork", false)) 48 Expect(pod.Spec.SecurityContext).To(BeNil()) 49 Expect(pod.Spec.DNSConfig).To(BeNil()) 50 Expect(pod.Spec.Containers[0]).To(HaveField("WorkingDir", "")) 51 Expect(pod.Spec.Containers[0].SecurityContext).To(BeNil()) 52 Expect(pod.Spec.Containers[0].Env).To(BeNil()) 53 Expect(pod).To(HaveField("Name", "top-pod")) 54 Expect(pod.Spec.TerminationGracePeriodSeconds).To(BeNil()) 55 56 numContainers := 0 57 for range pod.Spec.Containers { 58 numContainers++ 59 } 60 Expect(numContainers).To(Equal(1)) 61 }) 62 63 It("service on container with --security-opt level", func() { 64 session := podmanTest.Podman([]string{"create", "--name", "test", "--security-opt", "label=level:s0:c100,c200", CITEST_IMAGE}) 65 session.WaitWithDefaultTimeout() 66 Expect(session).Should(ExitCleanly()) 67 68 kube := podmanTest.Podman([]string{"kube", "generate", "test"}) 69 kube.WaitWithDefaultTimeout() 70 Expect(kube).Should(ExitCleanly()) 71 72 pod := new(v1.Pod) 73 err := yaml.Unmarshal(kube.Out.Contents(), pod) 74 Expect(err).ToNot(HaveOccurred()) 75 Expect(kube.OutputToString()).To(ContainSubstring("level: s0:c100,c200")) 76 }) 77 78 It("service kube on container with --security-opt disable", func() { 79 session := podmanTest.Podman([]string{"create", "--name", "test-disable", "--security-opt", "label=disable", CITEST_IMAGE}) 80 session.WaitWithDefaultTimeout() 81 Expect(session).Should(ExitCleanly()) 82 83 kube := podmanTest.Podman([]string{"kube", "generate", "test-disable"}) 84 kube.WaitWithDefaultTimeout() 85 Expect(kube).Should(ExitCleanly()) 86 87 pod := new(v1.Pod) 88 err = yaml.Unmarshal(kube.Out.Contents(), pod) 89 Expect(err).ToNot(HaveOccurred()) 90 Expect(kube.OutputToString()).To(ContainSubstring("type: spc_t")) 91 92 }) 93 94 It("service kube on container with --security-opt type", func() { 95 session := podmanTest.Podman([]string{"create", "--name", "test", "--security-opt", "label=type:foo_bar_t", CITEST_IMAGE}) 96 session.WaitWithDefaultTimeout() 97 Expect(session).Should(ExitCleanly()) 98 99 kube := podmanTest.Podman([]string{"kube", "generate", "test"}) 100 kube.WaitWithDefaultTimeout() 101 Expect(kube).Should(ExitCleanly()) 102 103 pod := new(v1.Pod) 104 err = yaml.Unmarshal(kube.Out.Contents(), pod) 105 Expect(err).ToNot(HaveOccurred()) 106 Expect(kube.OutputToString()).To(ContainSubstring("type: foo_bar_t")) 107 }) 108 109 It("service kube on container - targetPort should match port name", func() { 110 session := podmanTest.Podman([]string{"create", "--name", "test-ctr", "-p", "3890:3890", CITEST_IMAGE, "ls"}) 111 session.WaitWithDefaultTimeout() 112 Expect(session).Should(ExitCleanly()) 113 114 kube := podmanTest.Podman([]string{"kube", "generate", "-s", "test-ctr"}) 115 kube.WaitWithDefaultTimeout() 116 Expect(kube).Should(ExitCleanly()) 117 118 // Separate out the Service and Pod yaml 119 arr := strings.Split(string(kube.Out.Contents()), "---") 120 Expect(arr).To(HaveLen(2)) 121 122 svc := new(v1.Service) 123 err := yaml.Unmarshal([]byte(arr[0]), svc) 124 Expect(err).ToNot(HaveOccurred()) 125 Expect(svc.Spec.Ports).To(HaveLen(1)) 126 Expect(svc.Spec.Ports[0].TargetPort.IntValue()).To(Equal(3890)) 127 128 pod := new(v1.Pod) 129 err = yaml.Unmarshal([]byte(arr[1]), pod) 130 Expect(err).ToNot(HaveOccurred()) 131 }) 132 133 It("on container with and without service", func() { 134 session := podmanTest.Podman([]string{"create", "--name", "test-ctr", "-p", "3890:3890", CITEST_IMAGE, "ls"}) 135 session.WaitWithDefaultTimeout() 136 Expect(session).Should(ExitCleanly()) 137 138 kube := podmanTest.Podman([]string{"kube", "generate", "-s", "test-ctr"}) 139 kube.WaitWithDefaultTimeout() 140 Expect(kube).Should(ExitCleanly()) 141 142 // Separate out the Service and Pod yaml 143 arr := strings.Split(string(kube.Out.Contents()), "---") 144 Expect(arr).To(HaveLen(2)) 145 146 svc := new(v1.Service) 147 err := yaml.Unmarshal([]byte(arr[0]), svc) 148 Expect(err).ToNot(HaveOccurred()) 149 Expect(svc.Spec.Ports).To(HaveLen(1)) 150 Expect(svc.Spec.Ports[0].TargetPort.IntValue()).To(Equal(3890)) 151 152 pod := new(v1.Pod) 153 err = yaml.Unmarshal([]byte(arr[1]), pod) 154 Expect(err).ToNot(HaveOccurred()) 155 // Since hostPort will not be set in the yaml, when we unmarshal it it will have a value of 0 156 Expect(pod.Spec.Containers[0].Ports[0].HostPort).To(Equal(int32(0))) 157 158 // Now do kube generate without the --service flag 159 kube = podmanTest.Podman([]string{"kube", "generate", "test-ctr"}) 160 kube.WaitWithDefaultTimeout() 161 Expect(kube).Should(ExitCleanly()) 162 163 // The hostPort in the pod yaml should be set to 3890 164 pod = new(v1.Pod) 165 err = yaml.Unmarshal(kube.Out.Contents(), pod) 166 Expect(err).ToNot(HaveOccurred()) 167 Expect(pod.Spec.Containers[0].Ports[0].HostPort).To(Equal(int32(3890))) 168 }) 169 170 It("on pod", func() { 171 _, rc, _ := podmanTest.CreatePod(map[string][]string{"--name": {"toppod"}}) 172 Expect(rc).To(Equal(0)) 173 174 session := podmanTest.RunTopContainerInPod("topcontainer", "toppod") 175 session.WaitWithDefaultTimeout() 176 Expect(session).Should(ExitCleanly()) 177 178 kube := podmanTest.Podman([]string{"kube", "generate", "toppod"}) 179 kube.WaitWithDefaultTimeout() 180 Expect(kube).Should(ExitCleanly()) 181 182 pod := new(v1.Pod) 183 err := yaml.Unmarshal(kube.Out.Contents(), pod) 184 Expect(err).ToNot(HaveOccurred()) 185 Expect(pod.Spec).To(HaveField("HostNetwork", false)) 186 Expect(pod.Annotations).To(HaveLen(1)) 187 188 numContainers := 0 189 for range pod.Spec.Containers { 190 numContainers++ 191 } 192 Expect(numContainers).To(Equal(1)) 193 }) 194 195 It("multiple pods", func() { 196 pod1 := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:pod1", CITEST_IMAGE, "top"}) 197 pod1.WaitWithDefaultTimeout() 198 Expect(pod1).Should(ExitCleanly()) 199 200 pod2 := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:pod2", CITEST_IMAGE, "top"}) 201 pod2.WaitWithDefaultTimeout() 202 Expect(pod2).Should(ExitCleanly()) 203 204 kube := podmanTest.Podman([]string{"kube", "generate", "pod1", "pod2"}) 205 kube.WaitWithDefaultTimeout() 206 Expect(kube).Should(ExitCleanly()) 207 208 Expect(string(kube.Out.Contents())).To(ContainSubstring(`name: pod1`)) 209 Expect(string(kube.Out.Contents())).To(ContainSubstring(`name: pod2`)) 210 }) 211 212 It("on pod with init containers", func() { 213 session := podmanTest.Podman([]string{"create", "--pod", "new:toppod", "--init-ctr", "always", CITEST_IMAGE, "echo", "hello"}) 214 session.WaitWithDefaultTimeout() 215 Expect(session).Should(ExitCleanly()) 216 217 session = podmanTest.Podman([]string{"create", "--pod", "toppod", "--init-ctr", "always", CITEST_IMAGE, "echo", "world"}) 218 session.WaitWithDefaultTimeout() 219 Expect(session).Should(ExitCleanly()) 220 221 session = podmanTest.Podman([]string{"create", "--pod", "toppod", CITEST_IMAGE, "top"}) 222 session.WaitWithDefaultTimeout() 223 Expect(session).Should(ExitCleanly()) 224 225 kube := podmanTest.Podman([]string{"kube", "generate", "toppod"}) 226 kube.WaitWithDefaultTimeout() 227 Expect(kube).Should(ExitCleanly()) 228 229 pod := new(v1.Pod) 230 err := yaml.Unmarshal(kube.Out.Contents(), pod) 231 Expect(err).ToNot(HaveOccurred()) 232 Expect(pod.Spec).To(HaveField("HostNetwork", false)) 233 234 numContainers := len(pod.Spec.Containers) + len(pod.Spec.InitContainers) 235 Expect(numContainers).To(Equal(3)) 236 237 // Init container should be in the generated kube yaml if created with "once" type and the pod has not been started 238 session = podmanTest.Podman([]string{"create", "--pod", "new:toppod-2", "--init-ctr", "once", CITEST_IMAGE, "echo", "using once type"}) 239 session.WaitWithDefaultTimeout() 240 Expect(session).Should(ExitCleanly()) 241 242 session = podmanTest.Podman([]string{"create", "--pod", "toppod-2", CITEST_IMAGE, "top"}) 243 session.WaitWithDefaultTimeout() 244 Expect(session).Should(ExitCleanly()) 245 246 kube = podmanTest.Podman([]string{"kube", "generate", "toppod-2"}) 247 kube.WaitWithDefaultTimeout() 248 Expect(kube).Should(ExitCleanly()) 249 250 pod = new(v1.Pod) 251 err = yaml.Unmarshal(kube.Out.Contents(), pod) 252 Expect(err).ToNot(HaveOccurred()) 253 Expect(pod.Spec).To(HaveField("HostNetwork", false)) 254 255 numContainers = len(pod.Spec.Containers) + len(pod.Spec.InitContainers) 256 Expect(numContainers).To(Equal(2)) 257 258 // Init container should not be in the generated kube yaml if created with "once" type and the pod has been started 259 session = podmanTest.Podman([]string{"create", "--pod", "new:toppod-3", "--init-ctr", "once", CITEST_IMAGE, "echo", "using once type"}) 260 session.WaitWithDefaultTimeout() 261 Expect(session).Should(ExitCleanly()) 262 263 session = podmanTest.Podman([]string{"create", "--pod", "toppod-3", CITEST_IMAGE, "top"}) 264 session.WaitWithDefaultTimeout() 265 Expect(session).Should(ExitCleanly()) 266 267 session = podmanTest.Podman([]string{"pod", "start", "toppod-3"}) 268 session.WaitWithDefaultTimeout() 269 Expect(session).Should(ExitCleanly()) 270 271 kube = podmanTest.Podman([]string{"kube", "generate", "toppod-3"}) 272 kube.WaitWithDefaultTimeout() 273 Expect(kube).Should(ExitCleanly()) 274 275 pod = new(v1.Pod) 276 err = yaml.Unmarshal(kube.Out.Contents(), pod) 277 Expect(err).ToNot(HaveOccurred()) 278 Expect(pod.Spec).To(HaveField("HostNetwork", false)) 279 280 numContainers = len(pod.Spec.Containers) + len(pod.Spec.InitContainers) 281 Expect(numContainers).To(Equal(1)) 282 }) 283 284 It("on pod with user namespace", func() { 285 u, err := user.Current() 286 Expect(err).ToNot(HaveOccurred()) 287 name := u.Username 288 if name == "root" { 289 name = "containers" 290 } 291 content, err := os.ReadFile("/etc/subuid") 292 if err != nil { 293 Skip("cannot read /etc/subuid") 294 } 295 if !strings.Contains(string(content), name) { 296 Skip("cannot find mappings for the current user") 297 } 298 podSession := podmanTest.Podman([]string{"pod", "create", "--name", "testPod", "--userns=auto"}) 299 podSession.WaitWithDefaultTimeout() 300 Expect(podSession).Should(ExitCleanly()) 301 302 session := podmanTest.Podman([]string{"create", "--name", "topcontainer", "--pod", "testPod", CITEST_IMAGE, "top"}) 303 session.WaitWithDefaultTimeout() 304 Expect(session).Should(ExitCleanly()) 305 306 kube := podmanTest.Podman([]string{"kube", "generate", "testPod"}) 307 kube.WaitWithDefaultTimeout() 308 Expect(kube).Should(ExitCleanly()) 309 310 pod := new(v1.Pod) 311 err = yaml.Unmarshal(kube.Out.Contents(), pod) 312 Expect(err).ToNot(HaveOccurred()) 313 expected := false 314 Expect(pod.Spec).To(HaveField("HostUsers", &expected)) 315 }) 316 317 It("on pod with host network", func() { 318 podSession := podmanTest.Podman([]string{"pod", "create", "--name", "testHostNetwork", "--network", "host"}) 319 podSession.WaitWithDefaultTimeout() 320 Expect(podSession).Should(ExitCleanly()) 321 322 session := podmanTest.Podman([]string{"create", "--name", "topcontainer", "--pod", "testHostNetwork", "--network", "host", CITEST_IMAGE, "top"}) 323 session.WaitWithDefaultTimeout() 324 Expect(session).Should(ExitCleanly()) 325 326 kube := podmanTest.Podman([]string{"kube", "generate", "testHostNetwork"}) 327 kube.WaitWithDefaultTimeout() 328 Expect(kube).Should(ExitCleanly()) 329 330 pod := new(v1.Pod) 331 err := yaml.Unmarshal(kube.Out.Contents(), pod) 332 Expect(err).ToNot(HaveOccurred()) 333 Expect(pod.Spec).To(HaveField("HostNetwork", true)) 334 }) 335 336 It("on container with host network", func() { 337 session := podmanTest.RunTopContainerWithArgs("topcontainer", []string{"--network", "host"}) 338 session.WaitWithDefaultTimeout() 339 Expect(session).Should(ExitCleanly()) 340 341 kube := podmanTest.Podman([]string{"kube", "generate", "topcontainer"}) 342 kube.WaitWithDefaultTimeout() 343 Expect(kube).Should(ExitCleanly()) 344 345 pod := new(v1.Pod) 346 err := yaml.Unmarshal(kube.Out.Contents(), pod) 347 Expect(err).ToNot(HaveOccurred()) 348 Expect(pod.Spec).To(HaveField("HostNetwork", true)) 349 }) 350 351 It("on pod with hostAliases", func() { 352 podName := "testHost" 353 testIP := "127.0.0.1" 354 podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName, 355 "--add-host", "test1.podman.io" + ":" + testIP, 356 "--add-host", "test2.podman.io" + ":" + testIP, 357 }) 358 podSession.WaitWithDefaultTimeout() 359 Expect(podSession).Should(ExitCleanly()) 360 361 ctr1Name := "ctr1" 362 ctr1Session := podmanTest.Podman([]string{"create", "--name", ctr1Name, "--pod", podName, CITEST_IMAGE, "top"}) 363 ctr1Session.WaitWithDefaultTimeout() 364 Expect(ctr1Session).Should(ExitCleanly()) 365 366 ctr2Name := "ctr2" 367 ctr2Session := podmanTest.Podman([]string{"create", "--name", ctr2Name, "--pod", podName, CITEST_IMAGE, "top"}) 368 ctr2Session.WaitWithDefaultTimeout() 369 Expect(ctr2Session).Should(ExitCleanly()) 370 371 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 372 kube.WaitWithDefaultTimeout() 373 Expect(kube).Should(ExitCleanly()) 374 375 pod := new(v1.Pod) 376 err := yaml.Unmarshal(kube.Out.Contents(), pod) 377 Expect(err).ToNot(HaveOccurred()) 378 Expect(pod.Spec.HostAliases).To(HaveLen(2)) 379 Expect(pod.Spec.HostAliases[0]).To(HaveField("IP", testIP)) 380 Expect(pod.Spec.HostAliases[1]).To(HaveField("IP", testIP)) 381 }) 382 383 It("with network sharing", func() { 384 // Expect error with default sharing options as Net namespace is shared 385 podName := "testPod" 386 podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName}) 387 podSession.WaitWithDefaultTimeout() 388 Expect(podSession).Should(ExitCleanly()) 389 390 ctrSession := podmanTest.Podman([]string{"create", "--name", "testCtr", "--pod", podName, "-p", "9000:8000", CITEST_IMAGE, "top"}) 391 ctrSession.WaitWithDefaultTimeout() 392 Expect(ctrSession).Should(ExitWithError(125, "invalid config provided: published or exposed ports must be defined when the pod is created: network cannot be configured when it is shared with a pod")) 393 394 // Ports without Net sharing should work with ports being set for each container in the generated kube yaml 395 podName = "testNet" 396 podSession = podmanTest.Podman([]string{"pod", "create", "--name", podName, "--share", "ipc"}) 397 podSession.WaitWithDefaultTimeout() 398 Expect(podSession).Should(ExitCleanly()) 399 400 ctr1Name := "ctr1" 401 ctr1Session := podmanTest.Podman([]string{"create", "--name", ctr1Name, "--pod", podName, "-p", "9000:8000", CITEST_IMAGE, "top"}) 402 ctr1Session.WaitWithDefaultTimeout() 403 Expect(ctr1Session).Should(ExitCleanly()) 404 405 ctr2Name := "ctr2" 406 ctr2Session := podmanTest.Podman([]string{"create", "--name", ctr2Name, "--pod", podName, "-p", "6000:5000", CITEST_IMAGE, "top"}) 407 ctr2Session.WaitWithDefaultTimeout() 408 Expect(ctr2Session).Should(ExitCleanly()) 409 410 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 411 kube.WaitWithDefaultTimeout() 412 Expect(kube).Should(ExitCleanly()) 413 414 pod := new(v1.Pod) 415 err := yaml.Unmarshal(kube.Out.Contents(), pod) 416 Expect(err).ToNot(HaveOccurred()) 417 Expect(pod.Spec.Containers).To(HaveLen(2)) 418 Expect(pod.Spec.Containers[0].Ports[0].ContainerPort).To(Equal(int32(8000))) 419 Expect(pod.Spec.Containers[1].Ports[0].ContainerPort).To(Equal(int32(5000))) 420 Expect(pod.Spec.Containers[0].Ports[0].HostPort).To(Equal(int32(9000))) 421 Expect(pod.Spec.Containers[1].Ports[0].HostPort).To(Equal(int32(6000))) 422 }) 423 424 It("with and without hostname", func() { 425 // Expect error with default sharing options as UTS namespace is shared 426 podName := "testPod" 427 podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName}) 428 podSession.WaitWithDefaultTimeout() 429 Expect(podSession).Should(ExitCleanly()) 430 431 ctrSession := podmanTest.Podman([]string{"create", "--name", "testCtr", "--pod", podName, "--hostname", "test-hostname", CITEST_IMAGE, "top"}) 432 ctrSession.WaitWithDefaultTimeout() 433 Expect(ctrSession).Should(ExitWithError(125, "invalid config provided: cannot set hostname when joining the pod UTS namespace: invalid configuration")) 434 435 // Hostname without uts sharing should work, but generated kube yaml will have pod hostname 436 // set to the hostname of the first container 437 podName = "testHostname" 438 podSession = podmanTest.Podman([]string{"pod", "create", "--name", podName, "--share", "ipc"}) 439 podSession.WaitWithDefaultTimeout() 440 Expect(podSession).Should(ExitCleanly()) 441 442 ctr1Name := "ctr1" 443 ctr1HostName := "ctr1-hostname" 444 ctr1Session := podmanTest.Podman([]string{"create", "--name", ctr1Name, "--pod", podName, "--hostname", ctr1HostName, CITEST_IMAGE, "top"}) 445 ctr1Session.WaitWithDefaultTimeout() 446 Expect(ctr1Session).Should(ExitCleanly()) 447 448 ctr2Name := "ctr2" 449 ctr2Session := podmanTest.Podman([]string{"create", "--name", ctr2Name, "--pod", podName, CITEST_IMAGE, "top"}) 450 ctr2Session.WaitWithDefaultTimeout() 451 Expect(ctr2Session).Should(ExitCleanly()) 452 453 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 454 kube.WaitWithDefaultTimeout() 455 Expect(kube).Should(ExitCleanly()) 456 457 pod := new(v1.Pod) 458 err := yaml.Unmarshal(kube.Out.Contents(), pod) 459 Expect(err).ToNot(HaveOccurred()) 460 Expect(pod.Spec.Containers).To(HaveLen(2)) 461 Expect(pod.Spec.Hostname).To(Equal(ctr1HostName)) 462 463 // No hostname 464 465 podName = "testNoHostname" 466 podSession = podmanTest.Podman([]string{"pod", "create", "--name", podName, "--share", "ipc"}) 467 podSession.WaitWithDefaultTimeout() 468 Expect(podSession).Should(ExitCleanly()) 469 470 ctr3Name := "ctr3" 471 ctr3Session := podmanTest.Podman([]string{"create", "--name", ctr3Name, "--pod", podName, CITEST_IMAGE, "top"}) 472 ctr3Session.WaitWithDefaultTimeout() 473 Expect(ctr3Session).Should(ExitCleanly()) 474 475 kube = podmanTest.Podman([]string{"kube", "generate", podName}) 476 kube.WaitWithDefaultTimeout() 477 Expect(kube).Should(ExitCleanly()) 478 479 pod = new(v1.Pod) 480 err = yaml.Unmarshal(kube.Out.Contents(), pod) 481 Expect(err).ToNot(HaveOccurred()) 482 Expect(pod.Spec.Containers).To(HaveLen(1)) 483 Expect(pod.Spec.Hostname).To(BeEmpty()) 484 }) 485 486 It("service kube on pod", func() { 487 session := podmanTest.Podman([]string{"create", "--pod", "new:test-pod", "-p", "4000:4000/udp", CITEST_IMAGE, "ls"}) 488 session.WaitWithDefaultTimeout() 489 Expect(session).Should(ExitCleanly()) 490 491 kube := podmanTest.Podman([]string{"kube", "generate", "-s", "test-pod"}) 492 kube.WaitWithDefaultTimeout() 493 Expect(kube).Should(ExitCleanly()) 494 495 // Separate out the Service and Pod yaml 496 arr := strings.Split(string(kube.Out.Contents()), "---") 497 Expect(arr).To(HaveLen(2)) 498 499 svc := new(v1.Service) 500 err := yaml.Unmarshal([]byte(arr[0]), svc) 501 Expect(err).ToNot(HaveOccurred()) 502 Expect(svc.Spec.Ports).To(HaveLen(1)) 503 Expect(svc.Spec.Ports[0].TargetPort.IntValue()).To(Equal(4000)) 504 Expect(svc.Spec.Ports[0]).To(HaveField("Protocol", v1.ProtocolUDP)) 505 506 pod := new(v1.Pod) 507 err = yaml.Unmarshal([]byte(arr[1]), pod) 508 Expect(err).ToNot(HaveOccurred()) 509 }) 510 511 It("on pod with restartPolicy set for container in a pod", func() { 512 //TODO: v5.0 - change/remove test once we block --restart on container when it is in a pod 513 // podName, set, expect 514 testSli := [][]string{ 515 {"testPod1", "", ""}, // some pod create from cmdline, so set it to an empty string and let k8s default it to Always 516 {"testPod2", "always", "Always"}, 517 {"testPod3", "on-failure", "OnFailure"}, 518 {"testPod4", "no", "Never"}, 519 {"testPod5", "never", "Never"}, 520 } 521 522 for k, v := range testSli { 523 podName := v[0] 524 // Need to set --restart during pod creation as gen kube only picks up the pod's restart policy 525 podSession := podmanTest.Podman([]string{"pod", "create", "--restart", v[1], "--name", podName}) 526 podSession.WaitWithDefaultTimeout() 527 Expect(podSession).Should(ExitCleanly()) 528 529 ctrName := "ctr" + strconv.Itoa(k) 530 ctr1Session := podmanTest.Podman([]string{"create", "--name", ctrName, "--pod", podName, 531 "--restart", v[1], CITEST_IMAGE, "top"}) 532 ctr1Session.WaitWithDefaultTimeout() 533 Expect(ctr1Session).Should(ExitCleanly()) 534 535 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 536 kube.WaitWithDefaultTimeout() 537 Expect(kube).Should(ExitCleanly()) 538 539 pod := new(v1.Pod) 540 err := yaml.Unmarshal(kube.Out.Contents(), pod) 541 Expect(err).ToNot(HaveOccurred()) 542 543 Expect(string(pod.Spec.RestartPolicy)).To(Equal(v[2])) 544 } 545 }) 546 547 It("on pod with restartPolicy", func() { 548 // podName, set, expect 549 testSli := [][]string{ 550 {"testPod1", "", ""}, 551 {"testPod2", "always", "Always"}, 552 {"testPod3", "on-failure", "OnFailure"}, 553 {"testPod4", "no", "Never"}, 554 {"testPod5", "never", "Never"}, 555 } 556 557 for k, v := range testSli { 558 podName := v[0] 559 podSession := podmanTest.Podman([]string{"pod", "create", "--restart", v[1], podName}) 560 podSession.WaitWithDefaultTimeout() 561 Expect(podSession).Should(ExitCleanly()) 562 563 ctrName := "ctr" + strconv.Itoa(k) 564 ctr1Session := podmanTest.Podman([]string{"create", "--name", ctrName, "--pod", podName, CITEST_IMAGE, "top"}) 565 ctr1Session.WaitWithDefaultTimeout() 566 Expect(ctr1Session).Should(ExitCleanly()) 567 568 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 569 kube.WaitWithDefaultTimeout() 570 Expect(kube).Should(ExitCleanly()) 571 572 pod := new(v1.Pod) 573 err := yaml.Unmarshal(kube.Out.Contents(), pod) 574 Expect(err).ToNot(HaveOccurred()) 575 576 Expect(string(pod.Spec.RestartPolicy)).To(Equal(v[2])) 577 } 578 }) 579 580 It("on ctr with restartPolicy", func() { 581 // podName, set, expect 582 testSli := [][]string{ 583 {"", ""}, // some ctr created from cmdline, set it to "" and let k8s default it to Always 584 {"always", "Always"}, 585 {"on-failure", "OnFailure"}, 586 {"no", "Never"}, 587 {"never", "Never"}, 588 } 589 590 for k, v := range testSli { 591 ctrName := "ctr" + strconv.Itoa(k) 592 ctrSession := podmanTest.Podman([]string{"create", "--restart", v[0], "--name", ctrName, CITEST_IMAGE, "top"}) 593 ctrSession.WaitWithDefaultTimeout() 594 Expect(ctrSession).Should(ExitCleanly()) 595 596 kube := podmanTest.Podman([]string{"kube", "generate", ctrName}) 597 kube.WaitWithDefaultTimeout() 598 Expect(kube).Should(ExitCleanly()) 599 600 pod := new(v1.Pod) 601 err := yaml.Unmarshal(kube.Out.Contents(), pod) 602 Expect(err).ToNot(HaveOccurred()) 603 604 Expect(string(pod.Spec.RestartPolicy)).To(Equal(v[1])) 605 } 606 }) 607 608 It("on pod with memory limit", func() { 609 SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1") 610 podName := "testMemoryLimit" 611 podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName}) 612 podSession.WaitWithDefaultTimeout() 613 Expect(podSession).Should(ExitCleanly()) 614 615 ctr1Name := "ctr1" 616 ctr1Session := podmanTest.Podman([]string{"create", "--name", ctr1Name, "--pod", podName, "--memory", "10M", CITEST_IMAGE, "top"}) 617 ctr1Session.WaitWithDefaultTimeout() 618 Expect(ctr1Session).Should(ExitCleanly()) 619 620 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 621 kube.WaitWithDefaultTimeout() 622 Expect(kube).Should(ExitCleanly()) 623 624 pod := new(v1.Pod) 625 err := yaml.Unmarshal(kube.Out.Contents(), pod) 626 Expect(err).ToNot(HaveOccurred()) 627 628 for _, ctr := range pod.Spec.Containers { 629 memoryLimit, _ := ctr.Resources.Limits.Memory().AsInt64() 630 Expect(memoryLimit).To(Equal(int64(10 * 1024 * 1024))) 631 } 632 }) 633 634 It("on pod with cpu limit", func() { 635 SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1") 636 podName := "testCpuLimit" 637 podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName}) 638 podSession.WaitWithDefaultTimeout() 639 Expect(podSession).Should(ExitCleanly()) 640 641 ctr1Name := "ctr1" 642 ctr1Session := podmanTest.Podman([]string{"create", "--name", ctr1Name, "--pod", podName, 643 "--cpus", "0.5", CITEST_IMAGE, "top"}) 644 ctr1Session.WaitWithDefaultTimeout() 645 Expect(ctr1Session).Should(ExitCleanly()) 646 647 ctr2Name := "ctr2" 648 ctr2Session := podmanTest.Podman([]string{"create", "--name", ctr2Name, "--pod", podName, 649 "--cpu-period", "100000", "--cpu-quota", "50000", CITEST_IMAGE, "top"}) 650 ctr2Session.WaitWithDefaultTimeout() 651 Expect(ctr2Session).Should(ExitCleanly()) 652 653 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 654 kube.WaitWithDefaultTimeout() 655 Expect(kube).Should(ExitCleanly()) 656 657 pod := new(v1.Pod) 658 err := yaml.Unmarshal(kube.Out.Contents(), pod) 659 Expect(err).ToNot(HaveOccurred()) 660 661 for _, ctr := range pod.Spec.Containers { 662 cpuLimit := ctr.Resources.Limits.Cpu().MilliValue() 663 Expect(cpuLimit).To(Equal(int64(500))) 664 } 665 }) 666 667 It("on pod with ports", func() { 668 podName := "test" 669 670 lock4 := GetPortLock("4008") 671 defer lock4.Unlock() 672 lock5 := GetPortLock("5008") 673 defer lock5.Unlock() 674 podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName, "-p", "4008:4000", "-p", "5008:5000"}) 675 podSession.WaitWithDefaultTimeout() 676 Expect(podSession).Should(ExitCleanly()) 677 678 ctr1Name := "ctr1" 679 ctr1Session := podmanTest.Podman([]string{"create", "--name", ctr1Name, "--pod", podName, CITEST_IMAGE, "top"}) 680 ctr1Session.WaitWithDefaultTimeout() 681 Expect(ctr1Session).Should(ExitCleanly()) 682 683 ctr2Name := "ctr2" 684 ctr2Session := podmanTest.Podman([]string{"create", "--name", ctr2Name, "--pod", podName, CITEST_IMAGE, "top"}) 685 ctr2Session.WaitWithDefaultTimeout() 686 Expect(ctr2Session).Should(ExitCleanly()) 687 688 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 689 kube.WaitWithDefaultTimeout() 690 Expect(kube).Should(ExitCleanly()) 691 692 pod := new(v1.Pod) 693 err := yaml.Unmarshal(kube.Out.Contents(), pod) 694 Expect(err).ToNot(HaveOccurred()) 695 696 foundPort400x := 0 697 foundPort500x := 0 698 foundOtherPort := 0 699 for _, ctr := range pod.Spec.Containers { 700 for _, port := range ctr.Ports { 701 // Since we are using tcp here, the generated kube yaml shouldn't 702 // have anything for protocol under the ports as tcp is the default 703 // for k8s 704 Expect(port.Protocol).To(BeEmpty()) 705 if port.HostPort == 4008 { 706 foundPort400x++ 707 } else if port.HostPort == 5008 { 708 foundPort500x++ 709 } else { 710 foundOtherPort++ 711 } 712 } 713 } 714 Expect(foundPort400x).To(Equal(1)) 715 Expect(foundPort500x).To(Equal(1)) 716 Expect(foundOtherPort).To(Equal(0)) 717 718 // Create container with UDP port and check the generated kube yaml 719 ctrWithUDP := podmanTest.Podman([]string{"create", "--pod", "new:test-pod", "-p", "6666:66/udp", CITEST_IMAGE, "top"}) 720 ctrWithUDP.WaitWithDefaultTimeout() 721 Expect(ctrWithUDP).Should(ExitCleanly()) 722 723 kube = podmanTest.Podman([]string{"kube", "generate", "test-pod"}) 724 kube.WaitWithDefaultTimeout() 725 Expect(kube).Should(ExitCleanly()) 726 727 pod = new(v1.Pod) 728 err = yaml.Unmarshal(kube.Out.Contents(), pod) 729 Expect(err).ToNot(HaveOccurred()) 730 731 containers := pod.Spec.Containers 732 Expect(containers).To(HaveLen(1)) 733 Expect(containers[0].Ports).To(HaveLen(1)) 734 Expect(containers[0].Ports[0]).To(HaveField("Protocol", v1.ProtocolUDP)) 735 }) 736 737 It("generate and reimport kube on pod", func() { 738 podName := "toppod" 739 _, rc, _ := podmanTest.CreatePod(map[string][]string{"--name": {podName}}) 740 Expect(rc).To(Equal(0)) 741 742 session := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test1", CITEST_IMAGE, "top"}) 743 session.WaitWithDefaultTimeout() 744 Expect(session).Should(ExitCleanly()) 745 746 session2 := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test2", CITEST_IMAGE, "top"}) 747 session2.WaitWithDefaultTimeout() 748 Expect(session2).Should(ExitCleanly()) 749 750 outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") 751 kube := podmanTest.Podman([]string{"kube", "generate", "-f", outputFile, podName}) 752 kube.WaitWithDefaultTimeout() 753 Expect(kube).Should(ExitCleanly()) 754 755 session3 := podmanTest.Podman([]string{"pod", "rm", "-af"}) 756 session3.WaitWithDefaultTimeout() 757 Expect(session3).Should(ExitCleanly()) 758 759 session4 := podmanTest.Podman([]string{"kube", "play", outputFile}) 760 session4.WaitWithDefaultTimeout() 761 Expect(session4).Should(ExitCleanly()) 762 763 session5 := podmanTest.Podman([]string{"pod", "ps"}) 764 session5.WaitWithDefaultTimeout() 765 Expect(session5).Should(ExitCleanly()) 766 Expect(session5.OutputToString()).To(ContainSubstring(podName)) 767 768 session6 := podmanTest.Podman([]string{"ps", "-a"}) 769 session6.WaitWithDefaultTimeout() 770 Expect(session6).Should(ExitCleanly()) 771 psOut := session6.OutputToString() 772 Expect(psOut).To(ContainSubstring("test1")) 773 Expect(psOut).To(ContainSubstring("test2")) 774 }) 775 776 It("generate with user and reimport kube on pod", func() { 777 podName := "toppod" 778 _, rc, _ := podmanTest.CreatePod(map[string][]string{"--name": {podName}}) 779 Expect(rc).To(Equal(0)) 780 781 session := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test1", "--user", "100:200", CITEST_IMAGE, "top"}) 782 session.WaitWithDefaultTimeout() 783 Expect(session).Should(ExitCleanly()) 784 785 inspect := podmanTest.Podman([]string{"inspect", "--format", "{{.Config.User}}", "test1"}) 786 inspect.WaitWithDefaultTimeout() 787 Expect(inspect).Should(ExitCleanly()) 788 Expect(inspect.OutputToString()).To(ContainSubstring("100:200")) 789 790 outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") 791 kube := podmanTest.Podman([]string{"kube", "generate", "-f", outputFile, podName}) 792 kube.WaitWithDefaultTimeout() 793 Expect(kube).Should(ExitCleanly()) 794 795 session = podmanTest.Podman([]string{"pod", "rm", "-af"}) 796 session.WaitWithDefaultTimeout() 797 Expect(session).Should(ExitCleanly()) 798 799 podmanTest.AddImageToRWStore(CITEST_IMAGE) 800 session = podmanTest.Podman([]string{"kube", "play", outputFile}) 801 session.WaitWithDefaultTimeout() 802 Expect(session).Should(ExitCleanly()) 803 804 // container name in pod is <podName>-<ctrName> 805 inspect1 := podmanTest.Podman([]string{"inspect", "--format", "{{.Config.User}}", "toppod-test1"}) 806 inspect1.WaitWithDefaultTimeout() 807 Expect(inspect1).Should(ExitCleanly()) 808 Expect(inspect1.OutputToString()).To(ContainSubstring(inspect.OutputToString())) 809 }) 810 811 It("with volume", func() { 812 vol1 := filepath.Join(podmanTest.TempDir, "vol-test1") 813 err := os.MkdirAll(vol1, 0755) 814 Expect(err).ToNot(HaveOccurred()) 815 816 // we need a container name because IDs don't persist after rm/play 817 ctrName := "test-ctr" 818 ctrNameInKubePod := "test1-test-ctr" 819 820 session1 := podmanTest.Podman([]string{"run", "-d", "--pod", "new:test1", "--name", ctrName, "-v", vol1 + ":/volume/:z", CITEST_IMAGE, "top"}) 821 session1.WaitWithDefaultTimeout() 822 Expect(session1).Should(ExitCleanly()) 823 824 outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") 825 kube := podmanTest.Podman([]string{"kube", "generate", "test1", "-f", outputFile}) 826 kube.WaitWithDefaultTimeout() 827 Expect(kube).Should(ExitCleanly()) 828 829 b, err := os.ReadFile(outputFile) 830 Expect(err).ShouldNot(HaveOccurred()) 831 pod := new(v1.Pod) 832 err = yaml.Unmarshal(b, pod) 833 Expect(err).ToNot(HaveOccurred()) 834 Expect(pod.Annotations).To(HaveKeyWithValue(define.BindMountPrefix, vol1+":"+"z")) 835 836 rm := podmanTest.Podman([]string{"pod", "rm", "-t", "0", "-f", "test1"}) 837 rm.WaitWithDefaultTimeout() 838 Expect(rm).Should(ExitCleanly()) 839 840 play := podmanTest.Podman([]string{"kube", "play", outputFile}) 841 play.WaitWithDefaultTimeout() 842 Expect(play).Should(ExitCleanly()) 843 844 inspect := podmanTest.Podman([]string{"inspect", ctrNameInKubePod}) 845 inspect.WaitWithDefaultTimeout() 846 Expect(inspect).Should(ExitCleanly()) 847 Expect(inspect.OutputToString()).To(ContainSubstring(vol1)) 848 }) 849 850 It("when bind-mounting '/' and '/root' at the same time ", func() { 851 // Fixes https://github.com/containers/podman/issues/9764 852 853 ctrName := "mount-root-ctr" 854 session1 := podmanTest.Podman([]string{"run", "-d", "--pod", "new:mount-root-conflict", "--name", ctrName, 855 "-v", "/:/volume1/", 856 "-v", "/root:/volume2/", 857 CITEST_IMAGE, "top"}) 858 session1.WaitWithDefaultTimeout() 859 Expect(session1).Should(ExitCleanly()) 860 861 kube := podmanTest.Podman([]string{"kube", "generate", "mount-root-conflict"}) 862 kube.WaitWithDefaultTimeout() 863 Expect(kube).Should(ExitCleanly()) 864 865 pod := new(v1.Pod) 866 err := yaml.Unmarshal(kube.Out.Contents(), pod) 867 Expect(err).ToNot(HaveOccurred()) 868 869 Expect(pod.Spec.Volumes).To(HaveLen(2)) 870 871 }) 872 873 It("with persistent volume claim", func() { 874 vol := "vol-test-persistent-volume-claim" 875 876 // we need a container name because IDs don't persist after rm/play 877 ctrName := "test-persistent-volume-claim" 878 ctrNameInKubePod := "test1-test-persistent-volume-claim" 879 880 session := podmanTest.Podman([]string{"run", "-d", "--pod", "new:test1", "--name", ctrName, "-v", vol + ":/volume/:z", CITEST_IMAGE, "top"}) 881 session.WaitWithDefaultTimeout() 882 Expect(session).Should(ExitCleanly()) 883 884 outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") 885 kube := podmanTest.Podman([]string{"kube", "generate", "test1", "-f", outputFile}) 886 kube.WaitWithDefaultTimeout() 887 Expect(kube).Should(ExitCleanly()) 888 889 rm := podmanTest.Podman([]string{"pod", "rm", "-t", "0", "-f", "test1"}) 890 rm.WaitWithDefaultTimeout() 891 Expect(rm).Should(ExitCleanly()) 892 893 play := podmanTest.Podman([]string{"kube", "play", outputFile}) 894 play.WaitWithDefaultTimeout() 895 Expect(play).Should(ExitCleanly()) 896 897 inspect := podmanTest.Podman([]string{"inspect", ctrNameInKubePod}) 898 inspect.WaitWithDefaultTimeout() 899 Expect(inspect).Should(ExitCleanly()) 900 Expect(inspect.OutputToString()).To(ContainSubstring(vol)) 901 }) 902 903 It("sharing pid namespace", func() { 904 podName := "test" 905 podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--share", "pid"}) 906 podSession.WaitWithDefaultTimeout() 907 Expect(podSession).Should(ExitCleanly()) 908 909 session := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test1", CITEST_IMAGE, "top"}) 910 session.WaitWithDefaultTimeout() 911 Expect(session).Should(ExitCleanly()) 912 913 outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") 914 kube := podmanTest.Podman([]string{"kube", "generate", podName, "-f", outputFile}) 915 kube.WaitWithDefaultTimeout() 916 Expect(kube).Should(ExitCleanly()) 917 918 rm := podmanTest.Podman([]string{"pod", "rm", "-t", "0", "-f", podName}) 919 rm.WaitWithDefaultTimeout() 920 Expect(rm).Should(ExitCleanly()) 921 922 play := podmanTest.Podman([]string{"kube", "play", outputFile}) 923 play.WaitWithDefaultTimeout() 924 Expect(play).Should(ExitCleanly()) 925 926 inspect := podmanTest.Podman([]string{"pod", "inspect", podName}) 927 inspect.WaitWithDefaultTimeout() 928 Expect(inspect).Should(ExitCleanly()) 929 Expect(inspect.OutputToString()).To(ContainSubstring(`"pid"`)) 930 }) 931 932 It("with pods and containers", func() { 933 pod1 := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:pod1", CITEST_IMAGE, "top"}) 934 pod1.WaitWithDefaultTimeout() 935 Expect(pod1).Should(ExitCleanly()) 936 937 pod2 := podmanTest.Podman([]string{"run", "-dt", "--name", "top", CITEST_IMAGE, "top"}) 938 pod2.WaitWithDefaultTimeout() 939 Expect(pod2).Should(ExitCleanly()) 940 941 kube := podmanTest.Podman([]string{"kube", "generate", "pod1", "top"}) 942 kube.WaitWithDefaultTimeout() 943 Expect(kube).Should(ExitCleanly()) 944 }) 945 946 It("with containers in a pod should fail", func() { 947 pod1 := podmanTest.Podman([]string{"pod", "create", "--name", "pod1"}) 948 pod1.WaitWithDefaultTimeout() 949 Expect(pod1).Should(ExitCleanly()) 950 951 con := podmanTest.Podman([]string{"run", "-dt", "--pod", "pod1", "--name", "top", CITEST_IMAGE, "top"}) 952 con.WaitWithDefaultTimeout() 953 Expect(con).Should(ExitCleanly()) 954 955 kube := podmanTest.Podman([]string{"kube", "generate", "top"}) 956 kube.WaitWithDefaultTimeout() 957 Expect(kube).To(ExitWithError(125, " is associated with pod ")) 958 }) 959 960 It("with multiple containers", func() { 961 con1 := podmanTest.Podman([]string{"run", "-dt", "--name", "con1", CITEST_IMAGE, "top"}) 962 con1.WaitWithDefaultTimeout() 963 Expect(con1).Should(ExitCleanly()) 964 965 con2 := podmanTest.Podman([]string{"run", "-dt", "--name", "con2", CITEST_IMAGE, "top"}) 966 con2.WaitWithDefaultTimeout() 967 Expect(con2).Should(ExitCleanly()) 968 969 kube := podmanTest.Podman([]string{"kube", "generate", "con1", "con2"}) 970 kube.WaitWithDefaultTimeout() 971 Expect(kube).Should(ExitCleanly()) 972 }) 973 974 It("with containers in pods should fail", func() { 975 pod1 := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:pod1", "--name", "top1", CITEST_IMAGE, "top"}) 976 pod1.WaitWithDefaultTimeout() 977 Expect(pod1).Should(ExitCleanly()) 978 979 pod2 := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:pod2", "--name", "top2", CITEST_IMAGE, "top"}) 980 pod2.WaitWithDefaultTimeout() 981 Expect(pod2).Should(ExitCleanly()) 982 983 kube := podmanTest.Podman([]string{"kube", "generate", "top1", "top2"}) 984 kube.WaitWithDefaultTimeout() 985 Expect(kube).To(ExitWithError(125, " is associated with pod ")) 986 }) 987 988 It("on a container with dns options", func() { 989 top := podmanTest.Podman([]string{"run", "-dt", "--name", "top", "--dns", "8.8.8.8", "--dns-search", "foobar.com", "--dns-option", "color:blue", CITEST_IMAGE, "top"}) 990 top.WaitWithDefaultTimeout() 991 Expect(top).Should(ExitCleanly()) 992 993 kube := podmanTest.Podman([]string{"kube", "generate", "top"}) 994 kube.WaitWithDefaultTimeout() 995 Expect(kube).Should(ExitCleanly()) 996 997 pod := new(v1.Pod) 998 err := yaml.Unmarshal(kube.Out.Contents(), pod) 999 Expect(err).ToNot(HaveOccurred()) 1000 1001 Expect(pod.Spec.DNSConfig.Nameservers).To(ContainElement("8.8.8.8")) 1002 Expect(pod.Spec.DNSConfig.Searches).To(ContainElement("foobar.com")) 1003 Expect(pod.Spec.DNSConfig.Options).ToNot(BeEmpty()) 1004 Expect(pod.Spec.DNSConfig.Options[0]).To(HaveField("Name", "color")) 1005 s := "blue" 1006 Expect(pod.Spec.DNSConfig.Options[0]).To(HaveField("Value", &s)) 1007 }) 1008 1009 It("multiple container dns servers and options are cumulative", func() { 1010 top1 := podmanTest.Podman([]string{"run", "-dt", "--name", "top1", "--dns", "8.8.8.8", "--dns-search", "foobar.com", CITEST_IMAGE, "top"}) 1011 top1.WaitWithDefaultTimeout() 1012 Expect(top1).Should(ExitCleanly()) 1013 1014 top2 := podmanTest.Podman([]string{"run", "-dt", "--name", "top2", "--dns", "8.7.7.7", "--dns-search", "homer.com", CITEST_IMAGE, "top"}) 1015 top2.WaitWithDefaultTimeout() 1016 Expect(top2).Should(ExitCleanly()) 1017 1018 kube := podmanTest.Podman([]string{"kube", "generate", "top1", "top2"}) 1019 kube.WaitWithDefaultTimeout() 1020 Expect(kube).Should(ExitCleanly()) 1021 1022 pod := new(v1.Pod) 1023 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1024 Expect(err).ToNot(HaveOccurred()) 1025 1026 Expect(pod.Spec.DNSConfig.Nameservers).To(ContainElement("8.8.8.8")) 1027 Expect(pod.Spec.DNSConfig.Nameservers).To(ContainElement("8.7.7.7")) 1028 Expect(pod.Spec.DNSConfig.Searches).To(ContainElement("foobar.com")) 1029 Expect(pod.Spec.DNSConfig.Searches).To(ContainElement("homer.com")) 1030 }) 1031 1032 It("on a pod with dns options", func() { 1033 top := podmanTest.Podman([]string{"run", "--pod", "new:pod1", "-dt", "--name", "top", "--dns", "8.8.8.8", "--dns-search", "foobar.com", "--dns-opt", "color:blue", CITEST_IMAGE, "top"}) 1034 top.WaitWithDefaultTimeout() 1035 Expect(top).Should(ExitCleanly()) 1036 1037 kube := podmanTest.Podman([]string{"kube", "generate", "pod1"}) 1038 kube.WaitWithDefaultTimeout() 1039 Expect(kube).Should(ExitCleanly()) 1040 1041 pod := new(v1.Pod) 1042 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1043 Expect(err).ToNot(HaveOccurred()) 1044 1045 Expect(pod.Spec.DNSConfig.Nameservers).To(ContainElement("8.8.8.8")) 1046 Expect(pod.Spec.DNSConfig.Searches).To(ContainElement("foobar.com")) 1047 Expect(pod.Spec.DNSConfig.Options).ToNot(BeEmpty()) 1048 Expect(pod.Spec.DNSConfig.Options[0]).To(HaveField("Name", "color")) 1049 s := "blue" 1050 Expect(pod.Spec.DNSConfig.Options[0]).To(HaveField("Value", &s)) 1051 }) 1052 1053 It("- set entrypoint as command", func() { 1054 session := podmanTest.Podman([]string{"create", "--pod", "new:testpod", "--entrypoint", "/bin/sleep", CITEST_IMAGE, "10s"}) 1055 session.WaitWithDefaultTimeout() 1056 Expect(session).Should(ExitCleanly()) 1057 1058 kube := podmanTest.Podman([]string{"kube", "generate", "testpod"}) 1059 kube.WaitWithDefaultTimeout() 1060 Expect(kube).Should(ExitCleanly()) 1061 1062 // Now make sure that the container's command is set to the 1063 // entrypoint and it's arguments to "10s". 1064 pod := new(v1.Pod) 1065 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1066 Expect(err).ToNot(HaveOccurred()) 1067 1068 containers := pod.Spec.Containers 1069 Expect(containers).To(HaveLen(1)) 1070 1071 Expect(containers[0]).To(HaveField("Command", []string{"/bin/sleep"})) 1072 Expect(containers[0]).To(HaveField("Args", []string{"10s"})) 1073 }) 1074 1075 It("- use command from image unless explicitly set in the podman command", func() { 1076 session := podmanTest.Podman([]string{"create", "--name", "test", CITEST_IMAGE}) 1077 session.WaitWithDefaultTimeout() 1078 Expect(session).Should(ExitCleanly()) 1079 1080 kube := podmanTest.Podman([]string{"kube", "generate", "test"}) 1081 kube.WaitWithDefaultTimeout() 1082 Expect(kube).Should(ExitCleanly()) 1083 1084 // Now make sure that the container's command in the kube yaml is not set to the 1085 // image command. 1086 pod := new(v1.Pod) 1087 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1088 Expect(err).ToNot(HaveOccurred()) 1089 1090 containers := pod.Spec.Containers 1091 Expect(containers).To(HaveLen(1)) 1092 Expect(containers[0].Command).To(BeEmpty()) 1093 1094 cmd := []string{"echo", "hi"} 1095 session = podmanTest.Podman(append([]string{"create", "--name", "test1", CITEST_IMAGE}, cmd...)) 1096 session.WaitWithDefaultTimeout() 1097 Expect(session).Should(ExitCleanly()) 1098 1099 kube = podmanTest.Podman([]string{"kube", "generate", "test1"}) 1100 kube.WaitWithDefaultTimeout() 1101 Expect(kube).Should(ExitCleanly()) 1102 1103 // Now make sure that the container's command in the kube yaml is set to the 1104 // command passed via the cli to podman create. 1105 pod = new(v1.Pod) 1106 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1107 Expect(err).ToNot(HaveOccurred()) 1108 1109 containers = pod.Spec.Containers 1110 Expect(containers).To(HaveLen(1)) 1111 Expect(containers[0]).To(HaveField("Command", cmd)) 1112 }) 1113 1114 It("- use entrypoint from image unless --entrypoint is set", func() { 1115 // Build an image with an entrypoint. 1116 containerfile := `FROM quay.io/libpod/alpine:latest 1117 ENTRYPOINT ["sleep"]` 1118 1119 containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") 1120 err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) 1121 Expect(err).ToNot(HaveOccurred()) 1122 1123 image := "generatekube:test" 1124 session := podmanTest.Podman([]string{"build", "--pull-never", "-f", containerfilePath, "-t", image}) 1125 session.WaitWithDefaultTimeout() 1126 Expect(session).Should(ExitCleanly()) 1127 1128 session = podmanTest.Podman([]string{"create", "--pod", "new:testpod", image, "10s"}) 1129 session.WaitWithDefaultTimeout() 1130 Expect(session).Should(ExitCleanly()) 1131 1132 kube := podmanTest.Podman([]string{"kube", "generate", "testpod"}) 1133 kube.WaitWithDefaultTimeout() 1134 Expect(kube).Should(ExitCleanly()) 1135 1136 // Now make sure that the container's command in the kube yaml is NOT set to the 1137 // entrypoint but the arguments should be set to "10s". 1138 pod := new(v1.Pod) 1139 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1140 Expect(err).ToNot(HaveOccurred()) 1141 1142 containers := pod.Spec.Containers 1143 Expect(containers).To(HaveLen(1)) 1144 Expect(containers[0]).To(HaveField("Args", []string{"10s"})) 1145 1146 session = podmanTest.Podman([]string{"create", "--pod", "new:testpod-2", "--entrypoint", "echo", image, "hello"}) 1147 session.WaitWithDefaultTimeout() 1148 Expect(session).Should(ExitCleanly()) 1149 1150 kube = podmanTest.Podman([]string{"kube", "generate", "testpod-2"}) 1151 kube.WaitWithDefaultTimeout() 1152 Expect(kube).Should(ExitCleanly()) 1153 1154 // Now make sure that the container's command in the kube yaml is set to the 1155 // entrypoint defined by the --entrypoint flag and the arguments should be set to "hello". 1156 pod = new(v1.Pod) 1157 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1158 Expect(err).ToNot(HaveOccurred()) 1159 1160 containers = pod.Spec.Containers 1161 Expect(containers).To(HaveLen(1)) 1162 Expect(containers[0]).To(HaveField("Command", []string{"echo"})) 1163 Expect(containers[0]).To(HaveField("Args", []string{"hello"})) 1164 }) 1165 1166 It("- image has positive integer user set", func() { 1167 // Build an image with user=1000. 1168 containerfile := `FROM quay.io/libpod/alpine:latest 1169 USER 1000` 1170 1171 containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") 1172 err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) 1173 Expect(err).ToNot(HaveOccurred()) 1174 1175 image := "generatekube:test" 1176 session := podmanTest.Podman([]string{"build", "--pull-never", "-f", containerfilePath, "-t", image}) 1177 session.WaitWithDefaultTimeout() 1178 Expect(session).Should(ExitCleanly()) 1179 1180 session = podmanTest.Podman([]string{"create", "--pod", "new:testpod", image, "top"}) 1181 session.WaitWithDefaultTimeout() 1182 Expect(session).Should(ExitCleanly()) 1183 1184 kube := podmanTest.Podman([]string{"kube", "generate", "testpod"}) 1185 kube.WaitWithDefaultTimeout() 1186 Expect(kube).Should(ExitCleanly()) 1187 1188 // Now make sure that the container's securityContext has runAsNonRoot=true 1189 pod := new(v1.Pod) 1190 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1191 Expect(err).ToNot(HaveOccurred()) 1192 1193 containers := pod.Spec.Containers 1194 Expect(containers).To(HaveLen(1)) 1195 trueBool := true 1196 Expect(containers[0]).To(HaveField("SecurityContext.RunAsNonRoot", &trueBool)) 1197 }) 1198 1199 It("- --privileged container", func() { 1200 session := podmanTest.Podman([]string{"create", "--pod", "new:testpod", "--privileged", CITEST_IMAGE, "ls"}) 1201 session.WaitWithDefaultTimeout() 1202 Expect(session).Should(ExitCleanly()) 1203 1204 kube := podmanTest.Podman([]string{"kube", "generate", "testpod"}) 1205 kube.WaitWithDefaultTimeout() 1206 Expect(kube).Should(ExitCleanly()) 1207 1208 // Now make sure that the capabilities aren't set. 1209 pod := new(v1.Pod) 1210 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1211 Expect(err).ToNot(HaveOccurred()) 1212 1213 containers := pod.Spec.Containers 1214 Expect(containers).To(HaveLen(1)) 1215 Expect(containers[0].SecurityContext.Capabilities).To(BeNil()) 1216 1217 // Now make sure we can also `play` it. 1218 kubeFile := filepath.Join(podmanTest.TempDir, "kube.yaml") 1219 1220 kube = podmanTest.Podman([]string{"kube", "generate", "testpod", "-f", kubeFile}) 1221 kube.WaitWithDefaultTimeout() 1222 Expect(kube).Should(ExitCleanly()) 1223 1224 // Remove the pod so play can recreate it. 1225 kube = podmanTest.Podman([]string{"pod", "rm", "-t", "0", "-f", "testpod"}) 1226 kube.WaitWithDefaultTimeout() 1227 Expect(kube).Should(ExitCleanly()) 1228 1229 kube = podmanTest.Podman([]string{"kube", "play", kubeFile}) 1230 kube.WaitWithDefaultTimeout() 1231 Expect(kube).Should(ExitCleanly()) 1232 }) 1233 1234 It("based on user in container", func() { 1235 // Build an image with an entrypoint. 1236 containerfile := `FROM quay.io/libpod/alpine:latest 1237 RUN adduser -u 10001 -S test1 1238 USER test1` 1239 1240 containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") 1241 err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) 1242 Expect(err).ToNot(HaveOccurred()) 1243 1244 image := "generatekube:test" 1245 session := podmanTest.Podman([]string{"build", "--pull-never", "-f", containerfilePath, "-t", image}) 1246 session.WaitWithDefaultTimeout() 1247 Expect(session).Should(ExitCleanly()) 1248 1249 session = podmanTest.Podman([]string{"create", "--pod", "new:testpod", image, "test1"}) 1250 session.WaitWithDefaultTimeout() 1251 Expect(session).Should(ExitCleanly()) 1252 1253 kube := podmanTest.Podman([]string{"kube", "generate", "testpod"}) 1254 kube.WaitWithDefaultTimeout() 1255 Expect(kube).Should(ExitCleanly()) 1256 1257 pod := new(v1.Pod) 1258 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1259 Expect(err).ToNot(HaveOccurred()) 1260 Expect(pod.Spec.Containers[0].SecurityContext.RunAsUser).To(BeNil()) 1261 }) 1262 1263 It("on named volume", func() { 1264 vol := "simple-named-volume" 1265 1266 session := podmanTest.Podman([]string{"volume", "create", vol}) 1267 session.WaitWithDefaultTimeout() 1268 Expect(session).Should(ExitCleanly()) 1269 1270 kube := podmanTest.Podman([]string{"kube", "generate", vol}) 1271 kube.WaitWithDefaultTimeout() 1272 Expect(kube).Should(ExitCleanly()) 1273 1274 pvc := new(v1.PersistentVolumeClaim) 1275 err := yaml.Unmarshal(kube.Out.Contents(), pvc) 1276 Expect(err).ToNot(HaveOccurred()) 1277 Expect(pvc).To(HaveField("Name", vol)) 1278 Expect(pvc.Spec.AccessModes[0]).To(Equal(v1.ReadWriteOnce)) 1279 Expect(pvc.Spec.Resources.Requests.Storage().String()).To(Equal("1Gi")) 1280 }) 1281 1282 It("on named volume with options", func() { 1283 vol := "complex-named-volume" 1284 volDevice := define.TypeTmpfs 1285 volType := define.TypeTmpfs 1286 volOpts := "nodev,noexec" 1287 1288 session := podmanTest.Podman([]string{"volume", "create", "--opt", "device=" + volDevice, "--opt", "type=" + volType, "--opt", "o=" + volOpts, vol}) 1289 session.WaitWithDefaultTimeout() 1290 Expect(session).Should(ExitCleanly()) 1291 1292 kube := podmanTest.Podman([]string{"kube", "generate", vol}) 1293 kube.WaitWithDefaultTimeout() 1294 Expect(kube).Should(ExitCleanly()) 1295 1296 pvc := new(v1.PersistentVolumeClaim) 1297 err := yaml.Unmarshal(kube.Out.Contents(), pvc) 1298 Expect(err).ToNot(HaveOccurred()) 1299 Expect(pvc).To(HaveField("Name", vol)) 1300 Expect(pvc.Spec.AccessModes[0]).To(Equal(v1.ReadWriteOnce)) 1301 Expect(pvc.Spec.Resources.Requests.Storage().String()).To(Equal("1Gi")) 1302 1303 for k, v := range pvc.Annotations { 1304 switch k { 1305 case util.VolumeDeviceAnnotation: 1306 Expect(v).To(Equal(volDevice)) 1307 case util.VolumeTypeAnnotation: 1308 Expect(v).To(Equal(volType)) 1309 case util.VolumeMountOptsAnnotation: 1310 Expect(v).To(Equal(volOpts)) 1311 } 1312 } 1313 }) 1314 1315 It("on container with auto update labels", func() { 1316 top := podmanTest.Podman([]string{"run", "-dt", "--name", "top", "--label", "io.containers.autoupdate=local", CITEST_IMAGE, "top"}) 1317 top.WaitWithDefaultTimeout() 1318 Expect(top).Should(ExitCleanly()) 1319 1320 kube := podmanTest.Podman([]string{"kube", "generate", "top"}) 1321 kube.WaitWithDefaultTimeout() 1322 Expect(kube).Should(ExitCleanly()) 1323 1324 pod := new(v1.Pod) 1325 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1326 Expect(err).ToNot(HaveOccurred()) 1327 1328 Expect(pod.Annotations).To(HaveKeyWithValue("io.containers.autoupdate/top", "local")) 1329 }) 1330 1331 It("on pod with auto update labels in all containers", func() { 1332 pod1 := podmanTest.Podman([]string{"pod", "create", "--name", "pod1"}) 1333 pod1.WaitWithDefaultTimeout() 1334 Expect(pod1).Should(ExitCleanly()) 1335 1336 top1 := podmanTest.Podman([]string{"run", "-dt", "--name", "top1", "--pod", "pod1", "--label", "io.containers.autoupdate=registry", "--label", "io.containers.autoupdate.authfile=/some/authfile.json", CITEST_IMAGE, "top"}) 1337 top1.WaitWithDefaultTimeout() 1338 Expect(top1).Should(ExitCleanly()) 1339 1340 top2 := podmanTest.Podman([]string{"run", "-dt", "--name", "top2", "--workdir", "/root", "--pod", "pod1", "--label", "io.containers.autoupdate=registry", "--label", "io.containers.autoupdate.authfile=/some/authfile.json", CITEST_IMAGE, "top"}) 1341 top2.WaitWithDefaultTimeout() 1342 Expect(top2).Should(ExitCleanly()) 1343 1344 kube := podmanTest.Podman([]string{"kube", "generate", "pod1"}) 1345 kube.WaitWithDefaultTimeout() 1346 Expect(kube).Should(ExitCleanly()) 1347 1348 pod := new(v1.Pod) 1349 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1350 Expect(err).ToNot(HaveOccurred()) 1351 Expect(pod.Spec.Containers[0]).To(HaveField("WorkingDir", "")) 1352 Expect(pod.Spec.Containers[1]).To(HaveField("WorkingDir", "/root")) 1353 1354 for _, ctr := range []string{"top1", "top2"} { 1355 Expect(pod.Annotations).To(HaveKeyWithValue("io.containers.autoupdate/"+ctr, "registry")) 1356 Expect(pod.Annotations).To(HaveKeyWithValue("io.containers.autoupdate.authfile/"+ctr, "/some/authfile.json")) 1357 } 1358 }) 1359 1360 It("can export env variables correctly", func() { 1361 // Fixes https://github.com/containers/podman/issues/12647 1362 // PR https://github.com/containers/podman/pull/12648 1363 1364 ctrName := "gen-kube-env-ctr" 1365 podName := "gen-kube-env" 1366 // In proxy environment, this test needs to the --http-proxy=false option (#16684) 1367 session1 := podmanTest.Podman([]string{"run", "-d", "--http-proxy=false", "--pod", "new:" + podName, "--name", ctrName, 1368 "-e", "FOO=bar", 1369 "-e", "HELLO=WORLD", 1370 CITEST_IMAGE, "top"}) 1371 session1.WaitWithDefaultTimeout() 1372 Expect(session1).Should(ExitCleanly()) 1373 1374 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 1375 kube.WaitWithDefaultTimeout() 1376 Expect(kube).Should(ExitCleanly()) 1377 1378 pod := new(v1.Pod) 1379 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1380 Expect(err).ToNot(HaveOccurred()) 1381 1382 Expect(pod.Spec.Containers[0].Env).To(HaveLen(2)) 1383 }) 1384 1385 It("omit secret if empty", func() { 1386 dir := GinkgoT().TempDir() 1387 1388 podCreate := podmanTest.Podman([]string{"run", "-d", "--pod", "new:" + "noSecretsPod", "--name", "noSecretsCtr", "--volume", dir + ":/foobar", CITEST_IMAGE}) 1389 podCreate.WaitWithDefaultTimeout() 1390 Expect(podCreate).Should(ExitCleanly()) 1391 1392 kube := podmanTest.Podman([]string{"kube", "generate", "noSecretsPod"}) 1393 kube.WaitWithDefaultTimeout() 1394 Expect(kube).Should(ExitCleanly()) 1395 1396 Expect(kube.OutputToString()).ShouldNot(ContainSubstring("secret")) 1397 1398 pod := new(v1.Pod) 1399 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1400 Expect(err).ToNot(HaveOccurred()) 1401 1402 Expect(pod.Spec.Volumes[0].Secret).To(BeNil()) 1403 }) 1404 1405 It("with default ulimits", func() { 1406 ctrName := "ulimit-ctr" 1407 session := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, CITEST_IMAGE, "sleep", "1000"}) 1408 session.WaitWithDefaultTimeout() 1409 Expect(session).Should(ExitCleanly()) 1410 1411 outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") 1412 kube := podmanTest.Podman([]string{"kube", "generate", ctrName, "-f", outputFile}) 1413 kube.WaitWithDefaultTimeout() 1414 Expect(kube).Should(ExitCleanly()) 1415 1416 b, err := os.ReadFile(outputFile) 1417 Expect(err).ShouldNot(HaveOccurred()) 1418 pod := new(v1.Pod) 1419 err = yaml.Unmarshal(b, pod) 1420 Expect(err).ToNot(HaveOccurred()) 1421 Expect(pod.Annotations).To(Not(HaveKey(define.UlimitAnnotation))) 1422 }) 1423 1424 It("with --ulimit set", func() { 1425 ctrName := "ulimit-ctr" 1426 ctrNameInKubePod := ctrName + "-pod-" + ctrName 1427 session1 := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--ulimit", "nofile=1231:3123", CITEST_IMAGE, "sleep", "1000"}) 1428 session1.WaitWithDefaultTimeout() 1429 Expect(session1).Should(ExitCleanly()) 1430 1431 outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml") 1432 kube := podmanTest.Podman([]string{"kube", "generate", ctrName, "-f", outputFile}) 1433 kube.WaitWithDefaultTimeout() 1434 Expect(kube).Should(ExitCleanly()) 1435 1436 b, err := os.ReadFile(outputFile) 1437 Expect(err).ShouldNot(HaveOccurred()) 1438 pod := new(v1.Pod) 1439 err = yaml.Unmarshal(b, pod) 1440 Expect(err).ToNot(HaveOccurred()) 1441 Expect(pod.Annotations).To(HaveKey(define.UlimitAnnotation)) 1442 Expect(pod.Annotations[define.UlimitAnnotation]).To(ContainSubstring("nofile=1231:3123")) 1443 1444 rm := podmanTest.Podman([]string{"pod", "rm", "-t", "0", "-f", ctrName}) 1445 rm.WaitWithDefaultTimeout() 1446 Expect(rm).Should(ExitCleanly()) 1447 1448 play := podmanTest.Podman([]string{"kube", "play", outputFile}) 1449 play.WaitWithDefaultTimeout() 1450 Expect(play).Should(ExitCleanly()) 1451 1452 inspect := podmanTest.Podman([]string{"inspect", ctrNameInKubePod}) 1453 inspect.WaitWithDefaultTimeout() 1454 Expect(inspect).Should(ExitCleanly()) 1455 Expect(inspect.OutputToString()).To(ContainSubstring("RLIMIT_NOFILE")) 1456 Expect(inspect.OutputToString()).To(ContainSubstring("1231")) 1457 Expect(inspect.OutputToString()).To(ContainSubstring("3123")) 1458 }) 1459 1460 It("on pod with --type=deployment", func() { 1461 podName := "test-pod" 1462 session := podmanTest.Podman([]string{"pod", "create", podName}) 1463 session.WaitWithDefaultTimeout() 1464 Expect(session).Should(ExitCleanly()) 1465 1466 session = podmanTest.Podman([]string{"create", "--pod", podName, CITEST_IMAGE, "top"}) 1467 session.WaitWithDefaultTimeout() 1468 Expect(session).Should(ExitCleanly()) 1469 session = podmanTest.Podman([]string{"create", "--pod", podName, CITEST_IMAGE, "sleep", "100"}) 1470 session.WaitWithDefaultTimeout() 1471 Expect(session).Should(ExitCleanly()) 1472 1473 kube := podmanTest.Podman([]string{"kube", "generate", "--type", "deployment", podName}) 1474 kube.WaitWithDefaultTimeout() 1475 Expect(kube).Should(ExitCleanly()) 1476 1477 dep := new(v1.Deployment) 1478 err := yaml.Unmarshal(kube.Out.Contents(), dep) 1479 Expect(err).ToNot(HaveOccurred()) 1480 Expect(dep.Name).To(Equal(podName + "-deployment")) 1481 Expect(dep.Spec.Selector.MatchLabels).To(HaveKeyWithValue("app", podName)) 1482 Expect(dep.Spec.Template.Name).To(Equal(podName)) 1483 1484 numContainers := 0 1485 for range dep.Spec.Template.Spec.Containers { 1486 numContainers++ 1487 } 1488 Expect(numContainers).To(Equal(2)) 1489 }) 1490 1491 It("on ctr with --type=deployment and --replicas=3", func() { 1492 ctrName := "test-ctr" 1493 session := podmanTest.Podman([]string{"create", "--name", ctrName, CITEST_IMAGE, "top"}) 1494 session.WaitWithDefaultTimeout() 1495 Expect(session).Should(ExitCleanly()) 1496 1497 kube := podmanTest.Podman([]string{"kube", "generate", "--type", "deployment", "--replicas", "3", ctrName}) 1498 kube.WaitWithDefaultTimeout() 1499 Expect(kube).Should(ExitCleanly()) 1500 1501 dep := new(v1.Deployment) 1502 err := yaml.Unmarshal(kube.Out.Contents(), dep) 1503 Expect(err).ToNot(HaveOccurred()) 1504 Expect(dep.Name).To(Equal(ctrName + "-pod-deployment")) 1505 Expect(dep.Spec.Selector.MatchLabels).To(HaveKeyWithValue("app", ctrName+"-pod")) 1506 Expect(dep.Spec.Template.Name).To(Equal(ctrName + "-pod")) 1507 Expect(int(*dep.Spec.Replicas)).To(Equal(3)) 1508 1509 numContainers := 0 1510 for range dep.Spec.Template.Spec.Containers { 1511 numContainers++ 1512 } 1513 Expect(numContainers).To(Equal(1)) 1514 }) 1515 1516 It("on ctr with --type=pod and --replicas=3 should fail", func() { 1517 ctrName := "test-ctr" 1518 session := podmanTest.Podman([]string{"create", "--name", ctrName, CITEST_IMAGE, "top"}) 1519 session.WaitWithDefaultTimeout() 1520 Expect(session).Should(ExitCleanly()) 1521 1522 kube := podmanTest.Podman([]string{"kube", "generate", "--type", "pod", "--replicas", "3", ctrName}) 1523 kube.WaitWithDefaultTimeout() 1524 Expect(kube).Should(ExitWithError(125, "--replicas can only be set when --type is set to deployment")) 1525 }) 1526 1527 It("on pod with --type=deployment and --restart=no should fail", func() { 1528 podName := "test-pod" 1529 session := podmanTest.Podman([]string{"pod", "create", "--restart", "no", podName}) 1530 session.WaitWithDefaultTimeout() 1531 Expect(session).Should(ExitCleanly()) 1532 1533 session = podmanTest.Podman([]string{"create", "--pod", podName, CITEST_IMAGE, "top"}) 1534 session.WaitWithDefaultTimeout() 1535 Expect(session).Should(ExitCleanly()) 1536 1537 kube := podmanTest.Podman([]string{"kube", "generate", "--type", "deployment", podName}) 1538 kube.WaitWithDefaultTimeout() 1539 Expect(kube).Should(ExitWithError(125, "k8s Deployments can only have restartPolicy set to Always")) 1540 }) 1541 1542 It("on pod with invalid name", func() { 1543 podName := "test_pod" 1544 session := podmanTest.Podman([]string{"pod", "create", podName}) 1545 session.WaitWithDefaultTimeout() 1546 Expect(session).Should(ExitCleanly()) 1547 1548 session = podmanTest.Podman([]string{"create", "--pod", podName, "--restart", "no", CITEST_IMAGE, "top"}) 1549 session.WaitWithDefaultTimeout() 1550 Expect(session).Should(ExitCleanly()) 1551 1552 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 1553 kube.WaitWithDefaultTimeout() 1554 Expect(kube).Should(ExitCleanly()) 1555 1556 pod := new(v1.Pod) 1557 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1558 Expect(err).ToNot(HaveOccurred()) 1559 // The pod name should no longer have _ and there should be no hostname in the generated yaml 1560 Expect(pod.Name).To(Equal("testpod")) 1561 Expect(pod.Spec.Hostname).To(Equal("")) 1562 }) 1563 1564 It("--podman-only on container with --volumes-from", func() { 1565 ctr1 := "ctr1" 1566 ctr2 := "ctr2" 1567 vol1 := filepath.Join(podmanTest.TempDir, "vol-test1") 1568 1569 err := os.MkdirAll(vol1, 0755) 1570 Expect(err).ToNot(HaveOccurred()) 1571 1572 session := podmanTest.Podman([]string{"create", "--name", ctr1, "-v", vol1, CITEST_IMAGE}) 1573 session.WaitWithDefaultTimeout() 1574 Expect(session).Should(ExitCleanly()) 1575 1576 session = podmanTest.Podman([]string{"create", "--volumes-from", ctr1, "--name", ctr2, CITEST_IMAGE}) 1577 session.WaitWithDefaultTimeout() 1578 Expect(session).Should(ExitCleanly()) 1579 1580 kube := podmanTest.Podman([]string{"kube", "generate", "--podman-only", ctr2}) 1581 kube.WaitWithDefaultTimeout() 1582 Expect(kube).Should(ExitCleanly()) 1583 1584 pod := new(v1.Pod) 1585 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1586 Expect(err).ToNot(HaveOccurred()) 1587 Expect(pod.Annotations).To(HaveKeyWithValue(define.VolumesFromAnnotation+"/"+ctr2, ctr1)) 1588 }) 1589 1590 It("pod volumes-from annotation with semicolon as field separator", func() { 1591 // Assert that volumes-from annotation for multiple source 1592 // containers along with their mount options are getting 1593 // generated with semicolon as the field separator. 1594 1595 srcctr1, srcctr2, tgtctr := "srcctr1", "srcctr2", "tgtctr" 1596 frmopt1, frmopt2 := srcctr1+":ro", srcctr2+":ro" 1597 vol1 := filepath.Join(podmanTest.TempDir, "vol-test1") 1598 vol2 := filepath.Join(podmanTest.TempDir, "vol-test2") 1599 1600 err1 := os.MkdirAll(vol1, 0755) 1601 Expect(err1).ToNot(HaveOccurred()) 1602 1603 err2 := os.MkdirAll(vol2, 0755) 1604 Expect(err2).ToNot(HaveOccurred()) 1605 1606 session := podmanTest.Podman([]string{"create", "--name", srcctr1, "-v", vol1, CITEST_IMAGE}) 1607 session.WaitWithDefaultTimeout() 1608 Expect(session).Should(ExitCleanly()) 1609 1610 session = podmanTest.Podman([]string{"create", "--name", srcctr2, "-v", vol2, CITEST_IMAGE}) 1611 session.WaitWithDefaultTimeout() 1612 Expect(session).Should(ExitCleanly()) 1613 1614 session = podmanTest.Podman([]string{"create", "--volumes-from", frmopt1, "--volumes-from", frmopt2, "--name", tgtctr, CITEST_IMAGE}) 1615 session.WaitWithDefaultTimeout() 1616 Expect(session).Should(ExitCleanly()) 1617 1618 kube := podmanTest.Podman([]string{"kube", "generate", "--podman-only", tgtctr}) 1619 kube.WaitWithDefaultTimeout() 1620 Expect(kube).Should(ExitCleanly()) 1621 1622 pod := new(v1.Pod) 1623 err3 := yaml.Unmarshal(kube.Out.Contents(), pod) 1624 Expect(err3).ToNot(HaveOccurred()) 1625 Expect(pod.Annotations).To(HaveKeyWithValue(define.VolumesFromAnnotation+"/"+tgtctr, frmopt1+";"+frmopt2)) 1626 }) 1627 1628 It("--podman-only on container with --rm", func() { 1629 ctr := "ctr" 1630 1631 session := podmanTest.Podman([]string{"create", "--rm", "--name", ctr, CITEST_IMAGE}) 1632 session.WaitWithDefaultTimeout() 1633 Expect(session).Should(ExitCleanly()) 1634 1635 kube := podmanTest.Podman([]string{"kube", "generate", "--podman-only", ctr}) 1636 kube.WaitWithDefaultTimeout() 1637 Expect(kube).Should(ExitCleanly()) 1638 1639 pod := new(v1.Pod) 1640 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1641 Expect(err).ToNot(HaveOccurred()) 1642 Expect(pod.Annotations).To(HaveKeyWithValue(define.InspectAnnotationAutoremove+"/"+ctr, define.InspectResponseTrue)) 1643 }) 1644 1645 It("--podman-only on container with --privileged", func() { 1646 ctr := "ctr" 1647 1648 session := podmanTest.Podman([]string{"create", "--privileged", "--name", ctr, CITEST_IMAGE}) 1649 session.WaitWithDefaultTimeout() 1650 Expect(session).Should(ExitCleanly()) 1651 1652 kube := podmanTest.Podman([]string{"kube", "generate", "--podman-only", ctr}) 1653 kube.WaitWithDefaultTimeout() 1654 Expect(kube).Should(ExitCleanly()) 1655 1656 pod := new(v1.Pod) 1657 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1658 Expect(err).ToNot(HaveOccurred()) 1659 Expect(pod.Annotations).To(HaveKeyWithValue(define.InspectAnnotationPrivileged+"/"+ctr, define.InspectResponseTrue)) 1660 }) 1661 1662 It("--podman-only on container with --init", func() { 1663 ctr := "ctr" 1664 1665 session := podmanTest.Podman([]string{"create", "--init", "--name", ctr, CITEST_IMAGE}) 1666 session.WaitWithDefaultTimeout() 1667 Expect(session).Should(ExitCleanly()) 1668 1669 kube := podmanTest.Podman([]string{"kube", "generate", "--podman-only", ctr}) 1670 kube.WaitWithDefaultTimeout() 1671 Expect(kube).Should(ExitCleanly()) 1672 1673 pod := new(v1.Pod) 1674 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1675 Expect(err).ToNot(HaveOccurred()) 1676 Expect(pod.Annotations).To(HaveKeyWithValue(define.InspectAnnotationInit+"/"+ctr, define.InspectResponseTrue)) 1677 }) 1678 1679 It("--podman-only on container with --cidfile", func() { 1680 ctr := "ctr" 1681 cidFile := filepath.Join(podmanTest.TempDir, RandomString(10)+".txt") 1682 1683 session := podmanTest.Podman([]string{"create", "--cidfile", cidFile, "--name", ctr, CITEST_IMAGE}) 1684 session.WaitWithDefaultTimeout() 1685 Expect(session).Should(ExitCleanly()) 1686 1687 kube := podmanTest.Podman([]string{"kube", "generate", "--podman-only", ctr}) 1688 kube.WaitWithDefaultTimeout() 1689 Expect(kube).Should(ExitCleanly()) 1690 1691 pod := new(v1.Pod) 1692 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1693 Expect(err).ToNot(HaveOccurred()) 1694 Expect(pod.Annotations).To(HaveKeyWithValue(define.InspectAnnotationCIDFile+"/"+ctr, cidFile)) 1695 }) 1696 1697 It("--podman-only on container with --security-opt seccomp=unconfined", func() { 1698 ctr := "ctr" 1699 1700 session := podmanTest.Podman([]string{"create", "--security-opt", "seccomp=unconfined", "--name", ctr, CITEST_IMAGE}) 1701 session.WaitWithDefaultTimeout() 1702 Expect(session).Should(ExitCleanly()) 1703 1704 kube := podmanTest.Podman([]string{"kube", "generate", "--podman-only", ctr}) 1705 kube.WaitWithDefaultTimeout() 1706 Expect(kube).Should(ExitCleanly()) 1707 1708 pod := new(v1.Pod) 1709 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1710 Expect(err).ToNot(HaveOccurred()) 1711 Expect(pod.Annotations).To(HaveKeyWithValue(define.InspectAnnotationSeccomp+"/"+ctr, "unconfined")) 1712 }) 1713 1714 It("--podman-only on container with --security-opt apparmor=unconfined", func() { 1715 ctr := "ctr" 1716 1717 session := podmanTest.Podman([]string{"create", "--security-opt", "apparmor=unconfined", "--name", ctr, CITEST_IMAGE}) 1718 session.WaitWithDefaultTimeout() 1719 Expect(session).Should(ExitCleanly()) 1720 1721 kube := podmanTest.Podman([]string{"kube", "generate", "--podman-only", ctr}) 1722 kube.WaitWithDefaultTimeout() 1723 Expect(kube).Should(ExitCleanly()) 1724 1725 pod := new(v1.Pod) 1726 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1727 Expect(err).ToNot(HaveOccurred()) 1728 Expect(pod.Annotations).To(HaveKeyWithValue(define.InspectAnnotationApparmor+"/"+ctr, "unconfined")) 1729 }) 1730 1731 It("--podman-only on container with --security-opt label=level:s0", func() { 1732 ctr := "ctr" 1733 1734 session := podmanTest.Podman([]string{"create", "--security-opt", "label=level:s0", "--name", ctr, CITEST_IMAGE}) 1735 session.WaitWithDefaultTimeout() 1736 Expect(session).Should(ExitCleanly()) 1737 1738 kube := podmanTest.Podman([]string{"kube", "generate", "--podman-only", ctr}) 1739 kube.WaitWithDefaultTimeout() 1740 Expect(kube).Should(ExitCleanly()) 1741 1742 pod := new(v1.Pod) 1743 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1744 Expect(err).ToNot(HaveOccurred()) 1745 Expect(pod.Annotations).To(HaveKeyWithValue(define.InspectAnnotationLabel+"/"+ctr, "level:s0")) 1746 }) 1747 1748 It("--podman-only on container with --publish-all", func() { 1749 podmanTest.AddImageToRWStore(CITEST_IMAGE) 1750 dockerfile := fmt.Sprintf(`FROM %s 1751 EXPOSE 2002 1752 EXPOSE 2001-2003 1753 EXPOSE 2004-2005/tcp`, CITEST_IMAGE) 1754 imageName := "testimg" 1755 podmanTest.BuildImage(dockerfile, imageName, "false") 1756 1757 // Verify that the buildah is just passing through the EXPOSE keys 1758 inspect := podmanTest.Podman([]string{"inspect", imageName}) 1759 inspect.WaitWithDefaultTimeout() 1760 image := inspect.InspectImageJSON() 1761 Expect(image).To(HaveLen(1)) 1762 Expect(image[0].Config.ExposedPorts).To(HaveLen(3)) 1763 Expect(image[0].Config.ExposedPorts).To(HaveKey("2002/tcp")) 1764 Expect(image[0].Config.ExposedPorts).To(HaveKey("2001-2003/tcp")) 1765 Expect(image[0].Config.ExposedPorts).To(HaveKey("2004-2005/tcp")) 1766 1767 ctr := "ctr" 1768 session := podmanTest.Podman([]string{"create", "--publish-all", "--name", ctr, imageName, "true"}) 1769 session.WaitWithDefaultTimeout() 1770 Expect(session).Should(ExitCleanly()) 1771 1772 kube := podmanTest.Podman([]string{"kube", "generate", "--podman-only", ctr}) 1773 kube.WaitWithDefaultTimeout() 1774 Expect(kube).Should(ExitCleanly()) 1775 1776 pod := new(v1.Pod) 1777 err = yaml.Unmarshal(kube.Out.Contents(), pod) 1778 Expect(err).ToNot(HaveOccurred()) 1779 Expect(pod.Annotations).To(HaveKeyWithValue(define.InspectAnnotationPublishAll+"/"+ctr, define.InspectResponseTrue)) 1780 }) 1781 1782 It("on pod with --infra-name set", func() { 1783 infraName := "infra-ctr" 1784 podName := "test-pod" 1785 podSession := podmanTest.Podman([]string{"pod", "create", "--infra-name", infraName, podName}) 1786 podSession.WaitWithDefaultTimeout() 1787 Expect(podSession).Should(ExitCleanly()) 1788 1789 session := podmanTest.Podman([]string{"create", "--pod", podName, CITEST_IMAGE, "top"}) 1790 session.WaitWithDefaultTimeout() 1791 Expect(session).Should(ExitCleanly()) 1792 1793 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 1794 kube.WaitWithDefaultTimeout() 1795 Expect(kube).Should(ExitCleanly()) 1796 1797 pod := new(v1.Pod) 1798 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1799 Expect(err).ToNot(HaveOccurred()) 1800 Expect(pod.Annotations).To(HaveKeyWithValue(define.InfraNameAnnotation, infraName)) 1801 }) 1802 1803 It("on pod without --infra-name set", func() { 1804 podName := "test-pod" 1805 podSession := podmanTest.Podman([]string{"pod", "create", podName}) 1806 podSession.WaitWithDefaultTimeout() 1807 Expect(podSession).Should(ExitCleanly()) 1808 1809 session := podmanTest.Podman([]string{"create", "--pod", podName, CITEST_IMAGE, "top"}) 1810 session.WaitWithDefaultTimeout() 1811 Expect(session).Should(ExitCleanly()) 1812 1813 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 1814 kube.WaitWithDefaultTimeout() 1815 Expect(kube).Should(ExitCleanly()) 1816 1817 // There should be no infra name annotation set if the --infra-name flag wasn't set during pod creation 1818 pod := new(v1.Pod) 1819 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1820 Expect(err).ToNot(HaveOccurred()) 1821 Expect(pod.Annotations).To(HaveLen(1)) 1822 }) 1823 1824 It("on pod with --stop-timeout set for ctr", func() { 1825 podName := "test-pod" 1826 podSession := podmanTest.Podman([]string{"pod", "create", podName}) 1827 podSession.WaitWithDefaultTimeout() 1828 Expect(podSession).Should(ExitCleanly()) 1829 1830 session := podmanTest.Podman([]string{"create", "--pod", podName, "--stop-timeout", "20", CITEST_IMAGE, "top"}) 1831 session.WaitWithDefaultTimeout() 1832 Expect(session).Should(ExitCleanly()) 1833 1834 kube := podmanTest.Podman([]string{"kube", "generate", podName}) 1835 kube.WaitWithDefaultTimeout() 1836 Expect(kube).Should(ExitCleanly()) 1837 1838 // TerminationGracePeriodSeconds should be set to 20 1839 pod := new(v1.Pod) 1840 err := yaml.Unmarshal(kube.Out.Contents(), pod) 1841 Expect(err).ToNot(HaveOccurred()) 1842 Expect(int(*pod.Spec.TerminationGracePeriodSeconds)).To(Equal(20)) 1843 }) 1844 1845 It("on pod with --type=daemonset", func() { 1846 podName := "test-pod" 1847 session := podmanTest.Podman([]string{"pod", "create", podName}) 1848 session.WaitWithDefaultTimeout() 1849 Expect(session).Should(ExitCleanly()) 1850 1851 session = podmanTest.Podman([]string{"create", "--pod", podName, CITEST_IMAGE, "top"}) 1852 session.WaitWithDefaultTimeout() 1853 Expect(session).Should(ExitCleanly()) 1854 session = podmanTest.Podman([]string{"create", "--pod", podName, CITEST_IMAGE, "sleep", "100"}) 1855 session.WaitWithDefaultTimeout() 1856 Expect(session).Should(ExitCleanly()) 1857 1858 kube := podmanTest.Podman([]string{"kube", "generate", "--type", "daemonset", podName}) 1859 kube.WaitWithDefaultTimeout() 1860 Expect(kube).Should(ExitCleanly()) 1861 1862 dep := new(v1.DaemonSet) 1863 err := yaml.Unmarshal(kube.Out.Contents(), dep) 1864 Expect(err).ToNot(HaveOccurred()) 1865 Expect(dep.Name).To(Equal(podName + "-daemonset")) 1866 Expect(dep.Spec.Selector.MatchLabels).To(HaveKeyWithValue("app", podName)) 1867 Expect(dep.Spec.Template.Name).To(Equal(podName)) 1868 Expect(dep.Spec.Template.Spec.Containers).To(HaveLen(2)) 1869 }) 1870 1871 It("on ctr with --type=daemonset and --replicas=3 should fail", func() { 1872 ctrName := "test-ctr" 1873 session := podmanTest.Podman([]string{"create", "--name", ctrName, CITEST_IMAGE, "top"}) 1874 session.WaitWithDefaultTimeout() 1875 Expect(session).Should(ExitCleanly()) 1876 1877 kube := podmanTest.Podman([]string{"kube", "generate", "--type", "daemonset", "--replicas", "3", ctrName}) 1878 kube.WaitWithDefaultTimeout() 1879 Expect(kube).Should(ExitWithError(125, "--replicas can only be set when --type is set to deployment")) 1880 }) 1881 1882 It("on pod with --type=daemonset and --restart=no should fail", func() { 1883 podName := "test-pod" 1884 session := podmanTest.Podman([]string{"pod", "create", "--restart", "no", podName}) 1885 session.WaitWithDefaultTimeout() 1886 Expect(session).Should(ExitCleanly()) 1887 1888 session = podmanTest.Podman([]string{"create", "--pod", podName, CITEST_IMAGE, "top"}) 1889 session.WaitWithDefaultTimeout() 1890 Expect(session).Should(ExitCleanly()) 1891 1892 kube := podmanTest.Podman([]string{"kube", "generate", "--type", "daemonset", podName}) 1893 kube.WaitWithDefaultTimeout() 1894 Expect(kube).Should(ExitWithError(125, "k8s DaemonSets can only have restartPolicy set to Always")) 1895 }) 1896 })