Skip to content

Commit

Permalink
Yet More Plumbing for multi-host setup.
Browse files Browse the repository at this point in the history
- Move peers from flags to args in the app
- Allow users to specify peers as IPs and hostname, both with and without ports
- Allow users to specify peers on ./scope launch, and plumb that through entrypoint.sh and run-app
- Improce ./scope usage text
- Add brief document explaining how to cluster Scope
  • Loading branch information
Tom Wilkie committed Jun 1, 2015
1 parent 2e8df4a commit 8231987
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 31 deletions.
5 changes: 2 additions & 3 deletions app/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"time"

Expand All @@ -24,12 +23,12 @@ func main() {
var (
defaultProbes = []string{fmt.Sprintf("localhost:%d", xfer.ProbePort), fmt.Sprintf("scope.weave.local:%d", xfer.ProbePort)}
logfile = flag.String("log", "stderr", "stderr, syslog, or filename")
probes = flag.String("probes", strings.Join(defaultProbes, ","), "list of probe endpoints, comma separated")
batch = flag.Duration("batch", 1*time.Second, "batch interval")
window = flag.Duration("window", 15*time.Second, "window")
listen = flag.String("http.address", ":"+strconv.Itoa(xfer.AppPort), "webserver listen address")
)
flag.Parse()
probes := append(defaultProbes, flag.Args()...)

switch *logfile {
case "stderr":
Expand Down Expand Up @@ -62,7 +61,7 @@ func main() {
c := xfer.NewCollector(*batch)
defer c.Stop()

r := NewResolver(strings.Split(*probes, ","), c.AddAddress)
r := NewResolver(probes, c.AddAddress)
defer r.Stop()

lifo := NewReportLIFO(c, *window)
Expand Down
40 changes: 32 additions & 8 deletions app/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ package main
import (
"log"
"net"
"strconv"
"strings"
"time"

"github.com/weaveworks/scope/xfer"
)

var (
Expand Down Expand Up @@ -42,11 +46,22 @@ func NewResolver(peers []string, add func(string)) Resolver {
func prepareNames(strs []string) []peer {
var results []peer
for _, s := range strs {
hostname, port, err := net.SplitHostPort(s)
if err != nil {
log.Printf("invalid address %s: %v", s, err)
continue
var (
hostname string
port string
err error
)

if strings.Contains(s, ":") {
hostname, port, err = net.SplitHostPort(s)
if err != nil {
log.Printf("invalid address %s: %v", s, err)
continue
}
} else {
hostname, port = s, strconv.Itoa(xfer.ProbePort)
}

results = append(results, peer{hostname, port})
}
return results
Expand All @@ -67,10 +82,19 @@ func (r Resolver) loop() {

func (r Resolver) resolveHosts() {
for _, peer := range r.peers {
addrs, err := lookupIP(peer.hostname)
if err != nil {
log.Printf("lookup %s: %v", peer.hostname, err)
continue
var (
addrs []net.IP
err error
)

if addr := net.ParseIP(peer.hostname); addr != nil {
addrs = []net.IP{addr}
} else {
addrs, err = lookupIP(peer.hostname)
if err != nil {
log.Printf("lookup %s: %v", peer.hostname, err)
continue
}
}

for _, addr := range addrs {
Expand Down
52 changes: 35 additions & 17 deletions app/resolver_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package main

import (
"fmt"
"net"
"runtime"
"testing"
"time"

"github.com/weaveworks/scope/xfer"
)

func TestResolver(t *testing.T) {
Expand All @@ -15,20 +18,21 @@ func TestResolver(t *testing.T) {

oldLookupIP := lookupIP
defer func() { lookupIP = oldLookupIP }()
ips := []net.IP{}
lookupIP = func(host string) ([]net.IP, error) { return ips, nil }
ips := map[string][]net.IP{}
lookupIP = func(host string) ([]net.IP, error) {
addrs, ok := ips[host]
if !ok {
return nil, fmt.Errorf("Not found")
}
return addrs, nil
}

port := ":80"
ip1 := "192.168.0.1"
ip2 := "192.168.0.10"
adds := make(chan string)
add := func(s string) { adds <- s }
r := NewResolver([]string{"symbolic.name" + port}, add)

c <- time.Now() // trigger initial resolve, with no endpoints
select {
case <-time.After(time.Millisecond):
case s := <-adds:
t.Errorf("got unexpected add: %q", s)
}
r := NewResolver([]string{"symbolic.name" + port, "namewithnoport", ip1 + port, ip2}, add)

assertAdd := func(want string) {
select {
Expand All @@ -42,16 +46,30 @@ func TestResolver(t *testing.T) {
}
}

ip1 := "1.2.3.4"
ips = makeIPs(ip1)
// Initial resolve should just give us IPs
assertAdd(ip1 + port)
assertAdd(fmt.Sprintf("%s:%d", ip2, xfer.ProbePort))

// Trigger another resolve with a tick; again,
// just want ips.
c <- time.Now()
assertAdd(ip1 + port)
assertAdd(fmt.Sprintf("%s:%d", ip2, xfer.ProbePort))

ip3 := "1.2.3.4"
ips = map[string][]net.IP{"symbolic.name": makeIPs(ip3)}
c <- time.Now() // trigger a resolve
assertAdd(ip1 + port) // we want 1 add
assertAdd(ip3 + port) // we want 1 add
assertAdd(ip1 + port)
assertAdd(fmt.Sprintf("%s:%d", ip2, xfer.ProbePort))

ip2 := "10.10.10.10"
ips = makeIPs(ip1, ip2)
ip4 := "10.10.10.10"
ips = map[string][]net.IP{"symbolic.name": makeIPs(ip3, ip4)}
c <- time.Now() // trigger another resolve, this time with 2 adds
assertAdd(ip1 + port) // first add
assertAdd(ip2 + port) // second add
assertAdd(ip3 + port) // first add
assertAdd(ip4 + port) // second add
assertAdd(ip1 + port)
assertAdd(fmt.Sprintf("%s:%d", ip2, xfer.ProbePort))

done := make(chan struct{})
go func() { r.Stop(); close(done) }()
Expand Down
8 changes: 8 additions & 0 deletions docker/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,12 @@ if [ -n "$DNS_SERVER" -a -n "$SEARCHPATH" ]; then
echo "nameserver $DNS_SERVER" >>/etc/resolv.conf
fi

# End of the command line can optionally be some
# addresses of probes to connect to, for people not
# using Weave DNS. We stick these in /etc/weave/probes
# for the run-app script to pick up.
MANUAL_PROBES=$@
mkdir -p /etc/weave
echo "$MANUAL_PROBES" >/etc/weave/probes

exec /sbin/runsvdir /etc/service
2 changes: 1 addition & 1 deletion docker/run-app
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/sh

exec /home/weave/app
exec /home/weave/app $(cat /etc/weave/probes)
10 changes: 10 additions & 0 deletions docs/scope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

## Multi host setup

Weave Scope uses WeaveDNS to automatically discover other instances of Scope running on your network. If you have a running WeaveDNS setup, you do not need any further steps.

If you do not wish to use WeaveDNS, you can instruct Scope to cluster with other Scope instances on the command line. Hostnames and IP addresses are acceptable, both with and without ports:

```
# weave launch scope1:4040 192.168.0.12 192.168.0.11:4040
```
8 changes: 6 additions & 2 deletions scope
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#!/bin/bash

usage() {
echo "$0 (launch|stop)"
echo "Usage:"
echo "scope launch [<peer> ...]"
echo "scope stop"
echo
echo "scope <peer> is of the form <ip_address_or_fqdn>[:<port>]"
exit 1
}

SCOPE_IMAGE=weaveworks/scope
Expand Down Expand Up @@ -118,7 +123,6 @@ container_ip() {
case "$COMMAND" in

launch)
[ $# -eq 0 ] || usage
check_not_running $CONTAINER_NAME $IMAGE

# If WeaveDNS is running, we want to automatically tell the scope
Expand Down

0 comments on commit 8231987

Please sign in to comment.