summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/checkpoint.go11
-rw-r--r--docs/podman-container-checkpoint.1.md12
-rw-r--r--docs/podman-container-restore.1.md8
-rw-r--r--libpod/container_api.go11
-rw-r--r--libpod/container_internal_linux.go16
-rw-r--r--libpod/oci.go15
6 files changed, 59 insertions, 14 deletions
diff --git a/cmd/podman/checkpoint.go b/cmd/podman/checkpoint.go
index bf280920d..ddfd12bc3 100644
--- a/cmd/podman/checkpoint.go
+++ b/cmd/podman/checkpoint.go
@@ -24,6 +24,10 @@ var (
Usage: "keep all temporary checkpoint files",
},
cli.BoolFlag{
+ Name: "leave-running, R",
+ Usage: "leave the container running after writing checkpoint to disk",
+ },
+ cli.BoolFlag{
Name: "all, a",
Usage: "checkpoint all running containers",
},
@@ -50,7 +54,10 @@ func checkpointCmd(c *cli.Context) error {
}
defer runtime.Shutdown(false)
- keep := c.Bool("keep")
+ options := libpod.ContainerCheckpointOptions{
+ Keep: c.Bool("keep"),
+ KeepRunning: c.Bool("leave-running"),
+ }
if err := checkAllAndLatest(c); err != nil {
return err
@@ -59,7 +66,7 @@ func checkpointCmd(c *cli.Context) error {
containers, lastError := getAllOrLatestContainers(c, runtime, libpod.ContainerStateRunning, "running")
for _, ctr := range containers {
- if err = ctr.Checkpoint(context.TODO(), keep); err != nil {
+ if err = ctr.Checkpoint(context.TODO(), options); err != nil {
if lastError != nil {
fmt.Fprintln(os.Stderr, lastError)
}
diff --git a/docs/podman-container-checkpoint.1.md b/docs/podman-container-checkpoint.1.md
index 4906e0e12..6f454dfd1 100644
--- a/docs/podman-container-checkpoint.1.md
+++ b/docs/podman-container-checkpoint.1.md
@@ -17,6 +17,18 @@ are not deleted if checkpointing fails for further debugging. If checkpointing s
files are theoretically not needed, but if these files are needed Podman can keep the files
for further analysis.
+**--all, -a**
+
+Checkpoint all running containers.
+
+**--latest, -l**
+
+Instead of providing the container name or ID, checkpoint the last created container.
+
+**--leave-running, -R**
+
+Leave the container running after checkpointing instead of stopping it.
+
## EXAMPLE
podman container checkpoint mywebserver
diff --git a/docs/podman-container-restore.1.md b/docs/podman-container-restore.1.md
index 6360bccb0..4dd5ea7c7 100644
--- a/docs/podman-container-restore.1.md
+++ b/docs/podman-container-restore.1.md
@@ -24,6 +24,14 @@ processes in the checkpointed container.
Without the **-k**, **--keep** option the checkpoint will be consumed and cannot be used
again.
+**--all, -a**
+
+Restore all checkpointed containers.
+
+**--latest, -l**
+
+Instead of providing the container name or ID, restore the last created container.
+
## EXAMPLE
podman container restore mywebserver
diff --git a/libpod/container_api.go b/libpod/container_api.go
index 390987394..df6b6e962 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -830,8 +830,15 @@ func (c *Container) Refresh(ctx context.Context) error {
return nil
}
+// ContainerCheckpointOptions is a struct used to pass the parameters
+// for checkpointing to corresponding functions
+type ContainerCheckpointOptions struct {
+ Keep bool
+ KeepRunning bool
+}
+
// Checkpoint checkpoints a container
-func (c *Container) Checkpoint(ctx context.Context, keep bool) error {
+func (c *Container) Checkpoint(ctx context.Context, options ContainerCheckpointOptions) error {
logrus.Debugf("Trying to checkpoint container %s", c)
if !c.batched {
c.lock.Lock()
@@ -842,7 +849,7 @@ func (c *Container) Checkpoint(ctx context.Context, keep bool) error {
}
}
- return c.checkpoint(ctx, keep)
+ return c.checkpoint(ctx, options)
}
// Restore restores a container
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 66c7e8a04..e6071945d 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -431,7 +431,7 @@ func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr
return nil
}
-func (c *Container) checkpoint(ctx context.Context, keep bool) (err error) {
+func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointOptions) (err error) {
if !criu.CheckForCriu() {
return errors.Errorf("checkpointing a container requires at least CRIU %d", criu.MinCriuVersion)
@@ -440,7 +440,7 @@ func (c *Container) checkpoint(ctx context.Context, keep bool) (err error) {
if c.state.State != ContainerStateRunning {
return errors.Wrapf(ErrCtrStateInvalid, "%q is not running, cannot checkpoint", c.state.State)
}
- if err := c.runtime.ociRuntime.checkpointContainer(c); err != nil {
+ if err := c.runtime.ociRuntime.checkpointContainer(c, options); err != nil {
return err
}
@@ -457,14 +457,16 @@ func (c *Container) checkpoint(ctx context.Context, keep bool) (err error) {
logrus.Debugf("Checkpointed container %s", c.ID())
- c.state.State = ContainerStateStopped
+ if !options.KeepRunning {
+ c.state.State = ContainerStateStopped
- // Cleanup Storage and Network
- if err := c.cleanup(ctx); err != nil {
- return err
+ // Cleanup Storage and Network
+ if err := c.cleanup(ctx); err != nil {
+ return err
+ }
}
- if !keep {
+ if !options.Keep {
// Remove log file
os.Remove(filepath.Join(c.bundlePath(), "dump.log"))
// Remove statistic file
diff --git a/libpod/oci.go b/libpod/oci.go
index 71da830b5..8ee2c948f 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -844,13 +844,22 @@ func (r *OCIRuntime) execStopContainer(ctr *Container, timeout uint) error {
}
// checkpointContainer checkpoints the given container
-func (r *OCIRuntime) checkpointContainer(ctr *Container) error {
+func (r *OCIRuntime) checkpointContainer(ctr *Container, options ContainerCheckpointOptions) error {
// imagePath is used by CRIU to store the actual checkpoint files
imagePath := ctr.CheckpointPath()
// workPath will be used to store dump.log and stats-dump
workPath := ctr.bundlePath()
logrus.Debugf("Writing checkpoint to %s", imagePath)
logrus.Debugf("Writing checkpoint logs to %s", workPath)
- return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, nil, r.path, "checkpoint",
- "--image-path", imagePath, "--work-path", workPath, ctr.ID())
+ args := []string{}
+ args = append(args, "checkpoint")
+ args = append(args, "--image-path")
+ args = append(args, imagePath)
+ args = append(args, "--work-path")
+ args = append(args, workPath)
+ if options.KeepRunning {
+ args = append(args, "--leave-running")
+ }
+ args = append(args, ctr.ID())
+ return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, nil, r.path, args...)
}