mirror of
https://github.com/containers/podman.git
synced 2025-06-07 15:48:37 +08:00

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>
132 lines
3.4 KiB
Go
132 lines
3.4 KiB
Go
package network
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/containernetworking/cni/libcni"
|
|
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// LoadCNIConfsFromDir loads all the CNI configurations from a dir
|
|
func LoadCNIConfsFromDir(dir string) ([]*libcni.NetworkConfigList, error) {
|
|
var configs []*libcni.NetworkConfigList
|
|
files, err := libcni.ConfFiles(dir, []string{".conflist"})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
sort.Strings(files)
|
|
|
|
for _, confFile := range files {
|
|
conf, err := libcni.ConfListFromFile(confFile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
configs = append(configs, conf)
|
|
}
|
|
return configs, nil
|
|
}
|
|
|
|
// GetCNIConfigPathByName finds a CNI network by name and
|
|
// returns its configuration file path
|
|
func GetCNIConfigPathByName(name string) (string, error) {
|
|
files, err := libcni.ConfFiles(CNIConfigDir, []string{".conflist"})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
for _, confFile := range files {
|
|
conf, err := libcni.ConfListFromFile(confFile)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if conf.Name == name {
|
|
return confFile, nil
|
|
}
|
|
}
|
|
return "", errors.Errorf("unable to find network configuration for %s", name)
|
|
}
|
|
|
|
// ReadRawCNIConfByName reads the raw CNI configuration for a CNI
|
|
// network by name
|
|
func ReadRawCNIConfByName(name string) ([]byte, error) {
|
|
confFile, err := GetCNIConfigPathByName(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
b, err := ioutil.ReadFile(confFile)
|
|
return b, err
|
|
}
|
|
|
|
// GetCNIPlugins returns a list of plugins that a given network
|
|
// has in the form of a string
|
|
func GetCNIPlugins(list *libcni.NetworkConfigList) string {
|
|
var plugins []string
|
|
for _, plug := range list.Plugins {
|
|
plugins = append(plugins, plug.Network.Type)
|
|
}
|
|
return strings.Join(plugins, ",")
|
|
}
|
|
|
|
// GetNetworksFromFilesystem gets all the networks from the cni configuration
|
|
// files
|
|
func GetNetworksFromFilesystem() ([]*allocator.Net, error) {
|
|
var cniNetworks []*allocator.Net
|
|
networks, err := LoadCNIConfsFromDir(CNIConfigDir)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, n := range networks {
|
|
for _, cniplugin := range n.Plugins {
|
|
if cniplugin.Network.Type == "bridge" {
|
|
ipamConf := allocator.Net{}
|
|
if err := json.Unmarshal(cniplugin.Bytes, &ipamConf); err != nil {
|
|
return nil, err
|
|
}
|
|
cniNetworks = append(cniNetworks, &ipamConf)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return cniNetworks, nil
|
|
}
|
|
|
|
// GetNetworkNamesFromFileSystem gets all the names from the cni network
|
|
// configuration files
|
|
func GetNetworkNamesFromFileSystem() ([]string, error) {
|
|
var networkNames []string
|
|
networks, err := LoadCNIConfsFromDir(CNIConfigDir)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, n := range networks {
|
|
networkNames = append(networkNames, n.Name)
|
|
}
|
|
return networkNames, nil
|
|
}
|
|
|
|
// GetInterfaceNameFromConfig returns the interface name for the bridge plugin
|
|
func GetInterfaceNameFromConfig(path string) (string, error) {
|
|
var name string
|
|
conf, err := libcni.ConfListFromFile(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
for _, cniplugin := range conf.Plugins {
|
|
if cniplugin.Network.Type == "bridge" {
|
|
plugin := make(map[string]interface{})
|
|
if err := json.Unmarshal(cniplugin.Bytes, &plugin); err != nil {
|
|
return "", err
|
|
}
|
|
name = plugin["bridge"].(string)
|
|
break
|
|
}
|
|
}
|
|
if len(name) == 0 {
|
|
return "", errors.New("unable to find interface name for network")
|
|
}
|
|
return name, nil
|
|
}
|