diff options
-rw-r--r-- | cmd/podman/containers/restore.go | 51 | ||||
-rw-r--r-- | cmd/podman/containers/rm.go | 6 | ||||
-rw-r--r-- | cmd/podman/images/rm.go | 18 | ||||
-rw-r--r-- | cmd/podman/networks/rm.go | 6 | ||||
-rw-r--r-- | cmd/podman/pods/rm.go | 7 | ||||
-rw-r--r-- | cmd/podman/volumes/rm.go | 6 | ||||
-rw-r--r-- | pkg/domain/filters/containers.go | 9 | ||||
-rw-r--r-- | pkg/domain/filters/pods.go | 3 | ||||
-rw-r--r-- | pkg/domain/filters/volumes.go | 5 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 1 | ||||
-rw-r--r-- | pkg/domain/infra/abi/manifest.go | 3 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/manifest.go | 10 | ||||
-rw-r--r-- | pkg/util/filters.go | 33 | ||||
-rw-r--r-- | pkg/util/filters_test.go | 4 | ||||
-rw-r--r-- | test/e2e/checkpoint_test.go | 20 | ||||
-rw-r--r-- | test/e2e/manifest_test.go | 44 | ||||
-rw-r--r-- | test/e2e/prune_test.go | 18 | ||||
-rw-r--r-- | test/system/010-images.bats | 7 | ||||
-rw-r--r-- | test/system/055-rm.bats | 7 | ||||
-rw-r--r-- | test/system/160-volumes.bats | 7 | ||||
-rw-r--r-- | test/system/200-pod.bats | 7 | ||||
-rw-r--r-- | test/system/500-networking.bats | 9 |
22 files changed, 214 insertions, 67 deletions
diff --git a/cmd/podman/containers/restore.go b/cmd/podman/containers/restore.go index 1e4745354..6106f2bed 100644 --- a/cmd/podman/containers/restore.go +++ b/cmd/podman/containers/restore.go @@ -93,32 +93,49 @@ func init() { } func restore(cmd *cobra.Command, args []string) error { - var errs utils.OutputErrors + var ( + e error + errs utils.OutputErrors + ) podmanStart := time.Now() if rootless.IsRootless() { return fmt.Errorf("restoring a container requires root") } - // Find out if this is an image - inspectOpts := entities.InspectOptions{} - imgData, _, err := registry.ImageEngine().Inspect(context.Background(), args, inspectOpts) - if err != nil { - return err + // Check if the container exists (#15055) + exists := &entities.BoolReport{Value: false} + for _, ctr := range args { + exists, e = registry.ContainerEngine().ContainerExists(registry.GetContext(), ctr, entities.ContainerExistsOptions{}) + if e != nil { + return e + } + if exists.Value { + break + } } - hostInfo, err := registry.ContainerEngine().Info(context.Background()) - if err != nil { - return err - } + if !exists.Value { + // Find out if this is an image + inspectOpts := entities.InspectOptions{} + imgData, _, err := registry.ImageEngine().Inspect(context.Background(), args, inspectOpts) + if err != nil { + return err + } - for i := range imgData { - restoreOptions.CheckpointImage = true - checkpointRuntimeName, found := imgData[i].Annotations[define.CheckpointAnnotationRuntimeName] - if !found { - return fmt.Errorf("image is not a checkpoint: %s", imgData[i].ID) + hostInfo, err := registry.ContainerEngine().Info(context.Background()) + if err != nil { + return err } - if hostInfo.Host.OCIRuntime.Name != checkpointRuntimeName { - return fmt.Errorf("container image \"%s\" requires runtime: \"%s\"", imgData[i].ID, checkpointRuntimeName) + + for i := range imgData { + restoreOptions.CheckpointImage = true + checkpointRuntimeName, found := imgData[i].Annotations[define.CheckpointAnnotationRuntimeName] + if !found { + return fmt.Errorf("image is not a checkpoint: %s", imgData[i].ID) + } + if hostInfo.Host.OCIRuntime.Name != checkpointRuntimeName { + return fmt.Errorf("container image \"%s\" requires runtime: \"%s\"", imgData[i].ID, checkpointRuntimeName) + } } } diff --git a/cmd/podman/containers/rm.go b/cmd/podman/containers/rm.go index 9fa688d23..056e32651 100644 --- a/cmd/podman/containers/rm.go +++ b/cmd/podman/containers/rm.go @@ -126,6 +126,9 @@ 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) } @@ -136,6 +139,9 @@ 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) } diff --git a/cmd/podman/images/rm.go b/cmd/podman/images/rm.go index 18b22e51d..d3fd17440 100644 --- a/cmd/podman/images/rm.go +++ b/cmd/podman/images/rm.go @@ -3,11 +3,14 @@ package images import ( "errors" "fmt" + "strings" "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/registry" + "github.com/containers/podman/v4/cmd/podman/utils" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/errorhandling" + "github.com/containers/storage/types" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -81,8 +84,19 @@ func rm(cmd *cobra.Command, args []string) error { fmt.Println("Deleted: " + d) } } - registry.SetExitCode(report.ExitCode) + for _, err := range rmErrors { + if !imageOpts.Force || !strings.Contains(err.Error(), types.ErrImageUnknown.Error()) { + registry.SetExitCode(report.ExitCode) + } + } } - return errorhandling.JoinErrors(rmErrors) + 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) } diff --git a/cmd/podman/networks/rm.go b/cmd/podman/networks/rm.go index c2d3f655f..d734b2867 100644 --- a/cmd/podman/networks/rm.go +++ b/cmd/podman/networks/rm.go @@ -63,6 +63,9 @@ func networkRm(cmd *cobra.Command, args []string) error { } responses, err := registry.ContainerEngine().NetworkRm(registry.Context(), args, networkRmOptions) if err != nil { + if networkRmOptions.Force && strings.Contains(err.Error(), define.ErrNoSuchNetwork.Error()) { + return nil + } setExitCode(err) return err } @@ -70,6 +73,9 @@ func networkRm(cmd *cobra.Command, args []string) error { if r.Err == nil { fmt.Println(r.Name) } else { + if networkRmOptions.Force && strings.Contains(r.Err.Error(), define.ErrNoSuchNetwork.Error()) { + continue + } setExitCode(r.Err) errs = append(errs, r.Err) } diff --git a/cmd/podman/pods/rm.go b/cmd/podman/pods/rm.go index 2ffd968f9..0aa64481d 100644 --- a/cmd/podman/pods/rm.go +++ b/cmd/podman/pods/rm.go @@ -93,6 +93,9 @@ 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) return err } @@ -104,13 +107,15 @@ 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) } } return errs.PrintErrors() } - func setExitCode(err error) { if errors.Is(err, define.ErrNoSuchPod) || strings.Contains(err.Error(), define.ErrNoSuchPod.Error()) { registry.SetExitCode(1) diff --git a/cmd/podman/volumes/rm.go b/cmd/podman/volumes/rm.go index c160b8623..1383da279 100644 --- a/cmd/podman/volumes/rm.go +++ b/cmd/podman/volumes/rm.go @@ -65,6 +65,9 @@ func rm(cmd *cobra.Command, args []string) error { } responses, err := registry.ContainerEngine().VolumeRm(context.Background(), args, rmOptions) if err != nil { + if rmOptions.Force && strings.Contains(err.Error(), define.ErrNoSuchVolume.Error()) { + return nil + } setExitCode(err) return err } @@ -72,6 +75,9 @@ func rm(cmd *cobra.Command, args []string) error { if r.Err == nil { fmt.Println(r.Id) } else { + if rmOptions.Force && strings.Contains(r.Err.Error(), define.ErrNoSuchVolume.Error()) { + continue + } setExitCode(r.Err) errs = append(errs, r.Err) } diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go index f88a165e7..de62b6582 100644 --- a/pkg/domain/filters/containers.go +++ b/pkg/domain/filters/containers.go @@ -7,6 +7,7 @@ import ( "strings" "time" + "github.com/containers/common/pkg/filters" cutil "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" @@ -24,7 +25,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo case "label": // we have to match that all given labels exits on that container return func(c *libpod.Container) bool { - return util.MatchLabelFilters(filterValues, c.Labels()) + return filters.MatchLabelFilters(filterValues, c.Labels()) }, nil case "name": // we only have to match one name @@ -299,7 +300,11 @@ func GeneratePruneContainerFilterFuncs(filter string, filterValues []string, r * switch filter { case "label": return func(c *libpod.Container) bool { - return util.MatchLabelFilters(filterValues, c.Labels()) + return filters.MatchLabelFilters(filterValues, c.Labels()) + }, nil + case "label!": + return func(c *libpod.Container) bool { + return !filters.MatchLabelFilters(filterValues, c.Labels()) }, nil case "until": return prepareUntilFilterFunc(filterValues) diff --git a/pkg/domain/filters/pods.go b/pkg/domain/filters/pods.go index 78b97db64..7b0944292 100644 --- a/pkg/domain/filters/pods.go +++ b/pkg/domain/filters/pods.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" + "github.com/containers/common/pkg/filters" cutil "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" @@ -115,7 +116,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti case "label": return func(p *libpod.Pod) bool { labels := p.Labels() - return util.MatchLabelFilters(filterValues, labels) + return filters.MatchLabelFilters(filterValues, labels) }, nil case "until": return func(p *libpod.Pod) bool { diff --git a/pkg/domain/filters/volumes.go b/pkg/domain/filters/volumes.go index 7c5047225..9cec39fbb 100644 --- a/pkg/domain/filters/volumes.go +++ b/pkg/domain/filters/volumes.go @@ -6,6 +6,7 @@ import ( "regexp" "strings" + pruneFilters "github.com/containers/common/pkg/filters" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/pkg/util" ) @@ -36,7 +37,7 @@ func GenerateVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) { case "label": filter := val vf = append(vf, func(v *libpod.Volume) bool { - return util.MatchLabelFilters([]string{filter}, v.Labels()) + return pruneFilters.MatchLabelFilters([]string{filter}, v.Labels()) }) case "opt": filterArray := strings.SplitN(val, "=", 2) @@ -100,7 +101,7 @@ func GeneratePruneVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, erro switch filter { case "label": vf = append(vf, func(v *libpod.Volume) bool { - return util.MatchLabelFilters([]string{filterVal}, v.Labels()) + return pruneFilters.MatchLabelFilters([]string{filterVal}, v.Labels()) }) case "until": f, err := createUntilFilterVolumeFunction(filterVal) diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index dd7053a23..ab742fb35 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -260,6 +260,7 @@ func (ic *ContainerEngine) ContainerPrune(ctx context.Context, options entities. if err != nil { return nil, err } + filterFuncs = append(filterFuncs, generatedFunc) } return ic.Libpod.PruneContainers(filterFuncs) diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go index d20744d76..bdc3d9513 100644 --- a/pkg/domain/infra/abi/manifest.go +++ b/pkg/domain/infra/abi/manifest.go @@ -331,7 +331,8 @@ func (ir *ImageEngine) ManifestPush(ctx context.Context, name, destination strin } if opts.Rm { - if _, rmErrors := ir.Libpod.LibimageRuntime().RemoveImages(ctx, []string{manifestList.ID()}, nil); len(rmErrors) > 0 { + rmOpts := &libimage.RemoveImagesOptions{LookupManifest: true} + if _, rmErrors := ir.Libpod.LibimageRuntime().RemoveImages(ctx, []string{manifestList.ID()}, rmOpts); len(rmErrors) > 0 { return "", fmt.Errorf("error removing manifest after push: %w", rmErrors[0]) } } diff --git a/pkg/domain/infra/tunnel/manifest.go b/pkg/domain/infra/tunnel/manifest.go index d2554f198..4a3148fac 100644 --- a/pkg/domain/infra/tunnel/manifest.go +++ b/pkg/domain/infra/tunnel/manifest.go @@ -110,5 +110,15 @@ func (ir *ImageEngine) ManifestPush(ctx context.Context, name, destination strin } } digest, err := manifests.Push(ir.ClientCtx, name, destination, options) + if err != nil { + return "", fmt.Errorf("error adding to manifest list %s: %w", name, err) + } + + if opts.Rm { + if _, rmErrors := ir.Remove(ctx, []string{name}, entities.ImageRemoveOptions{LookupManifest: true}); len(rmErrors) > 0 { + return "", fmt.Errorf("error removing manifest after push: %w", rmErrors[0]) + } + } + return digest, err } diff --git a/pkg/util/filters.go b/pkg/util/filters.go index 08148806f..104b9c3c2 100644 --- a/pkg/util/filters.go +++ b/pkg/util/filters.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "net/http" - "path/filepath" "strings" "time" @@ -94,35 +93,3 @@ func PrepareFilters(r *http.Request) (*map[string][]string, error) { } return &filterMap, nil } - -func matchPattern(pattern string, value string) bool { - if strings.Contains(pattern, "*") { - filter := fmt.Sprintf("*%s*", pattern) - filter = strings.ReplaceAll(filter, string(filepath.Separator), "|") - newName := strings.ReplaceAll(value, string(filepath.Separator), "|") - match, _ := filepath.Match(filter, newName) - return match - } - return false -} - -// MatchLabelFilters matches labels and returns true if they are valid -func MatchLabelFilters(filterValues []string, labels map[string]string) bool { -outer: - for _, filterValue := range filterValues { - filterArray := strings.SplitN(filterValue, "=", 2) - filterKey := filterArray[0] - if len(filterArray) > 1 { - filterValue = filterArray[1] - } else { - filterValue = "" - } - for labelKey, labelValue := range labels { - if ((labelKey == filterKey) || matchPattern(filterKey, labelKey)) && (filterValue == "" || labelValue == filterValue) { - continue outer - } - } - return false - } - return true -} diff --git a/pkg/util/filters_test.go b/pkg/util/filters_test.go index 47259013e..8e45ea61c 100644 --- a/pkg/util/filters_test.go +++ b/pkg/util/filters_test.go @@ -2,6 +2,8 @@ package util import ( "testing" + + "github.com/containers/common/pkg/filters" ) func TestMatchLabelFilters(t *testing.T) { @@ -71,7 +73,7 @@ func TestMatchLabelFilters(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - if got := MatchLabelFilters(tt.args.filterValues, tt.args.labels); got != tt.want { + if got := filters.MatchLabelFilters(tt.args.filterValues, tt.args.labels); got != tt.want { t.Errorf("MatchLabelFilters() = %v, want %v", got, tt.want) } }) diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index d1771f336..8f5e1a0b6 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -223,6 +223,26 @@ var _ = Describe("Podman checkpoint", func() { Expect(result).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) + + // Restore a container which name is equal to a image name (#15055) + localRunString = getRunString([]string{"--name", "alpine", "quay.io/libpod/alpine:latest", "top"}) + session = podmanTest.Podman(localRunString) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + result = podmanTest.Podman([]string{"container", "checkpoint", "alpine"}) + result.WaitWithDefaultTimeout() + + Expect(result).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited")) + + result = podmanTest.Podman([]string{"container", "restore", "alpine"}) + result.WaitWithDefaultTimeout() + + Expect(result).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) }) It("podman pause a checkpointed container by id", func() { diff --git a/test/e2e/manifest_test.go b/test/e2e/manifest_test.go index 1f58419a1..a7fcd1559 100644 --- a/test/e2e/manifest_test.go +++ b/test/e2e/manifest_test.go @@ -339,6 +339,16 @@ var _ = Describe("Podman manifest", func() { push = podmanTest.Podman([]string{"manifest", "push", "--tls-verify=false", "--creds=podmantest:wrongpasswd", "foo", "localhost:" + registry.Port + "/credstest"}) push.WaitWithDefaultTimeout() Expect(push).To(ExitWithError()) + + // push --rm after pull image (#15033) + push = podmanTest.Podman([]string{"manifest", "push", "--rm", "--tls-verify=false", "--creds=" + registry.User + ":" + registry.Password, "foo", "localhost:" + registry.Port + "/rmtest"}) + push.WaitWithDefaultTimeout() + Expect(push).Should(Exit(0)) + + session = podmanTest.Podman([]string{"images", "-q", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) It("push with error", func() { @@ -348,8 +358,8 @@ var _ = Describe("Podman manifest", func() { Expect(session.ErrorToString()).NotTo(BeEmpty()) }) - It("push --rm", func() { - SkipIfRemote("remote does not support --rm") + It("push --rm to local directory", func() { + SkipIfRemote("manifest push to dir not supported in remote mode") session := podmanTest.Podman([]string{"manifest", "create", "foo"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -365,13 +375,35 @@ var _ = Describe("Podman manifest", func() { session = podmanTest.Podman([]string{"manifest", "push", "--purge", "foo", "dir:" + dest}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) + session = podmanTest.Podman([]string{"images", "-q", "foo"}) session.WaitWithDefaultTimeout() - Expect(session).To(ExitWithError()) + Expect(session).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) - session = podmanTest.Podman([]string{"manifest", "rm", "foo1", "foo2"}) + // push --rm after pull image (#15033) + session = podmanTest.Podman([]string{"pull", "quay.io/libpod/testdigest_v2s2"}) session.WaitWithDefaultTimeout() - Expect(session).To(ExitWithError()) + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"manifest", "create", "bar"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + session = podmanTest.Podman([]string{"manifest", "add", "bar", "quay.io/libpod/testdigest_v2s2"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + session = podmanTest.Podman([]string{"manifest", "push", "--rm", "bar", "dir:" + dest}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + session = podmanTest.Podman([]string{"images", "-q", "bar"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + + session = podmanTest.Podman([]string{"manifest", "rm", "foo", "bar"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(ExitWithError()) + Expect(session.ErrorToString()).To(ContainSubstring("foo: image not known")) + Expect(session.ErrorToString()).To(ContainSubstring("bar: image not known")) }) It("exists", func() { diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go index 89cc65540..0b1d68aea 100644 --- a/test/e2e/prune_test.go +++ b/test/e2e/prune_test.go @@ -280,6 +280,24 @@ var _ = Describe("Podman prune", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(session.OutputToStringArray()).To(HaveLen(0)) + + // Create new network. + session = podmanTest.Podman([]string{"network", "create", "test1", "--label", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + // Remove all unused networks. + session = podmanTest.Podman([]string{"system", "prune", "-f", "--filter", "label!=foo"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToString()).Should(Equal("Total reclaimed space: 0B")) + + // Unused networks removed. + session = podmanTest.Podman([]string{"network", "ls", "-q", "--filter", "name=^test1$"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + // label should make sure we do not remove this network + Expect(session.OutputToStringArray()).To(HaveLen(1)) }) It("podman system prune - pod,container stopped", func() { diff --git a/test/system/010-images.bats b/test/system/010-images.bats index 638910302..aa390f236 100644 --- a/test/system/010-images.bats +++ b/test/system/010-images.bats @@ -317,4 +317,11 @@ Deleted: $pauseID" is "$output" "" } +@test "podman image rm --force bogus" { + run_podman 1 image rm bogus + is "$output" "Error: bogus: image not known" "Should print error" + run_podman image rm --force bogus + is "$output" "" "Should print no output" +} + # vim: filetype=sh diff --git a/test/system/055-rm.bats b/test/system/055-rm.bats index 0ef2216b8..dcd679a1f 100644 --- a/test/system/055-rm.bats +++ b/test/system/055-rm.bats @@ -96,4 +96,11 @@ load helpers run_podman 137 run --name $rand $IMAGE sleep 30 } +@test "podman container rm --force bogus" { + run_podman 1 container rm bogus + is "$output" "Error: no container with name or ID \"bogus\" found: no such container" "Should print error" + run_podman container rm --force bogus + is "$output" "" "Should print no output" +} + # vim: filetype=sh diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats index 18e806699..6829c6a78 100644 --- a/test/system/160-volumes.bats +++ b/test/system/160-volumes.bats @@ -473,4 +473,11 @@ EOF run_podman image rm --force localhost/volume_image } +@test "podman volume rm --force bogus" { + run_podman 1 volume rm bogus + 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" +} + # vim: filetype=sh diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats index 667e2baef..da2f7cd59 100644 --- a/test/system/200-pod.bats +++ b/test/system/200-pod.bats @@ -547,4 +547,11 @@ io.max | $lomajmin rbps=1048576 wbps=1048576 riops=max wiops=max wait } +@test "podman pod rm --force bogus" { + run_podman 1 pod rm bogus + is "$output" "Error: .*bogus.*: no such pod" "Should print error" + run_podman pod rm --force bogus + is "$output" "" "Should print no output" +} + # vim: filetype=sh diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats index f45540f5f..b9a173c2a 100644 --- a/test/system/500-networking.bats +++ b/test/system/500-networking.bats @@ -260,7 +260,7 @@ load helpers run_podman rm -t 0 -f $cid run_podman network rm $mynetname - run_podman 1 network rm -f $mynetname + run_podman 1 network rm $mynetname } @test "podman network reload" { @@ -760,4 +760,11 @@ EOF done } +@test "podman network rm --force bogus" { + run_podman 1 network rm bogus + is "$output" "Error: unable to find network with name or ID bogus: network not found" "Should print error" + run_podman network rm --force bogus + is "$output" "" "Should print no output" +} + # vim: filetype=sh |