mirror of
https://github.com/containers/podman.git
synced 2025-06-19 16:33:24 +08:00
Add parallel operation to podman stop
This is the other command that benefits greatly from being run in parallel, due to the potential 15-second timeout for containers that ignore SIGTERM. While we're at it, also clean up how stop timeout is set. This needs to be an optional parameter, so that the value set when the container is created with `--stop-timeout` will be respected. Signed-off-by: Matthew Heon <matthew.heon@pm.me>
This commit is contained in:
@ -85,9 +85,8 @@ func stop(cmd *cobra.Command, args []string) error {
|
||||
var (
|
||||
errs utils.OutputErrors
|
||||
)
|
||||
stopOptions.Timeout = containerConfig.Engine.StopTimeout
|
||||
if cmd.Flag("time").Changed {
|
||||
stopOptions.Timeout = stopTimeout
|
||||
stopOptions.Timeout = &stopTimeout
|
||||
}
|
||||
|
||||
responses, err := registry.ContainerEngine().ContainerStop(context.Background(), args, stopOptions)
|
||||
|
@ -84,7 +84,7 @@ type StopOptions struct {
|
||||
CIDFiles []string
|
||||
Ignore bool
|
||||
Latest bool
|
||||
Timeout uint
|
||||
Timeout *uint
|
||||
}
|
||||
|
||||
type StopReport struct {
|
||||
|
@ -162,32 +162,33 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
|
||||
if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr) {
|
||||
return nil, err
|
||||
}
|
||||
for _, con := range ctrs {
|
||||
report := entities.StopReport{Id: con.ID()}
|
||||
err = con.StopWithTimeout(options.Timeout)
|
||||
if err != nil {
|
||||
// These first two are considered non-fatal under the right conditions
|
||||
if errors.Cause(err) == define.ErrCtrStopped {
|
||||
logrus.Debugf("Container %s is already stopped", con.ID())
|
||||
reports = append(reports, &report)
|
||||
continue
|
||||
|
||||
} else if options.All && errors.Cause(err) == define.ErrCtrStateInvalid {
|
||||
logrus.Debugf("Container %s is not running, could not stop", con.ID())
|
||||
reports = append(reports, &report)
|
||||
continue
|
||||
}
|
||||
report.Err = err
|
||||
reports = append(reports, &report)
|
||||
continue
|
||||
} else if err := con.Cleanup(ctx); err != nil {
|
||||
// Only if no error, proceed to cleanup to ensure all
|
||||
// mounts are removed before we exit.
|
||||
report.Err = err
|
||||
reports = append(reports, &report)
|
||||
continue
|
||||
errMap, err := parallel.ParallelContainerOp(ctx, ctrs, func(c *libpod.Container) error {
|
||||
var err error
|
||||
if options.Timeout != nil {
|
||||
err = c.StopWithTimeout(*options.Timeout)
|
||||
} else {
|
||||
err = c.Stop()
|
||||
}
|
||||
reports = append(reports, &report)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Cause(err) == define.ErrCtrStopped:
|
||||
logrus.Debugf("Container %s is already stopped", c.ID())
|
||||
case options.All && errors.Cause(err) == define.ErrCtrStateInvalid:
|
||||
logrus.Debugf("Container %s is not running, could not stop", c.ID())
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
return c.Cleanup(ctx)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for ctr, err := range errMap {
|
||||
report := new(entities.StopReport)
|
||||
report.Id = ctr.ID()
|
||||
report.Err = err
|
||||
reports = append(reports, report)
|
||||
}
|
||||
return reports, nil
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
|
||||
}
|
||||
for _, c := range ctrs {
|
||||
report := entities.StopReport{Id: c.ID}
|
||||
if err = containers.Stop(ic.ClientCxt, c.ID, &options.Timeout); err != nil {
|
||||
if err = containers.Stop(ic.ClientCxt, c.ID, options.Timeout); err != nil {
|
||||
// These first two are considered non-fatal under the right conditions
|
||||
if errors.Cause(err).Error() == define.ErrCtrStopped.Error() {
|
||||
logrus.Debugf("Container %s is already stopped", c.ID)
|
||||
|
Reference in New Issue
Block a user