Skip to content

Commit

Permalink
Merge pull request #11763 from rhatdan/timeout
Browse files Browse the repository at this point in the history
Add --time option for podman * rm -f flag
  • Loading branch information
openshift-merge-robot authored Oct 4, 2021
2 parents 2f72f17 + 21c9dc3 commit a866a2f
Show file tree
Hide file tree
Showing 81 changed files with 346 additions and 196 deletions.
9 changes: 9 additions & 0 deletions cmd/podman/containers/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ func rmFlags(cmd *cobra.Command) {
flags.BoolVarP(&rmOptions.All, "all", "a", false, "Remove all containers")
flags.BoolVarP(&rmOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing")
flags.BoolVarP(&rmOptions.Force, "force", "f", false, "Force removal of a running or unusable container. The default is false")
timeFlagName := "time"
flags.UintVarP(&stopTimeout, timeFlagName, "t", containerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container")
_ = cmd.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone)
flags.BoolVarP(&rmOptions.Volumes, "volumes", "v", false, "Remove anonymous volumes associated with the container")

cidfileFlagName := "cidfile"
Expand Down Expand Up @@ -91,6 +94,12 @@ func init() {
}

func rm(cmd *cobra.Command, args []string) error {
if cmd.Flag("time").Changed {
if !rmOptions.Force {
return errors.New("--force option must be specified to use the --time option")
}
rmOptions.Timeout = &stopTimeout
}
for _, cidFile := range cidFiles {
content, err := ioutil.ReadFile(string(cidFile))
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions cmd/podman/networks/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package network
import (
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/util"
"github.com/spf13/cobra"
)

Expand All @@ -17,6 +18,7 @@ var (
Long: "Manage networks",
RunE: validate.SubCommandExists,
}
containerConfig = util.DefaultContainerConfig()
)

func init() {
Expand Down
11 changes: 11 additions & 0 deletions cmd/podman/networks/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"strings"

"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/utils"
Expand All @@ -26,6 +27,7 @@ var (
Args: cobra.MinimumNArgs(1),
ValidArgsFunction: common.AutocompleteNetworks,
}
stopTimeout uint
)

var (
Expand All @@ -34,6 +36,9 @@ var (

func networkRmFlags(flags *pflag.FlagSet) {
flags.BoolVarP(&networkRmOptions.Force, "force", "f", false, "remove any containers using network")
timeFlagName := "time"
flags.UintVarP(&stopTimeout, timeFlagName, "t", containerConfig.Engine.StopTimeout, "Seconds to wait for running containers to stop before killing the container")
_ = networkrmCommand.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone)
}

func init() {
Expand All @@ -50,6 +55,12 @@ func networkRm(cmd *cobra.Command, args []string) error {
errs utils.OutputErrors
)

if cmd.Flag("time").Changed {
if !networkRmOptions.Force {
return errors.New("--force option must be specified to use the --time option")
}
networkRmOptions.Timeout = &stopTimeout
}
responses, err := registry.ContainerEngine().NetworkRm(registry.Context(), args, networkRmOptions)
if err != nil {
setExitCode(err)
Expand Down
13 changes: 12 additions & 1 deletion cmd/podman/pods/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var (
podman pod rm -f 860a4b23
podman pod rm -f -a`,
}
stopTimeout uint
)

func init() {
Expand All @@ -59,19 +60,29 @@ func init() {
flags.StringArrayVarP(&rmOptions.PodIDFiles, podIDFileFlagName, "", nil, "Read the pod ID from the file")
_ = rmCommand.RegisterFlagCompletionFunc(podIDFileFlagName, completion.AutocompleteDefault)

timeFlagName := "time"
flags.UintVarP(&stopTimeout, timeFlagName, "t", containerConfig.Engine.StopTimeout, "Seconds to wait for pod stop before killing the container")
_ = rmCommand.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone)

validate.AddLatestFlag(rmCommand, &rmOptions.Latest)

if registry.IsRemote() {
_ = flags.MarkHidden("ignore")
}
}

func rm(_ *cobra.Command, args []string) error {
func rm(cmd *cobra.Command, args []string) error {
ids, err := specgenutil.ReadPodIDFiles(rmOptions.PodIDFiles)
if err != nil {
return err
}
args = append(args, ids...)
if cmd.Flag("time").Changed {
if !rmOptions.Force {
return errors.New("--force option must be specified to use the --time option")
}
rmOptions.Timeout = &stopTimeout
}
return removePods(args, rmOptions.PodRmOptions, true)
}

Expand Down
13 changes: 12 additions & 1 deletion cmd/podman/volumes/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"strings"

"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/utils"
Expand Down Expand Up @@ -32,7 +33,8 @@ var (
)

var (
rmOptions = entities.VolumeRmOptions{}
rmOptions = entities.VolumeRmOptions{}
stopTimeout uint
)

func init() {
Expand All @@ -43,6 +45,9 @@ func init() {
flags := rmCommand.Flags()
flags.BoolVarP(&rmOptions.All, "all", "a", false, "Remove all volumes")
flags.BoolVarP(&rmOptions.Force, "force", "f", false, "Remove a volume by force, even if it is being used by a container")
timeFlagName := "time"
flags.UintVarP(&stopTimeout, timeFlagName, "t", containerConfig.Engine.StopTimeout, "Seconds to wait for running containers to stop before killing the container")
_ = rmCommand.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone)
}

func rm(cmd *cobra.Command, args []string) error {
Expand All @@ -52,6 +57,12 @@ func rm(cmd *cobra.Command, args []string) error {
if (len(args) > 0 && rmOptions.All) || (len(args) < 1 && !rmOptions.All) {
return errors.New("choose either one or more volumes or all")
}
if cmd.Flag("time").Changed {
if !rmOptions.Force {
return errors.New("--force option must be specified to use the --time option")
}
rmOptions.Timeout = &stopTimeout
}
responses, err := registry.ContainerEngine().VolumeRm(context.Background(), args, rmOptions)
if err != nil {
setExitCode(err)
Expand Down
2 changes: 2 additions & 0 deletions cmd/podman/volumes/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package volumes
import (
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/util"
"github.com/spf13/cobra"
)

Expand All @@ -17,6 +18,7 @@ var (
Long: "Volumes are created in and can be shared between containers",
RunE: validate.SubCommandExists,
}
containerConfig = util.DefaultContainerConfig()
)

func init() {
Expand Down
4 changes: 4 additions & 0 deletions docs/source/markdown/podman-network-rm.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ Delete one or more Podman networks.
The `force` option will remove all containers that use the named network. If the container is
running, the container will be stopped and removed.

#### **--time**, **-t**=*seconds*

Seconds to wait before forcibly stopping the running containers that are using the specified network. The --force option must be specified to use the --time option.

## EXAMPLE

Delete the `cni-podman9` network
Expand Down
4 changes: 4 additions & 0 deletions docs/source/markdown/podman-pod-rm.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ Stop running containers and delete all stopped containers before removal of pod.

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

#### **--time**, **-t**=*seconds*

Seconds to wait before forcibly stopping running containers within the pod. The --force option must be specified to use the --time option.

## EXAMPLE

podman pod rm mywebserverpod
Expand Down
4 changes: 2 additions & 2 deletions docs/source/markdown/podman-pod-stop.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ ExecStop directive of a systemd service referencing that pod.

Instead of providing the pod name or ID, stop the last created pod. (This option is not available with the remote Podman client)

#### **--time**, **-t**=*time*
#### **--time**, **-t**=*seconds*

Timeout to wait before forcibly stopping the containers in the pod.
Seconds to wait before forcibly stopping the containers in the pod.

#### **--pod-id-file**

Expand Down
4 changes: 2 additions & 2 deletions docs/source/markdown/podman-restart.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ to run containers such as CRI-O, the last started container could be from either
#### **--running**
Restart all containers that are already in the *running* state.

#### **--time**=*time*, **-t**
Timeout to wait before forcibly stopping the container.
#### **--time**, **-t**=*seconds*

Seconds to wait before forcibly stopping the container.

## EXAMPLES

Expand Down
4 changes: 4 additions & 0 deletions docs/source/markdown/podman-rm.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ during the ExecStop directive of a systemd service referencing that container.
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods. (This option is not available with the remote Podman client)

#### **--time**, **-t**=*seconds*

Seconds to wait before forcibly stopping the container. The --force option must be specified to use the --time option.

#### **--volumes**, **-v**

Remove anonymous volumes associated with the container. This does not include named volumes
Expand Down
4 changes: 2 additions & 2 deletions docs/source/markdown/podman-stop.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ during the ExecStop directive of a systemd service referencing that container.
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods. (This option is not available with the remote Podman client)

#### **--time**, **-t**=*time*
#### **--time**, **-t**=*seconds*

Time to wait before forcibly stopping the container
Seconds to wait before forcibly stopping the container

## EXAMPLES

Expand Down
3 changes: 3 additions & 0 deletions docs/source/markdown/podman-volume-rm.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ If it is being used by containers, the containers will be removed first.

Print usage statement

#### **--time**, **-t**=*seconds*

Seconds to wait before forcibly stopping running containers that are using the specified volume. The --force option must be specified to use the --time option.

## EXAMPLES

Expand Down
3 changes: 2 additions & 1 deletion libpod/pod_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ func (p *Pod) startInitContainers(ctx context.Context) error {
if initCon.config.InitContainerType == define.OneShotInitContainer {
icLock := initCon.lock
icLock.Lock()
if err := p.runtime.removeContainer(ctx, initCon, false, false, true); err != nil {
var time *uint
if err := p.runtime.removeContainer(ctx, initCon, false, false, true, time); err != nil {
icLock.Unlock()
return errors.Wrapf(err, "failed to remove once init container %s", initCon.ID())
}
Expand Down
7 changes: 4 additions & 3 deletions libpod/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ import (

// Reset removes all storage
func (r *Runtime) Reset(ctx context.Context) error {
var timeout *uint
pods, err := r.GetAllPods()
if err != nil {
return err
}
for _, p := range pods {
if err := r.RemovePod(ctx, p, true, true); err != nil {
if err := r.RemovePod(ctx, p, true, true, timeout); err != nil {
if errors.Cause(err) == define.ErrNoSuchPod {
continue
}
Expand All @@ -37,7 +38,7 @@ func (r *Runtime) Reset(ctx context.Context) error {
}

for _, c := range ctrs {
if err := r.RemoveContainer(ctx, c, true, true); err != nil {
if err := r.RemoveContainer(ctx, c, true, true, timeout); err != nil {
if err := r.RemoveStorageContainer(c.ID(), true); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
continue
Expand All @@ -61,7 +62,7 @@ func (r *Runtime) Reset(ctx context.Context) error {
return err
}
for _, v := range volumes {
if err := r.RemoveVolume(ctx, v, true); err != nil {
if err := r.RemoveVolume(ctx, v, true, timeout); err != nil {
if errors.Cause(err) == define.ErrNoSuchVolume {
continue
}
Expand Down
22 changes: 14 additions & 8 deletions libpod/runtime_ctr.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,18 +535,18 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
// If removeVolume is specified, named volumes used by the container will
// be removed also if and only if the container is the sole user
// Otherwise, RemoveContainer will return an error if the container is running
func (r *Runtime) RemoveContainer(ctx context.Context, c *Container, force bool, removeVolume bool) error {
func (r *Runtime) RemoveContainer(ctx context.Context, c *Container, force bool, removeVolume bool, timeout *uint) error {
r.lock.Lock()
defer r.lock.Unlock()
return r.removeContainer(ctx, c, force, removeVolume, false)
return r.removeContainer(ctx, c, force, removeVolume, false, timeout)
}

// Internal function to remove a container.
// Locks the container, but does not lock the runtime.
// removePod is used only when removing pods. It instructs Podman to ignore
// infra container protections, and *not* remove from the database (as pod
// remove will handle that).
func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, removeVolume, removePod bool) error {
func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, removeVolume, removePod bool, timeout *uint) error {
if !c.valid {
if ok, _ := r.state.HasContainer(c.ID()); !ok {
// Container probably already removed
Expand Down Expand Up @@ -642,9 +642,13 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo

// Check that the container's in a good state to be removed.
if c.state.State == define.ContainerStateRunning {
time := c.StopTimeout()
if timeout != nil {
time = *timeout
}
// Ignore ErrConmonDead - we couldn't retrieve the container's
// exit code properly, but it's still stopped.
if err := c.stop(c.StopTimeout()); err != nil && errors.Cause(err) != define.ErrConmonDead {
if err := c.stop(time); err != nil && errors.Cause(err) != define.ErrConmonDead {
return errors.Wrapf(err, "cannot remove container %s as it could not be stopped", c.ID())
}

Expand Down Expand Up @@ -751,7 +755,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
if !volume.Anonymous() {
continue
}
if err := runtime.removeVolume(ctx, volume, false); err != nil && errors.Cause(err) != define.ErrNoSuchVolume {
if err := runtime.removeVolume(ctx, volume, false, timeout); err != nil && errors.Cause(err) != define.ErrNoSuchVolume {
logrus.Errorf("Cleanup volume (%s): %v", v, err)
}
}
Expand Down Expand Up @@ -782,6 +786,7 @@ func (r *Runtime) EvictContainer(ctx context.Context, idOrName string, removeVol
// remove will handle that).
func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVolume bool) (string, error) {
var err error
var timeout *uint

if !r.valid {
return "", define.ErrRuntimeStopped
Expand All @@ -797,7 +802,7 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol
if err == nil {
logrus.Infof("Container %s successfully retrieved from state, attempting normal removal", id)
// Assume force = true for the evict case
err = r.removeContainer(ctx, tmpCtr, true, removeVolume, false)
err = r.removeContainer(ctx, tmpCtr, true, removeVolume, false, timeout)
if !tmpCtr.valid {
// If the container is marked invalid, remove succeeded
// in kicking it out of the state - no need to continue.
Expand Down Expand Up @@ -892,7 +897,7 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol
if !volume.Anonymous() {
continue
}
if err := r.removeVolume(ctx, volume, false); err != nil && err != define.ErrNoSuchVolume && err != define.ErrVolumeBeingUsed {
if err := r.removeVolume(ctx, volume, false, timeout); err != nil && err != define.ErrNoSuchVolume && err != define.ErrVolumeBeingUsed {
logrus.Errorf("Cleanup volume (%s): %v", v, err)
}
}
Expand Down Expand Up @@ -1089,7 +1094,8 @@ func (r *Runtime) PruneContainers(filterFuncs []ContainerFilter) ([]*reports.Pru
preports = append(preports, report)
continue
}
err = r.RemoveContainer(context.Background(), c, false, false)
var time *uint
err = r.RemoveContainer(context.Background(), c, false, false, time)
if err != nil {
report.Err = err
} else {
Expand Down
3 changes: 2 additions & 1 deletion libpod/runtime_img.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ func (r *Runtime) RemoveContainersForImageCallback(ctx context.Context) libimage
}
for _, ctr := range ctrs {
if ctr.config.RootfsImageID == imageID {
if err := r.removeContainer(ctx, ctr, true, false, false); err != nil {
var timeout *uint
if err := r.removeContainer(ctx, ctr, true, false, false, timeout); err != nil {
return errors.Wrapf(err, "error removing image %s: container %s using image could not be removed", imageID, ctr.ID())
}
}
Expand Down
Loading

0 comments on commit a866a2f

Please sign in to comment.