Skip to content

Commit

Permalink
pkg/ocicni: a cross-platform namespace manager thing
Browse files Browse the repository at this point in the history
Signed-off-by: Vincent Batts <[email protected]>
  • Loading branch information
vbatts authored and Rajat Chopra committed Jun 28, 2018
1 parent 7374120 commit 84aa158
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 35 deletions.
11 changes: 5 additions & 6 deletions pkg/ocicni/ocicni.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"os"
"os/exec"
"sort"
"strings"
"sync"
Expand All @@ -21,7 +20,7 @@ type cniNetworkPlugin struct {
sync.RWMutex
defaultNetwork *cniNetwork

nsenterPath string
nsManager *nsManager
pluginDir string
cniDirs []string
vendorCNIDirPrefix string
Expand Down Expand Up @@ -170,11 +169,11 @@ func InitCNI(pluginDir string, cniDirs ...string) (CNIPlugin, error) {
pods: make(map[string]*podLock),
}

var err error
plugin.nsenterPath, err = exec.LookPath("nsenter")
nsm, err := newNSManager()
if err != nil {
return nil, err
}
plugin.nsManager = nsm

// Ensure plugin directory exists, because the following monitoring logic
// relies on that.
Expand Down Expand Up @@ -352,9 +351,9 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) (stri
plugin.podLock(podNetwork).Lock()
defer plugin.podUnlock(podNetwork)

ip, err := getContainerIP(plugin.nsenterPath, podNetwork.NetNS, DefaultInterfaceName, "-4")
ip, err := getContainerIP(plugin.nsManager, podNetwork.NetNS, DefaultInterfaceName, "-4")
if err != nil {
ip, err = getContainerIP(plugin.nsenterPath, podNetwork.NetNS, DefaultInterfaceName, "-6")
ip, err = getContainerIP(plugin.nsManager, podNetwork.NetNS, DefaultInterfaceName, "-6")
}
if err != nil {
return "", err
Expand Down
34 changes: 5 additions & 29 deletions pkg/ocicni/util.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,8 @@
package ocicni

import (
"fmt"
"net"
"os/exec"
"strings"
)

func getContainerIP(nsenterPath, netnsPath, interfaceName, addrType string) (net.IP, error) {
// Try to retrieve ip inside container network namespace
output, err := exec.Command(nsenterPath, fmt.Sprintf("--net=%s", netnsPath), "-F", "--",
"ip", "-o", addrType, "addr", "show", "dev", interfaceName, "scope", "global").CombinedOutput()
if err != nil {
return nil, fmt.Errorf("Unexpected command output %s with error: %v", output, err)
}

lines := strings.Split(string(output), "\n")
if len(lines) < 1 {
return nil, fmt.Errorf("Unexpected command output %s", output)
}
fields := strings.Fields(lines[0])
if len(fields) < 4 {
return nil, fmt.Errorf("Unexpected address output %s ", lines[0])
}
ip, _, err := net.ParseCIDR(fields[3])
if err != nil {
return nil, fmt.Errorf("CNI failed to parse ip from output %s due to %v", output, err)
}

return ip, nil
// newNSManager initializes a new namespace manager, which is a platform dependent struct.
func newNSManager() (*nsManager, error) {
nsm := &nsManager{}
err := nsm.init()
return nsm, err
}
46 changes: 46 additions & 0 deletions pkg/ocicni/util_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// +build linux

package ocicni

import (
"fmt"
"net"
"os/exec"
"strings"
)

var defaultNamespaceEnterCommandName = "nsenter"

type nsManager struct {
nsenterPath string
}

func (nsm *nsManager) init() error {
var err error
nsm.nsenterPath, err = exec.LookPath(defaultNamespaceEnterCommandName)
return err
}

func getContainerIP(nsm *nsManager, netnsPath, interfaceName, addrType string) (net.IP, error) {
// Try to retrieve ip inside container network namespace
output, err := exec.Command(nsm.nsenterPath, fmt.Sprintf("--net=%s", netnsPath), "-F", "--",
"ip", "-o", addrType, "addr", "show", "dev", interfaceName, "scope", "global").CombinedOutput()
if err != nil {
return nil, fmt.Errorf("Unexpected command output %s with error: %v", output, err)
}

lines := strings.Split(string(output), "\n")
if len(lines) < 1 {
return nil, fmt.Errorf("Unexpected command output %s", output)
}
fields := strings.Fields(lines[0])
if len(fields) < 4 {
return nil, fmt.Errorf("Unexpected address output %s ", lines[0])
}
ip, _, err := net.ParseCIDR(fields[3])
if err != nil {
return nil, fmt.Errorf("CNI failed to parse ip from output %s due to %v", output, err)
}

return ip, nil
}
19 changes: 19 additions & 0 deletions pkg/ocicni/util_unsupported.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// +build !linux

package ocicni

import (
"fmt"
"net"
)

type nsManager struct {
}

func (nsm *nsManager) init() error {
return nil
}

func getContainerIP(nsm *nsManager, netnsPath, interfaceName, addrType string) (net.IP, error) {
return nil, fmt.Errorf("not supported yet")
}

0 comments on commit 84aa158

Please sign in to comment.