From a750ef8033337647eb31cff8e61563b018be98d4 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Mon, 11 Jan 2016 16:29:00 +0000 Subject: [PATCH 1/5] Don't check if container is running when we only want its ID. This avoids trying to decide if "restarting" is as good as "running". In wait_for_status we now explitly check_running, and in dns_add/remove we add an extra check_running test. --- weave | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/weave b/weave index b2da6ed8..fe071c42 100755 --- a/weave +++ b/weave @@ -951,23 +951,14 @@ stop() { } # Given a container name or short ID in $1, ensure the specified -# container is running and then print its full ID to stdout. If -# it's not running or doesn't exist, print an error to stderr and +# container exists and then print its full ID to stdout. If +# it doesn't exist, print an error to stderr and # return with an indicative non-zero exit code. container_id() { - if ! status=$(docker inspect --format='{{.State.Running}} {{.Id}}' $1 2>/dev/null) ; then + if ! docker inspect --format='{{.Id}}' $1 2>/dev/null ; then echo "Error: No such container: $1" >&2 return 1 fi - case "$status" in - true*) - echo "${status#true }" - ;; - *) - echo "$1 container is not running." >&2 - return 2 - ;; - esac } container_ip() { @@ -1033,7 +1024,7 @@ wait_for_status() { shift while true ; do "$@" GET /status >/dev/null 2>&1 && return 0 - if ! container_id $container >/dev/null 2>&1 ; then + if ! check_running $container >/dev/null 2>&1 ; then echo $(death_msg $container) >&2 return 1 fi @@ -1286,6 +1277,7 @@ collect_dns_add_remove_args() { [ $# -eq 0 -a \( -n "$C" -o \( $IP_COUNT -gt 0 -a -n "$FQDN" \) \) ] || usage check_running $CONTAINER_NAME if [ -n "$C" ] ; then + check_running $C CONTAINER=$(container_id $C) [ $IP_COUNT -gt 0 ] || IP_ARGS=$(with_container_addresses echo_ips $CONTAINER) fi From c2a869491fb0ca62b292aacfea5223a99aa67c60 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Mon, 11 Jan 2016 14:21:08 +0000 Subject: [PATCH 2/5] Check State.Restarting as well as State.Running --- weave | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/weave b/weave index fe071c42..7c785227 100755 --- a/weave +++ b/weave @@ -1200,10 +1200,13 @@ rewrite_etc_hosts() { # Print an error to stderr and return with an indicative exit status # if the container $1 does not exist or isn't running. check_running() { - if ! STATUS=$(docker inspect --format='{{.State.Running}}' $1 2>/dev/null) ; then + if ! STATUS=$(docker inspect --format='{{.State.Running}} {{.State.Restarting}}' $1 2>/dev/null) ; then echo "$1 container is not present. Have you launched it?" >&2 return 1 - elif [ "$STATUS" != "true" ] ; then + elif [ "$STATUS" == "true true" ] ; then + echo "$1 container is restarting." >&2 + return 2 + elif [ "$STATUS" != "true false" ] ; then echo "$1 container is not running." >&2 return 2 fi From 78f2d82984b0bdb3ef8c8ce7197ffc4b2ce71c7b Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 29 Jan 2016 17:25:37 +0000 Subject: [PATCH 3/5] Extract function to listen on Unix socket --- net/listen.go | 18 ++++++++++++++++++ prog/plugin/main.go | 9 ++------- proxy/proxy.go | 6 ++---- 3 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 net/listen.go diff --git a/net/listen.go b/net/listen.go new file mode 100644 index 00000000..628ec949 --- /dev/null +++ b/net/listen.go @@ -0,0 +1,18 @@ +package net + +import ( + "fmt" + "net" + "os" +) + +func ListenUnixSocket(pathname string) (net.Listener, error) { + if err := os.Remove(pathname); err != nil && !os.IsNotExist(err) { + return nil, fmt.Errorf("Error removing existing unix socket: %s", err) + } + listener, err := net.Listen("unix", pathname) + if err != nil { + return nil, fmt.Errorf("ListenUnixSocket failed: %s", err) + } + return listener, nil +} diff --git a/prog/plugin/main.go b/prog/plugin/main.go index 84440fee..29d04713 100644 --- a/prog/plugin/main.go +++ b/prog/plugin/main.go @@ -11,6 +11,7 @@ import ( "github.com/docker/libnetwork/ipamapi" . "github.com/weaveworks/weave/common" "github.com/weaveworks/weave/common/docker" + weavenet "github.com/weaveworks/weave/net" ipamplugin "github.com/weaveworks/weave/plugin/ipam" netplugin "github.com/weaveworks/weave/plugin/net" "github.com/weaveworks/weave/plugin/skel" @@ -101,13 +102,7 @@ func listenAndServe(dockerClient *docker.Client, address string, noMulticastRout } } - var listener net.Listener - - // remove sockets from last invocation - if err := os.Remove(address); err != nil && !os.IsNotExist(err) { - return nil, err - } - listener, err = net.Listen("unix", address) + listener, err := weavenet.ListenUnixSocket(address) if err != nil { return nil, err } diff --git a/proxy/proxy.go b/proxy/proxy.go index 1045fd51..748d298e 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -19,6 +19,7 @@ import ( docker "github.com/fsouza/go-dockerclient" . "github.com/weaveworks/weave/common" weavedocker "github.com/weaveworks/weave/common/docker" + weavenet "github.com/weaveworks/weave/net" ) const ( @@ -296,10 +297,7 @@ func (proxy *Proxy) Serve(listeners []net.Listener) { } func (proxy *Proxy) ListenAndServeStatus(socket string) { - if err := os.Remove(socket); err != nil && !os.IsNotExist(err) { - Log.Fatalf("Error removing existing status socket: %s", err) - } - listener, err := net.Listen("unix", socket) + listener, err := weavenet.ListenUnixSocket(socket) if err != nil { Log.Fatalf("ListenAndServeStatus failed: %s", err) } From 0a4b3a04ba891b150b5c20f859e281d5f0d75af5 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 29 Jan 2016 18:01:17 +0000 Subject: [PATCH 4/5] Wait for plugin status via unix socket --- prog/plugin/main.go | 15 +++++++++++++++ weave | 1 + 2 files changed, 16 insertions(+) diff --git a/prog/plugin/main.go b/prog/plugin/main.go index 29d04713..17ea2120 100644 --- a/prog/plugin/main.go +++ b/prog/plugin/main.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "net" + "net/http" "os" "os/signal" "syscall" @@ -77,6 +78,11 @@ func run(dockerClient *docker.Client, address, meshAddress string, noMulticastRo defer meshListener.Close() } + statusListener, err := weavenet.ListenUnixSocket("/home/weave/status.sock") + if err != nil { + return err + } + go serveStatus(statusListener) sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, os.Kill, syscall.SIGTERM) @@ -114,3 +120,12 @@ func listenAndServe(dockerClient *docker.Client, address string, noMulticastRout return listener, nil } + +func serveStatus(listener net.Listener) { + server := &http.Server{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "ok") + })} + if err := server.Serve(listener); err != nil { + Log.Fatalf("ListenAndServeStatus failed: %s", err) + } +} diff --git a/weave b/weave index 7c785227..bec9d62b 100755 --- a/weave +++ b/weave @@ -1724,6 +1724,7 @@ launch_plugin_if_not_running() { $PLUGIN_IMAGE "$@") ; then return 1 fi + wait_for_status $PLUGIN_CONTAINER_NAME http_call_unix $PLUGIN_CONTAINER_NAME status.sock util_op create-plugin-network weave weavemesh } From 38013d2f41760dffba144550362c0383ab7737ec Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 4 Feb 2016 12:52:16 +0000 Subject: [PATCH 5/5] Kill zombies --- weave | 1 + 1 file changed, 1 insertion(+) diff --git a/weave b/weave index bec9d62b..3e748f19 100755 --- a/weave +++ b/weave @@ -1025,6 +1025,7 @@ wait_for_status() { while true ; do "$@" GET /status >/dev/null 2>&1 && return 0 if ! check_running $container >/dev/null 2>&1 ; then + docker kill $container >/dev/null 2>&1 || true # stop it restarting echo $(death_msg $container) >&2 return 1 fi