diff options
author | baude <bbaude@redhat.com> | 2018-10-29 12:06:48 -0500 |
---|---|---|
committer | baude <bbaude@redhat.com> | 2018-11-01 13:14:12 -0500 |
commit | 2011782d9d52958546e481f84892d00a548b9e12 (patch) | |
tree | 208158661ad4089007f9124d0eeecefcba1b7d42 /cmd/podman/restart.go | |
parent | 9c1985fc4ee0a30a5a852dfbeae742e64978ed25 (diff) | |
download | podman-2011782d9d52958546e481f84892d00a548b9e12.tar.gz podman-2011782d9d52958546e481f84892d00a548b9e12.tar.bz2 podman-2011782d9d52958546e481f84892d00a548b9e12.zip |
Make restart parallel and add --all
When attempting to restart many containers, we can benefit from making
the restarts parallel. For convenience, two new options are added:
--all attempts to restart all containers
--run-only when used with --all will attempt to restart only running containers
Signed-off-by: baude <bbaude@redhat.com>
Diffstat (limited to 'cmd/podman/restart.go')
-rw-r--r-- | cmd/podman/restart.go | 95 |
1 files changed, 68 insertions, 27 deletions
diff --git a/cmd/podman/restart.go b/cmd/podman/restart.go index 7b48ef24e..2e264db79 100644 --- a/cmd/podman/restart.go +++ b/cmd/podman/restart.go @@ -1,18 +1,26 @@ package main import ( - "context" "fmt" - "os" "github.com/containers/libpod/cmd/podman/libpodruntime" + "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/urfave/cli" ) var ( restartFlags = []cli.Flag{ + cli.BoolFlag{ + Name: "all, a", + Usage: "restart all non-running containers", + }, + cli.BoolFlag{ + Name: "running", + Usage: "restart only running containers when --all is used", + }, cli.UintFlag{ Name: "timeout, time, t", Usage: "Seconds to wait for stop before killing the container", @@ -35,11 +43,19 @@ var ( ) func restartCmd(c *cli.Context) error { + var ( + restartFuncs []shared.ParallelWorkerInput + containers []*libpod.Container + lastError error + restartContainers []*libpod.Container + ) + args := c.Args() - if len(args) < 1 && !c.Bool("latest") { + runOnly := c.Bool("running") + all := c.Bool("all") + if len(args) < 1 && !c.Bool("latest") && !all { return errors.Wrapf(libpod.ErrInvalidArg, "you must provide at least one container name or ID") } - if err := validateFlags(c, restartFlags); err != nil { return err } @@ -50,8 +66,6 @@ func restartCmd(c *cli.Context) error { } defer runtime.Shutdown(false) - var lastError error - timeout := c.Uint("timeout") useTimeout := c.IsSet("timeout") @@ -59,39 +73,66 @@ func restartCmd(c *cli.Context) error { if c.Bool("latest") { lastCtr, err := runtime.GetLatestContainer() if err != nil { - lastError = errors.Wrapf(err, "unable to get latest container") - } else { - ctrTimeout := lastCtr.StopTimeout() - if useTimeout { - ctrTimeout = timeout - } - - lastError = lastCtr.RestartWithTimeout(context.TODO(), ctrTimeout) + return errors.Wrapf(err, "unable to get latest container") } - } - - for _, id := range args { - ctr, err := runtime.LookupContainer(id) + restartContainers = append(restartContainers, lastCtr) + } else if runOnly { + containers, err = getAllOrLatestContainers(c, runtime, libpod.ContainerStateRunning, "running") if err != nil { - if lastError != nil { - fmt.Fprintln(os.Stderr, lastError) + return err + } + restartContainers = append(restartContainers, containers...) + } else if all { + containers, err = runtime.GetAllContainers() + if err != nil { + return err + } + restartContainers = append(restartContainers, containers...) + } else { + for _, id := range args { + ctr, err := runtime.LookupContainer(id) + if err != nil { + return err } - lastError = errors.Wrapf(err, "unable to find container %s", id) - continue + restartContainers = append(restartContainers, ctr) } + } + // We now have a slice of all the containers to be restarted. Iterate them to + // create restart Funcs with a timeout as needed + for _, ctr := range restartContainers { + con := ctr ctrTimeout := ctr.StopTimeout() if useTimeout { ctrTimeout = timeout } - if err := ctr.RestartWithTimeout(context.TODO(), ctrTimeout); err != nil { - if lastError != nil { - fmt.Fprintln(os.Stderr, lastError) - } - lastError = errors.Wrapf(err, "error restarting container %s", ctr.ID()) + f := func() error { + return con.RestartWithTimeout(getContext(), ctrTimeout) } + + restartFuncs = append(restartFuncs, shared.ParallelWorkerInput{ + ContainerID: con.ID(), + ParallelFunc: f, + }) + } + + maxWorkers := shared.Parallelize("restart") + if c.GlobalIsSet("max-workers") { + maxWorkers = c.GlobalInt("max-workers") } + logrus.Debugf("Setting maximum workers to %d", maxWorkers) + + restartErrors := shared.ParallelExecuteWorkerPool(maxWorkers, restartFuncs) + + for cid, result := range restartErrors { + if result != nil { + fmt.Println(result.Error()) + lastError = result + continue + } + fmt.Println(cid) + } return lastError } |