Browse Source

sandbox_externalkey.go: split for cross compilation

runc/libcontainer split the `State` struct into platform specific structs
in
https://github.com/opencontainers/runc/commit/fe1cce69b31faee84a17abfabbac079adea53f06.
As a result, `NamespacePaths` isn't anymore in a global struct and
libnetwork is not cross-compiling in Docker (specifically on Windows) because
`sandbox_externalkey.go` is using `NamespacePaths`.
This patch splits `sandbox_externalkey.go` into platform specific
files and moves common things to a generic `sandbox_externalkey.go`.

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
Antonio Murdaca 9 years ago
parent
commit
ffbe62a8f7

+ 1 - 174
libnetwork/sandbox_externalkey.go

@@ -1,19 +1,6 @@
 package libnetwork
 
-import (
-	"encoding/json"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net"
-	"os"
-
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/pkg/reexec"
-	"github.com/docker/libnetwork/types"
-	"github.com/opencontainers/runc/libcontainer"
-	"github.com/opencontainers/runc/libcontainer/configs"
-)
+import "github.com/docker/docker/pkg/reexec"
 
 type setKeyData struct {
 	ContainerID string
@@ -23,163 +10,3 @@ type setKeyData struct {
 func init() {
 	reexec.Register("libnetwork-setkey", processSetKeyReexec)
 }
-
-const udsBase = "/var/lib/docker/network/files/"
-const success = "success"
-
-// processSetKeyReexec is a private function that must be called only on an reexec path
-// It expects 3 args { [0] = "libnetwork-setkey", [1] = <container-id>, [2] = <controller-id> }
-// It also expects libcontainer.State as a json string in <stdin>
-// Refer to https://github.com/opencontainers/runc/pull/160/ for more information
-func processSetKeyReexec() {
-	var err error
-
-	// Return a failure to the calling process via ExitCode
-	defer func() {
-		if err != nil {
-			logrus.Fatalf("%v", err)
-		}
-	}()
-
-	// expecting 3 args {[0]="libnetwork-setkey", [1]=<container-id>, [2]=<controller-id> }
-	if len(os.Args) < 3 {
-		err = fmt.Errorf("Re-exec expects 3 args, received : %d", len(os.Args))
-		return
-	}
-	containerID := os.Args[1]
-
-	// We expect libcontainer.State as a json string in <stdin>
-	stateBuf, err := ioutil.ReadAll(os.Stdin)
-	if err != nil {
-		return
-	}
-	var state libcontainer.State
-	if err = json.Unmarshal(stateBuf, &state); err != nil {
-		return
-	}
-
-	controllerID := os.Args[2]
-	key := state.NamespacePaths[configs.NamespaceType("NEWNET")]
-
-	err = SetExternalKey(controllerID, containerID, key)
-	return
-}
-
-// SetExternalKey provides a convenient way to set an External key to a sandbox
-func SetExternalKey(controllerID string, containerID string, key string) error {
-	keyData := setKeyData{
-		ContainerID: containerID,
-		Key:         key}
-
-	c, err := net.Dial("unix", udsBase+controllerID+".sock")
-	if err != nil {
-		return err
-	}
-	defer c.Close()
-
-	if err = sendKey(c, keyData); err != nil {
-		return fmt.Errorf("sendKey failed with : %v", err)
-	}
-	return processReturn(c)
-}
-
-func sendKey(c net.Conn, data setKeyData) error {
-	var err error
-	defer func() {
-		if err != nil {
-			c.Close()
-		}
-	}()
-
-	var b []byte
-	if b, err = json.Marshal(data); err != nil {
-		return err
-	}
-
-	_, err = c.Write(b)
-	return err
-}
-
-func processReturn(r io.Reader) error {
-	buf := make([]byte, 1024)
-	n, err := r.Read(buf[:])
-	if err != nil {
-		return fmt.Errorf("failed to read buf in processReturn : %v", err)
-	}
-	if string(buf[0:n]) != success {
-		return fmt.Errorf(string(buf[0:n]))
-	}
-	return nil
-}
-
-func (c *controller) startExternalKeyListener() error {
-	if err := os.MkdirAll(udsBase, 0600); err != nil {
-		return err
-	}
-	uds := udsBase + c.id + ".sock"
-	l, err := net.Listen("unix", uds)
-	if err != nil {
-		return err
-	}
-	if err := os.Chmod(uds, 0600); err != nil {
-		l.Close()
-		return err
-	}
-	c.Lock()
-	c.extKeyListener = l
-	c.Unlock()
-
-	go c.acceptClientConnections(uds, l)
-	return nil
-}
-
-func (c *controller) acceptClientConnections(sock string, l net.Listener) {
-	for {
-		conn, err := l.Accept()
-		if err != nil {
-			if _, err1 := os.Stat(sock); os.IsNotExist(err1) {
-				logrus.Debugf("Unix socket %s doesnt exist. cannot accept client connections", sock)
-				return
-			}
-			logrus.Errorf("Error accepting connection %v", err)
-			continue
-		}
-		go func() {
-			err := c.processExternalKey(conn)
-			ret := success
-			if err != nil {
-				ret = err.Error()
-			}
-
-			_, err = conn.Write([]byte(ret))
-			if err != nil {
-				logrus.Errorf("Error returning to the client %v", err)
-			}
-		}()
-	}
-}
-
-func (c *controller) processExternalKey(conn net.Conn) error {
-	buf := make([]byte, 1280)
-	nr, err := conn.Read(buf)
-	if err != nil {
-		return err
-	}
-	var s setKeyData
-	if err = json.Unmarshal(buf[0:nr], &s); err != nil {
-		return err
-	}
-
-	var sandbox Sandbox
-	search := SandboxContainerWalker(&sandbox, s.ContainerID)
-	c.WalkSandboxes(search)
-	if sandbox == nil {
-		return types.BadRequestErrorf("no sandbox present for %s", s.ContainerID)
-	}
-
-	return sandbox.SetKey(s.Key)
-}
-
-func (c *controller) stopExternalKeyListener() {
-	c.extKeyListener.Close()
-}

+ 177 - 0
libnetwork/sandbox_externalkey_unix.go

@@ -0,0 +1,177 @@
+// +build !windows
+
+package libnetwork
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net"
+	"os"
+
+	"github.com/Sirupsen/logrus"
+	"github.com/docker/libnetwork/types"
+	"github.com/opencontainers/runc/libcontainer"
+	"github.com/opencontainers/runc/libcontainer/configs"
+)
+
+const udsBase = "/var/lib/docker/network/files/"
+const success = "success"
+
+// processSetKeyReexec is a private function that must be called only on an reexec path
+// It expects 3 args { [0] = "libnetwork-setkey", [1] = <container-id>, [2] = <controller-id> }
+// It also expects libcontainer.State as a json string in <stdin>
+// Refer to https://github.com/opencontainers/runc/pull/160/ for more information
+func processSetKeyReexec() {
+	var err error
+
+	// Return a failure to the calling process via ExitCode
+	defer func() {
+		if err != nil {
+			logrus.Fatalf("%v", err)
+		}
+	}()
+
+	// expecting 3 args {[0]="libnetwork-setkey", [1]=<container-id>, [2]=<controller-id> }
+	if len(os.Args) < 3 {
+		err = fmt.Errorf("Re-exec expects 3 args, received : %d", len(os.Args))
+		return
+	}
+	containerID := os.Args[1]
+
+	// We expect libcontainer.State as a json string in <stdin>
+	stateBuf, err := ioutil.ReadAll(os.Stdin)
+	if err != nil {
+		return
+	}
+	var state libcontainer.State
+	if err = json.Unmarshal(stateBuf, &state); err != nil {
+		return
+	}
+
+	controllerID := os.Args[2]
+	key := state.NamespacePaths[configs.NamespaceType("NEWNET")]
+
+	err = SetExternalKey(controllerID, containerID, key)
+	return
+}
+
+// SetExternalKey provides a convenient way to set an External key to a sandbox
+func SetExternalKey(controllerID string, containerID string, key string) error {
+	keyData := setKeyData{
+		ContainerID: containerID,
+		Key:         key}
+
+	c, err := net.Dial("unix", udsBase+controllerID+".sock")
+	if err != nil {
+		return err
+	}
+	defer c.Close()
+
+	if err = sendKey(c, keyData); err != nil {
+		return fmt.Errorf("sendKey failed with : %v", err)
+	}
+	return processReturn(c)
+}
+
+func sendKey(c net.Conn, data setKeyData) error {
+	var err error
+	defer func() {
+		if err != nil {
+			c.Close()
+		}
+	}()
+
+	var b []byte
+	if b, err = json.Marshal(data); err != nil {
+		return err
+	}
+
+	_, err = c.Write(b)
+	return err
+}
+
+func processReturn(r io.Reader) error {
+	buf := make([]byte, 1024)
+	n, err := r.Read(buf[:])
+	if err != nil {
+		return fmt.Errorf("failed to read buf in processReturn : %v", err)
+	}
+	if string(buf[0:n]) != success {
+		return fmt.Errorf(string(buf[0:n]))
+	}
+	return nil
+}
+
+func (c *controller) startExternalKeyListener() error {
+	if err := os.MkdirAll(udsBase, 0600); err != nil {
+		return err
+	}
+	uds := udsBase + c.id + ".sock"
+	l, err := net.Listen("unix", uds)
+	if err != nil {
+		return err
+	}
+	if err := os.Chmod(uds, 0600); err != nil {
+		l.Close()
+		return err
+	}
+	c.Lock()
+	c.extKeyListener = l
+	c.Unlock()
+
+	go c.acceptClientConnections(uds, l)
+	return nil
+}
+
+func (c *controller) acceptClientConnections(sock string, l net.Listener) {
+	for {
+		conn, err := l.Accept()
+		if err != nil {
+			if _, err1 := os.Stat(sock); os.IsNotExist(err1) {
+				logrus.Debugf("Unix socket %s doesnt exist. cannot accept client connections", sock)
+				return
+			}
+			logrus.Errorf("Error accepting connection %v", err)
+			continue
+		}
+		go func() {
+			err := c.processExternalKey(conn)
+			ret := success
+			if err != nil {
+				ret = err.Error()
+			}
+
+			_, err = conn.Write([]byte(ret))
+			if err != nil {
+				logrus.Errorf("Error returning to the client %v", err)
+			}
+		}()
+	}
+}
+
+func (c *controller) processExternalKey(conn net.Conn) error {
+	buf := make([]byte, 1280)
+	nr, err := conn.Read(buf)
+	if err != nil {
+		return err
+	}
+	var s setKeyData
+	if err = json.Unmarshal(buf[0:nr], &s); err != nil {
+		return err
+	}
+
+	var sandbox Sandbox
+	search := SandboxContainerWalker(&sandbox, s.ContainerID)
+	c.WalkSandboxes(search)
+	if sandbox == nil {
+		return types.BadRequestErrorf("no sandbox present for %s", s.ContainerID)
+	}
+
+	return sandbox.SetKey(s.Key)
+}
+
+func (c *controller) stopExternalKeyListener() {
+	c.extKeyListener.Close()
+}

+ 45 - 0
libnetwork/sandbox_externalkey_windows.go

@@ -0,0 +1,45 @@
+// +build windows
+
+package libnetwork
+
+import (
+	"io"
+	"net"
+
+	"github.com/docker/libnetwork/types"
+)
+
+// processSetKeyReexec is a private function that must be called only on an reexec path
+// It expects 3 args { [0] = "libnetwork-setkey", [1] = <container-id>, [2] = <controller-id> }
+// It also expects libcontainer.State as a json string in <stdin>
+// Refer to https://github.com/opencontainers/runc/pull/160/ for more information
+func processSetKeyReexec() {
+}
+
+// SetExternalKey provides a convenient way to set an External key to a sandbox
+func SetExternalKey(controllerID string, containerID string, key string) error {
+	return types.NotImplementedErrorf("SetExternalKey isn't supported on non linux systems")
+}
+
+func sendKey(c net.Conn, data setKeyData) error {
+	return types.NotImplementedErrorf("sendKey isn't supported on non linux systems")
+}
+
+func processReturn(r io.Reader) error {
+	return types.NotImplementedErrorf("processReturn isn't supported on non linux systems")
+}
+
+// no-op on non linux systems
+func (c *controller) startExternalKeyListener() error {
+	return nil
+}
+
+func (c *controller) acceptClientConnections(sock string, l net.Listener) {
+}
+
+func (c *controller) processExternalKey(conn net.Conn) error {
+	return types.NotImplementedErrorf("processExternalKey isn't supported on non linux systems")
+}
+
+func (c *controller) stopExternalKeyListener() {
+}