diff options
-rw-r--r-- | cmd/podman/checkpoint.go | 11 | ||||
-rw-r--r-- | docs/podman-container-checkpoint.1.md | 12 | ||||
-rw-r--r-- | docs/podman-container-restore.1.md | 8 | ||||
-rw-r--r-- | libpod/container_api.go | 11 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 16 | ||||
-rw-r--r-- | libpod/oci.go | 15 |
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...) } |