mirror of
https://github.com/weaveworks/scope.git
synced 2026-08-23 22:36:24 +00:00
Yet More Plumbing for multi-host setup.
- 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
This commit is contained in:
+2
-3
@@ -10,7 +10,6 @@ import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@@ -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":
|
||||
@@ -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)
|
||||
|
||||
+29
-8
@@ -3,7 +3,11 @@ package main
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/weaveworks/scope/xfer"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
|
||||
+36
-18
@@ -1,10 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/weaveworks/scope/xfer"
|
||||
)
|
||||
|
||||
func TestResolver(t *testing.T) {
|
||||
@@ -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 {
|
||||
@@ -42,16 +46,30 @@ func TestResolver(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
ip1 := "1.2.3.4"
|
||||
ips = makeIPs(ip1)
|
||||
c <- time.Now() // trigger a resolve
|
||||
assertAdd(ip1 + port) // we want 1 add
|
||||
// Initial resolve should just give us IPs
|
||||
assertAdd(ip1 + port)
|
||||
assertAdd(fmt.Sprintf("%s:%d", ip2, xfer.ProbePort))
|
||||
|
||||
ip2 := "10.10.10.10"
|
||||
ips = makeIPs(ip1, ip2)
|
||||
// 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(ip3 + port) // we want 1 add
|
||||
assertAdd(ip1 + port)
|
||||
assertAdd(fmt.Sprintf("%s:%d", ip2, xfer.ProbePort))
|
||||
|
||||
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) }()
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec /home/weave/app
|
||||
exec /home/weave/app $(cat /etc/weave/probes)
|
||||
|
||||
@@ -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
|
||||
```
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user