mirror of
https://github.com/containers/podman.git
synced 2025-07-02 08:47:43 +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")
|
logrus.Debug("--all is set: enforcing --depend=true")
|
||||||
rmOptions.Depend = true
|
rmOptions.Depend = true
|
||||||
}
|
}
|
||||||
|
if rmOptions.Force {
|
||||||
|
rmOptions.Ignore = true
|
||||||
|
}
|
||||||
|
|
||||||
return removeContainers(utils.RemoveSlash(args), rmOptions, true, false)
|
return removeContainers(utils.RemoveSlash(args), rmOptions, true, false)
|
||||||
}
|
}
|
||||||
@ -144,9 +147,6 @@ func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit
|
|||||||
var errs utils.OutputErrors
|
var errs utils.OutputErrors
|
||||||
responses, err := registry.ContainerEngine().ContainerRm(context.Background(), namesOrIDs, rmOptions)
|
responses, err := registry.ContainerEngine().ContainerRm(context.Background(), namesOrIDs, rmOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rmOptions.Force && strings.Contains(err.Error(), define.ErrNoSuchCtr.Error()) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if setExit {
|
if setExit {
|
||||||
setExitCode(err)
|
setExitCode(err)
|
||||||
}
|
}
|
||||||
@ -158,9 +158,6 @@ func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit
|
|||||||
if errors.Is(r.Err, define.ErrWillDeadlock) {
|
if errors.Is(r.Err, define.ErrWillDeadlock) {
|
||||||
logrus.Errorf("Potential deadlock detected - please run 'podman system renumber' to resolve")
|
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 {
|
if setExit {
|
||||||
setExitCode(r.Err)
|
setExitCode(r.Err)
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,11 @@ package images
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/containers/podman/v5/cmd/podman/common"
|
"github.com/containers/podman/v5/cmd/podman/common"
|
||||||
"github.com/containers/podman/v5/cmd/podman/registry"
|
"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/domain/entities"
|
||||||
"github.com/containers/podman/v5/pkg/errorhandling"
|
"github.com/containers/podman/v5/pkg/errorhandling"
|
||||||
"github.com/containers/storage/types"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"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")
|
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
|
// Note: certain image-removal errors are non-fatal. Hence, the report
|
||||||
// might be set even if err != nil.
|
// might be set even if err != nil.
|
||||||
report, rmErrors := registry.ImageEngine().Remove(registry.GetContext(), args, imageOpts)
|
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)
|
fmt.Println("Deleted: " + d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, err := range rmErrors {
|
}
|
||||||
if !imageOpts.Force || !strings.Contains(err.Error(), types.ErrImageUnknown.Error()) {
|
if len(rmErrors) > 0 {
|
||||||
registry.SetExitCode(report.ExitCode)
|
registry.SetExitCode(report.ExitCode)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var errs utils.OutputErrors
|
return errorhandling.JoinErrors(rmErrors)
|
||||||
for _, err := range rmErrors {
|
|
||||||
if imageOpts.Force && strings.Contains(err.Error(), types.ErrImageUnknown.Error()) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
errs = append(errs, err)
|
|
||||||
}
|
|
||||||
return errorhandling.JoinErrors(errs)
|
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,10 @@ func rm(cmd *cobra.Command, args []string) error {
|
|||||||
rmOptions.Timeout = &timeout
|
rmOptions.Timeout = &timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rmOptions.Force {
|
||||||
|
rmOptions.Ignore = true
|
||||||
|
}
|
||||||
|
|
||||||
errs = append(errs, removePods(args, rmOptions.PodRmOptions, true)...)
|
errs = append(errs, removePods(args, rmOptions.PodRmOptions, true)...)
|
||||||
|
|
||||||
for _, idFile := range rmOptions.PodIDFiles {
|
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)
|
responses, err := registry.ContainerEngine().PodRm(context.Background(), namesOrIDs, rmOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rmOptions.Force && strings.Contains(err.Error(), define.ErrNoSuchPod.Error()) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
setExitCode(err)
|
setExitCode(err)
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
if !strings.Contains(err.Error(), define.ErrRemovingCtrs.Error()) {
|
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)
|
fmt.Println(r.Id)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if rmOptions.Force && strings.Contains(r.Err.Error(), define.ErrNoSuchPod.Error()) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
setExitCode(r.Err)
|
setExitCode(r.Err)
|
||||||
errs = append(errs, r.Err)
|
errs = append(errs, r.Err)
|
||||||
for ctr, err := range r.RemovedCtrs {
|
for ctr, err := range r.RemovedCtrs {
|
||||||
|
@ -81,7 +81,7 @@ func getContainersAndInputByContext(contextWithConnection context.Context, all,
|
|||||||
return filtered, rawInputs, nil
|
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 {
|
if all && len(namesOrIDs) > 0 {
|
||||||
return nil, errors.New("cannot look up specific pods and all")
|
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)
|
inspectData, err := pods.Inspect(contextWithConnection, nameOrID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errorhandling.Contains(err, define.ErrNoSuchPod) {
|
if errorhandling.Contains(err, define.ErrNoSuchPod) {
|
||||||
|
if ignore {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return nil, fmt.Errorf("unable to find pod %q: %w", nameOrID, define.ErrNoSuchPod)
|
return nil, fmt.Errorf("unable to find pod %q: %w", nameOrID, define.ErrNoSuchPod)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -126,6 +129,9 @@ func getPodsByContext(contextWithConnection context.Context, all bool, namesOrID
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
|
if ignore {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return nil, fmt.Errorf("unable to find pod %q: %w", nameOrID, define.ErrNoSuchPod)
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, namesOrIds)
|
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, false, namesOrIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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) {
|
func (ic *ContainerEngine) PodStop(ctx context.Context, namesOrIds []string, opts entities.PodStopOptions) ([]*entities.PodStopReport, error) {
|
||||||
timeout := -1
|
timeout := -1
|
||||||
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, namesOrIds)
|
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, opts.Ignore, namesOrIds)
|
||||||
if err != nil && !(opts.Ignore && errors.Is(err, define.ErrNoSuchPod)) {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if opts.Timeout != -1 {
|
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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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) {
|
func (ic *ContainerEngine) PodRm(ctx context.Context, namesOrIds []string, opts entities.PodRmOptions) ([]*entities.PodRmReport, error) {
|
||||||
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, namesOrIds)
|
foundPods, err := getPodsByContext(ic.ClientCtx, opts.All, opts.Ignore, namesOrIds)
|
||||||
if err != nil && !(opts.Ignore && errors.Is(err, define.ErrNoSuchPod)) {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
reports := make([]*entities.PodRmReport, 0, len(foundPods))
|
reports := make([]*entities.PodRmReport, 0, len(foundPods))
|
||||||
|
@ -312,6 +312,15 @@ Deleted: $pauseID"
|
|||||||
is "$output" "Error: bogus: image not known" "Should print error"
|
is "$output" "Error: bogus: image not known" "Should print error"
|
||||||
run_podman image rm --force bogus
|
run_podman image rm --force bogus
|
||||||
is "$output" "" "Should print no output"
|
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" {
|
@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"
|
is "$output" "Error: no container with ID or name \"bogus\" found: no such container" "Should print error"
|
||||||
run_podman container rm --force bogus
|
run_podman container rm --force bogus
|
||||||
is "$output" "" "Should print no output"
|
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() {
|
function __run_healthcheck_container() {
|
||||||
|
@ -550,6 +550,13 @@ EOF
|
|||||||
is "$output" "Error: no volume with name \"bogus\" found: no such volume" "Should print error"
|
is "$output" "Error: no volume with name \"bogus\" found: no such volume" "Should print error"
|
||||||
run_podman volume rm --force bogus
|
run_podman volume rm --force bogus
|
||||||
is "$output" "" "Should print no output"
|
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" {
|
@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"
|
is "$output" "Error: .*bogus.*: no such pod" "Should print error"
|
||||||
run_podman pod rm -t -1 --force bogus
|
run_podman pod rm -t -1 --force bogus
|
||||||
is "$output" "" "Should print no output"
|
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" {
|
@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"
|
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
|
run_podman network rm -t -1 --force bogus
|
||||||
is "$output" "" "Should print no output"
|
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 " {
|
@test "podman network rm --dns-option " {
|
||||||
|
Reference in New Issue
Block a user