summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2018-10-29 13:53:39 -0500
committerbaude <bbaude@redhat.com>2018-11-01 14:23:55 -0500
commitb559c19c2fa739cf1c8ede50eab8f5acf74f6bf3 (patch)
treeb4d63dfa9418edf29dbbac4b00ae397e93632299 /cmd/podman
parent732a4c814e575ead4b39f00097f22b2f3b64bfc0 (diff)
downloadpodman-b559c19c2fa739cf1c8ede50eab8f5acf74f6bf3.tar.gz
podman-b559c19c2fa739cf1c8ede50eab8f5acf74f6bf3.tar.bz2
podman-b559c19c2fa739cf1c8ede50eab8f5acf74f6bf3.zip
Make kill, pause, and unpause parallel.
Operations like kill, pause, and unpause -- which can operation on one or more containers -- can greatly benefit from parallizing its main job (eq kill). In the case of pauseand unpause, an --all option as was added. pause --all will pause all **running** containers. And unpause --all will unpause all **paused** containers. Signed-off-by: baude <bbaude@redhat.com>
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/kill.go51
-rw-r--r--cmd/podman/pause.go72
-rw-r--r--cmd/podman/shared/parallel.go15
-rw-r--r--cmd/podman/stop.go4
-rw-r--r--cmd/podman/unpause.go73
5 files changed, 173 insertions, 42 deletions
diff --git a/cmd/podman/kill.go b/cmd/podman/kill.go
index 7ca5bd7c5..27882aeee 100644
--- a/cmd/podman/kill.go
+++ b/cmd/podman/kill.go
@@ -1,15 +1,16 @@
package main
import (
- "os"
+ "fmt"
"syscall"
- "fmt"
"github.com/containers/libpod/cmd/podman/libpodruntime"
+ "github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/rootless"
"github.com/docker/docker/pkg/signal"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
@@ -41,6 +42,12 @@ var (
// killCmd kills one or more containers with a signal
func killCmd(c *cli.Context) error {
+ var (
+ lastError error
+ killFuncs []shared.ParallelWorkerInput
+ killSignal uint = uint(syscall.SIGTERM)
+ )
+
if err := checkAllAndLatest(c); err != nil {
return err
}
@@ -56,7 +63,6 @@ func killCmd(c *cli.Context) error {
}
defer runtime.Shutdown(false)
- var killSignal uint = uint(syscall.SIGTERM)
if c.String("signal") != "" {
// Check if the signalString provided by the user is valid
// Invalid signals will return err
@@ -67,17 +73,40 @@ func killCmd(c *cli.Context) error {
killSignal = uint(sysSignal)
}
- containers, lastError := getAllOrLatestContainers(c, runtime, libpod.ContainerStateRunning, "running")
-
+ containers, err := getAllOrLatestContainers(c, runtime, libpod.ContainerStateRunning, "running")
+ if err != nil {
+ return err
+ }
for _, ctr := range containers {
- if err := ctr.Kill(killSignal); err != nil {
- if lastError != nil {
- fmt.Fprintln(os.Stderr, lastError)
+ con := ctr
+ f := func() error {
+ return con.Kill(killSignal)
+ }
+
+ killFuncs = append(killFuncs, shared.ParallelWorkerInput{
+ ContainerID: con.ID(),
+ ParallelFunc: f,
+ })
+ }
+
+ maxWorkers := shared.Parallelize("kill")
+ if c.GlobalIsSet("max-workers") {
+ maxWorkers = c.GlobalInt("max-workers")
+ }
+ logrus.Debugf("Setting maximum workers to %d", maxWorkers)
+
+ killErrors := shared.ParallelExecuteWorkerPool(maxWorkers, killFuncs)
+
+ for cid, result := range killErrors {
+ if result != nil {
+ if len(killErrors) > 1 {
+ fmt.Println(result.Error())
}
- lastError = errors.Wrapf(err, "unable to find container %v", ctr.ID())
- } else {
- fmt.Println(ctr.ID())
+ lastError = result
+ continue
}
+ fmt.Println(cid)
}
+
return lastError
}
diff --git a/cmd/podman/pause.go b/cmd/podman/pause.go
index 203fa6070..1e1585216 100644
--- a/cmd/podman/pause.go
+++ b/cmd/podman/pause.go
@@ -5,11 +5,20 @@ import (
"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 (
+ pauseFlags = []cli.Flag{
+ cli.BoolFlag{
+ Name: "all, a",
+ Usage: "pause all running containers",
+ },
+ }
pauseDescription = `
podman pause
@@ -19,6 +28,7 @@ var (
Name: "pause",
Usage: "Pauses all the processes in one or more containers",
Description: pauseDescription,
+ Flags: pauseFlags,
Action: pauseCmd,
ArgsUsage: "CONTAINER-NAME [CONTAINER-NAME ...]",
OnUsageError: usageErrorHandler,
@@ -26,6 +36,11 @@ var (
)
func pauseCmd(c *cli.Context) error {
+ var (
+ lastError error
+ pauseContainers []*libpod.Container
+ pauseFuncs []shared.ParallelWorkerInput
+ )
if os.Geteuid() != 0 {
return errors.New("pause is not supported for rootless containers")
}
@@ -37,28 +52,55 @@ func pauseCmd(c *cli.Context) error {
defer runtime.Shutdown(false)
args := c.Args()
- if len(args) < 1 {
+ if len(args) < 1 && !c.Bool("all") {
return errors.Errorf("you must provide at least one container name or id")
}
-
- var lastError error
- for _, arg := range args {
- ctr, err := runtime.LookupContainer(arg)
+ if c.Bool("all") {
+ containers, err := getAllOrLatestContainers(c, runtime, libpod.ContainerStateRunning, "running")
if err != nil {
- if lastError != nil {
- fmt.Fprintln(os.Stderr, lastError)
+ return err
+ }
+ pauseContainers = append(pauseContainers, containers...)
+ } else {
+ for _, arg := range args {
+ ctr, err := runtime.LookupContainer(arg)
+ if err != nil {
+ return err
}
- lastError = errors.Wrapf(err, "error looking up container %q", arg)
- continue
+ pauseContainers = append(pauseContainers, ctr)
+ }
+ }
+
+ // Now assemble the slice of pauseFuncs
+ for _, ctr := range pauseContainers {
+ con := ctr
+
+ f := func() error {
+ return con.Pause()
}
- if err = ctr.Pause(); err != nil {
- if lastError != nil {
- fmt.Fprintln(os.Stderr, lastError)
+ pauseFuncs = append(pauseFuncs, shared.ParallelWorkerInput{
+ ContainerID: con.ID(),
+ ParallelFunc: f,
+ })
+ }
+
+ maxWorkers := shared.Parallelize("pause")
+ if c.GlobalIsSet("max-workers") {
+ maxWorkers = c.GlobalInt("max-workers")
+ }
+ logrus.Debugf("Setting maximum workers to %d", maxWorkers)
+
+ pauseErrors := shared.ParallelExecuteWorkerPool(maxWorkers, pauseFuncs)
+
+ for cid, result := range pauseErrors {
+ if result != nil {
+ if len(pauseErrors) > 1 {
+ fmt.Println(result.Error())
}
- lastError = errors.Wrapf(err, "failed to pause container %v", ctr.ID())
- } else {
- fmt.Println(ctr.ID())
+ lastError = result
+ continue
}
+ fmt.Println(cid)
}
return lastError
}
diff --git a/cmd/podman/shared/parallel.go b/cmd/podman/shared/parallel.go
index dbf43a982..633781a45 100644
--- a/cmd/podman/shared/parallel.go
+++ b/cmd/podman/shared/parallel.go
@@ -72,6 +72,16 @@ func ParallelExecuteWorkerPool(workers int, functions []ParallelWorkerInput) map
func Parallelize(job string) int {
numCpus := runtime.NumCPU()
switch job {
+ case "kill":
+ if numCpus <= 3 {
+ return numCpus * 3
+ }
+ return numCpus * 4
+ case "pause":
+ if numCpus <= 3 {
+ return numCpus * 3
+ }
+ return numCpus * 4
case "ps":
return 8
case "restart":
@@ -88,6 +98,11 @@ func Parallelize(job string) int {
} else {
return numCpus * 3
}
+ case "unpause":
+ if numCpus <= 3 {
+ return numCpus * 3
+ }
+ return numCpus * 4
}
return 3
}
diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go
index afeb49f76..cb36fd5cd 100644
--- a/cmd/podman/stop.go
+++ b/cmd/podman/stop.go
@@ -89,7 +89,9 @@ func stopCmd(c *cli.Context) error {
for cid, result := range stopErrors {
if result != nil && result != libpod.ErrCtrStopped {
- fmt.Println(result.Error())
+ if len(stopErrors) > 1 {
+ fmt.Println(result.Error())
+ }
lastError = result
continue
}
diff --git a/cmd/podman/unpause.go b/cmd/podman/unpause.go
index a792aaf6d..648fc9d3d 100644
--- a/cmd/podman/unpause.go
+++ b/cmd/podman/unpause.go
@@ -5,11 +5,20 @@ import (
"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 (
+ unpauseFlags = []cli.Flag{
+ cli.BoolFlag{
+ Name: "all, a",
+ Usage: "unpause all paused containers",
+ },
+ }
unpauseDescription = `
podman unpause
@@ -19,6 +28,7 @@ var (
Name: "unpause",
Usage: "Unpause the processes in one or more containers",
Description: unpauseDescription,
+ Flags: unpauseFlags,
Action: unpauseCmd,
ArgsUsage: "CONTAINER-NAME [CONTAINER-NAME ...]",
OnUsageError: usageErrorHandler,
@@ -26,6 +36,11 @@ var (
)
func unpauseCmd(c *cli.Context) error {
+ var (
+ lastError error
+ unpauseContainers []*libpod.Container
+ unpauseFuncs []shared.ParallelWorkerInput
+ )
if os.Geteuid() != 0 {
return errors.New("unpause is not supported for rootless containers")
}
@@ -37,28 +52,56 @@ func unpauseCmd(c *cli.Context) error {
defer runtime.Shutdown(false)
args := c.Args()
- if len(args) < 1 {
+ if len(args) < 1 && !c.Bool("all") {
return errors.Errorf("you must provide at least one container name or id")
}
-
- var lastError error
- for _, arg := range args {
- ctr, err := runtime.LookupContainer(arg)
+ if c.Bool("all") {
+ cs, err := getAllOrLatestContainers(c, runtime, libpod.ContainerStatePaused, "paused")
if err != nil {
- if lastError != nil {
- fmt.Fprintln(os.Stderr, lastError)
+ return err
+ }
+ unpauseContainers = append(unpauseContainers, cs...)
+ } else {
+ for _, arg := range args {
+ ctr, err := runtime.LookupContainer(arg)
+ if err != nil {
+ return err
}
- lastError = errors.Wrapf(err, "error looking up container %q", arg)
- continue
+ unpauseContainers = append(unpauseContainers, ctr)
}
- if err = ctr.Unpause(); err != nil {
- if lastError != nil {
- fmt.Fprintln(os.Stderr, lastError)
+ }
+
+ // Assemble the unpause funcs
+ for _, ctr := range unpauseContainers {
+ con := ctr
+ f := func() error {
+ return con.Unpause()
+ }
+
+ unpauseFuncs = append(unpauseFuncs, shared.ParallelWorkerInput{
+ ContainerID: con.ID(),
+ ParallelFunc: f,
+ })
+ }
+
+ maxWorkers := shared.Parallelize("unpause")
+ if c.GlobalIsSet("max-workers") {
+ maxWorkers = c.GlobalInt("max-workers")
+ }
+ logrus.Debugf("Setting maximum workers to %d", maxWorkers)
+
+ unpauseErrors := shared.ParallelExecuteWorkerPool(maxWorkers, unpauseFuncs)
+
+ for cid, result := range unpauseErrors {
+ if result != nil && result != libpod.ErrCtrStopped {
+ if len(unpauseErrors) > 1 {
+ fmt.Println(result.Error())
}
- lastError = errors.Wrapf(err, "failed to unpause container %v", ctr.ID())
- } else {
- fmt.Println(ctr.ID())
+ lastError = result
+ continue
}
+ fmt.Println(cid)
}
+
return lastError
}