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:
commit
e89fc8f66a
7 files changed
+118
-106
No files matched your search
+45
-17
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -66,6 +66,14 @@
|
||||
"value"
|
||||
],
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"description": "Enable multicast for all Weave networks",
|
||||
"name": "WEAVE_MULTICAST",
|
||||
"settable": [
|
||||
"value"
|
||||
],
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"network": {
|
||||
|
||||
+15
-19
@@ -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
@@ -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")
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user