Merge pull request #121 from mrjana/cnm_integ

Properly handle leave in libnetwork and bridge driver
This commit is contained in:
Madhu Venugopal
2015-05-05 18:30:29 -07:00
4 changed files with 86 additions and 8 deletions

View File

@@ -60,11 +60,12 @@ type ContainerConfiguration struct {
}
type bridgeEndpoint struct {
id types.UUID
intf *sandbox.Interface
macAddress net.HardwareAddr
config *EndpointConfiguration // User specified parameters
portMapping []netutils.PortBinding // Operation port bindings
id types.UUID
intf *sandbox.Interface
macAddress net.HardwareAddr
config *EndpointConfiguration // User specified parameters
containerConfig *ContainerConfiguration
portMapping []netutils.PortBinding // Operation port bindings
}
type bridgeNetwork struct {
@@ -643,6 +644,8 @@ func (d *driver) Leave(nid, eid types.UUID, options map[string]interface{}) erro
}
func (d *driver) link(nid, eid types.UUID, options map[string]interface{}, enable bool) error {
var cc *ContainerConfiguration
network, err := d.getNetwork(nid)
if err != nil {
return err
@@ -656,10 +659,15 @@ func (d *driver) link(nid, eid types.UUID, options map[string]interface{}, enabl
return EndpointNotFoundError(eid)
}
cc, err := parseContainerOptions(options)
if err != nil {
return err
if enable {
cc, err = parseContainerOptions(options)
if err != nil {
return err
}
} else {
cc = endpoint.containerConfig
}
if cc == nil {
return nil
}
@@ -725,6 +733,11 @@ func (d *driver) link(nid, eid types.UUID, options map[string]interface{}, enabl
l.Disable()
}
}
if enable {
endpoint.containerConfig = cc
}
return nil
}

View File

@@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/etchosts"
"github.com/docker/docker/pkg/resolvconf"
"github.com/docker/libnetwork/driverapi"
@@ -275,6 +276,18 @@ func (ep *endpoint) Leave(containerID string, options ...EndpointOption) error {
n := ep.network
err := n.driver.Leave(n.id, ep.id, ep.context)
sinfo := ep.SandboxInfo()
if sinfo != nil {
sb := ep.network.ctrlr.sandboxGet(ep.container.data.SandboxKey)
for _, i := range sinfo.Interfaces {
err = sb.RemoveInterface(i)
if err != nil {
logrus.Debugf("Remove interface failed: %v", err)
}
}
}
ep.network.ctrlr.sandboxRm(ep.container.data.SandboxKey)
ep.container = nil
ep.context = nil

View File

@@ -109,6 +109,54 @@ func loopbackUp() error {
return netlink.LinkSetUp(iface)
}
func (n *networkNamespace) RemoveInterface(i *Interface) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
origns, err := netns.Get()
if err != nil {
return err
}
defer origns.Close()
f, err := os.OpenFile(n.path, os.O_RDONLY, 0)
if err != nil {
return fmt.Errorf("failed get network namespace %q: %v", n.path, err)
}
defer f.Close()
nsFD := f.Fd()
if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
return err
}
defer netns.Set(origns)
// Find the network inteerface identified by the DstName attribute.
iface, err := netlink.LinkByName(i.DstName)
if err != nil {
return err
}
// Down the interface before configuring
if err := netlink.LinkSetDown(iface); err != nil {
return err
}
err = netlink.LinkSetName(iface, i.SrcName)
if err != nil {
fmt.Println("LinkSetName failed: ", err)
return err
}
// Move the network interface to init namespace.
if err := netlink.LinkSetNsPid(iface, 1); err != nil {
fmt.Println("LinkSetNsPid failed: ", err)
return err
}
return nil
}
func (n *networkNamespace) AddInterface(i *Interface) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()

View File

@@ -23,6 +23,10 @@ type Sandbox interface {
// interface according to the specified settings.
AddInterface(*Interface) error
// Remove an interface from the sandbox by renamin to original name
// and moving it out of the sandbox.
RemoveInterface(*Interface) error
// Set default IPv4 gateway for the sandbox
SetGateway(gw net.IP) error