mirror of
https://github.com/containers/podman.git
synced 2025-07-02 00:30:00 +08:00
Merge pull request #22259 from Luap99/rm-force
rm --force work for more than one arg
This commit is contained in:
@ -132,6 +132,9 @@ func rm(cmd *cobra.Command, args []string) error {
|
||||
logrus.Debug("--all is set: enforcing --depend=true")
|
||||
rmOptions.Depend = true
|
||||
}
|
||||
if rmOptions.Force {
|
||||
rmOptions.Ignore = true
|
||||
}
|
||||
|
||||
return removeContainers(utils.RemoveSlash(args), rmOptions, true, false)
|
||||
}
|
||||
@ -144,9 +147,6 @@ func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit
|
||||
var errs utils.OutputErrors
|
||||
responses, err := registry.ContainerEngine().ContainerRm(context.Background(), namesOrIDs, rmOptions)
|
||||
if err != nil {
|
||||
if rmOptions.Force && strings.Contains(err.Error(), define.ErrNoSuchCtr.Error()) {
|
||||
return nil
|
||||
}
|
||||
if setExit {
|
||||
setExitCode(err)
|
||||
}
|
||||
@ -158,9 +158,6 @@ func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit
|
||||
if errors.Is(r.Err, define.ErrWillDeadlock) {
|
||||
logrus.Errorf("Potential deadlock detected - please run 'podman system renumber' to resolve")
|
||||
}
|
||||
if rmOptions.Force && strings.Contains(r.Err.Error(), define.ErrNoSuchCtr.Error()) {
|
||||
continue
|
||||
}
|
||||
if setExit {
|
||||
setExitCode(r.Err)
|
||||
}
|
||||
|
@ -3,14 +3,11 @@ package images
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/podman/v5/cmd/podman/common"
|
||||
"github.com/containers/podman/v5/cmd/podman/registry"
|
||||
"github.com/containers/podman/v5/cmd/podman/utils"
|
||||
"github.com/containers/podman/v5/pkg/domain/entities"
|
||||
"github.com/containers/podman/v5/pkg/errorhandling"
|
||||
"github.com/containers/storage/types"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
@ -72,6 +69,10 @@ func rm(cmd *cobra.Command, args []string) error {
|
||||
return errors.New("when using the --all switch, you may not pass any images names or IDs")
|
||||
}
|
||||
|
||||
if imageOpts.Force {
|
||||
imageOpts.Ignore = true
|
||||
}
|
||||
|
||||
// Note: certain image-removal errors are non-fatal. Hence, the report
|
||||
// might be set even if err != nil.
|
||||
report, rmErrors := registry.ImageEngine().Remove(registry.GetContext(), args, imageOpts)
|
||||
@ -85,19 +86,10 @@ func rm(cmd *cobra.Command, args []string) error {
|
||||
fmt.Println("Deleted: " + d)
|
||||
}
|
||||
}
|
||||
for _, err := range rmErrors {
|
||||
if !imageOpts.Force || !strings.Contains(err.Error(), types.ErrImageUnknown.Error()) {
|
||||
registry.SetExitCode(report.ExitCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(rmErrors) > 0 {
|
||||
registry.SetExitCode(report.ExitCode)
|
||||
}
|
||||
|
||||
var errs utils.OutputErrors
|
||||
for _, err := range rmErrors {
|
||||
if imageOpts.Force && strings.Contains(err.Error(), types.ErrImageUnknown.Error()) {
|
||||
continue
|
||||
}
|
||||
errs = append(errs, err)
|
||||
}
|
||||
return errorhandling.JoinErrors(errs)
|
||||
return errorhandling.JoinErrors(rmErrors)
|
||||
}
|
||||
|
@ -83,6 +83,10 @@ func rm(cmd *cobra.Command, args []string) error {
|
||||
rmOptions.Timeout = &timeout
|
||||
}
|
||||
|
||||
if rmOptions.Force {
|
||||
rmOptions.Ignore = true
|
||||
}
|
||||
|
||||
errs = append(errs, removePods(args, rmOptions.PodRmOptions, true)...)
|
||||
|
||||
for _, idFile := range rmOptions.PodIDFiles {
|
||||
@ -110,9 +114,6 @@ func removePods(namesOrIDs []string, rmOptions entities.PodRmOptions, printIDs b
|
||||
|
||||
responses, err := registry.ContainerEngine().PodRm(context.Background(), namesOrIDs, rmOptions)
|
||||
if err != nil {
|
||||
if rmOptions.Force && strings.Contains(err.Error(), define.ErrNoSuchPod.Error()) {
|
||||
return nil
|
||||
}
|
||||
setExitCode(err)
|
||||
errs = append(errs, err)
|
||||
if !strings.Contains(err.Error(), define.ErrRemovingCtrs.Error()) {
|
||||
@ -127,9 +128,6 @@ func removePods(namesOrIDs []string, rmOptions entities.PodRmOptions, printIDs b
|
||||
fmt.Println(r.Id)
|
||||
}
|
||||
} else {
|
||||
if rmOptions.Force && strings.Contains(r.Err.Error(), define.ErrNoSuchPod.Error()) {
|
||||
continue
|
||||
}
|
||||
setExitCode(r.Err)
|
||||
errs = append(errs, r.Err)
|
||||
for ctr, err := range r.RemovedCtrs {
|
||||
|
@ -81,7 +81,7 @@ func getContainersAndInputByContext(contextWithConnection context.Context, all,
|
||||
return filtered, rawInputs, nil
|
||||
}
|
||||
|
||||
func getPodsByContext(contextWithConnection context.Context, all bool, namesOrIDs []string) ([]*entities.ListPodsReport, error) {
|
||||
func getPodsByContext(contextWithConnection context.Context, all bool, ignore bool, namesOrIDs []string) ([]*entities.ListPodsReport, error) {
|
||||
if all && len(namesOrIDs) > 0 {
|
||||
return nil, errors.New("cannot look up specific pods and all")
|
||||
}
|
||||
@ -108,6 +108,9 @@ func getPodsByContext(contextWithConnection context.Context, all bool, namesOrID
|
||||
inspectData, err := pods.Inspect(contextWithConnection, nameOrID, nil)
|
||||
if err != nil {
|
||||
if errorhandling.Contains(err, define.ErrNoSuchPod) {
|
||||
if ignore {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("unable to find pod %q: %w", nameOrID, define.ErrNoSuchPod)
|
||||
}
|
||||
return nil, err
|
||||
@ -126,6 +129,9 @@ func getPodsByContext(contextWithConnection context.Context, all bool, namesOrID
|
||||
}
|
||||
|
||||
if !found {
|
||||
if ignore {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("unable to find pod %q: %w", nameOrID, define.ErrNoSuchPod)
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ func (ic *ContainerEngine) PodKill(ctx context.Context, namesOrIds []string, opt
|
||||
return nil, err
|
||||
}
|
||||
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, namesOrIds)
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, false, namesOrIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -55,7 +55,7 @@ func (ic *ContainerEngine) PodLogs(ctx context.Context, nameOrIDs string, option
|
||||
}
|
||||
|
||||
func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, options entities.PodPauseOptions) ([]*entities.PodPauseReport, error) {
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, options.All, namesOrIds)
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, options.All, false, namesOrIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -76,7 +76,7 @@ func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, op
|
||||
}
|
||||
|
||||
func (ic *ContainerEngine) PodUnpause(ctx context.Context, namesOrIds []string, options entities.PodunpauseOptions) ([]*entities.PodUnpauseReport, error) {
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, options.All, namesOrIds)
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, options.All, false, namesOrIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -102,8 +102,8 @@ func (ic *ContainerEngine) PodUnpause(ctx context.Context, namesOrIds []string,
|
||||
|
||||
func (ic *ContainerEngine) PodStop(ctx context.Context, namesOrIds []string, opts entities.PodStopOptions) ([]*entities.PodStopReport, error) {
|
||||
timeout := -1
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, namesOrIds)
|
||||
if err != nil && !(opts.Ignore && errors.Is(err, define.ErrNoSuchPod)) {
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, opts.Ignore, namesOrIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if opts.Timeout != -1 {
|
||||
@ -127,7 +127,7 @@ func (ic *ContainerEngine) PodStop(ctx context.Context, namesOrIds []string, opt
|
||||
}
|
||||
|
||||
func (ic *ContainerEngine) PodRestart(ctx context.Context, namesOrIds []string, options entities.PodRestartOptions) ([]*entities.PodRestartReport, error) {
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, options.All, namesOrIds)
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, options.All, false, namesOrIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -148,7 +148,7 @@ func (ic *ContainerEngine) PodRestart(ctx context.Context, namesOrIds []string,
|
||||
}
|
||||
|
||||
func (ic *ContainerEngine) PodStart(ctx context.Context, namesOrIds []string, options entities.PodStartOptions) ([]*entities.PodStartReport, error) {
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, options.All, namesOrIds)
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, options.All, false, namesOrIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -169,8 +169,8 @@ func (ic *ContainerEngine) PodStart(ctx context.Context, namesOrIds []string, op
|
||||
}
|
||||
|
||||
func (ic *ContainerEngine) PodRm(ctx context.Context, namesOrIds []string, opts entities.PodRmOptions) ([]*entities.PodRmReport, error) {
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, namesOrIds)
|
||||
if err != nil && !(opts.Ignore && errors.Is(err, define.ErrNoSuchPod)) {
|
||||
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, opts.Ignore, namesOrIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reports := make([]*entities.PodRmReport, 0, len(foundPods))
|
||||
|
@ -312,6 +312,15 @@ Deleted: $pauseID"
|
||||
is "$output" "Error: bogus: image not known" "Should print error"
|
||||
run_podman image rm --force bogus
|
||||
is "$output" "" "Should print no output"
|
||||
|
||||
random_image_name=$(random_string)
|
||||
random_image_name=${random_image_name,,} # name must be lowercase
|
||||
run_podman image tag $IMAGE $random_image_name
|
||||
run_podman image rm --force bogus $random_image_name
|
||||
assert "$output" = "Untagged: localhost/$random_image_name:latest" "removed image"
|
||||
|
||||
run_podman images
|
||||
assert "$output" !~ "$random_image_name" "image must be removed"
|
||||
}
|
||||
|
||||
@test "podman images - commit docker with comment" {
|
||||
|
@ -111,6 +111,13 @@ load helpers
|
||||
is "$output" "Error: no container with ID or name \"bogus\" found: no such container" "Should print error"
|
||||
run_podman container rm --force bogus
|
||||
is "$output" "" "Should print no output"
|
||||
|
||||
run_podman create --name test $IMAGE
|
||||
run_podman container rm --force bogus test
|
||||
assert "$output" = "test" "should delete test"
|
||||
|
||||
run_podman ps -a -q
|
||||
assert "$output" = "" "container should be removed"
|
||||
}
|
||||
|
||||
function __run_healthcheck_container() {
|
||||
|
@ -550,6 +550,13 @@ EOF
|
||||
is "$output" "Error: no volume with name \"bogus\" found: no such volume" "Should print error"
|
||||
run_podman volume rm --force bogus
|
||||
is "$output" "" "Should print no output"
|
||||
|
||||
run_podman volume create testvol
|
||||
run_podman volume rm --force bogus testvol
|
||||
assert "$output" = "testvol" "removed volume"
|
||||
|
||||
run_podman volume ls -q
|
||||
assert "$output" = "" "no volumes"
|
||||
}
|
||||
|
||||
@test "podman ps -f" {
|
||||
|
@ -579,6 +579,12 @@ io.max | $lomajmin rbps=1048576 wbps=1048576 riops=max wiops=max
|
||||
is "$output" "Error: .*bogus.*: no such pod" "Should print error"
|
||||
run_podman pod rm -t -1 --force bogus
|
||||
is "$output" "" "Should print no output"
|
||||
|
||||
run_podman pod create --name testpod
|
||||
run_podman pod rm --force bogus testpod
|
||||
assert "$output" =~ "[0-9a-f]{64}" "rm pod"
|
||||
run_podman pod ps -q
|
||||
assert "$output" = "" "no pods listed"
|
||||
}
|
||||
|
||||
@test "podman pod create on failure" {
|
||||
|
@ -848,6 +848,12 @@ EOF
|
||||
is "$output" "Error: unable to find network with name or ID bogus: network not found" "Should print error"
|
||||
run_podman network rm -t -1 --force bogus
|
||||
is "$output" "" "Should print no output"
|
||||
|
||||
run_podman network create testnet
|
||||
run_podman network rm --force bogus testnet
|
||||
assert "$output" = "testnet" "rm network"
|
||||
run_podman network ls -q
|
||||
assert "$output" = "podman" "only podman network listed"
|
||||
}
|
||||
|
||||
@test "podman network rm --dns-option " {
|
||||
|
Reference in New Issue
Block a user