Skip to content

Commit

Permalink
Merge pull request #1662 from adrianreber/all-and-latest
Browse files Browse the repository at this point in the history
Add --all and --latest to checkpoint/restore
  • Loading branch information
openshift-merge-robot authored Oct 23, 2018
2 parents 41a8bbd + e8d6903 commit c019830
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 187 deletions.
25 changes: 12 additions & 13 deletions cmd/podman/checkpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"

"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/urfave/cli"
Expand All @@ -22,6 +23,11 @@ var (
Name: "keep, k",
Usage: "keep all temporary checkpoint files",
},
cli.BoolFlag{
Name: "all, a",
Usage: "checkpoint all running containers",
},
LatestFlag,
}
checkpointCommand = cli.Command{
Name: "checkpoint",
Expand All @@ -45,21 +51,14 @@ func checkpointCmd(c *cli.Context) error {
defer runtime.Shutdown(false)

keep := c.Bool("keep")
args := c.Args()
if len(args) < 1 {
return errors.Errorf("you must provide at least one container name or id")

if err := checkAllAndLatest(c); err != nil {
return err
}

var lastError error
for _, arg := range args {
ctr, err := runtime.LookupContainer(arg)
if err != nil {
if lastError != nil {
fmt.Fprintln(os.Stderr, lastError)
}
lastError = errors.Wrapf(err, "error looking up container %q", arg)
continue
}
containers, lastError := getAllOrLatestContainers(c, runtime, libpod.ContainerStateRunning, "running")

for _, ctr := range containers {
if err = ctr.Checkpoint(context.TODO(), keep); err != nil {
if lastError != nil {
fmt.Fprintln(os.Stderr, lastError)
Expand Down
40 changes: 5 additions & 35 deletions cmd/podman/cleanup.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"os"

"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
"github.com/pkg/errors"
"github.com/urfave/cli"
)
Expand Down Expand Up @@ -44,43 +43,14 @@ func cleanupCmd(c *cli.Context) error {
}
defer runtime.Shutdown(false)

args := c.Args()
if err := checkAllAndLatest(c); err != nil {
return err
}

cleanupContainers, lastError := getAllOrLatestContainers(c, runtime, -1, "all")

ctx := getContext()

var lastError error
var cleanupContainers []*libpod.Container
if c.Bool("all") {
if c.Bool("lastest") {
return errors.New("--all and --latest cannot be used together")
}
if len(args) != 0 {
return errors.New("--all and explicit container IDs cannot be used together")
}
cleanupContainers, err = runtime.GetContainers()
if err != nil {
return errors.Wrapf(err, "unable to get container list")
}
} else if c.Bool("latest") {
if len(args) != 0 {
return errors.New("--latest and explicit container IDs cannot be used together")
}
lastCtr, err := runtime.GetLatestContainer()
if err != nil {
return errors.Wrapf(err, "unable to get latest container")
}
cleanupContainers = append(cleanupContainers, lastCtr)
} else {
for _, i := range args {
container, err := runtime.LookupContainer(i)
if err != nil {
fmt.Fprintln(os.Stderr, err)
lastError = errors.Wrapf(err, "unable to find container %s", i)
continue
}
cleanupContainers = append(cleanupContainers, container)
}
}
for _, ctr := range cleanupContainers {
if err = ctr.Cleanup(ctx); err != nil {
if lastError != nil {
Expand Down
67 changes: 67 additions & 0 deletions cmd/podman/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,73 @@ func validateFlags(c *cli.Context, flags []cli.Flag) error {
return nil
}

// checkAllAndLatest checks that --all and --latest are used correctly
func checkAllAndLatest(c *cli.Context) error {
argLen := len(c.Args())
if (c.Bool("all") || c.Bool("latest")) && argLen > 0 {
return errors.Errorf("no arguments are needed with --all or --latest")
}
if c.Bool("all") && c.Bool("latest") {
return errors.Errorf("--all and --latest cannot be used together")
}
if argLen < 1 && !c.Bool("all") && !c.Bool("latest") {
return errors.Errorf("you must provide at least one pod name or id")
}
return nil
}

// getAllOrLatestContainers tries to return the correct list of containers
// depending if --all, --latest or <container-id> is used.
// It requires the Context (c) and the Runtime (runtime). As different
// commands are using different container state for the --all option
// the desired state has to be specified in filterState. If no filter
// is desired a -1 can be used to get all containers. For a better
// error message, if the filter fails, a corresponding verb can be
// specified which will then appear in the error message.
func getAllOrLatestContainers(c *cli.Context, runtime *libpod.Runtime, filterState libpod.ContainerStatus, verb string) ([]*libpod.Container, error) {
var containers []*libpod.Container
var lastError error
var err error
if c.Bool("all") {
if filterState != -1 {
var filterFuncs []libpod.ContainerFilter
filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
state, _ := c.State()
return state == filterState
})
containers, err = runtime.GetContainers(filterFuncs...)
} else {
containers, err = runtime.GetContainers()
}
if err != nil {
return nil, errors.Wrapf(err, "unable to get %s containers", verb)
}
} else if c.Bool("latest") {
lastCtr, err := runtime.GetLatestContainer()
if err != nil {
return nil, errors.Wrapf(err, "unable to get latest container")
}
containers = append(containers, lastCtr)
} else {
args := c.Args()
for _, i := range args {
container, err := runtime.LookupContainer(i)
if err != nil {
if lastError != nil {
fmt.Fprintln(os.Stderr, lastError)
}
lastError = errors.Wrapf(err, "unable to find container %s", i)
}
if container != nil {
// This is here to make sure this does not return [<nil>] but only nil
containers = append(containers, container)
}
}
}

return containers, lastError
}

// getContext returns a non-nil, empty context
func getContext() context.Context {
return context.TODO()
Expand Down
48 changes: 4 additions & 44 deletions cmd/podman/kill.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,10 @@ var (

// killCmd kills one or more containers with a signal
func killCmd(c *cli.Context) error {
args := c.Args()
if (!c.Bool("all") && !c.Bool("latest")) && len(args) == 0 {
return errors.Errorf("you must specify one or more containers to kill")
}
if (c.Bool("all") || c.Bool("latest")) && len(args) > 0 {
return errors.Errorf("you cannot specify any containers to kill with --latest or --all")
}
if c.Bool("all") && c.Bool("latest") {
return errors.Errorf("--all and --latest cannot be used together")
}
if len(args) < 1 && !c.Bool("all") && !c.Bool("latest") {
return errors.Errorf("you must provide at least one container name or id")
if err := checkAllAndLatest(c); err != nil {
return err
}

if err := validateFlags(c, killFlags); err != nil {
return err
}
Expand All @@ -76,38 +67,7 @@ func killCmd(c *cli.Context) error {
killSignal = uint(sysSignal)
}

var filterFuncs []libpod.ContainerFilter
var containers []*libpod.Container
var lastError error
if c.Bool("all") {
// only get running containers
filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
state, _ := c.State()
return state == libpod.ContainerStateRunning
})
containers, err = runtime.GetContainers(filterFuncs...)
if err != nil {
return errors.Wrapf(err, "unable to get running containers")
}
} else if c.Bool("latest") {
lastCtr, err := runtime.GetLatestContainer()
if err != nil {
return errors.Wrapf(err, "unable to get last created container")
}
containers = append(containers, lastCtr)
} else {
for _, i := range args {
container, err := runtime.LookupContainer(i)
if err != nil {
if lastError != nil {
fmt.Fprintln(os.Stderr, lastError)
}
lastError = errors.Wrapf(err, "unable to find container %s", i)
continue
}
containers = append(containers, container)
}
}
containers, lastError := getAllOrLatestContainers(c, runtime, libpod.ContainerStateRunning, "running")

for _, ctr := range containers {
if err := ctr.Kill(killSignal); err != nil {
Expand Down
28 changes: 15 additions & 13 deletions cmd/podman/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"

"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/urfave/cli"
Expand All @@ -22,6 +23,14 @@ var (
Name: "keep, k",
Usage: "keep all temporary checkpoint files",
},
// restore --all would make more sense if there would be
// dedicated state for container which are checkpointed.
// TODO: add ContainerStateCheckpointed
cli.BoolFlag{
Name: "all, a",
Usage: "restore all checkpointed containers",
},
LatestFlag,
}
restoreCommand = cli.Command{
Name: "restore",
Expand All @@ -45,21 +54,14 @@ func restoreCmd(c *cli.Context) error {
defer runtime.Shutdown(false)

keep := c.Bool("keep")
args := c.Args()
if len(args) < 1 {
return errors.Errorf("you must provide at least one container name or id")

if err := checkAllAndLatest(c); err != nil {
return err
}

var lastError error
for _, arg := range args {
ctr, err := runtime.LookupContainer(arg)
if err != nil {
if lastError != nil {
fmt.Fprintln(os.Stderr, lastError)
}
lastError = errors.Wrapf(err, "error looking up container %q", arg)
continue
}
containers, lastError := getAllOrLatestContainers(c, runtime, libpod.ContainerStateRunning, "checkpointed")

for _, ctr := range containers {
if err = ctr.Restore(context.TODO(), keep); err != nil {
if lastError != nil {
fmt.Fprintln(os.Stderr, lastError)
Expand Down
33 changes: 3 additions & 30 deletions cmd/podman/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"fmt"
"os"
rt "runtime"

"github.com/containers/libpod/cmd/podman/libpodruntime"
Expand Down Expand Up @@ -63,37 +62,11 @@ func rmCmd(c *cli.Context) error {
}
defer runtime.Shutdown(false)

args := c.Args()
if c.Bool("latest") && c.Bool("all") {
return errors.Errorf("--all and --latest cannot be used together")
}

if len(args) == 0 && !c.Bool("all") && !c.Bool("latest") {
return errors.Errorf("specify one or more containers to remove")
if err := checkAllAndLatest(c); err != nil {
return err
}

if c.Bool("all") {
delContainers, err = runtime.GetContainers()
if err != nil {
return errors.Wrapf(err, "unable to get container list")
}
} else if c.Bool("latest") {
lastCtr, err := runtime.GetLatestContainer()
if err != nil {
return errors.Wrapf(err, "unable to get latest container")
}
delContainers = append(delContainers, lastCtr)
} else {
for _, i := range args {
container, err := runtime.LookupContainer(i)
if err != nil {
fmt.Fprintln(os.Stderr, err)
lastError = errors.Wrapf(err, "unable to find container %s", i)
continue
}
delContainers = append(delContainers, container)
}
}
delContainers, lastError = getAllOrLatestContainers(c, runtime, -1, "all")

for _, container := range delContainers {
f := func() error {
Expand Down
Loading

0 comments on commit c019830

Please sign in to comment.