mirror of
https://github.com/containers/podman.git
synced 2025-06-23 02:18:13 +08:00
Merge pull request #7825 from rhatdan/exitcode
Fix handling of remove of bogus volumes, networks and Pods
This commit is contained in:
@ -105,7 +105,7 @@ func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit
|
|||||||
}
|
}
|
||||||
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 setExit && len(namesOrIDs) < 2 {
|
if setExit {
|
||||||
setExitCode(err)
|
setExitCode(err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@ -132,7 +132,7 @@ func setExitCode(err error) {
|
|||||||
switch {
|
switch {
|
||||||
case cause == define.ErrNoSuchCtr:
|
case cause == define.ErrNoSuchCtr:
|
||||||
registry.SetExitCode(1)
|
registry.SetExitCode(1)
|
||||||
case strings.Contains(cause.Error(), define.ErrNoSuchImage.Error()):
|
case strings.Contains(cause.Error(), define.ErrNoSuchCtr.Error()):
|
||||||
registry.SetExitCode(1)
|
registry.SetExitCode(1)
|
||||||
case cause == define.ErrCtrStateInvalid:
|
case cause == define.ErrCtrStateInvalid:
|
||||||
registry.SetExitCode(2)
|
registry.SetExitCode(2)
|
||||||
|
@ -2,10 +2,13 @@ package network
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/podman/v2/cmd/podman/registry"
|
"github.com/containers/podman/v2/cmd/podman/registry"
|
||||||
"github.com/containers/podman/v2/cmd/podman/utils"
|
"github.com/containers/podman/v2/cmd/podman/utils"
|
||||||
|
"github.com/containers/podman/v2/libpod/define"
|
||||||
"github.com/containers/podman/v2/pkg/domain/entities"
|
"github.com/containers/podman/v2/pkg/domain/entities"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
@ -47,14 +50,30 @@ func networkRm(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
responses, err := registry.ContainerEngine().NetworkRm(registry.Context(), args, networkRmOptions)
|
responses, err := registry.ContainerEngine().NetworkRm(registry.Context(), args, networkRmOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
setExitCode(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, r := range responses {
|
for _, r := range responses {
|
||||||
if r.Err == nil {
|
if r.Err == nil {
|
||||||
fmt.Println(r.Name)
|
fmt.Println(r.Name)
|
||||||
} else {
|
} else {
|
||||||
|
setExitCode(r.Err)
|
||||||
errs = append(errs, r.Err)
|
errs = append(errs, r.Err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errs.PrintErrors()
|
return errs.PrintErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setExitCode(err error) {
|
||||||
|
cause := errors.Cause(err)
|
||||||
|
switch {
|
||||||
|
case cause == define.ErrNoSuchNetwork:
|
||||||
|
registry.SetExitCode(1)
|
||||||
|
case strings.Contains(cause.Error(), define.ErrNoSuchNetwork.Error()):
|
||||||
|
registry.SetExitCode(1)
|
||||||
|
case cause == define.ErrNetworkInUse:
|
||||||
|
registry.SetExitCode(2)
|
||||||
|
case strings.Contains(cause.Error(), define.ErrNetworkInUse.Error()):
|
||||||
|
registry.SetExitCode(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,12 +3,15 @@ package pods
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/podman/v2/cmd/podman/common"
|
"github.com/containers/podman/v2/cmd/podman/common"
|
||||||
"github.com/containers/podman/v2/cmd/podman/registry"
|
"github.com/containers/podman/v2/cmd/podman/registry"
|
||||||
"github.com/containers/podman/v2/cmd/podman/utils"
|
"github.com/containers/podman/v2/cmd/podman/utils"
|
||||||
"github.com/containers/podman/v2/cmd/podman/validate"
|
"github.com/containers/podman/v2/cmd/podman/validate"
|
||||||
|
"github.com/containers/podman/v2/libpod/define"
|
||||||
"github.com/containers/podman/v2/pkg/domain/entities"
|
"github.com/containers/podman/v2/pkg/domain/entities"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -73,6 +76,7 @@ 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 {
|
||||||
|
setExitCode(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,8 +87,19 @@ func removePods(namesOrIDs []string, rmOptions entities.PodRmOptions, printIDs b
|
|||||||
fmt.Println(r.Id)
|
fmt.Println(r.Id)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
setExitCode(r.Err)
|
||||||
errs = append(errs, r.Err)
|
errs = append(errs, r.Err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errs.PrintErrors()
|
return errs.PrintErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setExitCode(err error) {
|
||||||
|
cause := errors.Cause(err)
|
||||||
|
switch {
|
||||||
|
case cause == define.ErrNoSuchPod:
|
||||||
|
registry.SetExitCode(1)
|
||||||
|
case strings.Contains(cause.Error(), define.ErrNoSuchPod.Error()):
|
||||||
|
registry.SetExitCode(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,9 +3,11 @@ package volumes
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/podman/v2/cmd/podman/registry"
|
"github.com/containers/podman/v2/cmd/podman/registry"
|
||||||
"github.com/containers/podman/v2/cmd/podman/utils"
|
"github.com/containers/podman/v2/cmd/podman/utils"
|
||||||
|
"github.com/containers/podman/v2/libpod/define"
|
||||||
"github.com/containers/podman/v2/pkg/domain/entities"
|
"github.com/containers/podman/v2/pkg/domain/entities"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -51,14 +53,30 @@ func rm(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
responses, err := registry.ContainerEngine().VolumeRm(context.Background(), args, rmOptions)
|
responses, err := registry.ContainerEngine().VolumeRm(context.Background(), args, rmOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
setExitCode(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, r := range responses {
|
for _, r := range responses {
|
||||||
if r.Err == nil {
|
if r.Err == nil {
|
||||||
fmt.Println(r.Id)
|
fmt.Println(r.Id)
|
||||||
} else {
|
} else {
|
||||||
|
setExitCode(r.Err)
|
||||||
errs = append(errs, r.Err)
|
errs = append(errs, r.Err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errs.PrintErrors()
|
return errs.PrintErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setExitCode(err error) {
|
||||||
|
cause := errors.Cause(err)
|
||||||
|
switch {
|
||||||
|
case cause == define.ErrNoSuchVolume:
|
||||||
|
registry.SetExitCode(1)
|
||||||
|
case strings.Contains(cause.Error(), define.ErrNoSuchVolume.Error()):
|
||||||
|
registry.SetExitCode(1)
|
||||||
|
case cause == define.ErrVolumeBeingUsed:
|
||||||
|
registry.SetExitCode(2)
|
||||||
|
case strings.Contains(cause.Error(), define.ErrVolumeBeingUsed.Error()):
|
||||||
|
registry.SetExitCode(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -31,6 +31,15 @@ Delete the `fred` network and all containers associated with the network.
|
|||||||
Deleted: fred
|
Deleted: fred
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Exit Status
|
||||||
|
**0** All specified networks removed
|
||||||
|
|
||||||
|
**1** One of the specified networks did not exist, and no other failures
|
||||||
|
|
||||||
|
**2** The network is in use by a container or a Pod
|
||||||
|
|
||||||
|
**125** The command fails for any other reason
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
podman(1), podman-network(1), podman-network-inspect(1)
|
podman(1), podman-network(1), podman-network-inspect(1)
|
||||||
|
|
||||||
|
@ -49,6 +49,15 @@ podman pod rm -fa
|
|||||||
|
|
||||||
podman pod rm --pod-id-file /path/to/id/file
|
podman pod rm --pod-id-file /path/to/id/file
|
||||||
|
|
||||||
|
## Exit Status
|
||||||
|
**0** All specified pods removed
|
||||||
|
|
||||||
|
**1** One of the specified pods did not exist, and no other failures
|
||||||
|
|
||||||
|
**2** One of the specified pods is attached to a container
|
||||||
|
|
||||||
|
**125** The command fails for any other reason
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
podman-pod(1)
|
podman-pod(1)
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ $ podman rm -f --latest
|
|||||||
|
|
||||||
**2** One of the specified containers is paused or running
|
**2** One of the specified containers is paused or running
|
||||||
|
|
||||||
**125** The command fails for a reason other than container did not exist or is paused/running
|
**125** The command fails for any other reason
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
podman(1), podman-image-rm(1), podman-ps(1), podman-build(1)
|
podman(1), podman-image-rm(1), podman-ps(1), podman-build(1)
|
||||||
|
@ -47,7 +47,7 @@ $ podman rmi -a -f
|
|||||||
|
|
||||||
**2** One of the specified images has child images or is being used by a container
|
**2** One of the specified images has child images or is being used by a container
|
||||||
|
|
||||||
**125** The command fails for a reason other than an image did not exist or is in use
|
**125** The command fails for any other reason
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
podman(1)
|
podman(1)
|
||||||
|
@ -39,6 +39,15 @@ $ podman volume rm --all
|
|||||||
$ podman volume rm --force myvol
|
$ podman volume rm --force myvol
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Exit Status
|
||||||
|
**0** All specified volumes removed
|
||||||
|
|
||||||
|
**1** One of the specified volumes did not exist, and no other failures
|
||||||
|
|
||||||
|
**2** One of the specified volumes is being used by a container
|
||||||
|
|
||||||
|
**125** The command fails for any other reason
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
podman-volume(1)
|
podman-volume(1)
|
||||||
|
|
||||||
|
@ -162,6 +162,9 @@ var (
|
|||||||
// in a pod. This cannot be done as the infra container has all the network information
|
// in a pod. This cannot be done as the infra container has all the network information
|
||||||
ErrNetworkOnPodContainer = errors.New("network cannot be configured when it is shared with a pod")
|
ErrNetworkOnPodContainer = errors.New("network cannot be configured when it is shared with a pod")
|
||||||
|
|
||||||
|
// ErrNetworkInUse indicates the requested operation failed because the network was in use
|
||||||
|
ErrNetworkInUse = errors.New("network is being used")
|
||||||
|
|
||||||
// ErrStoreNotInitialized indicates that the container storage was never
|
// ErrStoreNotInitialized indicates that the container storage was never
|
||||||
// initialized.
|
// initialized.
|
||||||
ErrStoreNotInitialized = errors.New("the container storage was never initialized")
|
ErrStoreNotInitialized = errors.New("the container storage was never initialized")
|
||||||
|
@ -92,8 +92,8 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
if reports[0].Err != nil {
|
if reports[0].Err != nil {
|
||||||
// If the network cannot be found, we return a 404.
|
// If the network cannot be found, we return a 404.
|
||||||
if errors.Cause(err) == define.ErrNoSuchNetwork {
|
if errors.Cause(reports[0].Err) == define.ErrNoSuchNetwork {
|
||||||
utils.Error(w, "Something went wrong", http.StatusNotFound, err)
|
utils.Error(w, "Something went wrong", http.StatusNotFound, reports[0].Err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/containernetworking/cni/libcni"
|
"github.com/containernetworking/cni/libcni"
|
||||||
cniversion "github.com/containernetworking/cni/pkg/version"
|
cniversion "github.com/containernetworking/cni/pkg/version"
|
||||||
"github.com/containers/podman/v2/libpod"
|
"github.com/containers/podman/v2/libpod"
|
||||||
|
"github.com/containers/podman/v2/libpod/define"
|
||||||
"github.com/containers/podman/v2/pkg/domain/entities"
|
"github.com/containers/podman/v2/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v2/pkg/network"
|
"github.com/containers/podman/v2/pkg/network"
|
||||||
"github.com/containers/podman/v2/pkg/util"
|
"github.com/containers/podman/v2/pkg/util"
|
||||||
@ -85,7 +86,7 @@ func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, o
|
|||||||
// if user passes force, we nuke containers and pods
|
// if user passes force, we nuke containers and pods
|
||||||
if !options.Force {
|
if !options.Force {
|
||||||
// Without the force option, we return an error
|
// Without the force option, we return an error
|
||||||
return reports, errors.Errorf("%q has associated containers with it. Use -f to forcibly delete containers and pods", name)
|
return reports, errors.Wrapf(define.ErrNetworkInUse, "%q has associated containers with it. Use -f to forcibly delete containers and pods", name)
|
||||||
}
|
}
|
||||||
if c.IsInfra() {
|
if c.IsInfra() {
|
||||||
// if we have a infra container we need to remove the pod
|
// if we have a infra container we need to remove the pod
|
||||||
|
@ -265,6 +265,12 @@ var _ = Describe("Podman network", func() {
|
|||||||
Expect(rmAll.ExitCode()).To(BeZero())
|
Expect(rmAll.ExitCode()).To(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman network remove bogus", func() {
|
||||||
|
session := podmanTest.Podman([]string{"network", "rm", "bogus"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(1))
|
||||||
|
})
|
||||||
|
|
||||||
It("podman network remove --force with pod", func() {
|
It("podman network remove --force with pod", func() {
|
||||||
netName := "testnet"
|
netName := "testnet"
|
||||||
session := podmanTest.Podman([]string{"network", "create", netName})
|
session := podmanTest.Podman([]string{"network", "create", netName})
|
||||||
@ -280,6 +286,10 @@ var _ = Describe("Podman network", func() {
|
|||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session.ExitCode()).To(BeZero())
|
Expect(session.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"network", "rm", netName})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(2))
|
||||||
|
|
||||||
session = podmanTest.Podman([]string{"network", "rm", "--force", netName})
|
session = podmanTest.Podman([]string{"network", "rm", "--force", netName})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session.ExitCode()).To(BeZero())
|
Expect(session.ExitCode()).To(BeZero())
|
||||||
|
@ -195,8 +195,7 @@ var _ = Describe("Podman pod rm", func() {
|
|||||||
It("podman rm bogus pod", func() {
|
It("podman rm bogus pod", func() {
|
||||||
session := podmanTest.Podman([]string{"pod", "rm", "bogus"})
|
session := podmanTest.Podman([]string{"pod", "rm", "bogus"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
// TODO: `podman rm` returns 1 for a bogus container. Should the RC be consistent?
|
Expect(session.ExitCode()).To(Equal(1))
|
||||||
Expect(session.ExitCode()).To(Equal(125))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman rm bogus pod and a running pod", func() {
|
It("podman rm bogus pod and a running pod", func() {
|
||||||
@ -209,11 +208,11 @@ var _ = Describe("Podman pod rm", func() {
|
|||||||
|
|
||||||
session = podmanTest.Podman([]string{"pod", "rm", "bogus", "test1"})
|
session = podmanTest.Podman([]string{"pod", "rm", "bogus", "test1"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session.ExitCode()).To(Equal(125))
|
Expect(session.ExitCode()).To(Equal(1))
|
||||||
|
|
||||||
session = podmanTest.Podman([]string{"pod", "rm", "test1", "bogus"})
|
session = podmanTest.Podman([]string{"pod", "rm", "test1", "bogus"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session.ExitCode()).To(Equal(125))
|
Expect(session.ExitCode()).To(Equal(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman rm --ignore bogus pod and a running pod", func() {
|
It("podman rm --ignore bogus pod and a running pod", func() {
|
||||||
|
@ -228,11 +228,11 @@ var _ = Describe("Podman rm", func() {
|
|||||||
|
|
||||||
session = podmanTest.Podman([]string{"rm", "bogus", "test1"})
|
session = podmanTest.Podman([]string{"rm", "bogus", "test1"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session.ExitCode()).To(Equal(125))
|
Expect(session.ExitCode()).To(Equal(1))
|
||||||
|
|
||||||
session = podmanTest.Podman([]string{"rm", "test1", "bogus"})
|
session = podmanTest.Podman([]string{"rm", "test1", "bogus"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session.ExitCode()).To(Equal(125))
|
Expect(session.ExitCode()).To(Equal(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman rm --ignore bogus container and a running container", func() {
|
It("podman rm --ignore bogus container and a running container", func() {
|
||||||
|
@ -55,7 +55,7 @@ var _ = Describe("Podman volume rm", func() {
|
|||||||
|
|
||||||
session = podmanTest.Podman([]string{"volume", "rm", "myvol"})
|
session = podmanTest.Podman([]string{"volume", "rm", "myvol"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).To(ExitWithError())
|
Expect(session.ExitCode()).To(Equal(2))
|
||||||
Expect(session.ErrorToString()).To(ContainSubstring(cid))
|
Expect(session.ErrorToString()).To(ContainSubstring(cid))
|
||||||
|
|
||||||
session = podmanTest.Podman([]string{"volume", "rm", "-f", "myvol"})
|
session = podmanTest.Podman([]string{"volume", "rm", "-f", "myvol"})
|
||||||
@ -70,6 +70,12 @@ var _ = Describe("Podman volume rm", func() {
|
|||||||
podmanTest.Cleanup()
|
podmanTest.Cleanup()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman volume remove bogus", func() {
|
||||||
|
session := podmanTest.Podman([]string{"volume", "rm", "bogus"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(1))
|
||||||
|
})
|
||||||
|
|
||||||
It("podman rm with --all flag", func() {
|
It("podman rm with --all flag", func() {
|
||||||
session := podmanTest.Podman([]string{"volume", "create", "myvol"})
|
session := podmanTest.Podman([]string{"volume", "create", "myvol"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
|
@ -99,7 +99,7 @@ load helpers
|
|||||||
"Trying to create an already-existing network"
|
"Trying to create an already-existing network"
|
||||||
|
|
||||||
run_podman network rm $mynetname
|
run_podman network rm $mynetname
|
||||||
run_podman 125 network rm $mynetname
|
run_podman 1 network rm $mynetname
|
||||||
|
|
||||||
# rootless CNI leaves behind an image pulled by SHA, hence with no tag.
|
# rootless CNI leaves behind an image pulled by SHA, hence with no tag.
|
||||||
# Remove it if present; we can only remove it by ID.
|
# Remove it if present; we can only remove it by ID.
|
||||||
|
Reference in New Issue
Block a user