Skip to content
This repository was archived by the owner on Dec 13, 2018. It is now read-only.
Closed
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
3 changes: 3 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ type Config struct {
// Ipc specifies the container's ipc setup to be created
IpcNsPath string `json:"ipc,omitempty"`

// PidNS specifies the container's pid setup to be created
PidNsPath string `json:"pidns,omitempty"`

// Routes can be specified to create entries in the route table as the container is started
Routes []*Route `json:"routes,omitempty"`

Expand Down
119 changes: 119 additions & 0 deletions integration/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,122 @@ func TestRlimit(t *testing.T) {
t.Fatalf("expected rlimit to be 1024, got %s", limit)
}
}

func TestPIDNSPrivate(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/pid")
if err != nil {
t.Fatal(err)
}

config := newTemplateConfig(rootfs)
config.Namespaces["NEWPIDNS"] = true
buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/pid")
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("pid link should be private to the conatiner but equals host %q %q", actual, l)
}
}

func TestPIDNSHost(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/pid")
if err != nil {
t.Fatal(err)
}

config := newTemplateConfig(rootfs)
config.Namespaces["NEWPIDNS"] = false
buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/pid")
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("pid link not equal to host link %q %q", actual, l)
}
}

func TestPIDNSJoinPath(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/pid")
if err != nil {
t.Fatal(err)
}

config := newTemplateConfig(rootfs)
config.Namespaces["NEWPIDNS"] = false
config.PidNsPath = "/proc/1/ns/pid"

buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/pid")
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("pid link not equal to host link %q %q", actual, l)
}
}

func TestPIDNSBadPath(t *testing.T) {
if testing.Short() {
return
}

rootfs, err := newRootFs()
if err != nil {
t.Fatal(err)
}
defer remove(rootfs)

config := newTemplateConfig(rootfs)
config.Namespaces["NEWPIDNS"] = false
config.PidNsPath = "/proc/1/ns/pidc"

_, _, err = runContainer(config, "", "true")
if err == nil {
t.Fatal("container succeded with bad pid path")
}
}
4 changes: 4 additions & 0 deletions namespaces/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/docker/libcontainer/mount"
"github.com/docker/libcontainer/netlink"
"github.com/docker/libcontainer/network"
"github.com/docker/libcontainer/pidns"
"github.com/docker/libcontainer/security/capabilities"
"github.com/docker/libcontainer/security/restrict"
"github.com/docker/libcontainer/system"
Expand Down Expand Up @@ -82,6 +83,9 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, pip
if err := ipc.Initialize(container.IpcNsPath); err != nil {
return fmt.Errorf("setup IPC %s", err)
}
if err := pidns.Initialize(container.PidNsPath); err != nil {
return fmt.Errorf("setup PIDNS %s", err)
}
if err := setupNetwork(container, networkState); err != nil {
return fmt.Errorf("setup networking %s", err)
}
Expand Down
29 changes: 29 additions & 0 deletions pidns/pidns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package pidns

import (
"fmt"
"os"
"syscall"

"github.com/docker/libcontainer/system"
)

// Join the PID Namespace of specified pid 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 PID namespace fd: %v", err)
}

err = system.Setns(f.Fd(), syscall.CLONE_NEWPID)
f.Close()

if err != nil {
return fmt.Errorf("failed to setns current PID namespace: %v", err)
}
return nil
}