diff options
author | Paul Holzinger <pholzing@redhat.com> | 2021-12-17 14:46:15 +0100 |
---|---|---|
committer | Paul Holzinger <pholzing@redhat.com> | 2022-01-12 17:07:30 +0100 |
commit | 495884b3195de482dc610a2a002db7e053188a32 (patch) | |
tree | 2a6f23db066cd52aa366991b0b34d7b919368ddc | |
parent | 2cdab5d53923784e72020d70ee9375518f19f9b6 (diff) | |
download | podman-495884b3195de482dc610a2a002db7e053188a32.tar.gz podman-495884b3195de482dc610a2a002db7e053188a32.tar.bz2 podman-495884b3195de482dc610a2a002db7e053188a32.zip |
use libnetwork from c/common
The libpod/network packages were moved to c/common so that buildah can
use it as well. To prevent duplication use it in podman as well and
remove it from here.
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
121 files changed, 458 insertions, 6459 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go index f1dea4113..2bd67bf4f 100644 --- a/cmd/podman/common/completion.go +++ b/cmd/podman/common/completion.go @@ -7,11 +7,11 @@ import ( "reflect" "strings" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/image/v5/pkg/sysregistriesv2" "github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/rootless" systemdDefine "github.com/containers/podman/v3/pkg/systemd/define" diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go index 297188a45..b4641ea96 100644 --- a/cmd/podman/common/create_opts.go +++ b/cmd/podman/common/create_opts.go @@ -8,11 +8,11 @@ import ( "strconv" "strings" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/api/handlers" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/rootless" diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go index 425d85c9d..39b699812 100644 --- a/cmd/podman/common/netflags.go +++ b/cmd/podman/common/netflags.go @@ -3,10 +3,10 @@ package common import ( "net" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/completion" "github.com/containers/podman/v3/cmd/podman/parse" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/specgenutil" diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go index cebe61b5a..c8a03ab4f 100644 --- a/cmd/podman/containers/ps.go +++ b/cmd/podman/containers/ps.go @@ -7,13 +7,13 @@ import ( "time" tm "github.com/buger/goterm" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/report" "github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/cmd/podman/utils" "github.com/containers/podman/v3/cmd/podman/validate" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/docker/go-units" "github.com/pkg/errors" diff --git a/cmd/podman/networks/connect.go b/cmd/podman/networks/connect.go index b0ffbfe6d..b0eece06c 100644 --- a/cmd/podman/networks/connect.go +++ b/cmd/podman/networks/connect.go @@ -3,10 +3,10 @@ package network import ( "net" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/completion" "github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/registry" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/spf13/cobra" ) diff --git a/cmd/podman/networks/create.go b/cmd/podman/networks/create.go index 21d720f55..ad1f9cbd0 100644 --- a/cmd/podman/networks/create.go +++ b/cmd/podman/networks/create.go @@ -4,12 +4,12 @@ import ( "fmt" "net" + "github.com/containers/common/libnetwork/types" + "github.com/containers/common/libnetwork/util" "github.com/containers/common/pkg/completion" "github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/parse" "github.com/containers/podman/v3/cmd/podman/registry" - "github.com/containers/podman/v3/libpod/network/types" - "github.com/containers/podman/v3/libpod/network/util" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/pkg/errors" "github.com/sirupsen/logrus" diff --git a/cmd/podman/networks/list.go b/cmd/podman/networks/list.go index 7ce566225..b84c9f5d3 100644 --- a/cmd/podman/networks/list.go +++ b/cmd/podman/networks/list.go @@ -6,12 +6,12 @@ import ( "sort" "strings" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/report" "github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/cmd/podman/validate" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/pkg/errors" "github.com/spf13/cobra" diff --git a/cmd/rootlessport/main.go b/cmd/rootlessport/main.go index e691ce2fc..8ac4fe1be 100644 --- a/cmd/rootlessport/main.go +++ b/cmd/rootlessport/main.go @@ -13,7 +13,7 @@ import ( "strings" "github.com/containernetworking/plugins/pkg/ns" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/pkg/rootlessport" "github.com/pkg/errors" rkport "github.com/rootless-containers/rootlesskit/pkg/port" diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index 9669cf921..ceeb5119d 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -8,8 +8,8 @@ import ( "strings" "sync" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" "github.com/sirupsen/logrus" diff --git a/libpod/common_test.go b/libpod/common_test.go index 67e29c265..d64168284 100644 --- a/libpod/common_test.go +++ b/libpod/common_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/lock" - "github.com/containers/podman/v3/libpod/network/types" "github.com/opencontainers/runtime-tools/generate" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/libpod/container.go b/libpod/container.go index c746f97c7..1dd2ef5f7 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -10,13 +10,13 @@ import ( "time" types040 "github.com/containernetworking/cni/pkg/types/040" + "github.com/containers/common/libnetwork/cni" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/secrets" "github.com/containers/image/v5/manifest" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/lock" - "github.com/containers/podman/v3/libpod/network/cni" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/storage" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" diff --git a/libpod/container_config.go b/libpod/container_config.go index 288524dbd..102d74236 100644 --- a/libpod/container_config.go +++ b/libpod/container_config.go @@ -4,9 +4,9 @@ import ( "net" "time" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/secrets" "github.com/containers/image/v5/manifest" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/namespaces" "github.com/containers/storage" spec "github.com/opencontainers/runtime-spec/specs-go" diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 28d961e4b..5654f3c4f 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -27,6 +27,7 @@ import ( "github.com/containers/buildah/pkg/chrootuser" "github.com/containers/buildah/pkg/overlay" butil "github.com/containers/buildah/util" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/apparmor" "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/chown" @@ -35,7 +36,6 @@ import ( "github.com/containers/common/pkg/umask" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/annotations" "github.com/containers/podman/v3/pkg/checkpoint/crutils" "github.com/containers/podman/v3/pkg/criu" diff --git a/libpod/define/config.go b/libpod/define/config.go index a5cf07afc..0181bd31c 100644 --- a/libpod/define/config.go +++ b/libpod/define/config.go @@ -5,7 +5,7 @@ import ( "io" "regexp" - "github.com/pkg/errors" + "github.com/containers/common/libnetwork/types" ) var ( @@ -17,9 +17,9 @@ var ( // NameRegex is a regular expression to validate container/pod names. // This must NOT be changed from outside of Libpod. It should be a // constant, but Go won't let us do that. - NameRegex = regexp.MustCompile("^[a-zA-Z0-9][a-zA-Z0-9_.-]*$") + NameRegex = types.NameRegex // RegexError is thrown in presence of an invalid container/pod name. - RegexError = errors.Wrapf(ErrInvalidArg, "names must match [a-zA-Z0-9][a-zA-Z0-9_.-]*") + RegexError = types.RegexError // UmaskRegex is a regular expression to validate Umask. UmaskRegex = regexp.MustCompile(`^[0-7]{1,4}$`) ) diff --git a/libpod/define/errors.go b/libpod/define/errors.go index 9fd210eed..653ef187d 100644 --- a/libpod/define/errors.go +++ b/libpod/define/errors.go @@ -3,6 +3,8 @@ package define import ( "errors" "fmt" + + "github.com/containers/common/libnetwork/types" ) var ( @@ -16,7 +18,7 @@ var ( ErrNoSuchVolume = errors.New("no such volume") // ErrNoSuchNetwork indicates the requested network does not exist - ErrNoSuchNetwork = errors.New("network not found") + ErrNoSuchNetwork = types.ErrNoSuchNetwork // ErrNoSuchExecSession indicates that the requested exec session does // not exist. @@ -48,7 +50,7 @@ var ( ErrExecSessionExists = errors.New("exec session already exists") // ErrNetworkExists indicates that a network with the given name already // exists. - ErrNetworkExists = errors.New("network already exists") + ErrNetworkExists = types.ErrNetworkExists // ErrCtrStateInvalid indicates a container is in an improper state for // the requested operation @@ -73,7 +75,7 @@ var ( ErrVolumeFinalized = errors.New("volume has been finalized") // ErrInvalidArg indicates that an invalid argument was passed - ErrInvalidArg = errors.New("invalid argument") + ErrInvalidArg = types.ErrInvalidArg // ErrEmptyID indicates that an empty ID was passed ErrEmptyID = errors.New("name or ID cannot be empty") diff --git a/libpod/kube.go b/libpod/kube.go index f465fc776..2ed7ddf0b 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -11,9 +11,9 @@ import ( "strings" "time" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/env" "github.com/containers/podman/v3/pkg/lookup" "github.com/containers/podman/v3/pkg/namespaces" 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/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/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 - } - } - ] -} diff --git a/libpod/network/internal/util/ip_test.go b/libpod/network/internal/util/ip_test.go deleted file mode 100644 index eaed769d7..000000000 --- a/libpod/network/internal/util/ip_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package util - -import ( - "fmt" - "net" - "reflect" - "testing" -) - -func parseCIDR(n string) *net.IPNet { - _, parsedNet, _ := net.ParseCIDR(n) - return parsedNet -} - -func TestNextSubnet(t *testing.T) { - type args struct { - subnet *net.IPNet - } - tests := []struct { - name string - args args - want *net.IPNet - wantErr bool - }{ - {"class b", args{subnet: parseCIDR("192.168.0.0/16")}, parseCIDR("192.169.0.0/16"), false}, - {"class c", args{subnet: parseCIDR("192.168.1.0/24")}, parseCIDR("192.168.2.0/24"), false}, - } - for _, tt := range tests { - test := tt - t.Run(test.name, func(t *testing.T) { - got, err := NextSubnet(test.args.subnet) - if (err != nil) != test.wantErr { - t.Errorf("NextSubnet() error = %v, wantErr %v", err, test.wantErr) - return - } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("NextSubnet() got = %v, want %v", got, test.want) - } - }) - } -} - -func TestGetRandomIPv6Subnet(t *testing.T) { - for i := 0; i < 1000; i++ { - t.Run(fmt.Sprintf("GetRandomIPv6Subnet %d", i), func(t *testing.T) { - sub, err := getRandomIPv6Subnet() - if err != nil { - t.Errorf("GetRandomIPv6Subnet() error should be nil: %v", err) - return - } - if sub.IP.To4() != nil { - t.Errorf("ip %s is not an ipv6 address", sub.IP) - } - if sub.IP[0] != 0xfd { - t.Errorf("ipv6 %s does not start with fd", sub.IP) - } - ones, bytes := sub.Mask.Size() - if ones != 64 || bytes != 128 { - t.Errorf("wrong network mask %v, it should be /64", sub.Mask) - } - }) - } -} diff --git a/libpod/network/netavark/config_test.go b/libpod/network/netavark/config_test.go deleted file mode 100644 index ee4a825f1..000000000 --- a/libpod/network/netavark/config_test.go +++ /dev/null @@ -1,1123 +0,0 @@ -// +build linux - -package netavark_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 - networkConfDir string - logBuffer bytes.Buffer - ) - - BeforeEach(func() { - var err error - networkConfDir, err = ioutil.TempDir("", "podman_netavark_test") - if err != nil { - Fail("Failed to create tmpdir") - - } - logBuffer = bytes.Buffer{} - logrus.SetOutput(&logBuffer) - }) - - JustBeforeEach(func() { - var err error - libpodNet, err = getNetworkInterface(networkConfDir, false) - if err != nil { - Fail("Failed to create NewCNINetworkInterface") - } - }) - - AfterEach(func() { - os.RemoveAll(networkConfDir) - }) - - 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].ID).To(Equal("2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9")) - Expect(networks[0].NetworkInterface).To(Equal("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(networkConfDir, network1.Name+".json") - 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()) - EqualNetwork(network2, network1) - - // inspect by ID - network2, err = libpodNet.NetworkInspect(network1.ID) - Expect(err).To(BeNil()) - EqualNetwork(network2, network1) - - // inspect by partial ID - network2, err = libpodNet.NetworkInspect(network1.ID[:10]) - Expect(err).To(BeNil()) - EqualNetwork(network2, network1) - - // create a new interface to force a config load from disk - libpodNet, err = getNetworkInterface(networkConfDir, false) - Expect(err).To(BeNil()) - - network2, err = libpodNet.NetworkInspect(network1.Name) - Expect(err).To(BeNil()) - EqualNetwork(network2, 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(networkConfDir, network1.Name+".json")).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: "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("podman2")) - Expect(network1.Driver).To(Equal("bridge")) - - _, err = libpodNet.NetworkCreate(network) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("bridge name podman2 already in use")) - }) - - 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(networkConfDir, false) - Expect(err).To(BeNil()) - // check the the networks are identical - network2, err := libpodNet.NetworkInspect(network1.Name) - Expect(err).To(BeNil()) - EqualNetwork(network2, network1) - }) - - 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.10" - 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(networkConfDir, network1.Name+".json")).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)) - }) - - 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(networkConfDir, network1.Name+".json") - Expect(path).To(BeARegularFile()) - grepInFile(path, `"dns_enabled": true`) - }) - - 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(networkConfDir, network1.Name+".json") - 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 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(networkConfDir, network1.Name+".json") - 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, - } - _, err := libpodNet.NetworkCreate(network) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("cannot set internal and dns enabled")) - }) - - It("network inspect partial ID", func() { - network := types.Network{Name: "net4"} - network1, err := libpodNet.NetworkCreate(network) - Expect(err).To(BeNil()) - Expect(network1.ID).To(HaveLen(64)) - - network2, err := libpodNet.NetworkInspect(network1.ID[:10]) - Expect(err).ToNot(HaveOccurred()) - EqualNetwork(network2, network1) - }) - - 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(networkConfDir, 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(7)) - // 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(7)) - - nets[0].Name = "myname" - nets, err = libpodNet.NetworkList() - Expect(err).To(BeNil()) - Expect(nets).To(HaveLen(7)) - 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("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("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("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("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("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("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("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("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"}, - } - filterFuncs, err := util.GenerateNetworkFilters(filters) - Expect(err).To(BeNil()) - - networks, err := libpodNet.NetworkList(filterFuncs...) - Expect(err).To(BeNil()) - Expect(networks).To(HaveLen(7)) - Expect(networks).To(ConsistOf(HaveNetworkName("internal"), HaveNetworkName("bridge"), - HaveNetworkName("mtu"), HaveNetworkName("vlan"), HaveNetworkName("podman"), - HaveNetworkName("label"), 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: "podman9", - } - _, err := libpodNet.NetworkCreate(network) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("bridge name 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(networkConfDir, 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(1)) - logString := logBuffer.String() - Expect(logString).To(ContainSubstring("Error reading network config file \\\"%s/broken.json\\\": unexpected EOF", networkConfDir)) - Expect(logString).To(ContainSubstring("Network config \\\"%s/invalid name.json\\\" has invalid name: \\\"invalid name\\\", skipping: names must match [a-zA-Z0-9][a-zA-Z0-9_.-]*: invalid argument", networkConfDir)) - Expect(logString).To(ContainSubstring("Network config name \\\"name_miss\\\" does not match file name \\\"name_missmatch.json\\\", skipping")) - Expect(logString).To(ContainSubstring("Network config \\\"%s/wrongID.json\\\" could not be parsed, skipping: invalid network ID \\\"someID\\\"", networkConfDir)) - Expect(logString).To(ContainSubstring("Network config \\\"%s/invalid_gateway.json\\\" could not be parsed, skipping: gateway 10.89.100.1 not in subnet 10.89.9.0/24", networkConfDir)) - }) - - }) - -}) - -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)) -} - -// EqualNetwork must be used because comparing the time with deep equal does not work -func EqualNetwork(net1, net2 types.Network) { - ExpectWithOffset(1, net1.Created.Equal(net2.Created)).To(BeTrue(), "net1 created: %v is not equal net2 created: %v", net1.Created, net2.Created) - net1.Created = time.Time{} - net2.Created = time.Time{} - ExpectWithOffset(1, net1).To(Equal(net2)) -} diff --git a/libpod/network/netavark/ipam_test.go b/libpod/network/netavark/ipam_test.go deleted file mode 100644 index 4b3947501..000000000 --- a/libpod/network/netavark/ipam_test.go +++ /dev/null @@ -1,433 +0,0 @@ -package netavark - -import ( - "bytes" - "fmt" - "io/ioutil" - "net" - "os" - "path/filepath" - - "github.com/containers/podman/v3/libpod/network/types" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/sirupsen/logrus" -) - -var _ = Describe("IPAM", func() { - var ( - networkInterface *netavarkNetwork - networkConfDir string - logBuffer bytes.Buffer - ) - - BeforeEach(func() { - var err error - networkConfDir, err = ioutil.TempDir("", "podman_netavark_test") - if err != nil { - Fail("Failed to create tmpdir") - - } - logBuffer = bytes.Buffer{} - logrus.SetOutput(&logBuffer) - }) - - JustBeforeEach(func() { - libpodNet, err := NewNetworkInterface(InitConfig{ - NetworkConfigDir: networkConfDir, - IPAMDBPath: filepath.Join(networkConfDir, "ipam.db"), - LockFile: filepath.Join(networkConfDir, "netavark.lock"), - }) - if err != nil { - Fail("Failed to create NewCNINetworkInterface") - } - - networkInterface = libpodNet.(*netavarkNetwork) - // run network list to force a network load - networkInterface.NetworkList() - }) - - AfterEach(func() { - os.RemoveAll(networkConfDir) - }) - - It("simple ipam alloc", func() { - netName := types.DefaultNetworkName - for i := 2; i < 100; i++ { - opts := &types.NetworkOptions{ - ContainerID: "someContainerID", - Networks: map[string]types.PerNetworkOptions{ - netName: {}, - }, - } - - err := networkInterface.allocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(net.ParseIP(fmt.Sprintf("10.88.0.%d", i)).To4())) - } - }) - - It("ipam try to alloc same ip", func() { - netName := types.DefaultNetworkName - opts := &types.NetworkOptions{ - ContainerID: "someContainerID", - Networks: map[string]types.PerNetworkOptions{ - netName: {}, - }, - } - - err := networkInterface.allocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(net.ParseIP("10.88.0.2").To4())) - - opts = &types.NetworkOptions{ - ContainerID: "otherID", - Networks: map[string]types.PerNetworkOptions{ - netName: {StaticIPs: []net.IP{net.ParseIP("10.88.0.2")}}, - }, - } - err = networkInterface.allocIPs(opts) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("IPAM error: requested ip address 10.88.0.2 is already allocated to container ID someContainerID")) - }) - - It("ipam try to alloc more ips as in range", func() { - s, _ := types.ParseCIDR("10.0.0.1/24") - network, err := networkInterface.NetworkCreate(types.Network{ - Subnets: []types.Subnet{ - { - Subnet: s, - LeaseRange: &types.LeaseRange{ - StartIP: net.ParseIP("10.0.0.10"), - EndIP: net.ParseIP("10.0.0.20"), - }, - }, - }, - }) - Expect(err).ToNot(HaveOccurred()) - - netName := network.Name - - for i := 10; i < 21; i++ { - opts := &types.NetworkOptions{ - ContainerID: fmt.Sprintf("someContainerID-%d", i), - Networks: map[string]types.PerNetworkOptions{ - netName: {}, - }, - } - - err = networkInterface.allocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(net.ParseIP(fmt.Sprintf("10.0.0.%d", i)).To4())) - } - - opts := &types.NetworkOptions{ - ContainerID: "someContainerID-22", - Networks: map[string]types.PerNetworkOptions{ - netName: {}, - }, - } - - // now this should fail because all free ips are already assigned - err = networkInterface.allocIPs(opts) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("IPAM error: failed to find free IP in range: 10.0.0.10 - 10.0.0.20")) - }) - - It("ipam basic setup", func() { - netName := types.DefaultNetworkName - opts := &types.NetworkOptions{ - ContainerID: "someContainerID", - Networks: map[string]types.PerNetworkOptions{ - netName: {}, - }, - } - - expectedIP := net.ParseIP("10.88.0.2").To4() - - err := networkInterface.allocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(expectedIP)) - - // remove static ips from opts - netOpts := opts.Networks[netName] - netOpts.StaticIPs = nil - opts.Networks[netName] = netOpts - - err = networkInterface.getAssignedIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(expectedIP)) - - err = networkInterface.allocIPs(opts) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("IPAM error: requested ip address 10.88.0.2 is already allocated to container ID someContainerID")) - - // dealloc the ip - err = networkInterface.deallocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - - err = networkInterface.allocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(expectedIP)) - }) - - It("ipam dual stack", func() { - s1, _ := types.ParseCIDR("10.0.0.0/26") - s2, _ := types.ParseCIDR("fd80::/24") - network, err := networkInterface.NetworkCreate(types.Network{ - Subnets: []types.Subnet{ - { - Subnet: s1, - }, - { - Subnet: s2, - }, - }, - }) - Expect(err).ToNot(HaveOccurred()) - - netName := network.Name - - opts := &types.NetworkOptions{ - ContainerID: "someContainerID", - Networks: map[string]types.PerNetworkOptions{ - netName: {}, - }, - } - - err = networkInterface.allocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(2)) - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(net.ParseIP("10.0.0.2").To4())) - Expect(opts.Networks[netName].StaticIPs[1]).To(Equal(net.ParseIP("fd80::2"))) - - // remove static ips from opts - netOpts := opts.Networks[netName] - netOpts.StaticIPs = nil - opts.Networks[netName] = netOpts - - err = networkInterface.getAssignedIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(2)) - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(net.ParseIP("10.0.0.2").To4())) - Expect(opts.Networks[netName].StaticIPs[1]).To(Equal(net.ParseIP("fd80::2"))) - - err = networkInterface.deallocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - - // try to alloc the same again - err = networkInterface.allocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(2)) - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(net.ParseIP("10.0.0.2").To4())) - Expect(opts.Networks[netName].StaticIPs[1]).To(Equal(net.ParseIP("fd80::2"))) - }) - - It("ipam with two networks", func() { - s, _ := types.ParseCIDR("10.0.0.0/24") - network, err := networkInterface.NetworkCreate(types.Network{ - Subnets: []types.Subnet{ - { - Subnet: s, - }, - }, - }) - Expect(err).ToNot(HaveOccurred()) - - netName1 := network.Name - - s, _ = types.ParseCIDR("10.0.1.0/24") - network, err = networkInterface.NetworkCreate(types.Network{ - Subnets: []types.Subnet{ - { - Subnet: s, - }, - }, - }) - Expect(err).ToNot(HaveOccurred()) - - netName2 := network.Name - - opts := &types.NetworkOptions{ - ContainerID: "someContainerID", - Networks: map[string]types.PerNetworkOptions{ - netName1: {}, - netName2: {}, - }, - } - - err = networkInterface.allocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName1)) - Expect(opts.Networks[netName1].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName1].StaticIPs[0]).To(Equal(net.ParseIP("10.0.0.2").To4())) - Expect(opts.Networks).To(HaveKey(netName2)) - Expect(opts.Networks[netName2].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName2].StaticIPs[0]).To(Equal(net.ParseIP("10.0.1.2").To4())) - - // remove static ips from opts - netOpts := opts.Networks[netName1] - netOpts.StaticIPs = nil - opts.Networks[netName1] = netOpts - netOpts = opts.Networks[netName2] - netOpts.StaticIPs = nil - opts.Networks[netName2] = netOpts - - err = networkInterface.getAssignedIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName1)) - Expect(opts.Networks[netName1].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName1].StaticIPs[0]).To(Equal(net.ParseIP("10.0.0.2").To4())) - Expect(opts.Networks).To(HaveKey(netName2)) - Expect(opts.Networks[netName2].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName2].StaticIPs[0]).To(Equal(net.ParseIP("10.0.1.2").To4())) - - err = networkInterface.deallocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - - // try to alloc the same again - err = networkInterface.allocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName1)) - Expect(opts.Networks[netName1].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName1].StaticIPs[0]).To(Equal(net.ParseIP("10.0.0.2").To4())) - Expect(opts.Networks).To(HaveKey(netName2)) - Expect(opts.Networks[netName2].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName2].StaticIPs[0]).To(Equal(net.ParseIP("10.0.1.2").To4())) - }) - - It("ipam alloc more ips as in subnet", func() { - s, _ := types.ParseCIDR("10.0.0.0/26") - network, err := networkInterface.NetworkCreate(types.Network{ - Subnets: []types.Subnet{ - { - Subnet: s, - }, - }, - }) - Expect(err).ToNot(HaveOccurred()) - - netName := network.Name - - for i := 2; i < 64; i++ { - opts := &types.NetworkOptions{ - ContainerID: fmt.Sprintf("id-%d", i), - Networks: map[string]types.PerNetworkOptions{ - netName: {}, - }, - } - err = networkInterface.allocIPs(opts) - if i < 63 { - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(net.ParseIP(fmt.Sprintf("10.0.0.%d", i)).To4())) - } else { - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("IPAM error: failed to find free IP in range: 10.0.0.1 - 10.0.0.62")) - } - } - }) - - It("ipam alloc -> dealloc -> alloc", func() { - s, _ := types.ParseCIDR("10.0.0.0/27") - network, err := networkInterface.NetworkCreate(types.Network{ - Subnets: []types.Subnet{ - { - Subnet: s, - }, - }, - }) - Expect(err).ToNot(HaveOccurred()) - - netName := network.Name - - for i := 2; i < 10; i++ { - opts := types.NetworkOptions{ - ContainerID: fmt.Sprintf("id-%d", i), - Networks: map[string]types.PerNetworkOptions{ - netName: {}, - }, - } - err = networkInterface.allocIPs(&opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(1)) - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(net.ParseIP(fmt.Sprintf("10.0.0.%d", i)).To4())) - - err = networkInterface.deallocIPs(&opts) - Expect(err).ToNot(HaveOccurred()) - } - - for i := 0; i < 30; i++ { - opts := types.NetworkOptions{ - ContainerID: fmt.Sprintf("id-%d", i), - Networks: map[string]types.PerNetworkOptions{ - netName: {}, - }, - } - err = networkInterface.allocIPs(&opts) - if i < 29 { - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(1)) - // The (i+8)%29+2 part looks cryptic but it is actually simple, we already have 8 ips allocated above - // so we expect the 8 available ip. We have 29 assignable ip addresses in this subnet because "i"+8 can - // be greater than 30 we have to modulo by 29 to go back to the beginning. Also the first free ip is - // network address + 2, so we have to add 2 to the result - Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(net.ParseIP(fmt.Sprintf("10.0.0.%d", (i+8)%29+2)).To4())) - } else { - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("IPAM error: failed to find free IP in range: 10.0.0.1 - 10.0.0.30")) - } - } - }) - - It("ipam with dhcp driver should not set ips", func() { - network, err := networkInterface.NetworkCreate(types.Network{ - IPAMOptions: map[string]string{ - "driver": types.DHCPIPAMDriver, - }, - }) - Expect(err).ToNot(HaveOccurred()) - - netName := network.Name - - opts := &types.NetworkOptions{ - ContainerID: "someContainerID", - Networks: map[string]types.PerNetworkOptions{ - netName: {}, - }, - } - - err = networkInterface.allocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(0)) - - err = networkInterface.getAssignedIPs(opts) - Expect(err).ToNot(HaveOccurred()) - Expect(opts.Networks).To(HaveKey(netName)) - Expect(opts.Networks[netName].StaticIPs).To(HaveLen(0)) - - // dealloc the ip - err = networkInterface.deallocIPs(opts) - Expect(err).ToNot(HaveOccurred()) - }) - -}) diff --git a/libpod/network/netavark/netavark_suite_test.go b/libpod/network/netavark/netavark_suite_test.go deleted file mode 100644 index 6063a54e3..000000000 --- a/libpod/network/netavark/netavark_suite_test.go +++ /dev/null @@ -1,75 +0,0 @@ -// +build linux - -package netavark_test - -import ( - "fmt" - "net" - "os" - "path/filepath" - "reflect" - "testing" - - "github.com/containers/podman/v3/libpod/network/netavark" - "github.com/containers/podman/v3/libpod/network/types" - "github.com/containers/podman/v3/libpod/network/util" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - gomegaTypes "github.com/onsi/gomega/types" -) - -func TestNetavark(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Netavark Suite") -} - -var netavarkBinary string - -func init() { - netavarkBinary = os.Getenv("NETAVARK_BINARY") - if netavarkBinary == "" { - netavarkBinary = "/usr/libexec/podman/netavark" - } -} - -func getNetworkInterface(confDir string, machine bool) (types.ContainerNetwork, error) { - return netavark.NewNetworkInterface(netavark.InitConfig{ - NetworkConfigDir: confDir, - IsMachine: machine, - NetavarkBinary: netavarkBinary, - IPAMDBPath: filepath.Join(confDir, "ipam.db"), - LockFile: filepath.Join(confDir, "netavark.lock"), - }) -} - -// EqualSubnet is a custom GomegaMatcher to match a subnet -// This makes sure to not use the 16 bytes ip representation. -func EqualSubnet(subnet *net.IPNet) gomegaTypes.GomegaMatcher { - return &equalSubnetMatcher{ - expected: subnet, - } -} - -type equalSubnetMatcher struct { - expected *net.IPNet -} - -func (m *equalSubnetMatcher) Match(actual interface{}) (bool, error) { - util.NormalizeIP(&m.expected.IP) - - subnet, ok := actual.(*net.IPNet) - if !ok { - return false, fmt.Errorf("EqualSubnet expects a *net.IPNet") - } - util.NormalizeIP(&subnet.IP) - - return reflect.DeepEqual(subnet, m.expected), nil -} - -func (m *equalSubnetMatcher) FailureMessage(actual interface{}) string { - return fmt.Sprintf("Expected subnet %#v to equal subnet %#v", actual, m.expected) -} - -func (m *equalSubnetMatcher) NegatedFailureMessage(actual interface{}) string { - return fmt.Sprintf("Expected subnet %#v not to equal subnet %#v", actual, m.expected) -} diff --git a/libpod/network/netavark/run_test.go b/libpod/network/netavark/run_test.go deleted file mode 100644 index f79e6d812..000000000 --- a/libpod/network/netavark/run_test.go +++ /dev/null @@ -1,699 +0,0 @@ -// +build linux - -package netavark_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 ( - "io/ioutil" - "net" - "os" - "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" - - "github.com/containers/podman/v3/libpod/network/types" - "github.com/containers/podman/v3/libpod/network/util" - "github.com/containers/podman/v3/pkg/netns" - "github.com/containers/podman/v3/pkg/rootless" - "github.com/containers/storage/pkg/stringid" -) - -var _ = Describe("run netavark", func() { - var ( - libpodNet types.ContainerNetwork - confDir string - netNSTest ns.NetNS - netNSContainer ns.NetNS - ) - - // 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() - // 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() { - if _, ok := os.LookupEnv("NETAVARK_BINARY"); !ok { - Skip("NETAVARK_BINARY not set skip run tests") - } - - // set the logrus settings - logrus.SetLevel(logrus.TraceLevel) - // disable extra quotes so we can easily copy the netavark command - logrus.SetFormatter(&logrus.TextFormatter{DisableQuote: true}) - logrus.SetOutput(os.Stderr) - // 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 - confDir, err = ioutil.TempDir("", "podman_netavark_test") - if err != nil { - Fail("Failed to create tmpdir") - } - - netNSTest, err = netns.NewNS() - if err != nil { - Fail("Failed to create netns") - } - - netNSContainer, err = netns.NewNS() - if err != nil { - Fail("Failed to create netns") - } - - // Force iptables driver, firewalld is broken inside the extra - // namespace because it still connects to firewalld on the host. - _ = os.Setenv("NETAVARK_FW", "iptables") - }) - - JustBeforeEach(func() { - var err error - libpodNet, err = getNetworkInterface(confDir, false) - if err != nil { - Fail("Failed to create NewCNINetworkInterface") - } - }) - - AfterEach(func() { - logrus.SetFormatter(&logrus.TextFormatter{}) - logrus.SetLevel(logrus.InfoLevel) - os.RemoveAll(confDir) - - netns.UnmountNS(netNSTest) - netNSTest.Close() - - netns.UnmountNS(netNSContainer) - netNSContainer.Close() - - _ = os.Unsetenv("NETAVARK_FW") - }) - - It("test basic setup", func() { - runTest(func() { - defNet := types.DefaultNetworkName - intName := "eth0" - opts := types.SetupOptions{ - NetworkOptions: types.NetworkOptions{ - ContainerID: "someID", - ContainerName: "someName", - Networks: map[string]types.PerNetworkOptions{ - defNet: { - InterfaceName: intName, - }, - }, - }, - } - res, err := libpodNet.Setup(netNSContainer.Path(), opts) - Expect(err).ToNot(HaveOccurred()) - 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)) - ip := res[defNet].Interfaces[intName].Subnets[0].IPNet.IP - Expect(ip.String()).To(ContainSubstring("10.88.0.")) - gw := res[defNet].Interfaces[intName].Subnets[0].Gateway - util.NormalizeIP(&gw) - Expect(gw.String()).To(Equal("10.88.0.1")) - macAddress := res[defNet].Interfaces[intName].MacAddress - Expect(macAddress).To(HaveLen(6)) - // default network has no dns - Expect(res[defNet].DNSServerIPs).To(BeEmpty()) - Expect(res[defNet].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(intName) - Expect(err).To(BeNil()) - Expect(i.Name).To(Equal(intName)) - Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macAddress))) - addrs, err := i.Addrs() - Expect(err).To(BeNil()) - subnet := &net.IPNet{ - IP: ip, - Mask: net.CIDRMask(16, 32), - } - Expect(addrs).To(ContainElements(EqualSubnet(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()) - - // default bridge name - bridgeName := "podman0" - // check settings on the host side - i, err := net.InterfaceByName(bridgeName) - Expect(err).ToNot(HaveOccurred()) - Expect(i.Name).To(Equal(bridgeName)) - addrs, err := i.Addrs() - Expect(err).ToNot(HaveOccurred()) - // test that the gateway ip is assigned to the interface - subnet := &net.IPNet{ - IP: gw, - Mask: net.CIDRMask(16, 32), - } - Expect(addrs).To(ContainElements(EqualSubnet(subnet))) - - wg := &sync.WaitGroup{} - expected := stringid.GenerateNonCryptoID() - // now check ip connectivity - err = netNSContainer.Do(func(_ ns.NetNS) error { - wg.Add(1) - runNetListener(wg, "tcp", "0.0.0.0", 5000, expected) - return nil - }) - Expect(err).ToNot(HaveOccurred()) - - conn, err := net.Dial("tcp", ip.String()+":5000") - Expect(err).To(BeNil()) - _, err = conn.Write([]byte(expected)) - Expect(err).To(BeNil()) - conn.Close() - - err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(opts)) - Expect(err).ToNot(HaveOccurred()) - wg.Wait() - }) - }) - - It("setup two containers", func() { - runTest(func() { - defNet := types.DefaultNetworkName - intName := "eth0" - setupOpts1 := types.SetupOptions{ - NetworkOptions: types.NetworkOptions{ - ContainerID: stringid.GenerateNonCryptoID(), - Networks: map[string]types.PerNetworkOptions{ - defNet: {InterfaceName: intName}, - }, - }, - } - res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts1) - Expect(err).ToNot(HaveOccurred()) - 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)) - ip1 := res[defNet].Interfaces[intName].Subnets[0].IPNet.IP - Expect(ip1.String()).To(ContainSubstring("10.88.0.")) - Expect(res[defNet].Interfaces[intName].MacAddress).To(HaveLen(6)) - - setupOpts2 := types.SetupOptions{ - NetworkOptions: types.NetworkOptions{ - ContainerID: stringid.GenerateNonCryptoID(), - Networks: map[string]types.PerNetworkOptions{ - defNet: {InterfaceName: intName}, - }, - }, - } - - netNSContainer2, err := netns.NewNS() - Expect(err).ToNot(HaveOccurred()) - defer netns.UnmountNS(netNSContainer2) - defer netNSContainer2.Close() - - res, err = libpodNet.Setup(netNSContainer2.Path(), setupOpts2) - Expect(err).ToNot(HaveOccurred()) - 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)) - ip2 := res[defNet].Interfaces[intName].Subnets[0].IPNet.IP - Expect(ip2.String()).To(ContainSubstring("10.88.0.")) - Expect(res[defNet].Interfaces[intName].MacAddress).To(HaveLen(6)) - Expect(ip1.Equal(ip2)).To(BeFalse(), "IP1 %s should not be equal to IP2 %s", ip1.String(), ip2.String()) - - err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts1)) - Expect(err).ToNot(HaveOccurred()) - err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts2)) - Expect(err).ToNot(HaveOccurred()) - }) - }) - - It("setup dualstack network", func() { - runTest(func() { - s1, _ := types.ParseCIDR("10.0.0.1/24") - s2, _ := types.ParseCIDR("fd10:88:a::/64") - network, err := libpodNet.NetworkCreate(types.Network{ - Subnets: []types.Subnet{ - {Subnet: s1}, {Subnet: s2}, - }, - }) - Expect(err).ToNot(HaveOccurred()) - - netName := network.Name - intName := "eth0" - - setupOpts := types.SetupOptions{ - NetworkOptions: types.NetworkOptions{ - ContainerID: stringid.GenerateNonCryptoID(), - Networks: map[string]types.PerNetworkOptions{ - netName: {InterfaceName: intName}, - }, - }, - } - res, err := libpodNet.Setup(netNSContainer.Path(), setupOpts) - Expect(err).ToNot(HaveOccurred()) - 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(2)) - ip1 := res[netName].Interfaces[intName].Subnets[0].IPNet.IP - Expect(ip1.String()).To(ContainSubstring("10.0.0.")) - gw1 := res[netName].Interfaces[intName].Subnets[0].Gateway - Expect(gw1.String()).To(Equal("10.0.0.1")) - ip2 := res[netName].Interfaces[intName].Subnets[1].IPNet.IP - Expect(ip2.String()).To(ContainSubstring("fd10:88:a::")) - gw2 := res[netName].Interfaces[intName].Subnets[0].Gateway - Expect(gw2.String()).To(Equal("fd10:88:a::1")) - Expect(res[netName].Interfaces[intName].MacAddress).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(intName) - Expect(err).ToNot(HaveOccurred()) - Expect(i.Name).To(Equal(intName)) - addrs, err := i.Addrs() - Expect(err).ToNot(HaveOccurred()) - subnet1 := s1.IPNet - subnet1.IP = ip1 - subnet2 := s2.IPNet - subnet2.IP = ip2 - Expect(addrs).To(ContainElements(EqualSubnet(&subnet1), EqualSubnet(&subnet2))) - - // check loopback adapter - i, err = net.InterfaceByName("lo") - Expect(err).ToNot(HaveOccurred()) - 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).ToNot(HaveOccurred()) - - bridgeName := network.NetworkInterface - // check settings on the host side - i, err := net.InterfaceByName(bridgeName) - Expect(err).ToNot(HaveOccurred()) - Expect(i.Name).To(Equal(bridgeName)) - addrs, err := i.Addrs() - Expect(err).ToNot(HaveOccurred()) - // test that the gateway ip is assigned to the interface - subnet1 := s1.IPNet - subnet1.IP = gw1 - subnet2 := s2.IPNet - subnet2.IP = gw2 - Expect(addrs).To(ContainElements(EqualSubnet(&subnet1), EqualSubnet(&subnet2))) - - err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts)) - Expect(err).ToNot(HaveOccurred()) - }) - }) - - It("setup two networks", func() { - runTest(func() { - s1, _ := types.ParseCIDR("10.0.0.1/24") - network1, err := libpodNet.NetworkCreate(types.Network{ - Subnets: []types.Subnet{ - {Subnet: s1}, - }, - }) - Expect(err).ToNot(HaveOccurred()) - - netName1 := network1.Name - intName1 := "eth0" - - s2, _ := types.ParseCIDR("10.1.0.0/24") - network2, err := libpodNet.NetworkCreate(types.Network{ - Subnets: []types.Subnet{ - {Subnet: s2}, - }, - }) - Expect(err).ToNot(HaveOccurred()) - - netName2 := network2.Name - intName2 := "eth1" - - 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).ToNot(HaveOccurred()) - Expect(res).To(HaveLen(2)) - Expect(res).To(HaveKey(netName1)) - Expect(res).To(HaveKey(netName2)) - Expect(res[netName1].Interfaces).To(HaveKey(intName1)) - Expect(res[netName2].Interfaces).To(HaveKey(intName2)) - Expect(res[netName1].Interfaces[intName1].Subnets).To(HaveLen(1)) - ip1 := res[netName1].Interfaces[intName1].Subnets[0].IPNet.IP - Expect(ip1.String()).To(ContainSubstring("10.0.0.")) - gw1 := res[netName1].Interfaces[intName1].Subnets[0].Gateway - Expect(gw1.String()).To(Equal("10.0.0.1")) - ip2 := res[netName2].Interfaces[intName2].Subnets[0].IPNet.IP - Expect(ip2.String()).To(ContainSubstring("10.1.0.")) - gw2 := res[netName2].Interfaces[intName2].Subnets[0].Gateway - Expect(gw2.String()).To(Equal("10.1.0.1")) - mac1 := res[netName1].Interfaces[intName1].MacAddress - Expect(mac1).To(HaveLen(6)) - mac2 := res[netName2].Interfaces[intName2].MacAddress - Expect(mac2).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).ToNot(HaveOccurred()) - Expect(i.Name).To(Equal(intName1)) - addrs, err := i.Addrs() - Expect(err).ToNot(HaveOccurred()) - subnet1 := s1.IPNet - subnet1.IP = ip1 - Expect(addrs).To(ContainElements(EqualSubnet(&subnet1))) - - i, err = net.InterfaceByName(intName2) - Expect(err).ToNot(HaveOccurred()) - Expect(i.Name).To(Equal(intName2)) - addrs, err = i.Addrs() - Expect(err).ToNot(HaveOccurred()) - subnet2 := s2.IPNet - subnet2.IP = ip2 - Expect(addrs).To(ContainElements(EqualSubnet(&subnet2))) - - // check loopback adapter - i, err = net.InterfaceByName("lo") - Expect(err).ToNot(HaveOccurred()) - 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).ToNot(HaveOccurred()) - - bridgeName1 := network1.NetworkInterface - // check settings on the host side - i, err := net.InterfaceByName(bridgeName1) - Expect(err).ToNot(HaveOccurred()) - Expect(i.Name).To(Equal(bridgeName1)) - addrs, err := i.Addrs() - Expect(err).ToNot(HaveOccurred()) - // test that the gateway ip is assigned to the interface - subnet1 := s1.IPNet - subnet1.IP = gw1 - Expect(addrs).To(ContainElements(EqualSubnet(&subnet1))) - - bridgeName2 := network2.NetworkInterface - // check settings on the host side - i, err = net.InterfaceByName(bridgeName2) - Expect(err).ToNot(HaveOccurred()) - Expect(i.Name).To(Equal(bridgeName2)) - addrs, err = i.Addrs() - Expect(err).ToNot(HaveOccurred()) - // test that the gateway ip is assigned to the interface - subnet2 := s2.IPNet - subnet2.IP = gw2 - Expect(addrs).To(ContainElements(EqualSubnet(&subnet2))) - - err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(setupOpts)) - Expect(err).ToNot(HaveOccurred()) - }) - }) - - 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("simple teardown", func() { - runTest(func() { - defNet := types.DefaultNetworkName - intName := "eth0" - opts := types.SetupOptions{ - NetworkOptions: types.NetworkOptions{ - ContainerID: "someID", - ContainerName: "someName", - Networks: map[string]types.PerNetworkOptions{ - defNet: { - InterfaceName: intName, - }, - }, - }, - } - res, err := libpodNet.Setup(netNSContainer.Path(), opts) - Expect(err).ToNot(HaveOccurred()) - 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)) - ip := res[defNet].Interfaces[intName].Subnets[0].IPNet.IP - Expect(ip.String()).To(ContainSubstring("10.88.0.")) - gw := res[defNet].Interfaces[intName].Subnets[0].Gateway - Expect(gw.String()).To(Equal("10.88.0.1")) - macAddress := res[defNet].Interfaces[intName].MacAddress - Expect(macAddress).To(HaveLen(6)) - - err = libpodNet.Teardown(netNSContainer.Path(), types.TeardownOptions(opts)) - Expect(err).ToNot(HaveOccurred()) - err = netNSContainer.Do(func(_ ns.NetNS) error { - defer GinkgoRecover() - // check that the container interface is removed - _, err := net.InterfaceByName(intName) - Expect(err).To(HaveOccurred()) - return nil - }) - Expect(err).ToNot(HaveOccurred()) - - // default bridge name - bridgeName := "podman0" - // check that bridge interface was removed - _, err = net.InterfaceByName(bridgeName) - Expect(err).To(HaveOccurred()) - }) - }) - - It("test netavark error", func() { - runTest(func() { - intName := "eth0" - err := netNSContainer.Do(func(_ ns.NetNS) error { - defer GinkgoRecover() - - attr := netlink.NewLinkAttrs() - attr.Name = "eth0" - err := netlink.LinkAdd(&netlink.Bridge{LinkAttrs: attr}) - Expect(err).ToNot(HaveOccurred()) - return nil - }) - Expect(err).ToNot(HaveOccurred()) - defNet := types.DefaultNetworkName - opts := types.SetupOptions{ - NetworkOptions: types.NetworkOptions{ - ContainerID: "someID", - ContainerName: "someName", - Networks: map[string]types.PerNetworkOptions{ - defNet: { - InterfaceName: intName, - }, - }, - }, - } - _, err = libpodNet.Setup(netNSContainer.Path(), opts) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("interface eth0 already exists on container namespace")) - }) - }) -}) - -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() - defer ln.Close() - conn, err := ln.Accept() - Expect(err).To(BeNil()) - defer conn.Close() - conn.SetDeadline(time.Now().Add(1 * time.Second)) - data, err := ioutil.ReadAll(conn) - Expect(err).To(BeNil()) - Expect(string(data)).To(Equal(expectedData)) - }() - 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() - defer conn.Close() - 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)) - }() - default: - Fail("unsupported protocol") - } -} diff --git a/libpod/network/netavark/testfiles/invalid/broken.json b/libpod/network/netavark/testfiles/invalid/broken.json deleted file mode 100644 index 8968ddc73..000000000 --- a/libpod/network/netavark/testfiles/invalid/broken.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "bridge", - "id": "17f29b073143d8cd97b5bbe492bdeffec1c5fee55cc1fe2112c8b9335f8b6121", - "driver": "bridge", - "network_interface": "podman9", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "10.89.8.0/24", - "gateway": "10.89.8.1", - "lease_range": { - "start_ip": "10.89.8.20", - "end_ip": "10.89.8.50" - } - } - ], diff --git a/libpod/network/netavark/testfiles/invalid/invalid name.json b/libpod/network/netavark/testfiles/invalid/invalid name.json deleted file mode 100644 index 02b441279..000000000 --- a/libpod/network/netavark/testfiles/invalid/invalid name.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "invalid name", - "id": "6839f44f0fd01c5c5830856b66a1d7ce46842dd8798be0addf96f7255ce9f889", - "driver": "bridge", - "network_interface": "podman9", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "10.89.8.0/24", - "gateway": "10.89.8.1" - } - ], - "ipv6_enabled": false, - "internal": false, - "dns_enabled": true, - "ipam_options": { - "driver": "host-local" - } -} diff --git a/libpod/network/netavark/testfiles/invalid/invalid_gateway.json b/libpod/network/netavark/testfiles/invalid/invalid_gateway.json deleted file mode 100644 index 6e3a83156..000000000 --- a/libpod/network/netavark/testfiles/invalid/invalid_gateway.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "invalid_gateway", - "id": "49be6e401e7f8b9844afb969dcbc96e78205ed86ec1e5a46150bd4ab4fdd5686", - "driver": "bridge", - "network_interface": "podman9", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "10.89.9.0/24", - "gateway": "10.89.100.1" - } - ], - "ipv6_enabled": false, - "internal": false, - "dns_enabled": true, - "ipam_options": { - "driver": "host-local" - } -} diff --git a/libpod/network/netavark/testfiles/invalid/name_missmatch.json b/libpod/network/netavark/testfiles/invalid/name_missmatch.json deleted file mode 100644 index a3142d8bb..000000000 --- a/libpod/network/netavark/testfiles/invalid/name_missmatch.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "name_miss", - "id": "3bed2cb3a3acf7b6a8ef408420cc682d5520e26976d354254f528c965612054f", - "driver": "bridge", - "network_interface": "podman8", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "10.89.7.0/24", - "gateway": "10.89.7.1" - } - ], - "ipv6_enabled": false, - "internal": true, - "dns_enabled": false, - "ipam_options": { - "driver": "host-local" - } -} diff --git a/libpod/network/netavark/testfiles/invalid/wrongID.json b/libpod/network/netavark/testfiles/invalid/wrongID.json deleted file mode 100644 index 7c1446306..000000000 --- a/libpod/network/netavark/testfiles/invalid/wrongID.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "wrongID", - "id": "someID", - "driver": "bridge", - "network_interface": "podman1", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "10.89.0.0/24", - "gateway": "10.89.0.1" - } - ], - "ipv6_enabled": false, - "internal": false, - "dns_enabled": false, - "ipam_options": { - "driver": "host-local" - } -} diff --git a/libpod/network/netavark/testfiles/valid/bridge.json b/libpod/network/netavark/testfiles/valid/bridge.json deleted file mode 100644 index f4ec82188..000000000 --- a/libpod/network/netavark/testfiles/valid/bridge.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "bridge", - "id": "17f29b073143d8cd97b5bbe492bdeffec1c5fee55cc1fe2112c8b9335f8b6121", - "driver": "bridge", - "network_interface": "podman9", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "10.89.8.0/24", - "gateway": "10.89.8.1", - "lease_range": { - "start_ip": "10.89.8.20", - "end_ip": "10.89.8.50" - } - } - ], - "ipv6_enabled": false, - "internal": false, - "dns_enabled": true, - "ipam_options": { - "driver": "host-local" - } -} diff --git a/libpod/network/netavark/testfiles/valid/dualstack.json b/libpod/network/netavark/testfiles/valid/dualstack.json deleted file mode 100644 index bb4168f3a..000000000 --- a/libpod/network/netavark/testfiles/valid/dualstack.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "dualstack", - "id": "6839f44f0fd01c5c5830856b66a1d7ce46842dd8798be0addf96f7255ce9f889", - "driver": "bridge", - "network_interface": "podman21", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "fd10:88:a::/64", - "gateway": "fd10:88:a::1" - }, - { - "subnet": "10.89.19.0/24", - "gateway": "10.89.19.10" - } - ], - "ipv6_enabled": true, - "internal": false, - "dns_enabled": true, - "ipam_options": { - "driver": "host-local" - } -} diff --git a/libpod/network/netavark/testfiles/valid/internal.json b/libpod/network/netavark/testfiles/valid/internal.json deleted file mode 100644 index 3ccdd3889..000000000 --- a/libpod/network/netavark/testfiles/valid/internal.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "internal", - "id": "3bed2cb3a3acf7b6a8ef408420cc682d5520e26976d354254f528c965612054f", - "driver": "bridge", - "network_interface": "podman8", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "10.89.7.0/24" - } - ], - "ipv6_enabled": false, - "internal": true, - "dns_enabled": false, - "ipam_options": { - "driver": "host-local" - } -} diff --git a/libpod/network/netavark/testfiles/valid/label.json b/libpod/network/netavark/testfiles/valid/label.json deleted file mode 100644 index c4ed637ec..000000000 --- a/libpod/network/netavark/testfiles/valid/label.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "label", - "id": "1aca80e8b55c802f7b43740da2990e1b5735bbb323d93eb5ebda8395b04025e2", - "driver": "bridge", - "network_interface": "podman15", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "10.89.13.0/24", - "gateway": "10.89.13.1" - } - ], - "ipv6_enabled": false, - "internal": false, - "dns_enabled": true, - "labels": { - "mykey": "value" - }, - "ipam_options": { - "driver": "host-local" - } -} diff --git a/libpod/network/netavark/testfiles/valid/mtu.json b/libpod/network/netavark/testfiles/valid/mtu.json deleted file mode 100644 index 53fa4c9bc..000000000 --- a/libpod/network/netavark/testfiles/valid/mtu.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "mtu", - "id": "49be6e401e7f8b9844afb969dcbc96e78205ed86ec1e5a46150bd4ab4fdd5686", - "driver": "bridge", - "network_interface": "podman13", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "10.89.11.0/24", - "gateway": "10.89.11.1" - } - ], - "ipv6_enabled": false, - "internal": false, - "dns_enabled": true, - "options": { - "mtu": "1500" - }, - "ipam_options": { - "driver": "host-local" - } -} diff --git a/libpod/network/netavark/testfiles/valid/podman.json b/libpod/network/netavark/testfiles/valid/podman.json deleted file mode 100644 index 19acddc83..000000000 --- a/libpod/network/netavark/testfiles/valid/podman.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "podman", - "id": "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9", - "driver": "bridge", - "network_interface": "podman0", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "10.88.0.0/16", - "gateway": "10.88.0.1" - } - ], - "ipv6_enabled": false, - "internal": false, - "dns_enabled": false, - "ipam_options": { - "driver": "host-local" - } -} diff --git a/libpod/network/netavark/testfiles/valid/vlan.json b/libpod/network/netavark/testfiles/valid/vlan.json deleted file mode 100644 index 30c88ec49..000000000 --- a/libpod/network/netavark/testfiles/valid/vlan.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "vlan", - "id": "c3b258168c41c0bce97616716bef315eeed33eb1142904bfe7f32eb392c7cf80", - "driver": "bridge", - "network_interface": "podman14", - "created": "2021-10-06T18:50:54.25770461+02:00", - "subnets": [ - { - "subnet": "10.89.12.0/24", - "gateway": "10.89.12.1" - } - ], - "ipv6_enabled": false, - "internal": false, - "dns_enabled": true, - "options": { - "vlan": "5" - }, - "ipam_options": { - "driver": "host-local" - } -} diff --git a/libpod/network/types/network_test.go b/libpod/network/types/network_test.go deleted file mode 100644 index 91ee93692..000000000 --- a/libpod/network/types/network_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package types_test - -import ( - "encoding/json" - "reflect" - "testing" - - "github.com/containers/podman/v3/libpod/network/types" -) - -func TestUnmarshalMacAddress(t *testing.T) { - tests := []struct { - name string - json string - want types.HardwareAddr - wantErr bool - }{ - { - name: "mac as string with colon", - json: `"52:54:00:1c:2e:46"`, - want: types.HardwareAddr{0x52, 0x54, 0x00, 0x1c, 0x2e, 0x46}, - }, - { - name: "mac as string with dash", - json: `"52-54-00-1c-2e-46"`, - want: types.HardwareAddr{0x52, 0x54, 0x00, 0x1c, 0x2e, 0x46}, - }, - { - name: "mac as byte array", - json: `[82, 84, 0, 28, 46, 70]`, - want: types.HardwareAddr{0x52, 0x54, 0x00, 0x1c, 0x2e, 0x46}, - }, - { - name: "null value", - json: `null`, - want: nil, - }, - { - name: "mac as base64", - json: `"qrvM3e7/"`, - want: types.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, - }, - { - name: "invalid string", - json: `"52:54:00:1c:2e`, - wantErr: true, - }, - { - name: "invalid array", - json: `[82, 84, 0, 28, 46`, - wantErr: true, - }, - - { - name: "invalid value", - json: `ab`, - wantErr: true, - }, - { - name: "invalid object", - json: `{}`, - wantErr: true, - }, - } - for _, tt := range tests { - test := tt - t.Run(test.name, func(t *testing.T) { - mac := types.HardwareAddr{} - err := json.Unmarshal([]byte(test.json), &mac) - if (err != nil) != test.wantErr { - t.Errorf("types.HardwareAddress Unmarshal() error = %v, wantErr %v", err, test.wantErr) - return - } - if test.wantErr { - return - } - if !reflect.DeepEqual(mac, test.want) { - t.Errorf("types.HardwareAddress Unmarshal() got = %v, want %v", mac, test.want) - } - }) - } -} diff --git a/libpod/network/util/ip_test.go b/libpod/network/util/ip_test.go deleted file mode 100644 index 63ac555f0..000000000 --- a/libpod/network/util/ip_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package util - -import ( - "net" - "testing" -) - -func parseCIDR(n string) *net.IPNet { - _, parsedNet, _ := net.ParseCIDR(n) - return parsedNet -} - -func TestFirstIPInSubnet(t *testing.T) { - tests := []struct { - name string - args *net.IPNet - want net.IP - wantErr bool - }{ - {"class b", parseCIDR("192.168.0.0/16"), net.ParseIP("192.168.0.1"), false}, - {"class c", parseCIDR("192.168.1.0/24"), net.ParseIP("192.168.1.1"), false}, - {"cidr /23", parseCIDR("192.168.0.0/23"), net.ParseIP("192.168.0.1"), false}, - {"cidr /25", parseCIDR("192.168.1.0/25"), net.ParseIP("192.168.1.1"), false}, - {"cidr /26", parseCIDR("172.16.1.128/26"), net.ParseIP("172.16.1.129"), false}, - {"class a", parseCIDR("10.0.0.0/8"), net.ParseIP("10.0.0.1"), false}, - {"cidr /32", parseCIDR("192.168.255.4/32"), net.ParseIP("192.168.255.4"), false}, - {"cidr /31", parseCIDR("192.168.255.4/31"), net.ParseIP("192.168.255.5"), false}, - } - for _, tt := range tests { - test := tt - t.Run(test.name, func(t *testing.T) { - got, err := FirstIPInSubnet(test.args) - if (err != nil) != test.wantErr { - t.Errorf("FirstIPInSubnet() error = %v, wantErr %v", err, test.wantErr) - return - } - if !got.Equal(test.want) { - t.Errorf("FirstIPInSubnet() got = %v, want %v", got, test.want) - } - }) - } -} - -func TestLastIPInSubnet(t *testing.T) { - tests := []struct { - name string - args *net.IPNet - want net.IP - wantErr bool - }{ - {"class b", parseCIDR("192.168.0.0/16"), net.ParseIP("192.168.255.255"), false}, - {"class c", parseCIDR("192.168.1.0/24"), net.ParseIP("192.168.1.255"), false}, - {"cidr /23", parseCIDR("192.168.0.0/23"), net.ParseIP("192.168.1.255"), false}, - {"cidr /25", parseCIDR("192.168.1.0/25"), net.ParseIP("192.168.1.127"), false}, - {"cidr /26", parseCIDR("172.16.1.128/26"), net.ParseIP("172.16.1.191"), false}, - {"class a", parseCIDR("10.0.0.0/8"), net.ParseIP("10.255.255.255"), false}, - {"cidr /32", parseCIDR("192.168.255.4/32"), net.ParseIP("192.168.255.4"), false}, - {"cidr /31", parseCIDR("192.168.255.4/31"), net.ParseIP("192.168.255.5"), false}, - } - for _, tt := range tests { - test := tt - t.Run(test.name, func(t *testing.T) { - got, err := LastIPInSubnet(test.args) - if (err != nil) != test.wantErr { - t.Errorf("LastIPInSubnet() error = %v, wantErr %v", err, test.wantErr) - return - } - if !got.Equal(test.want) { - t.Errorf("LastIPInSubnet() got = %v, want %v", got, test.want) - } - }) - } -} diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index a931774f8..185f59306 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -19,9 +19,9 @@ import ( "time" "github.com/containernetworking/plugins/pkg/ns" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/errorhandling" "github.com/containers/podman/v3/pkg/namespaces" "github.com/containers/podman/v3/pkg/netns" diff --git a/libpod/networking_linux_test.go b/libpod/networking_linux_test.go index d925b69f7..f19f50a3c 100644 --- a/libpod/networking_linux_test.go +++ b/libpod/networking_linux_test.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/assert" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" ) func Test_ocicniPortsToNetTypesPorts(t *testing.T) { diff --git a/libpod/networking_machine.go b/libpod/networking_machine.go index 7cb2a00f7..ca759b893 100644 --- a/libpod/networking_machine.go +++ b/libpod/networking_machine.go @@ -12,7 +12,7 @@ import ( "strconv" "strings" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" "github.com/sirupsen/logrus" ) diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go index cc1b3cfdc..8b8bcf8c8 100644 --- a/libpod/networking_slirp4netns.go +++ b/libpod/networking_slirp4netns.go @@ -17,7 +17,7 @@ import ( "time" "github.com/containernetworking/plugins/pkg/ns" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/pkg/errorhandling" "github.com/containers/podman/v3/pkg/rootless" "github.com/containers/podman/v3/pkg/rootlessport" diff --git a/libpod/oci_util.go b/libpod/oci_util.go index 06d1dc652..de20c1915 100644 --- a/libpod/oci_util.go +++ b/libpod/oci_util.go @@ -8,8 +8,8 @@ import ( "strings" "time" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) diff --git a/libpod/options.go b/libpod/options.go index 44505da26..1137d228f 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -8,13 +8,13 @@ import ( "syscall" "github.com/containers/buildah/pkg/parse" + nettypes "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/secrets" "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" - nettypes "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/namespaces" "github.com/containers/podman/v3/pkg/rootless" "github.com/containers/podman/v3/pkg/specgen" diff --git a/libpod/runtime.go b/libpod/runtime.go index 9794b3605..5a86cc993 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -19,6 +19,8 @@ import ( "github.com/containers/buildah/pkg/parse" "github.com/containers/common/libimage" + "github.com/containers/common/libnetwork/network" + nettypes "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/secrets" @@ -28,9 +30,6 @@ import ( "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" "github.com/containers/podman/v3/libpod/lock" - "github.com/containers/podman/v3/libpod/network/cni" - "github.com/containers/podman/v3/libpod/network/netavark" - nettypes "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/libpod/plugin" "github.com/containers/podman/v3/libpod/shutdown" "github.com/containers/podman/v3/pkg/rootless" @@ -489,50 +488,16 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) { } } - var netInterface nettypes.ContainerNetwork - - switch runtime.config.Network.NetworkBackend { - case "", "cni": - netInterface, err = cni.NewCNINetworkInterface(cni.InitConfig{ - CNIConfigDir: runtime.config.Network.NetworkConfigDir, - CNIPluginDirs: runtime.config.Network.CNIPluginDirs, - DefaultNetwork: runtime.config.Network.DefaultNetwork, - DefaultSubnet: runtime.config.Network.DefaultSubnet, - IsMachine: runtime.config.Engine.MachineEnabled, - LockFile: filepath.Join(runtime.config.Network.NetworkConfigDir, "cni.lock"), - }) - if err != nil { - return errors.Wrapf(err, "could not create network interface") - } - if runtime.config.Network.NetworkBackend == "" { - // set backend to cni so that podman info can display it - runtime.config.Network.NetworkBackend = "cni" - } - - case "netavark": - netavarkBin, err := runtime.config.FindHelperBinary("netavark", false) + // the store is only setup when we are in the userns so we do the same for the network interface + if !needsUserns { + netBackend, netInterface, err := network.NetworkBackend(runtime.store, runtime.config, runtime.syslog) if err != nil { return err } - - netInterface, err = netavark.NewNetworkInterface(netavark.InitConfig{ - NetavarkBinary: netavarkBin, - NetworkConfigDir: filepath.Join(runtime.config.Engine.StaticDir, "networks"), - DefaultNetwork: runtime.config.Network.DefaultNetwork, - DefaultSubnet: runtime.config.Network.DefaultSubnet, - IsMachine: runtime.config.Engine.MachineEnabled, - LockFile: filepath.Join(runtime.config.Network.NetworkConfigDir, "netavark.lock"), - Syslog: runtime.syslog, - }) - if err != nil { - return errors.Wrapf(err, "could not create network interface") - } - default: - return errors.Errorf("unsupported network backend %q, check network_backend in containers.conf", runtime.config.Network.NetworkBackend) + runtime.config.Network.NetworkBackend = string(netBackend) + runtime.network = netInterface } - runtime.network = netInterface - // We now need to see if the system has restarted // We check for the presence of a file in our tmp directory to verify this // This check must be locked to prevent races diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 53ccb9139..a56c21e75 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -10,11 +10,11 @@ import ( "time" "github.com/containers/buildah" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/libpod/shutdown" "github.com/containers/podman/v3/pkg/domain/entities/reports" "github.com/containers/podman/v3/pkg/rootless" diff --git a/libpod/state.go b/libpod/state.go index 21525107f..471023769 100644 --- a/libpod/state.go +++ b/libpod/state.go @@ -1,6 +1,6 @@ package libpod -import "github.com/containers/podman/v3/libpod/network/types" +import "github.com/containers/common/libnetwork/types" // State is a storage backend for libpod's current state. // A State is only initialized once per instance of libpod. diff --git a/libpod/state_test.go b/libpod/state_test.go index b0793127d..0b805b0f1 100644 --- a/libpod/state_test.go +++ b/libpod/state_test.go @@ -8,10 +8,10 @@ import ( "testing" "time" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/lock" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/storage" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/libpod/util.go b/libpod/util.go index e89c6faaa..2cd9ccfdc 100644 --- a/libpod/util.go +++ b/libpod/util.go @@ -13,9 +13,9 @@ import ( "strings" "time" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/utils" "github.com/fsnotify/fsnotify" spec "github.com/opencontainers/runtime-spec/specs-go" diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go index db3af7d0b..3345a9cfe 100644 --- a/pkg/api/handlers/compat/networks.go +++ b/pkg/api/handlers/compat/networks.go @@ -6,10 +6,10 @@ import ( "net" "net/http" + nettypes "github.com/containers/common/libnetwork/types" + netutil "github.com/containers/common/libnetwork/util" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" - nettypes "github.com/containers/podman/v3/libpod/network/types" - netutil "github.com/containers/podman/v3/libpod/network/util" "github.com/containers/podman/v3/pkg/api/handlers/utils" api "github.com/containers/podman/v3/pkg/api/types" "github.com/containers/podman/v3/pkg/domain/entities" diff --git a/pkg/api/handlers/libpod/networks.go b/pkg/api/handlers/libpod/networks.go index a28c3c57c..d140ec07f 100644 --- a/pkg/api/handlers/libpod/networks.go +++ b/pkg/api/handlers/libpod/networks.go @@ -4,9 +4,9 @@ import ( "encoding/json" "net/http" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/api/handlers/utils" api "github.com/containers/podman/v3/pkg/api/types" "github.com/containers/podman/v3/pkg/domain/entities" diff --git a/pkg/api/handlers/libpod/swagger.go b/pkg/api/handlers/libpod/swagger.go index 8d7058b1e..db93d7ac6 100644 --- a/pkg/api/handlers/libpod/swagger.go +++ b/pkg/api/handlers/libpod/swagger.go @@ -4,9 +4,9 @@ import ( "net/http" "os" + "github.com/containers/common/libnetwork/types" "github.com/containers/image/v5/manifest" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/api/handlers/utils" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/pkg/errors" diff --git a/pkg/bindings/network/network.go b/pkg/bindings/network/network.go index 66e01a016..f3e7c3ef2 100644 --- a/pkg/bindings/network/network.go +++ b/pkg/bindings/network/network.go @@ -5,7 +5,7 @@ import ( "net/http" "strings" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/pkg/bindings" "github.com/containers/podman/v3/pkg/domain/entities" jsoniter "github.com/json-iterator/go" diff --git a/pkg/bindings/test/networks_test.go b/pkg/bindings/test/networks_test.go index d95862f6f..5924d865a 100644 --- a/pkg/bindings/test/networks_test.go +++ b/pkg/bindings/test/networks_test.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/pkg/bindings" "github.com/containers/podman/v3/pkg/bindings/containers" "github.com/containers/podman/v3/pkg/bindings/network" diff --git a/pkg/domain/entities/container_ps.go b/pkg/domain/entities/container_ps.go index d018d373f..d32a2eead 100644 --- a/pkg/domain/entities/container_ps.go +++ b/pkg/domain/entities/container_ps.go @@ -5,7 +5,7 @@ import ( "strings" "time" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/pkg/ps/define" "github.com/pkg/errors" ) diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index e3f8f1b7c..110265e59 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -6,9 +6,9 @@ import ( "os" "time" + nettypes "github.com/containers/common/libnetwork/types" "github.com/containers/image/v5/types" "github.com/containers/podman/v3/libpod/define" - nettypes "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/storage/pkg/archive" ) diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go index 7ce4dd0f6..962782fd8 100644 --- a/pkg/domain/entities/engine_container.go +++ b/pkg/domain/entities/engine_container.go @@ -4,9 +4,9 @@ import ( "context" "io" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/domain/entities/reports" "github.com/containers/podman/v3/pkg/specgen" ) diff --git a/pkg/domain/entities/network.go b/pkg/domain/entities/network.go index 34b89ae7d..79edc3227 100644 --- a/pkg/domain/entities/network.go +++ b/pkg/domain/entities/network.go @@ -3,7 +3,7 @@ package entities import ( "net" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" ) // NetworkListOptions describes options for listing networks in cli diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go index 0348c0af5..ec30b6f9a 100644 --- a/pkg/domain/entities/types.go +++ b/pkg/domain/entities/types.go @@ -4,9 +4,9 @@ import ( "net" buildahDefine "github.com/containers/buildah/define" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/storage/pkg/archive" ) diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index c7b12663c..196fd3656 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -3,9 +3,9 @@ package abi import ( "context" + "github.com/containers/common/libnetwork/types" + netutil "github.com/containers/common/libnetwork/util" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" - netutil "github.com/containers/podman/v3/libpod/network/util" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/util" "github.com/pkg/errors" diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index 40c31b163..25aae7019 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -13,11 +13,11 @@ import ( buildahDefine "github.com/containers/buildah/define" "github.com/containers/common/libimage" + nettypes "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/image/v5/types" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" - nettypes "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/autoupdate" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/specgen" diff --git a/pkg/domain/infra/tunnel/network.go b/pkg/domain/infra/tunnel/network.go index b5050345a..0f1430b1a 100644 --- a/pkg/domain/infra/tunnel/network.go +++ b/pkg/domain/infra/tunnel/network.go @@ -3,8 +3,8 @@ package tunnel import ( "context" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/bindings/network" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/errorhandling" diff --git a/pkg/rootlessport/rootlessport_linux.go b/pkg/rootlessport/rootlessport_linux.go index 7e6075789..b89a92d1e 100644 --- a/pkg/rootlessport/rootlessport_linux.go +++ b/pkg/rootlessport/rootlessport_linux.go @@ -12,7 +12,7 @@ package rootlessport import ( - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" ) const ( diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index b41ee8db0..b4f633f31 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -9,11 +9,11 @@ import ( "time" "github.com/containers/common/libimage" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/parse" "github.com/containers/common/pkg/secrets" "github.com/containers/image/v5/manifest" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" ann "github.com/containers/podman/v3/pkg/annotations" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/specgen" diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go index a2bc37e34..b04cf30f5 100644 --- a/pkg/specgen/generate/namespaces.go +++ b/pkg/specgen/generate/namespaces.go @@ -7,10 +7,10 @@ import ( "strings" "github.com/containers/common/libimage" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/rootless" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/util" diff --git a/pkg/specgen/generate/ports.go b/pkg/specgen/generate/ports.go index 34b43a62e..a1cc1cf68 100644 --- a/pkg/specgen/generate/ports.go +++ b/pkg/specgen/generate/ports.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/containers/common/libimage" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/utils" "github.com/containers/podman/v3/pkg/specgen" diff --git a/pkg/specgen/generate/ports_bench_test.go b/pkg/specgen/generate/ports_bench_test.go index 06f02acda..f208a34c5 100644 --- a/pkg/specgen/generate/ports_bench_test.go +++ b/pkg/specgen/generate/ports_bench_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" ) func benchmarkParsePortMapping(b *testing.B, ports []types.PortMapping) { diff --git a/pkg/specgen/generate/ports_test.go b/pkg/specgen/generate/ports_test.go index 20d5d0166..40ac3a290 100644 --- a/pkg/specgen/generate/ports_test.go +++ b/pkg/specgen/generate/ports_test.go @@ -3,7 +3,7 @@ package generate import ( "testing" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" "github.com/stretchr/testify/assert" ) diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go index 15a8ece17..baf6cbec9 100644 --- a/pkg/specgen/namespaces.go +++ b/pkg/specgen/namespaces.go @@ -6,9 +6,9 @@ import ( "os" "strings" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/cgroups" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/rootless" "github.com/containers/podman/v3/pkg/util" "github.com/containers/storage" diff --git a/pkg/specgen/namespaces_test.go b/pkg/specgen/namespaces_test.go index 4f69e6b98..bb2fdd4c6 100644 --- a/pkg/specgen/namespaces_test.go +++ b/pkg/specgen/namespaces_test.go @@ -4,7 +4,7 @@ import ( "net" "testing" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/pkg/rootless" "github.com/stretchr/testify/assert" ) diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go index fdaa714da..ec4c66595 100644 --- a/pkg/specgen/podspecgen.go +++ b/pkg/specgen/podspecgen.go @@ -3,7 +3,7 @@ package specgen import ( "net" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" spec "github.com/opencontainers/runtime-spec/specs-go" ) diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go index 6c1011a78..82721ba92 100644 --- a/pkg/specgen/specgen.go +++ b/pkg/specgen/specgen.go @@ -6,8 +6,8 @@ import ( "syscall" "github.com/containers/common/libimage" + nettypes "github.com/containers/common/libnetwork/types" "github.com/containers/image/v5/manifest" - nettypes "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/storage/types" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" diff --git a/pkg/specgenutil/util.go b/pkg/specgenutil/util.go index 6b564c60e..9389a98a5 100644 --- a/pkg/specgenutil/util.go +++ b/pkg/specgenutil/util.go @@ -7,8 +7,8 @@ import ( "strconv" "strings" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" - "github.com/containers/podman/v3/libpod/network/types" storageTypes "github.com/containers/storage/types" "github.com/pkg/errors" "github.com/sirupsen/logrus" diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index 936597f72..3d67650d2 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -177,7 +177,7 @@ t GET libpod/containers/myctr/json 200 \ .ResolvConfPath=$userdata_path/resolv.conf \ .HostnamePath=$userdata_path/hostname \ .HostsPath=$userdata_path/hosts \ - .NetworkSettings.SandboxKey~.*/netns/cni- \ + .NetworkSettings.SandboxKey~.*/netns/netns- \ .OCIConfigPath~.*config\.json \ .GraphDriver.Data.MergedDir~.*merged diff --git a/test/e2e/network_create_test.go b/test/e2e/network_create_test.go index c9e13e7d2..194510f32 100644 --- a/test/e2e/network_create_test.go +++ b/test/e2e/network_create_test.go @@ -5,7 +5,7 @@ import ( "net" "os" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" . "github.com/containers/podman/v3/test/utils" "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index 424561943..1c99d0f36 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -6,7 +6,7 @@ import ( "os" "time" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v3/pkg/rootless" . "github.com/containers/podman/v3/test/utils" "github.com/containers/storage/pkg/stringid" diff --git a/libpod/network/cni/README.md b/vendor/github.com/containers/common/libnetwork/cni/README.md index 6f57feff5..6f57feff5 100644 --- a/libpod/network/cni/README.md +++ b/vendor/github.com/containers/common/libnetwork/cni/README.md diff --git a/libpod/network/cni/cni_conversion.go b/vendor/github.com/containers/common/libnetwork/cni/cni_conversion.go index 788165b5e..dedb40ad3 100644 --- a/libpod/network/cni/cni_conversion.go +++ b/vendor/github.com/containers/common/libnetwork/cni/cni_conversion.go @@ -14,10 +14,10 @@ import ( "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" + internalutil "github.com/containers/common/libnetwork/internal/util" + "github.com/containers/common/libnetwork/types" + "github.com/containers/common/libnetwork/util" + pkgutil "github.com/containers/common/pkg/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -76,7 +76,7 @@ func createNetworkFromCNIConfigList(conf *libcni.NetworkConfigList, confPath str network.Options["vlan"] = strconv.Itoa(bridge.Vlan) } - err = convertIPAMConfToNetwork(&network, bridge.IPAM, confPath) + err = convertIPAMConfToNetwork(&network, &bridge.IPAM, confPath) if err != nil { return nil, err } @@ -98,7 +98,7 @@ func createNetworkFromCNIConfigList(conf *libcni.NetworkConfigList, confPath str network.Options["mode"] = vlan.Mode } - err = convertIPAMConfToNetwork(&network, vlan.IPAM, confPath) + err = convertIPAMConfToNetwork(&network, &vlan.IPAM, confPath) if err != nil { return nil, err } @@ -126,7 +126,7 @@ func findPluginByName(plugins []*libcni.NetworkConfig, name string) bool { // 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 { +func convertIPAMConfToNetwork(network *types.Network, ipam *ipamConfig, confPath string) error { if ipam.PluginType == types.DHCPIPAMDriver { network.IPAMOptions["driver"] = types.DHCPIPAMDriver return nil @@ -256,11 +256,11 @@ func (n *cniNetwork) createCNIConfigListFromNetwork(network *types.Network, writ case "mode": switch network.Driver { case types.MacVLANNetworkDriver: - if !pkgutil.StringInSlice(v, []string{"", "bridge", "private", "vepa", "passthru"}) { + if !pkgutil.StringInSlice(v, types.ValidMacVLANModes) { return nil, "", errors.Errorf("unknown macvlan mode %q", v) } case types.IPVLANNetworkDriver: - if !pkgutil.StringInSlice(v, []string{"", "l2", "l3", "l3s"}) { + if !pkgutil.StringInSlice(v, types.ValidIPVLANModes) { return nil, "", errors.Errorf("unknown ipvlan mode %q", v) } default: @@ -288,7 +288,7 @@ func (n *cniNetwork) createCNIConfigListFromNetwork(network *types.Network, writ switch network.Driver { case types.BridgeNetworkDriver: - bridge := newHostLocalBridge(network.NetworkInterface, isGateway, ipMasq, mtu, vlan, ipamConf) + 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 { @@ -297,10 +297,10 @@ func (n *cniNetwork) createCNIConfigListFromNetwork(network *types.Network, writ } case types.MacVLANNetworkDriver: - plugins = append(plugins, newVLANPlugin(types.MacVLANNetworkDriver, network.NetworkInterface, vlanPluginMode, mtu, ipamConf)) + 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)) + 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) diff --git a/libpod/network/cni/cni_exec.go b/vendor/github.com/containers/common/libnetwork/cni/cni_exec.go index ae857bcfb..c66e7ef5d 100644 --- a/libpod/network/cni/cni_exec.go +++ b/vendor/github.com/containers/common/libnetwork/cni/cni_exec.go @@ -30,7 +30,7 @@ import ( "github.com/containernetworking/cni/pkg/invoke" "github.com/containernetworking/cni/pkg/version" - "github.com/containers/podman/v3/pkg/rootless" + "github.com/containers/storage/pkg/unshare" ) type cniExec struct { @@ -75,7 +75,7 @@ func (e *cniExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData [ // 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() { + if !unshare.IsRootless() { c.Env = append(c.Env, "XDG_RUNTIME_DIR=") } @@ -87,7 +87,7 @@ func (e *cniExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData [ } // annotatePluginError parses the common cni plugin error json. -func annotatePluginError(err error, plugin string, stdout []byte, stderr []byte) error { +func annotatePluginError(err error, plugin string, stdout, stderr []byte) error { pluginName := filepath.Base(plugin) emsg := cniPluginError{ plugin: pluginName, diff --git a/libpod/network/cni/cni_types.go b/vendor/github.com/containers/common/libnetwork/cni/cni_types.go index e5eb777de..fbfcd49ad 100644 --- a/libpod/network/cni/cni_types.go +++ b/vendor/github.com/containers/common/libnetwork/cni/cni_types.go @@ -7,7 +7,7 @@ import ( "os" "path/filepath" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" ) const ( @@ -133,7 +133,7 @@ func newNcList(name, version string, labels, options map[string]string) ncList { } // newHostLocalBridge creates a new LocalBridge for host-local -func newHostLocalBridge(name string, isGateWay, ipMasq bool, mtu int, vlan int, ipamConf ipamConfig) *hostLocalBridge { +func newHostLocalBridge(name string, isGateWay, ipMasq bool, mtu, vlan int, ipamConf *ipamConfig) *hostLocalBridge { caps := make(map[string]bool) caps["ips"] = true bridge := hostLocalBridge{ @@ -144,7 +144,7 @@ func newHostLocalBridge(name string, isGateWay, ipMasq bool, mtu int, vlan int, MTU: mtu, HairpinMode: true, Vlan: vlan, - IPAM: ipamConf, + 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 { @@ -255,10 +255,10 @@ func hasDNSNamePlugin(paths []string) bool { } // newVLANPlugin creates a macvlanconfig with a given device name -func newVLANPlugin(pluginType, device, mode string, mtu int, ipam ipamConfig) VLANConfig { +func newVLANPlugin(pluginType, device, mode string, mtu int, ipam *ipamConfig) VLANConfig { m := VLANConfig{ PluginType: pluginType, - IPAM: ipam, + IPAM: *ipam, } if mtu > 0 { m.MTU = mtu diff --git a/libpod/network/cni/config.go b/vendor/github.com/containers/common/libnetwork/cni/config.go index 5d587da23..e34daa3c5 100644 --- a/libpod/network/cni/config.go +++ b/vendor/github.com/containers/common/libnetwork/cni/config.go @@ -6,10 +6,9 @@ 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" + internalutil "github.com/containers/common/libnetwork/internal/util" + "github.com/containers/common/libnetwork/types" + pkgutil "github.com/containers/common/pkg/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" @@ -17,6 +16,7 @@ import ( // NetworkCreate will take a partial filled Network and fill the // missing fields. It creates the Network and returns the full Network. +// nolint:gocritic func (n *cniNetwork) NetworkCreate(net types.Network) (types.Network, error) { n.lock.Lock() defer n.lock.Unlock() @@ -24,7 +24,7 @@ func (n *cniNetwork) NetworkCreate(net types.Network) (types.Network, error) { if err != nil { return types.Network{}, err } - network, err := n.networkCreate(net, false) + network, err := n.networkCreate(&net, false) if err != nil { return types.Network{}, err } @@ -35,7 +35,7 @@ func (n *cniNetwork) NetworkCreate(net types.Network) (types.Network, error) { // 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) { +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 @@ -44,10 +44,10 @@ func (n *cniNetwork) networkCreate(newNetwork types.Network, defaultNet bool) (* // 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") + return nil, errors.Wrap(types.ErrInvalidArg, "ID can not be set for network create") } - err := internalutil.CommonNetworkCreate(n, &newNetwork) + err := internalutil.CommonNetworkCreate(n, newNetwork) if err != nil { return nil, err } @@ -69,20 +69,20 @@ func (n *cniNetwork) networkCreate(newNetwork types.Network, defaultNet bool) (* switch newNetwork.Driver { case types.BridgeNetworkDriver: - err = internalutil.CreateBridge(n, &newNetwork, usedNetworks) + err = internalutil.CreateBridge(n, newNetwork, usedNetworks) if err != nil { return nil, err } case types.MacVLANNetworkDriver, types.IPVLANNetworkDriver: - err = createIPMACVLAN(&newNetwork) + err = createIPMACVLAN(newNetwork) if err != nil { return nil, err } default: - return nil, errors.Wrapf(define.ErrInvalidArg, "unsupported driver %s", newNetwork.Driver) + return nil, errors.Wrapf(types.ErrInvalidArg, "unsupported driver %s", newNetwork.Driver) } - err = internalutil.ValidateSubnets(&newNetwork, usedNetworks) + err = internalutil.ValidateSubnets(newNetwork, usedNetworks) if err != nil { return nil, err } @@ -96,11 +96,11 @@ func (n *cniNetwork) networkCreate(newNetwork types.Network, defaultNet bool) (* newNetwork.DNSEnabled = false } - cniConf, path, err := n.createCNIConfigListFromNetwork(&newNetwork, !defaultNet) + cniConf, path, err := n.createCNIConfigListFromNetwork(newNetwork, !defaultNet) if err != nil { return nil, err } - return &network{cniNet: cniConf, libpodNet: &newNetwork, filename: path}, nil + return &network{cniNet: cniConf, libpodNet: newNetwork, filename: path}, nil } // NetworkRemove will remove the Network with the given name or ID. @@ -196,7 +196,7 @@ func createIPMACVLAN(network *types.Network) error { return err } if !pkgutil.StringInSlice(network.NetworkInterface, interfaceNames) { - return errors.Errorf("parent interface %s does not exists", network.NetworkInterface) + return errors.Errorf("parent interface %s does not exist", network.NetworkInterface) } } if len(network.Subnets) == 0 { diff --git a/libpod/network/cni/network.go b/vendor/github.com/containers/common/libnetwork/cni/network.go index 41e3e414e..958227235 100644 --- a/libpod/network/cni/network.go +++ b/vendor/github.com/containers/common/libnetwork/cni/network.go @@ -7,12 +7,12 @@ import ( "crypto/sha256" "encoding/hex" "os" + "path/filepath" "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/common/libnetwork/types" "github.com/containers/storage/pkg/lockfile" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -64,16 +64,13 @@ type InitConfig struct { // 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) { +func NewCNINetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { // TODO: consider using a shared memory lock - lock, err := lockfile.GetLockfile(conf.LockFile) + lock, err := lockfile.GetLockfile(filepath.Join(conf.CNIConfigDir, "cni.lock")) if err != nil { return nil, err } @@ -112,6 +109,11 @@ func (n *cniNetwork) Drivers() []string { return []string{types.BridgeNetworkDriver, types.MacVLANNetworkDriver, types.IPVLANNetworkDriver} } +// DefaultNetworkName will return the default cni network name. +func (n *cniNetwork) DefaultNetworkName() string { + return n.defaultNetwork +} + func (n *cniNetwork) loadNetworks() error { // check the mod time of the config dir f, err := os.Stat(n.cniConfigDir) @@ -145,8 +147,8 @@ func (n *cniNetwork) loadNetworks() error { continue } - if !define.NameRegex.MatchString(conf.Name) { - logrus.Warnf("CNI config list %s has invalid name, skipping: %v", file, define.RegexError) + if !types.NameRegex.MatchString(conf.Name) { + logrus.Warnf("CNI config list %s has invalid name, skipping: %v", file, types.RegexError) continue } @@ -204,7 +206,7 @@ func (n *cniNetwork) createDefaultNetwork() (*network, error) { {Subnet: n.defaultSubnet}, }, } - return n.networkCreate(net, true) + return n.networkCreate(&net, true) } // getNetwork will lookup a network by name or ID. It returns an @@ -235,7 +237,7 @@ func (n *cniNetwork) getNetwork(nameOrID string) (*network, error) { if net != nil { return net, nil } - return nil, errors.Wrapf(define.ErrNoSuchNetwork, "unable to find network with name or ID %s", nameOrID) + return nil, errors.Wrapf(types.ErrNoSuchNetwork, "unable to find network with name or ID %s", nameOrID) } // getNetworkIDFromName creates a network ID from the name. It is just the diff --git a/libpod/network/cni/run.go b/vendor/github.com/containers/common/libnetwork/cni/run.go index d0ff49b73..af05d9d9d 100644 --- a/libpod/network/cni/run.go +++ b/vendor/github.com/containers/common/libnetwork/cni/run.go @@ -12,9 +12,8 @@ import ( 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/containers/common/libnetwork/internal/util" + "github.com/containers/common/libnetwork/types" "github.com/hashicorp/go-multierror" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -70,8 +69,9 @@ func (n *cniNetwork) Setup(namespacePath string, options types.SetupOptions) (ma results := make(map[string]types.StatusBlock, len(options.Networks)) for name, netOpts := range options.Networks { + netOpts := netOpts network := n.networks[name] - rt := getRuntimeConfig(namespacePath, options.ContainerName, options.ContainerID, name, ports, netOpts) + 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 @@ -158,7 +158,7 @@ func CNIResultToStatus(res cnitypes.Result) (types.StatusBlock, error) { return result, nil } -func getRuntimeConfig(netns, conName, conID, networkName string, ports []cniPortMapEntry, opts types.PerNetworkOptions) *libcni.RuntimeConf { +func getRuntimeConfig(netns, conName, conID, networkName string, ports []cniPortMapEntry, opts *types.PerNetworkOptions) *libcni.RuntimeConf { rt := &libcni.RuntimeConf{ ContainerID: conID, NetNS: netns, @@ -231,7 +231,8 @@ func (n *cniNetwork) teardown(namespacePath string, options types.TeardownOption var multiErr *multierror.Error for name, netOpts := range options.Networks { - rt := getRuntimeConfig(namespacePath, options.ContainerName, options.ContainerID, name, ports, netOpts) + netOpts := netOpts + rt := getRuntimeConfig(namespacePath, options.ContainerName, options.ContainerID, name, ports, &netOpts) cniConfList, newRt, err := getCachedNetworkConfig(n.cniConf, name, rt) if err == nil { @@ -240,7 +241,7 @@ func (n *cniNetwork) teardown(namespacePath string, options types.TeardownOption 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)) + multiErr = multierror.Append(multiErr, errors.Wrapf(types.ErrNoSuchNetwork, "network %s", name)) continue } cniConfList = network.cniNet diff --git a/libpod/network/internal/util/bridge.go b/vendor/github.com/containers/common/libnetwork/internal/util/bridge.go index 476557050..27ad0a4fb 100644 --- a/libpod/network/internal/util/bridge.go +++ b/vendor/github.com/containers/common/libnetwork/internal/util/bridge.go @@ -3,10 +3,9 @@ package util import ( "net" - "github.com/containers/podman/v3/libpod/define" - "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/containers/common/libnetwork/types" + "github.com/containers/common/libnetwork/util" + pkgutil "github.com/containers/common/pkg/util" "github.com/pkg/errors" ) @@ -16,8 +15,8 @@ func CreateBridge(n NetUtil, network *types.Network, usedNetworks []*net.IPNet) if pkgutil.StringInSlice(network.NetworkInterface, bridges) { return errors.Errorf("bridge name %s already in use", network.NetworkInterface) } - if !define.NameRegex.MatchString(network.NetworkInterface) { - return errors.Wrapf(define.RegexError, "bridge name %s invalid", network.NetworkInterface) + if !types.NameRegex.MatchString(network.NetworkInterface) { + return errors.Wrapf(types.RegexError, "bridge name %s invalid", network.NetworkInterface) } } else { var err error diff --git a/libpod/network/internal/util/create.go b/vendor/github.com/containers/common/libnetwork/internal/util/create.go index cecfd7133..ccb0f001a 100644 --- a/libpod/network/internal/util/create.go +++ b/vendor/github.com/containers/common/libnetwork/internal/util/create.go @@ -1,8 +1,7 @@ package util import ( - "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/types" "github.com/pkg/errors" ) @@ -21,11 +20,11 @@ func CommonNetworkCreate(n NetUtil, network *types.Network) error { var err error // validate the name when given if network.Name != "" { - if !define.NameRegex.MatchString(network.Name) { - return errors.Wrapf(define.RegexError, "network name %s invalid", network.Name) + if !types.NameRegex.MatchString(network.Name) { + return errors.Wrapf(types.RegexError, "network name %s invalid", network.Name) } if _, err := n.Network(network.Name); err == nil { - return errors.Wrapf(define.ErrNetworkExists, "network name %s already used", network.Name) + return errors.Wrapf(types.ErrNetworkExists, "network name %s already used", network.Name) } } else { name, err = GetFreeDeviceName(n) diff --git a/libpod/network/internal/util/interface.go b/vendor/github.com/containers/common/libnetwork/internal/util/interface.go index 4b01a09b8..650fcb193 100644 --- a/libpod/network/internal/util/interface.go +++ b/vendor/github.com/containers/common/libnetwork/internal/util/interface.go @@ -1,6 +1,6 @@ package util -import "github.com/containers/podman/v3/libpod/network/types" +import "github.com/containers/common/libnetwork/types" // This is a helper package to allow code sharing between the different // network interfaces. diff --git a/libpod/network/internal/util/interfaces.go b/vendor/github.com/containers/common/libnetwork/internal/util/interfaces.go index 20819f756..20819f756 100644 --- a/libpod/network/internal/util/interfaces.go +++ b/vendor/github.com/containers/common/libnetwork/internal/util/interfaces.go diff --git a/libpod/network/internal/util/ip.go b/vendor/github.com/containers/common/libnetwork/internal/util/ip.go index 7fe35d3d4..8f00a2a55 100644 --- a/libpod/network/internal/util/ip.go +++ b/vendor/github.com/containers/common/libnetwork/internal/util/ip.go @@ -60,7 +60,7 @@ func getRandomIPv6Subnet() (net.IPNet, error) { // read 8 random bytes _, err := rand.Read(ip) if err != nil { - return net.IPNet{}, nil + return net.IPNet{}, err } // first byte must be FD as per RFC3879 ip[0] = 0xfd diff --git a/libpod/network/internal/util/parse.go b/vendor/github.com/containers/common/libnetwork/internal/util/parse.go index 1f68df0bb..1f68df0bb 100644 --- a/libpod/network/internal/util/parse.go +++ b/vendor/github.com/containers/common/libnetwork/internal/util/parse.go diff --git a/libpod/network/internal/util/util.go b/vendor/github.com/containers/common/libnetwork/internal/util/util.go index d9b9a8dc0..8138d9fbc 100644 --- a/libpod/network/internal/util/util.go +++ b/vendor/github.com/containers/common/libnetwork/internal/util/util.go @@ -5,8 +5,8 @@ import ( "fmt" "net" - "github.com/containers/podman/v3/libpod/network/types" - "github.com/containers/podman/v3/pkg/util" + "github.com/containers/common/libnetwork/types" + "github.com/containers/common/pkg/util" "github.com/sirupsen/logrus" ) diff --git a/libpod/network/internal/util/validate.go b/vendor/github.com/containers/common/libnetwork/internal/util/validate.go index 62c3f3951..bfc5e2247 100644 --- a/libpod/network/internal/util/validate.go +++ b/vendor/github.com/containers/common/libnetwork/internal/util/validate.go @@ -3,8 +3,8 @@ package util import ( "net" - "github.com/containers/podman/v3/libpod/network/types" - "github.com/containers/podman/v3/libpod/network/util" + "github.com/containers/common/libnetwork/types" + "github.com/containers/common/libnetwork/util" "github.com/pkg/errors" ) @@ -23,24 +23,24 @@ func ValidateSubnet(s *types.Subnet, addGateway bool, usedNetworks []*net.IPNet) // Reparse to ensure subnet is valid. // Do not use types.ParseCIDR() because we want the ip to be // the network address and not a random ip in the subnet. - _, net, err := net.ParseCIDR(s.Subnet.String()) + _, n, err := net.ParseCIDR(s.Subnet.String()) if err != nil { return errors.Wrap(err, "subnet invalid") } // check that the new subnet does not conflict with existing ones - if NetworkIntersectsWithNetworks(net, usedNetworks) { - return errors.Errorf("subnet %s is already used on the host or by another config", net.String()) + if NetworkIntersectsWithNetworks(n, usedNetworks) { + return errors.Errorf("subnet %s is already used on the host or by another config", n.String()) } - s.Subnet = types.IPNet{IPNet: *net} + s.Subnet = types.IPNet{IPNet: *n} if s.Gateway != nil { if !s.Subnet.Contains(s.Gateway) { return errors.Errorf("gateway %s not in subnet %s", s.Gateway, &s.Subnet) } util.NormalizeIP(&s.Gateway) } else if addGateway { - ip, err := util.FirstIPInSubnet(net) + ip, err := util.FirstIPInSubnet(n) if err != nil { return err } @@ -91,11 +91,12 @@ func ValidateSetupOptions(n NetUtil, namespacePath string, options types.SetupOp return errors.New("must specify at least one network") } for name, netOpts := range options.Networks { + netOpts := netOpts network, err := n.Network(name) if err != nil { return err } - err = validatePerNetworkOpts(network, netOpts) + err = validatePerNetworkOpts(network, &netOpts) if err != nil { return err } @@ -104,18 +105,20 @@ func ValidateSetupOptions(n NetUtil, namespacePath string, options types.SetupOp } // validatePerNetworkOpts checks that all given static ips are in a subnet on this network -func validatePerNetworkOpts(network *types.Network, netOpts types.PerNetworkOptions) error { +func validatePerNetworkOpts(network *types.Network, netOpts *types.PerNetworkOptions) error { if netOpts.InterfaceName == "" { return errors.Errorf("interface name on network %s is empty", network.Name) } -outer: - for _, ip := range netOpts.StaticIPs { - for _, s := range network.Subnets { - if s.Subnet.Contains(ip) { - continue outer + if network.IPAMOptions["driver"] == types.HostLocalIPAMDriver { + outer: + for _, ip := range netOpts.StaticIPs { + for _, s := range network.Subnets { + if s.Subnet.Contains(ip) { + continue outer + } } + return errors.Errorf("requested static ip %s not in any subnet on network %s", ip.String(), network.Name) } - return errors.Errorf("requested static ip %s not in any subnet on network %s", ip.String(), network.Name) } return nil } diff --git a/libpod/network/netavark/config.go b/vendor/github.com/containers/common/libnetwork/netavark/config.go index 5cab76710..6d2daf299 100644 --- a/libpod/network/netavark/config.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/config.go @@ -9,15 +9,16 @@ import ( "path/filepath" "time" - "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" + internalutil "github.com/containers/common/libnetwork/internal/util" + "github.com/containers/common/libnetwork/types" + "github.com/containers/common/pkg/util" "github.com/containers/storage/pkg/stringid" "github.com/pkg/errors" ) // NetworkCreate will take a partial filled Network and fill the // missing fields. It creates the Network and returns the full Network. +// nolint:gocritic func (n *netavarkNetwork) NetworkCreate(net types.Network) (types.Network, error) { n.lock.Lock() defer n.lock.Unlock() @@ -25,7 +26,7 @@ func (n *netavarkNetwork) NetworkCreate(net types.Network) (types.Network, error if err != nil { return types.Network{}, err } - network, err := n.networkCreate(net, false) + network, err := n.networkCreate(&net, false) if err != nil { return types.Network{}, err } @@ -34,7 +35,7 @@ func (n *netavarkNetwork) NetworkCreate(net types.Network) (types.Network, error return *network, nil } -func (n *netavarkNetwork) networkCreate(newNetwork types.Network, defaultNet bool) (*types.Network, error) { +func (n *netavarkNetwork) networkCreate(newNetwork *types.Network, defaultNet bool) (*types.Network, error) { // if no driver is set use the default one if newNetwork.Driver == "" { newNetwork.Driver = types.DefaultNetworkDriver @@ -43,7 +44,7 @@ func (n *netavarkNetwork) networkCreate(newNetwork types.Network, defaultNet boo // 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") + return nil, errors.Wrap(types.ErrInvalidArg, "ID can not be set for network create") } // generate random network ID @@ -60,7 +61,7 @@ func (n *netavarkNetwork) networkCreate(newNetwork types.Network, defaultNet boo } } - err := internalutil.CommonNetworkCreate(n, &newNetwork) + err := internalutil.CommonNetworkCreate(n, newNetwork) if err != nil { return nil, err } @@ -82,7 +83,7 @@ func (n *netavarkNetwork) networkCreate(newNetwork types.Network, defaultNet boo switch newNetwork.Driver { case types.BridgeNetworkDriver: - err = internalutil.CreateBridge(n, &newNetwork, usedNetworks) + err = internalutil.CreateBridge(n, newNetwork, usedNetworks) if err != nil { return nil, err } @@ -102,15 +103,19 @@ func (n *netavarkNetwork) networkCreate(newNetwork types.Network, defaultNet boo } default: - return nil, errors.Errorf("unsupported network option %s", key) + return nil, errors.Errorf("unsupported bridge network option %s", key) } } - + case types.MacVLANNetworkDriver: + err = createMacvlan(newNetwork) + if err != nil { + return nil, err + } default: - return nil, errors.Wrapf(define.ErrInvalidArg, "unsupported driver %s", newNetwork.Driver) + return nil, errors.Wrapf(types.ErrInvalidArg, "unsupported driver %s", newNetwork.Driver) } - err = internalutil.ValidateSubnets(&newNetwork, usedNetworks) + err = internalutil.ValidateSubnets(newNetwork, usedNetworks) if err != nil { return nil, err } @@ -136,7 +141,44 @@ func (n *netavarkNetwork) networkCreate(newNetwork types.Network, defaultNet boo } } - return &newNetwork, nil + return newNetwork, nil +} + +func createMacvlan(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 !util.StringInSlice(network.NetworkInterface, interfaceNames) { + return errors.Errorf("parent interface %s does not exist", network.NetworkInterface) + } + } + if len(network.Subnets) == 0 { + return errors.Errorf("macvlan driver needs at least one subnet specified, DHCP is not supported with netavark") + } + network.IPAMOptions["driver"] = types.HostLocalIPAMDriver + + // validate the given options, we do not need them but just check to make sure they are valid + for key, value := range network.Options { + switch key { + case "mode": + if !util.StringInSlice(value, types.ValidMacVLANModes) { + return errors.Errorf("unknown macvlan mode %q", value) + } + case "mtu": + _, err := internalutil.ParseMTU(value) + if err != nil { + return err + } + default: + return errors.Errorf("unsupported macvlan network option %s", key) + } + } + return nil } // NetworkRemove will remove the Network with the given name or ID. diff --git a/libpod/network/netavark/const.go b/vendor/github.com/containers/common/libnetwork/netavark/const.go index 9709315c6..9709315c6 100644 --- a/libpod/network/netavark/const.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/const.go diff --git a/libpod/network/netavark/exec.go b/vendor/github.com/containers/common/libnetwork/netavark/exec.go index 01dea8489..69466a423 100644 --- a/libpod/network/netavark/exec.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/exec.go @@ -1,3 +1,5 @@ +// +build linux + package netavark import ( diff --git a/libpod/network/netavark/ipam.go b/vendor/github.com/containers/common/libnetwork/netavark/ipam.go index db46ee652..f99d099ca 100644 --- a/libpod/network/netavark/ipam.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/ipam.go @@ -1,3 +1,5 @@ +// +build linux + package netavark import ( @@ -5,8 +7,8 @@ import ( "fmt" "net" - "github.com/containers/podman/v3/libpod/network/types" - "github.com/containers/podman/v3/libpod/network/util" + "github.com/containers/common/libnetwork/types" + "github.com/containers/common/libnetwork/util" "github.com/pkg/errors" "go.etcd.io/bbolt" ) @@ -56,6 +58,8 @@ func newIPAMError(cause error, msg string, args ...interface{}) *ipamError { // openDB will open the ipam database // Note that the caller has to Close it. func (n *netavarkNetwork) openDB() (*bbolt.DB, error) { + // linter complains about the octal value + // nolint:gocritic db, err := bbolt.Open(n.ipamDBPath, 0600, nil) if err != nil { return nil, newIPAMError(err, "failed to open database %s", n.ipamDBPath) @@ -94,8 +98,8 @@ func (n *netavarkNetwork) allocIPs(opts *types.NetworkOptions) error { // requestIPs is the list of ips which should be used for this container requestIPs := make([]net.IP, 0, len(network.Subnets)) - for _, subnet := range network.Subnets { - subnetBkt, err := netBkt.CreateBucketIfNotExists([]byte(subnet.Subnet.String())) + for i := range network.Subnets { + subnetBkt, err := netBkt.CreateBucketIfNotExists([]byte(network.Subnets[i].Subnet.String())) if err != nil { return newIPAMError(err, "failed to create/get subnet bucket for network %s", netName) } @@ -104,7 +108,7 @@ func (n *netavarkNetwork) allocIPs(opts *types.NetworkOptions) error { // in this case the user wants this one and we should not assign a free one var ip net.IP for _, staticIP := range netOpts.StaticIPs { - if subnet.Subnet.Contains(staticIP) { + if network.Subnets[i].Subnet.Contains(staticIP) { ip = staticIP break } @@ -119,7 +123,7 @@ func (n *netavarkNetwork) allocIPs(opts *types.NetworkOptions) error { return newIPAMError(nil, "requested ip address %s is already allocated to container ID %s", ip.String(), string(id)) } } else { - ip, err = getFreeIPFromBucket(subnetBkt, subnet) + ip, err = getFreeIPFromBucket(subnetBkt, &network.Subnets[i]) if err != nil { return err } @@ -160,7 +164,7 @@ func (n *netavarkNetwork) allocIPs(opts *types.NetworkOptions) error { return err } -func getFreeIPFromBucket(bucket *bbolt.Bucket, subnet types.Subnet) (net.IP, error) { +func getFreeIPFromBucket(bucket *bbolt.Bucket, subnet *types.Subnet) (net.IP, error) { var rangeStart net.IP var rangeEnd net.IP if subnet.LeaseRange != nil { diff --git a/libpod/network/netavark/network.go b/vendor/github.com/containers/common/libnetwork/netavark/network.go index 540d8d6e5..ce252bc1d 100644 --- a/libpod/network/netavark/network.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/network.go @@ -10,10 +10,8 @@ import ( "strings" "time" - "github.com/containers/podman/v3/libpod/define" - "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/containers/common/libnetwork/internal/util" + "github.com/containers/common/libnetwork/types" "github.com/containers/storage/pkg/lockfile" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -34,9 +32,6 @@ type netavarkNetwork struct { // ipamDBPath is the path to the ip allocation bolt db ipamDBPath string - // isMachine describes whenever podman runs in a podman machine environment. - isMachine bool - // syslog describes whenever the netavark debbug output should be log to the syslog as well. // This will use logrus to do so, make sure logrus is set up to log to the syslog. syslog bool @@ -58,21 +53,14 @@ type InitConfig struct { // NetavarkBinary is the path to the netavark binary. NetavarkBinary string - // IPAMDBPath is the path to the ipam database. This should be on a tmpfs. - // If empty defaults to XDG_RUNTIME_DIR/netavark/ipam.db or /run/netavark/ipam.db as root. - IPAMDBPath string + // NetworkRunDir is where temporary files are stored, i.e.the ipam db. + NetworkRunDir 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 - // Syslog describes whenever the netavark debbug output should be log to the syslog as well. // This will use logrus to do so, make sure logrus is set up to log to the syslog. Syslog bool @@ -80,9 +68,9 @@ type InitConfig struct { // NewNetworkInterface creates the ContainerNetwork interface for the netavark backend. // Note: The networks are not loaded from disk until a method is called. -func NewNetworkInterface(conf InitConfig) (types.ContainerNetwork, error) { +func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { // TODO: consider using a shared memory lock - lock, err := lockfile.GetLockfile(conf.LockFile) + lock, err := lockfile.GetLockfile(filepath.Join(conf.NetworkConfigDir, "netavark.lock")) if err != nil { return nil, err } @@ -101,34 +89,20 @@ func NewNetworkInterface(conf InitConfig) (types.ContainerNetwork, error) { return nil, errors.Wrap(err, "failed to parse default subnet") } - ipamdbPath := conf.IPAMDBPath - if ipamdbPath == "" { - runDir, err := pkgutil.GetRuntimeDir() - if err != nil { - return nil, err - } - // as root runtimeDir is empty so use /run - if runDir == "" { - runDir = "/run" - } - ipamdbPath = filepath.Join(runDir, "netavark") - if err := os.MkdirAll(ipamdbPath, 0700); err != nil { - return nil, errors.Wrap(err, "failed to create ipam db path") - } - ipamdbPath = filepath.Join(ipamdbPath, "ipam.db") + if err := os.MkdirAll(conf.NetworkConfigDir, 0755); err != nil { + return nil, err } - if err := os.MkdirAll(conf.NetworkConfigDir, 0755); err != nil { + if err := os.MkdirAll(conf.NetworkRunDir, 0755); err != nil { return nil, err } n := &netavarkNetwork{ networkConfigDir: conf.NetworkConfigDir, netavarkBinary: conf.NetavarkBinary, - ipamDBPath: ipamdbPath, + ipamDBPath: filepath.Join(conf.NetworkRunDir, "ipam.db"), defaultNetwork: defaultNetworkName, defaultSubnet: defaultNet, - isMachine: conf.IsMachine, lock: lock, syslog: conf.Syslog, } @@ -139,7 +113,12 @@ func NewNetworkInterface(conf InitConfig) (types.ContainerNetwork, error) { // Drivers will return the list of supported network drivers // for this interface. func (n *netavarkNetwork) Drivers() []string { - return []string{types.BridgeNetworkDriver} + return []string{types.BridgeNetworkDriver, types.MacVLANNetworkDriver} +} + +// DefaultNetworkName will return the default netavark network name. +func (n *netavarkNetwork) DefaultNetworkName() string { + return n.defaultNetwork } func (n *netavarkNetwork) loadNetworks() error { @@ -195,8 +174,8 @@ func (n *netavarkNetwork) loadNetworks() error { continue } - if !define.NameRegex.MatchString(network.Name) { - logrus.Warnf("Network config %q has invalid name: %q, skipping: %v", path, network.Name, define.RegexError) + if !types.NameRegex.MatchString(network.Name) { + logrus.Warnf("Network config %q has invalid name: %q, skipping: %v", path, network.Name, types.RegexError) continue } @@ -252,7 +231,7 @@ func (n *netavarkNetwork) createDefaultNetwork() (*types.Network, error) { {Subnet: n.defaultSubnet}, }, } - return n.networkCreate(net, true) + return n.networkCreate(&net, true) } // getNetwork will lookup a network by name or ID. It returns an @@ -283,7 +262,7 @@ func (n *netavarkNetwork) getNetwork(nameOrID string) (*types.Network, error) { if net != nil { return net, nil } - return nil, errors.Wrapf(define.ErrNoSuchNetwork, "unable to find network with name or ID %s", nameOrID) + return nil, errors.Wrapf(types.ErrNoSuchNetwork, "unable to find network with name or ID %s", nameOrID) } // Implement the NetUtil interface for easy code sharing with other network interfaces. diff --git a/libpod/network/netavark/run.go b/vendor/github.com/containers/common/libnetwork/netavark/run.go index 0ac20daee..c6f2007e2 100644 --- a/libpod/network/netavark/run.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/run.go @@ -6,8 +6,8 @@ import ( "encoding/json" "fmt" - "github.com/containers/podman/v3/libpod/network/internal/util" - "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/common/libnetwork/internal/util" + "github.com/containers/common/libnetwork/types" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) diff --git a/vendor/github.com/containers/common/libnetwork/network/interface.go b/vendor/github.com/containers/common/libnetwork/network/interface.go new file mode 100644 index 000000000..190e6945b --- /dev/null +++ b/vendor/github.com/containers/common/libnetwork/network/interface.go @@ -0,0 +1,132 @@ +// +build linux + +package network + +import ( + "errors" + "fmt" + "io/ioutil" + "os" + "path/filepath" + + "github.com/containers/common/libnetwork/cni" + "github.com/containers/common/libnetwork/netavark" + "github.com/containers/common/libnetwork/types" + "github.com/containers/common/pkg/config" + "github.com/containers/storage" + "github.com/containers/storage/pkg/ioutils" + "github.com/sirupsen/logrus" +) + +const defaultNetworkBackendFileName = "defaultNetworkBackend" + +// NetworkBackend returns the network backend name and interface +// It returns either the CNI or netavark backend depending on what is set in the config. +// If the the backend is set to "" we will automatically assign the backend on the following conditions: +// 1. read ${graphroot}/defaultNetworkBackend +// 2. find netavark binary (if not installed use CNI) +// 3. check containers, images and CNI networks and if there are some we have an existing install and should continue to use CNI +func NetworkBackend(store storage.Store, conf *config.Config, syslog bool) (types.NetworkBackend, types.ContainerNetwork, error) { + backend := types.NetworkBackend(conf.Network.NetworkBackend) + if backend == "" { + var err error + backend, err = defaultNetworkBackend(store, conf) + if err != nil { + return "", nil, fmt.Errorf("failed to get default network backend: %w", err) + } + } + + switch backend { + case types.Netavark: + netavarkBin, err := conf.FindHelperBinary("netavark", false) + if err != nil { + return "", nil, err + } + netInt, err := netavark.NewNetworkInterface(&netavark.InitConfig{ + NetworkConfigDir: filepath.Join(store.GraphRoot(), "networks"), + NetworkRunDir: filepath.Join(store.RunRoot(), "networks"), + NetavarkBinary: netavarkBin, + DefaultNetwork: conf.Network.DefaultNetwork, + DefaultSubnet: conf.Network.DefaultSubnet, + Syslog: syslog, + }) + return types.Netavark, netInt, err + case types.CNI: + netInt, err := getCniInterface(conf) + return types.CNI, netInt, err + + default: + return "", nil, fmt.Errorf("unsupported network backend %q, check network_backend in containers.conf", backend) + } +} + +func defaultNetworkBackend(store storage.Store, conf *config.Config) (backend types.NetworkBackend, err error) { + // read defaultNetworkBackend file + file := filepath.Join(store.GraphRoot(), defaultNetworkBackendFileName) + b, err := ioutil.ReadFile(file) + if err == nil { + val := string(b) + if val == string(types.Netavark) { + return types.Netavark, nil + } + if val == string(types.CNI) { + return types.CNI, nil + } + return "", fmt.Errorf("unknown network backend value %q in %q", val, file) + } + // fail for all errors except ENOENT + if !errors.Is(err, os.ErrNotExist) { + return "", fmt.Errorf("could not read network backend value: %w", err) + } + + // cache the network backend to make sure always the same one will be used + defer func() { + // only write when there is no error + if err == nil { + // nolint:gocritic + if err := ioutils.AtomicWriteFile(file, []byte(backend), 0644); err != nil { + logrus.Errorf("could not write network backend to file: %v", err) + } + } + }() + + _, err = conf.FindHelperBinary("netavark", false) + if err != nil { + // if we cannot find netavark use CNI + return types.CNI, nil + } + + // now check if there are already containers, images and CNI networks (new install?) + cons, err := store.Containers() + if err != nil { + return "", err + } + if len(cons) == 0 { + imgs, err := store.Images() + if err != nil { + return "", err + } + if len(imgs) == 0 { + cniInterface, err := getCniInterface(conf) + if err == nil { + nets, err := cniInterface.NetworkList() + // there is always a default network so check <= 1 + if err == nil && len(nets) <= 1 { + // we have a fresh system so use netavark + return types.Netavark, nil + } + } + } + } + return types.CNI, nil +} + +func getCniInterface(conf *config.Config) (types.ContainerNetwork, error) { + return cni.NewCNINetworkInterface(&cni.InitConfig{ + CNIConfigDir: conf.Network.NetworkConfigDir, + CNIPluginDirs: conf.Network.CNIPluginDirs, + DefaultNetwork: conf.Network.DefaultNetwork, + DefaultSubnet: conf.Network.DefaultSubnet, + IsMachine: conf.Engine.MachineEnabled, + }) +} diff --git a/libpod/network/types/const.go b/vendor/github.com/containers/common/libnetwork/types/const.go index 916c6e6bf..b2d4a4538 100644 --- a/libpod/network/types/const.go +++ b/vendor/github.com/containers/common/libnetwork/types/const.go @@ -20,4 +20,28 @@ const ( DefaultNetworkName = "podman" // DefaultSubnet is the subnet that will be used for the default CNI network. DefaultSubnet = "10.88.0.0/16" + + // valid macvlan driver mode values + MacVLANModeBridge = "bridge" + MacVLANModePrivate = "private" + MacVLANModeVepa = "vepa" + MacVLANModePassthru = "passthru" + + // valid ipvlan driver modes + IPVLANModeL2 = "l2" + IPVLANModeL3 = "l3" + IPVLANModeL3s = "l3s" +) + +type NetworkBackend string + +const ( + CNI NetworkBackend = "cni" + Netavark NetworkBackend = "netavark" ) + +// ValidMacVLANModes is the list of valid mode options for the macvlan driver +var ValidMacVLANModes = []string{MacVLANModeBridge, MacVLANModePrivate, MacVLANModeVepa, MacVLANModePassthru} + +// ValidIPVLANModes is the list of valid mode options for the ipvlan driver +var ValidIPVLANModes = []string{IPVLANModeL2, IPVLANModeL3, IPVLANModeL3s} diff --git a/vendor/github.com/containers/common/libnetwork/types/define.go b/vendor/github.com/containers/common/libnetwork/types/define.go new file mode 100644 index 000000000..d37e529df --- /dev/null +++ b/vendor/github.com/containers/common/libnetwork/types/define.go @@ -0,0 +1,25 @@ +package types + +import ( + "regexp" + + "github.com/pkg/errors" +) + +var ( + // ErrNoSuchNetwork indicates the requested network does not exist + ErrNoSuchNetwork = errors.New("network not found") + + // ErrInvalidArg indicates that an invalid argument was passed + ErrInvalidArg = errors.New("invalid argument") + + // ErrNetworkExists indicates that a network with the given name already + // exists. + ErrNetworkExists = errors.New("network already exists") + + // NameRegex is a regular expression to validate names. + // This must NOT be changed. + NameRegex = regexp.MustCompile("^[a-zA-Z0-9][a-zA-Z0-9_.-]*$") + // RegexError is thrown in presence of an invalid name. + RegexError = errors.Wrapf(ErrInvalidArg, "names must match [a-zA-Z0-9][a-zA-Z0-9_.-]*") +) diff --git a/libpod/network/types/network.go b/vendor/github.com/containers/common/libnetwork/types/network.go index 37fa11461..de8655377 100644 --- a/libpod/network/types/network.go +++ b/vendor/github.com/containers/common/libnetwork/types/network.go @@ -28,6 +28,10 @@ type ContainerNetwork interface { // Drivers will return the list of supported network drivers // for this interface. Drivers() []string + + // DefaultNetworkName will return the default network name + // for this interface. + DefaultNetworkName() string } // Network describes the Network attributes. @@ -69,7 +73,7 @@ type IPNet struct { // ParseCIDR parse a string to IPNet func ParseCIDR(cidr string) (IPNet, error) { - ip, net, err := net.ParseCIDR(cidr) + ip, subnet, err := net.ParseCIDR(cidr) if err != nil { return IPNet{}, err } @@ -78,8 +82,8 @@ func ParseCIDR(cidr string) (IPNet, error) { if ipv4 != nil { ip = ipv4 } - net.IP = ip - return IPNet{*net}, err + subnet.IP = ip + return IPNet{*subnet}, err } func (n *IPNet) MarshalText() ([]byte, error) { @@ -87,11 +91,11 @@ func (n *IPNet) MarshalText() ([]byte, error) { } func (n *IPNet) UnmarshalText(text []byte) error { - net, err := ParseCIDR(string(text)) + subnet, err := ParseCIDR(string(text)) if err != nil { return err } - *n = net + *n = subnet return nil } @@ -106,8 +110,8 @@ func (h *HardwareAddr) String() string { return (*net.HardwareAddr)(h).String() } -func (h *HardwareAddr) MarshalText() ([]byte, error) { - return []byte((*net.HardwareAddr)(h).String()), nil +func (h HardwareAddr) MarshalText() ([]byte, error) { + return []byte(h.String()), nil } func (h *HardwareAddr) UnmarshalJSON(text []byte) error { @@ -253,7 +257,7 @@ type PortMapping struct { } // OCICNIPortMapping maps to the standard CNI portmapping Capability. -// Deprecated, do not use this struct for new fields. This only exists +// Deprecated: Do not use this struct for new fields. This only exists // for backwards compatibility. type OCICNIPortMapping struct { // HostPort is the port number on the host. diff --git a/libpod/network/util/filters.go b/vendor/github.com/containers/common/libnetwork/util/filters.go index c3c80b352..b27ca1f9a 100644 --- a/libpod/network/util/filters.go +++ b/vendor/github.com/containers/common/libnetwork/util/filters.go @@ -3,14 +3,15 @@ package util import ( "strings" - "github.com/containers/podman/v3/libpod/network/types" - "github.com/containers/podman/v3/pkg/util" + "github.com/containers/common/libnetwork/types" + "github.com/containers/common/pkg/filters" + "github.com/containers/common/pkg/util" "github.com/pkg/errors" ) -func GenerateNetworkFilters(filters map[string][]string) ([]types.FilterFunc, error) { - filterFuncs := make([]types.FilterFunc, 0, len(filters)) - for key, filterValues := range filters { +func GenerateNetworkFilters(f map[string][]string) ([]types.FilterFunc, error) { + filterFuncs := make([]types.FilterFunc, 0, len(f)) + for key, filterValues := range f { filterFunc, err := createFilterFuncs(key, filterValues) if err != nil { return nil, err @@ -45,9 +46,9 @@ func createFilterFuncs(key string, filterValues []string) (types.FilterFunc, err return createPruneFilterFuncs(key, filterValues) } -func GenerateNetworkPruneFilters(filters map[string][]string) ([]types.FilterFunc, error) { - filterFuncs := make([]types.FilterFunc, 0, len(filters)) - for key, filterValues := range filters { +func GenerateNetworkPruneFilters(f map[string][]string) ([]types.FilterFunc, error) { + filterFuncs := make([]types.FilterFunc, 0, len(f)) + for key, filterValues := range f { filterFunc, err := createPruneFilterFuncs(key, filterValues) if err != nil { return nil, err @@ -62,11 +63,11 @@ func createPruneFilterFuncs(key string, filterValues []string) (types.FilterFunc case "label": // matches all labels return func(net types.Network) bool { - return util.MatchLabelFilters(filterValues, net.Labels) + return filters.MatchLabelFilters(filterValues, net.Labels) }, nil case "until": - until, err := util.ComputeUntilTimestamp(filterValues) + until, err := filters.ComputeUntilTimestamp(filterValues) if err != nil { return nil, err } diff --git a/libpod/network/util/ip.go b/vendor/github.com/containers/common/libnetwork/util/ip.go index e82b4a781..7c315e312 100644 --- a/libpod/network/util/ip.go +++ b/vendor/github.com/containers/common/libnetwork/util/ip.go @@ -27,7 +27,7 @@ func LastIPInSubnet(addr *net.IPNet) (net.IP, error) { //nolint:interfacer return cidr.IP, nil } for i := range cidr.IP { - cidr.IP[i] = cidr.IP[i] | ^cidr.Mask[i] + cidr.IP[i] |= ^cidr.Mask[i] } return cidr.IP, nil } diff --git a/libpod/network/util/ip_calc.go b/vendor/github.com/containers/common/libnetwork/util/ip_calc.go index a27ddf78b..a27ddf78b 100644 --- a/libpod/network/util/ip_calc.go +++ b/vendor/github.com/containers/common/libnetwork/util/ip_calc.go diff --git a/vendor/modules.txt b/vendor/modules.txt index 54d49db42..a09984ec0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -110,6 +110,12 @@ github.com/containers/buildah/util ## explicit github.com/containers/common/libimage github.com/containers/common/libimage/manifests +github.com/containers/common/libnetwork/cni +github.com/containers/common/libnetwork/internal/util +github.com/containers/common/libnetwork/netavark +github.com/containers/common/libnetwork/network +github.com/containers/common/libnetwork/types +github.com/containers/common/libnetwork/util github.com/containers/common/pkg/apparmor github.com/containers/common/pkg/apparmor/internal/supported github.com/containers/common/pkg/auth |