Skip to content

Commit

Permalink
add --cidfile to container kill
Browse files Browse the repository at this point in the history
Add the ability to read container ids from one or more files for the
kill command.

Fixes: #8443

Signed-off-by: baude <[email protected]>
  • Loading branch information
baude committed Dec 23, 2020
1 parent 54b82a1 commit c81e295
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 5 deletions.
8 changes: 6 additions & 2 deletions cmd/podman/containers/kill.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"

"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v2/cmd/podman/common"
"github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/cmd/podman/utils"
Expand All @@ -22,7 +23,7 @@ var (
Long: killDescription,
RunE: kill,
Args: func(cmd *cobra.Command, args []string) error {
return validate.CheckAllLatestAndCIDFile(cmd, args, false, false)
return validate.CheckAllLatestAndCIDFile(cmd, args, false, true)
},
ValidArgsFunction: common.AutocompleteContainersRunning,
Example: `podman kill mywebserver
Expand All @@ -32,7 +33,7 @@ var (

containerKillCommand = &cobra.Command{
Args: func(cmd *cobra.Command, args []string) error {
return validate.CheckAllLatestAndCIDFile(cmd, args, false, false)
return validate.CheckAllLatestAndCIDFile(cmd, args, false, true)
},
Use: killCommand.Use,
Short: killCommand.Short,
Expand All @@ -57,6 +58,9 @@ func killFlags(cmd *cobra.Command) {
signalFlagName := "signal"
flags.StringVarP(&killOptions.Signal, signalFlagName, "s", "KILL", "Signal to send to the container")
_ = cmd.RegisterFlagCompletionFunc(signalFlagName, common.AutocompleteStopSignal)
cidfileFlagName := "cidfile"
flags.StringArrayVar(&killOptions.CIDFiles, cidfileFlagName, []string{}, "Read the container ID from the file")
_ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
}

func init() {
Expand Down
8 changes: 8 additions & 0 deletions docs/source/markdown/podman-kill.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ The main process inside each container specified will be sent SIGKILL, or any si

Signal all running containers. This does not include paused containers.

#### **--cidfile**

Read container ID from the specified file and remove the container. Can be specified multiple times.

#### **--latest**, **-l**

Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
Expand All @@ -40,6 +44,10 @@ podman kill --latest

podman kill --signal KILL -a

podman kill --cidfile /home/user/cidfile-1

podman kill --cidfile /home/user/cidfile-1 --cidfile ./cidfile-2

## SEE ALSO
podman(1), podman-stop(1)

Expand Down
7 changes: 4 additions & 3 deletions pkg/domain/entities/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,10 @@ type TopOptions struct {
}

type KillOptions struct {
All bool
Latest bool
Signal string
All bool
Latest bool
Signal string
CIDFiles []string
}

type KillReport struct {
Expand Down
9 changes: 9 additions & 0 deletions pkg/domain/infra/abi/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ func (ic *ContainerEngine) pruneContainersHelper(filterFuncs []libpod.ContainerF
}

func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []string, options entities.KillOptions) ([]*entities.KillReport, error) {
for _, cidFile := range options.CIDFiles {
content, err := ioutil.ReadFile(cidFile)
if err != nil {
return nil, errors.Wrap(err, "error reading CIDFile")
}
id := strings.Split(string(content), "\n")[0]
namesOrIds = append(namesOrIds, id)
}
sig, err := signal.ParseSignalNameOrNumber(options.Signal)
if err != nil {
return nil, err
Expand All @@ -246,6 +254,7 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin
}
return reports, nil
}

func (ic *ContainerEngine) ContainerRestart(ctx context.Context, namesOrIds []string, options entities.RestartOptions) ([]*entities.RestartReport, error) {
var (
ctrs []*libpod.Container
Expand Down
8 changes: 8 additions & 0 deletions pkg/domain/infra/tunnel/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
}

func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []string, opts entities.KillOptions) ([]*entities.KillReport, error) {
for _, cidFile := range opts.CIDFiles {
content, err := ioutil.ReadFile(cidFile)
if err != nil {
return nil, errors.Wrap(err, "error reading CIDFile")
}
id := strings.Split(string(content), "\n")[0]
namesOrIds = append(namesOrIds, id)
}
ctrs, err := getContainersByContext(ic.ClientCtx, opts.All, false, namesOrIds)
if err != nil {
return nil, err
Expand Down
55 changes: 55 additions & 0 deletions test/e2e/kill_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package integration

import (
"io/ioutil"
"os"

. "github.com/containers/podman/v2/test/utils"
Expand Down Expand Up @@ -112,4 +113,58 @@ var _ = Describe("Podman kill", func() {
Expect(result.ExitCode()).To(Equal(0))
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
})

It("podman kill --cidfile", func() {
tmpDir, err := ioutil.TempDir("", "")
Expect(err).To(BeNil())
tmpFile := tmpDir + "cid"
defer os.RemoveAll(tmpDir)

session := podmanTest.Podman([]string{"run", "-dt", "--cidfile", tmpFile, ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
cid := session.OutputToStringArray()[0]

kill := podmanTest.Podman([]string{"kill", "--cidfile", tmpFile})
kill.WaitWithDefaultTimeout()
Expect(kill.ExitCode()).To(BeZero())

wait := podmanTest.Podman([]string{"wait", "--condition", "exited", cid})
wait.WaitWithDefaultTimeout()
Expect(wait.ExitCode()).To(BeZero())
})

It("podman kill multiple --cidfile", func() {
tmpDir1, err := ioutil.TempDir("", "")
Expect(err).To(BeNil())
tmpFile1 := tmpDir1 + "cid"
defer os.RemoveAll(tmpDir1)

tmpDir2, err := ioutil.TempDir("", "")
Expect(err).To(BeNil())
tmpFile2 := tmpDir2 + "cid"
defer os.RemoveAll(tmpDir2)

session := podmanTest.Podman([]string{"run", "-dt", "--cidfile", tmpFile1, ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
cid1 := session.OutputToStringArray()[0]

session2 := podmanTest.Podman([]string{"run", "-dt", "--cidfile", tmpFile2, ALPINE, "top"})
session2.WaitWithDefaultTimeout()
Expect(session2.ExitCode()).To(Equal(0))
cid2 := session2.OutputToStringArray()[0]

kill := podmanTest.Podman([]string{"kill", "--cidfile", tmpFile1, "--cidfile", tmpFile2})
kill.WaitWithDefaultTimeout()
Expect(kill.ExitCode()).To(BeZero())

wait := podmanTest.Podman([]string{"wait", "--condition", "exited", cid1})
wait.WaitWithDefaultTimeout()
Expect(wait.ExitCode()).To(BeZero())
wait = podmanTest.Podman([]string{"wait", "--condition", "exited", cid2})
wait.WaitWithDefaultTimeout()
Expect(wait.ExitCode()).To(BeZero())
})

})

0 comments on commit c81e295

Please sign in to comment.