github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/test/e2e/checkpoint_test.go (about) 1 // +build !remoteclient 2 3 package integration 4 5 import ( 6 "net" 7 "os" 8 "os/exec" 9 10 "github.com/containers/libpod/pkg/criu" 11 . "github.com/containers/libpod/test/utils" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 ) 15 16 func getRunString(input []string) []string { 17 // CRIU does not work with seccomp correctly on RHEL7 : seccomp=unconfined 18 runString := []string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", "--ip", GetRandomIPAddress()} 19 return append(runString, input...) 20 } 21 22 var _ = Describe("Podman checkpoint", func() { 23 var ( 24 tempdir string 25 err error 26 podmanTest *PodmanTestIntegration 27 ) 28 29 BeforeEach(func() { 30 SkipIfRootless() 31 tempdir, err = CreateTempDirInTempDir() 32 if err != nil { 33 os.Exit(1) 34 } 35 podmanTest = PodmanTestCreate(tempdir) 36 podmanTest.Setup() 37 podmanTest.SeedImages() 38 // Check if the runtime implements checkpointing. Currently only 39 // runc's checkpoint/restore implementation is supported. 40 cmd := exec.Command(podmanTest.OCIRuntime, "checkpoint", "--help") 41 if err := cmd.Start(); err != nil { 42 Skip("OCI runtime does not support checkpoint/restore") 43 } 44 if err := cmd.Wait(); err != nil { 45 Skip("OCI runtime does not support checkpoint/restore") 46 } 47 48 if !criu.CheckForCriu() { 49 Skip("CRIU is missing or too old.") 50 } 51 // Only Fedora 29 and newer has a new enough selinux-policy and 52 // container-selinux package to support CRIU in correctly 53 // restoring threaded processes 54 hostInfo := podmanTest.Host 55 if hostInfo.Distribution == "fedora" && hostInfo.Version < "29" { 56 Skip("Checkpoint/Restore with SELinux only works on Fedora >= 29") 57 } 58 }) 59 60 AfterEach(func() { 61 podmanTest.Cleanup() 62 f := CurrentGinkgoTestDescription() 63 processTestResult(f) 64 65 }) 66 67 It("podman checkpoint bogus container", func() { 68 session := podmanTest.Podman([]string{"container", "checkpoint", "foobar"}) 69 session.WaitWithDefaultTimeout() 70 Expect(session).To(ExitWithError()) 71 }) 72 73 It("podman restore bogus container", func() { 74 session := podmanTest.Podman([]string{"container", "restore", "foobar"}) 75 session.WaitWithDefaultTimeout() 76 Expect(session).To(ExitWithError()) 77 }) 78 79 It("podman checkpoint a running container by id", func() { 80 localRunString := getRunString([]string{ALPINE, "top"}) 81 session := podmanTest.Podman(localRunString) 82 session.WaitWithDefaultTimeout() 83 Expect(session.ExitCode()).To(Equal(0)) 84 cid := session.OutputToString() 85 86 result := podmanTest.Podman([]string{"container", "checkpoint", cid}) 87 result.WaitWithDefaultTimeout() 88 89 Expect(result.ExitCode()).To(Equal(0)) 90 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 91 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 92 93 result = podmanTest.Podman([]string{"container", "restore", cid}) 94 result.WaitWithDefaultTimeout() 95 96 Expect(result.ExitCode()).To(Equal(0)) 97 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 98 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 99 }) 100 101 It("podman checkpoint a running container by name", func() { 102 localRunString := getRunString([]string{"--name", "test_name", ALPINE, "top"}) 103 session := podmanTest.Podman(localRunString) 104 session.WaitWithDefaultTimeout() 105 Expect(session.ExitCode()).To(Equal(0)) 106 107 result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"}) 108 result.WaitWithDefaultTimeout() 109 110 Expect(result.ExitCode()).To(Equal(0)) 111 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 112 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 113 114 result = podmanTest.Podman([]string{"container", "restore", "test_name"}) 115 result.WaitWithDefaultTimeout() 116 117 Expect(result.ExitCode()).To(Equal(0)) 118 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 119 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 120 }) 121 122 It("podman pause a checkpointed container by id", func() { 123 localRunString := getRunString([]string{ALPINE, "top"}) 124 session := podmanTest.Podman(localRunString) 125 session.WaitWithDefaultTimeout() 126 Expect(session.ExitCode()).To(Equal(0)) 127 cid := session.OutputToString() 128 129 result := podmanTest.Podman([]string{"container", "checkpoint", cid}) 130 result.WaitWithDefaultTimeout() 131 132 Expect(result.ExitCode()).To(Equal(0)) 133 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 134 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 135 136 result = podmanTest.Podman([]string{"pause", cid}) 137 result.WaitWithDefaultTimeout() 138 139 Expect(result.ExitCode()).To(Equal(125)) 140 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 141 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 142 143 result = podmanTest.Podman([]string{"container", "restore", cid}) 144 result.WaitWithDefaultTimeout() 145 Expect(result.ExitCode()).To(Equal(0)) 146 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 147 148 result = podmanTest.Podman([]string{"rm", cid}) 149 result.WaitWithDefaultTimeout() 150 Expect(result.ExitCode()).To(Equal(2)) 151 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 152 153 result = podmanTest.Podman([]string{"rm", "-f", cid}) 154 result.WaitWithDefaultTimeout() 155 Expect(result.ExitCode()).To(Equal(0)) 156 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 157 158 }) 159 160 It("podman checkpoint latest running container", func() { 161 localRunString := getRunString([]string{"--name", "first", ALPINE, "top"}) 162 session1 := podmanTest.Podman(localRunString) 163 session1.WaitWithDefaultTimeout() 164 Expect(session1.ExitCode()).To(Equal(0)) 165 166 localRunString = getRunString([]string{"--name", "second", ALPINE, "top"}) 167 session2 := podmanTest.Podman(localRunString) 168 session2.WaitWithDefaultTimeout() 169 Expect(session2.ExitCode()).To(Equal(0)) 170 171 result := podmanTest.Podman([]string{"container", "checkpoint", "-l"}) 172 result.WaitWithDefaultTimeout() 173 174 Expect(result.ExitCode()).To(Equal(0)) 175 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 176 177 ps := podmanTest.Podman([]string{"ps", "-q", "--no-trunc"}) 178 ps.WaitWithDefaultTimeout() 179 Expect(ps.ExitCode()).To(Equal(0)) 180 Expect(ps.LineInOutputContains(session1.OutputToString())).To(BeTrue()) 181 Expect(ps.LineInOutputContains(session2.OutputToString())).To(BeFalse()) 182 183 result = podmanTest.Podman([]string{"container", "restore", "-l"}) 184 result.WaitWithDefaultTimeout() 185 186 Expect(result.ExitCode()).To(Equal(0)) 187 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) 188 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 189 Expect(podmanTest.GetContainerStatus()).To(Not(ContainSubstring("Exited"))) 190 191 result = podmanTest.Podman([]string{"rm", "-fa"}) 192 result.WaitWithDefaultTimeout() 193 Expect(result.ExitCode()).To(Equal(0)) 194 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 195 }) 196 197 It("podman checkpoint all running container", func() { 198 localRunString := getRunString([]string{"--name", "first", ALPINE, "top"}) 199 session1 := podmanTest.Podman(localRunString) 200 session1.WaitWithDefaultTimeout() 201 Expect(session1.ExitCode()).To(Equal(0)) 202 203 localRunString = getRunString([]string{"--name", "second", ALPINE, "top"}) 204 session2 := podmanTest.Podman(localRunString) 205 session2.WaitWithDefaultTimeout() 206 Expect(session2.ExitCode()).To(Equal(0)) 207 208 result := podmanTest.Podman([]string{"container", "checkpoint", "-a"}) 209 result.WaitWithDefaultTimeout() 210 211 Expect(result.ExitCode()).To(Equal(0)) 212 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 213 214 ps := podmanTest.Podman([]string{"ps", "-q", "--no-trunc"}) 215 ps.WaitWithDefaultTimeout() 216 Expect(ps.ExitCode()).To(Equal(0)) 217 Expect(ps.LineInOutputContains(session1.OutputToString())).To(BeFalse()) 218 Expect(ps.LineInOutputContains(session2.OutputToString())).To(BeFalse()) 219 220 result = podmanTest.Podman([]string{"container", "restore", "-a"}) 221 result.WaitWithDefaultTimeout() 222 223 Expect(result.ExitCode()).To(Equal(0)) 224 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) 225 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 226 Expect(podmanTest.GetContainerStatus()).To(Not(ContainSubstring("Exited"))) 227 228 result = podmanTest.Podman([]string{"rm", "-fa"}) 229 result.WaitWithDefaultTimeout() 230 Expect(result.ExitCode()).To(Equal(0)) 231 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 232 }) 233 234 It("podman checkpoint container with established tcp connections", func() { 235 localRunString := getRunString([]string{redis}) 236 session := podmanTest.Podman(localRunString) 237 session.WaitWithDefaultTimeout() 238 Expect(session.ExitCode()).To(Equal(0)) 239 240 IP := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"}) 241 IP.WaitWithDefaultTimeout() 242 Expect(IP.ExitCode()).To(Equal(0)) 243 244 // Open a network connection to the redis server 245 conn, err := net.Dial("tcp", IP.OutputToString()+":6379") 246 if err != nil { 247 os.Exit(1) 248 } 249 // This should fail as the container has established TCP connections 250 result := podmanTest.Podman([]string{"container", "checkpoint", "-l"}) 251 result.WaitWithDefaultTimeout() 252 253 Expect(result.ExitCode()).To(Equal(125)) 254 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 255 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 256 257 // Now it should work thanks to "--tcp-established" 258 result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "--tcp-established"}) 259 result.WaitWithDefaultTimeout() 260 261 Expect(result.ExitCode()).To(Equal(0)) 262 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 263 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 264 265 // Restore should fail as the checkpoint image contains established TCP connections 266 result = podmanTest.Podman([]string{"container", "restore", "-l"}) 267 result.WaitWithDefaultTimeout() 268 269 Expect(result.ExitCode()).To(Equal(125)) 270 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 271 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 272 273 // Now it should work thanks to "--tcp-established" 274 result = podmanTest.Podman([]string{"container", "restore", "-l", "--tcp-established"}) 275 result.WaitWithDefaultTimeout() 276 277 Expect(result.ExitCode()).To(Equal(0)) 278 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 279 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 280 281 result = podmanTest.Podman([]string{"rm", "-fa"}) 282 result.WaitWithDefaultTimeout() 283 Expect(result.ExitCode()).To(Equal(0)) 284 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 285 286 conn.Close() 287 }) 288 289 It("podman checkpoint with --leave-running", func() { 290 localRunString := getRunString([]string{ALPINE, "top"}) 291 session := podmanTest.Podman(localRunString) 292 session.WaitWithDefaultTimeout() 293 Expect(session.ExitCode()).To(Equal(0)) 294 cid := session.OutputToString() 295 296 // Checkpoint container, but leave it running 297 result := podmanTest.Podman([]string{"container", "checkpoint", "--leave-running", cid}) 298 result.WaitWithDefaultTimeout() 299 300 Expect(result.ExitCode()).To(Equal(0)) 301 // Make sure it is still running 302 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 303 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 304 305 // Stop the container 306 result = podmanTest.Podman([]string{"container", "stop", cid}) 307 result.WaitWithDefaultTimeout() 308 309 Expect(result.ExitCode()).To(Equal(0)) 310 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 311 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 312 313 // Restore the stopped container from the previous checkpoint 314 result = podmanTest.Podman([]string{"container", "restore", cid}) 315 result.WaitWithDefaultTimeout() 316 317 Expect(result.ExitCode()).To(Equal(0)) 318 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 319 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 320 321 result = podmanTest.Podman([]string{"rm", "-fa"}) 322 result.WaitWithDefaultTimeout() 323 Expect(result.ExitCode()).To(Equal(0)) 324 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 325 }) 326 327 It("podman checkpoint and restore container with same IP", func() { 328 localRunString := getRunString([]string{"--name", "test_name", ALPINE, "top"}) 329 session := podmanTest.Podman(localRunString) 330 session.WaitWithDefaultTimeout() 331 Expect(session.ExitCode()).To(Equal(0)) 332 333 IPBefore := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"}) 334 IPBefore.WaitWithDefaultTimeout() 335 Expect(IPBefore.ExitCode()).To(Equal(0)) 336 337 MACBefore := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.MacAddress}}"}) 338 MACBefore.WaitWithDefaultTimeout() 339 Expect(MACBefore.ExitCode()).To(Equal(0)) 340 341 result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"}) 342 result.WaitWithDefaultTimeout() 343 344 Expect(result.ExitCode()).To(Equal(0)) 345 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 346 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 347 348 result = podmanTest.Podman([]string{"container", "restore", "test_name"}) 349 result.WaitWithDefaultTimeout() 350 351 IPAfter := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"}) 352 IPAfter.WaitWithDefaultTimeout() 353 Expect(IPAfter.ExitCode()).To(Equal(0)) 354 355 MACAfter := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.MacAddress}}"}) 356 MACAfter.WaitWithDefaultTimeout() 357 Expect(MACAfter.ExitCode()).To(Equal(0)) 358 359 // Check that IP address did not change between checkpointing and restoring 360 Expect(IPBefore.OutputToString()).To(Equal(IPAfter.OutputToString())) 361 362 // Check that MAC address did not change between checkpointing and restoring 363 Expect(MACBefore.OutputToString()).To(Equal(MACAfter.OutputToString())) 364 365 Expect(result.ExitCode()).To(Equal(0)) 366 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 367 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 368 369 result = podmanTest.Podman([]string{"rm", "-fa"}) 370 result.WaitWithDefaultTimeout() 371 Expect(result.ExitCode()).To(Equal(0)) 372 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 373 }) 374 375 // This test does the same steps which are necessary for migrating 376 // a container from one host to another 377 It("podman checkpoint container with export (migration)", func() { 378 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 379 session := podmanTest.Podman(localRunString) 380 session.WaitWithDefaultTimeout() 381 Expect(session.ExitCode()).To(Equal(0)) 382 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 383 cid := session.OutputToString() 384 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 385 386 result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) 387 result.WaitWithDefaultTimeout() 388 389 // As the container has been started with '--rm' it will be completely 390 // cleaned up after checkpointing. 391 Expect(result.ExitCode()).To(Equal(0)) 392 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 393 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 394 395 // Restore container the first time with different name. 396 // Using '--ignore-static-ip' as for parallel test runs 397 // each containers gets a random IP address via '--ip'. 398 // '--ignore-static-ip' tells the restore to use the next 399 // available IP address. 400 // First restore the container with a new name/ID to make 401 // sure nothing in the restored container depends on the 402 // original container. 403 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName, "-n", "restore_again", "--ignore-static-ip"}) 404 result.WaitWithDefaultTimeout() 405 406 Expect(result.ExitCode()).To(Equal(0)) 407 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 408 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 409 410 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 411 result.WaitWithDefaultTimeout() 412 413 Expect(result.ExitCode()).To(Equal(0)) 414 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) 415 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 416 417 result = podmanTest.Podman([]string{"rm", "-fa"}) 418 result.WaitWithDefaultTimeout() 419 Expect(result.ExitCode()).To(Equal(0)) 420 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 421 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 422 423 // Remove exported checkpoint 424 os.Remove(fileName) 425 }) 426 427 It("podman checkpoint and restore container with root file-system changes", func() { 428 // Start the container 429 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 430 session := podmanTest.Podman(localRunString) 431 session.WaitWithDefaultTimeout() 432 Expect(session.ExitCode()).To(Equal(0)) 433 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 434 cid := session.OutputToString() 435 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 436 437 // Change the container's root file-system 438 result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) 439 result.WaitWithDefaultTimeout() 440 Expect(result.ExitCode()).To(Equal(0)) 441 442 result = podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "rm /etc/motd"}) 443 result.WaitWithDefaultTimeout() 444 Expect(result.ExitCode()).To(Equal(0)) 445 446 result = podmanTest.Podman([]string{"diff", "-l"}) 447 result.WaitWithDefaultTimeout() 448 Expect(result.ExitCode()).To(Equal(0)) 449 Expect(result.OutputToString()).To(ContainSubstring("C /etc")) 450 Expect(result.OutputToString()).To(ContainSubstring("A /test.output")) 451 Expect(result.OutputToString()).To(ContainSubstring("D /etc/motd")) 452 Expect(len(result.OutputToStringArray())).To(Equal(3)) 453 454 // Checkpoint the container 455 result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) 456 result.WaitWithDefaultTimeout() 457 458 Expect(result.ExitCode()).To(Equal(0)) 459 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 460 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 461 462 // Restore the container 463 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 464 result.WaitWithDefaultTimeout() 465 466 Expect(result.ExitCode()).To(Equal(0)) 467 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 468 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 469 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 470 471 // Verify the changes to the container's root file-system 472 result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) 473 result.WaitWithDefaultTimeout() 474 Expect(result.ExitCode()).To(Equal(0)) 475 Expect(result.OutputToString()).To(ContainSubstring("test" + cid + "test")) 476 477 result = podmanTest.Podman([]string{"diff", "-l"}) 478 result.WaitWithDefaultTimeout() 479 Expect(result.ExitCode()).To(Equal(0)) 480 Expect(result.OutputToString()).To(ContainSubstring("C /etc")) 481 Expect(result.OutputToString()).To(ContainSubstring("A /test.output")) 482 Expect(result.OutputToString()).To(ContainSubstring("D /etc/motd")) 483 Expect(len(result.OutputToStringArray())).To(Equal(3)) 484 485 // Remove exported checkpoint 486 os.Remove(fileName) 487 }) 488 It("podman checkpoint and restore container with root file-system changes using --ignore-rootfs during restore", func() { 489 // Start the container 490 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 491 session := podmanTest.Podman(localRunString) 492 session.WaitWithDefaultTimeout() 493 Expect(session.ExitCode()).To(Equal(0)) 494 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 495 cid := session.OutputToString() 496 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 497 498 // Change the container's root file-system 499 result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) 500 result.WaitWithDefaultTimeout() 501 Expect(result.ExitCode()).To(Equal(0)) 502 503 // Checkpoint the container 504 result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) 505 result.WaitWithDefaultTimeout() 506 507 Expect(result.ExitCode()).To(Equal(0)) 508 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 509 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 510 511 // Restore the container 512 result = podmanTest.Podman([]string{"container", "restore", "--ignore-rootfs", "-i", fileName}) 513 result.WaitWithDefaultTimeout() 514 515 Expect(result.ExitCode()).To(Equal(0)) 516 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 517 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 518 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 519 520 // Verify the changes to the container's root file-system 521 result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) 522 result.WaitWithDefaultTimeout() 523 Expect(result.ExitCode()).To(Equal(1)) 524 Expect(result.ErrorToString()).To(ContainSubstring("cat: can't open '/test.output': No such file or directory")) 525 526 // Remove exported checkpoint 527 os.Remove(fileName) 528 }) 529 It("podman checkpoint and restore container with root file-system changes using --ignore-rootfs during checkpoint", func() { 530 // Start the container 531 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 532 session := podmanTest.Podman(localRunString) 533 session.WaitWithDefaultTimeout() 534 Expect(session.ExitCode()).To(Equal(0)) 535 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 536 cid := session.OutputToString() 537 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 538 539 // Change the container's root file-system 540 result := podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) 541 result.WaitWithDefaultTimeout() 542 Expect(result.ExitCode()).To(Equal(0)) 543 544 // Checkpoint the container 545 result = podmanTest.Podman([]string{"container", "checkpoint", "--ignore-rootfs", "-l", "-e", fileName}) 546 result.WaitWithDefaultTimeout() 547 548 Expect(result.ExitCode()).To(Equal(0)) 549 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 550 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 551 552 // Restore the container 553 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 554 result.WaitWithDefaultTimeout() 555 556 Expect(result.ExitCode()).To(Equal(0)) 557 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 558 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 559 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 560 561 // Verify the changes to the container's root file-system 562 result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) 563 result.WaitWithDefaultTimeout() 564 Expect(result.ExitCode()).To(Equal(1)) 565 Expect(result.ErrorToString()).To(ContainSubstring("cat: can't open '/test.output': No such file or directory")) 566 567 // Remove exported checkpoint 568 os.Remove(fileName) 569 }) 570 571 It("podman checkpoint and run exec in restored container", func() { 572 // Start the container 573 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 574 session := podmanTest.Podman(localRunString) 575 session.WaitWithDefaultTimeout() 576 Expect(session.ExitCode()).To(Equal(0)) 577 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 578 cid := session.OutputToString() 579 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 580 581 // Checkpoint the container 582 result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) 583 result.WaitWithDefaultTimeout() 584 585 Expect(result.ExitCode()).To(Equal(0)) 586 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 587 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 588 589 // Restore the container 590 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 591 result.WaitWithDefaultTimeout() 592 593 Expect(result.ExitCode()).To(Equal(0)) 594 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 595 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 596 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 597 598 // Exec in the container 599 result = podmanTest.Podman([]string{"exec", "-l", "/bin/sh", "-c", "echo " + cid + " > /test.output"}) 600 result.WaitWithDefaultTimeout() 601 Expect(result.ExitCode()).To(Equal(0)) 602 603 result = podmanTest.Podman([]string{"exec", "-l", "cat", "/test.output"}) 604 result.WaitWithDefaultTimeout() 605 Expect(result.ExitCode()).To(Equal(0)) 606 Expect(result.OutputToString()).To(ContainSubstring(cid)) 607 608 // Remove exported checkpoint 609 os.Remove(fileName) 610 }) 611 612 It("podman checkpoint a container started with --rm", func() { 613 // Start the container 614 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 615 session := podmanTest.Podman(localRunString) 616 session.WaitWithDefaultTimeout() 617 cid := session.OutputToString() 618 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 619 620 // Checkpoint the container - this should fail as it was started with --rm 621 result := podmanTest.Podman([]string{"container", "checkpoint", "-l"}) 622 result.WaitWithDefaultTimeout() 623 Expect(result).To(ExitWithError()) 624 Expect(result.ErrorToString()).To(ContainSubstring("Cannot checkpoint containers that have been started with '--rm'")) 625 626 // Checkpointing with --export should still work 627 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 628 629 result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName}) 630 result.WaitWithDefaultTimeout() 631 632 // As the container has been started with '--rm' it will be completely 633 // cleaned up after checkpointing. 634 Expect(result.ExitCode()).To(Equal(0)) 635 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 636 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 637 638 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 639 result.WaitWithDefaultTimeout() 640 641 Expect(result.ExitCode()).To(Equal(0)) 642 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 643 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 644 645 result = podmanTest.Podman([]string{"rm", "-fa"}) 646 result.WaitWithDefaultTimeout() 647 Expect(result.ExitCode()).To(Equal(0)) 648 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 649 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 650 651 // Remove exported checkpoint 652 os.Remove(fileName) 653 }) 654 })