diff options
author | Brent Baude <bbaude@redhat.com> | 2020-03-27 08:20:13 -0500 |
---|---|---|
committer | Brent Baude <bbaude@redhat.com> | 2020-04-03 09:32:06 -0500 |
commit | 8a16674722ab4a33ce66e57d151b09ac348e8e6d (patch) | |
tree | 03505f230a58e656e8b85c44b2505696e16c50c2 /cmd/podmanV2 | |
parent | ccb9e579c48141f70d016adfa9a9d4934bbdf976 (diff) | |
download | podman-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/podmanV2')
-rw-r--r-- | cmd/podmanV2/containers/checkpoint.go | 79 | ||||
-rw-r--r-- | cmd/podmanV2/containers/restore.go | 104 |
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() + +} |