Allow containers to join the net namespace of other conatiners

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-03-21 00:48:17 +00:00
parent 1bedae9107
commit be5538d8a8
3 changed files with 35 additions and 17 deletions

View file

@ -14,13 +14,7 @@ type NetNS struct {
}
func (v *NetNS) Create(n *libcontainer.Network, nspid int, context libcontainer.Context) error {
nsname, exists := n.Context["nsname"]
if !exists {
return fmt.Errorf("nspath does not exist in network context")
}
context["nspath"] = fmt.Sprintf("/var/run/netns/%s", nsname)
context["nspath"] = n.Context["nspath"]
return nil
}
@ -29,12 +23,10 @@ func (v *NetNS) Initialize(config *libcontainer.Network, context libcontainer.Co
if !exists {
return fmt.Errorf("nspath does not exist in network context")
}
f, err := os.OpenFile(nspath, os.O_RDONLY, 0)
if err != nil {
return fmt.Errorf("failed get network namespace fd: %v", err)
}
if err := system.Setns(f.Fd(), syscall.CLONE_NEWNET); err != nil {
return fmt.Errorf("failed to setns current network namespace: %v", err)
}

View file

@ -6,12 +6,13 @@ import (
"github.com/dotcloud/docker/pkg/libcontainer"
"github.com/dotcloud/docker/runtime/execdriver"
"os"
"path/filepath"
"strings"
)
// createContainer populates and configures the container type with the
// data provided by the execdriver.Command
func createContainer(c *execdriver.Command) *libcontainer.Container {
func (d *driver) createContainer(c *execdriver.Command) *libcontainer.Container {
container := getDefaultTemplate()
container.Hostname = getEnv("HOSTNAME", c.Env)
@ -64,7 +65,7 @@ func createContainer(c *execdriver.Command) *libcontainer.Container {
container.Mounts = append(container.Mounts, libcontainer.Mount{m.Source, m.Destination, m.Writable, m.Private})
}
configureCustomOptions(container, c.Config["native"])
d.configureCustomOptions(container, c.Config["native"])
return container
}
@ -75,7 +76,8 @@ func createContainer(c *execdriver.Command) *libcontainer.Container {
// format: <key> <value>
// i.e: cap +MKNOD cap -NET_ADMIN
// i.e: cgroup devices.allow *:*
func configureCustomOptions(container *libcontainer.Container, opts []string) {
// i.e: net join <name>
func (d *driver) configureCustomOptions(container *libcontainer.Container, opts []string) {
for _, opt := range opts {
var (
parts = strings.Split(strings.TrimSpace(opt), " ")
@ -105,6 +107,26 @@ func configureCustomOptions(container *libcontainer.Container, opts []string) {
default:
// error
}
case "net":
switch strings.TrimSpace(parts[1]) {
case "join":
var (
id = strings.TrimSpace(parts[2])
cmd = d.activeContainers[id]
nspath = filepath.Join("/proc", fmt.Sprint(cmd.Process.Pid), "ns", "net")
)
container.Networks = append(container.Networks, &libcontainer.Network{
Type: "netns",
Context: libcontainer.Context{
"nspath": nspath,
},
})
default:
// error
}
default:
// error not defined
}
}
}

View file

@ -57,8 +57,9 @@ func init() {
}
type driver struct {
root string
initPath string
root string
initPath string
activeContainers map[string]*execdriver.Command
}
func NewDriver(root, initPath string) (*driver, error) {
@ -69,15 +70,18 @@ func NewDriver(root, initPath string) (*driver, error) {
return nil, err
}
return &driver{
root: root,
initPath: initPath,
root: root,
initPath: initPath,
activeContainers: make(map[string]*execdriver.Command),
}, nil
}
func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
d.activeContainers[c.ID] = c
var (
term nsinit.Terminal
container = createContainer(c)
container = d.createContainer(c)
factory = &dockerCommandFactory{c: c, driver: d}
stateWriter = &dockerStateWriter{
callback: startCallback,