diff --git a/.travis.yml b/.travis.yml index 40a13014..41df83b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: go sudo: required -dist: trusty +dist: xenial go: - 1.11.x diff --git a/pkg/testutils/netns_linux.go b/pkg/testutils/netns_linux.go index 6d56e405..f009bfb0 100644 --- a/pkg/testutils/netns_linux.go +++ b/pkg/testutils/netns_linux.go @@ -22,17 +22,36 @@ import ( "runtime" "strings" "sync" + "syscall" "github.com/containernetworking/plugins/pkg/ns" "golang.org/x/sys/unix" ) -const nsRunDir = "/var/run/netns" +func getNsRunDir() string { + xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR") + + /// If XDG_RUNTIME_DIR is set, check if the current user owns /var/run. If + // the owner is different, we are most likely running in a user namespace. + // In that case use $XDG_RUNTIME_DIR/netns as runtime dir. + if xdgRuntimeDir != "" { + if s, err := os.Stat("/var/run"); err == nil { + st, ok := s.Sys().(*syscall.Stat_t) + if ok && int(st.Uid) != os.Geteuid() { + return path.Join(xdgRuntimeDir, "netns") + } + } + } + + return "/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) { + nsRunDir := getNsRunDir() + b := make([]byte, 16) _, err := rand.Reader.Read(b) if err != nil { @@ -135,7 +154,7 @@ func NewNS() (ns.NetNS, error) { 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 strings.HasPrefix(nsPath, getNsRunDir()) { if err := unix.Unmount(nsPath, 0); err != nil { return fmt.Errorf("failed to unmount NS: at %s: %v", nsPath, err) } diff --git a/test_linux.sh b/test_linux.sh index 858534b3..d726ddb3 100755 --- a/test_linux.sh +++ b/test_linux.sh @@ -57,3 +57,7 @@ if [ -n "${vetRes}" ]; then echo -e "govet checking failed:\n${vetRes}" exit 255 fi + +# Run the pkg/ns tests as non root user +mkdir /tmp/cni-rootless +(export XDG_RUNTIME_DIR=/tmp/cni-rootless; cd pkg/ns/; unshare -rmn go test)