mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-08-05 00:15:44 +00:00
feat: add --ignore flag to network rm
Add `--ignore` to `podman network rm` so removing a missing network returns success instead of exit code 1. Keep existing error behavior for networks in use and other failures. This commit message was translated from Korean to English using an LLM. Fixes: #28363 Signed-off-by: KyounghoonJang <matkimchi_@naver.com>
This commit is contained in:
parent
1fecb62b34
commit
9e38f86993
12 changed files with 70 additions and 7 deletions
|
|
@ -34,6 +34,7 @@ var networkRmOptions entities.NetworkRmOptions
|
|||
|
||||
func networkRmFlags(flags *pflag.FlagSet) {
|
||||
flags.BoolVarP(&networkRmOptions.Force, "force", "f", false, "remove any containers using network")
|
||||
flags.BoolVarP(&networkRmOptions.Ignore, "ignore", "i", false, "ignore if a specified network does not exist")
|
||||
timeFlagName := "time"
|
||||
flags.IntVarP(&stopTimeout, timeFlagName, "t", int(containerConfig.Engine.StopTimeout), "Seconds to wait for running containers to stop before killing the container")
|
||||
_ = networkrmCommand.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone)
|
||||
|
|
@ -60,7 +61,7 @@ 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()) {
|
||||
if (networkRmOptions.Force || networkRmOptions.Ignore) && strings.Contains(err.Error(), define.ErrNoSuchNetwork.Error()) {
|
||||
return nil
|
||||
}
|
||||
setExitCode(err)
|
||||
|
|
@ -70,7 +71,7 @@ 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()) {
|
||||
if (networkRmOptions.Force || networkRmOptions.Ignore) && strings.Contains(r.Err.Error(), define.ErrNoSuchNetwork.Error()) {
|
||||
continue
|
||||
}
|
||||
setExitCode(r.Err)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@ Delete one or more Podman networks.
|
|||
The `force` option removes all containers that use the named network. If the container is
|
||||
running, the container is stopped and removed.
|
||||
|
||||
#### **--ignore**, **-i**
|
||||
|
||||
Ignore the error when a specified network does not exist.
|
||||
Other failures, including a network being in use, are still returned.
|
||||
|
||||
#### **--time**, **-t**=*seconds*
|
||||
|
||||
Seconds to wait before forcibly stopping the running containers that are using the specified network. The --force option must be specified to use the --time option. Use -1 for infinite wait.
|
||||
|
|
|
|||
|
|
@ -109,7 +109,8 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
|
||||
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
|
||||
query := struct {
|
||||
Force bool `schema:"force"`
|
||||
Force bool `schema:"force"`
|
||||
Ignore bool `schema:"ignore"`
|
||||
}{
|
||||
// override any golang type defaults
|
||||
}
|
||||
|
|
@ -121,7 +122,8 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
name := utils.GetName(r)
|
||||
|
||||
options := entities.NetworkRmOptions{
|
||||
Force: query.Force,
|
||||
Force: query.Force,
|
||||
Ignore: query.Ignore,
|
||||
}
|
||||
ic := abi.ContainerEngine{Libpod: runtime}
|
||||
reports, err := ic.NetworkRm(r.Context(), []string{name}, options)
|
||||
|
|
@ -129,6 +131,10 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
utils.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
if len(reports) == 0 {
|
||||
utils.WriteResponse(w, http.StatusOK, []*entities.NetworkRmReport{})
|
||||
return
|
||||
}
|
||||
if reports[0].Err != nil {
|
||||
// If the network cannot be found, we return a 404.
|
||||
if errors.Is(reports[0].Err, define.ErrNoSuchNetwork) {
|
||||
|
|
|
|||
|
|
@ -237,6 +237,10 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
|
|||
// name: force
|
||||
// type: boolean
|
||||
// description: remove containers associated with network
|
||||
// - in: query
|
||||
// name: ignore
|
||||
// type: boolean
|
||||
// description: ignore if a specified network does not exist
|
||||
// produces:
|
||||
// - application/json
|
||||
// responses:
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ type InspectOptions struct{}
|
|||
type RemoveOptions struct {
|
||||
// Force removes the network even if it is being used
|
||||
Force *bool
|
||||
Ignore *bool
|
||||
Timeout *uint
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,21 @@ func (o *RemoveOptions) GetForce() bool {
|
|||
return *o.Force
|
||||
}
|
||||
|
||||
// WithIgnore set field Ignore to given value
|
||||
func (o *RemoveOptions) WithIgnore(value bool) *RemoveOptions {
|
||||
o.Ignore = &value
|
||||
return o
|
||||
}
|
||||
|
||||
// GetIgnore returns value of field Ignore
|
||||
func (o *RemoveOptions) GetIgnore() bool {
|
||||
if o.Ignore == nil {
|
||||
var z bool
|
||||
return z
|
||||
}
|
||||
return *o.Ignore
|
||||
}
|
||||
|
||||
// WithTimeout set field Timeout to given value
|
||||
func (o *RemoveOptions) WithTimeout(value uint) *RemoveOptions {
|
||||
o.Timeout = &value
|
||||
|
|
|
|||
|
|
@ -178,6 +178,12 @@ var _ = Describe("Podman networks", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(code).To(BeNumerically("==", http.StatusNotFound))
|
||||
|
||||
// removing a noName network with ignore should succeed
|
||||
options := new(network.RemoveOptions).WithIgnore(true)
|
||||
report, err := network.Remove(connText, "noName", options)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(report).To(BeEmpty())
|
||||
|
||||
// Removing an unused network should work
|
||||
name := "unused"
|
||||
net := types.Network{
|
||||
|
|
@ -185,7 +191,7 @@ var _ = Describe("Podman networks", func() {
|
|||
}
|
||||
_, err = network.Create(connText, &net)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
report, err := network.Remove(connText, name, nil)
|
||||
report, err = network.Remove(connText, name, nil)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(report[0].Name).To(Equal(name))
|
||||
|
||||
|
|
@ -211,7 +217,7 @@ var _ = Describe("Podman networks", func() {
|
|||
// Removing with a network in use with force should work with a stopped container
|
||||
err = containers.Stop(connText, container, new(containers.StopOptions).WithTimeout(0))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
options := new(network.RemoveOptions).WithForce(true)
|
||||
options = new(network.RemoveOptions).WithForce(true)
|
||||
report, err = network.Remove(connText, name, options)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(report[0].Name).To(Equal(name))
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ type NetworkReloadReport = entitiesTypes.NetworkReloadReport
|
|||
// NetworkRmOptions describes options for removing networks
|
||||
type NetworkRmOptions struct {
|
||||
Force bool
|
||||
Ignore bool
|
||||
Timeout *uint
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -168,6 +168,9 @@ func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, o
|
|||
return reports, err
|
||||
}
|
||||
if err := ic.Libpod.Network().NetworkRemove(name); err != nil {
|
||||
if options.Ignore && errors.Is(err, define.ErrNoSuchNetwork) {
|
||||
continue
|
||||
}
|
||||
report.Err = err
|
||||
}
|
||||
if len(net.Name) != 0 {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func (ic *ContainerEngine) NetworkReload(_ context.Context, _ []string, _ entiti
|
|||
|
||||
func (ic *ContainerEngine) NetworkRm(_ context.Context, namesOrIds []string, opts entities.NetworkRmOptions) ([]*entities.NetworkRmReport, error) {
|
||||
reports := make([]*entities.NetworkRmReport, 0, len(namesOrIds))
|
||||
options := new(network.RemoveOptions).WithForce(opts.Force)
|
||||
options := new(network.RemoveOptions).WithForce(opts.Force).WithIgnore(opts.Ignore)
|
||||
if opts.Timeout != nil {
|
||||
options = options.WithTimeout(*opts.Timeout)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -426,6 +426,11 @@ var _ = Describe("Podman network", func() {
|
|||
Expect(session).Should(ExitWithError(1, "unable to find network with name or ID bogus: network not found"))
|
||||
})
|
||||
|
||||
It("podman network remove --ignore bogus", func() {
|
||||
session := podmanTest.PodmanExitCleanly("network", "rm", "--ignore", "bogus")
|
||||
Expect(session.OutputToString()).To(Equal(""))
|
||||
})
|
||||
|
||||
It("podman network remove --force with pod", func() {
|
||||
netName := "net-" + stringid.GenerateRandomID()
|
||||
session := podmanTest.Podman([]string{"network", "create", netName})
|
||||
|
|
|
|||
|
|
@ -978,6 +978,22 @@ EOF
|
|||
assert "$output" !~ "$(safename)" "all networks from this test should be gone"
|
||||
}
|
||||
|
||||
# bats test_tags=ci:parallel
|
||||
@test "podman network rm --ignore bogus" {
|
||||
bogusnet=bogusnet-$(safename)
|
||||
run_podman 1 network rm $bogusnet
|
||||
is "$output" "Error: unable to find network with name or ID $bogusnet: network not found" "Should print error"
|
||||
run_podman network rm --ignore $bogusnet
|
||||
is "$output" "" "Should print no output"
|
||||
|
||||
netname=testnet-$(safename)
|
||||
run_podman network create $netname
|
||||
run_podman network rm --ignore $bogusnet $netname
|
||||
assert "$output" = "$netname" "rm network"
|
||||
run_podman network ls -q
|
||||
assert "$output" !~ "$(safename)" "all networks from this test should be gone"
|
||||
}
|
||||
|
||||
# bats test_tags=ci:parallel
|
||||
@test "podman network rm --dns-option " {
|
||||
dns_opt=dns$(random_string)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue