mirror of
https://github.com/containers/podman.git
synced 2025-07-03 17:27:18 +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,
|
UseShortOptionHandling: true,
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
podCreateCommand,
|
podCreateCommand,
|
||||||
|
podKillCommand,
|
||||||
podPsCommand,
|
podPsCommand,
|
||||||
podRestartCommand,
|
podRestartCommand,
|
||||||
podRmCommand,
|
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-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(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-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-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-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 ||
|
| [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"
|
_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() {
|
__podman_pod_ps() {
|
||||||
local options_with_args="
|
local options_with_args="
|
||||||
-f
|
-f
|
||||||
@ -2215,6 +2238,7 @@ _podman_pod() {
|
|||||||
"
|
"
|
||||||
subcommands="
|
subcommands="
|
||||||
create
|
create
|
||||||
|
kill
|
||||||
ps
|
ps
|
||||||
restart
|
restart
|
||||||
rm
|
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 |
|
| Subcommand | Description |
|
||||||
| ------------------------------------------------- | ------------------------------------------------------------------------------ |
|
| ------------------------------------------------- | ------------------------------------------------------------------------------ |
|
||||||
| [podman-pod-create(1)](podman-pod-create.1.md) | Create a new pod. |
|
| [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-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-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. |
|
| [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