Selaa lähdekoodia

Allow containers to join the net namespace of other conatiners
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)

Michael Crosby 11 vuotta sitten
vanhempi
commit
be5538d8a8

+ 1 - 9
pkg/libcontainer/network/netns.go

@@ -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)
 	}

+ 25 - 3
runtime/execdriver/native/default_template.go

@@ -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
 		}
 	}
 }

+ 9 - 5
runtime/execdriver/native/driver.go

@@ -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,