-
Notifications
You must be signed in to change notification settings - Fork 879
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #770 from runcom/fix-cross-compile
sandbox_externalkey.go: split for cross compilation
- Loading branch information
Showing
3 changed files
with
223 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} |
Oops, something went wrong.