Merge pull request #131 from squeed/no-delete-ns
pkg/ns: remove namespace creation (and move to testutils)
This commit is contained in:
commit
e4f13535ab
@ -25,6 +25,7 @@ import (
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/ip"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
@ -58,10 +59,10 @@ var _ = Describe("Link", func() {
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
|
||||
hostNetNS, err = ns.NewNS()
|
||||
hostNetNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerNetNS, err = ns.NewNS()
|
||||
containerNetNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
fakeBytes := make([]byte, 20)
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/types/current"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
|
||||
"github.com/vishvananda/netlink"
|
||||
|
||||
@ -48,7 +49,7 @@ var _ = Describe("ConfigureIface", func() {
|
||||
BeforeEach(func() {
|
||||
// Create a new NetNS so we don't modify the host
|
||||
var err error
|
||||
originalNS, err = ns.NewNS()
|
||||
originalNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = originalNS.Do(func(ns.NetNS) error {
|
||||
|
@ -12,10 +12,6 @@ For example, you cannot rely on the `ns.Set()` namespace being the current names
|
||||
The `ns.Do()` method provides **partial** control over network namespaces for you by implementing these strategies. All code dependent on a particular network namespace (including the root namespace) should be wrapped in the `ns.Do()` method to ensure the correct namespace is selected for the duration of your code. For example:
|
||||
|
||||
```go
|
||||
targetNs, err := ns.NewNS()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = targetNs.Do(func(hostNs ns.NetNS) error {
|
||||
dummy := &netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
@ -26,11 +22,16 @@ err = targetNs.Do(func(hostNs ns.NetNS) error {
|
||||
})
|
||||
```
|
||||
|
||||
Note this requirement to wrap every network call is very onerous - any libraries you call might call out to network services such as DNS, and all such calls need to be protected after you call `ns.Do()`. The CNI plugins all exit very soon after calling `ns.Do()` which helps to minimize the problem.
|
||||
Note this requirement to wrap every network call is very onerous - any libraries you call might call out to network services such as DNS, and all such calls need to be protected after you call `ns.Do()`. All goroutines spawned from within the `ns.Do` will not inherit the new namespace. The CNI plugins all exit very soon after calling `ns.Do()` which helps to minimize the problem.
|
||||
|
||||
Also: If the runtime spawns a new OS thread, it will inherit the network namespace of the parent thread, which may have been temporarily switched, and thus the new OS thread will be permanently "stuck in the wrong namespace".
|
||||
When a new thread is spawned in Linux, it inherits the namepaces of its parent. In versions of go **prior to 1.10**, if the runtime spawns a new OS thread, it picks the parent randomly. If the chosen parent thread has been moved to a new namespace (even temporarily), the new OS thread will be permanently "stuck in the wrong namespace", and goroutines will non-deterministically switch namespaces as they are rescheduled.
|
||||
|
||||
In short, **there was no safe way to change network namespaces, even temporarily, from within a long-lived, multithreaded Go process**. If you wish to do this, you must use go 1.10 or greater.
|
||||
|
||||
|
||||
### Creating network namespaces
|
||||
Earlier versions of this library managed namespace creation, but as CNI does not actually utilize this feature (and it was essentialy unmaintained), it was removed. If you're writing a container runtime, you should implement namespace management yourself. However, there are some gotchas when doing so, especially around handling `/var/run/netns`. A reasonably correct reference implementation, borrowed from `rkt`, can be found in `pkg/testutils/netns_linux.go` if you're in need of a source of inspiration.
|
||||
|
||||
In short, **there is no safe way to change network namespaces from within a long-lived, multithreaded Go process**. If your daemon process needs to be namespace aware, consider spawning a separate process (like a CNI plugin) for each namespace.
|
||||
|
||||
### Further Reading
|
||||
- https://github.com/golang/go/wiki/LockOSThread
|
||||
|
@ -15,10 +15,8 @@
|
||||
package ns
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
@ -38,82 +36,6 @@ func getCurrentThreadNetNSPath() string {
|
||||
return fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid())
|
||||
}
|
||||
|
||||
// Creates a new persistent network namespace and returns an object
|
||||
// representing that namespace, without switching to it
|
||||
func NewNS() (NetNS, error) {
|
||||
const nsRunDir = "/var/run/netns"
|
||||
|
||||
b := make([]byte, 16)
|
||||
_, err := rand.Reader.Read(b)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate random netns name: %v", err)
|
||||
}
|
||||
|
||||
err = os.MkdirAll(nsRunDir, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// create an empty file at the mount point
|
||||
nsName := fmt.Sprintf("cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
|
||||
nsPath := path.Join(nsRunDir, nsName)
|
||||
mountPointFd, err := os.Create(nsPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mountPointFd.Close()
|
||||
|
||||
// Ensure the mount point is cleaned up on errors; if the namespace
|
||||
// was successfully mounted this will have no effect because the file
|
||||
// is in-use
|
||||
defer os.RemoveAll(nsPath)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
// do namespace work in a dedicated goroutine, so that we can safely
|
||||
// Lock/Unlock OSThread without upsetting the lock/unlock state of
|
||||
// the caller of this function
|
||||
var fd *os.File
|
||||
go (func() {
|
||||
defer wg.Done()
|
||||
runtime.LockOSThread()
|
||||
|
||||
var origNS NetNS
|
||||
origNS, err = GetNS(getCurrentThreadNetNSPath())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer origNS.Close()
|
||||
|
||||
// create a new netns on the current thread
|
||||
err = unix.Unshare(unix.CLONE_NEWNET)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer origNS.Set()
|
||||
|
||||
// bind mount the new netns from the current thread onto the mount point
|
||||
err = unix.Mount(getCurrentThreadNetNSPath(), nsPath, "none", unix.MS_BIND, "")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fd, err = os.Open(nsPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
})()
|
||||
wg.Wait()
|
||||
|
||||
if err != nil {
|
||||
unix.Unmount(nsPath, unix.MNT_DETACH)
|
||||
return nil, fmt.Errorf("failed to create namespace: %v", err)
|
||||
}
|
||||
|
||||
return &netNS{file: fd, mounted: true}, nil
|
||||
}
|
||||
|
||||
func (ns *netNS) Close() error {
|
||||
if err := ns.errorIfClosed(); err != nil {
|
||||
return err
|
||||
@ -124,16 +46,6 @@ func (ns *netNS) Close() error {
|
||||
}
|
||||
ns.closed = true
|
||||
|
||||
if ns.mounted {
|
||||
if err := unix.Unmount(ns.file.Name(), unix.MNT_DETACH); err != nil {
|
||||
return fmt.Errorf("Failed to unmount namespace %s: %v", ns.file.Name(), err)
|
||||
}
|
||||
if err := os.RemoveAll(ns.file.Name()); err != nil {
|
||||
return fmt.Errorf("Failed to clean up namespace %s: %v", ns.file.Name(), err)
|
||||
}
|
||||
ns.mounted = false
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -180,9 +92,8 @@ type NetNS interface {
|
||||
}
|
||||
|
||||
type netNS struct {
|
||||
file *os.File
|
||||
mounted bool
|
||||
closed bool
|
||||
file *os.File
|
||||
closed bool
|
||||
}
|
||||
|
||||
// netNS implements the NetNS interface
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"golang.org/x/sys/unix"
|
||||
@ -65,16 +66,19 @@ var _ = Describe("Linux namespace operations", func() {
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
|
||||
originalNetNS, err = ns.NewNS()
|
||||
originalNetNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
targetNetNS, err = ns.NewNS()
|
||||
targetNetNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
Expect(targetNetNS.Close()).To(Succeed())
|
||||
Expect(originalNetNS.Close()).To(Succeed())
|
||||
targetNetNS.Close()
|
||||
originalNetNS.Close()
|
||||
|
||||
Expect(testutils.UnmountNS(targetNetNS)).To(Succeed())
|
||||
Expect(testutils.UnmountNS(originalNetNS)).To(Succeed())
|
||||
})
|
||||
|
||||
It("executes the callback within the target network namespace", func() {
|
||||
@ -155,13 +159,14 @@ var _ = Describe("Linux namespace operations", func() {
|
||||
|
||||
It("should not leak a closed netns onto any threads in the process", func() {
|
||||
By("creating a new netns")
|
||||
createdNetNS, err := ns.NewNS()
|
||||
createdNetNS, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("discovering the inode of the created netns")
|
||||
createdNetNSInode, err := getInodeNS(createdNetNS)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
createdNetNS.Close()
|
||||
Expect(testutils.UnmountNS(createdNetNS)).NotTo(HaveOccurred())
|
||||
|
||||
By("comparing against the netns inode of every thread in the process")
|
||||
for _, netnsPath := range allNetNSInCurrentProcess() {
|
||||
@ -188,7 +193,8 @@ var _ = Describe("Linux namespace operations", func() {
|
||||
|
||||
Describe("closing a network namespace", func() {
|
||||
It("should prevent further operations", func() {
|
||||
createdNetNS, err := ns.NewNS()
|
||||
createdNetNS, err := testutils.NewNS()
|
||||
defer testutils.UnmountNS(createdNetNS)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = createdNetNS.Close()
|
||||
@ -202,8 +208,9 @@ var _ = Describe("Linux namespace operations", func() {
|
||||
})
|
||||
|
||||
It("should only work once", func() {
|
||||
createdNetNS, err := ns.NewNS()
|
||||
createdNetNS, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer testutils.UnmountNS(createdNetNS)
|
||||
|
||||
err = createdNetNS.Close()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@ -216,7 +223,8 @@ var _ = Describe("Linux namespace operations", func() {
|
||||
|
||||
Describe("IsNSorErr", func() {
|
||||
It("should detect a namespace", func() {
|
||||
createdNetNS, err := ns.NewNS()
|
||||
createdNetNS, err := testutils.NewNS()
|
||||
defer testutils.UnmountNS(createdNetNS)
|
||||
err = ns.IsNSorErr(createdNetNS.Path())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
157
pkg/testutils/netns_linux.go
Normal file
157
pkg/testutils/netns_linux.go
Normal file
@ -0,0 +1,157 @@
|
||||
// Copyright 2018 CNI authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testutils
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const nsRunDir = "/var/run/netns"
|
||||
|
||||
// Creates a new persistent (bind-mounted) network namespace and returns an object
|
||||
// representing that namespace, without switching to it.
|
||||
func NewNS() (ns.NetNS, error) {
|
||||
|
||||
b := make([]byte, 16)
|
||||
_, err := rand.Reader.Read(b)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate random netns name: %v", err)
|
||||
}
|
||||
|
||||
// Create the directory for mounting network namespaces
|
||||
// This needs to be a shared mountpoint in case it is mounted in to
|
||||
// other namespaces (containers)
|
||||
err = os.MkdirAll(nsRunDir, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Remount the namespace directory shared. This will fail if it is not
|
||||
// already a mountpoint, so bind-mount it on to itself to "upgrade" it
|
||||
// to a mountpoint.
|
||||
err = unix.Mount("", nsRunDir, "none", unix.MS_SHARED|unix.MS_REC, "")
|
||||
if err != nil {
|
||||
if err != unix.EINVAL {
|
||||
return nil, fmt.Errorf("mount --make-rshared %s failed: %q", nsRunDir, err)
|
||||
}
|
||||
|
||||
// Recursively remount /var/run/netns on itself. The recursive flag is
|
||||
// so that any existing netns bindmounts are carried over.
|
||||
err = unix.Mount(nsRunDir, nsRunDir, "none", unix.MS_BIND|unix.MS_REC, "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("mount --rbind %s %s failed: %q", nsRunDir, nsRunDir, err)
|
||||
}
|
||||
|
||||
// Now we can make it shared
|
||||
err = unix.Mount("", nsRunDir, "none", unix.MS_SHARED|unix.MS_REC, "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("mount --make-rshared %s failed: %q", nsRunDir, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nsName := fmt.Sprintf("cnitest-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
|
||||
|
||||
// create an empty file at the mount point
|
||||
nsPath := path.Join(nsRunDir, nsName)
|
||||
mountPointFd, err := os.Create(nsPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mountPointFd.Close()
|
||||
|
||||
// Ensure the mount point is cleaned up on errors; if the namespace
|
||||
// was successfully mounted this will have no effect because the file
|
||||
// is in-use
|
||||
defer os.RemoveAll(nsPath)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
// do namespace work in a dedicated goroutine, so that we can safely
|
||||
// Lock/Unlock OSThread without upsetting the lock/unlock state of
|
||||
// the caller of this function
|
||||
go (func() {
|
||||
defer wg.Done()
|
||||
runtime.LockOSThread()
|
||||
// Don't unlock. By not unlocking, golang will kill the OS thread when the
|
||||
// goroutine is done (for go1.10+)
|
||||
|
||||
var origNS ns.NetNS
|
||||
origNS, err = ns.GetNS(getCurrentThreadNetNSPath())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer origNS.Close()
|
||||
|
||||
// create a new netns on the current thread
|
||||
err = unix.Unshare(unix.CLONE_NEWNET)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Put this thread back to the orig ns, since it might get reused (pre go1.10)
|
||||
defer origNS.Set()
|
||||
|
||||
// bind mount the netns from the current thread (from /proc) onto the
|
||||
// mount point. This causes the namespace to persist, even when there
|
||||
// are no threads in the ns.
|
||||
err = unix.Mount(getCurrentThreadNetNSPath(), nsPath, "none", unix.MS_BIND, "")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to bind mount ns at %s: %v", nsPath, err)
|
||||
}
|
||||
})()
|
||||
wg.Wait()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create namespace: %v", err)
|
||||
}
|
||||
|
||||
return ns.GetNS(nsPath)
|
||||
}
|
||||
|
||||
// UnmountNS unmounts the NS held by the netns object
|
||||
func UnmountNS(ns ns.NetNS) error {
|
||||
nsPath := ns.Path()
|
||||
// Only unmount if it's been bind-mounted (don't touch namespaces in /proc...)
|
||||
if strings.HasPrefix(nsPath, nsRunDir) {
|
||||
if err := unix.Unmount(nsPath, 0); err != nil {
|
||||
return fmt.Errorf("failed to unmount NS: at %s: %v", nsPath, err)
|
||||
}
|
||||
|
||||
if err := os.Remove(nsPath); err != nil {
|
||||
return fmt.Errorf("failed to remove ns path %s: %v", nsPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getCurrentThreadNetNSPath copied from pkg/ns
|
||||
func getCurrentThreadNetNSPath() string {
|
||||
// /proc/self/ns/net returns the namespace of the main thread, not
|
||||
// of whatever thread this goroutine is running on. Make sure we
|
||||
// use the thread's net namespace since the thread is switching around
|
||||
return fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid())
|
||||
}
|
@ -120,10 +120,10 @@ var _ = Describe("DHCP Operations", func() {
|
||||
|
||||
// Create a new NetNS so we don't modify the host
|
||||
var err error
|
||||
originalNS, err = ns.NewNS()
|
||||
originalNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
targetNS, err = ns.NewNS()
|
||||
targetNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
serverIP := net.IPNet{
|
||||
|
@ -531,7 +531,7 @@ func cmdAddDelTest(testNS ns.NetNS, tc testCase) {
|
||||
// Get a Add/Del tester based on test case version
|
||||
tester := testerByVersion(tc.cniVersion)
|
||||
|
||||
targetNS, err := ns.NewNS()
|
||||
targetNS, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNS.Close()
|
||||
tester.setNS(testNS, targetNS)
|
||||
@ -552,7 +552,7 @@ var _ = Describe("bridge Operations", func() {
|
||||
BeforeEach(func() {
|
||||
// Create a new NetNS so we don't modify the host
|
||||
var err error
|
||||
originalNS, err = ns.NewNS()
|
||||
originalNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -693,7 +693,7 @@ var _ = Describe("bridge Operations", func() {
|
||||
}
|
||||
|
||||
tester := testerV03x{}
|
||||
targetNS, err := ns.NewNS()
|
||||
targetNS, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNS.Close()
|
||||
tester.setNS(originalNS, targetNS)
|
||||
|
@ -34,7 +34,7 @@ var _ = Describe("base functionality", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
originalNS, err = ns.NewNS()
|
||||
originalNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
ifname = fmt.Sprintf("dummy-%x", rand.Int31())
|
||||
@ -65,7 +65,7 @@ var _ = Describe("base functionality", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// call CmdAdd
|
||||
targetNS, err := ns.NewNS()
|
||||
targetNS, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
CNI_IFNAME := "eth0"
|
||||
|
@ -34,7 +34,7 @@ import (
|
||||
const MASTER_NAME = "eth0"
|
||||
|
||||
func ipvlanAddDelTest(conf, IFNAME string, originalNS ns.NetNS) {
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
@ -112,7 +112,7 @@ var _ = Describe("ipvlan Operations", func() {
|
||||
BeforeEach(func() {
|
||||
// Create a new NetNS so we don't modify the host
|
||||
var err error
|
||||
originalNS, err = ns.NewNS()
|
||||
originalNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = originalNS.Do(func(ns.NetNS) error {
|
||||
@ -149,7 +149,7 @@ var _ = Describe("ipvlan Operations", func() {
|
||||
}
|
||||
|
||||
// Create ipvlan in other namespace
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
@ -234,7 +234,7 @@ var _ = Describe("ipvlan Operations", func() {
|
||||
}
|
||||
}`, MASTER_NAME)
|
||||
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/onsi/gomega/gbytes"
|
||||
@ -39,7 +40,7 @@ var _ = Describe("Loopback", func() {
|
||||
command = exec.Command(pathToLoPlugin)
|
||||
|
||||
var err error
|
||||
networkNS, err = ns.NewNS()
|
||||
networkNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
environ = []string{
|
||||
|
@ -39,7 +39,7 @@ var _ = Describe("macvlan Operations", func() {
|
||||
BeforeEach(func() {
|
||||
// Create a new NetNS so we don't modify the host
|
||||
var err error
|
||||
originalNS, err = ns.NewNS()
|
||||
originalNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = originalNS.Do(func(ns.NetNS) error {
|
||||
@ -75,7 +75,7 @@ var _ = Describe("macvlan Operations", func() {
|
||||
MTU: 1500,
|
||||
}
|
||||
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
@ -114,7 +114,7 @@ var _ = Describe("macvlan Operations", func() {
|
||||
}
|
||||
}`, MASTER_NAME)
|
||||
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
@ -200,7 +200,7 @@ var _ = Describe("macvlan Operations", func() {
|
||||
}
|
||||
}`, MASTER_NAME)
|
||||
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
|
@ -35,7 +35,7 @@ var _ = Describe("ptp Operations", func() {
|
||||
BeforeEach(func() {
|
||||
// Create a new NetNS so we don't modify the host
|
||||
var err error
|
||||
originalNS, err = ns.NewNS()
|
||||
originalNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -46,7 +46,7 @@ var _ = Describe("ptp Operations", func() {
|
||||
doTest := func(conf string, numIPs int) {
|
||||
const IFNAME = "ptp0"
|
||||
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
@ -179,7 +179,7 @@ var _ = Describe("ptp Operations", func() {
|
||||
}
|
||||
}`
|
||||
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
|
@ -39,7 +39,7 @@ var _ = Describe("vlan Operations", func() {
|
||||
BeforeEach(func() {
|
||||
// Create a new NetNS so we don't modify the host
|
||||
var err error
|
||||
originalNS, err = ns.NewNS()
|
||||
originalNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = originalNS.Do(func(ns.NetNS) error {
|
||||
@ -78,7 +78,7 @@ var _ = Describe("vlan Operations", func() {
|
||||
}
|
||||
|
||||
// Create vlan in other namespace
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
@ -117,7 +117,7 @@ var _ = Describe("vlan Operations", func() {
|
||||
}
|
||||
|
||||
// Create vlan in other namespace
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
@ -163,7 +163,7 @@ var _ = Describe("vlan Operations", func() {
|
||||
}
|
||||
}`, MASTER_NAME)
|
||||
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
|
@ -52,10 +52,10 @@ var _ = Describe("bandwidth test", func() {
|
||||
hostIfname = "host-veth"
|
||||
containerIfname = "container-veth"
|
||||
|
||||
hostNs, err = ns.NewNS()
|
||||
hostNs, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerNs, err = ns.NewNS()
|
||||
containerNs, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
hostIP = net.IP{169, 254, 0, 1}
|
||||
@ -455,10 +455,10 @@ var _ = Describe("bandwidth test", func() {
|
||||
containerWithoutTbfIFName := "ptp1"
|
||||
|
||||
var err error
|
||||
containerWithTbfNS, err = ns.NewNS()
|
||||
containerWithTbfNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithoutTbfNS, err = ns.NewNS()
|
||||
containerWithoutTbfNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("create two containers, and use the bandwidth plugin on one of them")
|
||||
|
@ -37,7 +37,7 @@ var _ = Describe("Flannel", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
originalNS, err = ns.NewNS()
|
||||
originalNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -88,7 +88,7 @@ FLANNEL_IPMASQ=true
|
||||
It("uses dataDir for storing network configuration", func() {
|
||||
const IFNAME = "eth0"
|
||||
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"runtime"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
"github.com/coreos/go-iptables/iptables"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@ -40,7 +41,7 @@ var _ = Describe("chain tests", func() {
|
||||
currNs, err := ns.GetCurrentNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
testNs, err := ns.NewNS()
|
||||
testNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
tlChainName := fmt.Sprintf("cni-test-%d", rand.Intn(10000000))
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
"github.com/containernetworking/cni/libcni"
|
||||
"github.com/containernetworking/cni/pkg/types/current"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
"github.com/coreos/go-iptables/iptables"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@ -78,7 +79,7 @@ var _ = Describe("portmap integration tests", func() {
|
||||
dirs := filepath.SplitList(os.Getenv("PATH"))
|
||||
cniConf = &libcni.CNIConfig{Path: dirs}
|
||||
|
||||
targetNS, err = ns.NewNS()
|
||||
targetNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
fmt.Fprintln(GinkgoWriter, "namespace:", targetNS.Path())
|
||||
|
||||
|
@ -33,7 +33,7 @@ var _ = Describe("tuning plugin", func() {
|
||||
BeforeEach(func() {
|
||||
// Create a new NetNS so we don't modify the host
|
||||
var err error
|
||||
originalNS, err = ns.NewNS()
|
||||
originalNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = originalNS.Do(func(ns.NetNS) error {
|
||||
@ -79,7 +79,7 @@ var _ = Describe("tuning plugin", func() {
|
||||
}
|
||||
}`)
|
||||
|
||||
targetNs, err := ns.NewNS()
|
||||
targetNs, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer targetNs.Close()
|
||||
|
||||
|
@ -29,7 +29,7 @@ var _ = Describe("sample test", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
targetNs, err = ns.NewNS()
|
||||
targetNs, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user