diff --git a/README.md b/README.md index 36553af5..4c8da8e9 100644 --- a/README.md +++ b/README.md @@ -48,16 +48,17 @@ Sample `container.json` file: "MAC_ADMIN", "NET_ADMIN" ], - "network": { - "type": "veth", - "context": { - "bridge": "docker0", - "prefix": "dock" - }, - "address": "172.17.0.100/16", - "gateway": "172.17.42.1", - "mtu": 1500 - }, + "networks": [{ + "type": "veth", + "context": { + "bridge": "docker0", + "prefix": "dock" + }, + "address": "172.17.0.100/16", + "gateway": "172.17.42.1", + "mtu": 1500 + } + ], "cgroups": { "name": "docker-koye", "parent": "docker", diff --git a/container.go b/container.go index 4a479773..12a3d7ba 100644 --- a/container.go +++ b/container.go @@ -19,7 +19,7 @@ type Container struct { Tty bool `json:"tty,omitempty"` // setup a proper tty or not Namespaces Namespaces `json:"namespaces,omitempty"` // namespaces to apply Capabilities Capabilities `json:"capabilities,omitempty"` // capabilities to drop - Network *Network `json:"network,omitempty"` // nil for host's network stack + Networks []*Network `json:"networks,omitempty"` // nil for host's network stack Cgroups *cgroups.Cgroup `json:"cgroups,omitempty"` } diff --git a/container.json b/container.json index c2b21f86..83e40746 100644 --- a/container.json +++ b/container.json @@ -31,16 +31,17 @@ "MAC_ADMIN", "NET_ADMIN" ], - "network": { - "type": "veth", - "context": { - "bridge": "docker0", - "prefix": "dock" - }, - "address": "172.17.0.100/16", - "gateway": "172.17.42.1", - "mtu": 1500 - }, + "networks": [{ + "type": "veth", + "context": { + "bridge": "docker0", + "prefix": "dock" + }, + "address": "172.17.0.100/16", + "gateway": "172.17.42.1", + "mtu": 1500 + } + ], "cgroups": { "name": "docker-koye", "parent": "docker", diff --git a/network/strategy.go b/network/strategy.go index 8ecc11a2..a2f4f8f0 100644 --- a/network/strategy.go +++ b/network/strategy.go @@ -16,7 +16,7 @@ var strategies = map[string]NetworkStrategy{ // NetworkStrategy represends a specific network configuration for // a containers networking stack type NetworkStrategy interface { - Create(*libcontainer.Network, int) (libcontainer.Context, error) + Create(*libcontainer.Network, int, libcontainer.Context) error Initialize(*libcontainer.Network, libcontainer.Context) error } diff --git a/network/veth.go b/network/veth.go index 49e63f07..3ab1b239 100644 --- a/network/veth.go +++ b/network/veth.go @@ -12,39 +12,37 @@ import ( type Veth struct { } -func (v *Veth) Create(n *libcontainer.Network, nspid int) (libcontainer.Context, error) { +func (v *Veth) Create(n *libcontainer.Network, nspid int, context libcontainer.Context) error { var ( bridge string prefix string exists bool ) if bridge, exists = n.Context["bridge"]; !exists { - return nil, fmt.Errorf("bridge does not exist in network context") + return fmt.Errorf("bridge does not exist in network context") } if prefix, exists = n.Context["prefix"]; !exists { - return nil, fmt.Errorf("veth prefix does not exist in network context") + return fmt.Errorf("veth prefix does not exist in network context") } name1, name2, err := createVethPair(prefix) if err != nil { - return nil, err - } - context := libcontainer.Context{ - "vethHost": name1, - "vethChild": name2, + return err } + context["veth-host"] = name1 + context["veth-child"] = name2 if err := SetInterfaceMaster(name1, bridge); err != nil { - return context, err + return err } if err := SetMtu(name1, n.Mtu); err != nil { - return context, err + return err } if err := InterfaceUp(name1); err != nil { - return context, err + return err } if err := SetInterfaceInNamespacePid(name2, nspid); err != nil { - return context, err + return err } - return context, nil + return nil } func (v *Veth) Initialize(config *libcontainer.Network, context libcontainer.Context) error { @@ -52,7 +50,7 @@ func (v *Veth) Initialize(config *libcontainer.Network, context libcontainer.Con vethChild string exists bool ) - if vethChild, exists = context["vethChild"]; !exists { + if vethChild, exists = context["veth-child"]; !exists { return fmt.Errorf("vethChild does not exist in network context") } if err := InterfaceDown(vethChild); err != nil { diff --git a/nsinit/exec.go b/nsinit/exec.go index b13326ba..f7a9c17d 100644 --- a/nsinit/exec.go +++ b/nsinit/exec.go @@ -84,18 +84,15 @@ func (ns *linuxNs) SetupCgroups(container *libcontainer.Container, nspid int) er } func (ns *linuxNs) InitializeNetworking(container *libcontainer.Container, nspid int, pipe *SyncPipe) error { - if container.Network != nil { - strategy, err := network.GetStrategy(container.Network.Type) + context := libcontainer.Context{} + for _, config := range container.Networks { + strategy, err := network.GetStrategy(config.Type) if err != nil { return err } - networkContext, err := strategy.Create(container.Network, nspid) - if err != nil { - return err - } - if err := pipe.SendToChild(networkContext); err != nil { + if err := strategy.Create(config, nspid, context); err != nil { return err } } - return nil + return pipe.SendToChild(context) } diff --git a/nsinit/init.go b/nsinit/init.go index 1229560b..cfc50585 100644 --- a/nsinit/init.go +++ b/nsinit/init.go @@ -56,7 +56,7 @@ func (ns *linuxNs) Init(container *libcontainer.Container, uncleanRootfs, consol if err := setupNewMountNamespace(rootfs, console, container.ReadonlyFs); err != nil { return fmt.Errorf("setup mount namespace %s", err) } - if err := setupNetwork(container.Network, context); err != nil { + if err := setupNetwork(container, context); err != nil { return fmt.Errorf("setup networking %s", err) } if err := system.Sethostname(container.Hostname); err != nil { @@ -130,8 +130,8 @@ func dupSlave(slave *os.File) error { // setupVethNetwork uses the Network config if it is not nil to initialize // the new veth interface inside the container for use by changing the name to eth0 // setting the MTU and IP address along with the default gateway -func setupNetwork(config *libcontainer.Network, context libcontainer.Context) error { - if config != nil { +func setupNetwork(container *libcontainer.Container, context libcontainer.Context) error { + for _, config := range container.Networks { strategy, err := network.GetStrategy(config.Type) if err != nil { return err