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:
parent
1bedae9107
commit
be5538d8a8
3 changed files with 35 additions and 17 deletions
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue