summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorBrent Baude <bbaude@redhat.com>2020-03-27 08:20:13 -0500
committerBrent Baude <bbaude@redhat.com>2020-04-03 09:32:06 -0500
commit8a16674722ab4a33ce66e57d151b09ac348e8e6d (patch)
tree03505f230a58e656e8b85c44b2505696e16c50c2 /cmd
parentccb9e579c48141f70d016adfa9a9d4934bbdf976 (diff)
downloadpodman-8a16674722ab4a33ce66e57d151b09ac348e8e6d.tar.gz
podman-8a16674722ab4a33ce66e57d151b09ac348e8e6d.tar.bz2
podman-8a16674722ab4a33ce66e57d151b09ac348e8e6d.zip
podmanv2 checkpoint and restore
add the ability to checkpoint and restore containers on v2podman Signed-off-by: Brent Baude <bbaude@redhat.com>
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podmanV2/containers/checkpoint.go79
-rw-r--r--cmd/podmanV2/containers/restore.go104
2 files changed, 183 insertions, 0 deletions
diff --git a/cmd/podmanV2/containers/checkpoint.go b/cmd/podmanV2/containers/checkpoint.go
new file mode 100644
index 000000000..7c3e551bc
--- /dev/null
+++ b/cmd/podmanV2/containers/checkpoint.go
@@ -0,0 +1,79 @@
+package containers
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/containers/libpod/cmd/podmanV2/parse"
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/cmd/podmanV2/utils"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/rootless"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+var (
+ checkpointDescription = `
+ podman container checkpoint
+
+ Checkpoints one or more running containers. The container name or ID can be used.
+`
+ checkpointCommand = &cobra.Command{
+ Use: "checkpoint [flags] CONTAINER [CONTAINER...]",
+ Short: "Checkpoints one or more containers",
+ Long: checkpointDescription,
+ RunE: checkpoint,
+ Args: func(cmd *cobra.Command, args []string) error {
+ return parse.CheckAllLatestAndCIDFile(cmd, args, false, false)
+ },
+ Example: `podman container checkpoint --keep ctrID
+ podman container checkpoint --all
+ podman container checkpoint --leave-running --latest`,
+ }
+)
+
+var (
+ checkpointOptions entities.CheckpointOptions
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: checkpointCommand,
+ Parent: containerCmd,
+ })
+ flags := checkpointCommand.Flags()
+ flags.BoolVarP(&checkpointOptions.Keep, "keep", "k", false, "Keep all temporary checkpoint files")
+ flags.BoolVarP(&checkpointOptions.LeaveRuninng, "leave-running", "R", false, "Leave the container running after writing checkpoint to disk")
+ flags.BoolVar(&checkpointOptions.TCPEstablished, "tcp-established", false, "Checkpoint a container with established TCP connections")
+ flags.BoolVarP(&checkpointOptions.All, "all", "a", false, "Checkpoint all running containers")
+ flags.BoolVarP(&checkpointOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ flags.StringVarP(&checkpointOptions.Export, "export", "e", "", "Export the checkpoint image to a tar.gz")
+ flags.BoolVar(&checkpointOptions.IgnoreRootFS, "ignore-rootfs", false, "Do not include root file-system changes when exporting")
+ if registry.IsRemote() {
+ _ = flags.MarkHidden("latest")
+ }
+}
+
+func checkpoint(cmd *cobra.Command, args []string) error {
+ var errs utils.OutputErrors
+ if rootless.IsRootless() {
+ return errors.New("checkpointing a container requires root")
+ }
+ if checkpointOptions.Export == "" && checkpointOptions.IgnoreRootFS {
+ return errors.Errorf("--ignore-rootfs can only be used with --export")
+ }
+ responses, err := registry.ContainerEngine().ContainerCheckpoint(context.Background(), args, checkpointOptions)
+ if err != nil {
+ return err
+ }
+ for _, r := range responses {
+ if r.Err == nil {
+ fmt.Println(r.Id)
+ } else {
+ errs = append(errs, r.Err)
+ }
+ }
+ return errs.PrintErrors()
+}
diff --git a/cmd/podmanV2/containers/restore.go b/cmd/podmanV2/containers/restore.go
new file mode 100644
index 000000000..6cab6ab50
--- /dev/null
+++ b/cmd/podmanV2/containers/restore.go
@@ -0,0 +1,104 @@
+package containers
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/containers/libpod/cmd/podmanV2/parse"
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/cmd/podmanV2/utils"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/rootless"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+var (
+ restoreDescription = `
+ podman container restore
+
+ Restores a container from a checkpoint. The container name or ID can be used.
+`
+ restoreCommand = &cobra.Command{
+ Use: "restore [flags] CONTAINER [CONTAINER...]",
+ Short: "Restores one or more containers from a checkpoint",
+ Long: restoreDescription,
+ RunE: restore,
+ Args: func(cmd *cobra.Command, args []string) error {
+ return parse.CheckAllLatestAndCIDFile(cmd, args, true, false)
+ },
+ Example: `podman container restore ctrID
+ podman container restore --latest
+ podman container restore --all`,
+ }
+)
+
+var (
+ restoreOptions entities.RestoreOptions
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: restoreCommand,
+ Parent: containerCmd,
+ })
+ flags := restoreCommand.Flags()
+ flags.BoolVarP(&restoreOptions.All, "all", "a", false, "Restore all checkpointed containers")
+ flags.BoolVarP(&restoreOptions.Keep, "keep", "k", false, "Keep all temporary checkpoint files")
+ flags.BoolVarP(&restoreOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ flags.BoolVar(&restoreOptions.TCPEstablished, "tcp-established", false, "Restore a container with established TCP connections")
+ flags.StringVarP(&restoreOptions.Import, "import", "i", "", "Restore from exported checkpoint archive (tar.gz)")
+ flags.StringVarP(&restoreOptions.Name, "name", "n", "", "Specify new name for container restored from exported checkpoint (only works with --import)")
+ flags.BoolVar(&restoreOptions.IgnoreRootFS, "ignore-rootfs", false, "Do not apply root file-system changes when importing from exported checkpoint")
+ flags.BoolVar(&restoreOptions.IgnoreStaticIP, "ignore-static-ip", false, "Ignore IP address set via --static-ip")
+ flags.BoolVar(&restoreOptions.IgnoreStaticMAC, "ignore-static-mac", false, "Ignore MAC address set via --mac-address")
+ if registry.IsRemote() {
+ _ = flags.MarkHidden("latest")
+ }
+}
+
+func restore(cmd *cobra.Command, args []string) error {
+ var errs utils.OutputErrors
+ if rootless.IsRootless() {
+ return errors.New("restoring a container requires root")
+ }
+ if restoreOptions.Import == "" && restoreOptions.IgnoreRootFS {
+ return errors.Errorf("--ignore-rootfs can only be used with --import")
+ }
+ if restoreOptions.Import == "" && restoreOptions.Name != "" {
+ return errors.Errorf("--name can only be used with --import")
+ }
+ if restoreOptions.Name != "" && restoreOptions.TCPEstablished {
+ return errors.Errorf("--tcp-established cannot be used with --name")
+ }
+
+ argLen := len(args)
+ if restoreOptions.Import != "" {
+ if restoreOptions.All || restoreOptions.Latest {
+ return errors.Errorf("Cannot use --import with --all or --latest")
+ }
+ if argLen > 0 {
+ return errors.Errorf("Cannot use --import with positional arguments")
+ }
+ }
+ if (restoreOptions.All || restoreOptions.Latest) && argLen > 0 {
+ return errors.Errorf("no arguments are needed with --all or --latest")
+ }
+ if argLen < 1 && !restoreOptions.All && !restoreOptions.Latest && restoreOptions.Import == "" {
+ return errors.Errorf("you must provide at least one name or id")
+ }
+ responses, err := registry.ContainerEngine().ContainerRestore(context.Background(), args, restoreOptions)
+ if err != nil {
+ return err
+ }
+ for _, r := range responses {
+ if r.Err == nil {
+ fmt.Println(r.Id)
+ } else {
+ errs = append(errs, r.Err)
+ }
+ }
+ return errs.PrintErrors()
+
+}