diff options
author | Matthew Heon <matthew.heon@pm.me> | 2020-06-05 16:09:26 -0400 |
---|---|---|
committer | Matthew Heon <matthew.heon@pm.me> | 2020-06-05 16:18:53 -0400 |
commit | 1cc9731dfad9ec06ab162ce432c82ec4d675e60e (patch) | |
tree | c082c765c3463f53d80b729de596266e5f24301f /pkg/domain | |
parent | 723e8234393fba230961bc1214a73ba5d01bbfe1 (diff) | |
download | podman-1cc9731dfad9ec06ab162ce432c82ec4d675e60e.tar.gz podman-1cc9731dfad9ec06ab162ce432c82ec4d675e60e.tar.bz2 podman-1cc9731dfad9ec06ab162ce432c82ec4d675e60e.zip |
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>
Diffstat (limited to 'pkg/domain')
-rw-r--r-- | pkg/domain/entities/containers.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 47 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 2 |
3 files changed, 26 insertions, 25 deletions
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index 8d85a9b23..2363e6677 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -84,7 +84,7 @@ type StopOptions struct { CIDFiles []string Ignore bool Latest bool - Timeout uint + Timeout *uint } type StopReport struct { diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index eb45d4630..043fcfe7e 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -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) + 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() + } 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 + 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 } - 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 } - reports = append(reports, &report) + 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 } diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 36b7bf535..1981055e2 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -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) |