diff --git a/prog/v2-plugin/config.json b/prog/v2-plugin/config.json index 7f1e0b2a..ca04a7a8 100644 --- a/prog/v2-plugin/config.json +++ b/prog/v2-plugin/config.json @@ -21,6 +21,18 @@ "destination": "/procmount", "type": "proc", "source": "proc" + }, + { + "destination": "/var/run/docker.sock", + "source": "/var/run/docker.sock", + "type": "bind", + "options": ["rbind"] + }, + { + "destination": "/var/lib/weave", + "source": "/var/lib/weave", + "type": "bind", + "options": ["rbind"] } ], "network": { diff --git a/prog/v2-plugin/launch.sh b/prog/v2-plugin/launch.sh index ea2608e2..03bdd08a 100755 --- a/prog/v2-plugin/launch.sh +++ b/prog/v2-plugin/launch.sh @@ -7,13 +7,16 @@ IPALLOC_RANGE=${IPALLOC_RANGE:-10.32.0.0/12} HTTP_ADDR=${WEAVE_HTTP_ADDR:-127.0.0.1:6784} STATUS_ADDR=${WEAVE_STATUS_ADDR:-0.0.0.0:6782} HOST_ROOT=${HOST_ROOT:-/host} -LOG_FILE=/tmp/weaver.log +LOG_FILE=/var/lib/weave/weaver.log echo "Starting launch.sh" >>$LOG_FILE # Check if the IP range overlaps anything existing on the host /usr/bin/weaveutil netcheck $IPALLOC_RANGE weave +SWARM_PEERS=$(/usr/bin/weaveutil swarm-manager-peers 2>>$LOG_FILE) +! /usr/bin/weaveutil is-swarm-manager 2>>$LOG_FILE || IS_SWARM_MANAGER=1 + /home/weave/weave --local create-bridge --force >>$LOG_FILE 2>&1 BRIDGE_OPTIONS="--datapath=datapath" @@ -29,8 +32,11 @@ if [ "$(/home/weave/weave --local bridge-type)" = "bridge" ]; then fi if [ -z "$IPALLOC_INIT" ]; then - # ideally we would know the peer count - IPALLOC_INIT="consensus" + if [ $IS_SWARM_MANAGER == "1" ]; then + IPALLOC_INIT="consensus=$(echo $SWARM_PEERS | wc -l)" + else + IPALLOC_INIT="observer" + fi fi /home/weave/weaver $EXTRA_ARGS --port=6783 $BRIDGE_OPTIONS \ @@ -38,6 +44,7 @@ fi --ipalloc-range=$IPALLOC_RANGE \ --ipalloc-init $IPALLOC_INIT \ --nickname "$(hostname)" \ + $(echo $SWARM_PEERS | tr '\n' ' ') \ >>$LOG_FILE 2>&1 & WEAVE_PID=$! @@ -51,7 +58,7 @@ while true; do sleep 1 done -/home/weave/plugin --meshsocket='' --docker-api='' >/tmp/plugin.log 2>&1 & +/home/weave/plugin --meshsocket='' --docker-api='' >/var/lib/weave/plugin.log 2>&1 & echo "End of launch.sh" >>$LOG_FILE diff --git a/prog/weaveutil/main.go b/prog/weaveutil/main.go index 9e8ea815..103bd047 100644 --- a/prog/weaveutil/main.go +++ b/prog/weaveutil/main.go @@ -37,6 +37,8 @@ func init() { "expose-nat": exposeNAT, "bridge-ip": bridgeIP, "unique-id": uniqueID, + "swarm-manager-peers": swarmManagerPeers, + "is-swarm-manager": isSwarmManager, } } diff --git a/prog/weaveutil/swarm.go b/prog/weaveutil/swarm.go new file mode 100644 index 00000000..fbec29e9 --- /dev/null +++ b/prog/weaveutil/swarm.go @@ -0,0 +1,64 @@ +package main + +import ( + "fmt" + "strings" + + "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 + } + + 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 + } + + for _, managerNode := range info.Swarm.RemoteManagers { + ip, err := ipFromAddr(managerNode.Addr) + if err != nil { + return errors.Wrap(err, "ipFromAddr") + } + fmt.Println(ip) + } + + return nil +} + +func dockerInfo() (*docker.DockerInfo, error) { + client, err := docker.NewVersionedClientFromEnv(DOCKER_API_VERSION) + if err != nil { + return nil, errors.Wrap(err, "docker.NewVersionedClientFromEnv") + } + + info, err := client.Info() + if err != nil { + return nil, errors.Wrap(err, "docker.Info") + } + + return info, nil +} + +func ipFromAddr(addr string) (string, error) { + parts := strings.Split(addr, ":") + if len(parts) != 2 { + return "", fmt.Errorf("invalid address: %q", addr) + } + + return parts[0], nil +}