Workaround missing docker.sock in plugin-v2

"docker.sock" is used to access Docker API which is required to:

1. subscribe to Docker events to configure-arp,
2. query Docker network info to detect whether multicast should be
   enabled.
3. get list of Swarm peers before starting the plugin.

(1) is currently not implemented.

(2) is replaced by WEAVE_MULTICAST env var which
can enable multicast for all Weave networks created by
the plugin (not ideal, but better than nothing).

(3) is fixed by not removing "restart.sentinel".
This commit is contained in:
Martynas Pumputis authored and Bryan Boreham committed 2017-05-05 17:25:17 +00:00
1 parent bb66b6161a
commit 2ebd358aeb
5 files changed
+136 -84

No files matched your search

+47 -17
View File
@@ -29,28 +29,39 @@ type network struct {
type driver struct {
sync.RWMutex
scope string
docker *docker.Client
dns bool
isPluginV2 bool
networks map[string]network
isNetworkOur func(driverName string) bool
name string
scope string
// Docker API is not available for plugin-v2
docker *docker.Client
dns bool
isPluginV2 bool
// Enable multicast regardless whether multicast opt is passed to Docker;
// used only by plugin-v2
forceMulticast bool
networks map[string]network
}
func New(client *docker.Client, weave *weaveapi.Client, scope string, dns, isPluginV2 bool, isNetworkOur func(string) bool) (skel.Driver, error) {
func New(client *docker.Client, weave *weaveapi.Client, name, scope string, dns, isPluginV2, forceMulticast bool) (skel.Driver, error) {
driver := &driver{
scope: scope,
docker: client,
dns: dns,
isPluginV2: isPluginV2,
networks: make(map[string]network),
isNetworkOur: isNetworkOur,
name: name,
scope: scope,
docker: client,
dns: dns,
isPluginV2: isPluginV2,
// make sure that it's used only by plugin-v2
forceMulticast: isPluginV2 && forceMulticast,
networks: make(map[string]network),
}
_, err := NewWatcher(client, weave, driver)
if err != nil {
return nil, err
// Do not start watcher in the case of plugin v2, which prevents us from
// configuring arp settings of containers.
if client != nil {
_, err := NewWatcher(client, weave, driver)
if err != nil {
return nil, err
}
}
return driver, nil
}
@@ -189,11 +200,30 @@ func (driver *driver) findNetworkInfo(id string) (network, error) {
if found {
return network, nil
}
// plugin-v2 does not have access to docker.sock, so we cannot call Docker
// API for the network info.
if driver.isPluginV2 {
// safe to set, as isOurs used only by the watcher which is disabled for plugin-v2
network.isOurs = true
network.hasMulticastRoute = driver.forceMulticast
driver.Lock()
driver.networks[id] = network
driver.Unlock()
return network, nil
}
if driver.docker == nil {
return network, fmt.Errorf("Docker client disabled; unable to get network info")
}
info, err := driver.docker.NetworkInfo(id)
if err != nil {
return network, err
}
return driver.setupNetworkInfo(id, driver.isNetworkOur(info.Driver), info.Options)
return driver.setupNetworkInfo(id, info.Driver == driver.name, info.Options)
}
func (driver *driver) setupNetworkInfo(id string, isOurs bool, options map[string]string) (network, error) {
+10 -15
View File
@@ -23,23 +23,23 @@ const (
var Log = common.Log
func Start(weaveAPIAddr string, dockerClient *docker.Client, address string, meshAddress string, dns bool, isPluginV2 bool) {
func Start(weaveAPIAddr string, dockerClient *docker.Client, address string, meshAddress string, dns bool, isPluginV2, forceMulticast bool) {
weave := weaveapi.NewClient(weaveAPIAddr, Log)
Log.Info("Waiting for Weave API Server...")
weave.WaitAPIServer(30)
Log.Info("Finished waiting for Weave API Server")
if err := run(dockerClient, weave, address, meshAddress, dns, isPluginV2); err != nil {
if err := run(dockerClient, weave, address, meshAddress, dns, isPluginV2, forceMulticast); err != nil {
Log.Fatal(err)
}
}
func run(dockerClient *docker.Client, weave *weaveapi.Client, address, meshAddress string, dns, isPluginV2 bool) error {
func run(dockerClient *docker.Client, weave *weaveapi.Client, address, meshAddress string, dns, isPluginV2, forceMulticast bool) error {
endChan := make(chan error, 1)
if address != "" {
globalListener, err := listenAndServe(dockerClient, weave, address, endChan, "global", false, dns, isPluginV2)
globalListener, err := listenAndServe(dockerClient, weave, address, endChan, "global", false, dns, isPluginV2, forceMulticast)
if err != nil {
return err
}
@@ -47,7 +47,7 @@ func run(dockerClient *docker.Client, weave *weaveapi.Client, address, meshAddre
defer globalListener.Close()
}
if meshAddress != "" {
meshListener, err := listenAndServe(dockerClient, weave, meshAddress, endChan, "local", true, dns, isPluginV2)
meshListener, err := listenAndServe(dockerClient, weave, meshAddress, endChan, "local", true, dns, isPluginV2, forceMulticast)
if err != nil {
return err
}
@@ -58,20 +58,15 @@ func run(dockerClient *docker.Client, weave *weaveapi.Client, address, meshAddre
return <-endChan
}
func listenAndServe(dockerClient *docker.Client, weave *weaveapi.Client, address string, endChan chan<- error, scope string, withIpam, dns bool, isPluginV2 bool) (net.Listener, error) {
var isNetworkOur func(string) bool
func listenAndServe(dockerClient *docker.Client, weave *weaveapi.Client, address string, endChan chan<- error, scope string, withIpam, dns bool, isPluginV2, forceMulticast bool) (net.Listener, error) {
var name string
if isPluginV2 {
isNetworkOur = func(driverName string) bool {
return strings.Contains(driverName, pluginV2Name)
}
name = pluginV2Name
} else {
name := strings.TrimSuffix(path.Base(address), ".sock")
isNetworkOur = func(driverName string) bool {
return driverName == name
}
name = strings.TrimSuffix(path.Base(address), ".sock")
}
d, err := netplugin.New(dockerClient, weave, scope, dns, isPluginV2, isNetworkOur)
d, err := netplugin.New(dockerClient, weave, name, scope, dns, isPluginV2, forceMulticast)
if err != nil {
return nil, err
}