From a4cef543504600db95453aa863b97ed82c833d41 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Wed, 12 Jan 2022 15:33:00 +0100 Subject: podman container rm: remove pod Support removing the entire pod when --depend is used on an infra container. --all now implies --depend to properly support removing all containers and not error out when hitting infra containers. Signed-off-by: Valentin Rothberg --- pkg/domain/infra/abi/containers.go | 34 ++++++++++++++++++++++++- pkg/domain/infra/tunnel/containers.go | 48 ++++++++++++++++++++++++----------- 2 files changed, 66 insertions(+), 16 deletions(-) (limited to 'pkg') diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index a4522698e..afd25d313 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -357,24 +357,56 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, return rmReports, nil } + alreadyRemoved := make(map[string]bool) + addReports := func(newReports []*reports.RmReport) { + for i := range newReports { + alreadyRemoved[newReports[i].Id] = true + rmReports = append(rmReports, newReports[i]) + } + } if !options.All && options.Depend { // Add additional containers based on dependencies to container map for _, ctr := range ctrs { + if alreadyRemoved[ctr.ID()] { + continue + } reports, err := ic.Libpod.RemoveDepend(ctx, ctr, options.Force, options.Volumes, options.Timeout) if err != nil { return rmReports, err } - rmReports = append(rmReports, reports...) + addReports(reports) } return rmReports, nil } + + // If --all is set, make sure to remove the infra containers' + // dependencies before doing the parallel removal below. + if options.All { + for _, ctr := range ctrs { + if alreadyRemoved[ctr.ID()] || !ctr.IsInfra() { + continue + } + reports, err := ic.Libpod.RemoveDepend(ctx, ctr, options.Force, options.Volumes, options.Timeout) + if err != nil { + return rmReports, err + } + addReports(reports) + } + } + errMap, err := parallelctr.ContainerOp(ctx, ctrs, func(c *libpod.Container) error { + if alreadyRemoved[c.ID()] { + return nil + } return ic.removeContainer(ctx, c, options) }) if err != nil { return nil, err } for ctr, err := range errMap { + if alreadyRemoved[ctr.ID()] { + continue + } report := new(reports.RmReport) report.Id = ctr.ID() report.Err = err diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 4f72eab96..ae689f1f7 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -188,35 +188,53 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, if opts.Timeout != nil { options = options.WithTimeout(*opts.Timeout) } + + toRemove := []string{} + alreadyRemoved := make(map[string]bool) // Avoids trying to remove already removed containers if opts.All { - ctrs, err := getContainersByContext(ic.ClientCtx, opts.All, opts.Ignore, namesOrIds) + ctrs, err := getContainersByContext(ic.ClientCtx, opts.All, opts.Ignore, nil) if err != nil { return nil, err } - rmReports := make([]*reports.RmReport, 0, len(ctrs)) for _, c := range ctrs { - report, err := containers.Remove(ic.ClientCtx, c.ID, options) + toRemove = append(toRemove, c.ID) + } + } else { + for _, ctr := range namesOrIds { + // NOTE that we set ignore=true here to support + // removing external containers (e.g., Buildah + // containers). If we don't find the container, + // we'll use the raw input provided by the user + // instead of the ID. Since this can only happen + // with external containers, it poses no threat + // to the `alreadyRemoved` checks below. + ctrs, err := getContainersByContext(ic.ClientCtx, false, true, []string{ctr}) if err != nil { - return rmReports, err + return nil, err } - rmReports = append(rmReports, report...) + id := ctr + if len(ctrs) == 1 { + id = ctrs[0].ID + } + toRemove = append(toRemove, id) } - return rmReports, nil } - rmReports := make([]*reports.RmReport, 0, len(namesOrIds)) - for _, name := range namesOrIds { - report, err := containers.Remove(ic.ClientCtx, name, options) + rmReports := make([]*reports.RmReport, 0, len(toRemove)) + for _, nameOrID := range toRemove { + if alreadyRemoved[nameOrID] { + continue + } + newReports, err := containers.Remove(ic.ClientCtx, nameOrID, options) if err != nil { - rmReports = append(rmReports, &reports.RmReport{ - Id: name, - Err: err, - }) + rmReports = append(rmReports, &reports.RmReport{Id: nameOrID, Err: err}) continue } - rmReports = append(rmReports, report...) + for i := range newReports { + alreadyRemoved[newReports[i].Id] = true + rmReports = append(rmReports, newReports[i]) + } } - return rmReports, nil } -- cgit v1.2.3-54-g00ecf