зеркало из https://github.com/microsoft/docker.git
Vendor libnetwork to f4338b6f1085ccfe5972e655cca8a1d15d73439d
This fix updates libnetwork to f4338b6f1085ccfe5972e655cca8a1d15d73439d. Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Родитель
e9c4c513d1
Коммит
fc62ad6b95
|
@ -70,7 +70,7 @@ clone git github.com/RackSec/srslog 365bf33cd9acc21ae1c355209865f17228ca534e
|
||||||
clone git github.com/imdario/mergo 0.2.1
|
clone git github.com/imdario/mergo 0.2.1
|
||||||
|
|
||||||
#get libnetwork packages
|
#get libnetwork packages
|
||||||
clone git github.com/docker/libnetwork 9fbb4ecbb45af655c4ac3c2f3a849b2294cb447a
|
clone git github.com/docker/libnetwork f4338b6f1085ccfe5972e655cca8a1d15d73439d
|
||||||
clone git github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894
|
clone git github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894
|
||||||
clone git github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
|
clone git github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
|
||||||
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
||||||
|
|
|
@ -1062,9 +1062,14 @@ func SandboxKeyWalker(out *Sandbox, key string) SandboxWalker {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) loadDriver(networkType string) error {
|
func (c *controller) loadDriver(networkType string) error {
|
||||||
// Plugins pkg performs lazy loading of plugins that acts as remote drivers.
|
var err error
|
||||||
// As per the design, this Get call will result in remote driver discovery if there is a corresponding plugin available.
|
|
||||||
_, err := plugins.Get(networkType, driverapi.NetworkPluginEndpointType)
|
if pg := c.GetPluginGetter(); pg != nil {
|
||||||
|
_, err = pg.Get(networkType, driverapi.NetworkPluginEndpointType, plugingetter.LOOKUP)
|
||||||
|
} else {
|
||||||
|
_, err = plugins.Get(networkType, driverapi.NetworkPluginEndpointType)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == plugins.ErrNotFound {
|
if err == plugins.ErrNotFound {
|
||||||
return types.NotFoundErrorf(err.Error())
|
return types.NotFoundErrorf(err.Error())
|
||||||
|
@ -1076,7 +1081,15 @@ func (c *controller) loadDriver(networkType string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) loadIPAMDriver(name string) error {
|
func (c *controller) loadIPAMDriver(name string) error {
|
||||||
if _, err := c.GetPluginGetter().Get(name, ipamapi.PluginEndpointType, plugingetter.LOOKUP); err != nil {
|
var err error
|
||||||
|
|
||||||
|
if pg := c.GetPluginGetter(); pg != nil {
|
||||||
|
_, err = pg.Get(name, ipamapi.PluginEndpointType, plugingetter.LOOKUP)
|
||||||
|
} else {
|
||||||
|
_, err = plugins.Get(name, ipamapi.PluginEndpointType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
if err == plugins.ErrNotFound {
|
if err == plugins.ErrNotFound {
|
||||||
return types.NotFoundErrorf(err.Error())
|
return types.NotFoundErrorf(err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -779,6 +779,20 @@ func (d *driver) DeleteNetwork(nid string) error {
|
||||||
config := n.config
|
config := n.config
|
||||||
n.Unlock()
|
n.Unlock()
|
||||||
|
|
||||||
|
// delele endpoints belong to this network
|
||||||
|
for _, ep := range n.endpoints {
|
||||||
|
if err := n.releasePorts(ep); err != nil {
|
||||||
|
logrus.Warn(err)
|
||||||
|
}
|
||||||
|
if link, err := d.nlh.LinkByName(ep.srcName); err == nil {
|
||||||
|
d.nlh.LinkDel(link)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d.storeDelete(ep); err != nil {
|
||||||
|
logrus.Warnf("Failed to remove bridge endpoint %s from store: %v", ep.id[0:7], err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
d.Lock()
|
d.Lock()
|
||||||
delete(d.networks, nid)
|
delete(d.networks, nid)
|
||||||
d.Unlock()
|
d.Unlock()
|
||||||
|
|
|
@ -52,23 +52,22 @@ func (i *bridgeInterface) exists() bool {
|
||||||
return i.Link != nil
|
return i.Link != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// addresses returns a single IPv4 address and all IPv6 addresses for the
|
// addresses returns all IPv4 addresses and all IPv6 addresses for the bridge interface.
|
||||||
// bridge interface.
|
func (i *bridgeInterface) addresses() ([]netlink.Addr, []netlink.Addr, error) {
|
||||||
func (i *bridgeInterface) addresses() (netlink.Addr, []netlink.Addr, error) {
|
|
||||||
v4addr, err := i.nlh.AddrList(i.Link, netlink.FAMILY_V4)
|
v4addr, err := i.nlh.AddrList(i.Link, netlink.FAMILY_V4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netlink.Addr{}, nil, fmt.Errorf("Failed to retrieve V4 addresses: %v", err)
|
return nil, nil, fmt.Errorf("Failed to retrieve V4 addresses: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
v6addr, err := i.nlh.AddrList(i.Link, netlink.FAMILY_V6)
|
v6addr, err := i.nlh.AddrList(i.Link, netlink.FAMILY_V6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netlink.Addr{}, nil, fmt.Errorf("Failed to retrieve V6 addresses: %v", err)
|
return nil, nil, fmt.Errorf("Failed to retrieve V6 addresses: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(v4addr) == 0 {
|
if len(v4addr) == 0 {
|
||||||
return netlink.Addr{}, v6addr, nil
|
return nil, v6addr, nil
|
||||||
}
|
}
|
||||||
return v4addr[0], v6addr, nil
|
return v4addr, v6addr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *bridgeInterface) programIPv6Address() error {
|
func (i *bridgeInterface) programIPv6Address() error {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package bridge
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
@ -10,12 +11,28 @@ import (
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func selectIPv4Address(addresses []netlink.Addr, selector *net.IPNet) (netlink.Addr, error) {
|
||||||
|
if len(addresses) == 0 {
|
||||||
|
return netlink.Addr{}, fmt.Errorf("unable to select an address as the address pool is empty")
|
||||||
|
}
|
||||||
|
if selector != nil {
|
||||||
|
for _, addr := range addresses {
|
||||||
|
if selector.Contains(addr.IP) {
|
||||||
|
return addr, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return addresses[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
||||||
addrv4, _, err := i.addresses()
|
addrv4List, _, err := i.addresses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to retrieve bridge interface addresses: %v", err)
|
return fmt.Errorf("failed to retrieve bridge interface addresses: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addrv4, _ := selectIPv4Address(addrv4List, config.AddressIPv4)
|
||||||
|
|
||||||
if !types.CompareIPNet(addrv4.IPNet, config.AddressIPv4) {
|
if !types.CompareIPNet(addrv4.IPNet, config.AddressIPv4) {
|
||||||
if addrv4.IPNet != nil {
|
if addrv4.IPNet != nil {
|
||||||
if err := i.nlh.AddrDel(i.Link, &addrv4); err != nil {
|
if err := i.nlh.AddrDel(i.Link, &addrv4); err != nil {
|
||||||
|
|
|
@ -11,12 +11,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupVerifyAndReconcile(config *networkConfiguration, i *bridgeInterface) error {
|
func setupVerifyAndReconcile(config *networkConfiguration, i *bridgeInterface) error {
|
||||||
// Fetch a single IPv4 and a slice of IPv6 addresses from the bridge.
|
// Fetch a slice of IPv4 addresses and a slice of IPv6 addresses from the bridge.
|
||||||
addrv4, addrsv6, err := i.addresses()
|
addrsv4, addrsv6, err := i.addresses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to verify ip addresses: %v", err)
|
return fmt.Errorf("Failed to verify ip addresses: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addrv4, _ := selectIPv4Address(addrsv4, config.AddressIPv4)
|
||||||
|
|
||||||
// Verify that the bridge does have an IPv4 address.
|
// Verify that the bridge does have an IPv4 address.
|
||||||
if addrv4.IPNet == nil {
|
if addrv4.IPNet == nil {
|
||||||
return &ErrNoIPAddr{}
|
return &ErrNoIPAddr{}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
"github.com/docker/libnetwork/driverapi"
|
"github.com/docker/libnetwork/driverapi"
|
||||||
"github.com/docker/libnetwork/netlabel"
|
"github.com/docker/libnetwork/netlabel"
|
||||||
|
"github.com/docker/libnetwork/ns"
|
||||||
"github.com/docker/libnetwork/options"
|
"github.com/docker/libnetwork/options"
|
||||||
"github.com/docker/libnetwork/osl"
|
"github.com/docker/libnetwork/osl"
|
||||||
"github.com/docker/libnetwork/types"
|
"github.com/docker/libnetwork/types"
|
||||||
|
@ -147,6 +148,15 @@ func (d *driver) DeleteNetwork(nid string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, ep := range n.endpoints {
|
||||||
|
if link, err := ns.NlHandle().LinkByName(ep.srcName); err == nil {
|
||||||
|
ns.NlHandle().LinkDel(link)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d.storeDelete(ep); err != nil {
|
||||||
|
logrus.Warnf("Failed to remove ipvlan endpoint %s from store: %v", ep.id[0:7], err)
|
||||||
|
}
|
||||||
|
}
|
||||||
// delete the *network
|
// delete the *network
|
||||||
d.deleteNetwork(nid)
|
d.deleteNetwork(nid)
|
||||||
// delete the network record from persistent cache
|
// delete the network record from persistent cache
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
"github.com/docker/libnetwork/driverapi"
|
"github.com/docker/libnetwork/driverapi"
|
||||||
"github.com/docker/libnetwork/netlabel"
|
"github.com/docker/libnetwork/netlabel"
|
||||||
|
"github.com/docker/libnetwork/ns"
|
||||||
"github.com/docker/libnetwork/options"
|
"github.com/docker/libnetwork/options"
|
||||||
"github.com/docker/libnetwork/osl"
|
"github.com/docker/libnetwork/osl"
|
||||||
"github.com/docker/libnetwork/types"
|
"github.com/docker/libnetwork/types"
|
||||||
|
@ -151,6 +152,15 @@ func (d *driver) DeleteNetwork(nid string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, ep := range n.endpoints {
|
||||||
|
if link, err := ns.NlHandle().LinkByName(ep.srcName); err == nil {
|
||||||
|
ns.NlHandle().LinkDel(link)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d.storeDelete(ep); err != nil {
|
||||||
|
logrus.Warnf("Failed to remove macvlan endpoint %s from store: %v", ep.id[0:7], err)
|
||||||
|
}
|
||||||
|
}
|
||||||
// delete the *network
|
// delete the *network
|
||||||
d.deleteNetwork(nid)
|
d.deleteNetwork(nid)
|
||||||
// delete the network record from persistent cache
|
// delete the network record from persistent cache
|
||||||
|
|
|
@ -182,6 +182,18 @@ func (d *driver) DeleteNetwork(nid string) error {
|
||||||
return fmt.Errorf("could not find network with id %s", nid)
|
return fmt.Errorf("could not find network with id %s", nid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, ep := range n.endpoints {
|
||||||
|
if ep.ifName != "" {
|
||||||
|
if link, err := ns.NlHandle().LinkByName(ep.ifName); err != nil {
|
||||||
|
ns.NlHandle().LinkDel(link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d.deleteEndpointFromStore(ep); err != nil {
|
||||||
|
logrus.Warnf("Failed to delete overlay endpoint %s from local store: %v", ep.id[0:7], err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
d.deleteNetwork(nid)
|
d.deleteNetwork(nid)
|
||||||
|
|
||||||
vnis, err := n.releaseVxlanID()
|
vnis, err := n.releaseVxlanID()
|
||||||
|
|
|
@ -513,14 +513,22 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
|
||||||
if moveExtConn {
|
if moveExtConn {
|
||||||
if extEp != nil {
|
if extEp != nil {
|
||||||
log.Debugf("Revoking external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
|
log.Debugf("Revoking external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
|
||||||
if err = d.RevokeExternalConnectivity(extEp.network.ID(), extEp.ID()); err != nil {
|
extN, err := extEp.getNetworkFromStore()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get network from store during join: %v", err)
|
||||||
|
}
|
||||||
|
extD, err := extN.driver(true)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to join endpoint: %v", err)
|
||||||
|
}
|
||||||
|
if err = extD.RevokeExternalConnectivity(extEp.network.ID(), extEp.ID()); err != nil {
|
||||||
return types.InternalErrorf(
|
return types.InternalErrorf(
|
||||||
"driver failed revoking external connectivity on endpoint %s (%s): %v",
|
"driver failed revoking external connectivity on endpoint %s (%s): %v",
|
||||||
extEp.Name(), extEp.ID(), err)
|
extEp.Name(), extEp.ID(), err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e := d.ProgramExternalConnectivity(extEp.network.ID(), extEp.ID(), sb.Labels()); e != nil {
|
if e := extD.ProgramExternalConnectivity(extEp.network.ID(), extEp.ID(), sb.Labels()); e != nil {
|
||||||
log.Warnf("Failed to roll-back external connectivity on endpoint %s (%s): %v",
|
log.Warnf("Failed to roll-back external connectivity on endpoint %s (%s): %v",
|
||||||
extEp.Name(), extEp.ID(), e)
|
extEp.Name(), extEp.ID(), e)
|
||||||
}
|
}
|
||||||
|
@ -699,7 +707,15 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption)
|
||||||
extEp = sb.getGatewayEndpoint()
|
extEp = sb.getGatewayEndpoint()
|
||||||
if moveExtConn && extEp != nil {
|
if moveExtConn && extEp != nil {
|
||||||
log.Debugf("Programming external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
|
log.Debugf("Programming external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
|
||||||
if err := d.ProgramExternalConnectivity(extEp.network.ID(), extEp.ID(), sb.Labels()); err != nil {
|
extN, err := extEp.getNetworkFromStore()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get network from store during leave: %v", err)
|
||||||
|
}
|
||||||
|
extD, err := extN.driver(true)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to leave endpoint: %v", err)
|
||||||
|
}
|
||||||
|
if err := extD.ProgramExternalConnectivity(extEp.network.ID(), extEp.ID(), sb.Labels()); err != nil {
|
||||||
log.Warnf("driver failed programming external connectivity on endpoint %s: (%s) %v",
|
log.Warnf("driver failed programming external connectivity on endpoint %s: (%s) %v",
|
||||||
extEp.Name(), extEp.ID(), err)
|
extEp.Name(), extEp.ID(), err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,12 +199,22 @@ func (a *Allocator) GetDefaultAddressSpaces() (string, string, error) {
|
||||||
// RequestPool returns an address pool along with its unique id.
|
// RequestPool returns an address pool along with its unique id.
|
||||||
func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
|
func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
|
||||||
log.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
|
log.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
|
||||||
retry:
|
|
||||||
k, nw, ipr, pdf, err := a.parsePoolRequest(addressSpace, pool, subPool, v6)
|
k, nw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, nil, types.InternalErrorf("failed to parse pool request for address space %q pool %q subpool %q: %v", addressSpace, pool, subPool, err)
|
return "", nil, nil, types.InternalErrorf("failed to parse pool request for address space %q pool %q subpool %q: %v", addressSpace, pool, subPool, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pdf := k == nil
|
||||||
|
|
||||||
|
retry:
|
||||||
|
if pdf {
|
||||||
|
if nw, err = a.getPredefinedPool(addressSpace, v6); err != nil {
|
||||||
|
return "", nil, nil, err
|
||||||
|
}
|
||||||
|
k = &SubnetKey{AddressSpace: addressSpace, Subnet: nw.String()}
|
||||||
|
}
|
||||||
|
|
||||||
if err := a.refresh(addressSpace); err != nil {
|
if err := a.refresh(addressSpace); err != nil {
|
||||||
return "", nil, nil, err
|
return "", nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -279,39 +289,36 @@ func (a *Allocator) getAddrSpace(as string) (*addrSpace, error) {
|
||||||
return aSpace, nil
|
return aSpace, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Allocator) parsePoolRequest(addressSpace, pool, subPool string, v6 bool) (*SubnetKey, *net.IPNet, *AddressRange, bool, error) {
|
func (a *Allocator) parsePoolRequest(addressSpace, pool, subPool string, v6 bool) (*SubnetKey, *net.IPNet, *AddressRange, error) {
|
||||||
var (
|
var (
|
||||||
nw *net.IPNet
|
nw *net.IPNet
|
||||||
ipr *AddressRange
|
ipr *AddressRange
|
||||||
err error
|
err error
|
||||||
pdf = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if addressSpace == "" {
|
if addressSpace == "" {
|
||||||
return nil, nil, nil, false, ipamapi.ErrInvalidAddressSpace
|
return nil, nil, nil, ipamapi.ErrInvalidAddressSpace
|
||||||
}
|
}
|
||||||
|
|
||||||
if pool == "" && subPool != "" {
|
if pool == "" && subPool != "" {
|
||||||
return nil, nil, nil, false, ipamapi.ErrInvalidSubPool
|
return nil, nil, nil, ipamapi.ErrInvalidSubPool
|
||||||
}
|
}
|
||||||
|
|
||||||
if pool != "" {
|
if pool == "" {
|
||||||
if _, nw, err = net.ParseCIDR(pool); err != nil {
|
return nil, nil, nil, nil
|
||||||
return nil, nil, nil, false, ipamapi.ErrInvalidPool
|
|
||||||
}
|
|
||||||
if subPool != "" {
|
|
||||||
if ipr, err = getAddressRange(subPool, nw); err != nil {
|
|
||||||
return nil, nil, nil, false, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if nw, err = a.getPredefinedPool(addressSpace, v6); err != nil {
|
|
||||||
return nil, nil, nil, false, err
|
|
||||||
}
|
|
||||||
pdf = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &SubnetKey{AddressSpace: addressSpace, Subnet: nw.String(), ChildSubnet: subPool}, nw, ipr, pdf, nil
|
if _, nw, err = net.ParseCIDR(pool); err != nil {
|
||||||
|
return nil, nil, nil, ipamapi.ErrInvalidPool
|
||||||
|
}
|
||||||
|
|
||||||
|
if subPool != "" {
|
||||||
|
if ipr, err = getAddressRange(subPool, nw); err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &SubnetKey{AddressSpace: addressSpace, Subnet: nw.String(), ChildSubnet: subPool}, nw, ipr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Allocator) insertBitMask(key SubnetKey, pool *net.IPNet) error {
|
func (a *Allocator) insertBitMask(key SubnetKey, pool *net.IPNet) error {
|
||||||
|
@ -406,7 +413,7 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, types.NotFoundErrorf("could not find an available predefined network")
|
return nil, types.NotFoundErrorf("could not find an available non-overlapping address pool among the defaults to auto assign to the network")
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestAddress returns an address from the specified pool ID
|
// RequestAddress returns an address from the specified pool ID
|
||||||
|
|
|
@ -7,10 +7,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ElectInterfaceAddresses looks for an interface on the OS with the specified name
|
// ElectInterfaceAddresses looks for an interface on the OS with the specified name
|
||||||
// and returns its IPv4 and IPv6 addresses in CIDR form. If the interface does not exist,
|
// and returns returns all its IPv4 and IPv6 addresses in CIDR notation.
|
||||||
// it chooses from a predifined list the first IPv4 address which does not conflict
|
// If a failure in retrieving the addresses or no IPv4 address is found, an error is returned.
|
||||||
// with other interfaces on the system.
|
// If the interface does not exist, it chooses from a predefined
|
||||||
func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) {
|
// list the first IPv4 address which does not conflict with other
|
||||||
|
// interfaces on the system.
|
||||||
|
func ElectInterfaceAddresses(name string) ([]*net.IPNet, []*net.IPNet, error) {
|
||||||
return nil, nil, types.NotImplementedErrorf("not supported on freebsd")
|
return nil, nil, types.NotImplementedErrorf("not supported on freebsd")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,15 +62,15 @@ func GenerateIfaceName(nlh *netlink.Handle, prefix string, len int) (string, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ElectInterfaceAddresses looks for an interface on the OS with the
|
// ElectInterfaceAddresses looks for an interface on the OS with the
|
||||||
// specified name and returns its IPv4 and IPv6 addresses in CIDR
|
// specified name and returns returns all its IPv4 and IPv6 addresses in CIDR notation.
|
||||||
// form. If the interface does not exist, it chooses from a predefined
|
// If a failure in retrieving the addresses or no IPv4 address is found, an error is returned.
|
||||||
|
// If the interface does not exist, it chooses from a predefined
|
||||||
// list the first IPv4 address which does not conflict with other
|
// list the first IPv4 address which does not conflict with other
|
||||||
// interfaces on the system.
|
// interfaces on the system.
|
||||||
func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) {
|
func ElectInterfaceAddresses(name string) ([]*net.IPNet, []*net.IPNet, error) {
|
||||||
var (
|
var (
|
||||||
v4Net *net.IPNet
|
v4Nets []*net.IPNet
|
||||||
v6Nets []*net.IPNet
|
v6Nets []*net.IPNet
|
||||||
err error
|
|
||||||
)
|
)
|
||||||
|
|
||||||
defer osl.InitOSContext()()
|
defer osl.InitOSContext()()
|
||||||
|
@ -85,23 +85,24 @@ func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
if len(v4addr) > 0 {
|
for _, nlAddr := range v4addr {
|
||||||
v4Net = v4addr[0].IPNet
|
v4Nets = append(v4Nets, nlAddr.IPNet)
|
||||||
}
|
}
|
||||||
for _, nlAddr := range v6addr {
|
for _, nlAddr := range v6addr {
|
||||||
v6Nets = append(v6Nets, nlAddr.IPNet)
|
v6Nets = append(v6Nets, nlAddr.IPNet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if link == nil || v4Net == nil {
|
if link == nil || len(v4Nets) == 0 {
|
||||||
// Choose from predefined broad networks
|
// Choose from predefined broad networks
|
||||||
v4Net, err = FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
|
v4Net, err := FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
v4Nets = append(v4Nets, v4Net)
|
||||||
}
|
}
|
||||||
|
|
||||||
return v4Net, v6Nets, nil
|
return v4Nets, v6Nets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAvailableNetwork returns a network from the passed list which does not
|
// FindAvailableNetwork returns a network from the passed list which does not
|
||||||
|
|
|
@ -22,10 +22,12 @@ func CheckRouteOverlaps(toCheck *net.IPNet) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ElectInterfaceAddresses looks for an interface on the OS with the specified name
|
// ElectInterfaceAddresses looks for an interface on the OS with the specified name
|
||||||
// and returns its IPv4 and IPv6 addresses in CIDR form. If the interface does not exist,
|
// and returns returns all its IPv4 and IPv6 addresses in CIDR notation.
|
||||||
// it chooses from a predifined list the first IPv4 address which does not conflict
|
// If a failure in retrieving the addresses or no IPv4 address is found, an error is returned.
|
||||||
// with other interfaces on the system.
|
// If the interface does not exist, it chooses from a predefined
|
||||||
func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) {
|
// list the first IPv4 address which does not conflict with other
|
||||||
|
// interfaces on the system.
|
||||||
|
func ElectInterfaceAddresses(name string) ([]*net.IPNet, []*net.IPNet, error) {
|
||||||
var (
|
var (
|
||||||
v4Net *net.IPNet
|
v4Net *net.IPNet
|
||||||
)
|
)
|
||||||
|
@ -63,7 +65,7 @@ func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v4Net, nil, nil
|
return []*net.IPNet{v4Net}, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAvailableNetwork returns a network from the passed list which does not
|
// FindAvailableNetwork returns a network from the passed list which does not
|
||||||
|
|
|
@ -7,10 +7,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ElectInterfaceAddresses looks for an interface on the OS with the specified name
|
// ElectInterfaceAddresses looks for an interface on the OS with the specified name
|
||||||
// and returns its IPv4 and IPv6 addresses in CIDR form. If the interface does not exist,
|
// and returns returns all its IPv4 and IPv6 addresses in CIDR notation.
|
||||||
// it chooses from a predifined list the first IPv4 address which does not conflict
|
// If a failure in retrieving the addresses or no IPv4 address is found, an error is returned.
|
||||||
// with other interfaces on the system.
|
// If the interface does not exist, it chooses from a predefined
|
||||||
func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) {
|
// list the first IPv4 address which does not conflict with other
|
||||||
|
// interfaces on the system.
|
||||||
|
func ElectInterfaceAddresses(name string) ([]*net.IPNet, []*net.IPNet, error) {
|
||||||
return nil, nil, types.NotImplementedErrorf("not supported on windows")
|
return nil, nil, types.NotImplementedErrorf("not supported on windows")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
reapInterval = 60 * time.Second
|
reapInterval = 60 * time.Second
|
||||||
reapPeriod = 5 * time.Second
|
reapPeriod = 5 * time.Second
|
||||||
retryInterval = 1 * time.Second
|
retryInterval = 1 * time.Second
|
||||||
|
nodeReapInterval = 24 * time.Hour
|
||||||
|
nodeReapPeriod = 2 * time.Hour
|
||||||
)
|
)
|
||||||
|
|
||||||
type logWriter struct{}
|
type logWriter struct{}
|
||||||
|
@ -147,6 +149,7 @@ func (nDB *NetworkDB) clusterInit() error {
|
||||||
{config.GossipInterval, nDB.gossip},
|
{config.GossipInterval, nDB.gossip},
|
||||||
{config.PushPullInterval, nDB.bulkSyncTables},
|
{config.PushPullInterval, nDB.bulkSyncTables},
|
||||||
{retryInterval, nDB.reconnectNode},
|
{retryInterval, nDB.reconnectNode},
|
||||||
|
{nodeReapPeriod, nDB.reapDeadNode},
|
||||||
} {
|
} {
|
||||||
t := time.NewTicker(trigger.interval)
|
t := time.NewTicker(trigger.interval)
|
||||||
go nDB.triggerFunc(trigger.interval, t.C, nDB.stopCh, trigger.fn)
|
go nDB.triggerFunc(trigger.interval, t.C, nDB.stopCh, trigger.fn)
|
||||||
|
@ -234,6 +237,19 @@ func (nDB *NetworkDB) triggerFunc(stagger time.Duration, C <-chan time.Time, sto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (nDB *NetworkDB) reapDeadNode() {
|
||||||
|
nDB.Lock()
|
||||||
|
defer nDB.Unlock()
|
||||||
|
for id, n := range nDB.failedNodes {
|
||||||
|
if n.reapTime > 0 {
|
||||||
|
n.reapTime -= reapPeriod
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
logrus.Debugf("Removing failed node %v from gossip cluster", n.Name)
|
||||||
|
delete(nDB.failedNodes, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (nDB *NetworkDB) reconnectNode() {
|
func (nDB *NetworkDB) reconnectNode() {
|
||||||
nDB.RLock()
|
nDB.RLock()
|
||||||
if len(nDB.failedNodes) == 0 {
|
if len(nDB.failedNodes) == 0 {
|
||||||
|
|
|
@ -29,6 +29,8 @@ func (e *eventDelegate) NotifyLeave(mn *memberlist.Node) {
|
||||||
e.nDB.Lock()
|
e.nDB.Lock()
|
||||||
if n, ok := e.nDB.nodes[mn.Name]; ok {
|
if n, ok := e.nDB.nodes[mn.Name]; ok {
|
||||||
delete(e.nDB.nodes, mn.Name)
|
delete(e.nDB.nodes, mn.Name)
|
||||||
|
|
||||||
|
n.reapTime = reapInterval
|
||||||
e.nDB.failedNodes[mn.Name] = n
|
e.nDB.failedNodes[mn.Name] = n
|
||||||
}
|
}
|
||||||
e.nDB.Unlock()
|
e.nDB.Unlock()
|
||||||
|
|
|
@ -94,6 +94,8 @@ type NetworkDB struct {
|
||||||
type node struct {
|
type node struct {
|
||||||
memberlist.Node
|
memberlist.Node
|
||||||
ltime serf.LamportTime
|
ltime serf.LamportTime
|
||||||
|
// Number of hours left before the reaper removes the node
|
||||||
|
reapTime time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// network describes the node/network attachment.
|
// network describes the node/network attachment.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче