diff options
author | Jakub Filak <jakub.filak@sap.com> | 2019-09-24 21:45:48 +0200 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2019-11-06 16:22:18 +0100 |
commit | 455f5b76169515dcc36cf4d7c1d51ead3be02e1f (patch) | |
tree | 212ae930aa545132929a3ae2ded94009110a6485 /vendor/github.com/cri-o/ocicni/pkg | |
parent | 16cb2b38a8a645039bc4e2e9443cde777d90537f (diff) | |
download | podman-455f5b76169515dcc36cf4d7c1d51ead3be02e1f.tar.gz podman-455f5b76169515dcc36cf4d7c1d51ead3be02e1f.tar.bz2 podman-455f5b76169515dcc36cf4d7c1d51ead3be02e1f.zip |
vendor: updated ocicni for MAC address
`go get github.com/cri-o/ocicni@deac903fd99b6c52d781c9f42b8db3af7dcfd00a`
I had to fix compilation errors in libpod/networking_linux.go
---
ocicni.Networks has changed from string to the structure NetAttachment
with the member Name (the former string value) and the member Ifname
(optional).
I don't think we can make use of Ifname here, so I just map the array of
structures to array of strings - e.g. dropping Ifname.
---
The function GetPodNetworkStatus no longer returns Result but it returns
the wrapper structure NetResult which contains the former Result plus
NetAttachment (Network name and Interface name).
Again, I don't think we can make use of that information here, so I
just added `.Result` to fix the build.
---
Issue: #1136
Signed-off-by: Jakub Filak <jakub.filak@sap.com>
Diffstat (limited to 'vendor/github.com/cri-o/ocicni/pkg')
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go | 411 | ||||
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go | 32 |
2 files changed, 343 insertions, 100 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 8743abc56..0cdbf14b7 100644 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go +++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go @@ -2,11 +2,14 @@ package ocicni import ( "context" + "encoding/json" "errors" "fmt" + "io/ioutil" "net" "os" "path" + "path/filepath" "sort" "strings" "sync" @@ -21,10 +24,11 @@ import ( ) type cniNetworkPlugin struct { + cniConfig *libcni.CNIConfig loNetwork *cniNetwork sync.RWMutex - defaultNetName string + defaultNetName netName networks map[string]*cniNetwork nsManager *nsManager @@ -47,11 +51,15 @@ type cniNetworkPlugin struct { cacheDir string } +type netName struct { + name string + changeable bool +} + type cniNetwork struct { - name string - filePath string - NetworkConfig *libcni.NetworkConfigList - CNIConfig *libcni.CNIConfig + name string + filePath string + config *libcni.NetworkConfigList } var errMissingDefaultNetwork = errors.New("Missing CNI default network") @@ -186,6 +194,8 @@ func (plugin *cniNetworkPlugin) monitorConfDir(start *sync.WaitGroup) { // 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. +// If defaultNetName is empty, CNI config files should be reloaded real-time and +// defaultNetName should be changeable and determined by file sorting. func InitCNI(defaultNetName string, confDir string, binDirs ...string) (CNIPlugin, error) { return initCNI(nil, "", defaultNetName, confDir, binDirs...) } @@ -198,17 +208,24 @@ func initCNI(exec cniinvoke.Exec, cacheDir, defaultNetName string, confDir strin if len(binDirs) == 0 { binDirs = []string{DefaultBinDir} } + plugin := &cniNetworkPlugin{ - 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, + cniConfig: libcni.NewCNIConfig(binDirs, exec), + defaultNetName: netName{ + name: defaultNetName, + // If defaultNetName is not assigned in initialization, + // it should be changeable + changeable: defaultNetName == "", + }, + networks: make(map[string]*cniNetwork), + loNetwork: getLoNetwork(), + confDir: confDir, + binDirs: binDirs, + shutdownChan: make(chan struct{}), + done: &sync.WaitGroup{}, + pods: make(map[string]*podLock), + exec: exec, + cacheDir: cacheDir, } if exec == nil { @@ -246,7 +263,7 @@ func (plugin *cniNetworkPlugin) Shutdown() error { return nil } -func loadNetworks(exec cniinvoke.Exec, confDir string, binDirs []string) (map[string]*cniNetwork, string, error) { +func loadNetworks(confDir string, cni *libcni.CNIConfig) (map[string]*cniNetwork, string, error) { files, err := libcni.ConfFiles(confDir, []string{".conf", ".conflist", ".json"}) if err != nil { return nil, "", err @@ -284,17 +301,30 @@ func loadNetworks(exec cniinvoke.Exec, confDir string, binDirs []string) (map[st logrus.Warningf("CNI config list %s has no networks, skipping", confFile) continue } + + // Validation on CNI config should be done to pre-check presence + // of plugins which are necessary. + if _, err := cni.ValidateNetworkList(context.TODO(), confList); err != nil { + logrus.Warningf("Error validating CNI config file %s: %v", confFile, err) + continue + } + if confList.Name == "" { confList.Name = path.Base(confFile) } + cniNet := &cniNetwork{ + name: confList.Name, + filePath: confFile, + config: confList, + } + 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), + if _, ok := networks[confList.Name]; !ok { + networks[confList.Name] = cniNet + } else { + logrus.Infof("Ignore CNI network %s (type=%v) at %s because already exists", confList.Name, confList.Plugins[0].Network.Type, confFile) } if defaultNetName == "" { @@ -305,39 +335,49 @@ func loadNetworks(exec cniinvoke.Exec, confDir string, binDirs []string) (map[st return networks, defaultNetName, nil } -func getLoNetwork(exec cniinvoke.Exec, binDirs []string) *cniNetwork { - loConfig, err := libcni.ConfListFromBytes([]byte(`{ - "cniVersion": "0.2.0", - "name": "cni-loopback", +const ( + loIfname string = "lo" + loNetname string = "cni-loopback" +) + +func getLoNetwork() *cniNetwork { + loConfig, err := libcni.ConfListFromBytes([]byte(fmt.Sprintf(`{ + "cniVersion": "0.3.1", + "name": "%s", "plugins": [{ "type": "loopback" }] -}`)) +}`, loNetname))) if err != nil { // The hardcoded config above should always be valid and unit tests will // catch this panic(err) } loNetwork := &cniNetwork{ - name: "lo", - NetworkConfig: loConfig, - CNIConfig: libcni.NewCNIConfig(binDirs, exec), + name: loIfname, + config: loConfig, } return loNetwork } func (plugin *cniNetworkPlugin) syncNetworkConfig() error { - networks, defaultNetName, err := loadNetworks(plugin.exec, plugin.confDir, plugin.binDirs) + networks, defaultNetName, err := loadNetworks(plugin.confDir, plugin.cniConfig) if err != nil { return err } plugin.Lock() defer plugin.Unlock() - if plugin.defaultNetName == "" { - plugin.defaultNetName = defaultNetName + + // Update defaultNetName if it is changeable + if plugin.defaultNetName.changeable { + plugin.defaultNetName.name = defaultNetName + logrus.Infof("Update default CNI network name to %s", defaultNetName) + } else { + logrus.Warnf("Default CNI network name %s is unchangeable", plugin.defaultNetName.name) } + plugin.networks = networks return nil @@ -356,7 +396,7 @@ func (plugin *cniNetworkPlugin) getNetwork(name string) (*cniNetwork, error) { func (plugin *cniNetworkPlugin) GetDefaultNetworkName() string { plugin.RLock() defer plugin.RUnlock() - return plugin.defaultNetName + return plugin.defaultNetName.name } func (plugin *cniNetworkPlugin) getDefaultNetwork() *cniNetwork { @@ -382,27 +422,120 @@ func (plugin *cniNetworkPlugin) Name() string { return CNIPluginName } -func (plugin *cniNetworkPlugin) forEachNetwork(podNetwork *PodNetwork, forEachFunc func(*cniNetwork, string, *PodNetwork, RuntimeConfig) error) error { +func (plugin *cniNetworkPlugin) loadNetworkFromCache(name string, rt *libcni.RuntimeConf) (*cniNetwork, *libcni.RuntimeConf, error) { + cniNet := &cniNetwork{ + name: name, + config: &libcni.NetworkConfigList{ + Name: name, + }, + } + + var confBytes []byte + var err error + confBytes, rt, err = plugin.cniConfig.GetNetworkListCachedConfig(cniNet.config, rt) + if err != nil { + return nil, nil, err + } else if confBytes == nil { + return nil, nil, fmt.Errorf("network %q not found in CNI cache", name) + } + + cniNet.config, err = libcni.ConfListFromBytes(confBytes) + if err != nil { + // Might be a plain NetworkConfig + netConf, err := libcni.ConfFromBytes(confBytes) + if err != nil { + return nil, nil, err + } + // Up-convert to a NetworkConfigList + cniNet.config, err = libcni.ConfListFromConf(netConf) + if err != nil { + return nil, nil, err + } + } + + return cniNet, rt, nil +} + +type forEachNetworkFn func(*cniNetwork, *PodNetwork, *libcni.RuntimeConf) error + +func (plugin *cniNetworkPlugin) forEachNetwork(podNetwork *PodNetwork, fromCache bool, actionFn forEachNetworkFn) error { networks := podNetwork.Networks if len(networks) == 0 { - networks = append(networks, plugin.GetDefaultNetworkName()) + networks = append(networks, NetAttachment{ + Name: 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) + + allIfNames := make(map[string]bool) + for _, req := range networks { + if req.Ifname != "" { + // Make sure the requested name isn't already assigned + if allIfNames[req.Ifname] { + return fmt.Errorf("network %q requested interface name %q already assigned", req.Name, req.Ifname) + } + allIfNames[req.Ifname] = true + } + } + + for _, network := range networks { + ifName := network.Ifname + if ifName == "" { + for i := 0; i < 10000; i++ { + candidate := fmt.Sprintf("eth%d", i) + if !allIfNames[candidate] { + allIfNames[candidate] = true + ifName = candidate + break + } + } + if ifName == "" { + return fmt.Errorf("failed to find free interface name for network %q", network.Name) + } + } + + rt, err := buildCNIRuntimeConf(plugin.cacheDir, podNetwork, ifName, podNetwork.RuntimeConfig[network.Name]) if err != nil { - logrus.Errorf(err.Error()) + logrus.Errorf("error building CNI runtime config: %v", err) return err } - if err := forEachFunc(network, ifName, podNetwork, podNetwork.RuntimeConfig[netName]); err != nil { + + var cniNet *cniNetwork + if fromCache { + var newRt *libcni.RuntimeConf + cniNet, newRt, err = plugin.loadNetworkFromCache(network.Name, rt) + if err != nil { + logrus.Errorf("error loading cached network config: %v", err) + // fall back to loading from existing plugins on disk + } else { + // Use the updated RuntimeConf + rt = newRt + } + } + if cniNet == nil { + cniNet, err = plugin.getNetwork(network.Name) + if err != nil { + logrus.Errorf(err.Error()) + return err + } + } + + if err := actionFn(cniNet, podNetwork, rt); err != nil { return err } } return nil } -func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]cnitypes.Result, error) { +func buildLoopbackRuntimeConf(cacheDir string, podNetwork *PodNetwork) *libcni.RuntimeConf { + return &libcni.RuntimeConf{ + ContainerID: podNetwork.ID, + NetNS: podNetwork.NetNS, + CacheDir: cacheDir, + IfName: loIfname, + } +} + +func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]NetResult, error) { if err := plugin.networksAvailable(&podNetwork); err != nil { return nil, err } @@ -410,20 +543,26 @@ func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]cnitypes.Resu plugin.podLock(podNetwork).Lock() defer plugin.podUnlock(podNetwork) - _, err := plugin.loNetwork.addToNetwork(plugin.cacheDir, &podNetwork, "lo", RuntimeConfig{}) - if err != nil { + loRt := buildLoopbackRuntimeConf(plugin.cacheDir, &podNetwork) + if _, err := plugin.loNetwork.addToNetwork(loRt, plugin.cniConfig); err != nil { logrus.Errorf("Error while adding to cni lo network: %s", err) return nil, err } - results := make([]cnitypes.Result, 0) - if err := plugin.forEachNetwork(&podNetwork, func(network *cniNetwork, ifName string, podNetwork *PodNetwork, runtimeConfig RuntimeConfig) error { - result, err := network.addToNetwork(plugin.cacheDir, podNetwork, ifName, runtimeConfig) + results := make([]NetResult, 0) + if err := plugin.forEachNetwork(&podNetwork, false, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error { + result, err := network.addToNetwork(rt, plugin.cniConfig) if err != nil { logrus.Errorf("Error while adding pod to CNI network %q: %s", network.name, err) return err } - results = append(results, result) + results = append(results, NetResult{ + Result: result, + NetAttachment: NetAttachment{ + Name: network.name, + Ifname: rt.IfName, + }, + }) return nil }); err != nil { return nil, err @@ -432,16 +571,99 @@ func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]cnitypes.Resu return results, nil } +func (plugin *cniNetworkPlugin) getCachedNetworkInfo(containerID string) ([]NetAttachment, error) { + cacheDir := libcni.CacheDir + if plugin.cacheDir != "" { + cacheDir = plugin.cacheDir + } + + dirPath := filepath.Join(cacheDir, "results") + entries, err := ioutil.ReadDir(dirPath) + if err != nil { + return nil, err + } + + fileNames := make([]string, 0, len(entries)) + for _, e := range entries { + fileNames = append(fileNames, e.Name()) + } + sort.Strings(fileNames) + + attachments := []NetAttachment{} + for _, fname := range fileNames { + part := fmt.Sprintf("-%s-", containerID) + pos := strings.Index(fname, part) + if pos <= 0 || pos+len(part) >= len(fname) { + continue + } + + cacheFile := filepath.Join(dirPath, fname) + bytes, err := ioutil.ReadFile(cacheFile) + if err != nil { + logrus.Warningf("failed to read CNI cache file %s: %v", cacheFile, err) + continue + } + + cachedInfo := struct { + Kind string `json:"kind"` + IfName string `json:"ifName"` + ContainerID string `json:"containerID"` + NetName string `json:"networkName"` + }{} + + if err := json.Unmarshal(bytes, &cachedInfo); err != nil { + logrus.Warningf("failed to unmarshal CNI cache file %s: %v", cacheFile, err) + continue + } + if cachedInfo.Kind != libcni.CNICacheV1 { + logrus.Warningf("unknown CNI cache file %s kind %q", cacheFile, cachedInfo.Kind) + continue + } + if cachedInfo.ContainerID != containerID { + continue + } + // Ignore the loopback interface; it's handled separately + if cachedInfo.IfName == loIfname && cachedInfo.NetName == loNetname { + continue + } + if cachedInfo.IfName == "" || cachedInfo.NetName == "" { + logrus.Warningf("missing CNI cache file %s ifname %q or netname %q", cacheFile, cachedInfo.IfName, cachedInfo.NetName) + continue + } + + attachments = append(attachments, NetAttachment{ + Name: cachedInfo.NetName, + Ifname: cachedInfo.IfName, + }) + } + return attachments, nil +} + +// TearDownPod tears down pod networks. Prefers cached pod attachment information +// but falls back to given network attachment information. func (plugin *cniNetworkPlugin) TearDownPod(podNetwork PodNetwork) error { + if len(podNetwork.Networks) == 0 { + attachments, err := plugin.getCachedNetworkInfo(podNetwork.ID) + if err == nil && len(attachments) > 0 { + podNetwork.Networks = attachments + } + } + if err := plugin.networksAvailable(&podNetwork); err != nil { return err } + loRt := buildLoopbackRuntimeConf(plugin.cacheDir, &podNetwork) + if err := plugin.loNetwork.deleteFromNetwork(loRt, plugin.cniConfig); err != nil { + logrus.Errorf("Error while removing pod from CNI lo network: %v", err) + // Loopback teardown errors are not fatal + } + plugin.podLock(podNetwork).Lock() defer plugin.podUnlock(podNetwork) - return plugin.forEachNetwork(&podNetwork, func(network *cniNetwork, ifName string, podNetwork *PodNetwork, runtimeConfig RuntimeConfig) error { - if err := network.deleteFromNetwork(plugin.cacheDir, podNetwork, ifName, runtimeConfig); err != nil { + return plugin.forEachNetwork(&podNetwork, true, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error { + if err := network.deleteFromNetwork(rt, plugin.cniConfig); err != nil { logrus.Errorf("Error while removing pod from CNI network %q: %s", network.name, err) return err } @@ -451,19 +673,25 @@ func (plugin *cniNetworkPlugin) TearDownPod(podNetwork PodNetwork) error { // GetPodNetworkStatus returns IP addressing and interface details for all // networks attached to the pod. -func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) ([]cnitypes.Result, error) { +func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) ([]NetResult, error) { plugin.podLock(podNetwork).Lock() defer plugin.podUnlock(podNetwork) - results := make([]cnitypes.Result, 0) - if err := plugin.forEachNetwork(&podNetwork, func(network *cniNetwork, ifName string, podNetwork *PodNetwork, runtimeConfig RuntimeConfig) error { - result, err := network.checkNetwork(plugin.cacheDir, podNetwork, ifName, runtimeConfig, plugin.nsManager) + results := make([]NetResult, 0) + if err := plugin.forEachNetwork(&podNetwork, true, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error { + result, err := network.checkNetwork(rt, plugin.cniConfig, plugin.nsManager, podNetwork.NetNS) if err != nil { logrus.Errorf("Error while checking pod to CNI network %q: %s", network.name, err) return err } if result != nil { - results = append(results, result) + results = append(results, NetResult{ + Result: result, + NetAttachment: NetAttachment{ + Name: network.name, + Ifname: rt.IfName, + }, + }) } return nil }); err != nil { @@ -473,16 +701,9 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) ([]cn return results, nil } -func (network *cniNetwork) addToNetwork(cacheDir string, podNetwork *PodNetwork, ifName string, runtimeConfig RuntimeConfig) (cnitypes.Result, error) { - rt, err := buildCNIRuntimeConf(cacheDir, podNetwork, ifName, runtimeConfig) - if err != nil { - logrus.Errorf("Error adding network: %v", err) - return nil, err - } - - netconf, cninet := network.NetworkConfig, network.CNIConfig - logrus.Infof("About to add CNI network %s (type=%v)", netconf.Name, netconf.Plugins[0].Network.Type) - res, err := cninet.AddNetworkList(context.Background(), netconf, rt) +func (network *cniNetwork) addToNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIConfig) (cnitypes.Result, error) { + logrus.Infof("About to add CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type) + res, err := cni.AddNetworkList(context.Background(), network.config, rt) if err != nil { logrus.Errorf("Error adding network: %v", err) return nil, err @@ -491,18 +712,10 @@ func (network *cniNetwork) addToNetwork(cacheDir string, podNetwork *PodNetwork, return res, nil } -func (network *cniNetwork) checkNetwork(cacheDir string, podNetwork *PodNetwork, ifName string, runtimeConfig RuntimeConfig, nsManager *nsManager) (cnitypes.Result, error) { - - rt, err := buildCNIRuntimeConf(cacheDir, podNetwork, ifName, runtimeConfig) - if err != nil { - logrus.Errorf("Error checking network: %v", err) - return nil, err - } - - netconf, cninet := network.NetworkConfig, network.CNIConfig - logrus.Infof("About to check CNI network %s (type=%v)", netconf.Name, netconf.Plugins[0].Network.Type) +func (network *cniNetwork) checkNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIConfig, nsManager *nsManager, netns string) (cnitypes.Result, error) { + logrus.Infof("About to check CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type) - gtet, err := cniversion.GreaterThanOrEqualTo(netconf.CNIVersion, "0.4.0") + gtet, err := cniversion.GreaterThanOrEqualTo(network.config.CNIVersion, "0.4.0") if err != nil { return nil, err } @@ -511,15 +724,15 @@ func (network *cniNetwork) checkNetwork(cacheDir string, podNetwork *PodNetwork, // When CNIVersion supports Check, use it. Otherwise fall back on what was done initially. if gtet { - err = cninet.CheckNetworkList(context.Background(), netconf, rt) - logrus.Infof("Checking CNI network %s (config version=%v)", netconf.Name, netconf.CNIVersion) + err = cni.CheckNetworkList(context.Background(), network.config, rt) + logrus.Infof("Checking CNI network %s (config version=%v)", network.name, network.config.CNIVersion) if err != nil { logrus.Errorf("Error checking network: %v", err) return nil, err } } - result, err = cninet.GetNetworkListCachedResult(netconf, rt) + result, err = cni.GetNetworkListCachedResult(network.config, rt) if err != nil { logrus.Errorf("Error GetNetworkListCachedResult: %v", err) return nil, err @@ -528,19 +741,19 @@ func (network *cniNetwork) checkNetwork(cacheDir string, podNetwork *PodNetwork, } // result doesn't exist, create one - logrus.Infof("Checking CNI network %s (config version=%v) nsManager=%v", netconf.Name, netconf.CNIVersion, nsManager) + logrus.Infof("Checking CNI network %s (config version=%v) nsManager=%v", network.name, network.config.CNIVersion, nsManager) var cniInterface *cnicurrent.Interface ips := []*cnicurrent.IPConfig{} errs := []error{} for _, version := range []string{"4", "6"} { - ip, mac, err := getContainerDetails(nsManager, podNetwork.NetNS, ifName, "-"+version) + ip, mac, err := getContainerDetails(nsManager, netns, rt.IfName, "-"+version) if err == nil { if cniInterface == nil { cniInterface = &cnicurrent.Interface{ - Name: ifName, + Name: rt.IfName, Mac: mac.String(), - Sandbox: podNetwork.NetNS, + Sandbox: netns, } } ips = append(ips, &cnicurrent.IPConfig{ @@ -557,25 +770,23 @@ func (network *cniNetwork) checkNetwork(cacheDir string, podNetwork *PodNetwork, } result = &cnicurrent.Result{ - CNIVersion: netconf.CNIVersion, + CNIVersion: network.config.CNIVersion, Interfaces: []*cnicurrent.Interface{cniInterface}, IPs: ips, } - return result, nil -} - -func (network *cniNetwork) deleteFromNetwork(cacheDir string, podNetwork *PodNetwork, ifName string, runtimeConfig RuntimeConfig) error { - rt, err := buildCNIRuntimeConf(cacheDir, podNetwork, ifName, runtimeConfig) + // Result must be the same CNIVersion as the CNI config + converted, err := result.GetAsVersion(network.config.CNIVersion) if err != nil { - logrus.Errorf("Error deleting network: %v", err) - return err + return nil, err } - netconf, cninet := network.NetworkConfig, network.CNIConfig - logrus.Infof("About to del CNI network %s (type=%v)", netconf.Name, netconf.Plugins[0].Network.Type) - err = cninet.DelNetworkList(context.Background(), netconf, rt) - if err != nil { + return converted, nil +} + +func (network *cniNetwork) deleteFromNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIConfig) error { + logrus.Infof("About to del CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type) + if err := cni.DelNetworkList(context.Background(), network.config, rt); err != nil { logrus.Errorf("Error deleting network: %v", err) return err } @@ -608,6 +819,16 @@ func buildCNIRuntimeConf(cacheDir string, podNetwork *PodNetwork, ifName string, rt.Args = append(rt.Args, [2]string{"IP", ip}) } + // Add the requested static MAC to CNI_ARGS + mac := runtimeConfig.MAC + if mac != "" { + _, err := net.ParseMAC(mac) + if err != nil { + return nil, fmt.Errorf("unable to parse MAC address %q: %v", mac, err) + } + rt.Args = append(rt.Args, [2]string{"MAC", mac}) + } + // Set PortMappings in Capabilities if len(runtimeConfig.PortMappings) != 0 { rt.CapabilityArgs["portMappings"] = runtimeConfig.PortMappings 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 8709711e0..717ecda33 100644 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go +++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go @@ -44,6 +44,9 @@ type RuntimeConfig struct { // with the hostlocal IP allocator. If left unset, an IP will be // dynamically allocated. IP string + // MAC is a static MAC address to be assigned to the network interface. + // If left unset, a MAC will be dynamically allocated. + MAC string // PortMappings is the port mapping of the sandbox. PortMappings []PortMapping // Bandwidth is the bandwidth limiting of the pod @@ -75,9 +78,10 @@ type PodNetwork struct { // NetNS is the network namespace path of the sandbox. NetNS string - // 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 + // Networks is a list of CNI network names (and optional interface + // names) to attach to the sandbox. Leave this list empty to attach the + // default network to the sandbox + Networks []NetAttachment // NetworkConfig is configuration specific to a single CNI network. // It is optional, and can be omitted for some or all specified networks @@ -85,6 +89,24 @@ type PodNetwork struct { RuntimeConfig map[string]RuntimeConfig } +// NetAttachment describes a container network attachment +type NetAttachment struct { + // NetName contains the name of the CNI network to which the container + // should be or is attached + Name string + // Ifname contains the optional interface name of the attachment + Ifname string +} + +// NetResult contains the result the network attachment operation +type NetResult struct { + // Result is the CNI Result + Result types.Result + // NetAttachment contains the network and interface names of this + // network attachment + NetAttachment +} + // CNIPlugin is the interface that needs to be implemented by a plugin type CNIPlugin interface { // Name returns the plugin's name. This will be used when searching @@ -98,13 +120,13 @@ 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) ([]NetResult, 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) ([]types.Result, error) + GetPodNetworkStatus(network PodNetwork) ([]NetResult, error) // NetworkStatus returns error if the network plugin is in error state Status() error |