summaryrefslogtreecommitdiff
path: root/libpod/network/cni
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2022-01-13 18:06:54 +0100
committerGitHub <noreply@github.com>2022-01-13 18:06:54 +0100
commiteeb76db0fd0dc2a1115c2f2ad12c82eadbc62509 (patch)
tree4666b0a66a98bd3f29586b3d3ac2c3028bd7443a /libpod/network/cni
parentab7228b3c27719e447de4dffe9b3fd7f67d6f346 (diff)
parentece768ff9e7d2b0166c0b1850467a489556b93fc (diff)
downloadpodman-eeb76db0fd0dc2a1115c2f2ad12c82eadbc62509.tar.gz
podman-eeb76db0fd0dc2a1115c2f2ad12c82eadbc62509.tar.bz2
podman-eeb76db0fd0dc2a1115c2f2ad12c82eadbc62509.zip
Merge pull request #12642 from Luap99/libnetwork
use libnetwork from c/common
Diffstat (limited to 'libpod/network/cni')
-rw-r--r--libpod/network/cni/README.md10
-rw-r--r--libpod/network/cni/cni_conversion.go378
-rw-r--r--libpod/network/cni/cni_exec.go110
-rw-r--r--libpod/network/cni/cni_suite_test.go53
-rw-r--r--libpod/network/cni/cni_types.go281
-rw-r--r--libpod/network/cni/config.go208
-rw-r--r--libpod/network/cni/config_test.go1378
-rw-r--r--libpod/network/cni/network.go273
-rw-r--r--libpod/network/cni/run.go273
-rw-r--r--libpod/network/cni/run_test.go1329
-rw-r--r--libpod/network/cni/testfiles/invalid/broken.conflist25
-rw-r--r--libpod/network/cni/testfiles/invalid/invalid_gateway.conflist51
-rw-r--r--libpod/network/cni/testfiles/invalid/invalidname.conflist49
-rw-r--r--libpod/network/cni/testfiles/invalid/noname.conflist48
-rw-r--r--libpod/network/cni/testfiles/invalid/noplugin.conflist5
-rw-r--r--libpod/network/cni/testfiles/invalid/samename1.conflist49
-rw-r--r--libpod/network/cni/testfiles/invalid/samename2.conflist49
-rw-r--r--libpod/network/cni/testfiles/valid/87-podman.conflist37
-rw-r--r--libpod/network/cni/testfiles/valid/bridge.conflist51
-rw-r--r--libpod/network/cni/testfiles/valid/dualstack.conflist58
-rw-r--r--libpod/network/cni/testfiles/valid/internal.conflist40
-rw-r--r--libpod/network/cni/testfiles/valid/label.conflist54
-rw-r--r--libpod/network/cni/testfiles/valid/macvlan.conflist13
-rw-r--r--libpod/network/cni/testfiles/valid/macvlan_mtu.conflist14
-rw-r--r--libpod/network/cni/testfiles/valid/mtu.conflist49
-rw-r--r--libpod/network/cni/testfiles/valid/vlan.conflist50
26 files changed, 0 insertions, 4935 deletions
diff --git a/libpod/network/cni/README.md b/libpod/network/cni/README.md
deleted file mode 100644
index 6f57feff5..000000000
--- a/libpod/network/cni/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-This package abstracts CNI from libpod.
-It implements the `ContainerNetwork` interface defined in [libpod/network/types/network.go](../types/network.go) for the CNI backend.
-
-
-## Testing
-Run the tests with:
-```
-go test -v -mod=vendor -cover ./libpod/network/cni/
-```
-Run the tests as root to also test setup/teardown. This will execute CNI and therefore the cni plugins have to be installed.
diff --git a/libpod/network/cni/cni_conversion.go b/libpod/network/cni/cni_conversion.go
deleted file mode 100644
index 788165b5e..000000000
--- a/libpod/network/cni/cni_conversion.go
+++ /dev/null
@@ -1,378 +0,0 @@
-// +build linux
-
-package cni
-
-import (
- "encoding/json"
- "io/ioutil"
- "net"
- "os"
- "path/filepath"
- "strconv"
- "strings"
- "syscall"
- "time"
-
- "github.com/containernetworking/cni/libcni"
- internalutil "github.com/containers/podman/v3/libpod/network/internal/util"
- "github.com/containers/podman/v3/libpod/network/types"
- "github.com/containers/podman/v3/libpod/network/util"
- pkgutil "github.com/containers/podman/v3/pkg/util"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
-)
-
-func createNetworkFromCNIConfigList(conf *libcni.NetworkConfigList, confPath string) (*types.Network, error) {
- network := types.Network{
- Name: conf.Name,
- ID: getNetworkIDFromName(conf.Name),
- Labels: map[string]string{},
- Options: map[string]string{},
- IPAMOptions: map[string]string{},
- }
-
- cniJSON := make(map[string]interface{})
- err := json.Unmarshal(conf.Bytes, &cniJSON)
- if err != nil {
- return nil, errors.Wrapf(err, "failed to unmarshal network config %s", conf.Name)
- }
- if args, ok := cniJSON["args"]; ok {
- if key, ok := args.(map[string]interface{}); ok {
- // read network labels and options from the conf file
- network.Labels = getNetworkArgsFromConfList(key, podmanLabelKey)
- network.Options = getNetworkArgsFromConfList(key, podmanOptionsKey)
- }
- }
-
- f, err := os.Stat(confPath)
- if err != nil {
- return nil, err
- }
- stat := f.Sys().(*syscall.Stat_t)
- network.Created = time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec))
-
- firstPlugin := conf.Plugins[0]
- network.Driver = firstPlugin.Network.Type
-
- switch firstPlugin.Network.Type {
- case types.BridgeNetworkDriver:
- var bridge hostLocalBridge
- err := json.Unmarshal(firstPlugin.Bytes, &bridge)
- if err != nil {
- return nil, errors.Wrapf(err, "failed to unmarshal the bridge plugin config in %s", confPath)
- }
- network.NetworkInterface = bridge.BrName
-
- // if isGateway is false we have an internal network
- if !bridge.IsGW {
- network.Internal = true
- }
-
- // set network options
- if bridge.MTU != 0 {
- network.Options["mtu"] = strconv.Itoa(bridge.MTU)
- }
- if bridge.Vlan != 0 {
- network.Options["vlan"] = strconv.Itoa(bridge.Vlan)
- }
-
- err = convertIPAMConfToNetwork(&network, bridge.IPAM, confPath)
- if err != nil {
- return nil, err
- }
-
- case types.MacVLANNetworkDriver, types.IPVLANNetworkDriver:
- var vlan VLANConfig
- err := json.Unmarshal(firstPlugin.Bytes, &vlan)
- if err != nil {
- return nil, errors.Wrapf(err, "failed to unmarshal the macvlan plugin config in %s", confPath)
- }
- network.NetworkInterface = vlan.Master
-
- // set network options
- if vlan.MTU != 0 {
- network.Options["mtu"] = strconv.Itoa(vlan.MTU)
- }
-
- if vlan.Mode != "" {
- network.Options["mode"] = vlan.Mode
- }
-
- err = convertIPAMConfToNetwork(&network, vlan.IPAM, confPath)
- if err != nil {
- return nil, err
- }
-
- default:
- // A warning would be good but users would get this warning every time so keep this at info level.
- logrus.Infof("Unsupported CNI config type %s in %s, this network can still be used but inspect or list cannot show all information",
- firstPlugin.Network.Type, confPath)
- }
-
- // check if the dnsname plugin is configured
- network.DNSEnabled = findPluginByName(conf.Plugins, "dnsname")
-
- return &network, nil
-}
-
-func findPluginByName(plugins []*libcni.NetworkConfig, name string) bool {
- for _, plugin := range plugins {
- if plugin.Network.Type == name {
- return true
- }
- }
- return false
-}
-
-// convertIPAMConfToNetwork converts A cni IPAMConfig to libpod network subnets.
-// It returns an array of subnets and an extra bool if dhcp is configured.
-func convertIPAMConfToNetwork(network *types.Network, ipam ipamConfig, confPath string) error {
- if ipam.PluginType == types.DHCPIPAMDriver {
- network.IPAMOptions["driver"] = types.DHCPIPAMDriver
- return nil
- }
-
- if ipam.PluginType != types.HostLocalIPAMDriver {
- return errors.Errorf("unsupported ipam plugin %s in %s", ipam.PluginType, confPath)
- }
-
- network.IPAMOptions["driver"] = types.HostLocalIPAMDriver
- for _, r := range ipam.Ranges {
- for _, ipam := range r {
- s := types.Subnet{}
-
- // Do not use types.ParseCIDR() because we want the ip to be
- // the network address and not a random ip in the sub.
- _, sub, err := net.ParseCIDR(ipam.Subnet)
- if err != nil {
- return err
- }
- s.Subnet = types.IPNet{IPNet: *sub}
-
- // gateway
- var gateway net.IP
- if ipam.Gateway != "" {
- gateway = net.ParseIP(ipam.Gateway)
- if gateway == nil {
- return errors.Errorf("failed to parse gateway ip %s", ipam.Gateway)
- }
- // convert to 4 byte if ipv4
- util.NormalizeIP(&gateway)
- } else if !network.Internal {
- // only add a gateway address if the network is not internal
- gateway, err = util.FirstIPInSubnet(sub)
- if err != nil {
- return errors.Errorf("failed to get first ip in subnet %s", sub.String())
- }
- }
- s.Gateway = gateway
-
- var rangeStart net.IP
- var rangeEnd net.IP
- if ipam.RangeStart != "" {
- rangeStart = net.ParseIP(ipam.RangeStart)
- if rangeStart == nil {
- return errors.Errorf("failed to parse range start ip %s", ipam.RangeStart)
- }
- }
- if ipam.RangeEnd != "" {
- rangeEnd = net.ParseIP(ipam.RangeEnd)
- if rangeEnd == nil {
- return errors.Errorf("failed to parse range end ip %s", ipam.RangeEnd)
- }
- }
- if rangeStart != nil || rangeEnd != nil {
- s.LeaseRange = &types.LeaseRange{}
- s.LeaseRange.StartIP = rangeStart
- s.LeaseRange.EndIP = rangeEnd
- }
- if util.IsIPv6(s.Subnet.IP) {
- network.IPv6Enabled = true
- }
- network.Subnets = append(network.Subnets, s)
- }
- }
- return nil
-}
-
-// getNetworkArgsFromConfList returns the map of args in a conflist, argType should be labels or options
-func getNetworkArgsFromConfList(args map[string]interface{}, argType string) map[string]string {
- if args, ok := args[argType]; ok {
- if labels, ok := args.(map[string]interface{}); ok {
- result := make(map[string]string, len(labels))
- for k, v := range labels {
- if v, ok := v.(string); ok {
- result[k] = v
- }
- }
- return result
- }
- }
- return map[string]string{}
-}
-
-// createCNIConfigListFromNetwork will create a cni config file from the given network.
-// It returns the cni config and the path to the file where the config was written.
-// Set writeToDisk to false to only add this network into memory.
-func (n *cniNetwork) createCNIConfigListFromNetwork(network *types.Network, writeToDisk bool) (*libcni.NetworkConfigList, string, error) {
- var (
- routes []ipamRoute
- ipamRanges [][]ipamLocalHostRangeConf
- ipamConf ipamConfig
- err error
- )
- if len(network.Subnets) > 0 {
- for _, subnet := range network.Subnets {
- route, err := newIPAMDefaultRoute(util.IsIPv6(subnet.Subnet.IP))
- if err != nil {
- return nil, "", err
- }
- routes = append(routes, route)
- ipam := newIPAMLocalHostRange(subnet.Subnet, subnet.LeaseRange, subnet.Gateway)
- ipamRanges = append(ipamRanges, []ipamLocalHostRangeConf{*ipam})
- }
- ipamConf = newIPAMHostLocalConf(routes, ipamRanges)
- } else {
- ipamConf = ipamConfig{PluginType: "dhcp"}
- }
-
- vlan := 0
- mtu := 0
- vlanPluginMode := ""
- for k, v := range network.Options {
- switch k {
- case "mtu":
- mtu, err = internalutil.ParseMTU(v)
- if err != nil {
- return nil, "", err
- }
-
- case "vlan":
- vlan, err = internalutil.ParseVlan(v)
- if err != nil {
- return nil, "", err
- }
-
- case "mode":
- switch network.Driver {
- case types.MacVLANNetworkDriver:
- if !pkgutil.StringInSlice(v, []string{"", "bridge", "private", "vepa", "passthru"}) {
- return nil, "", errors.Errorf("unknown macvlan mode %q", v)
- }
- case types.IPVLANNetworkDriver:
- if !pkgutil.StringInSlice(v, []string{"", "l2", "l3", "l3s"}) {
- return nil, "", errors.Errorf("unknown ipvlan mode %q", v)
- }
- default:
- return nil, "", errors.Errorf("cannot set option \"mode\" with driver %q", network.Driver)
- }
- vlanPluginMode = v
-
- default:
- return nil, "", errors.Errorf("unsupported network option %s", k)
- }
- }
-
- isGateway := true
- ipMasq := true
- if network.Internal {
- isGateway = false
- ipMasq = false
- }
- // create CNI plugin configuration
- // explicitly use CNI version 0.4.0 here, to use v1.0.0 at least containernetwork-plugins-1.0.1 has to be installed
- // the dnsname plugin also needs to be updated for 1.0.0
- // TODO change to 1.0.0 when most distros support it
- ncList := newNcList(network.Name, "0.4.0", network.Labels, network.Options)
- var plugins []interface{}
-
- switch network.Driver {
- case types.BridgeNetworkDriver:
- bridge := newHostLocalBridge(network.NetworkInterface, isGateway, ipMasq, mtu, vlan, ipamConf)
- plugins = append(plugins, bridge, newPortMapPlugin(), newFirewallPlugin(), newTuningPlugin())
- // if we find the dnsname plugin we add configuration for it
- if hasDNSNamePlugin(n.cniPluginDirs) && network.DNSEnabled {
- // Note: in the future we might like to allow for dynamic domain names
- plugins = append(plugins, newDNSNamePlugin(defaultPodmanDomainName))
- }
-
- case types.MacVLANNetworkDriver:
- plugins = append(plugins, newVLANPlugin(types.MacVLANNetworkDriver, network.NetworkInterface, vlanPluginMode, mtu, ipamConf))
-
- case types.IPVLANNetworkDriver:
- plugins = append(plugins, newVLANPlugin(types.IPVLANNetworkDriver, network.NetworkInterface, vlanPluginMode, mtu, ipamConf))
-
- default:
- return nil, "", errors.Errorf("driver %q is not supported by cni", network.Driver)
- }
- ncList["plugins"] = plugins
- b, err := json.MarshalIndent(ncList, "", " ")
- if err != nil {
- return nil, "", err
- }
- cniPathName := ""
- if writeToDisk {
- cniPathName = filepath.Join(n.cniConfigDir, network.Name+".conflist")
- err = ioutil.WriteFile(cniPathName, b, 0644)
- if err != nil {
- return nil, "", err
- }
- f, err := os.Stat(cniPathName)
- if err != nil {
- return nil, "", err
- }
- stat := f.Sys().(*syscall.Stat_t)
- network.Created = time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec))
- } else {
- network.Created = time.Now()
- }
- config, err := libcni.ConfListFromBytes(b)
- if err != nil {
- return nil, "", err
- }
- return config, cniPathName, nil
-}
-
-func convertSpecgenPortsToCNIPorts(ports []types.PortMapping) ([]cniPortMapEntry, error) {
- cniPorts := make([]cniPortMapEntry, 0, len(ports))
- for _, port := range ports {
- if port.Protocol == "" {
- return nil, errors.New("port protocol should not be empty")
- }
- protocols := strings.Split(port.Protocol, ",")
-
- for _, protocol := range protocols {
- if !pkgutil.StringInSlice(protocol, []string{"tcp", "udp", "sctp"}) {
- return nil, errors.Errorf("unknown port protocol %s", protocol)
- }
- cniPort := cniPortMapEntry{
- HostPort: int(port.HostPort),
- ContainerPort: int(port.ContainerPort),
- HostIP: port.HostIP,
- Protocol: protocol,
- }
- cniPorts = append(cniPorts, cniPort)
- for i := 1; i < int(port.Range); i++ {
- cniPort := cniPortMapEntry{
- HostPort: int(port.HostPort) + i,
- ContainerPort: int(port.ContainerPort) + i,
- HostIP: port.HostIP,
- Protocol: protocol,
- }
- cniPorts = append(cniPorts, cniPort)
- }
- }
- }
- return cniPorts, nil
-}
-
-func removeMachinePlugin(conf *libcni.NetworkConfigList) *libcni.NetworkConfigList {
- plugins := make([]*libcni.NetworkConfig, 0, len(conf.Plugins))
- for _, net := range conf.Plugins {
- if net.Network.Type != "podman-machine" {
- plugins = append(plugins, net)
- }
- }
- conf.Plugins = plugins
- return conf
-}
diff --git a/libpod/network/cni/cni_exec.go b/libpod/network/cni/cni_exec.go
deleted file mode 100644
index ae857bcfb..000000000
--- a/libpod/network/cni/cni_exec.go
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 CNI authors
-// Copyright 2021 Podman authors
-//
-// This code has been originally copied from github.com/containernetworking/cni
-// but has been changed to better fit the Podman use case.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build linux
-
-package cni
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "fmt"
- "os/exec"
- "path/filepath"
-
- "github.com/containernetworking/cni/pkg/invoke"
- "github.com/containernetworking/cni/pkg/version"
- "github.com/containers/podman/v3/pkg/rootless"
-)
-
-type cniExec struct {
- version.PluginDecoder
-}
-
-type cniPluginError struct {
- plugin string
- Code uint `json:"code"`
- Msg string `json:"msg"`
- Details string `json:"details,omitempty"`
-}
-
-// Error returns a nicely formatted error message for the cni plugin errors.
-func (e *cniPluginError) Error() string {
- err := fmt.Sprintf("cni plugin %s failed", e.plugin)
- if e.Msg != "" {
- err = fmt.Sprintf("%s: %s", err, e.Msg)
- } else if e.Code > 0 {
- err = fmt.Sprintf("%s with error code %d", err, e.Code)
- }
- if e.Details != "" {
- err = fmt.Sprintf("%s: %s", err, e.Details)
- }
- return err
-}
-
-// ExecPlugin execute the cni plugin. Returns the stdout of the plugin or an error.
-func (e *cniExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData []byte, environ []string) ([]byte, error) {
- stdout := &bytes.Buffer{}
- stderr := &bytes.Buffer{}
- c := exec.CommandContext(ctx, pluginPath)
- c.Env = environ
- c.Stdin = bytes.NewBuffer(stdinData)
- c.Stdout = stdout
- c.Stderr = stderr
-
- // The dnsname plugin tries to use XDG_RUNTIME_DIR to store files.
- // podman run will have XDG_RUNTIME_DIR set and thus the cni plugin can use
- // it. The problem is that XDG_RUNTIME_DIR is unset for the conmon process
- // for rootful users. This causes issues since the cleanup process is spawned
- // by conmon and thus not have XDG_RUNTIME_DIR set to same value as podman run.
- // Because of it dnsname will not find the config files and cannot correctly cleanup.
- // To fix this we should also unset XDG_RUNTIME_DIR for the cni plugins as rootful.
- if !rootless.IsRootless() {
- c.Env = append(c.Env, "XDG_RUNTIME_DIR=")
- }
-
- err := c.Run()
- if err != nil {
- return nil, annotatePluginError(err, pluginPath, stdout.Bytes(), stderr.Bytes())
- }
- return stdout.Bytes(), nil
-}
-
-// annotatePluginError parses the common cni plugin error json.
-func annotatePluginError(err error, plugin string, stdout []byte, stderr []byte) error {
- pluginName := filepath.Base(plugin)
- emsg := cniPluginError{
- plugin: pluginName,
- }
- if len(stdout) == 0 {
- if len(stderr) == 0 {
- emsg.Msg = err.Error()
- } else {
- emsg.Msg = string(stderr)
- }
- } else if perr := json.Unmarshal(stdout, &emsg); perr != nil {
- emsg.Msg = fmt.Sprintf("failed to unmarshal error message %q: %v", string(stdout), perr)
- }
- return &emsg
-}
-
-// FindInPath finds the plugin in the given paths.
-func (e *cniExec) FindInPath(plugin string, paths []string) (string, error) {
- return invoke.FindInPath(plugin, paths)
-}
diff --git a/libpod/network/cni/cni_suite_test.go b/libpod/network/cni/cni_suite_test.go
deleted file mode 100644
index f98869c96..000000000
--- a/libpod/network/cni/cni_suite_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// +build linux
-
-package cni_test
-
-import (
- "os"
- "path/filepath"
- "testing"
-
- "github.com/containers/podman/v3/libpod/network/cni"
- "github.com/containers/podman/v3/libpod/network/types"
- "github.com/containers/podman/v3/test/utils"
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var cniPluginDirs = []string{
- "/usr/libexec/cni",
- "/usr/lib/cni",
- "/usr/local/lib/cni",
- "/opt/cni/bin",
-}
-
-func TestCni(t *testing.T) {
- RegisterFailHandler(Fail)
- RunSpecs(t, "CNI Suite")
-}
-
-func getNetworkInterface(cniConfDir string, machine bool) (types.ContainerNetwork, error) {
- return cni.NewCNINetworkInterface(cni.InitConfig{
- CNIConfigDir: cniConfDir,
- CNIPluginDirs: cniPluginDirs,
- IsMachine: machine,
- LockFile: filepath.Join(cniConfDir, "cni.lock"),
- })
-}
-
-func SkipIfNoDnsname() {
- for _, path := range cniPluginDirs {
- f, err := os.Stat(filepath.Join(path, "dnsname"))
- if err == nil && f.Mode().IsRegular() {
- return
- }
- }
- Skip("dnsname cni plugin needs to be installed for this test")
-}
-
-func SkipIfNotFedora(msg string) {
- info := utils.GetHostDistributionInfo()
- if info.Distribution != "fedora" {
- Skip("Test can only run on Fedora: " + msg)
- }
-}
diff --git a/libpod/network/cni/cni_types.go b/libpod/network/cni/cni_types.go
deleted file mode 100644
index e5eb777de..000000000
--- a/libpod/network/cni/cni_types.go
+++ /dev/null
@@ -1,281 +0,0 @@
-// +build linux
-
-package cni
-
-import (
- "net"
- "os"
- "path/filepath"
-
- "github.com/containers/podman/v3/libpod/network/types"
-)
-
-const (
- defaultIPv4Route = "0.0.0.0/0"
- defaultIPv6Route = "::/0"
- // defaultPodmanDomainName is used for the dnsname plugin to define
- // a localized domain name for a created network
- defaultPodmanDomainName = "dns.podman"
-
- // cniDeviceName is the default name for a new bridge, it should be suffixed with an integer
- cniDeviceName = "cni-podman"
-
- // podmanLabelKey key used to store the podman network label in a cni config
- podmanLabelKey = "podman_labels"
-
- // podmanOptionsKey key used to store the podman network options in a cni config
- podmanOptionsKey = "podman_options"
-)
-
-// cniPortMapEntry struct is used by the portmap plugin
-// https://github.com/containernetworking/plugins/blob/649e0181fe7b3a61e708f3e4249a798f57f25cc5/plugins/meta/portmap/main.go#L43-L50
-type cniPortMapEntry struct {
- HostPort int `json:"hostPort"`
- ContainerPort int `json:"containerPort"`
- Protocol string `json:"protocol"`
- HostIP string `json:"hostIP,omitempty"`
-}
-
-// hostLocalBridge describes a configuration for a bridge plugin
-// https://github.com/containernetworking/plugins/tree/master/plugins/main/bridge#network-configuration-reference
-type hostLocalBridge struct {
- PluginType string `json:"type"`
- BrName string `json:"bridge,omitempty"`
- IsGW bool `json:"isGateway"`
- IsDefaultGW bool `json:"isDefaultGateway,omitempty"`
- ForceAddress bool `json:"forceAddress,omitempty"`
- IPMasq bool `json:"ipMasq,omitempty"`
- MTU int `json:"mtu,omitempty"`
- HairpinMode bool `json:"hairpinMode,omitempty"`
- PromiscMode bool `json:"promiscMode,omitempty"`
- Vlan int `json:"vlan,omitempty"`
- IPAM ipamConfig `json:"ipam"`
- Capabilities map[string]bool `json:"capabilities,omitempty"`
-}
-
-// ipamConfig describes an IPAM configuration
-// https://github.com/containernetworking/plugins/tree/master/plugins/ipam/host-local#network-configuration-reference
-type ipamConfig struct {
- PluginType string `json:"type"`
- Routes []ipamRoute `json:"routes,omitempty"`
- ResolveConf string `json:"resolveConf,omitempty"`
- DataDir string `json:"dataDir,omitempty"`
- Ranges [][]ipamLocalHostRangeConf `json:"ranges,omitempty"`
-}
-
-// ipamLocalHostRangeConf describes the new style IPAM ranges
-type ipamLocalHostRangeConf struct {
- Subnet string `json:"subnet"`
- RangeStart string `json:"rangeStart,omitempty"`
- RangeEnd string `json:"rangeEnd,omitempty"`
- Gateway string `json:"gateway,omitempty"`
-}
-
-// ipamRoute describes a route in an ipam config
-type ipamRoute struct {
- Dest string `json:"dst"`
-}
-
-// portMapConfig describes the default portmapping config
-type portMapConfig struct {
- PluginType string `json:"type"`
- Capabilities map[string]bool `json:"capabilities"`
-}
-
-// VLANConfig describes the macvlan config
-type VLANConfig struct {
- PluginType string `json:"type"`
- Master string `json:"master"`
- IPAM ipamConfig `json:"ipam"`
- MTU int `json:"mtu,omitempty"`
- Mode string `json:"mode,omitempty"`
- Capabilities map[string]bool `json:"capabilities,omitempty"`
-}
-
-// firewallConfig describes the firewall plugin
-type firewallConfig struct {
- PluginType string `json:"type"`
- Backend string `json:"backend"`
-}
-
-// tuningConfig describes the tuning plugin
-type tuningConfig struct {
- PluginType string `json:"type"`
-}
-
-// dnsNameConfig describes the dns container name resolution plugin config
-type dnsNameConfig struct {
- PluginType string `json:"type"`
- DomainName string `json:"domainName"`
- Capabilities map[string]bool `json:"capabilities"`
-}
-
-// ncList describes a generic map
-type ncList map[string]interface{}
-
-// newNcList creates a generic map of values with string
-// keys and adds in version and network name
-func newNcList(name, version string, labels, options map[string]string) ncList {
- n := ncList{}
- n["cniVersion"] = version
- n["name"] = name
- args := map[string]map[string]string{}
- if len(labels) > 0 {
- args[podmanLabelKey] = labels
- }
- if len(options) > 0 {
- args[podmanOptionsKey] = options
- }
- if len(args) > 0 {
- n["args"] = args
- }
- return n
-}
-
-// newHostLocalBridge creates a new LocalBridge for host-local
-func newHostLocalBridge(name string, isGateWay, ipMasq bool, mtu int, vlan int, ipamConf ipamConfig) *hostLocalBridge {
- caps := make(map[string]bool)
- caps["ips"] = true
- bridge := hostLocalBridge{
- PluginType: "bridge",
- BrName: name,
- IsGW: isGateWay,
- IPMasq: ipMasq,
- MTU: mtu,
- HairpinMode: true,
- Vlan: vlan,
- IPAM: ipamConf,
- }
- // if we use host-local set the ips cap to ensure we can set static ips via runtime config
- if ipamConf.PluginType == types.HostLocalIPAMDriver {
- bridge.Capabilities = caps
- }
- return &bridge
-}
-
-// newIPAMHostLocalConf creates a new IPAMHostLocal configuration
-func newIPAMHostLocalConf(routes []ipamRoute, ipamRanges [][]ipamLocalHostRangeConf) ipamConfig {
- ipamConf := ipamConfig{
- PluginType: "host-local",
- Routes: routes,
- }
-
- ipamConf.Ranges = ipamRanges
- return ipamConf
-}
-
-// newIPAMLocalHostRange create a new IPAM range
-func newIPAMLocalHostRange(subnet types.IPNet, leaseRange *types.LeaseRange, gw net.IP) *ipamLocalHostRangeConf {
- hostRange := &ipamLocalHostRangeConf{
- Subnet: subnet.String(),
- }
-
- // a user provided a range, we add it here
- if leaseRange != nil {
- if leaseRange.StartIP != nil {
- hostRange.RangeStart = leaseRange.StartIP.String()
- }
- if leaseRange.EndIP != nil {
- hostRange.RangeEnd = leaseRange.EndIP.String()
- }
- }
-
- if gw != nil {
- hostRange.Gateway = gw.String()
- }
- return hostRange
-}
-
-// newIPAMRoute creates a new IPAM route configuration
-// nolint:interfacer
-func newIPAMRoute(r *net.IPNet) ipamRoute {
- return ipamRoute{Dest: r.String()}
-}
-
-// newIPAMDefaultRoute creates a new IPAMDefault route of
-// 0.0.0.0/0 for IPv4 or ::/0 for IPv6
-func newIPAMDefaultRoute(isIPv6 bool) (ipamRoute, error) {
- route := defaultIPv4Route
- if isIPv6 {
- route = defaultIPv6Route
- }
- _, n, err := net.ParseCIDR(route)
- if err != nil {
- return ipamRoute{}, err
- }
- return newIPAMRoute(n), nil
-}
-
-// newPortMapPlugin creates a predefined, default portmapping
-// configuration
-func newPortMapPlugin() portMapConfig {
- caps := make(map[string]bool)
- caps["portMappings"] = true
- p := portMapConfig{
- PluginType: "portmap",
- Capabilities: caps,
- }
- return p
-}
-
-// newFirewallPlugin creates a generic firewall plugin
-func newFirewallPlugin() firewallConfig {
- return firewallConfig{
- PluginType: "firewall",
- }
-}
-
-// newTuningPlugin creates a generic tuning section
-func newTuningPlugin() tuningConfig {
- return tuningConfig{
- PluginType: "tuning",
- }
-}
-
-// newDNSNamePlugin creates the dnsname config with a given
-// domainname
-func newDNSNamePlugin(domainName string) dnsNameConfig {
- caps := make(map[string]bool, 1)
- caps["aliases"] = true
- return dnsNameConfig{
- PluginType: "dnsname",
- DomainName: domainName,
- Capabilities: caps,
- }
-}
-
-// hasDNSNamePlugin looks to see if the dnsname cni plugin is present
-func hasDNSNamePlugin(paths []string) bool {
- for _, p := range paths {
- if _, err := os.Stat(filepath.Join(p, "dnsname")); err == nil {
- return true
- }
- }
- return false
-}
-
-// newVLANPlugin creates a macvlanconfig with a given device name
-func newVLANPlugin(pluginType, device, mode string, mtu int, ipam ipamConfig) VLANConfig {
- m := VLANConfig{
- PluginType: pluginType,
- IPAM: ipam,
- }
- if mtu > 0 {
- m.MTU = mtu
- }
- if len(mode) > 0 {
- m.Mode = mode
- }
- // CNI is supposed to use the default route if a
- // parent device is not provided
- if len(device) > 0 {
- m.Master = device
- }
- caps := make(map[string]bool)
- caps["ips"] = true
- // if we use host-local set the ips cap to ensure we can set static ips via runtime config
- if ipam.PluginType == types.HostLocalIPAMDriver {
- m.Capabilities = caps
- }
- return m
-}
diff --git a/libpod/network/cni/config.go b/libpod/network/cni/config.go
deleted file mode 100644
index 5d587da23..000000000
--- a/libpod/network/cni/config.go
+++ /dev/null
@@ -1,208 +0,0 @@
-// +build linux
-
-package cni
-
-import (
- "net"
- "os"
-
- "github.com/containers/podman/v3/libpod/define"
- internalutil "github.com/containers/podman/v3/libpod/network/internal/util"
- "github.com/containers/podman/v3/libpod/network/types"
- pkgutil "github.com/containers/podman/v3/pkg/util"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
- "github.com/vishvananda/netlink"
-)
-
-// NetworkCreate will take a partial filled Network and fill the
-// missing fields. It creates the Network and returns the full Network.
-func (n *cniNetwork) NetworkCreate(net types.Network) (types.Network, error) {
- n.lock.Lock()
- defer n.lock.Unlock()
- err := n.loadNetworks()
- if err != nil {
- return types.Network{}, err
- }
- network, err := n.networkCreate(net, false)
- if err != nil {
- return types.Network{}, err
- }
- // add the new network to the map
- n.networks[network.libpodNet.Name] = network
- return *network.libpodNet, nil
-}
-
-// networkCreate will fill out the given network struct and return the new network entry.
-// If defaultNet is true it will not validate against used subnets and it will not write the cni config to disk.
-func (n *cniNetwork) networkCreate(newNetwork types.Network, defaultNet bool) (*network, error) {
- // if no driver is set use the default one
- if newNetwork.Driver == "" {
- newNetwork.Driver = types.DefaultNetworkDriver
- }
-
- // FIXME: Should we use a different type for network create without the ID field?
- // the caller is not allowed to set a specific ID
- if newNetwork.ID != "" {
- return nil, errors.Wrap(define.ErrInvalidArg, "ID can not be set for network create")
- }
-
- err := internalutil.CommonNetworkCreate(n, &newNetwork)
- if err != nil {
- return nil, err
- }
-
- // Only get the used networks for validation if we do not create the default network.
- // The default network should not be validated against used subnets, we have to ensure
- // that this network can always be created even when a subnet is already used on the host.
- // This could happen if you run a container on this net, then the cni interface will be
- // created on the host and "block" this subnet from being used again.
- // Therefore the next podman command tries to create the default net again and it would
- // fail because it thinks the network is used on the host.
- var usedNetworks []*net.IPNet
- if !defaultNet {
- usedNetworks, err = internalutil.GetUsedSubnets(n)
- if err != nil {
- return nil, err
- }
- }
-
- switch newNetwork.Driver {
- case types.BridgeNetworkDriver:
- err = internalutil.CreateBridge(n, &newNetwork, usedNetworks)
- if err != nil {
- return nil, err
- }
- case types.MacVLANNetworkDriver, types.IPVLANNetworkDriver:
- err = createIPMACVLAN(&newNetwork)
- if err != nil {
- return nil, err
- }
- default:
- return nil, errors.Wrapf(define.ErrInvalidArg, "unsupported driver %s", newNetwork.Driver)
- }
-
- err = internalutil.ValidateSubnets(&newNetwork, usedNetworks)
- if err != nil {
- return nil, err
- }
-
- // generate the network ID
- newNetwork.ID = getNetworkIDFromName(newNetwork.Name)
-
- // FIXME: Should this be a hard error?
- if newNetwork.DNSEnabled && newNetwork.Internal && hasDNSNamePlugin(n.cniPluginDirs) {
- logrus.Warnf("dnsname and internal networks are incompatible. dnsname plugin not configured for network %s", newNetwork.Name)
- newNetwork.DNSEnabled = false
- }
-
- cniConf, path, err := n.createCNIConfigListFromNetwork(&newNetwork, !defaultNet)
- if err != nil {
- return nil, err
- }
- return &network{cniNet: cniConf, libpodNet: &newNetwork, filename: path}, nil
-}
-
-// NetworkRemove will remove the Network with the given name or ID.
-// It does not ensure that the network is unused.
-func (n *cniNetwork) NetworkRemove(nameOrID string) error {
- n.lock.Lock()
- defer n.lock.Unlock()
- err := n.loadNetworks()
- if err != nil {
- return err
- }
-
- network, err := n.getNetwork(nameOrID)
- if err != nil {
- return err
- }
-
- // Removing the default network is not allowed.
- if network.libpodNet.Name == n.defaultNetwork {
- return errors.Errorf("default network %s cannot be removed", n.defaultNetwork)
- }
-
- // Remove the bridge network interface on the host.
- if network.libpodNet.Driver == types.BridgeNetworkDriver {
- link, err := netlink.LinkByName(network.libpodNet.NetworkInterface)
- if err == nil {
- err = netlink.LinkDel(link)
- // only log the error, it is not fatal
- if err != nil {
- logrus.Infof("Failed to remove network interface %s: %v", network.libpodNet.NetworkInterface, err)
- }
- }
- }
-
- file := network.filename
- delete(n.networks, network.libpodNet.Name)
-
- // make sure to not error for ErrNotExist
- if err := os.Remove(file); err != nil && !errors.Is(err, os.ErrNotExist) {
- return err
- }
- return nil
-}
-
-// NetworkList will return all known Networks. Optionally you can
-// supply a list of filter functions. Only if a network matches all
-// functions it is returned.
-func (n *cniNetwork) NetworkList(filters ...types.FilterFunc) ([]types.Network, error) {
- n.lock.Lock()
- defer n.lock.Unlock()
- err := n.loadNetworks()
- if err != nil {
- return nil, err
- }
-
- networks := make([]types.Network, 0, len(n.networks))
-outer:
- for _, net := range n.networks {
- for _, filter := range filters {
- // All filters have to match, if one does not match we can skip to the next network.
- if !filter(*net.libpodNet) {
- continue outer
- }
- }
- networks = append(networks, *net.libpodNet)
- }
- return networks, nil
-}
-
-// NetworkInspect will return the Network with the given name or ID.
-func (n *cniNetwork) NetworkInspect(nameOrID string) (types.Network, error) {
- n.lock.Lock()
- defer n.lock.Unlock()
- err := n.loadNetworks()
- if err != nil {
- return types.Network{}, err
- }
-
- network, err := n.getNetwork(nameOrID)
- if err != nil {
- return types.Network{}, err
- }
- return *network.libpodNet, nil
-}
-
-func createIPMACVLAN(network *types.Network) error {
- if network.Internal {
- return errors.New("internal is not supported with macvlan")
- }
- if network.NetworkInterface != "" {
- interfaceNames, err := internalutil.GetLiveNetworkNames()
- if err != nil {
- return err
- }
- if !pkgutil.StringInSlice(network.NetworkInterface, interfaceNames) {
- return errors.Errorf("parent interface %s does not exists", network.NetworkInterface)
- }
- }
- if len(network.Subnets) == 0 {
- network.IPAMOptions["driver"] = types.DHCPIPAMDriver
- } else {
- network.IPAMOptions["driver"] = types.HostLocalIPAMDriver
- }
- return nil
-}
diff --git a/libpod/network/cni/config_test.go b/libpod/network/cni/config_test.go
deleted file mode 100644
index c2e5fc985..000000000
--- a/libpod/network/cni/config_test.go
+++ /dev/null
@@ -1,1378 +0,0 @@
-// +build linux
-
-package cni_test
-
-import (
- "bytes"
- "io/ioutil"
- "net"
- "os"
- "path/filepath"
- "time"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
- gomegaTypes "github.com/onsi/gomega/types"
- "github.com/sirupsen/logrus"
-
- "github.com/containers/podman/v3/libpod/network/types"
- "github.com/containers/podman/v3/libpod/network/util"
-)
-
-var _ = Describe("Config", func() {
- var (
- libpodNet types.ContainerNetwork
- cniConfDir string
- logBuffer bytes.Buffer
- )
-
- BeforeEach(func() {
- var err error
- cniConfDir, err = ioutil.TempDir("", "podman_cni_test")
- if err != nil {
- Fail("Failed to create tmpdir")
-
- }
- logBuffer = bytes.Buffer{}
- logrus.SetOutput(&logBuffer)
- })
-
- JustBeforeEach(func() {
- var err error
- libpodNet, err = getNetworkInterface(cniConfDir, false)
- if err != nil {
- Fail("Failed to create NewCNINetworkInterface")
- }
- })
-
- AfterEach(func() {
- os.RemoveAll(cniConfDir)
- })
-
- Context("basic network config tests", func() {
-
- It("check default network config exists", func() {
- networks, err := libpodNet.NetworkList()
- Expect(err).To(BeNil())
- Expect(networks).To(HaveLen(1))
- Expect(networks[0].Name).To(Equal("podman"))
- Expect(networks[0].Driver).To(Equal("bridge"))
- Expect(networks[0].NetworkInterface).To(Equal("cni-podman0"))
- Expect(networks[0].Created.Before(time.Now())).To(BeTrue())
- Expect(networks[0].Subnets).To(HaveLen(1))
- Expect(networks[0].Subnets[0].Subnet.String()).To(Equal("10.88.0.0/16"))
- Expect(networks[0].Subnets[0].Gateway.String()).To(Equal("10.88.0.1"))
- Expect(networks[0].Subnets[0].LeaseRange).To(BeNil())
- Expect(networks[0].IPAMOptions).To(HaveKeyWithValue("driver", "host-local"))
- Expect(networks[0].Options).To(BeEmpty())
- Expect(networks[0].Labels).To(BeEmpty())
- Expect(networks[0].DNSEnabled).To(BeFalse())
- Expect(networks[0].Internal).To(BeFalse())
- })
-
- It("basic network create, inspect and remove", func() {
- // Because we get the time from the file create timestamp there is small precision
- // loss so lets remove 500 milliseconds to make sure this test does not flake.
- now := time.Now().Add(-500 * time.Millisecond)
- network := types.Network{}
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- path := filepath.Join(cniConfDir, network1.Name+".conflist")
- Expect(path).To(BeARegularFile())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Labels).To(BeEmpty())
- Expect(network1.Options).To(BeEmpty())
- Expect(network1.IPAMOptions).ToNot(BeEmpty())
- Expect(network1.IPAMOptions).To(HaveKeyWithValue("driver", "host-local"))
- Expect(network1.Created.After(now)).To(BeTrue())
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal("10.89.0.0/24"))
- Expect(network1.Subnets[0].Gateway.String()).To(Equal("10.89.0.1"))
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
- Expect(network1.DNSEnabled).To(BeFalse())
- Expect(network1.Internal).To(BeFalse())
-
- // inspect by name
- network2, err := libpodNet.NetworkInspect(network1.Name)
- Expect(err).To(BeNil())
- Expect(network2).To(Equal(network1))
-
- // inspect by ID
- network2, err = libpodNet.NetworkInspect(network1.ID)
- Expect(err).To(BeNil())
- Expect(network2).To(Equal(network1))
-
- // inspect by partial ID
- network2, err = libpodNet.NetworkInspect(network1.ID[:10])
- Expect(err).To(BeNil())
- Expect(network2).To(Equal(network1))
-
- // create a new interface to force a config load from disk
- libpodNet, err = getNetworkInterface(cniConfDir, false)
- Expect(err).To(BeNil())
-
- network2, err = libpodNet.NetworkInspect(network1.Name)
- Expect(err).To(BeNil())
- Expect(network2).To(Equal(network1))
-
- err = libpodNet.NetworkRemove(network1.Name)
- Expect(err).To(BeNil())
- Expect(path).ToNot(BeARegularFile())
-
- _, err = libpodNet.NetworkInspect(network1.Name)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("network not found"))
- })
-
- It("create two networks", func() {
- network := types.Network{}
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.Subnets).To(HaveLen(1))
-
- network = types.Network{}
- network2, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network2.Name).ToNot(Equal(network1.Name))
- Expect(network2.ID).ToNot(Equal(network1.ID))
- Expect(network2.NetworkInterface).ToNot(Equal(network1.NetworkInterface))
- Expect(network2.Subnets).To(HaveLen(1))
- Expect(network2.Subnets[0].Subnet.Contains(network1.Subnets[0].Subnet.IP)).To(BeFalse())
- })
-
- It("create bridge config", func() {
- network := types.Network{Driver: "bridge"}
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(filepath.Join(cniConfDir, network1.Name+".conflist")).To(BeARegularFile())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Labels).To(BeEmpty())
- Expect(network1.Options).To(BeEmpty())
- Expect(network1.IPAMOptions).ToNot(BeEmpty())
- Expect(network1.IPAMOptions).To(HaveKeyWithValue("driver", "host-local"))
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal("10.89.0.0/24"))
- Expect(network1.Subnets[0].Gateway.String()).To(Equal("10.89.0.1"))
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
- Expect(network1.DNSEnabled).To(BeFalse())
- Expect(network1.Internal).To(BeFalse())
- })
-
- It("create bridge with same name should fail", func() {
- network := types.Network{
- Driver: "bridge",
- NetworkInterface: "cni-podman2",
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).To(Equal("cni-podman2"))
- Expect(network1.Driver).To(Equal("bridge"))
-
- _, err = libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("bridge name cni-podman2 already in use"))
- })
-
- It("create macvlan config", func() {
- network := types.Network{Driver: "macvlan"}
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(filepath.Join(cniConfDir, network1.Name+".conflist")).To(BeARegularFile())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("macvlan"))
- Expect(network1.Labels).To(BeEmpty())
- Expect(network1.Options).To(BeEmpty())
- Expect(network1.IPAMOptions).ToNot(BeEmpty())
- Expect(network1.IPAMOptions).To(HaveKeyWithValue("driver", "dhcp"))
- Expect(network1.Subnets).To(HaveLen(0))
- Expect(network1.DNSEnabled).To(BeFalse())
- Expect(network1.Internal).To(BeFalse())
- })
-
- It("create macvlan config with device", func() {
- network := types.Network{
- Driver: "macvlan",
- NetworkInterface: "lo",
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- path := filepath.Join(cniConfDir, network1.Name+".conflist")
- Expect(path).To(BeARegularFile())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("macvlan"))
- Expect(network1.Labels).To(BeEmpty())
- Expect(network1.Options).To(BeEmpty())
- Expect(network1.Subnets).To(HaveLen(0))
- Expect(network1.DNSEnabled).To(BeFalse())
- Expect(network1.Internal).To(BeFalse())
- Expect(network1.IPAMOptions).To(HaveKeyWithValue("driver", "dhcp"))
- grepInFile(path, `"type": "macvlan"`)
- grepInFile(path, `"master": "lo"`)
- grepInFile(path, `"type": "dhcp"`)
- })
-
- It("create macvlan config with subnet", func() {
- subnet := "10.1.0.0/24"
- n, _ := types.ParseCIDR(subnet)
- network := types.Network{
- Driver: "macvlan",
- Subnets: []types.Subnet{
- {Subnet: n},
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- path := filepath.Join(cniConfDir, network1.Name+".conflist")
- Expect(path).To(BeARegularFile())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("macvlan"))
- Expect(network1.Labels).To(BeEmpty())
- Expect(network1.Options).To(BeEmpty())
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet))
- Expect(network1.Subnets[0].Gateway.String()).To(Equal("10.1.0.1"))
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
- Expect(network1.DNSEnabled).To(BeFalse())
- Expect(network1.Internal).To(BeFalse())
- Expect(network1.IPAMOptions).To(HaveKeyWithValue("driver", "host-local"))
- grepInFile(path, `"type": "host-local"`)
- })
-
- It("create ipvlan config with subnet", func() {
- subnet := "10.1.0.0/24"
- n, _ := types.ParseCIDR(subnet)
- network := types.Network{
- Driver: "ipvlan",
- Subnets: []types.Subnet{
- {Subnet: n},
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- path := filepath.Join(cniConfDir, network1.Name+".conflist")
- Expect(path).To(BeARegularFile())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("ipvlan"))
- Expect(network1.Labels).To(BeEmpty())
- Expect(network1.Options).To(BeEmpty())
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet))
- Expect(network1.Subnets[0].Gateway.String()).To(Equal("10.1.0.1"))
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
- Expect(network1.DNSEnabled).To(BeFalse())
- Expect(network1.Internal).To(BeFalse())
- Expect(network1.IPAMOptions).To(HaveKeyWithValue("driver", "host-local"))
- grepInFile(path, `"type": "host-local"`)
- })
-
- It("create macvlan config with mode", func() {
- for _, mode := range []string{"bridge", "private", "vepa", "passthru"} {
- network := types.Network{
- Driver: "macvlan",
- Options: map[string]string{
- "mode": mode,
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- path := filepath.Join(cniConfDir, network1.Name+".conflist")
- Expect(path).To(BeARegularFile())
- Expect(network1.Driver).To(Equal("macvlan"))
- Expect(network1.Options).To(HaveKeyWithValue("mode", mode))
- Expect(network1.IPAMOptions).ToNot(BeEmpty())
- Expect(network1.IPAMOptions).To(HaveKeyWithValue("driver", "dhcp"))
- grepInFile(path, `"mode": "`+mode+`"`)
- }
- })
-
- It("create macvlan config with invalid mode", func() {
- network := types.Network{
- Driver: "macvlan",
- Options: map[string]string{
- "mode": "test",
- },
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring(`unknown macvlan mode "test"`))
- })
-
- It("create macvlan config with invalid device", func() {
- network := types.Network{
- Driver: "macvlan",
- NetworkInterface: "idonotexists",
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("parent interface idonotexists does not exists"))
- })
-
- It("create macvlan config with internal should fail", func() {
- network := types.Network{
- Driver: "macvlan",
- Internal: true,
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("internal is not supported with macvlan"))
- })
-
- It("create ipvlan config with mode", func() {
- for _, mode := range []string{"l2", "l3", "l3s"} {
- network := types.Network{
- Driver: "ipvlan",
- Options: map[string]string{
- "mode": mode,
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- path := filepath.Join(cniConfDir, network1.Name+".conflist")
- Expect(path).To(BeARegularFile())
- Expect(network1.Driver).To(Equal("ipvlan"))
- Expect(network1.Options).To(HaveKeyWithValue("mode", mode))
- Expect(network1.IPAMOptions).ToNot(BeEmpty())
- Expect(network1.IPAMOptions).To(HaveKeyWithValue("driver", "dhcp"))
- grepInFile(path, `"mode": "`+mode+`"`)
-
- // reload configs from disk
- libpodNet, err = getNetworkInterface(cniConfDir, false)
- Expect(err).To(BeNil())
-
- network2, err := libpodNet.NetworkInspect(network1.Name)
- Expect(err).To(BeNil())
- Expect(network2).To(Equal(network1))
- }
- })
-
- It("create ipvlan config with invalid mode", func() {
- network := types.Network{
- Driver: "ipvlan",
- Options: map[string]string{
- "mode": "test",
- },
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring(`unknown ipvlan mode "test"`))
- })
-
- It("create bridge with subnet", func() {
- subnet := "10.0.0.0/24"
- n, _ := types.ParseCIDR(subnet)
-
- network := types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n},
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet))
- Expect(network1.Subnets[0].Gateway.String()).To(Equal("10.0.0.1"))
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
- })
-
- It("create bridge with ipv6 subnet", func() {
- subnet := "fdcc::/64"
- n, _ := types.ParseCIDR(subnet)
-
- network := types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n},
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.IPv6Enabled).To(BeTrue())
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet))
- Expect(network1.Subnets[0].Gateway.String()).To(Equal("fdcc::1"))
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
-
- // reload configs from disk
- libpodNet, err = getNetworkInterface(cniConfDir, false)
- Expect(err).To(BeNil())
- // check the the networks are identical
- network2, err := libpodNet.NetworkInspect(network1.Name)
- Expect(err).To(BeNil())
- Expect(network1).To(Equal(network2))
- })
-
- It("create bridge with ipv6 enabled", func() {
- network := types.Network{
- Driver: "bridge",
- IPv6Enabled: true,
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(2))
- Expect(network1.Subnets[0].Subnet.String()).To(ContainSubstring(".0/24"))
- Expect(network1.Subnets[0].Gateway).ToNot(BeNil())
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
- Expect(network1.Subnets[1].Subnet.String()).To(ContainSubstring("::/64"))
- Expect(network1.Subnets[1].Gateway).ToNot(BeNil())
- Expect(network1.Subnets[1].LeaseRange).To(BeNil())
- })
-
- It("create bridge with ipv6 enabled and ipv4 subnet", func() {
- subnet := "10.100.0.0/24"
- n, _ := types.ParseCIDR(subnet)
-
- network := types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n},
- },
- IPv6Enabled: true,
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(2))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet))
- Expect(network1.Subnets[0].Gateway).ToNot(BeNil())
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
- Expect(network1.Subnets[1].Subnet.String()).To(ContainSubstring("::/64"))
- Expect(network1.Subnets[1].Gateway).ToNot(BeNil())
- Expect(network1.Subnets[1].LeaseRange).To(BeNil())
- })
-
- It("create bridge with ipv6 enabled and ipv6 subnet", func() {
- subnet := "fd66::/64"
- n, _ := types.ParseCIDR(subnet)
-
- network := types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n},
- },
- IPv6Enabled: true,
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(2))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet))
- Expect(network1.Subnets[0].Gateway).ToNot(BeNil())
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
- Expect(network1.Subnets[1].Subnet.String()).To(ContainSubstring(".0/24"))
- Expect(network1.Subnets[1].Gateway).ToNot(BeNil())
- Expect(network1.Subnets[1].LeaseRange).To(BeNil())
- })
-
- It("create bridge with ipv6 enabled and ipv4+ipv6 subnet", func() {
- subnet1 := "10.100.0.0/24"
- n1, _ := types.ParseCIDR(subnet1)
- subnet2 := "fd66::/64"
- n2, _ := types.ParseCIDR(subnet2)
-
- network := types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n1}, {Subnet: n2},
- },
- IPv6Enabled: true,
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(2))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet1))
- Expect(network1.Subnets[0].Gateway).ToNot(BeNil())
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
- Expect(network1.Subnets[1].Subnet.String()).To(Equal(subnet2))
- Expect(network1.Subnets[1].Gateway).ToNot(BeNil())
- Expect(network1.Subnets[1].LeaseRange).To(BeNil())
- })
-
- It("create bridge with ipv6 enabled and two ipv4 subnets", func() {
- subnet1 := "10.100.0.0/24"
- n1, _ := types.ParseCIDR(subnet1)
- subnet2 := "10.200.0.0/24"
- n2, _ := types.ParseCIDR(subnet2)
-
- network := types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n1}, {Subnet: n2},
- },
- IPv6Enabled: true,
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(3))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet1))
- Expect(network1.Subnets[0].Gateway).ToNot(BeNil())
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
- Expect(network1.Subnets[1].Subnet.String()).To(Equal(subnet2))
- Expect(network1.Subnets[1].Gateway).ToNot(BeNil())
- Expect(network1.Subnets[1].LeaseRange).To(BeNil())
- Expect(network1.Subnets[2].Subnet.String()).To(ContainSubstring("::/64"))
- Expect(network1.Subnets[2].Gateway).ToNot(BeNil())
- Expect(network1.Subnets[2].LeaseRange).To(BeNil())
- })
-
- It("create bridge with subnet and gateway", func() {
- subnet := "10.0.0.5/24"
- n, _ := types.ParseCIDR(subnet)
- gateway := "10.0.0.50"
- g := net.ParseIP(gateway)
- network := types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n, Gateway: g},
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal("10.0.0.0/24"))
- Expect(network1.Subnets[0].Gateway.String()).To(Equal(gateway))
- Expect(network1.Subnets[0].LeaseRange).To(BeNil())
- })
-
- It("create bridge with subnet and gateway not in the same subnet", func() {
- subnet := "10.0.0.0/24"
- n, _ := types.ParseCIDR(subnet)
- gateway := "10.10.0.50"
- g := net.ParseIP(gateway)
- network := types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n, Gateway: g},
- },
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("not in subnet"))
- })
-
- It("create bridge with subnet and lease range", func() {
- subnet := "10.0.0.0/24"
- n, _ := types.ParseCIDR(subnet)
- startIP := "10.0.0.10"
- network := types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n, LeaseRange: &types.LeaseRange{
- StartIP: net.ParseIP(startIP),
- }},
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet))
- Expect(network1.Subnets[0].Gateway.String()).To(Equal("10.0.0.1"))
- Expect(network1.Subnets[0].LeaseRange.StartIP.String()).To(Equal(startIP))
-
- err = libpodNet.NetworkRemove(network1.Name)
- Expect(err).To(BeNil())
-
- endIP := "10.0.0.30"
- network = types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n, LeaseRange: &types.LeaseRange{
- EndIP: net.ParseIP(endIP),
- }},
- },
- }
- network1, err = libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(filepath.Join(cniConfDir, network1.Name+".conflist")).To(BeARegularFile())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet))
- Expect(network1.Subnets[0].Gateway.String()).To(Equal("10.0.0.1"))
- Expect(network1.Subnets[0].LeaseRange.EndIP.String()).To(Equal(endIP))
-
- err = libpodNet.NetworkRemove(network1.Name)
- Expect(err).To(BeNil())
-
- network = types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n, LeaseRange: &types.LeaseRange{
- StartIP: net.ParseIP(startIP),
- EndIP: net.ParseIP(endIP),
- }},
- },
- }
- network1, err = libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet))
- Expect(network1.Subnets[0].Gateway.String()).To(Equal("10.0.0.1"))
- Expect(network1.Subnets[0].LeaseRange.StartIP.String()).To(Equal(startIP))
- Expect(network1.Subnets[0].LeaseRange.EndIP.String()).To(Equal(endIP))
-
- // create a new interface to force a config load from disk
- libpodNet, err = getNetworkInterface(cniConfDir, false)
- Expect(err).To(BeNil())
-
- network1, err = libpodNet.NetworkInspect(network1.Name)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(BeEmpty())
- Expect(network1.ID).ToNot(BeEmpty())
- Expect(network1.NetworkInterface).ToNot(BeEmpty())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).To(Equal(subnet))
- Expect(network1.Subnets[0].Gateway.String()).To(Equal("10.0.0.1"))
- Expect(network1.Subnets[0].LeaseRange.StartIP.String()).To(Equal(startIP))
- Expect(network1.Subnets[0].LeaseRange.EndIP.String()).To(Equal(endIP))
- })
-
- It("create bridge with subnet and invalid lease range", func() {
- subnet := "10.0.0.0/24"
- n, _ := types.ParseCIDR(subnet)
- startIP := "10.0.1.2"
- network := types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n, LeaseRange: &types.LeaseRange{
- StartIP: net.ParseIP(startIP),
- }},
- },
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("not in subnet"))
-
- endIP := "10.1.1.1"
- network = types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: n, LeaseRange: &types.LeaseRange{
- EndIP: net.ParseIP(endIP),
- }},
- },
- }
- _, err = libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("not in subnet"))
- })
-
- It("create bridge with broken subnet", func() {
- network := types.Network{
- Driver: "bridge",
- Subnets: []types.Subnet{
- {Subnet: types.IPNet{}},
- },
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("subnet ip is nil"))
- })
-
- It("create network with name", func() {
- name := "myname"
- network := types.Network{
- Name: name,
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).To(Equal(name))
- Expect(network1.NetworkInterface).ToNot(Equal(name))
- Expect(network1.Driver).To(Equal("bridge"))
- })
-
- It("create network with invalid name", func() {
- name := "myname@some"
- network := types.Network{
- Name: name,
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- })
-
- It("create network with name", func() {
- name := "myname"
- network := types.Network{
- Name: name,
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).To(Equal(name))
- Expect(network1.NetworkInterface).ToNot(Equal(name))
- Expect(network1.Driver).To(Equal("bridge"))
- })
-
- It("create network with invalid name", func() {
- name := "myname@some"
- network := types.Network{
- Name: name,
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- })
-
- It("create network with interface name", func() {
- name := "myname"
- network := types.Network{
- NetworkInterface: name,
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).ToNot(Equal(name))
- Expect(network1.NetworkInterface).To(Equal(name))
- Expect(network1.Driver).To(Equal("bridge"))
- })
-
- It("create network with invalid interface name", func() {
- name := "myname@some"
- network := types.Network{
- NetworkInterface: name,
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- })
-
- It("create network with ID should fail", func() {
- id := "17f29b073143d8cd97b5bbe492bdeffec1c5fee55cc1fe2112c8b9335f8b6121"
- network := types.Network{
- ID: id,
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("ID can not be set for network create"))
- })
-
- It("create bridge with dns", func() {
- network := types.Network{
- Driver: "bridge",
- DNSEnabled: true,
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.DNSEnabled).To(BeTrue())
- path := filepath.Join(cniConfDir, network1.Name+".conflist")
- Expect(path).To(BeARegularFile())
- grepInFile(path, `"type": "dnsname"`)
- })
-
- It("create bridge with internal", func() {
- network := types.Network{
- Driver: "bridge",
- Internal: true,
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).ToNot(BeEmpty())
- Expect(network1.Subnets[0].Gateway).To(BeNil())
- Expect(network1.Internal).To(BeTrue())
- })
-
- It("create network with labels", func() {
- network := types.Network{
- Labels: map[string]string{
- "key": "value",
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Labels).ToNot(BeNil())
- Expect(network1.Labels).To(ContainElement("value"))
- })
-
- It("create network with mtu option", func() {
- network := types.Network{
- Options: map[string]string{
- "mtu": "1500",
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Options).ToNot(BeNil())
- path := filepath.Join(cniConfDir, network1.Name+".conflist")
- Expect(path).To(BeARegularFile())
- grepInFile(path, `"mtu": 1500,`)
- Expect(network1.Options).To(HaveKeyWithValue("mtu", "1500"))
- })
-
- It("create network with invalid mtu option", func() {
- network := types.Network{
- Options: map[string]string{
- "mtu": "abc",
- },
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring(`parsing "abc": invalid syntax`))
-
- network = types.Network{
- Options: map[string]string{
- "mtu": "-1",
- },
- }
- _, err = libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring(`mtu -1 is less than zero`))
- })
-
- It("create macvlan network with mtu option", func() {
- network := types.Network{
- Driver: "macvlan",
- Options: map[string]string{
- "mtu": "1500",
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Driver).To(Equal("macvlan"))
- Expect(network1.Options).ToNot(BeNil())
- path := filepath.Join(cniConfDir, network1.Name+".conflist")
- Expect(path).To(BeARegularFile())
- grepInFile(path, `"mtu": 1500`)
- Expect(network1.Options).To(HaveKeyWithValue("mtu", "1500"))
- })
-
- It("create network with vlan option", func() {
- network := types.Network{
- Options: map[string]string{
- "vlan": "5",
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Options).ToNot(BeNil())
- path := filepath.Join(cniConfDir, network1.Name+".conflist")
- Expect(path).To(BeARegularFile())
- grepInFile(path, `"vlan": 5,`)
- Expect(network1.Options).To(HaveKeyWithValue("vlan", "5"))
- })
-
- It("create network with invalid vlan option", func() {
- network := types.Network{
- Options: map[string]string{
- "vlan": "abc",
- },
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring(`parsing "abc": invalid syntax`))
-
- network = types.Network{
- Options: map[string]string{
- "vlan": "-1",
- },
- }
- _, err = libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring(`vlan ID -1 must be between 0 and 4094`))
- })
-
- It("network create unsupported option", func() {
- network := types.Network{Options: map[string]string{
- "someopt": "",
- }}
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("unsupported network option someopt"))
- })
-
- It("network create unsupported driver", func() {
- network := types.Network{
- Driver: "someDriver",
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("unsupported driver someDriver"))
- })
-
- It("network create internal and dns", func() {
- network := types.Network{
- Driver: "bridge",
- Internal: true,
- DNSEnabled: true,
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Driver).To(Equal("bridge"))
- Expect(network1.Subnets).To(HaveLen(1))
- Expect(network1.Subnets[0].Subnet.String()).ToNot(BeEmpty())
- Expect(network1.Subnets[0].Gateway).To(BeNil())
- Expect(network1.Internal).To(BeTrue())
- // internal and dns does not work, dns should be disabled
- Expect(network1.DNSEnabled).To(BeFalse())
- logString := logBuffer.String()
- Expect(logString).To(ContainSubstring("dnsname and internal networks are incompatible"))
- })
-
- It("network inspect partial ID", func() {
- network := types.Network{Name: "net4"}
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.ID).To(Equal("b44b7426c006839e7fe6f15d1faf64db58079d5233cba09b43be2257c1652cf5"))
- network = types.Network{Name: "net5"}
- network1, err = libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.ID).To(Equal("b67e86fb039828ad686aa13667975b9e51f192eb617044faf06cded9d31602af"))
-
- // Note ID is the sha256 from the name
- // both net4 and net5 have an ID starting with b...
- _, err = libpodNet.NetworkInspect("b")
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("more than one result for network ID"))
- })
-
- It("network create two with same name", func() {
- network := types.Network{Name: "net"}
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Name).To(Equal("net"))
- network = types.Network{Name: "net"}
- _, err = libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("network name net already used"))
- })
-
- It("remove default network config should fail", func() {
- err := libpodNet.NetworkRemove("podman")
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(Equal("default network podman cannot be removed"))
-
- network, err := libpodNet.NetworkInspect("podman")
- Expect(err).To(BeNil())
- err = libpodNet.NetworkRemove(network.ID)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(Equal("default network podman cannot be removed"))
- })
-
- It("network create with same subnet", func() {
- subnet := "10.0.0.0/24"
- n, _ := types.ParseCIDR(subnet)
- subnet2 := "10.10.0.0/24"
- n2, _ := types.ParseCIDR(subnet2)
- network := types.Network{Subnets: []types.Subnet{{Subnet: n}, {Subnet: n2}}}
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Subnets).To(HaveLen(2))
- network = types.Network{Subnets: []types.Subnet{{Subnet: n}}}
- _, err = libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("subnet 10.0.0.0/24 is already used on the host or by another config"))
- network = types.Network{Subnets: []types.Subnet{{Subnet: n2}}}
- _, err = libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("subnet 10.10.0.0/24 is already used on the host or by another config"))
- })
- })
-
- Context("network load valid existing ones", func() {
-
- BeforeEach(func() {
- dir := "testfiles/valid"
- files, err := ioutil.ReadDir(dir)
- if err != nil {
- Fail("Failed to read test directory")
- }
- for _, file := range files {
- filename := file.Name()
- data, err := ioutil.ReadFile(filepath.Join(dir, filename))
- if err != nil {
- Fail("Failed to copy test files")
- }
- err = ioutil.WriteFile(filepath.Join(cniConfDir, filename), data, 0700)
- if err != nil {
- Fail("Failed to copy test files")
- }
- }
- })
-
- It("load networks from disk", func() {
- nets, err := libpodNet.NetworkList()
- Expect(err).To(BeNil())
- Expect(nets).To(HaveLen(9))
- // test the we do not show logrus warnings/errors
- logString := logBuffer.String()
- Expect(logString).To(BeEmpty())
- })
-
- It("change network struct fields should not affect network struct in the backend", func() {
- nets, err := libpodNet.NetworkList()
- Expect(err).To(BeNil())
- Expect(nets).To(HaveLen(9))
-
- nets[0].Name = "myname"
- nets, err = libpodNet.NetworkList()
- Expect(err).To(BeNil())
- Expect(nets).To(HaveLen(9))
- Expect(nets).ToNot(ContainElement(HaveNetworkName("myname")))
-
- network, err := libpodNet.NetworkInspect("bridge")
- Expect(err).To(BeNil())
- network.NetworkInterface = "abc"
-
- network, err = libpodNet.NetworkInspect("bridge")
- Expect(err).To(BeNil())
- Expect(network.NetworkInterface).ToNot(Equal("abc"))
- })
-
- It("bridge network", func() {
- network, err := libpodNet.NetworkInspect("bridge")
- Expect(err).To(BeNil())
- Expect(network.Name).To(Equal("bridge"))
- Expect(network.ID).To(HaveLen(64))
- Expect(network.NetworkInterface).To(Equal("cni-podman9"))
- Expect(network.Driver).To(Equal("bridge"))
- Expect(network.Subnets).To(HaveLen(1))
- Expect(network.Subnets[0].Subnet.String()).To(Equal("10.89.8.0/24"))
- Expect(network.Subnets[0].Gateway.String()).To(Equal("10.89.8.1"))
- Expect(network.Subnets[0].LeaseRange).ToNot(BeNil())
- Expect(network.Subnets[0].LeaseRange.StartIP.String()).To(Equal("10.89.8.20"))
- Expect(network.Subnets[0].LeaseRange.EndIP.String()).To(Equal("10.89.8.50"))
- Expect(network.Internal).To(BeFalse())
- })
-
- It("macvlan network", func() {
- network, err := libpodNet.NetworkInspect("macvlan")
- Expect(err).To(BeNil())
- Expect(network.Name).To(Equal("macvlan"))
- Expect(network.ID).To(HaveLen(64))
- Expect(network.NetworkInterface).To(Equal("lo"))
- Expect(network.Driver).To(Equal("macvlan"))
- Expect(network.Subnets).To(HaveLen(0))
- // DHCP
- })
-
- It("internal network", func() {
- network, err := libpodNet.NetworkInspect("internal")
- Expect(err).To(BeNil())
- Expect(network.Name).To(Equal("internal"))
- Expect(network.ID).To(HaveLen(64))
- Expect(network.NetworkInterface).To(Equal("cni-podman8"))
- Expect(network.Driver).To(Equal("bridge"))
- Expect(network.Subnets).To(HaveLen(1))
- Expect(network.Subnets[0].Subnet.String()).To(Equal("10.89.7.0/24"))
- Expect(network.Subnets[0].Gateway).To(BeNil())
- Expect(network.Internal).To(BeTrue())
- })
-
- It("bridge network with mtu", func() {
- network, err := libpodNet.NetworkInspect("mtu")
- Expect(err).To(BeNil())
- Expect(network.Name).To(Equal("mtu"))
- Expect(network.ID).To(HaveLen(64))
- Expect(network.NetworkInterface).To(Equal("cni-podman13"))
- Expect(network.Driver).To(Equal("bridge"))
- Expect(network.Subnets).To(HaveLen(1))
- Expect(network.Subnets[0].Subnet.String()).To(Equal("10.89.11.0/24"))
- Expect(network.Subnets[0].Gateway.String()).To(Equal("10.89.11.1"))
- Expect(network.Internal).To(BeFalse())
- Expect(network.Options).To(HaveLen(1))
- Expect(network.Options).To(HaveKeyWithValue("mtu", "1500"))
- })
-
- It("macvlan network with mtu", func() {
- network, err := libpodNet.NetworkInspect("macvlan_mtu")
- Expect(err).To(BeNil())
- Expect(network.Name).To(Equal("macvlan_mtu"))
- Expect(network.ID).To(HaveLen(64))
- Expect(network.NetworkInterface).To(Equal("lo"))
- Expect(network.Driver).To(Equal("macvlan"))
- Expect(network.Subnets).To(HaveLen(0))
- Expect(network.Internal).To(BeFalse())
- Expect(network.Options).To(HaveLen(1))
- Expect(network.Options).To(HaveKeyWithValue("mtu", "1300"))
- Expect(network.IPAMOptions).To(HaveLen(1))
- Expect(network.IPAMOptions).To(HaveKeyWithValue("driver", "dhcp"))
- })
-
- It("bridge network with vlan", func() {
- network, err := libpodNet.NetworkInspect("vlan")
- Expect(err).To(BeNil())
- Expect(network.Name).To(Equal("vlan"))
- Expect(network.ID).To(HaveLen(64))
- Expect(network.NetworkInterface).To(Equal("cni-podman14"))
- Expect(network.Driver).To(Equal("bridge"))
- Expect(network.Subnets).To(HaveLen(1))
- Expect(network.Options).To(HaveLen(1))
- Expect(network.Options).To(HaveKeyWithValue("vlan", "5"))
- })
-
- It("bridge network with labels", func() {
- network, err := libpodNet.NetworkInspect("label")
- Expect(err).To(BeNil())
- Expect(network.Name).To(Equal("label"))
- Expect(network.ID).To(HaveLen(64))
- Expect(network.NetworkInterface).To(Equal("cni-podman15"))
- Expect(network.Driver).To(Equal("bridge"))
- Expect(network.Subnets).To(HaveLen(1))
- Expect(network.Labels).To(HaveLen(1))
- Expect(network.Labels).To(HaveKeyWithValue("mykey", "value"))
- })
-
- It("dual stack network", func() {
- network, err := libpodNet.NetworkInspect("dualstack")
- Expect(err).To(BeNil())
- Expect(network.Name).To(Equal("dualstack"))
- Expect(network.ID).To(HaveLen(64))
- Expect(network.NetworkInterface).To(Equal("cni-podman21"))
- Expect(network.Driver).To(Equal("bridge"))
- Expect(network.Subnets).To(HaveLen(2))
-
- sub1, _ := types.ParseCIDR("fd10:88:a::/64")
- sub2, _ := types.ParseCIDR("10.89.19.0/24")
- Expect(network.Subnets).To(ContainElements(
- types.Subnet{Subnet: sub1, Gateway: net.ParseIP("fd10:88:a::1")},
- types.Subnet{Subnet: sub2, Gateway: net.ParseIP("10.89.19.10").To4()},
- ))
- })
-
- It("network list with filters (name)", func() {
- filters := map[string][]string{
- "name": {"internal", "bridge"},
- }
- filterFuncs, err := util.GenerateNetworkFilters(filters)
- Expect(err).To(BeNil())
-
- networks, err := libpodNet.NetworkList(filterFuncs...)
- Expect(err).To(BeNil())
- Expect(networks).To(HaveLen(2))
- Expect(networks).To(ConsistOf(HaveNetworkName("internal"), HaveNetworkName("bridge")))
- })
-
- It("network list with filters (partial name)", func() {
- filters := map[string][]string{
- "name": {"inte", "bri"},
- }
- filterFuncs, err := util.GenerateNetworkFilters(filters)
- Expect(err).To(BeNil())
-
- networks, err := libpodNet.NetworkList(filterFuncs...)
- Expect(err).To(BeNil())
- Expect(networks).To(HaveLen(2))
- Expect(networks).To(ConsistOf(HaveNetworkName("internal"), HaveNetworkName("bridge")))
- })
-
- It("network list with filters (id)", func() {
- filters := map[string][]string{
- "id": {"3bed2cb3a3acf7b6a8ef408420cc682d5520e26976d354254f528c965612054f", "17f29b073143d8cd97b5bbe492bdeffec1c5fee55cc1fe2112c8b9335f8b6121"},
- }
- filterFuncs, err := util.GenerateNetworkFilters(filters)
- Expect(err).To(BeNil())
-
- networks, err := libpodNet.NetworkList(filterFuncs...)
- Expect(err).To(BeNil())
- Expect(networks).To(HaveLen(2))
- Expect(networks).To(ConsistOf(HaveNetworkName("internal"), HaveNetworkName("bridge")))
- })
-
- It("network list with filters (id)", func() {
- filters := map[string][]string{
- "id": {"3bed2cb3a3acf7b6a8ef408420cc682d5520e26976d354254f528c965612054f", "17f29b073143d8cd97b5bbe492bdeffec1c5fee55cc1fe2112c8b9335f8b6121"},
- }
- filterFuncs, err := util.GenerateNetworkFilters(filters)
- Expect(err).To(BeNil())
-
- networks, err := libpodNet.NetworkList(filterFuncs...)
- Expect(err).To(BeNil())
- Expect(networks).To(HaveLen(2))
- Expect(networks).To(ConsistOf(HaveNetworkName("internal"), HaveNetworkName("bridge")))
- })
-
- It("network list with filters (partial id)", func() {
- filters := map[string][]string{
- "id": {"3bed2cb3a3acf7b6a8ef408420", "17f29b073143d8cd97b5bbe492bde"},
- }
- filterFuncs, err := util.GenerateNetworkFilters(filters)
- Expect(err).To(BeNil())
-
- networks, err := libpodNet.NetworkList(filterFuncs...)
- Expect(err).To(BeNil())
- Expect(networks).To(HaveLen(2))
- Expect(networks).To(ConsistOf(HaveNetworkName("internal"), HaveNetworkName("bridge")))
- })
-
- It("network list with filters (driver)", func() {
- filters := map[string][]string{
- "driver": {"bridge", "macvlan"},
- }
- filterFuncs, err := util.GenerateNetworkFilters(filters)
- Expect(err).To(BeNil())
-
- networks, err := libpodNet.NetworkList(filterFuncs...)
- Expect(err).To(BeNil())
- Expect(networks).To(HaveLen(9))
- Expect(networks).To(ConsistOf(HaveNetworkName("internal"), HaveNetworkName("bridge"),
- HaveNetworkName("mtu"), HaveNetworkName("vlan"), HaveNetworkName("podman"),
- HaveNetworkName("label"), HaveNetworkName("macvlan"), HaveNetworkName("macvlan_mtu"), HaveNetworkName("dualstack")))
- })
-
- It("network list with filters (label)", func() {
- filters := map[string][]string{
- "label": {"mykey"},
- }
- filterFuncs, err := util.GenerateNetworkFilters(filters)
- Expect(err).To(BeNil())
-
- networks, err := libpodNet.NetworkList(filterFuncs...)
- Expect(err).To(BeNil())
- Expect(networks).To(HaveLen(1))
- Expect(networks).To(ConsistOf(HaveNetworkName("label")))
-
- filters = map[string][]string{
- "label": {"mykey=value"},
- }
- filterFuncs, err = util.GenerateNetworkFilters(filters)
- Expect(err).To(BeNil())
-
- networks, err = libpodNet.NetworkList(filterFuncs...)
- Expect(err).To(BeNil())
- Expect(networks).To(HaveLen(1))
- Expect(networks).To(ConsistOf(HaveNetworkName("label")))
- })
-
- It("network list with filters", func() {
- filters := map[string][]string{
- "driver": {"bridge"},
- "label": {"mykey"},
- }
- filterFuncs, err := util.GenerateNetworkFilters(filters)
- Expect(err).To(BeNil())
- Expect(filterFuncs).To(HaveLen(2))
-
- networks, err := libpodNet.NetworkList(filterFuncs...)
- Expect(err).To(BeNil())
- Expect(networks).To(HaveLen(1))
- Expect(networks).To(ConsistOf(HaveNetworkName("label")))
-
- filters = map[string][]string{
- "driver": {"macvlan"},
- "label": {"mykey"},
- }
- filterFuncs, err = util.GenerateNetworkFilters(filters)
- Expect(err).To(BeNil())
-
- networks, err = libpodNet.NetworkList(filterFuncs...)
- Expect(err).To(BeNil())
- Expect(networks).To(HaveLen(0))
- })
-
- It("create bridge network with used interface name", func() {
- network := types.Network{
- NetworkInterface: "cni-podman9",
- }
- _, err := libpodNet.NetworkCreate(network)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("bridge name cni-podman9 already in use"))
- })
- })
-
- Context("network load invalid existing ones", func() {
-
- BeforeEach(func() {
- dir := "testfiles/invalid"
- files, err := ioutil.ReadDir(dir)
- if err != nil {
- Fail("Failed to read test directory")
- }
- for _, file := range files {
- filename := file.Name()
- data, err := ioutil.ReadFile(filepath.Join(dir, filename))
- if err != nil {
- Fail("Failed to copy test files")
- }
- err = ioutil.WriteFile(filepath.Join(cniConfDir, filename), data, 0700)
- if err != nil {
- Fail("Failed to copy test files")
- }
- }
- })
-
- It("load invalid networks from disk", func() {
- nets, err := libpodNet.NetworkList()
- Expect(err).To(BeNil())
- Expect(nets).To(HaveLen(2))
- logString := logBuffer.String()
- Expect(logString).To(ContainSubstring("noname.conflist: error parsing configuration list: no name"))
- Expect(logString).To(ContainSubstring("noplugin.conflist: error parsing configuration list: no plugins in list"))
- Expect(logString).To(ContainSubstring("invalidname.conflist has invalid name, skipping: names must match"))
- Expect(logString).To(ContainSubstring("has the same network name as"))
- Expect(logString).To(ContainSubstring("broken.conflist: error parsing configuration list"))
- Expect(logString).To(ContainSubstring("invalid_gateway.conflist could not be converted to a libpod config, skipping: failed to parse gateway ip 10.89.8"))
- })
-
- })
-
-})
-
-func grepInFile(path string, match string) {
- data, err := ioutil.ReadFile(path)
- ExpectWithOffset(1, err).To(BeNil())
- ExpectWithOffset(1, string(data)).To(ContainSubstring(match))
-}
-
-// HaveNetworkName is a custom GomegaMatcher to match a network name
-func HaveNetworkName(name string) gomegaTypes.GomegaMatcher {
- return WithTransform(func(e types.Network) string {
- return e.Name
- }, Equal(name))
-}
diff --git a/libpod/network/cni/network.go b/libpod/network/cni/network.go
deleted file mode 100644
index 41e3e414e..000000000
--- a/libpod/network/cni/network.go
+++ /dev/null
@@ -1,273 +0,0 @@
-// +build linux
-
-package cni
-
-import (
- "context"
- "crypto/sha256"
- "encoding/hex"
- "os"
- "strings"
- "time"
-
- "github.com/containernetworking/cni/libcni"
- "github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network/types"
- "github.com/containers/storage/pkg/lockfile"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
-)
-
-type cniNetwork struct {
- // cniConfigDir is directory where the cni config files are stored.
- cniConfigDir string
- // cniPluginDirs is a list of directories where cni should look for the plugins.
- cniPluginDirs []string
-
- cniConf *libcni.CNIConfig
-
- // defaultNetwork is the name for the default network.
- defaultNetwork string
- // defaultSubnet is the default subnet for the default network.
- defaultSubnet types.IPNet
-
- // isMachine describes whenever podman runs in a podman machine environment.
- isMachine bool
-
- // lock is a internal lock for critical operations
- lock lockfile.Locker
-
- // modTime is the timestamp when the config dir was modified
- modTime time.Time
-
- // networks is a map with loaded networks, the key is the network name
- networks map[string]*network
-}
-
-type network struct {
- // filename is the full path to the cni config file on disk
- filename string
- libpodNet *types.Network
- cniNet *libcni.NetworkConfigList
-}
-
-type InitConfig struct {
- // CNIConfigDir is directory where the cni config files are stored.
- CNIConfigDir string
- // CNIPluginDirs is a list of directories where cni should look for the plugins.
- CNIPluginDirs []string
-
- // DefaultNetwork is the name for the default network.
- DefaultNetwork string
- // DefaultSubnet is the default subnet for the default network.
- DefaultSubnet string
-
- // IsMachine describes whenever podman runs in a podman machine environment.
- IsMachine bool
-
- // LockFile is the path to lock file.
- LockFile string
-}
-
-// NewCNINetworkInterface creates the ContainerNetwork interface for the CNI backend.
-// Note: The networks are not loaded from disk until a method is called.
-func NewCNINetworkInterface(conf InitConfig) (types.ContainerNetwork, error) {
- // TODO: consider using a shared memory lock
- lock, err := lockfile.GetLockfile(conf.LockFile)
- if err != nil {
- return nil, err
- }
-
- defaultNetworkName := conf.DefaultNetwork
- if defaultNetworkName == "" {
- defaultNetworkName = types.DefaultNetworkName
- }
-
- defaultSubnet := conf.DefaultSubnet
- if defaultSubnet == "" {
- defaultSubnet = types.DefaultSubnet
- }
- defaultNet, err := types.ParseCIDR(defaultSubnet)
- if err != nil {
- return nil, errors.Wrap(err, "failed to parse default subnet")
- }
-
- cni := libcni.NewCNIConfig(conf.CNIPluginDirs, &cniExec{})
- n := &cniNetwork{
- cniConfigDir: conf.CNIConfigDir,
- cniPluginDirs: conf.CNIPluginDirs,
- cniConf: cni,
- defaultNetwork: defaultNetworkName,
- defaultSubnet: defaultNet,
- isMachine: conf.IsMachine,
- lock: lock,
- }
-
- return n, nil
-}
-
-// Drivers will return the list of supported network drivers
-// for this interface.
-func (n *cniNetwork) Drivers() []string {
- return []string{types.BridgeNetworkDriver, types.MacVLANNetworkDriver, types.IPVLANNetworkDriver}
-}
-
-func (n *cniNetwork) loadNetworks() error {
- // check the mod time of the config dir
- f, err := os.Stat(n.cniConfigDir)
- if err != nil {
- return err
- }
- modTime := f.ModTime()
-
- // skip loading networks if they are already loaded and
- // if the config dir was not modified since the last call
- if n.networks != nil && modTime.Equal(n.modTime) {
- return nil
- }
- // make sure the remove all networks before we reload them
- n.networks = nil
- n.modTime = modTime
-
- // FIXME: do we have to support other file types as well, e.g. .conf?
- files, err := libcni.ConfFiles(n.cniConfigDir, []string{".conflist"})
- if err != nil {
- return err
- }
- networks := make(map[string]*network, len(files))
- for _, file := range files {
- conf, err := libcni.ConfListFromFile(file)
- if err != nil {
- // do not log ENOENT errors
- if !errors.Is(err, os.ErrNotExist) {
- logrus.Warnf("Error loading CNI config file %s: %v", file, err)
- }
- continue
- }
-
- if !define.NameRegex.MatchString(conf.Name) {
- logrus.Warnf("CNI config list %s has invalid name, skipping: %v", file, define.RegexError)
- continue
- }
-
- // podman < v4.0 used the podman-machine cni plugin for podman machine port forwarding
- // since this is now build into podman we no longer use the plugin
- // old configs may still contain it so we just remove it here
- if n.isMachine {
- conf = removeMachinePlugin(conf)
- }
-
- if _, err := n.cniConf.ValidateNetworkList(context.Background(), conf); err != nil {
- logrus.Warnf("Error validating CNI config file %s: %v", file, err)
- continue
- }
-
- if val, ok := networks[conf.Name]; ok {
- logrus.Warnf("CNI config list %s has the same network name as %s, skipping", file, val.filename)
- continue
- }
-
- net, err := createNetworkFromCNIConfigList(conf, file)
- if err != nil {
- logrus.Errorf("CNI config list %s could not be converted to a libpod config, skipping: %v", file, err)
- continue
- }
- logrus.Debugf("Successfully loaded network %s: %v", net.Name, net)
- networkInfo := network{
- filename: file,
- cniNet: conf,
- libpodNet: net,
- }
- networks[net.Name] = &networkInfo
- }
-
- // create the default network in memory if it did not exists on disk
- if networks[n.defaultNetwork] == nil {
- networkInfo, err := n.createDefaultNetwork()
- if err != nil {
- return errors.Wrapf(err, "failed to create default network %s", n.defaultNetwork)
- }
- networks[n.defaultNetwork] = networkInfo
- }
-
- logrus.Debugf("Successfully loaded %d networks", len(networks))
- n.networks = networks
- return nil
-}
-
-func (n *cniNetwork) createDefaultNetwork() (*network, error) {
- net := types.Network{
- Name: n.defaultNetwork,
- NetworkInterface: "cni-podman0",
- Driver: types.BridgeNetworkDriver,
- Subnets: []types.Subnet{
- {Subnet: n.defaultSubnet},
- },
- }
- return n.networkCreate(net, true)
-}
-
-// getNetwork will lookup a network by name or ID. It returns an
-// error when no network was found or when more than one network
-// with the given (partial) ID exists.
-// getNetwork will read from the networks map, therefore the caller
-// must ensure that n.lock is locked before using it.
-func (n *cniNetwork) getNetwork(nameOrID string) (*network, error) {
- // fast path check the map key, this will only work for names
- if val, ok := n.networks[nameOrID]; ok {
- return val, nil
- }
- // If there was no match we might got a full or partial ID.
- var net *network
- for _, val := range n.networks {
- // This should not happen because we already looked up the map by name but check anyway.
- if val.libpodNet.Name == nameOrID {
- return val, nil
- }
-
- if strings.HasPrefix(val.libpodNet.ID, nameOrID) {
- if net != nil {
- return nil, errors.Errorf("more than one result for network ID %s", nameOrID)
- }
- net = val
- }
- }
- if net != nil {
- return net, nil
- }
- return nil, errors.Wrapf(define.ErrNoSuchNetwork, "unable to find network with name or ID %s", nameOrID)
-}
-
-// getNetworkIDFromName creates a network ID from the name. It is just the
-// sha256 hash so it is not safe but it should be safe enough for our use case.
-func getNetworkIDFromName(name string) string {
- hash := sha256.Sum256([]byte(name))
- return hex.EncodeToString(hash[:])
-}
-
-// Implement the NetUtil interface for easy code sharing with other network interfaces.
-
-// ForEach call the given function for each network
-func (n *cniNetwork) ForEach(run func(types.Network)) {
- for _, val := range n.networks {
- run(*val.libpodNet)
- }
-}
-
-// Len return the number of networks
-func (n *cniNetwork) Len() int {
- return len(n.networks)
-}
-
-// DefaultInterfaceName return the default cni bridge name, must be suffixed with a number.
-func (n *cniNetwork) DefaultInterfaceName() string {
- return cniDeviceName
-}
-
-func (n *cniNetwork) Network(nameOrID string) (*types.Network, error) {
- network, err := n.getNetwork(nameOrID)
- if err != nil {
- return nil, err
- }
- return network.libpodNet, err
-}
diff --git a/libpod/network/cni/run.go b/libpod/network/cni/run.go
deleted file mode 100644
index d0ff49b73..000000000
--- a/libpod/network/cni/run.go
+++ /dev/null
@@ -1,273 +0,0 @@
-// +build linux
-
-package cni
-
-import (
- "context"
- "net"
- "os"
- "strings"
-
- "github.com/containernetworking/cni/libcni"
- cnitypes "github.com/containernetworking/cni/pkg/types"
- types040 "github.com/containernetworking/cni/pkg/types/040"
- "github.com/containernetworking/plugins/pkg/ns"
- "github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network/internal/util"
- "github.com/containers/podman/v3/libpod/network/types"
- "github.com/hashicorp/go-multierror"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
- "github.com/vishvananda/netlink"
-)
-
-// Setup will setup the container network namespace. It returns
-// a map of StatusBlocks, the key is the network name.
-func (n *cniNetwork) Setup(namespacePath string, options types.SetupOptions) (map[string]types.StatusBlock, error) {
- n.lock.Lock()
- defer n.lock.Unlock()
- err := n.loadNetworks()
- if err != nil {
- return nil, err
- }
-
- err = util.ValidateSetupOptions(n, namespacePath, options)
- if err != nil {
- return nil, err
- }
-
- // set the loopback adapter up in the container netns
- err = ns.WithNetNSPath(namespacePath, func(_ ns.NetNS) error {
- link, err := netlink.LinkByName("lo")
- if err == nil {
- err = netlink.LinkSetUp(link)
- }
- return err
- })
- if err != nil {
- return nil, errors.Wrapf(err, "failed to set the loopback adapter up")
- }
-
- var retErr error
- teardownOpts := options
- teardownOpts.Networks = map[string]types.PerNetworkOptions{}
- // make sure to teardown the already connected networks on error
- defer func() {
- if retErr != nil {
- if len(teardownOpts.Networks) > 0 {
- err := n.teardown(namespacePath, types.TeardownOptions(teardownOpts))
- if err != nil {
- logrus.Warn(err)
- }
- }
- }
- }()
-
- ports, err := convertSpecgenPortsToCNIPorts(options.PortMappings)
- if err != nil {
- return nil, err
- }
-
- results := make(map[string]types.StatusBlock, len(options.Networks))
- for name, netOpts := range options.Networks {
- network := n.networks[name]
- rt := getRuntimeConfig(namespacePath, options.ContainerName, options.ContainerID, name, ports, netOpts)
-
- // If we have more than one static ip we need parse the ips via runtime config,
- // make sure to add the ips capability to the first plugin otherwise it doesn't get the ips
- if len(netOpts.StaticIPs) > 0 && !network.cniNet.Plugins[0].Network.Capabilities["ips"] {
- caps := make(map[string]interface{})
- caps["capabilities"] = map[string]bool{"ips": true}
- network.cniNet.Plugins[0], retErr = libcni.InjectConf(network.cniNet.Plugins[0], caps)
- if retErr != nil {
- return nil, retErr
- }
- }
-
- var res cnitypes.Result
- res, retErr = n.cniConf.AddNetworkList(context.Background(), network.cniNet, rt)
- // Add this network to teardown opts since it is now connected.
- // Also add this if an errors was returned since we want to call teardown on this regardless.
- teardownOpts.Networks[name] = netOpts
- if retErr != nil {
- return nil, retErr
- }
-
- logrus.Debugf("cni result for container %s network %s: %v", options.ContainerID, name, res)
- var status types.StatusBlock
- status, retErr = CNIResultToStatus(res)
- if retErr != nil {
- return nil, retErr
- }
- results[name] = status
- }
- return results, nil
-}
-
-// CNIResultToStatus convert the cni result to status block
-// nolint:golint
-func CNIResultToStatus(res cnitypes.Result) (types.StatusBlock, error) {
- result := types.StatusBlock{}
- cniResult, err := types040.GetResult(res)
- if err != nil {
- return result, err
- }
- nameservers := make([]net.IP, 0, len(cniResult.DNS.Nameservers))
- for _, nameserver := range cniResult.DNS.Nameservers {
- ip := net.ParseIP(nameserver)
- if ip == nil {
- return result, errors.Errorf("failed to parse cni nameserver ip %s", nameserver)
- }
- nameservers = append(nameservers, ip)
- }
- result.DNSServerIPs = nameservers
- result.DNSSearchDomains = cniResult.DNS.Search
-
- interfaces := make(map[string]types.NetInterface)
- for _, ip := range cniResult.IPs {
- if ip.Interface == nil {
- // we do no expect ips without an interface
- continue
- }
- if len(cniResult.Interfaces) <= *ip.Interface {
- return result, errors.Errorf("invalid cni result, interface index %d out of range", *ip.Interface)
- }
- cniInt := cniResult.Interfaces[*ip.Interface]
- netInt, ok := interfaces[cniInt.Name]
- if ok {
- netInt.Subnets = append(netInt.Subnets, types.NetAddress{
- IPNet: types.IPNet{IPNet: ip.Address},
- Gateway: ip.Gateway,
- })
- interfaces[cniInt.Name] = netInt
- } else {
- mac, err := net.ParseMAC(cniInt.Mac)
- if err != nil {
- return result, err
- }
- interfaces[cniInt.Name] = types.NetInterface{
- MacAddress: types.HardwareAddr(mac),
- Subnets: []types.NetAddress{{
- IPNet: types.IPNet{IPNet: ip.Address},
- Gateway: ip.Gateway,
- }},
- }
- }
- }
- result.Interfaces = interfaces
- return result, nil
-}
-
-func getRuntimeConfig(netns, conName, conID, networkName string, ports []cniPortMapEntry, opts types.PerNetworkOptions) *libcni.RuntimeConf {
- rt := &libcni.RuntimeConf{
- ContainerID: conID,
- NetNS: netns,
- IfName: opts.InterfaceName,
- Args: [][2]string{
- {"IgnoreUnknown", "1"},
- // Do not set the K8S env vars, see https://github.com/containers/podman/issues/12083.
- // Only K8S_POD_NAME is used by dnsname to get the container name.
- {"K8S_POD_NAME", conName},
- },
- CapabilityArgs: map[string]interface{}{},
- }
-
- // Propagate environment CNI_ARGS
- for _, kvpairs := range strings.Split(os.Getenv("CNI_ARGS"), ";") {
- if keyval := strings.SplitN(kvpairs, "=", 2); len(keyval) == 2 {
- rt.Args = append(rt.Args, [2]string{keyval[0], keyval[1]})
- }
- }
-
- // Add mac address to cni args
- if len(opts.StaticMAC) > 0 {
- rt.Args = append(rt.Args, [2]string{"MAC", opts.StaticMAC.String()})
- }
-
- if len(opts.StaticIPs) == 1 {
- // Add a single IP to the args field. CNI plugins < 1.0.0
- // do not support multiple ips via capability args.
- rt.Args = append(rt.Args, [2]string{"IP", opts.StaticIPs[0].String()})
- } else if len(opts.StaticIPs) > 1 {
- // Set the static ips in the capability args
- // to support more than one static ip per network.
- rt.CapabilityArgs["ips"] = opts.StaticIPs
- }
-
- // Set network aliases for the dnsname plugin.
- if len(opts.Aliases) > 0 {
- rt.CapabilityArgs["aliases"] = map[string][]string{
- networkName: opts.Aliases,
- }
- }
-
- // Set PortMappings in Capabilities
- if len(ports) > 0 {
- rt.CapabilityArgs["portMappings"] = ports
- }
-
- return rt
-}
-
-// Teardown will teardown the container network namespace.
-func (n *cniNetwork) Teardown(namespacePath string, options types.TeardownOptions) error {
- n.lock.Lock()
- defer n.lock.Unlock()
- err := n.loadNetworks()
- if err != nil {
- return err
- }
- return n.teardown(namespacePath, options)
-}
-
-func (n *cniNetwork) teardown(namespacePath string, options types.TeardownOptions) error {
- // Note: An empty namespacePath is allowed because some plugins
- // still need teardown, for example ipam should remove used ip allocations.
-
- ports, err := convertSpecgenPortsToCNIPorts(options.PortMappings)
- if err != nil {
- return err
- }
-
- var multiErr *multierror.Error
- for name, netOpts := range options.Networks {
- rt := getRuntimeConfig(namespacePath, options.ContainerName, options.ContainerID, name, ports, netOpts)
-
- cniConfList, newRt, err := getCachedNetworkConfig(n.cniConf, name, rt)
- if err == nil {
- rt = newRt
- } else {
- logrus.Warnf("Failed to load cached network config: %v, falling back to loading network %s from disk", err, name)
- network := n.networks[name]
- if network == nil {
- multiErr = multierror.Append(multiErr, errors.Wrapf(define.ErrNoSuchNetwork, "network %s", name))
- continue
- }
- cniConfList = network.cniNet
- }
-
- err = n.cniConf.DelNetworkList(context.Background(), cniConfList, rt)
- if err != nil {
- multiErr = multierror.Append(multiErr, err)
- }
- }
- return multiErr.ErrorOrNil()
-}
-
-func getCachedNetworkConfig(cniConf *libcni.CNIConfig, name string, rt *libcni.RuntimeConf) (*libcni.NetworkConfigList, *libcni.RuntimeConf, error) {
- cniConfList := &libcni.NetworkConfigList{
- Name: name,
- }
- confBytes, rt, err := cniConf.GetNetworkListCachedConfig(cniConfList, rt)
- if err != nil {
- return nil, nil, err
- } else if confBytes == nil {
- return nil, nil, errors.Errorf("network %s not found in CNI cache", name)
- }
-
- cniConfList, err = libcni.ConfListFromBytes(confBytes)
- if err != nil {
- return nil, nil, err
- }
- return cniConfList, rt, nil
-}
diff --git a/libpod/network/cni/run_test.go b/libpod/network/cni/run_test.go
deleted file mode 100644
index f6cc2d412..000000000
--- a/libpod/network/cni/run_test.go
+++ /dev/null
@@ -1,1329 +0,0 @@
-// +build linux
-
-package cni_test
-
-// The tests have to be run as root.
-// For each test there will be two network namespaces created,
-// netNSTest and netNSContainer. Each test must be run inside
-// netNSTest to prevent leakage in the host netns, therefore
-// it should use the following structure:
-// It("test name", func() {
-// runTest(func() {
-// // add test logic here
-// })
-// })
-
-import (
- "bytes"
- "io/ioutil"
- "net"
- "os"
- "path/filepath"
- "strconv"
- "sync"
- "time"
-
- "github.com/containernetworking/plugins/pkg/ns"
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
- "github.com/sirupsen/logrus"
- "github.com/vishvananda/netlink"
- "golang.org/x/sys/unix"
-
- "github.com/containers/podman/v3/libpod/network/types"
- "github.com/containers/podman/v3/pkg/netns"
- "github.com/containers/podman/v3/pkg/rootless"
- "github.com/containers/storage/pkg/stringid"
-)
-
-var _ = Describe("run CNI", func() {
- var (
- libpodNet types.ContainerNetwork
- cniConfDir string
- logBuffer bytes.Buffer
- netNSTest ns.NetNS
- netNSContainer ns.NetNS
- )
- const cniVarDir = "/var/lib/cni"
-
- // runTest is a helper function to run a test. It ensures that each test
- // is run in its own netns. It also creates a mountns to mount a tmpfs to /var/lib/cni.
- runTest := func(run func()) {
- netNSTest.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- err := os.MkdirAll(cniVarDir, 0755)
- Expect(err).To(BeNil(), "Failed to create cniVarDir")
- err = unix.Unshare(unix.CLONE_NEWNS)
- Expect(err).To(BeNil(), "Failed to create new mountns")
- err = unix.Mount("tmpfs", cniVarDir, "tmpfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, "")
- Expect(err).To(BeNil(), "Failed to mount tmpfs for cniVarDir")
- defer unix.Unmount(cniVarDir, 0)
-
- // we have to setup the loopback adapter in this netns to use port forwarding
- link, err := netlink.LinkByName("lo")
- Expect(err).To(BeNil(), "Failed to get loopback adapter")
- err = netlink.LinkSetUp(link)
- Expect(err).To(BeNil(), "Failed to set loopback adapter up")
- run()
- return nil
- })
- }
-
- BeforeEach(func() {
- // The tests need root privileges.
- // Technically we could work around that by using user namespaces and
- // the rootless cni code but this is to much work to get it right for a unit test.
- if rootless.IsRootless() {
- Skip("this test needs to be run as root")
- }
-
- var err error
- cniConfDir, err = ioutil.TempDir("", "podman_cni_test")
- if err != nil {
- Fail("Failed to create tmpdir")
- }
- logBuffer = bytes.Buffer{}
- logrus.SetOutput(&logBuffer)
-
- netNSTest, err = netns.NewNS()
- if err != nil {
- Fail("Failed to create netns")
- }
-
- netNSContainer, err = netns.NewNS()
- if err != nil {
- Fail("Failed to create netns")
- }
- })
-
- JustBeforeEach(func() {
- var err error
- libpodNet, err = getNetworkInterface(cniConfDir, false)
- if err != nil {
- Fail("Failed to create NewCNINetworkInterface")
- }
- })
-
- AfterEach(func() {
- os.RemoveAll(cniConfDir)
-
- netns.UnmountNS(netNSTest)
- netNSTest.Close()
-
- netns.UnmountNS(netNSContainer)
- netNSContainer.Close()
- })
-
- Context("network setup test", func() {
-
- It("run with default config", func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- defNet: {InterfaceName: intName},
- },
- },
- }
- res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(BeNil())
- Expect(res).To(HaveLen(1))
- Expect(res).To(HaveKey(defNet))
- Expect(res[defNet].Interfaces).To(HaveKey(intName))
- Expect(res[defNet].Interfaces[intName].Subnets).To(HaveLen(1))
- Expect(res[defNet].Interfaces[intName].Subnets[0].IPNet.IP.String()).To(ContainSubstring("10.88.0."))
- Expect(res[defNet].Interfaces[intName].MacAddress).To(HaveLen(6))
- // default network has no dns
- Expect(res[defNet].DNSServerIPs).To(BeEmpty())
- Expect(res[defNet].DNSSearchDomains).To(BeEmpty())
-
- // reload the interface so the networks are reload from disk
- libpodNet, err := getNetworkInterface(cniConfDir, false)
- Expect(err).To(BeNil())
-
- err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts))
- Expect(err).To(BeNil())
- })
- })
-
- It("run with default config and static ip", func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- intName := "eth0"
- ip := net.ParseIP("10.88.5.5")
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- defNet: {
- InterfaceName: intName,
- StaticIPs: []net.IP{ip},
- },
- },
- },
- }
- res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(BeNil())
- Expect(res).To(HaveLen(1))
- Expect(res).To(HaveKey(defNet))
- Expect(res[defNet].Interfaces).To(HaveKey(intName))
- Expect(res[defNet].Interfaces[intName].Subnets).To(HaveLen(1))
- Expect(res[defNet].Interfaces[intName].Subnets[0].IPNet.IP).To(Equal(ip))
- Expect(res[defNet].Interfaces[intName].MacAddress).To(HaveLen(6))
- // default network has no dns
- Expect(res[defNet].DNSServerIPs).To(BeEmpty())
- Expect(res[defNet].DNSSearchDomains).To(BeEmpty())
-
- err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts))
- Expect(err).To(BeNil())
- })
- })
-
- for _, proto := range []string{"tcp", "udp"} {
- // copy proto to extra var to keep correct references in the goroutines
- protocol := proto
- It("run with exposed ports protocol "+protocol, func() {
- runTest(func() {
- testdata := stringid.GenerateNonCryptoID()
- defNet := types.DefaultNetworkName
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- PortMappings: []types.PortMapping{{
- Protocol: protocol,
- HostIP: "127.0.0.1",
- HostPort: 5000,
- ContainerPort: 5000,
- }},
- Networks: map[string]types.PerNetworkOptions{
- defNet: {InterfaceName: intName},
- },
- },
- }
- res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(BeNil())
- Expect(res).To(HaveLen(1))
- Expect(res).To(HaveKey(defNet))
- Expect(res[defNet].Interfaces).To(HaveKey(intName))
- Expect(res[defNet].Interfaces[intName].Subnets).To(HaveLen(1))
- Expect(res[defNet].Interfaces[intName].Subnets[0].IPNet.IP.String()).To(ContainSubstring("10.88.0."))
- Expect(res[defNet].Interfaces[intName].MacAddress).To(HaveLen(6))
- // default network has no dns
- Expect(res[defNet].DNSServerIPs).To(BeEmpty())
- Expect(res[defNet].DNSSearchDomains).To(BeEmpty())
- var wg sync.WaitGroup
- wg.Add(1)
- // start a listener in the container ns
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- runNetListener(&wg, protocol, "0.0.0.0", 5000, testdata)
- return nil
- })
- Expect(err).To(BeNil())
-
- conn, err := net.Dial(protocol, "127.0.0.1:5000")
- Expect(err).To(BeNil())
- _, err = conn.Write([]byte(testdata))
- Expect(err).To(BeNil())
- conn.Close()
-
- // wait for the listener to finish
- wg.Wait()
-
- err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts))
- Expect(err).To(BeNil())
- })
- })
-
- It("run with range ports protocol "+protocol, func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- PortMappings: []types.PortMapping{{
- Protocol: protocol,
- HostIP: "127.0.0.1",
- HostPort: 5001,
- ContainerPort: 5000,
- Range: 3,
- }},
- Networks: map[string]types.PerNetworkOptions{
- defNet: {InterfaceName: intName},
- },
- },
- }
- res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(BeNil())
- Expect(res).To(HaveLen(1))
- Expect(res).To(HaveKey(defNet))
- Expect(res[defNet].Interfaces).To(HaveKey(intName))
- Expect(res[defNet].Interfaces[intName].Subnets).To(HaveLen(1))
- containerIP := res[defNet].Interfaces[intName].Subnets[0].IPNet.IP.String()
- Expect(containerIP).To(ContainSubstring("10.88.0."))
- Expect(res[defNet].Interfaces[intName].MacAddress).To(HaveLen(6))
- // default network has no dns
- Expect(res[defNet].DNSServerIPs).To(BeEmpty())
- Expect(res[defNet].DNSSearchDomains).To(BeEmpty())
-
- // loop over all ports
- for p := 5001; p < 5004; p++ {
- port := p
- var wg sync.WaitGroup
- wg.Add(1)
- testdata := stringid.GenerateNonCryptoID()
- // start a listener in the container ns
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- runNetListener(&wg, protocol, containerIP, port-1, testdata)
- return nil
- })
- Expect(err).To(BeNil())
-
- conn, err := net.Dial(protocol, net.JoinHostPort("127.0.0.1", strconv.Itoa(port)))
- Expect(err).To(BeNil())
- _, err = conn.Write([]byte(testdata))
- Expect(err).To(BeNil())
- conn.Close()
-
- // wait for the listener to finish
- wg.Wait()
- }
-
- err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts))
- Expect(err).To(BeNil())
- })
- })
- }
-
- It("run with comma separated port protocol", func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- PortMappings: []types.PortMapping{{
- Protocol: "tcp,udp",
- HostIP: "127.0.0.1",
- HostPort: 5000,
- ContainerPort: 5000,
- }},
- Networks: map[string]types.PerNetworkOptions{
- defNet: {InterfaceName: intName},
- },
- },
- }
- res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(BeNil())
- Expect(res).To(HaveLen(1))
- Expect(res).To(HaveKey(defNet))
- Expect(res[defNet].Interfaces).To(HaveKey(intName))
- Expect(res[defNet].Interfaces[intName].Subnets).To(HaveLen(1))
- Expect(res[defNet].Interfaces[intName].Subnets[0].IPNet.IP.String()).To(ContainSubstring("10.88.0."))
- Expect(res[defNet].Interfaces[intName].MacAddress).To(HaveLen(6))
-
- for _, proto := range []string{"tcp", "udp"} {
- // copy proto to extra var to keep correct references in the goroutines
- protocol := proto
-
- testdata := stringid.GenerateNonCryptoID()
- var wg sync.WaitGroup
- wg.Add(1)
- // start tcp listener in the container ns
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- runNetListener(&wg, protocol, "0.0.0.0", 5000, testdata)
- return nil
- })
- Expect(err).To(BeNil())
-
- conn, err := net.Dial(protocol, "127.0.0.1:5000")
- Expect(err).To(BeNil())
- _, err = conn.Write([]byte(testdata))
- Expect(err).To(BeNil())
- conn.Close()
-
- // wait for the listener to finish
- wg.Wait()
- }
-
- err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts))
- Expect(err).To(BeNil())
- })
- })
-
- It("call setup twice", func() {
- runTest(func() {
- network := types.Network{}
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
-
- intName1 := "eth0"
- netName1 := network1.Name
-
- containerID := stringid.GenerateNonCryptoID()
-
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: containerID,
- Networks: map[string]types.PerNetworkOptions{
- netName1: {
- InterfaceName: intName1,
- },
- },
- },
- }
-
- res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(BeNil())
- Expect(res).To(HaveLen(1))
-
- Expect(res).To(HaveKey(netName1))
- Expect(res[netName1].Interfaces).To(HaveKey(intName1))
- Expect(res[netName1].Interfaces[intName1].Subnets).To(HaveLen(1))
- ipInt1 := res[netName1].Interfaces[intName1].Subnets[0].IPNet.IP
- Expect(ipInt1).ToNot(BeEmpty())
- macInt1 := res[netName1].Interfaces[intName1].MacAddress
- Expect(macInt1).To(HaveLen(6))
-
- // check in the container namespace if the settings are applied
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- i, err := net.InterfaceByName(intName1)
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal(intName1))
- Expect(i.HardwareAddr).To(Equal((net.HardwareAddr)(macInt1)))
- addrs, err := i.Addrs()
- Expect(err).To(BeNil())
- subnet := &net.IPNet{
- IP: ipInt1,
- Mask: net.CIDRMask(24, 32),
- }
- Expect(addrs).To(ContainElements(subnet))
-
- // check loopback adapter
- i, err = net.InterfaceByName("lo")
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal("lo"))
- Expect(i.Flags & net.FlagLoopback).To(Equal(net.FlagLoopback))
- Expect(i.Flags&net.FlagUp).To(Equal(net.FlagUp), "Loopback adapter should be up")
- return nil
- })
- Expect(err).To(BeNil())
-
- network = types.Network{}
- network2, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
-
- intName2 := "eth1"
- netName2 := network2.Name
-
- setupOpts.Networks = map[string]types.PerNetworkOptions{
- netName2: {
- InterfaceName: intName2,
- },
- }
-
- res, err = libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(BeNil())
- Expect(res).To(HaveLen(1))
-
- Expect(res).To(HaveKey(netName2))
- Expect(res[netName2].Interfaces).To(HaveKey(intName2))
- Expect(res[netName2].Interfaces[intName2].Subnets).To(HaveLen(1))
- ipInt2 := res[netName2].Interfaces[intName2].Subnets[0].IPNet.IP
- Expect(ipInt2).ToNot(BeEmpty())
- macInt2 := res[netName2].Interfaces[intName2].MacAddress
- Expect(macInt2).To(HaveLen(6))
-
- // check in the container namespace if the settings are applied
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- i, err := net.InterfaceByName(intName1)
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal(intName1))
- Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt1)))
- addrs, err := i.Addrs()
- Expect(err).To(BeNil())
- subnet := &net.IPNet{
- IP: ipInt1,
- Mask: net.CIDRMask(24, 32),
- }
- Expect(addrs).To(ContainElements(subnet))
-
- i, err = net.InterfaceByName(intName2)
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal(intName2))
- Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt2)))
- addrs, err = i.Addrs()
- Expect(err).To(BeNil())
- subnet = &net.IPNet{
- IP: ipInt2,
- Mask: net.CIDRMask(24, 32),
- }
- Expect(addrs).To(ContainElements(subnet))
-
- // check loopback adapter
- i, err = net.InterfaceByName("lo")
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal("lo"))
- Expect(i.Flags & net.FlagLoopback).To(Equal(net.FlagLoopback))
- Expect(i.Flags&net.FlagUp).To(Equal(net.FlagUp), "Loopback adapter should be up")
- return nil
- })
- Expect(err).To(BeNil())
-
- teatdownOpts := types.TeardownOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: containerID,
- Networks: map[string]types.PerNetworkOptions{
- netName1: {
- InterfaceName: intName1,
- },
- netName2: {
- InterfaceName: intName2,
- },
- },
- },
- }
-
- err = libpodNet.Teardown(netNSContainer.Path(), teatdownOpts)
- Expect(err).To(BeNil())
- logString := logBuffer.String()
- Expect(logString).To(BeEmpty())
-
- // check in the container namespace that the interface is removed
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- _, err := net.InterfaceByName(intName1)
- Expect(err).To(HaveOccurred())
- _, err = net.InterfaceByName(intName2)
- Expect(err).To(HaveOccurred())
-
- // check that only the loopback adapter is left
- ints, err := net.Interfaces()
- Expect(err).To(BeNil())
- Expect(ints).To(HaveLen(1))
- Expect(ints[0].Name).To(Equal("lo"))
- Expect(ints[0].Flags & net.FlagLoopback).To(Equal(net.FlagLoopback))
- Expect(ints[0].Flags&net.FlagUp).To(Equal(net.FlagUp), "Loopback adapter should be up")
-
- return nil
- })
- Expect(err).To(BeNil())
-
- err = libpodNet.NetworkRemove(netName1)
- Expect(err).To(BeNil())
- err = libpodNet.NetworkRemove(netName2)
- Expect(err).To(BeNil())
-
- // check that the interfaces are removed in the host ns
- _, err = net.InterfaceByName(network1.NetworkInterface)
- Expect(err).To(HaveOccurred())
- _, err = net.InterfaceByName(network2.NetworkInterface)
- Expect(err).To(HaveOccurred())
- })
- })
-
- It("setup two networks with one setup call", func() {
- runTest(func() {
- subnet1, _ := types.ParseCIDR("192.168.0.0/24")
- subnet2, _ := types.ParseCIDR("192.168.1.0/24")
- network := types.Network{
- Subnets: []types.Subnet{
- {Subnet: subnet1},
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
-
- network = types.Network{
- Subnets: []types.Subnet{
- {Subnet: subnet2},
- },
- }
- network2, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
-
- intName1 := "eth0"
- intName2 := "eth1"
- netName1 := network1.Name
- netName2 := network2.Name
-
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- netName1: {
- InterfaceName: intName1,
- },
- netName2: {
- InterfaceName: intName2,
- },
- },
- },
- }
-
- res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(BeNil())
- Expect(res).To(HaveLen(2))
-
- Expect(res).To(HaveKey(netName1))
- Expect(res[netName1].Interfaces).To(HaveKey(intName1))
- Expect(res[netName1].Interfaces[intName1].Subnets).To(HaveLen(1))
- ipInt1 := res[netName1].Interfaces[intName1].Subnets[0].IPNet.IP
- Expect(ipInt1.String()).To(ContainSubstring("192.168.0."))
- macInt1 := res[netName1].Interfaces[intName1].MacAddress
- Expect(macInt1).To(HaveLen(6))
-
- Expect(res).To(HaveKey(netName2))
- Expect(res[netName2].Interfaces).To(HaveKey(intName2))
- Expect(res[netName2].Interfaces[intName2].Subnets).To(HaveLen(1))
- ipInt2 := res[netName2].Interfaces[intName2].Subnets[0].IPNet.IP
- Expect(ipInt2.String()).To(ContainSubstring("192.168.1."))
- macInt2 := res[netName2].Interfaces[intName2].MacAddress
- Expect(macInt2).To(HaveLen(6))
-
- // default network has no dns
- Expect(res[netName1].DNSServerIPs).To(BeEmpty())
- Expect(res[netName1].DNSSearchDomains).To(BeEmpty())
-
- // check in the container namespace if the settings are applied
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- i, err := net.InterfaceByName(intName1)
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal(intName1))
- Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt1)))
- addrs, err := i.Addrs()
- Expect(err).To(BeNil())
- subnet := &net.IPNet{
- IP: ipInt1,
- Mask: net.CIDRMask(24, 32),
- }
- Expect(addrs).To(ContainElements(subnet))
-
- i, err = net.InterfaceByName(intName2)
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal(intName2))
- Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt2)))
- addrs, err = i.Addrs()
- Expect(err).To(BeNil())
- subnet = &net.IPNet{
- IP: ipInt2,
- Mask: net.CIDRMask(24, 32),
- }
- Expect(addrs).To(ContainElements(subnet))
-
- // check loopback adapter
- i, err = net.InterfaceByName("lo")
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal("lo"))
- Expect(i.Flags & net.FlagLoopback).To(Equal(net.FlagLoopback))
- Expect(i.Flags&net.FlagUp).To(Equal(net.FlagUp), "Loopback adapter should be up")
- return nil
- })
- Expect(err).To(BeNil())
-
- err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts))
- Expect(err).To(BeNil())
- logString := logBuffer.String()
- Expect(logString).To(BeEmpty())
-
- // check in the container namespace that the interface is removed
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- _, err := net.InterfaceByName(intName1)
- Expect(err).To(HaveOccurred())
- _, err = net.InterfaceByName(intName2)
- Expect(err).To(HaveOccurred())
-
- // check that only the loopback adapter is left
- ints, err := net.Interfaces()
- Expect(err).To(BeNil())
- Expect(ints).To(HaveLen(1))
- Expect(ints[0].Name).To(Equal("lo"))
- Expect(ints[0].Flags & net.FlagLoopback).To(Equal(net.FlagLoopback))
- Expect(ints[0].Flags&net.FlagUp).To(Equal(net.FlagUp), "Loopback adapter should be up")
-
- return nil
- })
- Expect(err).To(BeNil())
- })
-
- })
-
- It("dual stack network with static ips", func() {
- // Version checks for cni plugins are not possible, the plugins do not output
- // version information and using the package manager does not work across distros.
- // Fedora has the right version so we use this for now.
- SkipIfNotFedora("requires cni plugins 1.0.0 or newer for multiple static ips")
- runTest(func() {
- subnet1, _ := types.ParseCIDR("192.168.0.0/24")
- subnet2, _ := types.ParseCIDR("fd41:0a75:2ca0:48a9::/64")
- network := types.Network{
- Subnets: []types.Subnet{
- {Subnet: subnet1}, {Subnet: subnet2},
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
-
- mac, _ := net.ParseMAC("40:15:2f:d8:42:36")
- interfaceName := "eth0"
-
- ip1 := net.ParseIP("192.168.0.5")
- ip2 := net.ParseIP("fd41:0a75:2ca0:48a9::5")
-
- netName := network1.Name
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerName: "mycon",
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- netName: {
- InterfaceName: interfaceName,
- StaticIPs: []net.IP{ip1, ip2},
- StaticMAC: types.HardwareAddr(mac),
- },
- },
- },
- }
-
- res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(BeNil())
- Expect(res).To(HaveLen(1))
- Expect(res).To(HaveKey(netName))
- Expect(res[netName].Interfaces).To(HaveKey(interfaceName))
- Expect(res[netName].Interfaces[interfaceName].Subnets).To(HaveLen(2))
- Expect(res[netName].Interfaces[interfaceName].Subnets[0].IPNet.IP.String()).To(Equal(ip1.String()))
- Expect(res[netName].Interfaces[interfaceName].Subnets[0].IPNet.Mask).To(Equal(subnet1.Mask))
- Expect(res[netName].Interfaces[interfaceName].Subnets[0].Gateway).To(Equal(net.ParseIP("192.168.0.1")))
- Expect(res[netName].Interfaces[interfaceName].Subnets[1].IPNet.IP.String()).To(Equal(ip2.String()))
- Expect(res[netName].Interfaces[interfaceName].Subnets[1].IPNet.Mask).To(Equal(subnet2.Mask))
- Expect(res[netName].Interfaces[interfaceName].Subnets[1].Gateway).To(Equal(net.ParseIP("fd41:0a75:2ca0:48a9::1")))
- Expect(res[netName].Interfaces[interfaceName].MacAddress).To(Equal(types.HardwareAddr(mac)))
- // default network has no dns
- Expect(res[netName].DNSServerIPs).To(BeEmpty())
- Expect(res[netName].DNSSearchDomains).To(BeEmpty())
-
- // check in the container namespace if the settings are applied
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- i, err := net.InterfaceByName(interfaceName)
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal(interfaceName))
- Expect(i.HardwareAddr).To(Equal(mac))
- addrs, err := i.Addrs()
- Expect(err).To(BeNil())
- subnet1 := &net.IPNet{
- IP: ip1,
- Mask: net.CIDRMask(24, 32),
- }
- subnet2 := &net.IPNet{
- IP: ip2,
- Mask: net.CIDRMask(64, 128),
- }
- Expect(addrs).To(ContainElements(subnet1, subnet2))
-
- // check loopback adapter
- i, err = net.InterfaceByName("lo")
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal("lo"))
- Expect(i.Flags & net.FlagLoopback).To(Equal(net.FlagLoopback))
- Expect(i.Flags&net.FlagUp).To(Equal(net.FlagUp), "Loopback adapter should be up")
- return nil
- })
- Expect(err).To(BeNil())
-
- err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts))
- Expect(err).To(BeNil())
- logString := logBuffer.String()
- Expect(logString).To(BeEmpty())
-
- // check in the container namespace that the interface is removed
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- _, err := net.InterfaceByName(interfaceName)
- Expect(err).To(HaveOccurred())
-
- // check that only the loopback adapter is left
- ints, err := net.Interfaces()
- Expect(err).To(BeNil())
- Expect(ints).To(HaveLen(1))
- Expect(ints[0].Name).To(Equal("lo"))
- Expect(ints[0].Flags & net.FlagLoopback).To(Equal(net.FlagLoopback))
- Expect(ints[0].Flags&net.FlagUp).To(Equal(net.FlagUp), "Loopback adapter should be up")
-
- return nil
- })
- Expect(err).To(BeNil())
- })
- })
-
- It("CNI_ARGS from environment variable", func() {
- runTest(func() {
- subnet1, _ := types.ParseCIDR("172.16.1.0/24")
- ip := "172.16.1.5"
- network := types.Network{
- Subnets: []types.Subnet{
- {Subnet: subnet1},
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- netName := network1.Name
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- netName: {
- InterfaceName: intName,
- },
- },
- },
- }
-
- os.Setenv("CNI_ARGS", "IP="+ip)
- defer os.Unsetenv("CNI_ARGS")
-
- res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(BeNil())
- Expect(res).To(HaveLen(1))
- Expect(res).To(HaveKey(netName))
- Expect(res[netName].Interfaces).To(HaveKey(intName))
- Expect(res[netName].Interfaces[intName].Subnets).To(HaveLen(1))
- Expect(res[netName].Interfaces[intName].Subnets[0].IPNet.IP.String()).To(Equal(ip))
- Expect(res[netName].Interfaces[intName].Subnets[0].IPNet.Mask).To(Equal(net.CIDRMask(24, 32)))
-
- // check in the container namespace if the settings are applied
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- i, err := net.InterfaceByName(intName)
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal(intName))
- addrs, err := i.Addrs()
- Expect(err).To(BeNil())
- subnet := &net.IPNet{
- IP: net.ParseIP(ip),
- Mask: net.CIDRMask(24, 32),
- }
- Expect(addrs).To(ContainElements(subnet))
-
- // check loopback adapter
- i, err = net.InterfaceByName("lo")
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal("lo"))
- Expect(i.Flags & net.FlagLoopback).To(Equal(net.FlagLoopback))
- Expect(i.Flags&net.FlagUp).To(Equal(net.FlagUp), "Loopback adapter should be up")
- return nil
- })
- Expect(err).To(BeNil())
- })
- })
- })
-
- Context("network setup test with networks from disk", func() {
-
- BeforeEach(func() {
- dir := "testfiles/valid"
- files, err := ioutil.ReadDir(dir)
- if err != nil {
- Fail("Failed to read test directory")
- }
- for _, file := range files {
- filename := file.Name()
- data, err := ioutil.ReadFile(filepath.Join(dir, filename))
- if err != nil {
- Fail("Failed to copy test files")
- }
- err = ioutil.WriteFile(filepath.Join(cniConfDir, filename), data, 0700)
- if err != nil {
- Fail("Failed to copy test files")
- }
- }
- })
-
- It("dualstack setup with static ip and dns", func() {
- SkipIfNoDnsname()
- // Version checks for cni plugins are not possible, the plugins do not output
- // version information and using the package manager does not work across distros.
- // Fedora has the right version so we use this for now.
- SkipIfNotFedora("requires cni plugins 1.0.0 or newer for multiple static ips")
- runTest(func() {
- interfaceName := "eth0"
-
- ip1 := net.ParseIP("fd10:88:a::11")
- ip2 := net.ParseIP("10.89.19.15")
-
- containerName := "myname"
- aliases := []string{"aliasname"}
-
- netName := "dualstack"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- ContainerName: containerName,
- Networks: map[string]types.PerNetworkOptions{
- netName: {
- InterfaceName: interfaceName,
- StaticIPs: []net.IP{ip1, ip2},
- Aliases: aliases,
- },
- },
- },
- }
-
- network, err := libpodNet.NetworkInspect(netName)
- Expect(err).To(BeNil())
- Expect(network.Name).To(Equal(netName))
- Expect(network.DNSEnabled).To(BeTrue())
- Expect(network.Subnets).To(HaveLen(2))
- gw1 := network.Subnets[0].Gateway
- Expect(gw1).To(HaveLen(16))
- mask1 := network.Subnets[0].Subnet.Mask
- Expect(mask1).To(HaveLen(16))
- gw2 := network.Subnets[1].Gateway
- Expect(gw2).To(HaveLen(4))
- mask2 := network.Subnets[1].Subnet.Mask
- Expect(mask2).To(HaveLen(4))
-
- // because this net has dns we should always teardown otherwise we leak a dnsmasq process
- defer libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts))
- res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(BeNil())
- Expect(res).To(HaveLen(1))
- Expect(res).To(HaveKey(netName))
- Expect(res[netName].Interfaces).To(HaveKey(interfaceName))
- Expect(res[netName].Interfaces[interfaceName].Subnets).To(HaveLen(2))
- Expect(res[netName].Interfaces[interfaceName].Subnets[0].IPNet.IP.String()).To(Equal(ip1.String()))
- Expect(res[netName].Interfaces[interfaceName].Subnets[0].IPNet.Mask).To(Equal(mask1))
- Expect(res[netName].Interfaces[interfaceName].Subnets[1].IPNet.IP.String()).To(Equal(ip2.String()))
- Expect(res[netName].Interfaces[interfaceName].Subnets[1].IPNet.Mask).To(Equal(mask2))
- // dualstack network dns
- Expect(res[netName].DNSServerIPs).To(HaveLen(2))
- Expect(res[netName].DNSSearchDomains).To(HaveLen(1))
- Expect(res[netName].DNSSearchDomains).To(ConsistOf("dns.podman"))
-
- // check in the container namespace if the settings are applied
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- i, err := net.InterfaceByName(interfaceName)
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal(interfaceName))
- addrs, err := i.Addrs()
- Expect(err).To(BeNil())
- subnet1 := &net.IPNet{
- IP: ip1,
- Mask: net.CIDRMask(64, 128),
- }
- subnet2 := &net.IPNet{
- IP: ip2,
- Mask: net.CIDRMask(24, 32),
- }
- Expect(addrs).To(ContainElements(subnet1, subnet2))
-
- // check loopback adapter
- i, err = net.InterfaceByName("lo")
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal("lo"))
- Expect(i.Flags & net.FlagLoopback).To(Equal(net.FlagLoopback))
- Expect(i.Flags&net.FlagUp).To(Equal(net.FlagUp), "Loopback adapter should be up")
-
- return nil
- })
- Expect(err).To(BeNil())
-
- err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts))
- Expect(err).To(BeNil())
- logString := logBuffer.String()
- Expect(logString).To(BeEmpty())
-
- // check in the container namespace that the interface is removed
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- _, err := net.InterfaceByName(interfaceName)
- Expect(err).To(HaveOccurred())
-
- // check that only the loopback adapter is left
- ints, err := net.Interfaces()
- Expect(err).To(BeNil())
- Expect(ints).To(HaveLen(1))
- Expect(ints[0].Name).To(Equal("lo"))
- Expect(ints[0].Flags & net.FlagLoopback).To(Equal(net.FlagLoopback))
- Expect(ints[0].Flags&net.FlagUp).To(Equal(net.FlagUp), "Loopback adapter should be up")
-
- return nil
- })
- Expect(err).To(BeNil())
- })
- })
-
- It("setup with aliases but dns disabled should work", func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- defNet: {
- InterfaceName: intName,
- Aliases: []string{"somealias"},
- },
- },
- },
- }
- _, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).ToNot(HaveOccurred())
- })
- })
-
- })
-
- Context("invalid network setup test", func() {
-
- It("static ip not in subnet", func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- intName := "eth0"
- ip := "1.1.1.1"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- defNet: {
- InterfaceName: intName,
- StaticIPs: []net.IP{net.ParseIP(ip)},
- },
- },
- },
- }
- _, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("requested static ip %s not in any subnet on network %s", ip, defNet))
- })
- })
-
- It("setup without namespace path", func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- defNet: {
- InterfaceName: intName,
- },
- },
- },
- }
- _, err := libpodNet.Setup("", setupOpts)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("namespacePath is empty"))
- })
- })
-
- It("setup with invalid namespace path", func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- defNet: {
- InterfaceName: intName,
- },
- },
- },
- }
- _, err := libpodNet.Setup("some path", setupOpts)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring(`"some path": no such file or directory`))
- })
- })
-
- It("setup without container ID", func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: "",
- Networks: map[string]types.PerNetworkOptions{
- defNet: {
- InterfaceName: intName,
- },
- },
- },
- }
- _, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("ContainerID is empty"))
- })
- })
-
- It("setup without networks", func() {
- runTest(func() {
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- },
- }
- _, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("must specify at least one network"))
- })
- })
-
- It("setup without interface name", func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- defNet: {
- InterfaceName: "",
- },
- },
- },
- }
- _, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("interface name on network %s is empty", defNet))
- })
- })
-
- It("setup does teardown on failure", func() {
- runTest(func() {
- subnet1, _ := types.ParseCIDR("192.168.0.0/24")
- network := types.Network{
- Subnets: []types.Subnet{
- {Subnet: subnet1},
- },
- }
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
-
- subnet2, _ := types.ParseCIDR("192.168.1.0/31")
- network = types.Network{
- Subnets: []types.Subnet{
- {Subnet: subnet2},
- },
- }
- network2, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
-
- intName1 := "eth0"
- intName2 := "eth1"
- netName1 := network1.Name
- netName2 := network2.Name
-
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- netName1: {
- InterfaceName: intName1,
- },
- netName2: {
- InterfaceName: intName2,
- },
- },
- },
- }
- _, err = libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("Network 192.168.1.0/31 too small to allocate from"))
- // Note: we call teardown on the failing net and log the error, it should be the same.
- logString := logBuffer.String()
- Expect(logString).To(ContainSubstring("Network 192.168.1.0/31 too small to allocate from"))
-
- // check in the container namespace that no interface is there
- err = netNSContainer.Do(func(_ ns.NetNS) error {
- defer GinkgoRecover()
- _, err := net.InterfaceByName(intName1)
- Expect(err).To(HaveOccurred())
-
- // Note: We can check if intName2 is removed because
- // the cni plugin fails before it removes the interface
-
- // check loopback adapter
- i, err := net.InterfaceByName("lo")
- Expect(err).To(BeNil())
- Expect(i.Name).To(Equal("lo"))
- Expect(i.Flags & net.FlagLoopback).To(Equal(net.FlagLoopback))
- Expect(i.Flags&net.FlagUp).To(Equal(net.FlagUp), "Loopback adapter should be up")
- return nil
- })
- Expect(err).To(BeNil())
- })
- })
-
- It("setup with exposed invalid port protocol", func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- PortMappings: []types.PortMapping{{
- Protocol: "someproto",
- HostIP: "127.0.0.1",
- HostPort: 5000,
- ContainerPort: 5000,
- }},
- Networks: map[string]types.PerNetworkOptions{
- defNet: {InterfaceName: intName},
- },
- },
- }
- _, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("unknown port protocol someproto"))
- })
- })
-
- It("setup with exposed empty port protocol", func() {
- runTest(func() {
- defNet := types.DefaultNetworkName
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- PortMappings: []types.PortMapping{{
- Protocol: "",
- HostIP: "127.0.0.1",
- HostPort: 5000,
- ContainerPort: 5000,
- }},
- Networks: map[string]types.PerNetworkOptions{
- defNet: {InterfaceName: intName},
- },
- },
- }
- _, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("port protocol should not be empty"))
- })
- })
-
- It("setup with unknown network", func() {
- runTest(func() {
- defNet := "somenet"
- intName := "eth0"
- setupOpts := types.SetupOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- defNet: {InterfaceName: intName},
- },
- },
- }
- _, err := libpodNet.Setup(netNSContainer.Path(), setupOpts)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("unable to find network with name or ID somenet: network not found"))
- })
- })
-
- It("teardown with unknown network", func() {
- runTest(func() {
- interfaceName := "eth0"
- netName := "somenet"
- teardownOpts := types.TeardownOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- netName: {
- InterfaceName: interfaceName,
- },
- },
- },
- }
-
- err := libpodNet.Teardown(netNSContainer.Path(), teardownOpts)
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("network somenet: network not found"))
- logString := logBuffer.String()
- Expect(logString).To(ContainSubstring("Failed to load cached network config"))
- })
- })
-
- It("teardown on not connected network", func() {
- runTest(func() {
- network := types.Network{}
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
-
- interfaceName := "eth0"
- netName := network1.Name
- teardownOpts := types.TeardownOptions{
- NetworkOptions: types.NetworkOptions{
- ContainerID: stringid.GenerateNonCryptoID(),
- Networks: map[string]types.PerNetworkOptions{
- netName: {
- InterfaceName: interfaceName,
- },
- },
- },
- }
-
- // Most CNI plugins do not error on teardown when there is nothing to do.
- err = libpodNet.Teardown(netNSContainer.Path(), teardownOpts)
- Expect(err).To(BeNil())
- logString := logBuffer.String()
- Expect(logString).To(ContainSubstring("Failed to load cached network config"))
- })
- })
- })
-})
-
-func runNetListener(wg *sync.WaitGroup, protocol, ip string, port int, expectedData string) {
- switch protocol {
- case "tcp":
- ln, err := net.Listen(protocol, net.JoinHostPort(ip, strconv.Itoa(port)))
- Expect(err).To(BeNil())
- // make sure to read in a separate goroutine to not block
- go func() {
- defer GinkgoRecover()
- defer wg.Done()
- conn, err := ln.Accept()
- Expect(err).To(BeNil())
- conn.SetDeadline(time.Now().Add(1 * time.Second))
- data, err := ioutil.ReadAll(conn)
- Expect(err).To(BeNil())
- Expect(string(data)).To(Equal(expectedData))
- conn.Close()
- ln.Close()
- }()
- case "udp":
- conn, err := net.ListenUDP("udp", &net.UDPAddr{
- IP: net.ParseIP(ip),
- Port: port,
- })
- Expect(err).To(BeNil())
- conn.SetDeadline(time.Now().Add(1 * time.Second))
- go func() {
- defer GinkgoRecover()
- defer wg.Done()
- data := make([]byte, len(expectedData))
- i, err := conn.Read(data)
- Expect(err).To(BeNil())
- Expect(i).To(Equal(len(expectedData)))
- Expect(string(data)).To(Equal(expectedData))
- conn.Close()
- }()
- default:
- Fail("unsupported protocol")
- }
-}
diff --git a/libpod/network/cni/testfiles/invalid/broken.conflist b/libpod/network/cni/testfiles/invalid/broken.conflist
deleted file mode 100644
index e5bf48b39..000000000
--- a/libpod/network/cni/testfiles/invalid/broken.conflist
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "bridge",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman9",
- "isGateway": true,
- "ipMasq": true,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "10.89.8.0/24",
- "gateway": "10.89.8.1"
- }
- ]
- ]
diff --git a/libpod/network/cni/testfiles/invalid/invalid_gateway.conflist b/libpod/network/cni/testfiles/invalid/invalid_gateway.conflist
deleted file mode 100644
index f03c1fde4..000000000
--- a/libpod/network/cni/testfiles/invalid/invalid_gateway.conflist
+++ /dev/null
@@ -1,51 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "invalidgw",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman8",
- "isGateway": true,
- "ipMasq": true,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "10.89.8.0/24",
- "gateway": "10.89.8",
- "rangeStart": "10.89.8.20",
- "rangeEnd": "10.89.8.50"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall",
- "backend": ""
- },
- {
- "type": "tuning"
- },
- {
- "type": "dnsname",
- "domainName": "dns.podman",
- "capabilities": {
- "aliases": true
- }
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/invalid/invalidname.conflist b/libpod/network/cni/testfiles/invalid/invalidname.conflist
deleted file mode 100644
index e35be69db..000000000
--- a/libpod/network/cni/testfiles/invalid/invalidname.conflist
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "bridge@123",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman9",
- "isGateway": true,
- "ipMasq": true,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "10.89.8.0/24",
- "gateway": "10.89.8.1"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall",
- "backend": ""
- },
- {
- "type": "tuning"
- },
- {
- "type": "dnsname",
- "domainName": "dns.podman",
- "capabilities": {
- "aliases": true
- }
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/invalid/noname.conflist b/libpod/network/cni/testfiles/invalid/noname.conflist
deleted file mode 100644
index 865abadf8..000000000
--- a/libpod/network/cni/testfiles/invalid/noname.conflist
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman9",
- "isGateway": true,
- "ipMasq": true,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "10.89.8.0/24",
- "gateway": "10.89.8.1"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall",
- "backend": ""
- },
- {
- "type": "tuning"
- },
- {
- "type": "dnsname",
- "domainName": "dns.podman",
- "capabilities": {
- "aliases": true
- }
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/invalid/noplugin.conflist b/libpod/network/cni/testfiles/invalid/noplugin.conflist
deleted file mode 100644
index af192adca..000000000
--- a/libpod/network/cni/testfiles/invalid/noplugin.conflist
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "bridge",
- "plugins": []
-}
diff --git a/libpod/network/cni/testfiles/invalid/samename1.conflist b/libpod/network/cni/testfiles/invalid/samename1.conflist
deleted file mode 100644
index 57b325264..000000000
--- a/libpod/network/cni/testfiles/invalid/samename1.conflist
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "bridge",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman9",
- "isGateway": true,
- "ipMasq": true,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "10.89.8.0/24",
- "gateway": "10.89.8.1"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall",
- "backend": ""
- },
- {
- "type": "tuning"
- },
- {
- "type": "dnsname",
- "domainName": "dns.podman",
- "capabilities": {
- "aliases": true
- }
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/invalid/samename2.conflist b/libpod/network/cni/testfiles/invalid/samename2.conflist
deleted file mode 100644
index 57b325264..000000000
--- a/libpod/network/cni/testfiles/invalid/samename2.conflist
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "bridge",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman9",
- "isGateway": true,
- "ipMasq": true,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "10.89.8.0/24",
- "gateway": "10.89.8.1"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall",
- "backend": ""
- },
- {
- "type": "tuning"
- },
- {
- "type": "dnsname",
- "domainName": "dns.podman",
- "capabilities": {
- "aliases": true
- }
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/valid/87-podman.conflist b/libpod/network/cni/testfiles/valid/87-podman.conflist
deleted file mode 100644
index ef760a61b..000000000
--- a/libpod/network/cni/testfiles/valid/87-podman.conflist
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "podman",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman0",
- "isGateway": true,
- "ipMasq": true,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [{ "dst": "0.0.0.0/0" }],
- "ranges": [
- [
- {
- "subnet": "10.88.0.0/16",
- "gateway": "10.88.0.1"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall"
- },
- {
- "type": "tuning"
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/valid/bridge.conflist b/libpod/network/cni/testfiles/valid/bridge.conflist
deleted file mode 100644
index 8952b50b7..000000000
--- a/libpod/network/cni/testfiles/valid/bridge.conflist
+++ /dev/null
@@ -1,51 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "bridge",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman9",
- "isGateway": true,
- "ipMasq": true,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "10.89.8.0/24",
- "gateway": "10.89.8.1",
- "rangeStart": "10.89.8.20",
- "rangeEnd": "10.89.8.50"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall",
- "backend": ""
- },
- {
- "type": "tuning"
- },
- {
- "type": "dnsname",
- "domainName": "dns.podman",
- "capabilities": {
- "aliases": true
- }
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/valid/dualstack.conflist b/libpod/network/cni/testfiles/valid/dualstack.conflist
deleted file mode 100644
index dd08382f0..000000000
--- a/libpod/network/cni/testfiles/valid/dualstack.conflist
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "dualstack",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman21",
- "isGateway": true,
- "ipMasq": true,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "::/0"
- },
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "fd10:88:a::/64",
- "gateway": "fd10:88:a::1"
- }
- ],
- [
- {
- "subnet": "10.89.19.0/24",
- "gateway": "10.89.19.10"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall",
- "backend": ""
- },
- {
- "type": "tuning"
- },
- {
- "type": "dnsname",
- "domainName": "dns.podman",
- "capabilities": {
- "aliases": true
- }
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/valid/internal.conflist b/libpod/network/cni/testfiles/valid/internal.conflist
deleted file mode 100644
index 1b6f15a96..000000000
--- a/libpod/network/cni/testfiles/valid/internal.conflist
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "internal",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman8",
- "isGateway": false,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "10.89.7.0/24"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall",
- "backend": ""
- },
- {
- "type": "tuning"
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/valid/label.conflist b/libpod/network/cni/testfiles/valid/label.conflist
deleted file mode 100644
index 1501f9bd7..000000000
--- a/libpod/network/cni/testfiles/valid/label.conflist
+++ /dev/null
@@ -1,54 +0,0 @@
-{
- "args": {
- "podman_labels": {
- "mykey": "value"
- }
- },
- "cniVersion": "0.4.0",
- "name": "label",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman15",
- "isGateway": true,
- "ipMasq": true,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "10.89.13.0/24",
- "gateway": "10.89.13.1"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall",
- "backend": ""
- },
- {
- "type": "tuning"
- },
- {
- "type": "dnsname",
- "domainName": "dns.podman",
- "capabilities": {
- "aliases": true
- }
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/valid/macvlan.conflist b/libpod/network/cni/testfiles/valid/macvlan.conflist
deleted file mode 100644
index 8f3692334..000000000
--- a/libpod/network/cni/testfiles/valid/macvlan.conflist
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "macvlan",
- "plugins": [
- {
- "type": "macvlan",
- "master": "lo",
- "ipam": {
- "type": "dhcp"
- }
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/valid/macvlan_mtu.conflist b/libpod/network/cni/testfiles/valid/macvlan_mtu.conflist
deleted file mode 100644
index 2fd259117..000000000
--- a/libpod/network/cni/testfiles/valid/macvlan_mtu.conflist
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "macvlan_mtu",
- "plugins": [
- {
- "type": "macvlan",
- "master": "lo",
- "ipam": {
- "type": "dhcp"
- },
- "mtu": 1300
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/valid/mtu.conflist b/libpod/network/cni/testfiles/valid/mtu.conflist
deleted file mode 100644
index db5f7e194..000000000
--- a/libpod/network/cni/testfiles/valid/mtu.conflist
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "mtu",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman13",
- "isGateway": true,
- "ipMasq": true,
- "mtu": 1500,
- "hairpinMode": true,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "10.89.11.0/24"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall",
- "backend": ""
- },
- {
- "type": "tuning"
- },
- {
- "type": "dnsname",
- "domainName": "dns.podman",
- "capabilities": {
- "aliases": true
- }
- }
- ]
-}
diff --git a/libpod/network/cni/testfiles/valid/vlan.conflist b/libpod/network/cni/testfiles/valid/vlan.conflist
deleted file mode 100644
index 75e8967f1..000000000
--- a/libpod/network/cni/testfiles/valid/vlan.conflist
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "cniVersion": "0.4.0",
- "name": "vlan",
- "plugins": [
- {
- "type": "bridge",
- "bridge": "cni-podman14",
- "isGateway": true,
- "ipMasq": true,
- "hairpinMode": true,
- "vlan": 5,
- "ipam": {
- "type": "host-local",
- "routes": [
- {
- "dst": "0.0.0.0/0"
- }
- ],
- "ranges": [
- [
- {
- "subnet": "10.89.12.0/24",
- "gateway": "10.89.12.1"
- }
- ]
- ]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- },
- {
- "type": "firewall",
- "backend": ""
- },
- {
- "type": "tuning"
- },
- {
- "type": "dnsname",
- "domainName": "dns.podman",
- "capabilities": {
- "aliases": true
- }
- }
- ]
-}