summaryrefslogtreecommitdiff
path: root/pkg/domain
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2021-12-23 06:41:55 -0500
committerDaniel J Walsh <dwalsh@redhat.com>2022-01-11 14:33:54 -0500
commit8f2358eeaa59fe369eebc6186403f95c2d66e49b (patch)
treea454ef259ab28f85b17f53b3273725480aa78515 /pkg/domain
parentc4142ce0cfff792092bf420950b1985058cc241c (diff)
downloadpodman-8f2358eeaa59fe369eebc6186403f95c2d66e49b.tar.gz
podman-8f2358eeaa59fe369eebc6186403f95c2d66e49b.tar.bz2
podman-8f2358eeaa59fe369eebc6186403f95c2d66e49b.zip
Add podman rm --depend
This option causes Podman to not only remove the specified containers but all of the containers that depend on the specified containers. Fixes: https://github.com/containers/podman/issues/10360 Also ran codespell on the code Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'pkg/domain')
-rw-r--r--pkg/domain/entities/containers.go6
-rw-r--r--pkg/domain/entities/engine_container.go2
-rw-r--r--pkg/domain/entities/reports/containers.go28
-rw-r--r--pkg/domain/infra/abi/containers.go37
-rw-r--r--pkg/domain/infra/tunnel/containers.go90
5 files changed, 103 insertions, 60 deletions
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index ae441b7f3..e3f8f1b7c 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -129,6 +129,7 @@ type RestartReport struct {
type RmOptions struct {
All bool
+ Depend bool
Force bool
Ignore bool
Latest bool
@@ -136,11 +137,6 @@ type RmOptions struct {
Volumes bool
}
-type RmReport struct {
- Err error
- Id string //nolint
-}
-
type ContainerInspectReport struct {
*define.InspectContainerData
}
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 383e42098..7ce4dd0f6 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -40,7 +40,7 @@ type ContainerEngine interface {
ContainerRename(ctr context.Context, nameOrID string, options ContainerRenameOptions) error
ContainerRestart(ctx context.Context, namesOrIds []string, options RestartOptions) ([]*RestartReport, error)
ContainerRestore(ctx context.Context, namesOrIds []string, options RestoreOptions) ([]*RestoreReport, error)
- ContainerRm(ctx context.Context, namesOrIds []string, options RmOptions) ([]*RmReport, error)
+ ContainerRm(ctx context.Context, namesOrIds []string, options RmOptions) ([]*reports.RmReport, error)
ContainerRun(ctx context.Context, opts ContainerRunOptions) (*ContainerRunReport, error)
ContainerRunlabel(ctx context.Context, label string, image string, args []string, opts ContainerRunlabelOptions) error
ContainerStart(ctx context.Context, namesOrIds []string, options ContainerStartOptions) ([]*ContainerStartReport, error)
diff --git a/pkg/domain/entities/reports/containers.go b/pkg/domain/entities/reports/containers.go
new file mode 100644
index 000000000..54bcd092b
--- /dev/null
+++ b/pkg/domain/entities/reports/containers.go
@@ -0,0 +1,28 @@
+package reports
+
+type RmReport struct {
+ Id string `json:"Id"` //nolint
+ Err error `json:"Err,omitempty"`
+}
+
+func RmReportsIds(r []*RmReport) []string {
+ ids := make([]string, 0, len(r))
+ for _, v := range r {
+ if v == nil || v.Id == "" {
+ continue
+ }
+ ids = append(ids, v.Id)
+ }
+ return ids
+}
+
+func RmReportsErrs(r []*RmReport) []error {
+ errs := make([]error, 0, len(r))
+ for _, v := range r {
+ if v == nil || v.Err == nil {
+ continue
+ }
+ errs = append(errs, v.Err)
+ }
+ return errs
+}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index bf4dcff62..a4522698e 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -301,27 +301,27 @@ func (ic *ContainerEngine) removeContainer(ctx context.Context, ctr *libpod.Cont
return err
}
-func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, options entities.RmOptions) ([]*entities.RmReport, error) {
- reports := []*entities.RmReport{}
+func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, options entities.RmOptions) ([]*reports.RmReport, error) {
+ rmReports := []*reports.RmReport{}
names := namesOrIds
// Attempt to remove named containers directly from storage, if container is defined in libpod
// this will fail and code will fall through to removing the container from libpod.`
tmpNames := []string{}
for _, ctr := range names {
- report := entities.RmReport{Id: ctr}
+ report := reports.RmReport{Id: ctr}
report.Err = ic.Libpod.RemoveStorageContainer(ctr, options.Force)
switch errors.Cause(report.Err) {
case nil:
// remove container names that we successfully deleted
- reports = append(reports, &report)
+ rmReports = append(rmReports, &report)
case define.ErrNoSuchCtr, define.ErrCtrExists:
// There is still a potential this is a libpod container
tmpNames = append(tmpNames, ctr)
default:
if _, err := ic.Libpod.LookupContainer(ctr); errors.Cause(err) == define.ErrNoSuchCtr {
// remove container failed, but not a libpod container
- reports = append(reports, &report)
+ rmReports = append(rmReports, &report)
continue
}
// attempt to remove as a libpod container
@@ -340,23 +340,34 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
for _, ctr := range names {
logrus.Debugf("Evicting container %q", ctr)
- report := entities.RmReport{Id: ctr}
+ report := reports.RmReport{Id: ctr}
_, err := ic.Libpod.EvictContainer(ctx, ctr, options.Volumes)
if err != nil {
if options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr {
logrus.Debugf("Ignoring error (--allow-missing): %v", err)
- reports = append(reports, &report)
+ rmReports = append(rmReports, &report)
continue
}
report.Err = err
- reports = append(reports, &report)
+ rmReports = append(rmReports, &report)
continue
}
- reports = append(reports, &report)
+ rmReports = append(rmReports, &report)
}
- return reports, nil
+ return rmReports, nil
}
+ if !options.All && options.Depend {
+ // Add additional containers based on dependencies to container map
+ for _, ctr := range ctrs {
+ reports, err := ic.Libpod.RemoveDepend(ctx, ctr, options.Force, options.Volumes, options.Timeout)
+ if err != nil {
+ return rmReports, err
+ }
+ rmReports = append(rmReports, reports...)
+ }
+ return rmReports, nil
+ }
errMap, err := parallelctr.ContainerOp(ctx, ctrs, func(c *libpod.Container) error {
return ic.removeContainer(ctx, c, options)
})
@@ -364,12 +375,12 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
return nil, err
}
for ctr, err := range errMap {
- report := new(entities.RmReport)
+ report := new(reports.RmReport)
report.Id = ctr.ID()
report.Err = err
- reports = append(reports, report)
+ rmReports = append(rmReports, report)
}
- return reports, nil
+ return rmReports, nil
}
func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, []error, error) {
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 2127f8749..4f72eab96 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -182,9 +182,9 @@ func (ic *ContainerEngine) ContainerRestart(ctx context.Context, namesOrIds []st
return reports, nil
}
-func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, opts entities.RmOptions) ([]*entities.RmReport, error) {
+func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, opts entities.RmOptions) ([]*reports.RmReport, error) {
// TODO there is no endpoint for container eviction. Need to discuss
- options := new(containers.RemoveOptions).WithForce(opts.Force).WithVolumes(opts.Volumes).WithIgnore(opts.Ignore)
+ options := new(containers.RemoveOptions).WithForce(opts.Force).WithVolumes(opts.Volumes).WithIgnore(opts.Ignore).WithDepend(opts.Depend)
if opts.Timeout != nil {
options = options.WithTimeout(*opts.Timeout)
}
@@ -193,25 +193,31 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
if err != nil {
return nil, err
}
- reports := make([]*entities.RmReport, 0, len(ctrs))
+ rmReports := make([]*reports.RmReport, 0, len(ctrs))
for _, c := range ctrs {
- reports = append(reports, &entities.RmReport{
- Id: c.ID,
- Err: containers.Remove(ic.ClientCtx, c.ID, options),
- })
+ report, err := containers.Remove(ic.ClientCtx, c.ID, options)
+ if err != nil {
+ return rmReports, err
+ }
+ rmReports = append(rmReports, report...)
}
- return reports, nil
+ return rmReports, nil
}
- reports := make([]*entities.RmReport, 0, len(namesOrIds))
+ rmReports := make([]*reports.RmReport, 0, len(namesOrIds))
for _, name := range namesOrIds {
- reports = append(reports, &entities.RmReport{
- Id: name,
- Err: containers.Remove(ic.ClientCtx, name, options),
- })
+ report, err := containers.Remove(ic.ClientCtx, name, options)
+ if err != nil {
+ rmReports = append(rmReports, &reports.RmReport{
+ Id: name,
+ Err: err,
+ })
+ continue
+ }
+ rmReports = append(rmReports, report...)
}
- return reports, nil
+ return rmReports, nil
}
func (ic *ContainerEngine) ContainerPrune(ctx context.Context, opts entities.ContainerPruneOptions) ([]*reports.PruneReport, error) {
@@ -552,6 +558,27 @@ func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input,
return <-attachErr
}
+func logIfRmError(id string, err error, reports []*reports.RmReport) {
+ logError := func(id string, err error) {
+ if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
+ errorhandling.Contains(err, define.ErrCtrRemoved) ||
+ errorhandling.Contains(err, types.ErrLayerUnknown) {
+ logrus.Debugf("Container %s does not exist: %v", id, err)
+ } else {
+ logrus.Errorf("Removing container %s: %v", id, err)
+ }
+ }
+ if err != nil {
+ logError(id, err)
+ } else {
+ for _, report := range reports {
+ if report.Err != nil {
+ logError(report.Id, report.Err)
+ }
+ }
+ }
+}
+
func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) {
reports := []*entities.ContainerStartReport{}
var exitCode = define.ExecErrorCodeGeneric
@@ -590,14 +617,8 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
}
removeOptions := new(containers.RemoveOptions).WithVolumes(true).WithForce(false)
removeContainer := func(id string) {
- if err := containers.Remove(ic.ClientCtx, id, removeOptions); err != nil {
- if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
- errorhandling.Contains(err, define.ErrCtrRemoved) {
- logrus.Debugf("Container %s does not exist: %v", id, err)
- } else {
- logrus.Errorf("Removing container %s: %v", id, err)
- }
- }
+ reports, err := containers.Remove(ic.ClientCtx, id, removeOptions)
+ logIfRmError(id, err, reports)
}
// There can only be one container if attach was used
@@ -674,15 +695,8 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
if err != nil {
if ctr.AutoRemove {
rmOptions := new(containers.RemoveOptions).WithForce(false).WithVolumes(true)
- if err := containers.Remove(ic.ClientCtx, ctr.ID, rmOptions); err != nil {
- if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
- errorhandling.Contains(err, define.ErrCtrRemoved) ||
- errorhandling.Contains(err, types.ErrLayerUnknown) {
- logrus.Debugf("Container %s does not exist: %v", ctr.ID, err)
- } else {
- logrus.Errorf("Removing container %s: %v", ctr.ID, err)
- }
- }
+ reports, err := containers.Remove(ic.ClientCtx, ctr.ID, rmOptions)
+ logIfRmError(ctr.ID, err, reports)
}
report.Err = errors.Wrapf(err, "unable to start container %q", name)
report.ExitCode = define.ExitCode(err)
@@ -741,7 +755,8 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
report.ExitCode = define.ExitCode(err)
if opts.Rm {
- if rmErr := containers.Remove(ic.ClientCtx, con.ID, new(containers.RemoveOptions).WithForce(false).WithVolumes(true)); rmErr != nil {
+ reports, rmErr := containers.Remove(ic.ClientCtx, con.ID, new(containers.RemoveOptions).WithForce(false).WithVolumes(true))
+ if rmErr != nil || reports[0].Err != nil {
logrus.Debugf("unable to remove container %s after failing to start and attach to it", con.ID)
}
}
@@ -759,15 +774,8 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
}
if !shouldRestart {
- if err := containers.Remove(ic.ClientCtx, con.ID, new(containers.RemoveOptions).WithForce(false).WithVolumes(true)); err != nil {
- if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
- errorhandling.Contains(err, define.ErrCtrRemoved) ||
- errorhandling.Contains(err, types.ErrLayerUnknown) {
- logrus.Debugf("Container %s does not exist: %v", con.ID, err)
- } else {
- logrus.Errorf("Removing container %s: %v", con.ID, err)
- }
- }
+ reports, err := containers.Remove(ic.ClientCtx, con.ID, new(containers.RemoveOptions).WithForce(false).WithVolumes(true))
+ logIfRmError(con.ID, err, reports)
}
}()
}