Refactores network Interface a bit to use NetworkState struct instead of a map for passing runtime information around.

Docker-DCO-1.1-Signed-off-by: Vishnu Kannan <vishnuk@google.com> (github: vishh)
This commit is contained in:
Vishnu Kannan 2014-06-25 22:51:28 +00:00
parent edf1e856a0
commit 98c2593cdc
9 changed files with 45 additions and 64 deletions

View File

@ -69,7 +69,8 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string
defer cleaner.Cleanup()
}
if err := InitializeNetworking(container, command.Process.Pid, syncPipe, dataPath); err != nil {
var networkState network.NetworkState
if err := InitializeNetworking(container, command.Process.Pid, syncPipe, &networkState); err != nil {
command.Process.Kill()
command.Wait()
return -1, err
@ -78,7 +79,7 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string
state := &libcontainer.State{
InitPid: command.Process.Pid,
InitStartTime: started,
NetworkState: *network.NetworkStateImpl.GetNetworkState(),
NetworkState: networkState,
}
if err := libcontainer.SaveState(dataPath, state); err != nil {
@ -157,18 +158,17 @@ func SetupCgroups(container *libcontainer.Config, nspid int) (cgroups.ActiveCgro
// InitializeNetworking creates the container's network stack outside of the namespace and moves
// interfaces into the container's net namespaces if necessary
func InitializeNetworking(container *libcontainer.Config, nspid int, pipe *SyncPipe, dataPath string) error {
context := map[string]string{}
func InitializeNetworking(container *libcontainer.Config, nspid int, pipe *SyncPipe, networkState *network.NetworkState) error {
for _, config := range container.Networks {
strategy, err := network.GetStrategy(config.Type)
if err != nil {
return err
}
if err := strategy.Create((*network.Network)(config), nspid, context, dataPath); err != nil {
if err := strategy.Create((*network.Network)(config), nspid, networkState); err != nil {
return err
}
}
return pipe.SendToChild(context)
return pipe.SendToChild(networkState)
}
// GetNamespaceFlags parses the container's Namespaces options to set the correct

View File

@ -40,7 +40,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn
}
// We always read this as it is a way to sync with the parent as well
context, err := syncPipe.ReadFromParent()
networkState, err := syncPipe.ReadFromParent()
if err != nil {
syncPipe.Close()
return err
@ -60,7 +60,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn
return fmt.Errorf("setctty %s", err)
}
}
if err := setupNetwork(container, context); err != nil {
if err := setupNetwork(container, networkState); err != nil {
return fmt.Errorf("setup networking %s", err)
}
if err := setupRoute(container); err != nil {
@ -165,14 +165,14 @@ func SetupUser(u string) 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(container *libcontainer.Config, context map[string]string) error {
func setupNetwork(container *libcontainer.Config, networkState *network.NetworkState) error {
for _, config := range container.Networks {
strategy, err := network.GetStrategy(config.Type)
if err != nil {
return err
}
err1 := strategy.Initialize((*network.Network)(config), context)
err1 := strategy.Initialize((*network.Network)(config), networkState)
if err1 != nil {
return err1
}

View File

@ -5,6 +5,8 @@ import (
"fmt"
"io/ioutil"
"os"
"github.com/docker/libcontainer/network"
)
// SyncPipe allows communication to and from the child processes
@ -43,8 +45,8 @@ func (s *SyncPipe) Parent() *os.File {
return s.parent
}
func (s *SyncPipe) SendToChild(context map[string]string) error {
data, err := json.Marshal(context)
func (s *SyncPipe) SendToChild(networkState *network.NetworkState) error {
data, err := json.Marshal(networkState)
if err != nil {
return err
}
@ -52,18 +54,18 @@ func (s *SyncPipe) SendToChild(context map[string]string) error {
return nil
}
func (s *SyncPipe) ReadFromParent() (map[string]string, error) {
func (s *SyncPipe) ReadFromParent() (*network.NetworkState, error) {
data, err := ioutil.ReadAll(s.child)
if err != nil {
return nil, fmt.Errorf("error reading from sync pipe %s", err)
}
var context map[string]string
var networkState *network.NetworkState
if len(data) > 0 {
if err := json.Unmarshal(data, &context); err != nil {
if err := json.Unmarshal(data, &networkState); err != nil {
return nil, err
}
}
return context, nil
return networkState, nil
}

View File

@ -10,11 +10,11 @@ import (
type Loopback struct {
}
func (l *Loopback) Create(n *Network, nspid int, context map[string]string, _ string) error {
func (l *Loopback) Create(n *Network, nspid int, networkState *NetworkState) error {
return nil
}
func (l *Loopback) Initialize(config *Network, context map[string]string) error {
func (l *Loopback) Initialize(config *Network, networkState *NetworkState) error {
if err := SetMtu("lo", config.Mtu); err != nil {
return fmt.Errorf("set lo mtu to %d %s", config.Mtu, err)
}

View File

@ -14,17 +14,16 @@ import (
type NetNS struct {
}
func (v *NetNS) Create(n *Network, nspid int, context map[string]string, _ string) error {
context["nspath"] = n.NsPath
func (v *NetNS) Create(n *Network, nspid int, networkState *NetworkState) error {
networkState.NsPath = n.NsPath
return nil
}
func (v *NetNS) Initialize(config *Network, context map[string]string) error {
nspath, exists := context["nspath"]
if !exists {
return fmt.Errorf("nspath does not exist in network context")
func (v *NetNS) Initialize(config *Network, networkState *NetworkState) error {
if networkState.NsPath == "" {
return fmt.Errorf("nspath does is not specified in NetworkState")
}
f, err := os.OpenFile(nspath, os.O_RDONLY, 0)
f, err := os.OpenFile(networkState.NsPath, os.O_RDONLY, 0)
if err != nil {
return fmt.Errorf("failed get network namespace fd: %v", err)
}

View File

@ -1,25 +0,0 @@
package network
// Struct describing the network specific runtime state that will be maintained by libcontainer for all running containers
// Do not depend on it outside of libcontainer.
type NetworkState struct {
// The name of the veth interface on the Host.
VethHost string `json:"veth_host,omitempty"`
// The name of the veth interface created inside the container for the child.
VethChild string `json:"veth_child,omitempty"`
}
type networkStateIntImpl struct{}
var (
networkState = &NetworkState{}
NetworkStateImpl = &networkStateIntImpl{}
)
func (networkStateIntImpl) GetNetworkState() *NetworkState {
return networkState
}
func (networkStateIntImpl) updateNetworkState(n *NetworkState) {
networkState = n
}

View File

@ -19,8 +19,8 @@ var strategies = map[string]NetworkStrategy{
// NetworkStrategy represents a specific network configuration for
// a container's networking stack
type NetworkStrategy interface {
Create(*Network, int, map[string]string, string) error
Initialize(*Network, map[string]string) error
Create(*Network, int, *NetworkState) error
Initialize(*Network, *NetworkState) error
}
// GetStrategy returns the specific network strategy for the

View File

@ -27,3 +27,14 @@ type Network struct {
// container's interfaces if a pair is created, specifically in the case of type veth
Mtu int `json:"mtu,omitempty"`
}
// Struct describing the network specific runtime state that will be maintained by libcontainer for all running containers
// Do not depend on it outside of libcontainer.
type NetworkState struct {
// The name of the veth interface on the Host.
VethHost string `json:"veth_host,omitempty"`
// The name of the veth interface created inside the container for the child.
VethChild string `json:"veth_child,omitempty"`
// Net namespace path.
NsPath string `json:"ns_path,omitempty"`
}

View File

@ -16,7 +16,7 @@ type Veth struct {
const defaultDevice = "eth0"
func (v *Veth) Create(n *Network, nspid int, context map[string]string, dataPath string) error {
func (v *Veth) Create(n *Network, nspid int, networkState *NetworkState) error {
var (
bridge = n.Bridge
prefix = n.VethPrefix
@ -31,8 +31,6 @@ func (v *Veth) Create(n *Network, nspid int, context map[string]string, dataPath
if err != nil {
return err
}
context["veth-host"] = name1
context["veth-child"] = name2
if err := SetInterfaceMaster(name1, bridge); err != nil {
return err
}
@ -45,20 +43,16 @@ func (v *Veth) Create(n *Network, nspid int, context map[string]string, dataPath
if err := SetInterfaceInNamespacePid(name2, nspid); err != nil {
return err
}
networkState := NetworkStateImpl.GetNetworkState()
networkState.VethHost = name1
networkState.VethChild = name2
NetworkStateImpl.updateNetworkState(networkState)
return nil
}
func (v *Veth) Initialize(config *Network, context map[string]string) error {
var (
vethChild string
exists bool
)
if vethChild, exists = context["veth-child"]; !exists {
return fmt.Errorf("vethChild does not exist in network context")
func (v *Veth) Initialize(config *Network, networkState *NetworkState) error {
var vethChild = networkState.VethChild
if vethChild == "" {
return fmt.Errorf("vethChild is not specified")
}
if err := InterfaceDown(vethChild); err != nil {
return fmt.Errorf("interface down %s %s", vethChild, err)