Docker side changes for the newly introduced IPAM driver

* Made use of IPAM driver primitives for legacy IP configurations
* Replaced custom Generics with backend labels

Signed-off-by: Madhu Venugopal <madhu@docker.com>
This commit is contained in:
Madhu Venugopal 2015-10-10 09:43:03 -07:00
parent 2e3113aeef
commit 0f351ce364
6 changed files with 85 additions and 58 deletions

View file

@ -204,12 +204,12 @@ func buildEndpointResource(e libnetwork.Endpoint) types.EndpointResource {
if mac := iface.MacAddress(); mac != nil {
er.MacAddress = mac.String()
}
if ip := iface.Address(); len(ip.IP) > 0 {
er.IPv4Address = (&ip).String()
if ip := iface.Address(); ip != nil && len(ip.IP) > 0 {
er.IPv4Address = ip.String()
}
if ipv6 := iface.AddressIPv6(); len(ipv6.IP) > 0 {
er.IPv6Address = (&ipv6).String()
if ipv6 := iface.AddressIPv6(); ipv6 != nil && len(ipv6.IP) > 0 {
er.IPv6Address = ipv6.String()
}
}
return er

View file

@ -30,6 +30,7 @@ import (
"github.com/docker/docker/volume"
"github.com/docker/docker/volume/store"
"github.com/docker/libnetwork"
"github.com/docker/libnetwork/drivers/bridge"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/types"
@ -651,11 +652,13 @@ func (container *Container) buildEndpointInfo(ep libnetwork.Endpoint, networkSet
return networkSettings, nil
}
ones, _ := iface.Address().Mask.Size()
networkSettings.IPAddress = iface.Address().IP.String()
networkSettings.IPPrefixLen = ones
if iface.Address() != nil {
ones, _ := iface.Address().Mask.Size()
networkSettings.IPAddress = iface.Address().IP.String()
networkSettings.IPPrefixLen = ones
}
if iface.AddressIPv6().IP.To16() != nil {
if iface.AddressIPv6() != nil && iface.AddressIPv6().IP.To16() != nil {
onesv6, _ := iface.AddressIPv6().Mask.Size()
networkSettings.GlobalIPv6Address = iface.AddressIPv6().IP.String()
networkSettings.GlobalIPv6PrefixLen = onesv6
@ -861,9 +864,8 @@ func createNetwork(controller libnetwork.NetworkController, dnet string, driver
// Bridge driver is special due to legacy reasons
if runconfig.NetworkMode(driver).IsBridge() {
genericOption[netlabel.GenericData] = map[string]interface{}{
"BridgeName": dnet,
"AllowNonDefaultBridge": "true",
genericOption[netlabel.GenericData] = map[string]string{
bridge.BridgeName: dnet,
}
networkOption := libnetwork.NetworkOptionGeneric(genericOption)
createOptions = append(createOptions, networkOption)
@ -1163,7 +1165,7 @@ func (container *Container) disconnectFromNetwork(n libnetwork.Network, updateSe
n.WalkEndpoints(s)
if ep == nil {
return fmt.Errorf("could not locate network endpoint for container %s", container.ID)
return fmt.Errorf("container %s is not connected to the network", container.ID)
}
if err := ep.Leave(sbox); err != nil {

View file

@ -7,6 +7,7 @@ import (
"net"
"os"
"path/filepath"
"strconv"
"strings"
"syscall"
@ -23,8 +24,11 @@ import (
"github.com/docker/docker/utils"
"github.com/docker/libnetwork"
nwconfig "github.com/docker/libnetwork/config"
"github.com/docker/libnetwork/drivers/bridge"
"github.com/docker/libnetwork/ipamutils"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/types"
"github.com/opencontainers/runc/libcontainer/label"
"github.com/vishvananda/netlink"
)
@ -312,6 +316,9 @@ func (daemon *Daemon) networkOptions(dconfig *Config) ([]nwconfig.Option, error)
if dconfig == nil {
return options, nil
}
options = append(options, nwconfig.OptionDataDir(dconfig.Root))
if strings.TrimSpace(dconfig.DefaultNetwork) != "" {
dn := strings.Split(dconfig.DefaultNetwork, ":")
if len(dn) < 2 {
@ -392,22 +399,48 @@ func driverOptions(config *Config) []nwconfig.Option {
}
func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error {
netOption := options.Generic{
"BridgeName": config.Bridge.Iface,
"DefaultBridge": true,
"Mtu": config.Mtu,
"EnableIPMasquerade": config.Bridge.EnableIPMasq,
"EnableICC": config.Bridge.InterContainerCommunication,
if n, err := controller.NetworkByName("bridge"); err == nil {
if err = n.Delete(); err != nil {
return fmt.Errorf("could not delete the default bridge network: %v", err)
}
}
bridgeName := bridge.DefaultBridgeName
if config.Bridge.Iface != "" {
bridgeName = config.Bridge.Iface
}
netOption := map[string]string{
bridge.BridgeName: bridgeName,
bridge.DefaultBridge: strconv.FormatBool(true),
netlabel.DriverMTU: strconv.Itoa(config.Mtu),
bridge.EnableIPMasquerade: strconv.FormatBool(config.Bridge.EnableIPMasq),
bridge.EnableICC: strconv.FormatBool(config.Bridge.InterContainerCommunication),
}
// --ip processing
if config.Bridge.DefaultIP != nil {
netOption[bridge.DefaultBindingIP] = config.Bridge.DefaultIP.String()
}
ipamV4Conf := libnetwork.IpamConf{}
ipamV4Conf.AuxAddresses = make(map[string]string)
if nw, _, err := ipamutils.ElectInterfaceAddresses(bridgeName); err == nil {
ipamV4Conf.PreferredPool = nw.String()
hip, _ := types.GetHostPartIP(nw.IP, nw.Mask)
if hip.IsGlobalUnicast() {
ipamV4Conf.Gateway = nw.IP.String()
}
}
if config.Bridge.IP != "" {
ip, bipNet, err := net.ParseCIDR(config.Bridge.IP)
ipamV4Conf.PreferredPool = config.Bridge.IP
ip, _, err := net.ParseCIDR(config.Bridge.IP)
if err != nil {
return err
}
bipNet.IP = ip
netOption["AddressIPv4"] = bipNet
ipamV4Conf.Gateway = ip.String()
}
if config.Bridge.FixedCIDR != "" {
@ -416,38 +449,44 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
return err
}
netOption["FixedCIDR"] = fCIDR
ipamV4Conf.SubPool = fCIDR.String()
}
if config.Bridge.DefaultGatewayIPv4 != nil {
ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.Bridge.DefaultGatewayIPv4.String()
}
var ipamV6Conf *libnetwork.IpamConf
if config.Bridge.FixedCIDRv6 != "" {
_, fCIDRv6, err := net.ParseCIDR(config.Bridge.FixedCIDRv6)
if err != nil {
return err
}
netOption["FixedCIDRv6"] = fCIDRv6
}
if config.Bridge.DefaultGatewayIPv4 != nil {
netOption["DefaultGatewayIPv4"] = config.Bridge.DefaultGatewayIPv4
if ipamV6Conf == nil {
ipamV6Conf = &libnetwork.IpamConf{}
}
ipamV6Conf.PreferredPool = fCIDRv6.String()
}
if config.Bridge.DefaultGatewayIPv6 != nil {
netOption["DefaultGatewayIPv6"] = config.Bridge.DefaultGatewayIPv6
if ipamV6Conf == nil {
ipamV6Conf = &libnetwork.IpamConf{}
}
ipamV6Conf.AuxAddresses["DefaultGatewayIPv6"] = config.Bridge.DefaultGatewayIPv6.String()
}
// --ip processing
if config.Bridge.DefaultIP != nil {
netOption["DefaultBindingIP"] = config.Bridge.DefaultIP
v4Conf := []*libnetwork.IpamConf{&ipamV4Conf}
v6Conf := []*libnetwork.IpamConf{}
if ipamV6Conf != nil {
v6Conf = append(v6Conf, ipamV6Conf)
}
// Initialize default network on "bridge" with the same name
_, err := controller.NewNetwork("bridge", "bridge",
libnetwork.NetworkOptionGeneric(options.Generic{
netlabel.GenericData: netOption,
netlabel.EnableIPv6: config.Bridge.EnableIPv6,
}),
libnetwork.NetworkOptionPersist(false))
libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf))
if err != nil {
return fmt.Errorf("Error creating default \"bridge\" network: %v", err)
}

View file

@ -6,6 +6,7 @@ import (
"github.com/docker/libnetwork"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/options"
)
const (
@ -78,29 +79,14 @@ func (daemon *Daemon) GetNetworksByID(partialID string) []libnetwork.Network {
}
// CreateNetwork creates a network with the given name, driver and other optional parameters
func (daemon *Daemon) CreateNetwork(name, driver string, options map[string]interface{}) (libnetwork.Network, error) {
func (daemon *Daemon) CreateNetwork(name, driver string, labels map[string]interface{}) (libnetwork.Network, error) {
c := daemon.netController
if driver == "" {
driver = c.Config().Daemon.DefaultDriver
}
option := libnetwork.NetworkOptionGeneric(options.Generic{
netlabel.GenericData: map[string]string{},
})
if options == nil {
options = make(map[string]interface{})
}
_, ok := options[netlabel.GenericData]
if !ok {
options[netlabel.GenericData] = make(map[string]interface{})
}
return c.NewNetwork(driver, name, parseOptions(options)...)
}
func parseOptions(options map[string]interface{}) []libnetwork.NetworkOption {
var setFctList []libnetwork.NetworkOption
if options != nil {
setFctList = append(setFctList, libnetwork.NetworkOptionGeneric(options))
}
return setFctList
return c.NewNetwork(driver, name, option)
}

View file

@ -8,7 +8,7 @@ import (
"github.com/docker/docker/api/types/versions/v1p20"
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/pkg/version"
"github.com/docker/libnetwork/osl"
lntypes "github.com/docker/libnetwork/types"
"github.com/opencontainers/runc/libcontainer"
)
@ -166,7 +166,7 @@ func (daemon *Daemon) getNetworkStats(c *Container) ([]*libcontainer.NetworkInte
return list, nil
}
func convertLnNetworkStats(name string, stats *osl.InterfaceStatistics) *libcontainer.NetworkInterface {
func convertLnNetworkStats(name string, stats *lntypes.InterfaceStatistics) *libcontainer.NetworkInterface {
n := &libcontainer.NetworkInterface{Name: name}
n.RxBytes = stats.RxBytes
n.RxPackets = stats.RxPackets

View file

@ -787,7 +787,7 @@ func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidr(c *check.C) {
cName := "Container" + strconv.Itoa(i)
out, err := d.Cmd("run", "-d", "--name", cName, "busybox", "top")
if err != nil {
c.Assert(strings.Contains(out, "no available ip addresses"), check.Equals, true,
c.Assert(strings.Contains(out, "no available IPv4 addresses"), check.Equals, true,
check.Commentf("Could not run a Container : %s %s", err.Error(), out))
}
}