diff options
author | baude <bbaude@redhat.com> | 2019-04-02 08:37:11 -0500 |
---|---|---|
committer | baude <bbaude@redhat.com> | 2019-04-11 10:13:58 -0500 |
commit | 72d08d4c61c1466a4e10fc46c29cb0a14893f923 (patch) | |
tree | f9661e51323f6aa2c66fa4d27b777d3a8340007d | |
parent | 4596c39655f7ff5e741adbc97aaa49bb3a9d453e (diff) | |
download | podman-72d08d4c61c1466a4e10fc46c29cb0a14893f923.tar.gz podman-72d08d4c61c1466a4e10fc46c29cb0a14893f923.tar.bz2 podman-72d08d4c61c1466a4e10fc46c29cb0a14893f923.zip |
remote-client checkpoint/restore
add the ability for the remote client to be able to checkpoint and
restore containers.
Signed-off-by: baude <bbaude@redhat.com>
-rw-r--r-- | cmd/podman/checkpoint.go | 22 | ||||
-rw-r--r-- | cmd/podman/restore.go | 23 | ||||
-rw-r--r-- | pkg/adapter/containers.go | 64 | ||||
-rw-r--r-- | pkg/adapter/containers_remote.go | 72 |
4 files changed, 142 insertions, 39 deletions
diff --git a/cmd/podman/checkpoint.go b/cmd/podman/checkpoint.go index dbf72c2cd..5b8d00ff9 100644 --- a/cmd/podman/checkpoint.go +++ b/cmd/podman/checkpoint.go @@ -1,13 +1,9 @@ package main import ( - "context" - "fmt" - "os" - "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/adapter" "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -57,7 +53,7 @@ func checkpointCmd(c *cliconfig.CheckpointValues) error { return errors.New("checkpointing a container requires root") } - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") } @@ -68,17 +64,5 @@ func checkpointCmd(c *cliconfig.CheckpointValues) error { KeepRunning: c.LeaveRunning, TCPEstablished: c.TcpEstablished, } - containers, lastError := getAllOrLatestContainers(&c.PodmanCommand, runtime, libpod.ContainerStateRunning, "running") - - for _, ctr := range containers { - if err = ctr.Checkpoint(context.TODO(), options); err != nil { - if lastError != nil { - fmt.Fprintln(os.Stderr, lastError) - } - lastError = errors.Wrapf(err, "failed to checkpoint container %v", ctr.ID()) - } else { - fmt.Println(ctr.ID()) - } - } - return lastError + return runtime.Checkpoint(c, options) } diff --git a/cmd/podman/restore.go b/cmd/podman/restore.go index 0f6828432..0f0150644 100644 --- a/cmd/podman/restore.go +++ b/cmd/podman/restore.go @@ -1,13 +1,9 @@ package main import ( - "context" - "fmt" - "os" - "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/adapter" "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -57,7 +53,7 @@ func restoreCmd(c *cliconfig.RestoreValues) error { return errors.New("restoring a container requires root") } - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") } @@ -67,18 +63,5 @@ func restoreCmd(c *cliconfig.RestoreValues) error { Keep: c.Keep, TCPEstablished: c.TcpEstablished, } - - containers, lastError := getAllOrLatestContainers(&c.PodmanCommand, runtime, libpod.ContainerStateExited, "checkpointed") - - for _, ctr := range containers { - if err = ctr.Restore(context.TODO(), options); err != nil { - if lastError != nil { - fmt.Fprintln(os.Stderr, lastError) - } - lastError = errors.Wrapf(err, "failed to restore container %v", ctr.ID()) - } else { - fmt.Println(ctr.ID()) - } - } - return lastError + return runtime.Restore(c, options) } diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index a9b3232e7..1bb1aab87 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -443,3 +443,67 @@ func (r *LocalRuntime) Attach(ctx context.Context, c *cliconfig.AttachValues) er } return nil } + +// Checkpoint one or more containers +func (r *LocalRuntime) Checkpoint(c *cliconfig.CheckpointValues, options libpod.ContainerCheckpointOptions) error { + var ( + containers []*libpod.Container + err, lastError error + ) + + if c.All { + containers, err = r.Runtime.GetRunningContainers() + } else { + containers, err = shortcuts.GetContainersByContext(false, c.Latest, c.InputArgs, r.Runtime) + } + if err != nil { + return err + } + + for _, ctr := range containers { + if err = ctr.Checkpoint(context.TODO(), options); err != nil { + if lastError != nil { + fmt.Fprintln(os.Stderr, lastError) + } + lastError = errors.Wrapf(err, "failed to checkpoint container %v", ctr.ID()) + } else { + fmt.Println(ctr.ID()) + } + } + return lastError +} + +// Restore one or more containers +func (r *LocalRuntime) Restore(c *cliconfig.RestoreValues, options libpod.ContainerCheckpointOptions) error { + var ( + containers []*libpod.Container + err, lastError error + filterFuncs []libpod.ContainerFilter + ) + + filterFuncs = append(filterFuncs, func(c *libpod.Container) bool { + state, _ := c.State() + return state == libpod.ContainerStateExited + }) + + if c.All { + containers, err = r.GetContainers(filterFuncs...) + } else { + containers, err = shortcuts.GetContainersByContext(false, c.Latest, c.InputArgs, r.Runtime) + } + if err != nil { + return err + } + + for _, ctr := range containers { + if err = ctr.Restore(context.TODO(), options); err != nil { + if lastError != nil { + fmt.Fprintln(os.Stderr, lastError) + } + lastError = errors.Wrapf(err, "failed to restore container %v", ctr.ID()) + } else { + fmt.Println(ctr.ID()) + } + } + return lastError +} diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go index 1ae39749f..31727fd0e 100644 --- a/pkg/adapter/containers_remote.go +++ b/pkg/adapter/containers_remote.go @@ -539,3 +539,75 @@ func (r *LocalRuntime) Attach(ctx context.Context, c *cliconfig.AttachValues) er } return <-errChan } + +// Checkpoint one or more containers +func (r *LocalRuntime) Checkpoint(c *cliconfig.CheckpointValues, options libpod.ContainerCheckpointOptions) error { + var lastError error + ids, err := iopodman.GetContainersByContext().Call(r.Conn, c.All, c.Latest, c.InputArgs) + if err != nil { + return err + } + if c.All { + // We dont have a great way to get all the running containers, so need to get all and then + // check status on them bc checkpoint considers checkpointing a stopped container an error + var runningIds []string + for _, id := range ids { + ctr, err := r.LookupContainer(id) + if err != nil { + return err + } + if ctr.state.State == libpod.ContainerStateRunning { + runningIds = append(runningIds, id) + } + } + ids = runningIds + } + + for _, id := range ids { + if _, err := iopodman.ContainerCheckpoint().Call(r.Conn, id, options.Keep, options.KeepRunning, options.TCPEstablished); err != nil { + if lastError != nil { + fmt.Fprintln(os.Stderr, lastError) + } + lastError = errors.Wrapf(err, "failed to checkpoint container %v", id) + } else { + fmt.Println(id) + } + } + return lastError +} + +// Restore one or more containers +func (r *LocalRuntime) Restore(c *cliconfig.RestoreValues, options libpod.ContainerCheckpointOptions) error { + var lastError error + ids, err := iopodman.GetContainersByContext().Call(r.Conn, c.All, c.Latest, c.InputArgs) + if err != nil { + return err + } + if c.All { + // We dont have a great way to get all the exited containers, so need to get all and then + // check status on them bc checkpoint considers restoring a running container an error + var exitedIDs []string + for _, id := range ids { + ctr, err := r.LookupContainer(id) + if err != nil { + return err + } + if ctr.state.State != libpod.ContainerStateRunning { + exitedIDs = append(exitedIDs, id) + } + } + ids = exitedIDs + } + + for _, id := range ids { + if _, err := iopodman.ContainerRestore().Call(r.Conn, id, options.Keep, options.TCPEstablished); err != nil { + if lastError != nil { + fmt.Fprintln(os.Stderr, lastError) + } + lastError = errors.Wrapf(err, "failed to restore container %v", id) + } else { + fmt.Println(id) + } + } + return lastError +} |