diff options
author | baude <bbaude@redhat.com> | 2019-09-09 15:37:35 -0500 |
---|---|---|
committer | baude <bbaude@redhat.com> | 2019-09-12 14:03:52 -0500 |
commit | b94ea07265045f447572c264ef62e7960f484b58 (patch) | |
tree | 10ed1b8a28515fb083d4c306055e1db9da3c1f81 /pkg/adapter | |
parent | af8fedcc78674d71d43ca3000438c42b7b6b6994 (diff) | |
download | podman-b94ea07265045f447572c264ef62e7960f484b58.tar.gz podman-b94ea07265045f447572c264ef62e7960f484b58.tar.bz2 podman-b94ea07265045f447572c264ef62e7960f484b58.zip |
enhance podman network rm
when removing a podman network, we need to make sure we delete the
network interface if one was ever created (by running a container).
also, when removing networks, we check if any containers are using the
network. if they are, we error out unless the user provides a 'force'
option which will remove the containers in question.
Signed-off-by: baude <bbaude@redhat.com>
Diffstat (limited to 'pkg/adapter')
-rw-r--r-- | pkg/adapter/network.go | 68 |
1 files changed, 61 insertions, 7 deletions
diff --git a/pkg/adapter/network.go b/pkg/adapter/network.go index e4a160767..d407984ce 100644 --- a/pkg/adapter/network.go +++ b/pkg/adapter/network.go @@ -3,9 +3,9 @@ package adapter import ( + "context" "encoding/json" "fmt" - "github.com/containers/libpod/pkg/util" "io/ioutil" "os" "path/filepath" @@ -14,6 +14,7 @@ import ( cniversion "github.com/containernetworking/cni/pkg/version" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/pkg/network" + "github.com/containers/libpod/pkg/util" "github.com/pkg/errors" ) @@ -85,16 +86,69 @@ func (r *LocalRuntime) NetworkInspect(cli *cliconfig.NetworkInspectValues) error } // NetworkRemove deletes one or more CNI networks -func (r *LocalRuntime) NetworkRemove(cli *cliconfig.NetworkRmValues) error { +func (r *LocalRuntime) NetworkRemove(ctx context.Context, cli *cliconfig.NetworkRmValues) ([]string, map[string]error, error) { + var ( + networkRmSuccesses []string + lastError error + ) + networkRmErrors := make(map[string]error) + for _, name := range cli.InputArgs { - cniPath, err := network.GetCNIConfigPathByName(name) + containers, err := r.GetAllContainers() if err != nil { - return err + return networkRmSuccesses, networkRmErrors, err } - if err := os.Remove(cniPath); err != nil { - return err + if err := r.removeNetwork(ctx, name, containers, cli.Force); err != nil { + if lastError != nil { + networkRmErrors[name] = lastError + } + lastError = err + } else { + networkRmSuccesses = append(networkRmSuccesses, fmt.Sprintf("Deleted: %s\n", name)) + } + } + return networkRmSuccesses, networkRmErrors, lastError +} + +// removeNetwork removes a single network and its containers given a force bool +func (r *LocalRuntime) removeNetwork(ctx context.Context, name string, containers []*Container, force bool) error { + cniPath, err := network.GetCNIConfigPathByName(name) + if err != nil { + return err + } + // We need to iterate containers looking to see if they belong to the given network + for _, c := range containers { + if util.StringInSlice(name, c.Config().Networks) { + // if user passes force, we nuke containers + if force { + if err := r.RemoveContainer(ctx, c.Container, true, true); err != nil { + return err + } + } else { + // Without the the force option, we return an error + return errors.Errorf("%q has associated containers with it. use -f to forcibly delete containers", name) + } + } - fmt.Printf("Deleted: %s\n", name) + } + // Before we delete the configuration file, we need to make sure we can read and parse + // it to get the network interface name so we can remove that too + interfaceName, err := network.GetInterfaceNameFromConfig(cniPath) + if err != nil { + return errors.Wrapf(err, "failed to find network interface name in %q", cniPath) + } + liveNetworkNames, err := network.GetLiveNetworkNames() + if err != nil { + return errors.Wrapf(err, "failed to get live network names") + } + if util.StringInSlice(interfaceName, liveNetworkNames) { + if err := network.RemoveInterface(interfaceName); err != nil { + return errors.Wrapf(err, "failed to delete the network interface %q", interfaceName) + } + } + // Remove the configuration file + if err := os.Remove(cniPath); err != nil { + return errors.Wrapf(err, "failed to remove network configuration file %q", cniPath) } return nil } |