Merge pull request #2929 from weaveworks/issues/2906-plugin-v2-docker-sock

Work around missing docker.sock in plugin-v2
This commit is contained in:
Bryan Boreham authored and GitHub committed 2017-05-09 10:14:47 +01:00
commit e89fc8f66a
7 files changed
+118 -106

No files matched your search

+45 -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
}
@@ -183,17 +194,34 @@ func (driver *driver) JoinEndpoint(j *api.JoinRequest) (*api.JoinResponse, error
}
func (driver *driver) findNetworkInfo(id string) (network, error) {
var network network
// 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
return network, nil
}
driver.Lock()
network, found := driver.networks[id]
driver.Unlock()
if found {
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
}
+8
View File
@@ -66,6 +66,14 @@
"value"
],
"value": ""
},
{
"description": "Enable multicast for all Weave networks",
"name": "WEAVE_MULTICAST",
"settable": [
"value"
],
"value": ""
}
],
"network": {
+15 -19
View File
@@ -16,18 +16,16 @@ echo "Starting launch.sh"
# Check if the IP range overlaps anything existing on the host
/usr/bin/weaveutil netcheck $IPALLOC_RANGE weave
STATUS=0
/usr/bin/weaveutil is-swarm-manager 2>/dev/null || STATUS=$?
if [ $STATUS -eq 0 ]; then
IS_SWARM_MANAGER=1
elif [ $STATUS -eq 20 ]; then
echo "Host swarm is not \"active\"; exiting." >&2
exit 1
fi
# We need to get a list of Swarm nodes which might run the net-plugin:
# - In the case of missing restart.sentinel, we assume that net-plugin has started
# for the first time via the docker-plugin cmd. So it's safe to request docker.sock.
# - If restart.sentinel present, let weaver restore from it as docker.sock is not
# available to any plugin in general (https://github.com/moby/moby/issues/32815).
SWARM_MANAGER_PEERS=$(/usr/bin/weaveutil swarm-manager-peers)
# Prevent from restoring from a persisted peers list
rm -f "/restart.sentinel"
PEERS=
if [ ! -f "/restart.sentinel" ]; then
PEERS=$(/usr/bin/weaveutil swarm-manager-peers)
fi
router_bridge_opts() {
echo --datapath=datapath
@@ -35,12 +33,9 @@ router_bridge_opts() {
[ -z "$WEAVE_NO_FASTDP" ] || echo --no-fastdp
}
if [ -z "$IPALLOC_INIT" ]; then
IPALLOC_INIT="observer"
if [ "$IS_SWARM_MANAGER" == "1" ]; then
IPALLOC_INIT="consensus=$(echo $SWARM_MANAGER_PEERS | wc -l)"
fi
fi
multicast_opt() {
[ -z "$WEAVE_MULTICAST" ] || echo "--plugin-v2-multicast"
}
exec /home/weave/weaver $EXTRA_ARGS --port=6783 $(router_bridge_opts) \
--host-root=/host \
@@ -48,10 +43,11 @@ exec /home/weave/weaver $EXTRA_ARGS --port=6783 $(router_bridge_opts) \
--http-addr=$HTTP_ADDR --status-addr=$STATUS_ADDR \
--no-dns \
--ipalloc-range=$IPALLOC_RANGE \
--ipalloc-init $IPALLOC_INIT \
--nickname "$(hostname)" \
--log-level=debug \
--db-prefix="$WEAVE_DIR/weave" \
--plugin-v2 \
$(multicast_opt) \
--plugin-mesh-socket='' \
$(echo $SWARM_MANAGER_PEERS | tr '\n' ' ')
--docker-api='' \
$PEERS
+35 -33
View File
@@ -123,38 +123,39 @@ func main() {
runtime.GOMAXPROCS(procs)
var (
justVersion bool
config mesh.Config
bridgeConfig weavenet.BridgeConfig
networkConfig weave.NetworkConfig
protocolMinVersion int
resume bool
routerName string
nickName string
password string
pktdebug bool
logLevel string
prof string
bufSzMB int
noDiscovery bool
httpAddr string
statusAddr string
ipamConfig ipamConfig
dockerAPI string
peers []string
noDNS bool
dnsConfig dnsConfig
trustedSubnetStr string
dbPrefix string
hostRoot string
procPath string
discoveryEndpoint string
token string
advertiseAddress string
pluginSocket string
pluginMeshSocket string
enablePlugin bool
enablePluginV2 bool
justVersion bool
config mesh.Config
bridgeConfig weavenet.BridgeConfig
networkConfig weave.NetworkConfig
protocolMinVersion int
resume bool
routerName string
nickName string
password string
pktdebug bool
logLevel string
prof string
bufSzMB int
noDiscovery bool
httpAddr string
statusAddr string
ipamConfig ipamConfig
dockerAPI string
peers []string
noDNS bool
dnsConfig dnsConfig
trustedSubnetStr string
dbPrefix string
hostRoot string
procPath string
discoveryEndpoint string
token string
advertiseAddress string
pluginSocket string
pluginMeshSocket string
enablePlugin bool
enablePluginV2 bool
enablePluginV2Multicast bool
defaultDockerHost = "unix:///var/run/docker.sock"
)
@@ -208,6 +209,7 @@ func main() {
mflag.BoolVar(&enablePlugin, []string{"-plugin"}, false, "enable Docker plugin (v1)")
mflag.BoolVar(&enablePluginV2, []string{"-plugin-v2"}, false, "enable Docker plugin (v2)")
mflag.BoolVar(&enablePluginV2Multicast, []string{"-plugin-v2-multicast"}, false, "enable multicast for Docker plugin (v2)")
mflag.StringVar(&pluginSocket, []string{"-plugin-socket"}, "/run/docker/plugins/weave.sock", "plugin socket on which to listen")
mflag.StringVar(&pluginMeshSocket, []string{"-plugin-mesh-socket"}, "/run/docker/plugins/weavemesh.sock", "plugin socket on which to listen in mesh mode")
@@ -427,7 +429,7 @@ func main() {
}
if enablePlugin || enablePluginV2 {
go plugin.Start(httpAddr, dockerCli, pluginSocket, pluginMeshSocket, !noDNS, enablePluginV2)
go plugin.Start(httpAddr, dockerCli, pluginSocket, pluginMeshSocket, !noDNS, enablePluginV2, enablePluginV2Multicast)
}
if enablePlugin {
Log.Println("Creating default 'weave' network")
-1
View File
@@ -39,7 +39,6 @@ func init() {
"bridge-ip": bridgeIP,
"unique-id": uniqueID,
"swarm-manager-peers": swarmManagerPeers,
"is-swarm-manager": isSwarmManager,
"is-docker-plugin-enabled": isDockerPluginEnabled,
}
}
+5 -21
View File
@@ -2,48 +2,32 @@ package main
import (
"fmt"
"os"
"strings"
"github.com/docker/docker/api/types/swarm"
"github.com/fsouza/go-dockerclient"
"github.com/pkg/errors"
)
const DOCKER_API_VERSION = "1.26"
func isSwarmManager(args []string) error {
info, err := dockerInfo()
if err != nil {
return err
}
// hack-y way to denote that a node does not belong to any swarm
if info.Swarm.LocalNodeState != swarm.LocalNodeStateActive {
os.Exit(20)
}
if !info.Swarm.ControlAvailable {
return fmt.Errorf("node is not a manager")
}
return nil
}
func swarmManagerPeers(args []string) error {
info, err := dockerInfo()
if err != nil {
return err
}
ips := make([]string, 0)
for _, managerNode := range info.Swarm.RemoteManagers {
ip, err := ipFromAddr(managerNode.Addr)
if err != nil {
return errors.Wrap(err, "ipFromAddr")
}
fmt.Println(ip)
ips = append(ips, ip)
}
fmt.Println(strings.Join(ips, " "))
return nil
}