Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yet More Plumbing for multi-host setup. #141

Merged
merged 1 commit into from
Jun 1, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
37 changes: 29 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
)

if strings.Contains(s, ":") {
var err error
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,16 @@ 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
if addr := net.ParseIP(peer.hostname); addr != nil {
addrs = []net.IP{addr}
} else {
var err error
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:4030 192.168.0.12 192.168.0.11:4030
```
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