mirror of
https://github.com/containers/podman.git
synced 2025-05-20 16:47:39 +08:00
Add rm --filter option
--filter : remove the filtered container. Signed-off-by: Toshiki Sonoda <sonoda.toshiki@fujitsu.com>
This commit is contained in:
@ -49,7 +49,8 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
killOptions = entities.KillOptions{}
|
||||
killOptions = entities.KillOptions{}
|
||||
killCidFiles = []string{}
|
||||
)
|
||||
|
||||
func killFlags(cmd *cobra.Command) {
|
||||
@ -61,7 +62,7 @@ func killFlags(cmd *cobra.Command) {
|
||||
flags.StringVarP(&killOptions.Signal, signalFlagName, "s", "KILL", "Signal to send to the container")
|
||||
_ = cmd.RegisterFlagCompletionFunc(signalFlagName, common.AutocompleteStopSignal)
|
||||
cidfileFlagName := "cidfile"
|
||||
flags.StringArrayVar(&cidFiles, cidfileFlagName, []string{}, "Read the container ID from the file")
|
||||
flags.StringArrayVar(&killCidFiles, cidfileFlagName, nil, "Read the container ID from the file")
|
||||
_ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
|
||||
}
|
||||
|
||||
@ -94,7 +95,7 @@ func kill(_ *cobra.Command, args []string) error {
|
||||
if sig < 1 || sig > 64 {
|
||||
return errors.New("valid signals are 1 through 64")
|
||||
}
|
||||
for _, cidFile := range cidFiles {
|
||||
for _, cidFile := range killCidFiles {
|
||||
content, err := ioutil.ReadFile(cidFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading CIDFile: %w", err)
|
||||
|
@ -52,8 +52,10 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
rmOptions = entities.RmOptions{}
|
||||
cidFiles = []string{}
|
||||
rmOptions = entities.RmOptions{
|
||||
Filters: make(map[string][]string),
|
||||
}
|
||||
rmCidFiles = []string{}
|
||||
)
|
||||
|
||||
func rmFlags(cmd *cobra.Command) {
|
||||
@ -69,9 +71,13 @@ func rmFlags(cmd *cobra.Command) {
|
||||
flags.BoolVarP(&rmOptions.Volumes, "volumes", "v", false, "Remove anonymous volumes associated with the container")
|
||||
|
||||
cidfileFlagName := "cidfile"
|
||||
flags.StringArrayVar(&cidFiles, cidfileFlagName, nil, "Read the container ID from the file")
|
||||
flags.StringArrayVar(&rmCidFiles, cidfileFlagName, nil, "Read the container ID from the file")
|
||||
_ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
|
||||
|
||||
filterFlagName := "filter"
|
||||
flags.StringSliceVar(&filters, filterFlagName, []string{}, "Filter output based on conditions given")
|
||||
_ = cmd.RegisterFlagCompletionFunc(filterFlagName, common.AutocompletePsFilters)
|
||||
|
||||
if !registry.IsRemote() {
|
||||
// This option is deprecated, but needs to still exists for backwards compatibility
|
||||
flags.Bool("storage", false, "Remove container from storage library")
|
||||
@ -101,7 +107,7 @@ func rm(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
rmOptions.Timeout = &stopTimeout
|
||||
}
|
||||
for _, cidFile := range cidFiles {
|
||||
for _, cidFile := range rmCidFiles {
|
||||
content, err := ioutil.ReadFile(cidFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading CIDFile: %w", err)
|
||||
@ -110,6 +116,14 @@ func rm(cmd *cobra.Command, args []string) error {
|
||||
args = append(args, id)
|
||||
}
|
||||
|
||||
for _, f := range filters {
|
||||
split := strings.SplitN(f, "=", 2)
|
||||
if len(split) < 2 {
|
||||
return fmt.Errorf("invalid filter %q", f)
|
||||
}
|
||||
rmOptions.Filters[split[0]] = append(rmOptions.Filters[split[0]], split[1])
|
||||
}
|
||||
|
||||
if rmOptions.All {
|
||||
logrus.Debug("--all is set: enforcing --depend=true")
|
||||
rmOptions.Depend = true
|
||||
@ -147,7 +161,7 @@ func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit
|
||||
}
|
||||
errs = append(errs, r.Err)
|
||||
} else {
|
||||
fmt.Println(r.Id)
|
||||
fmt.Println(r.RawInput)
|
||||
}
|
||||
}
|
||||
return errs.PrintErrors()
|
||||
|
@ -52,7 +52,8 @@ var (
|
||||
stopOptions = entities.StopOptions{
|
||||
Filters: make(map[string][]string),
|
||||
}
|
||||
stopTimeout uint
|
||||
stopCidFiles = []string{}
|
||||
stopTimeout uint
|
||||
)
|
||||
|
||||
func stopFlags(cmd *cobra.Command) {
|
||||
@ -62,7 +63,7 @@ func stopFlags(cmd *cobra.Command) {
|
||||
flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing")
|
||||
|
||||
cidfileFlagName := "cidfile"
|
||||
flags.StringArrayVar(&cidFiles, cidfileFlagName, nil, "Read the container ID from the file")
|
||||
flags.StringArrayVar(&stopCidFiles, cidfileFlagName, nil, "Read the container ID from the file")
|
||||
_ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
|
||||
|
||||
timeFlagName := "time"
|
||||
@ -103,7 +104,7 @@ func stop(cmd *cobra.Command, args []string) error {
|
||||
if cmd.Flag("time").Changed {
|
||||
stopOptions.Timeout = &stopTimeout
|
||||
}
|
||||
for _, cidFile := range cidFiles {
|
||||
for _, cidFile := range stopCidFiles {
|
||||
content, err := ioutil.ReadFile(cidFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading CIDFile: %w", err)
|
||||
|
@ -26,6 +26,30 @@ Read container ID from the specified file and remove the container. Can be spec
|
||||
|
||||
Remove selected container and recursively remove all containers that depend on it.
|
||||
|
||||
#### **--filter**=*filter*
|
||||
|
||||
Filter what containers remove.
|
||||
Multiple filters can be given with multiple uses of the --filter flag.
|
||||
Filters with the same key work inclusive with the only exception being
|
||||
`label` which is exclusive. Filters with different keys always work exclusive.
|
||||
|
||||
Valid filters are listed below:
|
||||
|
||||
| **Filter** | **Description** |
|
||||
| --------------- | -------------------------------------------------------------------------------- |
|
||||
| id | [ID] Container's ID (accepts regex) |
|
||||
| name | [Name] Container's name (accepts regex) |
|
||||
| label | [Key] or [Key=Value] Label assigned to a container |
|
||||
| exited | [Int] Container's exit code |
|
||||
| status | [Status] Container's status: 'created', 'exited', 'paused', 'running', 'unknown' |
|
||||
| ancestor | [ImageName] Image or descendant used to create container |
|
||||
| before | [ID] or [Name] Containers created before this container |
|
||||
| since | [ID] or [Name] Containers created since this container |
|
||||
| volume | [VolumeName] or [MountpointDestination] Volume mounted in container |
|
||||
| health | [Status] healthy or unhealthy |
|
||||
| pod | [Pod] name or full or partial ID of pod |
|
||||
| network | [Network] name or full ID of network |
|
||||
|
||||
#### **--force**, **-f**
|
||||
|
||||
Force the removal of running and paused containers. Forcing a container removal also
|
||||
|
@ -995,7 +995,7 @@ func (r *Runtime) RemoveDepend(ctx context.Context, rmCtr *Container, force bool
|
||||
return nil, err
|
||||
}
|
||||
for _, cID := range podContainerIDS {
|
||||
rmReports = append(rmReports, &reports.RmReport{Id: cID})
|
||||
rmReports = append(rmReports, &reports.RmReport{Id: cID, RawInput: cID})
|
||||
}
|
||||
return rmReports, nil
|
||||
}
|
||||
@ -1023,7 +1023,7 @@ func (r *Runtime) RemoveDepend(ctx context.Context, rmCtr *Container, force bool
|
||||
rmReports = append(rmReports, reports...)
|
||||
}
|
||||
|
||||
report := reports.RmReport{Id: rmCtr.ID()}
|
||||
report := reports.RmReport{Id: rmCtr.ID(), RawInput: rmCtr.ID()}
|
||||
report.Err = r.removeContainer(ctx, rmCtr, force, removeVolume, false, timeout)
|
||||
return append(rmReports, &report), nil
|
||||
}
|
||||
|
@ -131,6 +131,7 @@ type RestartReport struct {
|
||||
}
|
||||
|
||||
type RmOptions struct {
|
||||
Filters map[string][]string
|
||||
All bool
|
||||
Depend bool
|
||||
Force bool
|
||||
|
@ -1,8 +1,9 @@
|
||||
package reports
|
||||
|
||||
type RmReport struct {
|
||||
Id string `json:"Id"` //nolint:revive,stylecheck
|
||||
Err error `json:"Err,omitempty"`
|
||||
Id string `json:"Id"` //nolint:revive,stylecheck
|
||||
Err error `json:"Err,omitempty"`
|
||||
RawInput string
|
||||
}
|
||||
|
||||
func RmReportsIds(r []*RmReport) []string {
|
||||
|
@ -142,10 +142,10 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctrMap := map[string]string{}
|
||||
idToRawInput := map[string]string{}
|
||||
if len(rawInputs) == len(ctrs) {
|
||||
for i := range ctrs {
|
||||
ctrMap[ctrs[i].ID()] = rawInputs[i]
|
||||
idToRawInput[ctrs[i].ID()] = rawInputs[i]
|
||||
}
|
||||
}
|
||||
reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
|
||||
@ -158,7 +158,7 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
|
||||
reports = append(reports, &entities.PauseUnpauseReport{
|
||||
Id: c.ID(),
|
||||
Err: err,
|
||||
RawInput: ctrMap[c.ID()],
|
||||
RawInput: idToRawInput[c.ID()],
|
||||
})
|
||||
}
|
||||
return reports, nil
|
||||
@ -169,10 +169,10 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctrMap := map[string]string{}
|
||||
idToRawInput := map[string]string{}
|
||||
if len(rawInputs) == len(ctrs) {
|
||||
for i := range ctrs {
|
||||
ctrMap[ctrs[i].ID()] = rawInputs[i]
|
||||
idToRawInput[ctrs[i].ID()] = rawInputs[i]
|
||||
}
|
||||
}
|
||||
reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
|
||||
@ -185,7 +185,7 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st
|
||||
reports = append(reports, &entities.PauseUnpauseReport{
|
||||
Id: c.ID(),
|
||||
Err: err,
|
||||
RawInput: ctrMap[c.ID()],
|
||||
RawInput: idToRawInput[c.ID()],
|
||||
})
|
||||
}
|
||||
return reports, nil
|
||||
@ -196,10 +196,10 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
|
||||
if err != nil && !(options.Ignore && errors.Is(err, define.ErrNoSuchCtr)) {
|
||||
return nil, err
|
||||
}
|
||||
ctrMap := map[string]string{}
|
||||
idToRawInput := map[string]string{}
|
||||
if len(rawInputs) == len(ctrs) {
|
||||
for i := range ctrs {
|
||||
ctrMap[ctrs[i].ID()] = rawInputs[i]
|
||||
idToRawInput[ctrs[i].ID()] = rawInputs[i]
|
||||
}
|
||||
}
|
||||
errMap, err := parallelctr.ContainerOp(ctx, ctrs, func(c *libpod.Container) error {
|
||||
@ -245,7 +245,7 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
|
||||
if options.All {
|
||||
report.RawInput = ctr.ID()
|
||||
} else {
|
||||
report.RawInput = ctrMap[ctr.ID()]
|
||||
report.RawInput = idToRawInput[ctr.ID()]
|
||||
}
|
||||
report.Err = err
|
||||
reports = append(reports, report)
|
||||
@ -275,10 +275,10 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctrMap := map[string]string{}
|
||||
idToRawInput := map[string]string{}
|
||||
if len(rawInputs) == len(ctrs) {
|
||||
for i := range ctrs {
|
||||
ctrMap[ctrs[i].ID()] = rawInputs[i]
|
||||
idToRawInput[ctrs[i].ID()] = rawInputs[i]
|
||||
}
|
||||
}
|
||||
reports := make([]*entities.KillReport, 0, len(ctrs))
|
||||
@ -291,7 +291,7 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin
|
||||
reports = append(reports, &entities.KillReport{
|
||||
Id: con.ID(),
|
||||
Err: err,
|
||||
RawInput: ctrMap[con.ID()],
|
||||
RawInput: idToRawInput[con.ID()],
|
||||
})
|
||||
}
|
||||
return reports, nil
|
||||
@ -360,7 +360,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
|
||||
// this will fail and code will fall through to removing the container from libpod.`
|
||||
tmpNames := []string{}
|
||||
for _, ctr := range names {
|
||||
report := reports.RmReport{Id: ctr}
|
||||
report := reports.RmReport{Id: ctr, RawInput: ctr}
|
||||
report.Err = ic.Libpod.RemoveStorageContainer(ctr, options.Force)
|
||||
//nolint:gocritic
|
||||
if report.Err == nil {
|
||||
@ -381,7 +381,16 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
|
||||
}
|
||||
names = tmpNames
|
||||
|
||||
ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod)
|
||||
ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, names, options.Filters, ic.Libpod)
|
||||
if err != nil && !(options.Ignore && errors.Is(err, define.ErrNoSuchCtr)) {
|
||||
return nil, err
|
||||
}
|
||||
idToRawInput := map[string]string{}
|
||||
if len(rawInputs) == len(ctrs) {
|
||||
for i := range ctrs {
|
||||
idToRawInput[ctrs[i].ID()] = rawInputs[i]
|
||||
}
|
||||
}
|
||||
if err != nil && !(options.Ignore && errors.Is(err, define.ErrNoSuchCtr)) {
|
||||
// Failed to get containers. If force is specified, get the containers ID
|
||||
// and evict them
|
||||
@ -391,7 +400,10 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
|
||||
|
||||
for _, ctr := range names {
|
||||
logrus.Debugf("Evicting container %q", ctr)
|
||||
report := reports.RmReport{Id: ctr}
|
||||
report := reports.RmReport{
|
||||
Id: ctr,
|
||||
RawInput: idToRawInput[ctr],
|
||||
}
|
||||
_, err := ic.Libpod.EvictContainer(ctx, ctr, options.Volumes)
|
||||
if err != nil {
|
||||
if options.Ignore && errors.Is(err, define.ErrNoSuchCtr) {
|
||||
@ -461,6 +473,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
|
||||
report := new(reports.RmReport)
|
||||
report.Id = ctr.ID()
|
||||
report.Err = err
|
||||
report.RawInput = idToRawInput[ctr.ID()]
|
||||
rmReports = append(rmReports, report)
|
||||
}
|
||||
return rmReports, nil
|
||||
|
@ -61,9 +61,9 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctrMap := map[string]string{}
|
||||
idToRawInput := map[string]string{}
|
||||
for i := range ctrs {
|
||||
ctrMap[ctrs[i].ID] = rawInputs[i]
|
||||
idToRawInput[ctrs[i].ID] = rawInputs[i]
|
||||
}
|
||||
reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
|
||||
for _, c := range ctrs {
|
||||
@ -75,7 +75,7 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
|
||||
reports = append(reports, &entities.PauseUnpauseReport{
|
||||
Id: c.ID,
|
||||
Err: err,
|
||||
RawInput: ctrMap[c.ID],
|
||||
RawInput: idToRawInput[c.ID],
|
||||
})
|
||||
}
|
||||
return reports, nil
|
||||
@ -86,9 +86,9 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctrMap := map[string]string{}
|
||||
idToRawInput := map[string]string{}
|
||||
for i := range ctrs {
|
||||
ctrMap[ctrs[i].ID] = rawInputs[i]
|
||||
idToRawInput[ctrs[i].ID] = rawInputs[i]
|
||||
}
|
||||
reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
|
||||
for _, c := range ctrs {
|
||||
@ -100,7 +100,7 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st
|
||||
reports = append(reports, &entities.PauseUnpauseReport{
|
||||
Id: c.ID,
|
||||
Err: err,
|
||||
RawInput: ctrMap[c.ID],
|
||||
RawInput: idToRawInput[c.ID],
|
||||
})
|
||||
}
|
||||
return reports, nil
|
||||
@ -111,9 +111,9 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctrMap := map[string]string{}
|
||||
idToRawInput := map[string]string{}
|
||||
for i := range ctrs {
|
||||
ctrMap[ctrs[i].ID] = rawInputs[i]
|
||||
idToRawInput[ctrs[i].ID] = rawInputs[i]
|
||||
}
|
||||
options := new(containers.StopOptions).WithIgnore(opts.Ignore)
|
||||
if to := opts.Timeout; to != nil {
|
||||
@ -123,7 +123,7 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
|
||||
for _, c := range ctrs {
|
||||
report := entities.StopReport{
|
||||
Id: c.ID,
|
||||
RawInput: ctrMap[c.ID],
|
||||
RawInput: idToRawInput[c.ID],
|
||||
}
|
||||
if err = containers.Stop(ic.ClientCtx, c.ID, options); err != nil {
|
||||
// These first two are considered non-fatal under the right conditions
|
||||
@ -154,9 +154,9 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctrMap := map[string]string{}
|
||||
idToRawInput := map[string]string{}
|
||||
for i := range ctrs {
|
||||
ctrMap[ctrs[i].ID] = rawInputs[i]
|
||||
idToRawInput[ctrs[i].ID] = rawInputs[i]
|
||||
}
|
||||
options := new(containers.KillOptions).WithSignal(opts.Signal)
|
||||
reports := make([]*entities.KillReport, 0, len(ctrs))
|
||||
@ -169,7 +169,7 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin
|
||||
reports = append(reports, &entities.KillReport{
|
||||
Id: c.ID,
|
||||
Err: err,
|
||||
RawInput: ctrMap[c.ID],
|
||||
RawInput: idToRawInput[c.ID],
|
||||
})
|
||||
}
|
||||
return reports, nil
|
||||
@ -208,11 +208,18 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
|
||||
|
||||
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, nil)
|
||||
idToRawInput := map[string]string{}
|
||||
|
||||
if opts.All || len(opts.Filters) > 0 {
|
||||
ctrs, rawInputs, err := getContainersAndInputByContext(ic.ClientCtx, opts.All, opts.Ignore, nil, opts.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(rawInputs) == len(ctrs) {
|
||||
for i := range ctrs {
|
||||
idToRawInput[ctrs[i].ID] = rawInputs[i]
|
||||
}
|
||||
}
|
||||
for _, c := range ctrs {
|
||||
toRemove = append(toRemove, c.ID)
|
||||
}
|
||||
@ -225,10 +232,15 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
|
||||
// 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})
|
||||
ctrs, rawInputs, err := getContainersAndInputByContext(ic.ClientCtx, false, true, []string{ctr}, opts.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(rawInputs) == len(ctrs) {
|
||||
for i := range ctrs {
|
||||
idToRawInput[ctrs[i].ID] = rawInputs[i]
|
||||
}
|
||||
}
|
||||
id := ctr
|
||||
if len(ctrs) == 1 {
|
||||
id = ctrs[0].ID
|
||||
@ -238,13 +250,20 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
|
||||
}
|
||||
|
||||
rmReports := make([]*reports.RmReport, 0, len(toRemove))
|
||||
for _, nameOrID := range toRemove {
|
||||
if alreadyRemoved[nameOrID] {
|
||||
for _, rmCtr := range toRemove {
|
||||
if alreadyRemoved[rmCtr] {
|
||||
continue
|
||||
}
|
||||
newReports, err := containers.Remove(ic.ClientCtx, nameOrID, options)
|
||||
if ctr, exist := idToRawInput[rmCtr]; exist {
|
||||
rmCtr = ctr
|
||||
}
|
||||
newReports, err := containers.Remove(ic.ClientCtx, rmCtr, options)
|
||||
if err != nil {
|
||||
rmReports = append(rmReports, &reports.RmReport{Id: nameOrID, Err: err})
|
||||
rmReports = append(rmReports, &reports.RmReport{
|
||||
Id: rmCtr,
|
||||
Err: err,
|
||||
RawInput: idToRawInput[rmCtr],
|
||||
})
|
||||
continue
|
||||
}
|
||||
for i := range newReports {
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
|
||||
// FIXME: the `ignore` parameter is very likely wrong here as it should rather
|
||||
// be used on *errors* from operations such as remove.
|
||||
func getContainersByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, error) {
|
||||
func getContainersByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, error) { //nolint:unparam
|
||||
ctrs, _, err := getContainersAndInputByContext(contextWithConnection, all, ignore, namesOrIDs, nil)
|
||||
return ctrs, err
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
@ -51,6 +52,7 @@ var _ = Describe("Podman rm", func() {
|
||||
result := podmanTest.Podman([]string{"rm", cid})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(Exit(2))
|
||||
Expect(result.ErrorToString()).To(ContainSubstring("containers cannot be removed without force"))
|
||||
})
|
||||
|
||||
It("podman rm created container", func() {
|
||||
@ -140,11 +142,9 @@ var _ = Describe("Podman rm", func() {
|
||||
output := result.OutputToString()
|
||||
Expect(output).To(ContainSubstring(cid))
|
||||
Expect(podmanTest.NumberOfContainers()).To(Equal(1))
|
||||
|
||||
})
|
||||
|
||||
It("podman rm --cidfile", func() {
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "")
|
||||
Expect(err).To(BeNil())
|
||||
tmpFile := tmpDir + "cid"
|
||||
@ -166,7 +166,6 @@ var _ = Describe("Podman rm", func() {
|
||||
})
|
||||
|
||||
It("podman rm multiple --cidfile", func() {
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "")
|
||||
Expect(err).To(BeNil())
|
||||
tmpFile1 := tmpDir + "cid-1"
|
||||
@ -201,18 +200,22 @@ var _ = Describe("Podman rm", func() {
|
||||
result := podmanTest.Podman([]string{"rm", "--cidfile", "foobar", "--latest"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(Exit(125))
|
||||
Expect(result.ErrorToString()).To(ContainSubstring("--all, --latest, and --cidfile cannot be used together"))
|
||||
|
||||
result = podmanTest.Podman([]string{"rm", "--cidfile", "foobar", "--all"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(Exit(125))
|
||||
Expect(result.ErrorToString()).To(ContainSubstring("--all, --latest, and --cidfile cannot be used together"))
|
||||
|
||||
result = podmanTest.Podman([]string{"rm", "--cidfile", "foobar", "--all", "--latest"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(Exit(125))
|
||||
Expect(result.ErrorToString()).To(ContainSubstring("--all, --latest, and --cidfile cannot be used together"))
|
||||
|
||||
result = podmanTest.Podman([]string{"rm", "--latest", "--all"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(Exit(125))
|
||||
Expect(result.ErrorToString()).To(ContainSubstring("--all and --latest cannot be used together"))
|
||||
})
|
||||
|
||||
It("podman rm --all", func() {
|
||||
@ -242,10 +245,17 @@ var _ = Describe("Podman rm", func() {
|
||||
session = podmanTest.Podman([]string{"rm", "bogus", cid})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(1))
|
||||
Expect(session.ErrorToString()).To(ContainSubstring("\"bogus\" found: no such container"))
|
||||
if IsRemote() {
|
||||
Expect(session.OutputToString()).To(BeEquivalentTo(cid))
|
||||
}
|
||||
|
||||
session = podmanTest.Podman([]string{"rm", "--ignore", "bogus", cid})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
if !IsRemote() {
|
||||
Expect(session.OutputToString()).To(BeEquivalentTo(cid))
|
||||
}
|
||||
Expect(podmanTest.NumberOfContainers()).To(Equal(0))
|
||||
})
|
||||
|
||||
@ -253,6 +263,7 @@ var _ = Describe("Podman rm", func() {
|
||||
session := podmanTest.Podman([]string{"rm", "bogus"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(1))
|
||||
Expect(session.ErrorToString()).To(ContainSubstring("\"bogus\" found: no such container"))
|
||||
})
|
||||
|
||||
It("podman rm bogus container and a running container", func() {
|
||||
@ -263,10 +274,12 @@ var _ = Describe("Podman rm", func() {
|
||||
session = podmanTest.Podman([]string{"rm", "bogus", "test1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(1))
|
||||
Expect(session.ErrorToString()).To(ContainSubstring("\"bogus\" found: no such container"))
|
||||
|
||||
session = podmanTest.Podman([]string{"rm", "test1", "bogus"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(1))
|
||||
Expect(session.ErrorToString()).To(ContainSubstring("\"bogus\" found: no such container"))
|
||||
})
|
||||
|
||||
It("podman rm --ignore bogus container and a running container", func() {
|
||||
@ -274,12 +287,52 @@ var _ = Describe("Podman rm", func() {
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"rm", "--ignore", "test1", "bogus"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(2))
|
||||
Expect(session.ErrorToString()).To(ContainSubstring("containers cannot be removed without force"))
|
||||
|
||||
session = podmanTest.Podman([]string{"rm", "-t", "0", "--force", "--ignore", "bogus", "test1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
Expect(session.OutputToString()).To(BeEquivalentTo("test1"))
|
||||
})
|
||||
|
||||
session = podmanTest.Podman([]string{"rm", "--ignore", "test1", "bogus"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
It("podman rm --filter", func() {
|
||||
session1 := podmanTest.RunTopContainer("test1")
|
||||
session1.WaitWithDefaultTimeout()
|
||||
Expect(session1).Should(Exit(0))
|
||||
cid1 := session1.OutputToString()
|
||||
|
||||
session1 = podmanTest.RunTopContainer("test2")
|
||||
session1.WaitWithDefaultTimeout()
|
||||
Expect(session1).Should(Exit(0))
|
||||
cid2 := session1.OutputToString()
|
||||
|
||||
session1 = podmanTest.RunTopContainer("test3")
|
||||
session1.WaitWithDefaultTimeout()
|
||||
Expect(session1).Should(Exit(0))
|
||||
cid3 := session1.OutputToString()
|
||||
shortCid3 := cid3[0:5]
|
||||
|
||||
session1 = podmanTest.Podman([]string{"rm", cid1, "-f", "--filter", "status=running"})
|
||||
session1.WaitWithDefaultTimeout()
|
||||
Expect(session1).Should(Exit(125))
|
||||
Expect(session1.ErrorToString()).To(ContainSubstring("--filter takes no arguments"))
|
||||
|
||||
session1 = podmanTest.Podman([]string{"rm", "-a", "-f", "--filter", fmt.Sprintf("id=%swrongid", shortCid3)})
|
||||
session1.WaitWithDefaultTimeout()
|
||||
Expect(session1).Should(Exit(0))
|
||||
Expect(session1.OutputToString()).To(HaveLen(0))
|
||||
|
||||
session1 = podmanTest.Podman([]string{"rm", "-a", "-f", "--filter", fmt.Sprintf("id=%s", shortCid3)})
|
||||
session1.WaitWithDefaultTimeout()
|
||||
Expect(session1).Should(Exit(0))
|
||||
Expect(session1.OutputToString()).To(BeEquivalentTo(cid3))
|
||||
|
||||
session1 = podmanTest.Podman([]string{"rm", "-f", "--filter", fmt.Sprintf("id=%s", cid2)})
|
||||
session1.WaitWithDefaultTimeout()
|
||||
Expect(session1).Should(Exit(0))
|
||||
Expect(session1.OutputToString()).To(BeEquivalentTo(cid2))
|
||||
})
|
||||
})
|
||||
|
@ -18,6 +18,7 @@ load helpers
|
||||
|
||||
# Remove container; now 'inspect' should fail
|
||||
run_podman rm $rand
|
||||
is "$output" "$rand" "display raw input"
|
||||
run_podman 125 inspect $rand
|
||||
}
|
||||
|
||||
|
@ -345,10 +345,10 @@ failed | exited | 17
|
||||
|
||||
@test "rm a stopped container" {
|
||||
run_podman rm myfailedcontainer
|
||||
is "$output" "[0-9a-f]\\{64\\}" "podman rm myfailedcontainer"
|
||||
is "$output" "myfailedcontainer" "podman rm myfailedcontainer"
|
||||
|
||||
run_podman rm mydonecontainer
|
||||
is "$output" "[0-9a-f]\\{64\\}" "podman rm mydonecontainer"
|
||||
is "$output" "mydonecontainer" "podman rm mydonecontainer"
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user