Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sandbox_externalkey.go: split for cross compilation #770

Merged
merged 1 commit into from
Nov 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 1 addition & 174 deletions sandbox_externalkey.go
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 changes: 177 additions & 0 deletions sandbox_externalkey_unix.go
Original file line number Diff line number Diff line change
@@ -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()
}
Loading