Merge pull request #245 from crosbymichael/share-ipc
Allow IPC namespace to be shared between containers or with the host
This commit is contained in:
commit
f60d7b9195
4
Makefile
4
Makefile
|
@ -12,10 +12,10 @@ sh:
|
|||
GO_PACKAGES = $(shell find . -not \( -wholename ./vendor -prune -o -wholename ./.git -prune \) -name '*.go' -print0 | xargs -0n1 dirname | sort -u)
|
||||
|
||||
direct-test:
|
||||
go test -cover -v $(GO_PACKAGES)
|
||||
go test $(TEST_TAGS) -cover -v $(GO_PACKAGES)
|
||||
|
||||
direct-test-short:
|
||||
go test -cover -test.short -v $(GO_PACKAGES)
|
||||
go test $(TEST_TAGS) -cover -test.short -v $(GO_PACKAGES)
|
||||
|
||||
direct-build:
|
||||
go build -v $(GO_PACKAGES)
|
||||
|
|
|
@ -47,6 +47,9 @@ type Config struct {
|
|||
// Networks specifies the container's network setup to be created
|
||||
Networks []*Network `json:"networks,omitempty"`
|
||||
|
||||
// Ipc specifies the container's ipc setup to be created
|
||||
IpcNsPath string `json:"ipc,omitempty"`
|
||||
|
||||
// Routes can be specified to create entries in the route table as the container is started
|
||||
Routes []*Route `json:"routes,omitempty"`
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package integration
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
@ -36,3 +37,122 @@ func TestExecPS(t *testing.T) {
|
|||
t.Fatalf("expected output %q but received %q", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPCPrivate(t *testing.T) {
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
rootfs, err := newRootFs()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer remove(rootfs)
|
||||
|
||||
l, err := os.Readlink("/proc/1/ns/ipc")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
config := newTemplateConfig(rootfs)
|
||||
config.Namespaces["NEWIPC"] = true
|
||||
buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/ipc")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if exitCode != 0 {
|
||||
t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr)
|
||||
}
|
||||
|
||||
if actual := strings.Trim(buffers.Stdout.String(), "\n"); actual == l {
|
||||
t.Fatalf("ipc link should be private to the conatiner but equals host %q %q", actual, l)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPCHost(t *testing.T) {
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
rootfs, err := newRootFs()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer remove(rootfs)
|
||||
|
||||
l, err := os.Readlink("/proc/1/ns/ipc")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
config := newTemplateConfig(rootfs)
|
||||
config.Namespaces["NEWIPC"] = false
|
||||
buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/ipc")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if exitCode != 0 {
|
||||
t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr)
|
||||
}
|
||||
|
||||
if actual := strings.Trim(buffers.Stdout.String(), "\n"); actual != l {
|
||||
t.Fatalf("ipc link not equal to host link %q %q", actual, l)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPCJoinPath(t *testing.T) {
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
rootfs, err := newRootFs()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer remove(rootfs)
|
||||
|
||||
l, err := os.Readlink("/proc/1/ns/ipc")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
config := newTemplateConfig(rootfs)
|
||||
config.Namespaces["NEWIPC"] = false
|
||||
config.IpcNsPath = "/proc/1/ns/ipc"
|
||||
|
||||
buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/ipc")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if exitCode != 0 {
|
||||
t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr)
|
||||
}
|
||||
|
||||
if actual := strings.Trim(buffers.Stdout.String(), "\n"); actual != l {
|
||||
t.Fatalf("ipc link not equal to host link %q %q", actual, l)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPCBadPath(t *testing.T) {
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
rootfs, err := newRootFs()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer remove(rootfs)
|
||||
|
||||
config := newTemplateConfig(rootfs)
|
||||
config.Namespaces["NEWIPC"] = false
|
||||
config.IpcNsPath = "/proc/1/ns/ipcc"
|
||||
|
||||
_, _, err = runContainer(config, "", "true")
|
||||
if err == nil {
|
||||
t.Fatal("container succeded with bad ipc path")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package ipc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/libcontainer/system"
|
||||
)
|
||||
|
||||
// Join the IPC Namespace of specified ipc path if it exists.
|
||||
// If the path does not exist then you are not joining a container.
|
||||
func Initialize(nsPath string) error {
|
||||
if nsPath == "" {
|
||||
return nil
|
||||
}
|
||||
f, err := os.OpenFile(nsPath, os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed get IPC namespace fd: %v", err)
|
||||
}
|
||||
|
||||
err = system.Setns(f.Fd(), syscall.CLONE_NEWIPC)
|
||||
f.Close()
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to setns current IPC namespace: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/docker/libcontainer"
|
||||
"github.com/docker/libcontainer/apparmor"
|
||||
"github.com/docker/libcontainer/console"
|
||||
"github.com/docker/libcontainer/ipc"
|
||||
"github.com/docker/libcontainer/label"
|
||||
"github.com/docker/libcontainer/mount"
|
||||
"github.com/docker/libcontainer/netlink"
|
||||
|
@ -66,6 +67,9 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn
|
|||
return fmt.Errorf("setctty %s", err)
|
||||
}
|
||||
}
|
||||
if err := ipc.Initialize(container.IpcNsPath); err != nil {
|
||||
return fmt.Errorf("setup IPC %s", err)
|
||||
}
|
||||
if err := setupNetwork(container, networkState); err != nil {
|
||||
return fmt.Errorf("setup networking %s", err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue