Make network a slice to support multiple types

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-02-26 14:19:39 -08:00
parent 87e010b2e9
commit 4f6cdc6f08
7 changed files with 44 additions and 47 deletions

View file

@ -48,7 +48,7 @@ Sample `container.json` file:
"MAC_ADMIN", "MAC_ADMIN",
"NET_ADMIN" "NET_ADMIN"
], ],
"network": { "networks": [{
"type": "veth", "type": "veth",
"context": { "context": {
"bridge": "docker0", "bridge": "docker0",
@ -57,7 +57,8 @@ Sample `container.json` file:
"address": "172.17.0.100/16", "address": "172.17.0.100/16",
"gateway": "172.17.42.1", "gateway": "172.17.42.1",
"mtu": 1500 "mtu": 1500
}, }
],
"cgroups": { "cgroups": {
"name": "docker-koye", "name": "docker-koye",
"parent": "docker", "parent": "docker",

View file

@ -19,7 +19,7 @@ type Container struct {
Tty bool `json:"tty,omitempty"` // setup a proper tty or not Tty bool `json:"tty,omitempty"` // setup a proper tty or not
Namespaces Namespaces `json:"namespaces,omitempty"` // namespaces to apply Namespaces Namespaces `json:"namespaces,omitempty"` // namespaces to apply
Capabilities Capabilities `json:"capabilities,omitempty"` // capabilities to drop 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"` Cgroups *cgroups.Cgroup `json:"cgroups,omitempty"`
} }

View file

@ -31,7 +31,7 @@
"MAC_ADMIN", "MAC_ADMIN",
"NET_ADMIN" "NET_ADMIN"
], ],
"network": { "networks": [{
"type": "veth", "type": "veth",
"context": { "context": {
"bridge": "docker0", "bridge": "docker0",
@ -40,7 +40,8 @@
"address": "172.17.0.100/16", "address": "172.17.0.100/16",
"gateway": "172.17.42.1", "gateway": "172.17.42.1",
"mtu": 1500 "mtu": 1500
}, }
],
"cgroups": { "cgroups": {
"name": "docker-koye", "name": "docker-koye",
"parent": "docker", "parent": "docker",

View file

@ -16,7 +16,7 @@ var strategies = map[string]NetworkStrategy{
// NetworkStrategy represends a specific network configuration for // NetworkStrategy represends a specific network configuration for
// a containers networking stack // a containers networking stack
type NetworkStrategy interface { type NetworkStrategy interface {
Create(*libcontainer.Network, int) (libcontainer.Context, error) Create(*libcontainer.Network, int, libcontainer.Context) error
Initialize(*libcontainer.Network, libcontainer.Context) error Initialize(*libcontainer.Network, libcontainer.Context) error
} }

View file

@ -12,39 +12,37 @@ import (
type Veth struct { 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 ( var (
bridge string bridge string
prefix string prefix string
exists bool exists bool
) )
if bridge, exists = n.Context["bridge"]; !exists { 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 { 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) name1, name2, err := createVethPair(prefix)
if err != nil { if err != nil {
return nil, err return err
}
context := libcontainer.Context{
"vethHost": name1,
"vethChild": name2,
} }
context["veth-host"] = name1
context["veth-child"] = name2
if err := SetInterfaceMaster(name1, bridge); err != nil { if err := SetInterfaceMaster(name1, bridge); err != nil {
return context, err return err
} }
if err := SetMtu(name1, n.Mtu); err != nil { if err := SetMtu(name1, n.Mtu); err != nil {
return context, err return err
} }
if err := InterfaceUp(name1); err != nil { if err := InterfaceUp(name1); err != nil {
return context, err return err
} }
if err := SetInterfaceInNamespacePid(name2, nspid); err != nil { 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 { 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 vethChild string
exists bool 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") return fmt.Errorf("vethChild does not exist in network context")
} }
if err := InterfaceDown(vethChild); err != nil { if err := InterfaceDown(vethChild); err != nil {

View file

@ -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 { func (ns *linuxNs) InitializeNetworking(container *libcontainer.Container, nspid int, pipe *SyncPipe) error {
if container.Network != nil { context := libcontainer.Context{}
strategy, err := network.GetStrategy(container.Network.Type) for _, config := range container.Networks {
strategy, err := network.GetStrategy(config.Type)
if err != nil { if err != nil {
return err return err
} }
networkContext, err := strategy.Create(container.Network, nspid) if err := strategy.Create(config, nspid, context); err != nil {
if err != nil {
return err
}
if err := pipe.SendToChild(networkContext); err != nil {
return err return err
} }
} }
return nil return pipe.SendToChild(context)
} }

View file

@ -56,7 +56,7 @@ func (ns *linuxNs) Init(container *libcontainer.Container, uncleanRootfs, consol
if err := setupNewMountNamespace(rootfs, console, container.ReadonlyFs); err != nil { if err := setupNewMountNamespace(rootfs, console, container.ReadonlyFs); err != nil {
return fmt.Errorf("setup mount namespace %s", err) 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) return fmt.Errorf("setup networking %s", err)
} }
if err := system.Sethostname(container.Hostname); err != nil { 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 // 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 // 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 // setting the MTU and IP address along with the default gateway
func setupNetwork(config *libcontainer.Network, context libcontainer.Context) error { func setupNetwork(container *libcontainer.Container, context libcontainer.Context) error {
if config != nil { for _, config := range container.Networks {
strategy, err := network.GetStrategy(config.Type) strategy, err := network.GetStrategy(config.Type)
if err != nil { if err != nil {
return err return err