From a113da0e34b2cd9620354fbe2702930f6f1a618e Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 29 Aug 2014 14:44:50 +0100 Subject: [PATCH 01/10] Added a new command 'weave status', implemented via an http listener #11 --- consts.go | 1 + http_responder.go | 34 ++++++++++++++++++++++++++++++++++ weaver/main.go | 6 ++++-- weaver/weave | 24 +++++++++++++++++++++--- 4 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 http_responder.go diff --git a/consts.go b/consts.go index 106e1c8e..6d4074a2 100644 --- a/consts.go +++ b/consts.go @@ -10,6 +10,7 @@ const ( EthernetOverhead = 14 UDPOverhead = 28 // 20 bytes for IPv4, 8 bytes for UDP Port = 6783 + StatusPort = Port+1 DefaultPMTU = 65535 MaxUDPPacketSize = 65536 ChannelSize = 16 diff --git a/http_responder.go b/http_responder.go new file mode 100644 index 00000000..bf2ff05c --- /dev/null +++ b/http_responder.go @@ -0,0 +1,34 @@ +package weave + +import ( + "fmt" + "net/http" +) + +/* A simple http responder that will show the status of the router when asked, + e.g. via http://172.17.0.2/status +*/ +type HttpStatusResponder struct { + router *Router +} + +func NewHttpStatusResponder(router *Router) *HttpStatusResponder { + resp := &HttpStatusResponder{router} + return resp +} + +func (resp *HttpStatusResponder) SetRouter(newRouter *Router) { + resp.router = newRouter +} + +func (resp *HttpStatusResponder) ListenAndServe() { + http.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) { + if resp.router != nil { + fmt.Fprint(w, resp.router.Status()) + } else { + fmt.Fprintf(w, "Not initialized") + } + }) + address := fmt.Sprintf(":%d", StatusPort) + http.ListenAndServe(address, nil) +} diff --git a/weaver/main.go b/weaver/main.go index 174f9f93..27e89912 100644 --- a/weaver/main.go +++ b/weaver/main.go @@ -1,7 +1,7 @@ package main import ( - "github.com/zettio/weave" + "github.com/bboreham/weave" "code.google.com/p/gopacket/layers" "crypto/sha256" "flag" @@ -70,7 +70,7 @@ func main() { flag.IntVar(&bufSz, "bufsz", 8, "capture buffer size in MB (defaults to 8MB)") flag.Parse() peers = flag.Args() - + if ifaceName == "" { fmt.Println("Missing required parameter 'iface'") os.Exit(1) @@ -123,6 +123,8 @@ func main() { } }() } + httpResponder := weave.NewHttpStatusResponder(router) + go httpResponder.ListenAndServe() handleSignals(router) } diff --git a/weaver/weave b/weaver/weave index e6bd3143..a7dee039 100755 --- a/weaver/weave +++ b/weaver/weave @@ -13,10 +13,14 @@ usage() { echo "Usage:" echo "weave / launch [-passwd ] ..." echo "weave / run ..." + echo "weave status" exit 1 } -shift 2 || usage +if [ "$#" -lt 1 ]; then + usage +exit 1 +fi [ `id -u` = 0 ] || { echo "weave must be run as 'root'" @@ -46,10 +50,25 @@ MACADDR=`cat /sys/class/net/$BRIDGE/address` case "$COMMAND" in launch) + shift 2 CONTAINER=$(docker run --privileged -d --name=weave -p 6783:6783/tcp -p 6783:6783/udp $WEAVE_DOCKER_ARGS zettio/weave -name $MACADDR "$@") IFACE=eth0 ;; + status) + DOCKERIP=$(docker inspect --format='{{ .NetworkSettings.IPAddress }}' weave) + if command -v wget >/dev/null 2>&1 ; then + wget -O - -q $DOCKERIP:6784/status + elif command -v curl >/dev/null 2>&1 ; then + curl $DOCKERIP:6784/status + else + echo "weave status needs either curl or wget to function" >&2 + exit 1 + fi + # return the status from the wget or curl command, so if they fail then we fail. + exit $? + ;; run) + shift 2 CONTAINER=$(docker run -d "$@") IFACE=$CONTAINER_IFNAME ;; @@ -87,8 +106,7 @@ ip netns exec $NSPID ip link set $GUEST_IFNAME name $CONTAINER_IFNAME ip netns exec $NSPID ip addr add $IPADDR dev $CONTAINER_IFNAME ip netns exec $NSPID ip link set $CONTAINER_IFNAME up -if [ command -v ethtool >/dev/null 2>&1 ] -then +if command -v ethtool >/dev/null 2>&1 ; then ip netns exec $NSPID ethtool -K $IFACE tx off > /dev/null else echo "Cannot find ethtool; continuing without it" >&2 From 94e00e2c8ec41de74325aaa79d1dc0134d48b1f4 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 29 Aug 2014 14:51:31 +0100 Subject: [PATCH 02/10] ran 'go fmt'; cosmetic changes --- consts.go | 2 +- http_responder.go | 30 +++++++++++++++--------------- weaver/main.go | 8 ++++---- weaver/weave | 3 ++- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/consts.go b/consts.go index 6d4074a2..30704df6 100644 --- a/consts.go +++ b/consts.go @@ -10,7 +10,7 @@ const ( EthernetOverhead = 14 UDPOverhead = 28 // 20 bytes for IPv4, 8 bytes for UDP Port = 6783 - StatusPort = Port+1 + StatusPort = Port + 1 DefaultPMTU = 65535 MaxUDPPacketSize = 65536 ChannelSize = 16 diff --git a/http_responder.go b/http_responder.go index bf2ff05c..29cfd299 100644 --- a/http_responder.go +++ b/http_responder.go @@ -2,33 +2,33 @@ package weave import ( "fmt" - "net/http" + "net/http" ) /* A simple http responder that will show the status of the router when asked, - e.g. via http://172.17.0.2/status +e.g. via http://172.17.0.2/status */ type HttpStatusResponder struct { - router *Router + router *Router } func NewHttpStatusResponder(router *Router) *HttpStatusResponder { - resp := &HttpStatusResponder{router} - return resp + resp := &HttpStatusResponder{router} + return resp } func (resp *HttpStatusResponder) SetRouter(newRouter *Router) { - resp.router = newRouter + resp.router = newRouter } func (resp *HttpStatusResponder) ListenAndServe() { - http.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) { - if resp.router != nil { - fmt.Fprint(w, resp.router.Status()) - } else { - fmt.Fprintf(w, "Not initialized") - } - }) - address := fmt.Sprintf(":%d", StatusPort) - http.ListenAndServe(address, nil) + http.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) { + if resp.router != nil { + fmt.Fprint(w, resp.router.Status()) + } else { + fmt.Fprintf(w, "Not initialized") + } + }) + address := fmt.Sprintf(":%d", StatusPort) + http.ListenAndServe(address, nil) } diff --git a/weaver/main.go b/weaver/main.go index 27e89912..e8c210e3 100644 --- a/weaver/main.go +++ b/weaver/main.go @@ -1,7 +1,7 @@ package main import ( - "github.com/bboreham/weave" + "github.com/zettio/weave" "code.google.com/p/gopacket/layers" "crypto/sha256" "flag" @@ -70,7 +70,7 @@ func main() { flag.IntVar(&bufSz, "bufsz", 8, "capture buffer size in MB (defaults to 8MB)") flag.Parse() peers = flag.Args() - + if ifaceName == "" { fmt.Println("Missing required parameter 'iface'") os.Exit(1) @@ -123,8 +123,8 @@ func main() { } }() } - httpResponder := weave.NewHttpStatusResponder(router) - go httpResponder.ListenAndServe() + httpResponder := weave.NewHttpStatusResponder(router) + go httpResponder.ListenAndServe() handleSignals(router) } diff --git a/weaver/weave b/weaver/weave index a7dee039..7c71675d 100755 --- a/weaver/weave +++ b/weaver/weave @@ -106,7 +106,8 @@ ip netns exec $NSPID ip link set $GUEST_IFNAME name $CONTAINER_IFNAME ip netns exec $NSPID ip addr add $IPADDR dev $CONTAINER_IFNAME ip netns exec $NSPID ip link set $CONTAINER_IFNAME up -if command -v ethtool >/dev/null 2>&1 ; then +if [ command -v ethtool >/dev/null 2>&1 ] +then ip netns exec $NSPID ethtool -K $IFACE tx off > /dev/null else echo "Cannot find ethtool; continuing without it" >&2 From 3942f19897c3ee655ac00ba9af5fd97d759181f4 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 29 Aug 2014 15:26:04 +0100 Subject: [PATCH 03/10] Remove boilerplate and condense the http handler down to one function. Also fixed indenting on one line in shell script. --- http_responder.go | 34 ---------------------------------- weaver/main.go | 13 +++++++++++-- weaver/weave | 2 +- 3 files changed, 12 insertions(+), 37 deletions(-) delete mode 100644 http_responder.go diff --git a/http_responder.go b/http_responder.go deleted file mode 100644 index 29cfd299..00000000 --- a/http_responder.go +++ /dev/null @@ -1,34 +0,0 @@ -package weave - -import ( - "fmt" - "net/http" -) - -/* A simple http responder that will show the status of the router when asked, -e.g. via http://172.17.0.2/status -*/ -type HttpStatusResponder struct { - router *Router -} - -func NewHttpStatusResponder(router *Router) *HttpStatusResponder { - resp := &HttpStatusResponder{router} - return resp -} - -func (resp *HttpStatusResponder) SetRouter(newRouter *Router) { - resp.router = newRouter -} - -func (resp *HttpStatusResponder) ListenAndServe() { - http.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) { - if resp.router != nil { - fmt.Fprint(w, resp.router.Status()) - } else { - fmt.Fprintf(w, "Not initialized") - } - }) - address := fmt.Sprintf(":%d", StatusPort) - http.ListenAndServe(address, nil) -} diff --git a/weaver/main.go b/weaver/main.go index e8c210e3..92758700 100644 --- a/weaver/main.go +++ b/weaver/main.go @@ -9,6 +9,7 @@ import ( "github.com/davecheney/profile" "log" "net" + "net/http" "os" "os/signal" "runtime" @@ -123,11 +124,19 @@ func main() { } }() } - httpResponder := weave.NewHttpStatusResponder(router) - go httpResponder.ListenAndServe() + go handleHttp(router) handleSignals(router) } +func handleHttp(router *weave.Router) { + http.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, router.Status()) + }) + address := fmt.Sprintf(":%d", weave.StatusPort) + http.ListenAndServe(address, nil) +} + + func handleSignals(router *weave.Router) { sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGQUIT, syscall.SIGUSR1) diff --git a/weaver/weave b/weaver/weave index 1b89e749..ab0b591f 100755 --- a/weaver/weave +++ b/weaver/weave @@ -19,7 +19,7 @@ usage() { if [ "$#" -lt 1 ]; then usage -exit 1 + exit 1 fi [ `id -u` = 0 ] || { From c8da7131a5f62ac660f5d1c29a5da994434d7b2a Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 29 Aug 2014 15:35:27 +0100 Subject: [PATCH 04/10] Add back the usage test for two arguments, except when the command is 'status' --- weaver/weave | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weaver/weave b/weaver/weave index fbf6cf96..25624042 100755 --- a/weaver/weave +++ b/weaver/weave @@ -17,7 +17,7 @@ usage() { exit 1 } -if [ "$#" -lt 1 ]; then +if [ "$COMMAND" != "status" -a "$#" -lt 2 ]; then usage exit 1 fi From 48bcaa7851ad6896155b9b08144c0befb258e3fb Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 29 Aug 2014 15:49:25 +0100 Subject: [PATCH 05/10] Pull out ugly 'command -v' code to a utility function --- weaver/weave | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/weaver/weave b/weaver/weave index 25624042..6ed51262 100755 --- a/weaver/weave +++ b/weaver/weave @@ -17,6 +17,12 @@ usage() { exit 1 } +# utility function to check whether a command can be executed by the shell +# see http://stackoverflow.com/questions/592620/how-to-check-if-a-program-exists-from-a-bash-script +command_exists () { + command -v $1 >/dev/null 2>&1 +} + if [ "$COMMAND" != "status" -a "$#" -lt 2 ]; then usage exit 1 @@ -56,9 +62,9 @@ case "$COMMAND" in ;; status) DOCKERIP=$(docker inspect --format='{{ .NetworkSettings.IPAddress }}' weave) - if command -v wget >/dev/null 2>&1 ; then + if command_exists wget ; then wget -O - -q $DOCKERIP:6784/status - elif command -v curl >/dev/null 2>&1 ; then + elif command_exists curl ; then curl $DOCKERIP:6784/status else echo "weave status needs either curl or wget to function" >&2 @@ -106,7 +112,7 @@ ip netns exec $NSPID ip link set $GUEST_IFNAME name $CONTAINER_IFNAME ip netns exec $NSPID ip addr add $IPADDR dev $CONTAINER_IFNAME ip netns exec $NSPID ip link set $CONTAINER_IFNAME up -if command -v ethtool >/dev/null 2>&1 +if command_exists ethtool then ip netns exec $NSPID ethtool -K $IFACE tx off > /dev/null else From 67d8220bdf1590e1878ec3912e84242ff29f024d Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 4 Sep 2014 13:04:19 +0100 Subject: [PATCH 06/10] Convert one further use of 'command -v' into the function command_exists --- weaver/weave | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weaver/weave b/weaver/weave index 47a3196d..d6c208bb 100755 --- a/weaver/weave +++ b/weaver/weave @@ -123,7 +123,7 @@ case "$COMMAND" in stop) docker kill weave > /dev/null docker rm weave > /dev/null - if command -v conntrack >/dev/null 2>&1 + if command_exists conntrack then conntrack -D -p udp --dport 6783 >/dev/null 2>&1 else From 04ca3d24697760e86beaee74d1a8fdee730aa190 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 4 Sep 2014 14:44:42 +0100 Subject: [PATCH 07/10] Addressed various points raised in review: error-handling, simplified Fprint call --- weaver/main.go | 8 ++++++-- weaver/weave | 9 ++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/weaver/main.go b/weaver/main.go index b9cd3670..38c234af 100644 --- a/weaver/main.go +++ b/weaver/main.go @@ -6,6 +6,7 @@ import ( "crypto/sha256" "flag" "fmt" + "io" "github.com/davecheney/profile" "log" "net" @@ -136,10 +137,13 @@ func main() { func handleHttp(router *weave.Router) { http.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, router.Status()) + io.WriteString(w, router.Status()) }) address := fmt.Sprintf(":%d", weave.StatusPort) - http.ListenAndServe(address, nil) + err := http.ListenAndServe(address, nil) + if err != nil { + log.Fatal("ListenAndServe: ", err) + } } diff --git a/weaver/weave b/weaver/weave index d6c208bb..0ef1e761 100755 --- a/weaver/weave +++ b/weaver/weave @@ -80,16 +80,19 @@ case "$COMMAND" in ;; status) DOCKERIP=$(docker inspect --format='{{ .NetworkSettings.IPAddress }}' weave) + if [ -z "$DOCKERIP" ] ; then + echo "The weave container is not running." >&2 + exit 1 + fi if command_exists wget ; then wget -O - -q $DOCKERIP:6784/status elif command_exists curl ; then curl $DOCKERIP:6784/status else - echo "weave status needs either curl or wget to function" >&2 + echo "Cannot find wget or curl. Install one of them for 'weave status' to function." >&2 exit 1 fi - # return the status from the wget or curl command, so if they fail then we fail. - exit $? + exit 0 ;; run) [ $# -gt 0 ] || usage From c930ef38dcde9bfef4eb2c089aa093fb9fdf411d Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 4 Sep 2014 14:59:48 +0100 Subject: [PATCH 08/10] Improved error message on http ListenAndServe --- weaver/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weaver/main.go b/weaver/main.go index 38c234af..c0be4ea5 100644 --- a/weaver/main.go +++ b/weaver/main.go @@ -142,7 +142,7 @@ func handleHttp(router *weave.Router) { address := fmt.Sprintf(":%d", weave.StatusPort) err := http.ListenAndServe(address, nil) if err != nil { - log.Fatal("ListenAndServe: ", err) + log.Fatal("Unable to create http listener: ", err) } } From 733af3f1082b600dd596dc41d5e6258a444b90ed Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 4 Sep 2014 15:24:18 +0100 Subject: [PATCH 09/10] Swap round 'status' and 'stop' in usage --- weaver/weave | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weaver/weave b/weaver/weave index 0ef1e761..4b323d7a 100755 --- a/weaver/weave +++ b/weaver/weave @@ -7,8 +7,8 @@ usage() { echo "weave run / ..." echo "weave expose /" echo "weave hide /" - echo "weave stop" echo "weave status" + echo "weave stop" exit 1 } From f8ae0cd3f6798fc0689f06a13ac6266f576c5401 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 4 Sep 2014 15:27:38 +0100 Subject: [PATCH 10/10] =?UTF-8?q?Add=20=E2=80=98weave=20status=E2=80=99=20?= =?UTF-8?q?to=20the=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index abd2a532..649e2d83 100644 --- a/README.md +++ b/README.md @@ -349,12 +349,9 @@ The log verbosity can be increased by supplying the `-debug` flag when launching weave. Be warned, this will log information on a per-packet basis, so can produce a lot of output. -One can ask a weave router to log a status report by sending it a USR1 -signal, e.g. +One can ask a weave router to report its status with - kill -USR1 `docker inspect --format='{{ .State.Pid }}' weave` - -and then inspect the logs. + weave status ## Installation with Boot2Docker