mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
a226c36b75
- Renamed netlabel prefixes to accomodate both global and local store configs. - Added a `private` marker. - Skipping the data store configs for remote driver so that external plugins don't get it as there is no secure and sane way to coordinate providing data store access to external plugins. Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
186 lines
3.9 KiB
Go
186 lines
3.9 KiB
Go
package overlay
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
"github.com/docker/libkv/store"
|
|
"github.com/docker/libnetwork/datastore"
|
|
"github.com/docker/libnetwork/driverapi"
|
|
"github.com/docker/libnetwork/idm"
|
|
"github.com/docker/libnetwork/netlabel"
|
|
"github.com/hashicorp/serf/serf"
|
|
)
|
|
|
|
const (
|
|
networkType = "overlay"
|
|
vethPrefix = "veth"
|
|
vethLen = 7
|
|
vxlanIDStart = 256
|
|
vxlanIDEnd = 1000
|
|
vxlanPort = 4789
|
|
vxlanVethMTU = 1450
|
|
)
|
|
|
|
type driver struct {
|
|
eventCh chan serf.Event
|
|
notifyCh chan ovNotify
|
|
exitCh chan chan struct{}
|
|
bindAddress string
|
|
neighIP string
|
|
config map[string]interface{}
|
|
peerDb peerNetworkMap
|
|
serfInstance *serf.Serf
|
|
networks networkTable
|
|
store datastore.DataStore
|
|
ipAllocator *idm.Idm
|
|
vxlanIdm *idm.Idm
|
|
once sync.Once
|
|
joinOnce sync.Once
|
|
sync.Mutex
|
|
}
|
|
|
|
// Init registers a new instance of overlay driver
|
|
func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
|
|
c := driverapi.Capability{
|
|
DataScope: datastore.GlobalScope,
|
|
}
|
|
|
|
d := &driver{
|
|
networks: networkTable{},
|
|
peerDb: peerNetworkMap{
|
|
mp: map[string]peerMap{},
|
|
},
|
|
config: config,
|
|
}
|
|
|
|
return dc.RegisterDriver(networkType, d, c)
|
|
}
|
|
|
|
// Fini cleans up the driver resources
|
|
func Fini(drv driverapi.Driver) {
|
|
d := drv.(*driver)
|
|
|
|
if d.exitCh != nil {
|
|
waitCh := make(chan struct{})
|
|
|
|
d.exitCh <- waitCh
|
|
|
|
<-waitCh
|
|
}
|
|
}
|
|
|
|
func (d *driver) configure() error {
|
|
var err error
|
|
|
|
if len(d.config) == 0 {
|
|
return nil
|
|
}
|
|
|
|
d.once.Do(func() {
|
|
provider, provOk := d.config[netlabel.GlobalKVProvider]
|
|
provURL, urlOk := d.config[netlabel.GlobalKVProviderURL]
|
|
|
|
if provOk && urlOk {
|
|
cfg := &datastore.ScopeCfg{
|
|
Client: datastore.ScopeClientCfg{
|
|
Provider: provider.(string),
|
|
Address: provURL.(string),
|
|
},
|
|
}
|
|
provConfig, confOk := d.config[netlabel.GlobalKVProviderConfig]
|
|
if confOk {
|
|
cfg.Client.Config = provConfig.(*store.Config)
|
|
}
|
|
d.store, err = datastore.NewDataStore(datastore.GlobalScope, cfg)
|
|
if err != nil {
|
|
err = fmt.Errorf("failed to initialize data store: %v", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
d.vxlanIdm, err = idm.New(d.store, "vxlan-id", vxlanIDStart, vxlanIDEnd)
|
|
if err != nil {
|
|
err = fmt.Errorf("failed to initialize vxlan id manager: %v", err)
|
|
return
|
|
}
|
|
|
|
d.ipAllocator, err = idm.New(d.store, "ipam-id", 1, 0xFFFF-2)
|
|
if err != nil {
|
|
err = fmt.Errorf("failed to initalize ipam id manager: %v", err)
|
|
return
|
|
}
|
|
})
|
|
|
|
return err
|
|
}
|
|
|
|
func (d *driver) Type() string {
|
|
return networkType
|
|
}
|
|
|
|
func (d *driver) nodeJoin(node string, self bool) {
|
|
if self && !d.isSerfAlive() {
|
|
d.Lock()
|
|
d.bindAddress = node
|
|
d.Unlock()
|
|
err := d.serfInit()
|
|
if err != nil {
|
|
logrus.Errorf("initializing serf instance failed: %v", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
d.Lock()
|
|
if !self {
|
|
d.neighIP = node
|
|
}
|
|
neighIP := d.neighIP
|
|
d.Unlock()
|
|
|
|
if d.serfInstance != nil && neighIP != "" {
|
|
var err error
|
|
d.joinOnce.Do(func() {
|
|
err = d.serfJoin(neighIP)
|
|
if err == nil {
|
|
d.pushLocalDb()
|
|
}
|
|
})
|
|
if err != nil {
|
|
logrus.Errorf("joining serf neighbor %s failed: %v", node, err)
|
|
d.Lock()
|
|
d.joinOnce = sync.Once{}
|
|
d.Unlock()
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (d *driver) pushLocalEndpointEvent(action, nid, eid string) {
|
|
if !d.isSerfAlive() {
|
|
return
|
|
}
|
|
d.notifyCh <- ovNotify{
|
|
action: "join",
|
|
nid: nid,
|
|
eid: eid,
|
|
}
|
|
}
|
|
|
|
// DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
|
|
func (d *driver) DiscoverNew(dType driverapi.DiscoveryType, data interface{}) error {
|
|
if dType == driverapi.NodeDiscovery {
|
|
nodeData, ok := data.(driverapi.NodeDiscoveryData)
|
|
if !ok || nodeData.Address == "" {
|
|
return fmt.Errorf("invalid discovery data")
|
|
}
|
|
d.nodeJoin(nodeData.Address, nodeData.Self)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
|
|
func (d *driver) DiscoverDelete(dType driverapi.DiscoveryType, data interface{}) error {
|
|
return nil
|
|
}
|