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>
This commit is contained in:
baude
2018-10-29 13:53:39 -05:00
parent 732a4c814e
commit b559c19c2f
10 changed files with 287 additions and 50 deletions

View File

@ -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")
for _, ctr := range containers {
if err := ctr.Kill(killSignal); err != nil {
if lastError != nil {
fmt.Fprintln(os.Stderr, lastError)
}
lastError = errors.Wrapf(err, "unable to find container %v", ctr.ID())
} else {
fmt.Println(ctr.ID())
}
containers, err := getAllOrLatestContainers(c, runtime, libpod.ContainerStateRunning, "running")
if err != nil {
return err
}
for _, ctr := range containers {
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 = result
continue
}
fmt.Println(cid)
}
return lastError
}