github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/test/e2e/checkpoint_test.go (about) 1 package integration 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net" 7 "os" 8 "os/exec" 9 "path/filepath" 10 "strings" 11 "time" 12 13 "github.com/checkpoint-restore/go-criu/v5/stats" 14 "github.com/hanks177/podman/v4/pkg/checkpoint/crutils" 15 "github.com/hanks177/podman/v4/pkg/criu" 16 "github.com/hanks177/podman/v4/pkg/domain/entities" 17 . "github.com/hanks177/podman/v4/test/utils" 18 "github.com/hanks177/podman/v4/utils" 19 . "github.com/onsi/ginkgo" 20 . "github.com/onsi/gomega" 21 . "github.com/onsi/gomega/gexec" 22 ) 23 24 func getRunString(input []string) []string { 25 // CRIU does not work with seccomp correctly on RHEL7 : seccomp=unconfined 26 runString := []string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", "--ip", GetRandomIPAddress()} 27 return append(runString, input...) 28 } 29 30 var _ = Describe("Podman checkpoint", func() { 31 var ( 32 tempdir string 33 err error 34 podmanTest *PodmanTestIntegration 35 ) 36 37 BeforeEach(func() { 38 SkipIfRootless("checkpoint not supported in rootless mode") 39 tempdir, err = CreateTempDirInTempDir() 40 Expect(err).To(BeNil()) 41 42 podmanTest = PodmanTestCreate(tempdir) 43 podmanTest.Setup() 44 // Check if the runtime implements checkpointing. Currently only 45 // runc's checkpoint/restore implementation is supported. 46 cmd := exec.Command(podmanTest.OCIRuntime, "checkpoint", "--help") 47 if err := cmd.Start(); err != nil { 48 Skip("OCI runtime does not support checkpoint/restore") 49 } 50 if err := cmd.Wait(); err != nil { 51 Skip("OCI runtime does not support checkpoint/restore") 52 } 53 54 if !criu.CheckForCriu(criu.MinCriuVersion) { 55 Skip("CRIU is missing or too old.") 56 } 57 // Only Fedora 29 and newer has a new enough selinux-policy and 58 // container-selinux package to support CRIU in correctly 59 // restoring threaded processes 60 hostInfo := podmanTest.Host 61 if hostInfo.Distribution == "fedora" && hostInfo.Version < "29" { 62 Skip("Checkpoint/Restore with SELinux only works on Fedora >= 29") 63 } 64 }) 65 66 AfterEach(func() { 67 podmanTest.Cleanup() 68 f := CurrentGinkgoTestDescription() 69 processTestResult(f) 70 71 }) 72 73 It("podman checkpoint bogus container", func() { 74 session := podmanTest.Podman([]string{"container", "checkpoint", "foobar"}) 75 session.WaitWithDefaultTimeout() 76 Expect(session).To(ExitWithError()) 77 }) 78 79 It("podman restore bogus container", func() { 80 session := podmanTest.Podman([]string{"container", "restore", "foobar"}) 81 session.WaitWithDefaultTimeout() 82 Expect(session).To(ExitWithError()) 83 }) 84 85 It("podman checkpoint a running container by id", func() { 86 localRunString := getRunString([]string{ALPINE, "top"}) 87 session := podmanTest.Podman(localRunString) 88 session.WaitWithDefaultTimeout() 89 Expect(session).Should(Exit(0)) 90 cid := session.OutputToString() 91 92 // Check if none of the checkpoint/restore specific information is displayed 93 // for newly started containers. 94 inspect := podmanTest.Podman([]string{"inspect", cid}) 95 inspect.WaitWithDefaultTimeout() 96 Expect(inspect).Should(Exit(0)) 97 inspectOut := inspect.InspectContainerToJSON() 98 Expect(inspectOut[0].State.Checkpointed).To(BeFalse(), ".State.Checkpointed") 99 Expect(inspectOut[0].State.Restored).To(BeFalse(), ".State.Restored") 100 Expect(inspectOut[0].State).To(HaveField("CheckpointPath", "")) 101 Expect(inspectOut[0].State).To(HaveField("CheckpointLog", "")) 102 Expect(inspectOut[0].State).To(HaveField("RestoreLog", "")) 103 104 result := podmanTest.Podman([]string{ 105 "container", 106 "checkpoint", 107 "--keep", 108 cid, 109 }) 110 result.WaitWithDefaultTimeout() 111 112 Expect(result).Should(Exit(0)) 113 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 114 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 115 116 // For a checkpointed container we expect the checkpoint related information 117 // to be populated. 118 inspect = podmanTest.Podman([]string{"inspect", cid}) 119 inspect.WaitWithDefaultTimeout() 120 Expect(inspect).Should(Exit(0)) 121 inspectOut = inspect.InspectContainerToJSON() 122 Expect(inspectOut[0].State.Checkpointed).To(BeTrue(), ".State.Checkpointed") 123 Expect(inspectOut[0].State.Restored).To(BeFalse(), ".State.Restored") 124 Expect(inspectOut[0].State.CheckpointPath).To(ContainSubstring("userdata/checkpoint")) 125 Expect(inspectOut[0].State.CheckpointLog).To(ContainSubstring("userdata/dump.log")) 126 Expect(inspectOut[0].State).To(HaveField("RestoreLog", "")) 127 128 result = podmanTest.Podman([]string{ 129 "container", 130 "restore", 131 "--keep", 132 cid, 133 }) 134 result.WaitWithDefaultTimeout() 135 136 Expect(result).Should(Exit(0)) 137 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 138 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 139 140 inspect = podmanTest.Podman([]string{"inspect", cid}) 141 inspect.WaitWithDefaultTimeout() 142 Expect(inspect).Should(Exit(0)) 143 inspectOut = inspect.InspectContainerToJSON() 144 Expect(inspectOut[0].State.Restored).To(BeTrue(), ".State.Restored") 145 Expect(inspectOut[0].State.Checkpointed).To(BeFalse(), ".State.Checkpointed") 146 Expect(inspectOut[0].State.CheckpointPath).To(ContainSubstring("userdata/checkpoint")) 147 Expect(inspectOut[0].State.CheckpointLog).To(ContainSubstring("userdata/dump.log")) 148 Expect(inspectOut[0].State.RestoreLog).To(ContainSubstring("userdata/restore.log")) 149 150 result = podmanTest.Podman([]string{ 151 "container", 152 "stop", 153 "--timeout", 154 "0", 155 cid, 156 }) 157 result.WaitWithDefaultTimeout() 158 159 Expect(result).Should(Exit(0)) 160 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 161 162 result = podmanTest.Podman([]string{ 163 "container", 164 "start", 165 cid, 166 }) 167 result.WaitWithDefaultTimeout() 168 169 Expect(result).Should(Exit(0)) 170 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 171 172 // Stopping and starting the container should remove all checkpoint 173 // related information from inspect again. 174 inspect = podmanTest.Podman([]string{"inspect", cid}) 175 inspect.WaitWithDefaultTimeout() 176 Expect(inspect).Should(Exit(0)) 177 inspectOut = inspect.InspectContainerToJSON() 178 Expect(inspectOut[0].State.Checkpointed).To(BeFalse(), ".State.Checkpointed") 179 Expect(inspectOut[0].State.Restored).To(BeFalse(), ".State.Restored") 180 Expect(inspectOut[0].State).To(HaveField("CheckpointPath", "")) 181 Expect(inspectOut[0].State).To(HaveField("CheckpointLog", "")) 182 Expect(inspectOut[0].State).To(HaveField("RestoreLog", "")) 183 }) 184 185 It("podman checkpoint a running container by name", func() { 186 localRunString := getRunString([]string{"--name", "test_name", ALPINE, "top"}) 187 session := podmanTest.Podman(localRunString) 188 session.WaitWithDefaultTimeout() 189 Expect(session).Should(Exit(0)) 190 191 result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"}) 192 result.WaitWithDefaultTimeout() 193 194 Expect(result).Should(Exit(0)) 195 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 196 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 197 198 result = podmanTest.Podman([]string{"container", "restore", "test_name"}) 199 result.WaitWithDefaultTimeout() 200 201 Expect(result).Should(Exit(0)) 202 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 203 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 204 }) 205 206 It("podman pause a checkpointed container by id", func() { 207 localRunString := getRunString([]string{ALPINE, "top"}) 208 session := podmanTest.Podman(localRunString) 209 session.WaitWithDefaultTimeout() 210 Expect(session).Should(Exit(0)) 211 cid := session.OutputToString() 212 213 result := podmanTest.Podman([]string{"container", "checkpoint", cid}) 214 result.WaitWithDefaultTimeout() 215 216 Expect(result).Should(Exit(0)) 217 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 218 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 219 220 result = podmanTest.Podman([]string{"pause", cid}) 221 result.WaitWithDefaultTimeout() 222 223 Expect(result).Should(Exit(125)) 224 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 225 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 226 227 result = podmanTest.Podman([]string{"container", "restore", cid}) 228 result.WaitWithDefaultTimeout() 229 Expect(result).Should(Exit(0)) 230 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 231 232 result = podmanTest.Podman([]string{"rm", cid}) 233 result.WaitWithDefaultTimeout() 234 Expect(result).Should(Exit(2)) 235 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 236 237 result = podmanTest.Podman([]string{"rm", "-t", "1", "-f", cid}) 238 result.WaitWithDefaultTimeout() 239 Expect(result).Should(Exit(0)) 240 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 241 242 }) 243 244 It("podman checkpoint latest running container", func() { 245 localRunString := getRunString([]string{"--name", "first", ALPINE, "top"}) 246 session1 := podmanTest.Podman(localRunString) 247 session1.WaitWithDefaultTimeout() 248 Expect(session1).Should(Exit(0)) 249 250 localRunString = getRunString([]string{"--name", "second", ALPINE, "top"}) 251 session2 := podmanTest.Podman(localRunString) 252 session2.WaitWithDefaultTimeout() 253 Expect(session2).Should(Exit(0)) 254 255 result := podmanTest.Podman([]string{"container", "checkpoint", "second"}) 256 result.WaitWithDefaultTimeout() 257 258 Expect(result).Should(Exit(0)) 259 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 260 261 ps := podmanTest.Podman([]string{"ps", "-q", "--no-trunc"}) 262 ps.WaitWithDefaultTimeout() 263 Expect(ps).Should(Exit(0)) 264 Expect(ps.OutputToString()).To(ContainSubstring(session1.OutputToString())) 265 Expect(ps.OutputToString()).To(Not(ContainSubstring(session2.OutputToString()))) 266 267 result = podmanTest.Podman([]string{"container", "restore", "second"}) 268 result.WaitWithDefaultTimeout() 269 270 Expect(result).Should(Exit(0)) 271 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) 272 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 273 Expect(podmanTest.GetContainerStatus()).To(Not(ContainSubstring("Exited"))) 274 275 result = podmanTest.Podman([]string{"rm", "-t", "0", "-fa"}) 276 result.WaitWithDefaultTimeout() 277 Expect(result).Should(Exit(0)) 278 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 279 }) 280 281 It("podman checkpoint all running container", func() { 282 localRunString := getRunString([]string{"--name", "first", ALPINE, "top"}) 283 session1 := podmanTest.Podman(localRunString) 284 session1.WaitWithDefaultTimeout() 285 Expect(session1).Should(Exit(0)) 286 287 localRunString = getRunString([]string{"--name", "second", ALPINE, "top"}) 288 session2 := podmanTest.Podman(localRunString) 289 session2.WaitWithDefaultTimeout() 290 Expect(session2).Should(Exit(0)) 291 292 result := podmanTest.Podman([]string{"container", "checkpoint", "-a"}) 293 result.WaitWithDefaultTimeout() 294 295 Expect(result).Should(Exit(0)) 296 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 297 298 ps := podmanTest.Podman([]string{"ps", "-q", "--no-trunc"}) 299 ps.WaitWithDefaultTimeout() 300 Expect(ps).Should(Exit(0)) 301 Expect(ps.OutputToString()).To(Not(ContainSubstring(session1.OutputToString()))) 302 Expect(ps.OutputToString()).To(Not(ContainSubstring(session2.OutputToString()))) 303 304 result = podmanTest.Podman([]string{"container", "restore", "-a"}) 305 result.WaitWithDefaultTimeout() 306 307 Expect(result).Should(Exit(0)) 308 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) 309 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 310 Expect(podmanTest.GetContainerStatus()).To(Not(ContainSubstring("Exited"))) 311 312 result = podmanTest.Podman([]string{"rm", "-t", "0", "-fa"}) 313 result.WaitWithDefaultTimeout() 314 Expect(result).Should(Exit(0)) 315 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 316 }) 317 318 It("podman checkpoint container with established tcp connections", func() { 319 // Broken on Ubuntu. 320 SkipIfNotFedora() 321 localRunString := getRunString([]string{redis}) 322 session := podmanTest.Podman(localRunString) 323 session.WaitWithDefaultTimeout() 324 Expect(session).Should(Exit(0)) 325 cid := session.OutputToString() 326 if !WaitContainerReady(podmanTest, cid, "Ready to accept connections", 20, 1) { 327 Fail("Container failed to get ready") 328 } 329 330 IP := podmanTest.Podman([]string{"inspect", cid, "--format={{.NetworkSettings.IPAddress}}"}) 331 IP.WaitWithDefaultTimeout() 332 Expect(IP).Should(Exit(0)) 333 334 // Open a network connection to the redis server 335 conn, err := net.DialTimeout("tcp4", IP.OutputToString()+":6379", time.Duration(3)*time.Second) 336 Expect(err).To(BeNil()) 337 338 // This should fail as the container has established TCP connections 339 result := podmanTest.Podman([]string{"container", "checkpoint", cid}) 340 result.WaitWithDefaultTimeout() 341 342 Expect(result).Should(Exit(125)) 343 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 344 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 345 346 // Now it should work thanks to "--tcp-established" 347 result = podmanTest.Podman([]string{"container", "checkpoint", cid, "--tcp-established"}) 348 result.WaitWithDefaultTimeout() 349 350 Expect(result).Should(Exit(0)) 351 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 352 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 353 354 // Restore should fail as the checkpoint image contains established TCP connections 355 result = podmanTest.Podman([]string{"container", "restore", cid}) 356 result.WaitWithDefaultTimeout() 357 358 Expect(result).Should(Exit(125)) 359 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 360 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 361 362 // Now it should work thanks to "--tcp-established" 363 result = podmanTest.Podman([]string{"container", "restore", cid, "--tcp-established"}) 364 result.WaitWithDefaultTimeout() 365 366 Expect(result).Should(Exit(0)) 367 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 368 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 369 370 result = podmanTest.Podman([]string{"rm", "-t", "0", "-fa"}) 371 result.WaitWithDefaultTimeout() 372 Expect(result).Should(Exit(0)) 373 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 374 375 conn.Close() 376 }) 377 378 It("podman checkpoint with --leave-running", func() { 379 localRunString := getRunString([]string{ALPINE, "top"}) 380 session := podmanTest.Podman(localRunString) 381 session.WaitWithDefaultTimeout() 382 Expect(session).Should(Exit(0)) 383 cid := session.OutputToString() 384 385 // Checkpoint container, but leave it running 386 result := podmanTest.Podman([]string{"container", "checkpoint", "--leave-running", cid}) 387 result.WaitWithDefaultTimeout() 388 389 Expect(result).Should(Exit(0)) 390 // Make sure it is still running 391 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 392 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 393 394 // Stop the container 395 result = podmanTest.Podman([]string{"container", "stop", cid}) 396 result.WaitWithDefaultTimeout() 397 398 Expect(result).Should(Exit(0)) 399 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 400 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 401 402 // Restore the stopped container from the previous checkpoint 403 result = podmanTest.Podman([]string{"container", "restore", cid}) 404 result.WaitWithDefaultTimeout() 405 406 Expect(result).Should(Exit(0)) 407 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 408 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 409 410 result = podmanTest.Podman([]string{"rm", "-t", "0", "-fa"}) 411 result.WaitWithDefaultTimeout() 412 Expect(result).Should(Exit(0)) 413 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 414 }) 415 416 It("podman checkpoint and restore container with same IP", func() { 417 localRunString := getRunString([]string{"--name", "test_name", ALPINE, "top"}) 418 session := podmanTest.Podman(localRunString) 419 session.WaitWithDefaultTimeout() 420 Expect(session).Should(Exit(0)) 421 422 IPBefore := podmanTest.Podman([]string{"inspect", "test_name", "--format={{.NetworkSettings.IPAddress}}"}) 423 IPBefore.WaitWithDefaultTimeout() 424 Expect(IPBefore).Should(Exit(0)) 425 426 MACBefore := podmanTest.Podman([]string{"inspect", "test_name", "--format={{.NetworkSettings.MacAddress}}"}) 427 MACBefore.WaitWithDefaultTimeout() 428 Expect(MACBefore).Should(Exit(0)) 429 430 result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"}) 431 result.WaitWithDefaultTimeout() 432 433 Expect(result).Should(Exit(0)) 434 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 435 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 436 437 result = podmanTest.Podman([]string{"container", "restore", "test_name"}) 438 result.WaitWithDefaultTimeout() 439 440 IPAfter := podmanTest.Podman([]string{"inspect", "test_name", "--format={{.NetworkSettings.IPAddress}}"}) 441 IPAfter.WaitWithDefaultTimeout() 442 Expect(IPAfter).Should(Exit(0)) 443 444 MACAfter := podmanTest.Podman([]string{"inspect", "test_name", "--format={{.NetworkSettings.MacAddress}}"}) 445 MACAfter.WaitWithDefaultTimeout() 446 Expect(MACAfter).Should(Exit(0)) 447 448 // Check that IP address did not change between checkpointing and restoring 449 Expect(IPBefore.OutputToString()).To(Equal(IPAfter.OutputToString())) 450 451 // Check that MAC address did not change between checkpointing and restoring 452 Expect(MACBefore.OutputToString()).To(Equal(MACAfter.OutputToString())) 453 454 Expect(result).Should(Exit(0)) 455 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 456 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 457 458 result = podmanTest.Podman([]string{"rm", "-t", "0", "-fa"}) 459 result.WaitWithDefaultTimeout() 460 Expect(result).Should(Exit(0)) 461 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 462 }) 463 464 // This test does the same steps which are necessary for migrating 465 // a container from one host to another 466 It("podman checkpoint container with export (migration)", func() { 467 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 468 session := podmanTest.Podman(localRunString) 469 session.WaitWithDefaultTimeout() 470 Expect(session).Should(Exit(0)) 471 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 472 cid := session.OutputToString() 473 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 474 475 result := podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) 476 result.WaitWithDefaultTimeout() 477 478 // As the container has been started with '--rm' it will be completely 479 // cleaned up after checkpointing. 480 Expect(result).Should(Exit(0)) 481 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 482 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 483 484 // Restore container the first time with different name. 485 // Using '--ignore-static-ip' as for parallel test runs 486 // each containers gets a random IP address via '--ip'. 487 // '--ignore-static-ip' tells the restore to use the next 488 // available IP address. 489 // First restore the container with a new name/ID to make 490 // sure nothing in the restored container depends on the 491 // original container. 492 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName, "-n", "restore_again", "--ignore-static-ip"}) 493 result.WaitWithDefaultTimeout() 494 495 Expect(result).Should(Exit(0)) 496 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 497 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 498 499 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 500 result.WaitWithDefaultTimeout() 501 502 Expect(result).Should(Exit(0)) 503 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) 504 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 505 506 result = podmanTest.Podman([]string{"rm", "-t", "0", "-fa"}) 507 result.WaitWithDefaultTimeout() 508 Expect(result).Should(Exit(0)) 509 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 510 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 511 512 // Remove exported checkpoint 513 os.Remove(fileName) 514 }) 515 // This test does the same steps which are necessary for migrating 516 // a container from one host to another 517 It("podman checkpoint container with export and different compression algorithms", func() { 518 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 519 session := podmanTest.Podman(localRunString) 520 session.WaitWithDefaultTimeout() 521 Expect(session).Should(Exit(0)) 522 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 523 cid := session.OutputToString() 524 fileName := "/tmp/checkpoint-" + cid + ".tar" 525 526 // Checkpoint with the default algorithm 527 result := podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) 528 result.WaitWithDefaultTimeout() 529 530 // As the container has been started with '--rm' it will be completely 531 // cleaned up after checkpointing. 532 Expect(result).Should(Exit(0)) 533 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 534 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 535 536 // Restore container 537 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 538 result.WaitWithDefaultTimeout() 539 540 Expect(result).Should(Exit(0)) 541 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 542 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 543 544 // Checkpoint with the zstd algorithm 545 result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName, "--compress", "zstd"}) 546 result.WaitWithDefaultTimeout() 547 548 // As the container has been started with '--rm' it will be completely 549 // cleaned up after checkpointing. 550 Expect(result).Should(Exit(0)) 551 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 552 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 553 554 // Restore container 555 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 556 result.WaitWithDefaultTimeout() 557 558 Expect(result).Should(Exit(0)) 559 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 560 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 561 562 // Checkpoint with the none algorithm 563 result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName, "-c", "none"}) 564 result.WaitWithDefaultTimeout() 565 566 // As the container has been started with '--rm' it will be completely 567 // cleaned up after checkpointing. 568 Expect(result).Should(Exit(0)) 569 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 570 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 571 572 // Restore container 573 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 574 result.WaitWithDefaultTimeout() 575 576 Expect(result).Should(Exit(0)) 577 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 578 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 579 580 // Checkpoint with the gzip algorithm 581 result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName, "-c", "gzip"}) 582 result.WaitWithDefaultTimeout() 583 584 // As the container has been started with '--rm' it will be completely 585 // cleaned up after checkpointing. 586 Expect(result).Should(Exit(0)) 587 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 588 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 589 590 // Restore container 591 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 592 result.WaitWithDefaultTimeout() 593 594 Expect(result).Should(Exit(0)) 595 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 596 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 597 598 // Checkpoint with the non-existing algorithm 599 result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName, "-c", "non-existing"}) 600 result.WaitWithDefaultTimeout() 601 602 Expect(result).Should(Exit(125)) 603 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 604 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 605 606 result = podmanTest.Podman([]string{"rm", "--time", "0", "-fa"}) 607 result.WaitWithDefaultTimeout() 608 Expect(result).Should(Exit(0)) 609 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 610 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 611 612 // Remove exported checkpoint 613 os.Remove(fileName) 614 }) 615 616 It("podman checkpoint and restore container with root file-system changes", func() { 617 // Start the container 618 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 619 session := podmanTest.Podman(localRunString) 620 session.WaitWithDefaultTimeout() 621 Expect(session).Should(Exit(0)) 622 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 623 cid := session.OutputToString() 624 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 625 626 // Change the container's root file-system 627 result := podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) 628 result.WaitWithDefaultTimeout() 629 Expect(result).Should(Exit(0)) 630 631 result = podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "rm /etc/motd"}) 632 result.WaitWithDefaultTimeout() 633 Expect(result).Should(Exit(0)) 634 635 result = podmanTest.Podman([]string{"diff", cid}) 636 result.WaitWithDefaultTimeout() 637 Expect(result).Should(Exit(0)) 638 Expect(result.OutputToString()).To(ContainSubstring("C /etc")) 639 Expect(result.OutputToString()).To(ContainSubstring("A /test.output")) 640 Expect(result.OutputToString()).To(ContainSubstring("D /etc/motd")) 641 Expect(result.OutputToStringArray()).To(HaveLen(3)) 642 643 // Checkpoint the container 644 result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) 645 result.WaitWithDefaultTimeout() 646 647 Expect(result).Should(Exit(0)) 648 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 649 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 650 651 // Restore the container 652 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 653 result.WaitWithDefaultTimeout() 654 655 Expect(result).Should(Exit(0)) 656 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 657 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 658 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 659 660 // Verify the changes to the container's root file-system 661 result = podmanTest.Podman([]string{"exec", cid, "cat", "/test.output"}) 662 result.WaitWithDefaultTimeout() 663 Expect(result).Should(Exit(0)) 664 Expect(result.OutputToString()).To(ContainSubstring("test" + cid + "test")) 665 666 result = podmanTest.Podman([]string{"diff", cid}) 667 result.WaitWithDefaultTimeout() 668 Expect(result).Should(Exit(0)) 669 Expect(result.OutputToString()).To(ContainSubstring("C /etc")) 670 Expect(result.OutputToString()).To(ContainSubstring("A /test.output")) 671 Expect(result.OutputToString()).To(ContainSubstring("D /etc/motd")) 672 Expect(result.OutputToStringArray()).To(HaveLen(3)) 673 674 // Remove exported checkpoint 675 os.Remove(fileName) 676 }) 677 It("podman checkpoint and restore container with root file-system changes using --ignore-rootfs during restore", func() { 678 // Start the container 679 // test that restore works without network namespace (https://github.com/containers/podman/issues/14389) 680 session := podmanTest.Podman([]string{"run", "--network=none", "-d", "--rm", ALPINE, "top"}) 681 session.WaitWithDefaultTimeout() 682 Expect(session).Should(Exit(0)) 683 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 684 cid := session.OutputToString() 685 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 686 687 // Change the container's root file-system 688 result := podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) 689 result.WaitWithDefaultTimeout() 690 Expect(result).Should(Exit(0)) 691 692 // Checkpoint the container 693 result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) 694 result.WaitWithDefaultTimeout() 695 696 Expect(result).Should(Exit(0)) 697 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 698 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 699 700 // Restore the container 701 result = podmanTest.Podman([]string{"container", "restore", "--ignore-rootfs", "-i", fileName}) 702 result.WaitWithDefaultTimeout() 703 704 Expect(result).Should(Exit(0)) 705 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 706 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 707 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 708 709 // Verify the changes to the container's root file-system 710 result = podmanTest.Podman([]string{"exec", cid, "cat", "/test.output"}) 711 result.WaitWithDefaultTimeout() 712 Expect(result).Should(Exit(1)) 713 Expect(result.ErrorToString()).To(ContainSubstring("cat: can't open '/test.output': No such file or directory")) 714 715 // Remove exported checkpoint 716 os.Remove(fileName) 717 }) 718 It("podman checkpoint and restore container with root file-system changes using --ignore-rootfs during checkpoint", func() { 719 // Start the container 720 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 721 session := podmanTest.Podman(localRunString) 722 session.WaitWithDefaultTimeout() 723 Expect(session).Should(Exit(0)) 724 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 725 cid := session.OutputToString() 726 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 727 728 // Change the container's root file-system 729 result := podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "echo test" + cid + "test > /test.output"}) 730 result.WaitWithDefaultTimeout() 731 Expect(result).Should(Exit(0)) 732 733 // Checkpoint the container 734 result = podmanTest.Podman([]string{"container", "checkpoint", "--ignore-rootfs", cid, "-e", fileName}) 735 result.WaitWithDefaultTimeout() 736 737 Expect(result).Should(Exit(0)) 738 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 739 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 740 741 // Restore the container 742 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 743 result.WaitWithDefaultTimeout() 744 745 Expect(result).Should(Exit(0)) 746 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 747 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 748 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 749 750 // Verify the changes to the container's root file-system 751 result = podmanTest.Podman([]string{"exec", cid, "cat", "/test.output"}) 752 result.WaitWithDefaultTimeout() 753 Expect(result).Should(Exit(1)) 754 Expect(result.ErrorToString()).To(ContainSubstring("cat: can't open '/test.output': No such file or directory")) 755 756 // Remove exported checkpoint 757 os.Remove(fileName) 758 }) 759 760 It("podman checkpoint and run exec in restored container", func() { 761 // Start the container 762 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 763 session := podmanTest.Podman(localRunString) 764 session.WaitWithDefaultTimeout() 765 Expect(session).Should(Exit(0)) 766 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 767 cid := session.OutputToString() 768 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 769 770 // Checkpoint the container 771 result := podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) 772 result.WaitWithDefaultTimeout() 773 774 Expect(result).Should(Exit(0)) 775 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 776 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 777 778 // Restore the container 779 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 780 result.WaitWithDefaultTimeout() 781 782 Expect(result).Should(Exit(0)) 783 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 784 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 785 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 786 787 // Exec in the container 788 result = podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "echo " + cid + " > /test.output"}) 789 result.WaitWithDefaultTimeout() 790 Expect(result).Should(Exit(0)) 791 792 result = podmanTest.Podman([]string{"exec", cid, "cat", "/test.output"}) 793 result.WaitWithDefaultTimeout() 794 Expect(result).Should(Exit(0)) 795 Expect(result.OutputToString()).To(ContainSubstring(cid)) 796 797 // Remove exported checkpoint 798 os.Remove(fileName) 799 }) 800 801 It("podman checkpoint a container started with --rm", func() { 802 // Start the container 803 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 804 session := podmanTest.Podman(localRunString) 805 session.WaitWithDefaultTimeout() 806 cid := session.OutputToString() 807 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 808 809 // Checkpoint the container - this should fail as it was started with --rm 810 result := podmanTest.Podman([]string{"container", "checkpoint", cid}) 811 result.WaitWithDefaultTimeout() 812 Expect(result).To(ExitWithError()) 813 Expect(result.ErrorToString()).To(ContainSubstring("cannot checkpoint containers that have been started with '--rm'")) 814 815 // Checkpointing with --export should still work 816 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 817 818 result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) 819 result.WaitWithDefaultTimeout() 820 821 // As the container has been started with '--rm' it will be completely 822 // cleaned up after checkpointing. 823 Expect(result).Should(Exit(0)) 824 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 825 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 826 827 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 828 result.WaitWithDefaultTimeout() 829 830 Expect(result).Should(Exit(0)) 831 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 832 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 833 834 result = podmanTest.Podman([]string{"rm", "-t", "0", "-fa"}) 835 result.WaitWithDefaultTimeout() 836 Expect(result).Should(Exit(0)) 837 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 838 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 839 840 // Remove exported checkpoint 841 os.Remove(fileName) 842 }) 843 844 It("podman checkpoint a container with volumes", func() { 845 session := podmanTest.Podman([]string{ 846 "build", "-f", "build/basicalpine/Containerfile.volume", "-t", "test-cr-volume", 847 }) 848 session.WaitWithDefaultTimeout() 849 Expect(session).Should(Exit(0)) 850 851 // Start the container 852 localRunString := getRunString([]string{ 853 "--rm", 854 "-v", "/volume1", 855 "-v", "my-test-vol:/volume2", 856 "test-cr-volume", 857 "top", 858 }) 859 session = podmanTest.Podman(localRunString) 860 session.WaitWithDefaultTimeout() 861 Expect(session).Should(Exit(0)) 862 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 863 864 cid := session.OutputToString() 865 866 // Add file in volume0 867 result := podmanTest.Podman([]string{ 868 "exec", cid, "/bin/sh", "-c", "echo " + cid + " > /volume0/test.output", 869 }) 870 result.WaitWithDefaultTimeout() 871 Expect(result).Should(Exit(0)) 872 873 // Add file in volume1 874 result = podmanTest.Podman([]string{ 875 "exec", cid, "/bin/sh", "-c", "echo " + cid + " > /volume1/test.output", 876 }) 877 result.WaitWithDefaultTimeout() 878 Expect(result).Should(Exit(0)) 879 880 // Add file in volume2 881 result = podmanTest.Podman([]string{ 882 "exec", cid, "/bin/sh", "-c", "echo " + cid + " > /volume2/test.output", 883 }) 884 result.WaitWithDefaultTimeout() 885 Expect(result).Should(Exit(0)) 886 887 checkpointFileName := "/tmp/checkpoint-" + cid + ".tar.gz" 888 889 // Checkpoint the container 890 result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", checkpointFileName}) 891 result.WaitWithDefaultTimeout() 892 Expect(result).Should(Exit(0)) 893 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 894 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 895 896 // Restore container should fail because named volume still exists 897 result = podmanTest.Podman([]string{"container", "restore", "-i", checkpointFileName}) 898 result.WaitWithDefaultTimeout() 899 Expect(result).To(ExitWithError()) 900 Expect(result.ErrorToString()).To(ContainSubstring( 901 "volume with name my-test-vol already exists. Use --ignore-volumes to not restore content of volumes", 902 )) 903 904 // Remove named volume 905 session = podmanTest.Podman([]string{"volume", "rm", "my-test-vol"}) 906 session.WaitWithDefaultTimeout() 907 Expect(session).Should(Exit(0)) 908 909 // Restoring container 910 result = podmanTest.Podman([]string{"container", "restore", "-i", checkpointFileName}) 911 result.WaitWithDefaultTimeout() 912 Expect(result).Should(Exit(0)) 913 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 914 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 915 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 916 917 // Validate volume0 content 918 result = podmanTest.Podman([]string{"exec", cid, "cat", "/volume0/test.output"}) 919 result.WaitWithDefaultTimeout() 920 Expect(result).Should(Exit(0)) 921 Expect(result.OutputToString()).To(ContainSubstring(cid)) 922 923 // Validate volume1 content 924 result = podmanTest.Podman([]string{"exec", cid, "cat", "/volume1/test.output"}) 925 result.WaitWithDefaultTimeout() 926 Expect(result).Should(Exit(0)) 927 Expect(result.OutputToString()).To(ContainSubstring(cid)) 928 929 // Validate volume2 content 930 result = podmanTest.Podman([]string{"exec", cid, "cat", "/volume2/test.output"}) 931 result.WaitWithDefaultTimeout() 932 Expect(result).Should(Exit(0)) 933 Expect(result.OutputToString()).To(ContainSubstring(cid)) 934 935 // Remove exported checkpoint 936 os.Remove(checkpointFileName) 937 }) 938 939 It("podman checkpoint container with --pre-checkpoint", func() { 940 if !criu.MemTrack() { 941 Skip("system (architecture/kernel/CRIU) does not support memory tracking") 942 } 943 if !strings.Contains(podmanTest.OCIRuntime, "runc") { 944 Skip("Test only works on runc 1.0-rc3 or higher.") 945 } 946 localRunString := getRunString([]string{ALPINE, "top"}) 947 session := podmanTest.Podman(localRunString) 948 session.WaitWithDefaultTimeout() 949 Expect(session).Should(Exit(0)) 950 cid := session.OutputToString() 951 952 result := podmanTest.Podman([]string{"container", "checkpoint", "-P", cid}) 953 result.WaitWithDefaultTimeout() 954 955 Expect(result).Should(Exit(0)) 956 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 957 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 958 959 result = podmanTest.Podman([]string{"container", "checkpoint", "--with-previous", cid}) 960 result.WaitWithDefaultTimeout() 961 962 Expect(result).Should(Exit(0)) 963 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 964 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 965 966 result = podmanTest.Podman([]string{"container", "restore", cid}) 967 result.WaitWithDefaultTimeout() 968 969 Expect(result).Should(Exit(0)) 970 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 971 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 972 }) 973 974 It("podman checkpoint container with --pre-checkpoint and export (migration)", func() { 975 SkipIfRemote("--import-previous is not yet supported on the remote client") 976 if !criu.MemTrack() { 977 Skip("system (architecture/kernel/CRIU) does not support memory tracking") 978 } 979 if !strings.Contains(podmanTest.OCIRuntime, "runc") { 980 Skip("Test only works on runc 1.0-rc3 or higher.") 981 } 982 localRunString := getRunString([]string{ALPINE, "top"}) 983 session := podmanTest.Podman(localRunString) 984 session.WaitWithDefaultTimeout() 985 Expect(session).Should(Exit(0)) 986 cid := session.OutputToString() 987 preCheckpointFileName := "/tmp/pre-checkpoint-" + cid + ".tar.gz" 988 checkpointFileName := "/tmp/checkpoint-" + cid + ".tar.gz" 989 990 result := podmanTest.Podman([]string{"container", "checkpoint", "-P", "-e", preCheckpointFileName, cid}) 991 result.WaitWithDefaultTimeout() 992 993 Expect(result).Should(Exit(0)) 994 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 995 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 996 997 result = podmanTest.Podman([]string{"container", "checkpoint", "--with-previous", "-e", checkpointFileName, cid}) 998 result.WaitWithDefaultTimeout() 999 1000 Expect(result).Should(Exit(0)) 1001 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1002 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 1003 1004 result = podmanTest.Podman([]string{"rm", "-t", "0", "-f", cid}) 1005 result.WaitWithDefaultTimeout() 1006 Expect(result).Should(Exit(0)) 1007 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1008 1009 result = podmanTest.Podman([]string{"container", "restore", "-i", checkpointFileName, "--import-previous", preCheckpointFileName}) 1010 result.WaitWithDefaultTimeout() 1011 1012 Expect(result).Should(Exit(0)) 1013 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1014 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 1015 1016 os.Remove(checkpointFileName) 1017 os.Remove(preCheckpointFileName) 1018 }) 1019 1020 It("podman checkpoint and restore container with different port mappings", func() { 1021 randomPort, err := utils.GetRandomPort() 1022 Expect(err).ShouldNot(HaveOccurred()) 1023 localRunString := getRunString([]string{"-p", fmt.Sprintf("%d:6379", randomPort), "--rm", redis}) 1024 session := podmanTest.Podman(localRunString) 1025 session.WaitWithDefaultTimeout() 1026 Expect(session).Should(Exit(0)) 1027 cid := session.OutputToString() 1028 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 1029 1030 if !WaitContainerReady(podmanTest, cid, "Ready to accept connections", 20, 1) { 1031 Fail("Container failed to get ready") 1032 } 1033 1034 fmt.Fprintf(os.Stderr, "Trying to connect to redis server at localhost:%d", randomPort) 1035 // Open a network connection to the redis server via initial port mapping 1036 conn, err := net.DialTimeout("tcp4", fmt.Sprintf("localhost:%d", randomPort), time.Duration(3)*time.Second) 1037 Expect(err).ShouldNot(HaveOccurred()) 1038 conn.Close() 1039 1040 // Checkpoint the container 1041 result := podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) 1042 result.WaitWithDefaultTimeout() 1043 1044 // As the container has been started with '--rm' it will be completely 1045 // cleaned up after checkpointing. 1046 Expect(result).Should(Exit(0)) 1047 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1048 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 1049 1050 // Restore container with different port mapping 1051 newRandomPort, err := utils.GetRandomPort() 1052 Expect(err).ShouldNot(HaveOccurred()) 1053 result = podmanTest.Podman([]string{"container", "restore", "-p", fmt.Sprintf("%d:6379", newRandomPort), "-i", fileName}) 1054 result.WaitWithDefaultTimeout() 1055 1056 Expect(result).Should(Exit(0)) 1057 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1058 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 1059 1060 // Open a network connection to the redis server via initial port mapping 1061 // This should fail 1062 _, err = net.DialTimeout("tcp4", fmt.Sprintf("localhost:%d", randomPort), time.Duration(3)*time.Second) 1063 Expect(err).ToNot(BeNil()) 1064 Expect(err.Error()).To(ContainSubstring("connection refused")) 1065 // Open a network connection to the redis server via new port mapping 1066 fmt.Fprintf(os.Stderr, "Trying to reconnect to redis server at localhost:%d", newRandomPort) 1067 conn, err = net.DialTimeout("tcp4", fmt.Sprintf("localhost:%d", newRandomPort), time.Duration(3)*time.Second) 1068 Expect(err).ShouldNot(HaveOccurred()) 1069 conn.Close() 1070 1071 result = podmanTest.Podman([]string{"rm", "-t", "0", "-fa"}) 1072 result.WaitWithDefaultTimeout() 1073 Expect(result).Should(Exit(0)) 1074 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1075 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 1076 1077 // Remove exported checkpoint 1078 os.Remove(fileName) 1079 }) 1080 1081 namespaceCombination := []string{ 1082 "ipc,net,uts,pid", 1083 "ipc,net,uts", 1084 "ipc,net", 1085 "net,uts,pid", 1086 "net,uts", 1087 "uts,pid", 1088 } 1089 for _, share := range namespaceCombination { 1090 testName := fmt.Sprintf( 1091 "podman checkpoint and restore container out of and into pod (%s)", 1092 share, 1093 ) 1094 1095 share := share // copy into local scope, for use inside function 1096 1097 It(testName, func() { 1098 if !criu.CheckForCriu(criu.PodCriuVersion) { 1099 Skip("CRIU is missing or too old.") 1100 } 1101 if !crutils.CRRuntimeSupportsPodCheckpointRestore(podmanTest.OCIRuntime) { 1102 Skip("runtime does not support pod restore: " + podmanTest.OCIRuntime) 1103 } 1104 // Create a pod 1105 session := podmanTest.Podman([]string{ 1106 "pod", 1107 "create", 1108 "--share", 1109 share, 1110 }) 1111 session.WaitWithDefaultTimeout() 1112 Expect(session).To(Exit(0)) 1113 podID := session.OutputToString() 1114 1115 session = podmanTest.Podman([]string{ 1116 "run", 1117 "-d", 1118 "--rm", 1119 "--pod", 1120 podID, 1121 ALPINE, 1122 "top", 1123 }) 1124 session.WaitWithDefaultTimeout() 1125 Expect(session).To(Exit(0)) 1126 cid := session.OutputToString() 1127 1128 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 1129 1130 // Checkpoint the container 1131 result := podmanTest.Podman([]string{ 1132 "container", 1133 "checkpoint", 1134 "-e", 1135 fileName, 1136 cid, 1137 }) 1138 result.WaitWithDefaultTimeout() 1139 1140 // As the container has been started with '--rm' it will be completely 1141 // cleaned up after checkpointing. 1142 Expect(result).To(Exit(0)) 1143 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1144 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 1145 1146 // Remove the pod and create a new pod 1147 result = podmanTest.Podman([]string{ 1148 "pod", 1149 "rm", 1150 podID, 1151 }) 1152 result.WaitWithDefaultTimeout() 1153 Expect(result).To(Exit(0)) 1154 1155 // First create a pod with different shared namespaces. 1156 // Restore should fail 1157 1158 wrongShare := share[:strings.LastIndex(share, ",")] 1159 1160 session = podmanTest.Podman([]string{ 1161 "pod", 1162 "create", 1163 "--share", 1164 wrongShare, 1165 }) 1166 session.WaitWithDefaultTimeout() 1167 Expect(session).To(Exit(0)) 1168 podID = session.OutputToString() 1169 1170 // Restore container with different port mapping 1171 result = podmanTest.Podman([]string{ 1172 "container", 1173 "restore", 1174 "--pod", 1175 podID, 1176 "-i", 1177 fileName, 1178 }) 1179 result.WaitWithDefaultTimeout() 1180 Expect(result).To(Exit(125)) 1181 Expect(result.ErrorToString()).To(ContainSubstring("does not share the")) 1182 1183 // Remove the pod and create a new pod 1184 result = podmanTest.Podman([]string{ 1185 "pod", 1186 "rm", 1187 podID, 1188 }) 1189 result.WaitWithDefaultTimeout() 1190 Expect(result).To(Exit(0)) 1191 1192 session = podmanTest.Podman([]string{ 1193 "pod", 1194 "create", 1195 "--share", 1196 share, 1197 }) 1198 session.WaitWithDefaultTimeout() 1199 Expect(session).To(Exit(0)) 1200 podID = session.OutputToString() 1201 1202 // Restore container with different port mapping 1203 result = podmanTest.Podman([]string{ 1204 "container", 1205 "restore", 1206 "--pod", 1207 podID, 1208 "-i", 1209 fileName, 1210 }) 1211 result.WaitWithDefaultTimeout() 1212 1213 Expect(result).To(Exit(0)) 1214 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) 1215 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 1216 1217 result = podmanTest.Podman([]string{ 1218 "rm", 1219 "-f", 1220 result.OutputToString(), 1221 }) 1222 result.WaitWithDefaultTimeout() 1223 Expect(result).To(Exit(0)) 1224 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1225 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 1226 1227 result = podmanTest.Podman([]string{ 1228 "pod", 1229 "rm", 1230 "-fa", 1231 }) 1232 result.WaitWithDefaultTimeout() 1233 Expect(result).To(Exit(0)) 1234 1235 // Remove exported checkpoint 1236 os.Remove(fileName) 1237 }) 1238 } 1239 1240 It("podman checkpoint container with export (migration) and --ipc host", func() { 1241 localRunString := getRunString([]string{"--rm", "--ipc", "host", ALPINE, "top"}) 1242 session := podmanTest.Podman(localRunString) 1243 session.WaitWithDefaultTimeout() 1244 Expect(session).Should(Exit(0)) 1245 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1246 cid := session.OutputToString() 1247 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 1248 1249 result := podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", fileName}) 1250 result.WaitWithDefaultTimeout() 1251 1252 // As the container has been started with '--rm' it will be completely 1253 // cleaned up after checkpointing. 1254 Expect(result).Should(Exit(0)) 1255 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1256 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 1257 1258 result = podmanTest.Podman([]string{"container", "restore", "-i", fileName}) 1259 result.WaitWithDefaultTimeout() 1260 1261 Expect(result).Should(Exit(0)) 1262 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1263 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 1264 1265 result = podmanTest.Podman([]string{"rm", "-t", "0", "-fa"}) 1266 result.WaitWithDefaultTimeout() 1267 Expect(result).Should(Exit(0)) 1268 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1269 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 1270 1271 // Remove exported checkpoint 1272 os.Remove(fileName) 1273 }) 1274 1275 It("podman checkpoint container with export and statistics", func() { 1276 localRunString := getRunString([]string{ 1277 "--rm", 1278 ALPINE, 1279 "top", 1280 }) 1281 session := podmanTest.Podman(localRunString) 1282 session.WaitWithDefaultTimeout() 1283 Expect(session).Should(Exit(0)) 1284 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1285 cid := session.OutputToString() 1286 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 1287 1288 result := podmanTest.Podman([]string{ 1289 "container", 1290 "checkpoint", 1291 cid, "-e", 1292 fileName, 1293 }) 1294 result.WaitWithDefaultTimeout() 1295 1296 // As the container has been started with '--rm' it will be completely 1297 // cleaned up after checkpointing. 1298 Expect(result).Should(Exit(0)) 1299 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1300 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 1301 1302 // Extract checkpoint archive 1303 destinationDirectory, err := CreateTempDirInTempDir() 1304 Expect(err).ShouldNot(HaveOccurred()) 1305 1306 tarsession := SystemExec( 1307 "tar", 1308 []string{ 1309 "xf", 1310 fileName, 1311 "-C", 1312 destinationDirectory, 1313 }, 1314 ) 1315 Expect(tarsession).Should(Exit(0)) 1316 1317 _, err = os.Stat(filepath.Join(destinationDirectory, stats.StatsDump)) 1318 Expect(err).ShouldNot(HaveOccurred()) 1319 1320 Expect(os.RemoveAll(destinationDirectory)).To(BeNil()) 1321 1322 // Remove exported checkpoint 1323 os.Remove(fileName) 1324 }) 1325 1326 It("podman checkpoint and restore containers with --print-stats", func() { 1327 session1 := podmanTest.Podman(getRunString([]string{redis})) 1328 session1.WaitWithDefaultTimeout() 1329 Expect(session1).Should(Exit(0)) 1330 1331 session2 := podmanTest.Podman(getRunString([]string{redis, "top"})) 1332 session2.WaitWithDefaultTimeout() 1333 Expect(session2).Should(Exit(0)) 1334 1335 result := podmanTest.Podman([]string{ 1336 "container", 1337 "checkpoint", 1338 "-a", 1339 "--print-stats", 1340 }) 1341 result.WaitWithDefaultTimeout() 1342 1343 Expect(result).Should(Exit(0)) 1344 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1345 1346 type checkpointStatistics struct { 1347 PodmanDuration int64 `json:"podman_checkpoint_duration"` 1348 ContainerStatistics []*entities.CheckpointReport `json:"container_statistics"` 1349 } 1350 1351 cS := new(checkpointStatistics) 1352 err := json.Unmarshal([]byte(result.OutputToString()), cS) 1353 Expect(err).ShouldNot(HaveOccurred()) 1354 1355 Expect(cS.ContainerStatistics).To(HaveLen(2)) 1356 Expect(cS.PodmanDuration).To(BeNumerically(">", cS.ContainerStatistics[0].RuntimeDuration)) 1357 Expect(cS.PodmanDuration).To(BeNumerically(">", cS.ContainerStatistics[1].RuntimeDuration)) 1358 Expect(cS.ContainerStatistics[0].RuntimeDuration).To( 1359 BeNumerically(">", cS.ContainerStatistics[0].CRIUStatistics.FrozenTime), 1360 ) 1361 Expect(cS.ContainerStatistics[1].RuntimeDuration).To( 1362 BeNumerically(">", cS.ContainerStatistics[1].CRIUStatistics.FrozenTime), 1363 ) 1364 1365 ps := podmanTest.Podman([]string{ 1366 "ps", 1367 "-q", 1368 "--no-trunc", 1369 }) 1370 ps.WaitWithDefaultTimeout() 1371 Expect(ps).Should(Exit(0)) 1372 Expect(ps.OutputToString()).To(Not(ContainSubstring(session1.OutputToString()))) 1373 Expect(ps.OutputToString()).To(Not(ContainSubstring(session2.OutputToString()))) 1374 1375 result = podmanTest.Podman([]string{ 1376 "container", 1377 "restore", 1378 "-a", 1379 "--print-stats", 1380 }) 1381 result.WaitWithDefaultTimeout() 1382 1383 Expect(result).Should(Exit(0)) 1384 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) 1385 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 1386 Expect(podmanTest.GetContainerStatus()).To(Not(ContainSubstring("Exited"))) 1387 1388 type restoreStatistics struct { 1389 PodmanDuration int64 `json:"podman_restore_duration"` 1390 ContainerStatistics []*entities.RestoreReport `json:"container_statistics"` 1391 } 1392 1393 rS := new(restoreStatistics) 1394 err = json.Unmarshal([]byte(result.OutputToString()), rS) 1395 Expect(err).ShouldNot(HaveOccurred()) 1396 1397 Expect(cS.ContainerStatistics).To(HaveLen(2)) 1398 Expect(cS.PodmanDuration).To(BeNumerically(">", cS.ContainerStatistics[0].RuntimeDuration)) 1399 Expect(cS.PodmanDuration).To(BeNumerically(">", cS.ContainerStatistics[1].RuntimeDuration)) 1400 Expect(cS.ContainerStatistics[0].RuntimeDuration).To( 1401 BeNumerically(">", cS.ContainerStatistics[0].CRIUStatistics.RestoreTime), 1402 ) 1403 Expect(cS.ContainerStatistics[1].RuntimeDuration).To( 1404 BeNumerically(">", cS.ContainerStatistics[1].CRIUStatistics.RestoreTime), 1405 ) 1406 1407 result = podmanTest.Podman([]string{ 1408 "rm", 1409 "-t", 1410 "0", 1411 "-fa", 1412 }) 1413 result.WaitWithDefaultTimeout() 1414 Expect(result).Should(Exit(0)) 1415 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1416 }) 1417 1418 It("podman checkpoint and restore container with --file-locks", func() { 1419 if !strings.Contains(podmanTest.OCIRuntime, "runc") { 1420 // TODO: Enable test for crun when this feature has been released 1421 // https://github.com/containers/crun/pull/783 1422 Skip("FIXME: requires crun >= 1.4") 1423 } 1424 localRunString := getRunString([]string{"--name", "test_name", ALPINE, "flock", "test.lock", "sleep", "100"}) 1425 session := podmanTest.Podman(localRunString) 1426 session.WaitWithDefaultTimeout() 1427 Expect(session).Should(Exit(0)) 1428 1429 // Checkpoint is expected to fail without --file-locks 1430 result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"}) 1431 result.WaitWithDefaultTimeout() 1432 Expect(result).Should(Exit(125)) 1433 Expect(result.ErrorToString()).To(ContainSubstring("failed: exit status 1")) 1434 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1435 1436 // Checkpoint is expected to succeed with --file-locks 1437 result = podmanTest.Podman([]string{"container", "checkpoint", "--file-locks", "test_name"}) 1438 result.WaitWithDefaultTimeout() 1439 Expect(result).Should(Exit(0)) 1440 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1441 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 1442 1443 result = podmanTest.Podman([]string{"container", "restore", "--file-locks", "test_name"}) 1444 result.WaitWithDefaultTimeout() 1445 1446 Expect(result).Should(Exit(0)) 1447 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1448 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 1449 1450 result = podmanTest.Podman([]string{"rm", "-t", "0", "-f", "test_name"}) 1451 result.WaitWithDefaultTimeout() 1452 Expect(result).Should(Exit(0)) 1453 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1454 }) 1455 1456 It("podman checkpoint container with export and verify runtime", func() { 1457 SkipIfRemote("podman-remote does not support --runtime flag") 1458 localRunString := getRunString([]string{ 1459 "--rm", 1460 ALPINE, 1461 "top", 1462 }) 1463 session := podmanTest.Podman(localRunString) 1464 session.WaitWithDefaultTimeout() 1465 Expect(session).Should(Exit(0)) 1466 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1467 cid := session.OutputToString() 1468 1469 session = podmanTest.Podman([]string{ 1470 "inspect", 1471 "--format", 1472 "{{.OCIRuntime}}", 1473 cid, 1474 }) 1475 session.WaitWithDefaultTimeout() 1476 Expect(session).Should(Exit(0)) 1477 runtime := session.OutputToString() 1478 1479 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 1480 1481 result := podmanTest.Podman([]string{ 1482 "container", 1483 "checkpoint", 1484 cid, "-e", 1485 fileName, 1486 }) 1487 result.WaitWithDefaultTimeout() 1488 1489 // As the container has been started with '--rm' it will be completely 1490 // cleaned up after checkpointing. 1491 Expect(result).Should(Exit(0)) 1492 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1493 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 1494 1495 result = podmanTest.Podman([]string{ 1496 "container", 1497 "restore", 1498 "-i", 1499 fileName, 1500 }) 1501 result.WaitWithDefaultTimeout() 1502 Expect(result).Should(Exit(0)) 1503 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1504 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 1505 1506 // The restored container should have the same runtime as the original container 1507 result = podmanTest.Podman([]string{ 1508 "inspect", 1509 "--format", 1510 "{{.OCIRuntime}}", 1511 cid, 1512 }) 1513 result.WaitWithDefaultTimeout() 1514 Expect(result).Should(Exit(0)) 1515 Expect(session.OutputToString()).To(Equal(runtime)) 1516 1517 // Remove exported checkpoint 1518 os.Remove(fileName) 1519 }) 1520 1521 It("podman checkpoint container with export and try to change the runtime", func() { 1522 SkipIfRemote("podman-remote does not support --runtime flag") 1523 // This test will only run if runc and crun both exist 1524 if !strings.Contains(podmanTest.OCIRuntime, "crun") { 1525 Skip("Test requires crun and runc") 1526 } 1527 cmd := exec.Command("runc") 1528 if err := cmd.Start(); err != nil { 1529 Skip("Test requires crun and runc") 1530 } 1531 if err := cmd.Wait(); err != nil { 1532 Skip("Test requires crun and runc") 1533 } 1534 localRunString := getRunString([]string{ 1535 "--rm", 1536 ALPINE, 1537 "top", 1538 }) 1539 // Let's start a container with runc and try to restore it with crun (expected to fail) 1540 localRunString = append( 1541 []string{ 1542 "--runtime", 1543 "runc", 1544 }, 1545 localRunString..., 1546 ) 1547 session := podmanTest.Podman(localRunString) 1548 session.WaitWithDefaultTimeout() 1549 Expect(session).Should(Exit(0)) 1550 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1551 cid := session.OutputToString() 1552 1553 session = podmanTest.Podman([]string{ 1554 "inspect", 1555 "--format", 1556 "{{.OCIRuntime}}", 1557 cid, 1558 }) 1559 session.WaitWithDefaultTimeout() 1560 Expect(session).Should(Exit(0)) 1561 runtime := session.OutputToString() 1562 1563 fileName := "/tmp/checkpoint-" + cid + ".tar.gz" 1564 1565 result := podmanTest.Podman([]string{ 1566 "container", 1567 "checkpoint", 1568 cid, "-e", 1569 fileName, 1570 }) 1571 result.WaitWithDefaultTimeout() 1572 1573 // As the container has been started with '--rm' it will be completely 1574 // cleaned up after checkpointing. 1575 Expect(result).Should(Exit(0)) 1576 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1577 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 1578 1579 // This should fail as the container was checkpointed with runc 1580 result = podmanTest.Podman([]string{ 1581 "--runtime", 1582 "crun", 1583 "container", 1584 "restore", 1585 "-i", 1586 fileName, 1587 }) 1588 result.WaitWithDefaultTimeout() 1589 1590 Expect(result).Should(Exit(125)) 1591 Expect(result.ErrorToString()).To( 1592 ContainSubstring("and cannot be restored with runtime"), 1593 ) 1594 1595 result = podmanTest.Podman([]string{ 1596 "--runtime", 1597 "runc", 1598 "container", 1599 "restore", 1600 "-i", 1601 fileName, 1602 }) 1603 result.WaitWithDefaultTimeout() 1604 Expect(result).Should(Exit(0)) 1605 1606 result = podmanTest.Podman([]string{ 1607 "inspect", 1608 "--format", 1609 "{{.OCIRuntime}}", 1610 cid, 1611 }) 1612 result.WaitWithDefaultTimeout() 1613 Expect(result).Should(Exit(0)) 1614 Expect(result.OutputToString()).To(Equal(runtime)) 1615 1616 result = podmanTest.Podman([]string{ 1617 "--runtime", 1618 "runc", 1619 "rm", 1620 "-fa", 1621 }) 1622 result.WaitWithDefaultTimeout() 1623 Expect(result).Should(Exit(0)) 1624 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1625 // Remove exported checkpoint 1626 os.Remove(fileName) 1627 }) 1628 1629 It("podman checkpoint and restore dev/shm content with --export and --import", func() { 1630 localRunString := getRunString([]string{"--rm", ALPINE, "top"}) 1631 session := podmanTest.Podman(localRunString) 1632 session.WaitWithDefaultTimeout() 1633 Expect(session).Should(Exit(0)) 1634 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1635 cid := session.OutputToString() 1636 1637 // Add test file in dev/shm 1638 result := podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "echo test" + cid + "test > /dev/shm/test.output"}) 1639 result.WaitWithDefaultTimeout() 1640 Expect(result).Should(Exit(0)) 1641 1642 session = podmanTest.Podman([]string{"inspect", "--format", "{{.OCIRuntime}}", cid}) 1643 session.WaitWithDefaultTimeout() 1644 Expect(session).Should(Exit(0)) 1645 runtime := session.OutputToString() 1646 1647 checkpointFileName := "/tmp/checkpoint-" + cid + ".tar.gz" 1648 result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", checkpointFileName}) 1649 result.WaitWithDefaultTimeout() 1650 1651 // As the container has been started with '--rm' it will be completely 1652 // cleaned up after checkpointing. 1653 Expect(result).Should(Exit(0)) 1654 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1655 Expect(podmanTest.NumberOfContainers()).To(Equal(0)) 1656 1657 result = podmanTest.Podman([]string{"container", "restore", "-i", checkpointFileName}) 1658 result.WaitWithDefaultTimeout() 1659 Expect(result).Should(Exit(0)) 1660 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1661 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 1662 1663 // The restored container should have the same runtime as the original container 1664 result = podmanTest.Podman([]string{"inspect", "--format", "{{.OCIRuntime}}", cid}) 1665 result.WaitWithDefaultTimeout() 1666 Expect(result).Should(Exit(0)) 1667 Expect(session.OutputToString()).To(Equal(runtime)) 1668 1669 // Verify the test file content in dev/shm 1670 result = podmanTest.Podman([]string{"exec", cid, "cat", "/dev/shm/test.output"}) 1671 result.WaitWithDefaultTimeout() 1672 Expect(result).Should(Exit(0)) 1673 Expect(result.OutputToString()).To(ContainSubstring("test" + cid + "test")) 1674 1675 // Remove exported checkpoint 1676 os.Remove(checkpointFileName) 1677 }) 1678 1679 It("podman checkpoint and restore dev/shm content", func() { 1680 localRunString := getRunString([]string{ALPINE, "top"}) 1681 session := podmanTest.Podman(localRunString) 1682 session.WaitWithDefaultTimeout() 1683 Expect(session).Should(Exit(0)) 1684 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1685 cid := session.OutputToString() 1686 1687 // Add test file in dev/shm 1688 result := podmanTest.Podman([]string{"exec", cid, "/bin/sh", "-c", "echo test" + cid + "test > /dev/shm/test.output"}) 1689 result.WaitWithDefaultTimeout() 1690 Expect(result).Should(Exit(0)) 1691 1692 result = podmanTest.Podman([]string{"container", "checkpoint", cid}) 1693 result.WaitWithDefaultTimeout() 1694 Expect(result).Should(Exit(0)) 1695 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1696 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) 1697 1698 result = podmanTest.Podman([]string{"container", "restore", cid}) 1699 result.WaitWithDefaultTimeout() 1700 Expect(result).Should(Exit(0)) 1701 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) 1702 Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) 1703 1704 // Verify the test file content in dev/shm 1705 result = podmanTest.Podman([]string{"exec", cid, "cat", "/dev/shm/test.output"}) 1706 result.WaitWithDefaultTimeout() 1707 Expect(result).Should(Exit(0)) 1708 Expect(result.OutputToString()).To(ContainSubstring("test" + cid + "test")) 1709 1710 result = podmanTest.Podman([]string{"rm", "-t", "0", "-fa"}) 1711 result.WaitWithDefaultTimeout() 1712 Expect(result).Should(Exit(0)) 1713 Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) 1714 }) 1715 })