aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/cri-o/ocicni
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2018-07-12 09:51:31 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-07-12 21:45:47 +0000
commit4f699db8dad05b770b4e02d3de67137517c3463b (patch)
treea7f474b248d283dd8805da73bf2b63ca56e4fd67 /vendor/github.com/cri-o/ocicni
parente615b7d67124c548a3c7b422348821204ce32775 (diff)
downloadpodman-4f699db8dad05b770b4e02d3de67137517c3463b.tar.gz
podman-4f699db8dad05b770b4e02d3de67137517c3463b.tar.bz2
podman-4f699db8dad05b770b4e02d3de67137517c3463b.zip
Support multiple networks
This is a refresh of Dan William's PR #974 with a rebase and proper vendoring of ocicni and containernetworking/cni. It adds the ability to define multiple networks as so: podman run --network=net1,net2,foobar ... Signed-off-by: baude <bbaude@redhat.com> Closes: #1082 Approved by: baude
Diffstat (limited to 'vendor/github.com/cri-o/ocicni')
-rw-r--r--vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go410
-rw-r--r--vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go11
-rw-r--r--vendor/github.com/cri-o/ocicni/pkg/ocicni/types_unix.go10
-rw-r--r--vendor/github.com/cri-o/ocicni/pkg/ocicni/types_windows.go10
-rw-r--r--vendor/github.com/cri-o/ocicni/pkg/ocicni/util.go34
-rw-r--r--vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go71
-rw-r--r--vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go19
7 files changed, 383 insertions, 182 deletions
diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go
index e49c1dc84..33a3ae063 100644
--- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go
+++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go
@@ -4,13 +4,16 @@ import (
"errors"
"fmt"
"os"
- "os/exec"
+ "path"
"sort"
"strings"
"sync"
"github.com/containernetworking/cni/libcni"
+ cniinvoke "github.com/containernetworking/cni/pkg/invoke"
cnitypes "github.com/containernetworking/cni/pkg/types"
+ cnicurrent "github.com/containernetworking/cni/pkg/types/current"
+ cniversion "github.com/containernetworking/cni/pkg/version"
"github.com/fsnotify/fsnotify"
"github.com/sirupsen/logrus"
)
@@ -19,14 +22,16 @@ type cniNetworkPlugin struct {
loNetwork *cniNetwork
sync.RWMutex
- defaultNetwork *cniNetwork
+ defaultNetName string
+ networks map[string]*cniNetwork
- nsenterPath string
- pluginDir string
- cniDirs []string
- vendorCNIDirPrefix string
+ nsManager *nsManager
+ confDir string
+ binDirs []string
- monitorNetDirChan chan struct{}
+ shutdownChan chan struct{}
+ watcher *fsnotify.Watcher
+ done *sync.WaitGroup
// The pod map provides synchronization for a given pod's network
// operations. Each pod's setup/teardown/status operations
@@ -34,12 +39,17 @@ type cniNetworkPlugin struct {
// pods can proceed in parallel.
podsLock sync.Mutex
pods map[string]*podLock
+
+ // For testcases
+ exec cniinvoke.Exec
+ cacheDir string
}
type cniNetwork struct {
name string
+ filePath string
NetworkConfig *libcni.NetworkConfigList
- CNIConfig libcni.CNI
+ CNIConfig *libcni.CNIConfig
}
var errMissingDefaultNetwork = errors.New("Missing CNI default network")
@@ -99,110 +109,150 @@ func (plugin *cniNetworkPlugin) podUnlock(podNetwork PodNetwork) {
}
}
-func (plugin *cniNetworkPlugin) monitorNetDir() {
+func newWatcher(confDir string) (*fsnotify.Watcher, error) {
+ // Ensure plugin directory exists, because the following monitoring logic
+ // relies on that.
+ if err := os.MkdirAll(confDir, 0755); err != nil {
+ return nil, fmt.Errorf("failed to create %q: %v", confDir, err)
+ }
+
watcher, err := fsnotify.NewWatcher()
if err != nil {
- logrus.Errorf("could not create new watcher %v", err)
- return
+ return nil, fmt.Errorf("could not create new watcher %v", err)
}
- defer watcher.Close()
+ defer func() {
+ // Close watcher on error
+ if err != nil {
+ watcher.Close()
+ }
+ }()
- if err = watcher.Add(plugin.pluginDir); err != nil {
- logrus.Errorf("Failed to add watch on %q: %v", plugin.pluginDir, err)
- return
+ if err = watcher.Add(confDir); err != nil {
+ return nil, fmt.Errorf("failed to add watch on %q: %v", confDir, err)
}
- // Now that `watcher` is running and watching the `pluginDir`
- // gather the initial configuration, before starting the
- // goroutine which will actually process events. It has to be
- // done in this order to avoid missing any updates which might
- // otherwise occur between gathering the initial configuration
- // and starting the watcher.
- if err := plugin.syncNetworkConfig(); err != nil {
- logrus.Infof("Initial CNI setting failed, continue monitoring: %v", err)
- } else {
- logrus.Infof("Initial CNI setting succeeded")
- }
-
- go func() {
- for {
- select {
- case event := <-watcher.Events:
- logrus.Debugf("CNI monitoring event %v", event)
- if event.Op&fsnotify.Create != fsnotify.Create &&
- event.Op&fsnotify.Write != fsnotify.Write {
- continue
- }
+ return watcher, nil
+}
- if err = plugin.syncNetworkConfig(); err == nil {
- logrus.Infof("CNI asynchronous setting succeeded")
- continue
+func (plugin *cniNetworkPlugin) monitorConfDir(start *sync.WaitGroup) {
+ start.Done()
+ plugin.done.Add(1)
+ defer plugin.done.Done()
+ for {
+ select {
+ case event := <-plugin.watcher.Events:
+ logrus.Warningf("CNI monitoring event %v", event)
+
+ var defaultDeleted bool
+ createWrite := (event.Op&fsnotify.Create == fsnotify.Create ||
+ event.Op&fsnotify.Write == fsnotify.Write)
+ if event.Op&fsnotify.Remove == fsnotify.Remove {
+ // Care about the event if the default network
+ // was just deleted
+ defNet := plugin.getDefaultNetwork()
+ if defNet != nil && event.Name == defNet.filePath {
+ defaultDeleted = true
}
- logrus.Errorf("CNI setting failed, continue monitoring: %v", err)
+ }
+ if !createWrite && !defaultDeleted {
+ continue
+ }
- case err := <-watcher.Errors:
- if err == nil {
- continue
- }
- logrus.Errorf("CNI monitoring error %v", err)
- close(plugin.monitorNetDirChan)
- return
+ if err := plugin.syncNetworkConfig(); err != nil {
+ logrus.Errorf("CNI config loading failed, continue monitoring: %v", err)
+ continue
}
+
+ case err := <-plugin.watcher.Errors:
+ if err == nil {
+ continue
+ }
+ logrus.Errorf("CNI monitoring error %v", err)
+ return
+
+ case <-plugin.shutdownChan:
+ return
}
- }()
+ }
+}
- <-plugin.monitorNetDirChan
+// InitCNI takes a binary directory in which to search for CNI plugins, and
+// a configuration directory in which to search for CNI JSON config files.
+// If no valid CNI configs exist, network requests will fail until valid CNI
+// config files are present in the config directory.
+// If defaultNetName is not empty, a CNI config with that network name will
+// be used as the default CNI network, and container network operations will
+// fail until that network config is present and valid.
+func InitCNI(defaultNetName string, confDir string, binDirs ...string) (CNIPlugin, error) {
+ return initCNI(nil, "", defaultNetName, confDir, binDirs...)
}
-// InitCNI takes the plugin directory and CNI directories where the CNI config
-// files should be searched for. If no valid CNI configs exist, network requests
-// will fail until valid CNI config files are present in the config directory.
-func InitCNI(pluginDir string, cniDirs ...string) (CNIPlugin, error) {
- vendorCNIDirPrefix := ""
+// Internal function to allow faking out exec functions for testing
+func initCNI(exec cniinvoke.Exec, cacheDir, defaultNetName string, confDir string, binDirs ...string) (CNIPlugin, error) {
+ if confDir == "" {
+ confDir = DefaultConfDir
+ }
+ if len(binDirs) == 0 {
+ binDirs = []string{DefaultBinDir}
+ }
plugin := &cniNetworkPlugin{
- defaultNetwork: nil,
- loNetwork: getLoNetwork(cniDirs, vendorCNIDirPrefix),
- pluginDir: pluginDir,
- cniDirs: cniDirs,
- vendorCNIDirPrefix: vendorCNIDirPrefix,
- monitorNetDirChan: make(chan struct{}),
- pods: make(map[string]*podLock),
+ defaultNetName: defaultNetName,
+ networks: make(map[string]*cniNetwork),
+ loNetwork: getLoNetwork(exec, binDirs),
+ confDir: confDir,
+ binDirs: binDirs,
+ shutdownChan: make(chan struct{}),
+ done: &sync.WaitGroup{},
+ pods: make(map[string]*podLock),
+ exec: exec,
+ cacheDir: cacheDir,
+ }
+
+ if exec == nil {
+ exec = &cniinvoke.DefaultExec{
+ RawExec: &cniinvoke.RawExec{Stderr: os.Stderr},
+ PluginDecoder: cniversion.PluginDecoder{},
+ }
}
- var err error
- plugin.nsenterPath, err = exec.LookPath("nsenter")
+ nsm, err := newNSManager()
if err != nil {
return nil, err
}
+ plugin.nsManager = nsm
- // Ensure plugin directory exists, because the following monitoring logic
- // relies on that.
- if err := os.MkdirAll(pluginDir, 0755); err != nil {
+ plugin.syncNetworkConfig()
+
+ plugin.watcher, err = newWatcher(plugin.confDir)
+ if err != nil {
return nil, err
}
- go plugin.monitorNetDir()
+ startWg := sync.WaitGroup{}
+ startWg.Add(1)
+ go plugin.monitorConfDir(&startWg)
+ startWg.Wait()
return plugin, nil
}
-func getDefaultCNINetwork(pluginDir string, cniDirs []string, vendorCNIDirPrefix string) (*cniNetwork, error) {
- if pluginDir == "" {
- pluginDir = DefaultNetDir
- }
- if len(cniDirs) == 0 {
- cniDirs = []string{DefaultCNIDir}
- }
+func (plugin *cniNetworkPlugin) Shutdown() error {
+ close(plugin.shutdownChan)
+ plugin.watcher.Close()
+ plugin.done.Wait()
+ return nil
+}
- files, err := libcni.ConfFiles(pluginDir, []string{".conf", ".conflist", ".json"})
- switch {
- case err != nil:
- return nil, err
- case len(files) == 0:
- return nil, errMissingDefaultNetwork
+func loadNetworks(exec cniinvoke.Exec, confDir string, binDirs []string) (map[string]*cniNetwork, string, error) {
+ files, err := libcni.ConfFiles(confDir, []string{".conf", ".conflist", ".json"})
+ if err != nil {
+ return nil, "", err
}
+ networks := make(map[string]*cniNetwork)
+ defaultNetName := ""
+
sort.Strings(files)
for _, confFile := range files {
var confList *libcni.NetworkConfigList
@@ -232,27 +282,28 @@ func getDefaultCNINetwork(pluginDir string, cniDirs []string, vendorCNIDirPrefix
logrus.Warningf("CNI config list %s has no networks, skipping", confFile)
continue
}
- logrus.Infof("CNI network %s (type=%v) is used from %s", confList.Name, confList.Plugins[0].Network.Type, confFile)
- // Search for vendor-specific plugins as well as default plugins in the CNI codebase.
- vendorDir := vendorCNIDir(vendorCNIDirPrefix, confList.Plugins[0].Network.Type)
- cninet := &libcni.CNIConfig{
- Path: append(cniDirs, vendorDir),
+ if confList.Name == "" {
+ confList.Name = path.Base(confFile)
}
- network := &cniNetwork{name: confList.Name, NetworkConfig: confList, CNIConfig: cninet}
- return network, nil
- }
- return nil, fmt.Errorf("No valid networks found in %s", pluginDir)
-}
-func vendorCNIDir(prefix, pluginType string) string {
- return fmt.Sprintf(VendorCNIDirTemplate, prefix, pluginType)
-}
+ logrus.Infof("Found CNI network %s (type=%v) at %s", confList.Name, confList.Plugins[0].Network.Type, confFile)
+
+ networks[confList.Name] = &cniNetwork{
+ name: confList.Name,
+ filePath: confFile,
+ NetworkConfig: confList,
+ CNIConfig: libcni.NewCNIConfig(binDirs, exec),
+ }
-func getLoNetwork(cniDirs []string, vendorDirPrefix string) *cniNetwork {
- if len(cniDirs) == 0 {
- cniDirs = []string{DefaultCNIDir}
+ if defaultNetName == "" {
+ defaultNetName = confList.Name
+ }
}
+ return networks, defaultNetName, nil
+}
+
+func getLoNetwork(exec cniinvoke.Exec, binDirs []string) *cniNetwork {
loConfig, err := libcni.ConfListFromBytes([]byte(`{
"cniVersion": "0.2.0",
"name": "cni-loopback",
@@ -265,45 +316,62 @@ func getLoNetwork(cniDirs []string, vendorDirPrefix string) *cniNetwork {
// catch this
panic(err)
}
- vendorDir := vendorCNIDir(vendorDirPrefix, loConfig.Plugins[0].Network.Type)
- cninet := &libcni.CNIConfig{
- Path: append(cniDirs, vendorDir),
- }
loNetwork := &cniNetwork{
name: "lo",
NetworkConfig: loConfig,
- CNIConfig: cninet,
+ CNIConfig: libcni.NewCNIConfig(binDirs, exec),
}
return loNetwork
}
func (plugin *cniNetworkPlugin) syncNetworkConfig() error {
- network, err := getDefaultCNINetwork(plugin.pluginDir, plugin.cniDirs, plugin.vendorCNIDirPrefix)
+ networks, defaultNetName, err := loadNetworks(plugin.exec, plugin.confDir, plugin.binDirs)
if err != nil {
- logrus.Errorf("error updating cni config: %s", err)
return err
}
- plugin.setDefaultNetwork(network)
+
+ plugin.Lock()
+ defer plugin.Unlock()
+ if plugin.defaultNetName == "" {
+ plugin.defaultNetName = defaultNetName
+ }
+ plugin.networks = networks
return nil
}
-func (plugin *cniNetworkPlugin) getDefaultNetwork() *cniNetwork {
+func (plugin *cniNetworkPlugin) getNetwork(name string) (*cniNetwork, error) {
plugin.RLock()
defer plugin.RUnlock()
- return plugin.defaultNetwork
+ net, ok := plugin.networks[name]
+ if !ok {
+ return nil, fmt.Errorf("CNI network %q not found", name)
+ }
+ return net, nil
}
-func (plugin *cniNetworkPlugin) setDefaultNetwork(n *cniNetwork) {
- plugin.Lock()
- defer plugin.Unlock()
- plugin.defaultNetwork = n
+func (plugin *cniNetworkPlugin) getDefaultNetworkName() string {
+ plugin.RLock()
+ defer plugin.RUnlock()
+ return plugin.defaultNetName
}
-func (plugin *cniNetworkPlugin) checkInitialized() error {
- if plugin.getDefaultNetwork() == nil {
- return errors.New("cni config uninitialized")
+func (plugin *cniNetworkPlugin) getDefaultNetwork() *cniNetwork {
+ defaultNetName := plugin.getDefaultNetworkName()
+ if defaultNetName == "" {
+ return nil
+ }
+ network, _ := plugin.getNetwork(defaultNetName)
+ return network
+}
+
+// networksAvailable returns an error if the pod requests no networks and the
+// plugin has no default network, and thus the plugin has no idea what network
+// to attach the pod to.
+func (plugin *cniNetworkPlugin) networksAvailable(podNetwork *PodNetwork) error {
+ if len(podNetwork.Networks) == 0 && plugin.getDefaultNetwork() == nil {
+ return errMissingDefaultNetwork
}
return nil
}
@@ -312,59 +380,119 @@ func (plugin *cniNetworkPlugin) Name() string {
return CNIPluginName
}
-func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) (cnitypes.Result, error) {
- if err := plugin.checkInitialized(); err != nil {
+func (plugin *cniNetworkPlugin) forEachNetwork(podNetwork *PodNetwork, forEachFunc func(*cniNetwork, string, *PodNetwork) error) error {
+ networks := podNetwork.Networks
+ if len(networks) == 0 {
+ networks = append(networks, plugin.getDefaultNetworkName())
+ }
+ for i, netName := range networks {
+ // Interface names start at "eth0" and count up for each network
+ ifName := fmt.Sprintf("eth%d", i)
+ network, err := plugin.getNetwork(netName)
+ if err != nil {
+ logrus.Errorf(err.Error())
+ return err
+ }
+ if err := forEachFunc(network, ifName, podNetwork); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]cnitypes.Result, error) {
+ if err := plugin.networksAvailable(&podNetwork); err != nil {
return nil, err
}
plugin.podLock(podNetwork).Lock()
defer plugin.podUnlock(podNetwork)
- _, err := plugin.loNetwork.addToNetwork(podNetwork)
+ _, err := plugin.loNetwork.addToNetwork(plugin.cacheDir, &podNetwork, "lo")
if err != nil {
logrus.Errorf("Error while adding to cni lo network: %s", err)
return nil, err
}
- result, err := plugin.getDefaultNetwork().addToNetwork(podNetwork)
- if err != nil {
- logrus.Errorf("Error while adding to cni network: %s", err)
+ results := make([]cnitypes.Result, 0)
+ if err := plugin.forEachNetwork(&podNetwork, func(network *cniNetwork, ifName string, podNetwork *PodNetwork) error {
+ result, err := network.addToNetwork(plugin.cacheDir, podNetwork, ifName)
+ if err != nil {
+ logrus.Errorf("Error while adding pod to CNI network %q: %s", network.name, err)
+ return err
+ }
+ results = append(results, result)
+ return nil
+ }); err != nil {
return nil, err
}
- return result, err
+ return results, nil
}
func (plugin *cniNetworkPlugin) TearDownPod(podNetwork PodNetwork) error {
- if err := plugin.checkInitialized(); err != nil {
+ if err := plugin.networksAvailable(&podNetwork); err != nil {
return err
}
plugin.podLock(podNetwork).Lock()
defer plugin.podUnlock(podNetwork)
- return plugin.getDefaultNetwork().deleteFromNetwork(podNetwork)
+ return plugin.forEachNetwork(&podNetwork, func(network *cniNetwork, ifName string, podNetwork *PodNetwork) error {
+ if err := network.deleteFromNetwork(plugin.cacheDir, podNetwork, ifName); err != nil {
+ logrus.Errorf("Error while removing pod from CNI network %q: %s", network.name, err)
+ return err
+ }
+ return nil
+ })
}
-// TODO: Use the addToNetwork function to obtain the IP of the Pod. That will assume idempotent ADD call to the plugin.
-// Also fix the runtime's call to Status function to be done only in the case that the IP is lost, no need to do periodic calls
-func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) (string, error) {
+// GetPodNetworkStatus returns IP addressing and interface details for all
+// networks attached to the pod.
+func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) ([]cnitypes.Result, error) {
plugin.podLock(podNetwork).Lock()
defer plugin.podUnlock(podNetwork)
- ip, err := getContainerIP(plugin.nsenterPath, podNetwork.NetNS, DefaultInterfaceName, "-4")
- if err != nil {
- ip, err = getContainerIP(plugin.nsenterPath, podNetwork.NetNS, DefaultInterfaceName, "-6")
- }
- if err != nil {
- return "", err
+ results := make([]cnitypes.Result, 0)
+ if err := plugin.forEachNetwork(&podNetwork, func(network *cniNetwork, ifName string, podNetwork *PodNetwork) error {
+ version := "4"
+ ip, mac, err := getContainerDetails(plugin.nsManager, podNetwork.NetNS, ifName, "-4")
+ if err != nil {
+ ip, mac, err = getContainerDetails(plugin.nsManager, podNetwork.NetNS, ifName, "-6")
+ if err != nil {
+ return err
+ }
+ version = "6"
+ }
+
+ // Until CNI's GET request lands, construct the Result manually
+ results = append(results, &cnicurrent.Result{
+ CNIVersion: "0.3.1",
+ Interfaces: []*cnicurrent.Interface{
+ {
+ Name: ifName,
+ Mac: mac.String(),
+ Sandbox: podNetwork.NetNS,
+ },
+ },
+ IPs: []*cnicurrent.IPConfig{
+ {
+ Version: version,
+ Interface: cnicurrent.Int(0),
+ Address: *ip,
+ },
+ },
+ })
+ return nil
+ }); err != nil {
+ return nil, err
}
- return ip.String(), nil
+ return results, nil
}
-func (network *cniNetwork) addToNetwork(podNetwork PodNetwork) (cnitypes.Result, error) {
- rt, err := buildCNIRuntimeConf(podNetwork)
+func (network *cniNetwork) addToNetwork(cacheDir string, podNetwork *PodNetwork, ifName string) (cnitypes.Result, error) {
+ rt, err := buildCNIRuntimeConf(cacheDir, podNetwork, ifName)
if err != nil {
logrus.Errorf("Error adding network: %v", err)
return nil, err
@@ -381,8 +509,8 @@ func (network *cniNetwork) addToNetwork(podNetwork PodNetwork) (cnitypes.Result,
return res, nil
}
-func (network *cniNetwork) deleteFromNetwork(podNetwork PodNetwork) error {
- rt, err := buildCNIRuntimeConf(podNetwork)
+func (network *cniNetwork) deleteFromNetwork(cacheDir string, podNetwork *PodNetwork, ifName string) error {
+ rt, err := buildCNIRuntimeConf(cacheDir, podNetwork, ifName)
if err != nil {
logrus.Errorf("Error deleting network: %v", err)
return err
@@ -398,13 +526,14 @@ func (network *cniNetwork) deleteFromNetwork(podNetwork PodNetwork) error {
return nil
}
-func buildCNIRuntimeConf(podNetwork PodNetwork) (*libcni.RuntimeConf, error) {
+func buildCNIRuntimeConf(cacheDir string, podNetwork *PodNetwork, ifName string) (*libcni.RuntimeConf, error) {
logrus.Infof("Got pod network %+v", podNetwork)
rt := &libcni.RuntimeConf{
ContainerID: podNetwork.ID,
NetNS: podNetwork.NetNS,
- IfName: DefaultInterfaceName,
+ CacheDir: cacheDir,
+ IfName: ifName,
Args: [][2]string{
{"IgnoreUnknown", "1"},
{"K8S_POD_NAMESPACE", podNetwork.Namespace},
@@ -424,5 +553,8 @@ func buildCNIRuntimeConf(podNetwork PodNetwork) (*libcni.RuntimeConf, error) {
}
func (plugin *cniNetworkPlugin) Status() error {
- return plugin.checkInitialized()
+ if plugin.getDefaultNetwork() == nil {
+ return errMissingDefaultNetwork
+ }
+ return nil
}
diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go
index 39e9b591c..8ca61657a 100644
--- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go
+++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go
@@ -36,6 +36,10 @@ type PodNetwork struct {
NetNS string
// PortMappings is the port mapping of the sandbox.
PortMappings []PortMapping
+
+ // Networks is a list of CNI network names to attach to the sandbox
+ // Leave this list empty to attach the default network to the sandbox
+ Networks []string
}
// CNIPlugin is the interface that needs to be implemented by a plugin
@@ -47,14 +51,17 @@ type CNIPlugin interface {
// SetUpPod is the method called after the sandbox container of
// the pod has been created but before the other containers of the
// pod are launched.
- SetUpPod(network PodNetwork) (types.Result, error)
+ SetUpPod(network PodNetwork) ([]types.Result, error)
// TearDownPod is the method called before a pod's sandbox container will be deleted
TearDownPod(network PodNetwork) error
// Status is the method called to obtain the ipv4 or ipv6 addresses of the pod sandbox
- GetPodNetworkStatus(network PodNetwork) (string, error)
+ GetPodNetworkStatus(network PodNetwork) ([]types.Result, error)
// NetworkStatus returns error if the network plugin is in error state
Status() error
+
+ // Shutdown terminates all driver operations
+ Shutdown() error
}
diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_unix.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_unix.go
index 21e713ffc..88010f737 100644
--- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_unix.go
+++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_unix.go
@@ -3,10 +3,8 @@
package ocicni
const (
- // DefaultNetDir is the place to look for CNI Network
- DefaultNetDir = "/etc/cni/net.d"
- // DefaultCNIDir is the place to look for cni config files
- DefaultCNIDir = "/opt/cni/bin"
- // VendorCNIDirTemplate is the template for looking up vendor specific cni config/executable files
- VendorCNIDirTemplate = "%s/opt/%s/bin"
+ // DefaultConfDir is the default place to look for CNI Network
+ DefaultConfDir = "/etc/cni/net.d"
+ // DefaultBinDir is the default place to look for CNI config files
+ DefaultBinDir = "/opt/cni/bin"
)
diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_windows.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_windows.go
index f8b434c12..061ecae5c 100644
--- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_windows.go
+++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_windows.go
@@ -3,10 +3,8 @@
package ocicni
const (
- // DefaultNetDir is the place to look for CNI Network
- DefaultNetDir = "C:\\cni\\etc\\net.d"
- // DefaultCNIDir is the place to look for cni config files
- DefaultCNIDir = "C:\\cni\\bin"
- // VendorCNIDirTemplate is the template for looking up vendor specific cni config/executable files
- VendorCNIDirTemplate = "C:\\cni\\%s\\opt\\%s\\bin" // XXX(vbatts) Not sure what to do here ...
+ // DefaultConfDir is the default place to look for CNI Network
+ DefaultConfDir = "C:\\cni\\etc\\net.d"
+ // DefaultBinDir is the default place to look for cni config files
+ DefaultBinDir = "C:\\cni\\bin"
)
diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util.go
index 547e95972..2af786593 100644
--- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util.go
+++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util.go
@@ -1,32 +1,8 @@
package ocicni
-import (
- "fmt"
- "net"
- "os/exec"
- "strings"
-)
-
-func getContainerIP(nsenterPath, netnsPath, interfaceName, addrType string) (net.IP, error) {
- // Try to retrieve ip inside container network namespace
- output, err := exec.Command(nsenterPath, fmt.Sprintf("--net=%s", netnsPath), "-F", "--",
- "ip", "-o", addrType, "addr", "show", "dev", interfaceName, "scope", "global").CombinedOutput()
- if err != nil {
- return nil, fmt.Errorf("Unexpected command output %s with error: %v", output, err)
- }
-
- lines := strings.Split(string(output), "\n")
- if len(lines) < 1 {
- return nil, fmt.Errorf("Unexpected command output %s", output)
- }
- fields := strings.Fields(lines[0])
- if len(fields) < 4 {
- return nil, fmt.Errorf("Unexpected address output %s ", lines[0])
- }
- ip, _, err := net.ParseCIDR(fields[3])
- if err != nil {
- return nil, fmt.Errorf("CNI failed to parse ip from output %s due to %v", output, err)
- }
-
- return ip, nil
+// newNSManager initializes a new namespace manager, which is a platform dependent struct.
+func newNSManager() (*nsManager, error) {
+ nsm := &nsManager{}
+ err := nsm.init()
+ return nsm, err
}
diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go
new file mode 100644
index 000000000..d263ae4df
--- /dev/null
+++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go
@@ -0,0 +1,71 @@
+// +build linux
+
+package ocicni
+
+import (
+ "fmt"
+ "net"
+ "os/exec"
+ "strings"
+)
+
+var defaultNamespaceEnterCommandName = "nsenter"
+
+type nsManager struct {
+ nsenterPath string
+}
+
+func (nsm *nsManager) init() error {
+ var err error
+ nsm.nsenterPath, err = exec.LookPath(defaultNamespaceEnterCommandName)
+ return err
+}
+
+func getContainerDetails(nsm *nsManager, netnsPath, interfaceName, addrType string) (*net.IPNet, *net.HardwareAddr, error) {
+ // Try to retrieve ip inside container network namespace
+ output, err := exec.Command(nsm.nsenterPath, fmt.Sprintf("--net=%s", netnsPath), "-F", "--",
+ "ip", "-o", addrType, "addr", "show", "dev", interfaceName, "scope", "global").CombinedOutput()
+ if err != nil {
+ return nil, nil, fmt.Errorf("Unexpected command output %s with error: %v", output, err)
+ }
+
+ lines := strings.Split(string(output), "\n")
+ if len(lines) < 1 {
+ return nil, nil, fmt.Errorf("Unexpected command output %s", output)
+ }
+ fields := strings.Fields(lines[0])
+ if len(fields) < 4 {
+ return nil, nil, fmt.Errorf("Unexpected address output %s ", lines[0])
+ }
+ ip, ipNet, err := net.ParseCIDR(fields[3])
+ if err != nil {
+ return nil, nil, fmt.Errorf("CNI failed to parse ip from output %s due to %v", output, err)
+ }
+ if ip.To4() == nil {
+ ipNet.IP = ip
+ } else {
+ ipNet.IP = ip.To4()
+ }
+
+ // Try to retrieve MAC inside container network namespace
+ output, err = exec.Command(nsm.nsenterPath, fmt.Sprintf("--net=%s", netnsPath), "-F", "--",
+ "ip", "link", "show", "dev", interfaceName).CombinedOutput()
+ if err != nil {
+ return nil, nil, fmt.Errorf("unexpected 'ip link' command output %s with error: %v", output, err)
+ }
+
+ lines = strings.Split(string(output), "\n")
+ if len(lines) < 2 {
+ return nil, nil, fmt.Errorf("unexpected 'ip link' command output %s", output)
+ }
+ fields = strings.Fields(lines[1])
+ if len(fields) < 4 {
+ return nil, nil, fmt.Errorf("unexpected link output %s ", lines[0])
+ }
+ mac, err := net.ParseMAC(fields[1])
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to parse MAC from output %s due to %v", output, err)
+ }
+
+ return ipNet, &mac, nil
+}
diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go
new file mode 100644
index 000000000..0b1c72208
--- /dev/null
+++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go
@@ -0,0 +1,19 @@
+// +build !linux
+
+package ocicni
+
+import (
+ "fmt"
+ "net"
+)
+
+type nsManager struct {
+}
+
+func (nsm *nsManager) init() error {
+ return nil
+}
+
+func getContainerDetails(nsm *nsManager, netnsPath, interfaceName, addrType string) (*net.IPNet, *net.HardwareAddr, error) {
+ return nil, nil, fmt.Errorf("not supported yet")
+}