mirror of
https://github.com/containers/podman.git
synced 2025-07-02 00:30:00 +08:00
Add pod kill
With tests, man page, and completions. Signed-off-by: haircommander <pehunt@redhat.com> Closes: #1125 Approved by: rhatdan
This commit is contained in:

committed by
Atomic Bot

parent
8ce0e0b246
commit
73e3945282
@ -18,6 +18,7 @@ var (
|
||||
UseShortOptionHandling: true,
|
||||
Subcommands: []cli.Command{
|
||||
podCreateCommand,
|
||||
podKillCommand,
|
||||
podPsCommand,
|
||||
podRestartCommand,
|
||||
podRmCommand,
|
||||
|
114
cmd/podman/pod_kill.go
Normal file
114
cmd/podman/pod_kill.go
Normal file
@ -0,0 +1,114 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
|
||||
"github.com/projectatomic/libpod/libpod"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var (
|
||||
podKillFlags = []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "all, a",
|
||||
Usage: "Kill all containers in all pods",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "signal, s",
|
||||
Usage: "Signal to send to the containers in the pod",
|
||||
Value: "KILL",
|
||||
},
|
||||
LatestFlag,
|
||||
}
|
||||
podKillDescription = "The main process of each container inside the specified pod will be sent SIGKILL, or any signal specified with option --signal."
|
||||
podKillCommand = cli.Command{
|
||||
Name: "kill",
|
||||
Usage: "Send the specified signal or SIGKILL to containers in pod",
|
||||
Description: podKillDescription,
|
||||
Flags: podKillFlags,
|
||||
Action: podKillCmd,
|
||||
ArgsUsage: "[POD_NAME_OR_ID]",
|
||||
UseShortOptionHandling: true,
|
||||
}
|
||||
)
|
||||
|
||||
// podKillCmd kills one or more pods with a signal
|
||||
func podKillCmd(c *cli.Context) error {
|
||||
if err := checkMutuallyExclusiveFlags(c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
runtime, err := libpodruntime.GetRuntime(c)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not get runtime")
|
||||
}
|
||||
defer runtime.Shutdown(false)
|
||||
|
||||
args := c.Args()
|
||||
var killSignal uint = uint(syscall.SIGTERM)
|
||||
var lastError error
|
||||
var pods []*libpod.Pod
|
||||
|
||||
if c.String("signal") != "" {
|
||||
// Check if the signalString provided by the user is valid
|
||||
// Invalid signals will return err
|
||||
sysSignal, err := signal.ParseSignal(c.String("signal"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
killSignal = uint(sysSignal)
|
||||
}
|
||||
|
||||
if c.Bool("all") {
|
||||
pods, err = runtime.Pods()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to get pods")
|
||||
}
|
||||
}
|
||||
if c.Bool("latest") {
|
||||
pod, err := runtime.GetLatestPod()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to get latest pod")
|
||||
}
|
||||
pods = append(pods, pod)
|
||||
}
|
||||
for _, i := range args {
|
||||
pod, err := runtime.LookupPod(i)
|
||||
if err != nil {
|
||||
logrus.Errorf("%q", lastError)
|
||||
if lastError != nil {
|
||||
logrus.Errorf("%q", lastError)
|
||||
}
|
||||
lastError = errors.Wrapf(err, "unable to find pods %s", i)
|
||||
continue
|
||||
}
|
||||
pods = append(pods, pod)
|
||||
}
|
||||
|
||||
for _, pod := range pods {
|
||||
ctr_errs, err := pod.Kill(killSignal)
|
||||
if ctr_errs != nil {
|
||||
for ctr, err := range ctr_errs {
|
||||
if lastError != nil {
|
||||
logrus.Errorf("%q", lastError)
|
||||
}
|
||||
lastError = errors.Wrapf(err, "unable to kill container %q in pod %q", ctr, pod.ID())
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
if lastError != nil {
|
||||
logrus.Errorf("%q", lastError)
|
||||
}
|
||||
lastError = errors.Wrapf(err, "unable to kill pod %q", pod.ID())
|
||||
continue
|
||||
}
|
||||
fmt.Println(pod.ID())
|
||||
}
|
||||
return lastError
|
||||
}
|
@ -31,6 +31,7 @@
|
||||
| [podman-pause(1)](/docs/podman-pause.1.md) | Pause one or more running containers |[](https://asciinema.org/a/141292)|
|
||||
| [podman-pod(1)](/docs/podman-pod.1.md) | Simple management tool for groups of containers, called pods ||
|
||||
| [podman-pod-create(1)](/docs/podman-pod-create.1.md) | Create a new pod ||
|
||||
| [podman-pod-kill(1)](podman-pod-kill.1.md) | Kill the main process of each container in pod. ||
|
||||
| [podman-pod-ps(1)](/docs/podman-pod-ps.1.md) | List the pods on the system ||
|
||||
| [podman-pod-restart](/docs/podman-pod-restart.1.md) | Restart one or more pods ||
|
||||
| [podman-pod-rm(1)](/docs/podman-pod-rm.1.md) | Remove one or more pods ||
|
||||
|
@ -2086,6 +2086,29 @@ _podman_pod_create() {
|
||||
_complete_ "$options_with_args" "$boolean_options"
|
||||
}
|
||||
|
||||
_podman_pod_kill() {
|
||||
local options_with_args="
|
||||
"
|
||||
|
||||
local boolean_options="
|
||||
--all
|
||||
-a
|
||||
--signal
|
||||
-s
|
||||
--latest
|
||||
-l
|
||||
"
|
||||
_complete_ "$options_with_args" "$boolean_options"
|
||||
case "$cur" in
|
||||
-*)
|
||||
COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
|
||||
;;
|
||||
*)
|
||||
__podman_complete_pod_names
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
__podman_pod_ps() {
|
||||
local options_with_args="
|
||||
-f
|
||||
@ -2215,6 +2238,7 @@ _podman_pod() {
|
||||
"
|
||||
subcommands="
|
||||
create
|
||||
kill
|
||||
ps
|
||||
restart
|
||||
rm
|
||||
|
43
docs/podman-pod-kill.1.md
Normal file
43
docs/podman-pod-kill.1.md
Normal file
@ -0,0 +1,43 @@
|
||||
% podman-pod-kill "1"
|
||||
|
||||
## NAME
|
||||
podman\-pod\-kill - Kills all containers in one or more pods with a signal
|
||||
|
||||
## SYNOPSIS
|
||||
**podman pod kill** [*options*] *pod* ...
|
||||
|
||||
## DESCRIPTION
|
||||
The main process of each container inside the pods specified will be sent SIGKILL, or any signal specified with option --signal.
|
||||
|
||||
## OPTIONS
|
||||
**--all, -a**
|
||||
|
||||
Sends signal to all containers associated with a pod.
|
||||
|
||||
**--latest, -l**
|
||||
|
||||
Instead of providing the pod name or ID, use the last created pod. If you use methods other than Podman
|
||||
to run pods such as CRI-O, the last started pod could be from either of those methods.
|
||||
|
||||
**--signal, s**
|
||||
|
||||
Signal to send to the containers in the pod. For more information on Linux signals, refer to *man signal(7)*.
|
||||
|
||||
|
||||
## EXAMPLE
|
||||
|
||||
podman pod kill mywebserver
|
||||
|
||||
podman pod kill 860a4b23
|
||||
|
||||
podman pod kill --signal TERM 860a4b23
|
||||
|
||||
podman pod kill --latest
|
||||
|
||||
podman pod kill --all
|
||||
|
||||
## SEE ALSO
|
||||
podman-pod(1), podman-pod-stop(1)
|
||||
|
||||
## HISTORY
|
||||
July 2018, Originally compiled by Peter Hunt <pehunt@redhat.com>
|
@ -14,6 +14,7 @@ podman pod is a set of subcommands that manage pods, or groups of containers.
|
||||
| Subcommand | Description |
|
||||
| ------------------------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| [podman-pod-create(1)](podman-pod-create.1.md) | Create a new pod. |
|
||||
| [podman-pod-kill(1)](podman-pod-kill.1.md) | Kill the main process of each container in pod. |
|
||||
| [podman-pod-ps(1)](podman-pod-ps.1.md) | Prints out information about pods. |
|
||||
| [podman-pod-rm(1)](podman-pod-rm.1.md) | Remove one or more pods. |
|
||||
| [podman-pod-start(1)](podman-pod-start.1.md) | Start one or more pods. |
|
||||
|
162
test/e2e/pod_kill_test.go
Normal file
162
test/e2e/pod_kill_test.go
Normal file
@ -0,0 +1,162 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Podman pod kill", func() {
|
||||
var (
|
||||
tempdir string
|
||||
err error
|
||||
podmanTest PodmanTest
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
tempdir, err = CreateTempDirInTempDir()
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
podmanTest = PodmanCreate(tempdir)
|
||||
podmanTest.RestoreAllArtifacts()
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
podmanTest.CleanupPod()
|
||||
|
||||
})
|
||||
|
||||
It("podman pod kill bogus", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "kill", "foobar"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Not(Equal(0)))
|
||||
})
|
||||
|
||||
It("podman pod kill a pod by id", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "kill", podid})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
})
|
||||
|
||||
It("podman pod kill a pod by id with TERM", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "kill", "-s", "9", podid})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
})
|
||||
|
||||
It("podman pod kill a pod by name", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "test1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "kill", "test1"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
})
|
||||
|
||||
It("podman pod kill a pod by id with a bogus signal", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "test1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "kill", "-s", "bogus", "test1"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(125))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||
})
|
||||
|
||||
It("podman pod kill latest pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "test1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create", "--name", "test2"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid2 := session.OutputToString()
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid2)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid2)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "kill", "-l"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||
})
|
||||
|
||||
It("podman pod kill all", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "test1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create", "--name", "test2"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid2 := session.OutputToString()
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid2)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "kill", "-a"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user