From cb73b738621d57727072ae998cdeaec337f23a1a Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Wed, 27 May 2015 10:09:29 +0100 Subject: [PATCH 01/24] Fix bug of --with-ipam not setting entrypoints --- proxy/create_container_interceptor.go | 3 ++- proxy/create_exec_interceptor.go | 5 +++-- proxy/proxy.go | 4 ++-- test/620_proxy_entrypoint_command_test.sh | 6 ++++++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/proxy/create_container_interceptor.go b/proxy/create_container_interceptor.go index 2aa8c4dd..3aae2df4 100644 --- a/proxy/create_container_interceptor.go +++ b/proxy/create_container_interceptor.go @@ -15,6 +15,7 @@ type createContainerInterceptor struct { client *docker.Client withDNS bool dockerBridgeIP string + withIPAM bool } type createContainerRequestBody struct { @@ -35,7 +36,7 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error { return err } - if cidrs, ok := weaveCIDRsFromConfig(container.Config); ok { + if cidrs, ok := weaveCIDRsFromConfig(container.Config); ok || i.withIPAM { Info.Printf("Creating container with WEAVE_CIDR \"%s\"", strings.Join(cidrs, " ")) container.HostConfig.VolumesFrom = append(container.HostConfig.VolumesFrom, "weaveproxy") if err := i.setWeaveWaitEntrypoint(container.Config); err != nil { diff --git a/proxy/create_exec_interceptor.go b/proxy/create_exec_interceptor.go index 00050115..e3a9bc30 100644 --- a/proxy/create_exec_interceptor.go +++ b/proxy/create_exec_interceptor.go @@ -11,7 +11,8 @@ import ( ) type createExecInterceptor struct { - client *docker.Client + client *docker.Client + withIPAM bool } type createExecRequestBody struct { @@ -37,7 +38,7 @@ func (i *createExecInterceptor) InterceptRequest(r *http.Request) error { return err } - if cidrs, ok := weaveCIDRsFromConfig(container.Config); ok { + if cidrs, ok := weaveCIDRsFromConfig(container.Config); ok || i.withIPAM { Info.Printf("Exec in container %s with WEAVE_CIDR \"%s\"", container.ID, strings.Join(cidrs, " ")) options.Cmd = append(weaveWaitEntrypoint, options.Cmd...) } diff --git a/proxy/proxy.go b/proxy/proxy.go index 03ba90eb..ee820a21 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -68,11 +68,11 @@ func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { path := r.URL.Path switch { case containerCreateRegexp.MatchString(path): - proxy.serveWithInterceptor(&createContainerInterceptor{proxy.client, proxy.withDNS, proxy.dockerBridgeIP}, w, r) + proxy.serveWithInterceptor(&createContainerInterceptor{proxy.client, proxy.withDNS, proxy.dockerBridgeIP, proxy.withIPAM}, w, r) case containerStartRegexp.MatchString(path): proxy.serveWithInterceptor(&startContainerInterceptor{proxy.client, proxy.withDNS, proxy.withIPAM}, w, r) case execCreateRegexp.MatchString(path): - proxy.serveWithInterceptor(&createExecInterceptor{proxy.client}, w, r) + proxy.serveWithInterceptor(&createExecInterceptor{proxy.client, proxy.withIPAM}, w, r) case strings.HasPrefix(path, "/weave"): w.WriteHeader(http.StatusOK) default: diff --git a/test/620_proxy_entrypoint_command_test.sh b/test/620_proxy_entrypoint_command_test.sh index 73c6401c..e03b9a10 100755 --- a/test/620_proxy_entrypoint_command_test.sh +++ b/test/620_proxy_entrypoint_command_test.sh @@ -26,4 +26,10 @@ run_container "grep ^1$ /sys/class/net/ethwe/carrier" build_image false '["/bin/false"]' '' run_container "--entrypoint='grep' false ^1$ /sys/class/net/ethwe/carrier" +weave_on $HOST1 launch -iprange 10.2.2.0/24 +docker_on $HOST1 kill weaveproxy +weave_on $HOST1 launch-proxy --with-ipam + +assert_raises "proxy docker_on $HOST1 run check-ethwe-up" + end_suite From 169eb195235b99ec5f223f503458670fb064470f Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Thu, 28 May 2015 12:54:21 +0100 Subject: [PATCH 02/24] allow proxy to intercept unversioned (i.e. 1.0) urls --- proxy/common.go | 4 ++-- proxy/proxy.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/proxy/common.go b/proxy/common.go index 1198ef1b..6f6480fb 100644 --- a/proxy/common.go +++ b/proxy/common.go @@ -15,7 +15,7 @@ import ( ) var ( - containerIDRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/([^/]*)/.*") + containerIDRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/([^/]*)/.*") weaveWaitEntrypoint = []string{"/home/weavewait/weavewait"} ) @@ -54,7 +54,7 @@ func inspectContainerInPath(client *docker.Client, path string) (*docker.Contain Warning.Println(err) return nil, err } - containerID := subs[1] + containerID := subs[2] container, err := client.InspectContainer(containerID) if err != nil { diff --git a/proxy/proxy.go b/proxy/proxy.go index ee820a21..f781385b 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -12,9 +12,9 @@ import ( ) var ( - containerCreateRegexp = regexp.MustCompile("/v[0-9\\.]*/containers/create") - containerStartRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/[^/]*/(re)?start$") - execCreateRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/[^/]*/exec$") + containerCreateRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/create$") + containerStartRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/[^/]*/(re)?start$") + execCreateRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/[^/]*/exec$") ) type Proxy struct { From c8b95a252748b84fe2328ea9daf76258bfebcf97 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Thu, 28 May 2015 16:12:48 +0100 Subject: [PATCH 03/24] fix bug in proxy handling of minimal request bodies --- proxy/create_container_interceptor.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proxy/create_container_interceptor.go b/proxy/create_container_interceptor.go index 3aae2df4..3585fbd2 100644 --- a/proxy/create_container_interceptor.go +++ b/proxy/create_container_interceptor.go @@ -38,7 +38,13 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error { if cidrs, ok := weaveCIDRsFromConfig(container.Config); ok || i.withIPAM { Info.Printf("Creating container with WEAVE_CIDR \"%s\"", strings.Join(cidrs, " ")) + if container.HostConfig == nil { + container.HostConfig = &docker.HostConfig{} + } container.HostConfig.VolumesFrom = append(container.HostConfig.VolumesFrom, "weaveproxy") + if container.Config == nil { + container.Config = &docker.Config{} + } if err := i.setWeaveWaitEntrypoint(container.Config); err != nil { return err } From 147c7f503ca3b88772bc5a4641ca5d6f25a48ec8 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Thu, 28 May 2015 16:13:42 +0100 Subject: [PATCH 04/24] add curl test for proxy v1.0 api support --- test/620_proxy_entrypoint_command_test.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/620_proxy_entrypoint_command_test.sh b/test/620_proxy_entrypoint_command_test.sh index e03b9a10..d216077d 100755 --- a/test/620_proxy_entrypoint_command_test.sh +++ b/test/620_proxy_entrypoint_command_test.sh @@ -32,4 +32,22 @@ weave_on $HOST1 launch-proxy --with-ipam assert_raises "proxy docker_on $HOST1 run check-ethwe-up" +create_container_json=$(cat <<-EOF +{ + "Hostname":"c1", + "AttachStdin":false, + "AttachStdout":true, + "AttachStderr":true, + "Tty":false, + "OpenStdin":false, + "StdinOnce":false, + "Image":"check-ethwe-up" +} +EOF +) + +# Test a minimal request to the unversioned (v1.0) docker api +CONTAINER_ID=$(curl -s -X POST --header "Content-Type: application/json" http://$HOST1:12375/containers/create -d "$create_container_json" | sed -e 's/.*"Id":"\([^"]*\)".*/\1/') +assert_raises "proxy docker_on $HOST1 start -ai $CONTAINER_ID" + end_suite From af5531cbf62fbc179f74141feac765ec290c8a45 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 28 May 2015 18:12:30 +0100 Subject: [PATCH 05/24] Fix incorrect calculation of free space when granting a range that spans a token and inserting a new token, the free space on the last token that we are handing over has to change. Add unit test for this too. --- ipam/address/address.go | 7 +++++++ ipam/ring/ring.go | 2 +- ipam/ring/ring_test.go | 11 +++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ipam/address/address.go b/ipam/address/address.go index b9f47ac3..97e162d0 100644 --- a/ipam/address/address.go +++ b/ipam/address/address.go @@ -52,3 +52,10 @@ func Subtract(a, b Address) Offset { common.Assert(a >= b) return Offset(a - b) } + +func Min(a, b Offset) Offset { + if a > b { + return b + } + return a +} diff --git a/ipam/ring/ring.go b/ipam/ring/ring.go index 7590a3ce..16ae1451 100644 --- a/ipam/ring/ring.go +++ b/ipam/ring/ring.go @@ -167,7 +167,7 @@ func (r *Ring) GrantRangeToHost(start, end address.Address, peer router.PeerName pos := preceedingPos + 1 for ; pos < len(r.Entries) && r.Entries.entry(pos).Token < end; pos++ { entry := r.Entries.entry(pos) - entry.update(peer, entry.Free) + entry.update(peer, address.Min(entry.Free, r.distance(entry.Token, end))) } // There is never an entry with a token of r.End, as the end of diff --git a/ipam/ring/ring_test.go b/ipam/ring/ring_test.go index 1c12c777..f3ec1e0f 100644 --- a/ipam/ring/ring_test.go +++ b/ipam/ring/ring_test.go @@ -158,6 +158,17 @@ func TestGrantSplit(t *testing.T) { wt.AssertEquals(t, ring1.Entries, entries{{Token: start, Peer: peer1name, Free: 10, Version: 1}, {Token: dot10, Peer: peer2name, Free: 235}, {Token: dot245, Peer: peer1name, Free: 10}}) + ring1.assertInvariants() + + // Grant range spanning a live token, and inserting a new token + ring1.Entries = []*entry{{Token: start, Peer: peer1name, Free: 10, Version: 2}, + {Token: dot10, Peer: peer1name, Free: 118}, {Token: middle, Peer: peer1name, Free: 127}} + ring1.GrantRangeToHost(dot10, dot245, peer2name) + wt.AssertEquals(t, ring1.Entries, entries{{Token: start, Peer: peer1name, Free: 10, Version: 2}, + {Token: dot10, Peer: peer2name, Free: 118, Version: 1}, + {Token: middle, Peer: peer2name, Free: 117, Version: 1}, + {Token: dot245, Peer: peer1name, Free: 10, Version: 0}}) + ring1.assertInvariants() } func TestMergeSimple(t *testing.T) { From 915bf392e9aa772bc59d4ff1c7407b6c5394ff72 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 28 May 2015 16:22:22 +0100 Subject: [PATCH 06/24] Improve error reporting of too much free space --- ipam/ring/ring.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ipam/ring/ring.go b/ipam/ring/ring.go index 16ae1451..1bb891f4 100644 --- a/ipam/ring/ring.go +++ b/ipam/ring/ring.go @@ -40,7 +40,6 @@ var ( ErrInvalidEntry = errors.New("Received invalid state update!") ErrEntryInMyRange = errors.New("Received new entry in my range!") ErrNoFreeSpace = errors.New("No free space found!") - ErrTooMuchFreeSpace = errors.New("Entry reporting too much free space!") ErrInvalidTimeout = errors.New("dt must be greater than 0") ErrNotFound = errors.New("No entries for peer found") ) @@ -76,7 +75,7 @@ func (r *Ring) checkInvariants() error { distance := r.distance(entry.Token, next.Token) if entry.Free > distance { - return ErrTooMuchFreeSpace + return fmt.Errorf("Entry %s-%s reporting too much free space: %d > %d", entry.Token, next.Token, entry.Free, distance) } } From 20c9bc04a7b7cb4923097fd0c9d3135db36e1d1d Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Thu, 28 May 2015 16:33:48 +0100 Subject: [PATCH 07/24] simplifying and standardizing `launch-proxy` --- weave | 92 ++++++++++++++++++++++------------------------------------- 1 file changed, 34 insertions(+), 58 deletions(-) diff --git a/weave b/weave index 8460bd9e..50297d8b 100755 --- a/weave +++ b/weave @@ -167,6 +167,13 @@ MTU=65535 PORT=${WEAVE_PORT:-6783} HTTP_PORT=6784 DNS_HTTP_PORT=6785 +PROXY_PORT=12375 +PROXY_CONTAINER_NAME=weaveproxy +PROXY_HOST="localhost" +if [[ "$DOCKER_HOST" == "tcp://"* ]]; then + PROXY_HOST=$(echo "$DOCKER_HOST" | sed -e "s|tcp://\([^:]*\):[0-9]*|\1|") +fi + ###################################################################### # general helpers; independent of docker and weave @@ -540,6 +547,18 @@ wait_for_status() { return 1 } +# Just like wait_for_status, but takes the IP instead of a container ID +wait_for_status_ip() { + WAIT_TIME=0 + while [ $WAIT_TIME -lt 3 ]; do + sleep $WAIT_TIME + http_call_ip $1 $2 GET ${3:-/status} >/dev/null && return 0 + WAIT_TIME=$((WAIT_TIME+1)) + done + echo "Timed out waiting for container to start." >&2 + return 1 +} + # Call $1 for all containers, passing container ID, all MACs and all IPs with_container_addresses() { COMMAND=$1 @@ -688,63 +707,6 @@ get_ipam_cidr() { fi } -###################################################################### -# weave proxy helpers -###################################################################### - -PROXY_PORT=12375 -PROXY_CONTAINER_NAME=weaveproxy - -proxy_host() { - case $DOCKER_HOST in - tcp://*) - PROXY_HOST=$(echo $DOCKER_HOST | sed -e "s|tcp://\([^:]*\):[0-9]*|\1|") - ;; - *) - PROXY_HOST="localhost" - ;; - esac -} - -wait_for_proxy_to_boot() { - proxy_host - for n in $(seq 1 10); do - if curl --max-time 1 --connect-timeout 1 -s -X GET http://$PROXY_HOST:$PROXY_PORT/weave ; then - return 0 - fi - sleep 1 - done - echo "Proxy did not start within 10 seconds" >&2 - return 1 -} - -ensure_proxy_running() { - case $(docker inspect --format '{{.State.Running}} {{.Config.Image}}' $PROXY_CONTAINER_NAME 2>/dev/null) in - "true $EXEC_IMAGE") - return 0 - ;; - true*) - echo "Proxy already running with unknown image" >&2 - exit 1 - ;; - false*) - docker rm -f $PROXY_CONTAINER_NAME >/dev/null - ;; - esac - # Set WEAVEPROXY_DOCKER_ARGS in the environment in order to supply - # additional parameters, such as resource limits, to docker - # when launching the weave proxy container. - PROXY_CONTAINER=$(docker run --privileged --net=host -d \ - --name=$PROXY_CONTAINER_NAME \ - -p $PROXY_PORT:$PROXY_PORT/tcp -v /var/run/docker.sock:/var/run/docker.sock \ - -v /proc:/hostproc -e PROCFS=/hostproc \ - --entrypoint=/home/weave/weaveproxy \ - $WEAVE_DOCKER_ARGS $WEAVEPROXY_DOCKER_ARGS \ - $EXEC_IMAGE "$@") - - wait_for_proxy_to_boot -} - ########################################################################################## [ $(id -u) = 0 ] || { @@ -874,7 +836,21 @@ case "$COMMAND" in echo $DNS_CONTAINER ;; launch-proxy) - ensure_proxy_running "$@" + check_not_running $PROXY_CONTAINER_NAME $EXEC_IMAGE + # Set WEAVEPROXY_DOCKER_ARGS in the environment in order to supply + # additional parameters, such as resource limits, to docker + # when launching the weave proxy container. + PROXY_CONTAINER=$(docker run --privileged --net=host -d \ + --name=$PROXY_CONTAINER_NAME \ + -p $PROXY_PORT:$PROXY_PORT/tcp \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /proc:/hostproc -e PROCFS=/hostproc \ + --entrypoint=/home/weave/weaveproxy \ + $WEAVE_DOCKER_ARGS \ + $WEAVEPROXY_DOCKER_ARGS \ + $EXEC_IMAGE "$@") + + wait_for_status_ip $PROXY_HOST $PROXY_PORT /weave echo $PROXY_CONTAINER ;; connect) From f919ef12d08596b8992f58957200340075a630a5 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Thu, 28 May 2015 17:09:17 +0100 Subject: [PATCH 08/24] fix bug with WEAVEPROXY_DOCKER_ARGS not being passed through --- weave | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/weave b/weave index 50297d8b..4914a47f 100755 --- a/weave +++ b/weave @@ -61,6 +61,7 @@ exec_remote() { -e WEAVE_DEBUG \ -e WEAVE_DOCKER_ARGS \ -e WEAVEDNS_DOCKER_ARGS \ + -e WEAVEPROXY_DOCKER_ARGS \ -e WEAVE_PASSWORD \ -e WEAVE_PORT \ -e WEAVE_CONTAINER_NAME \ @@ -839,14 +840,13 @@ case "$COMMAND" in check_not_running $PROXY_CONTAINER_NAME $EXEC_IMAGE # Set WEAVEPROXY_DOCKER_ARGS in the environment in order to supply # additional parameters, such as resource limits, to docker - # when launching the weave proxy container. + # when launching the weaveproxy container. PROXY_CONTAINER=$(docker run --privileged --net=host -d \ --name=$PROXY_CONTAINER_NAME \ -p $PROXY_PORT:$PROXY_PORT/tcp \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /proc:/hostproc -e PROCFS=/hostproc \ --entrypoint=/home/weave/weaveproxy \ - $WEAVE_DOCKER_ARGS \ $WEAVEPROXY_DOCKER_ARGS \ $EXEC_IMAGE "$@") From 0cb2e80e0968afcc750436671b7e1f687de54875 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 29 May 2015 10:45:56 +0100 Subject: [PATCH 09/24] Proxy kills container and returns error when attach fails --- proxy/client.go | 4 ++-- proxy/start_container_interceptor.go | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/proxy/client.go b/proxy/client.go index 57cf98f4..87e1a968 100644 --- a/proxy/client.go +++ b/proxy/client.go @@ -35,7 +35,7 @@ func (c *client) ServeHTTP(w http.ResponseWriter, r *http.Request) { case err == docker.ErrNoSuchImage: http.Error(w, err.Error(), http.StatusNotFound) default: - http.Error(w, "Unable to intercept request", http.StatusInternalServerError) + http.Error(w, err.Error(), http.StatusInternalServerError) Warning.Print("Error intercepting request: ", err) } return @@ -58,7 +58,7 @@ func (c *client) ServeHTTP(w http.ResponseWriter, r *http.Request) { } err = c.InterceptResponse(resp) if err != nil { - http.Error(w, "Unable to intercept response", http.StatusInternalServerError) + http.Error(w, err.Error(), http.StatusInternalServerError) Warning.Print("Error intercepting response: ", err) return } diff --git a/proxy/start_container_interceptor.go b/proxy/start_container_interceptor.go index bce86074..1b95c733 100644 --- a/proxy/start_container_interceptor.go +++ b/proxy/start_container_interceptor.go @@ -1,6 +1,7 @@ package proxy import ( + "errors" "net/http" "strings" @@ -33,8 +34,10 @@ func (i *startContainerInterceptor) InterceptResponse(r *http.Response) error { args := []string{"attach"} args = append(args, cidrs...) args = append(args, container.ID) - if _, err := callWeave(args...); err != nil { - Warning.Printf("Attaching container %s to weave network failed: %v", container.ID, err) + if output, err := callWeave(args...); err != nil { + i.client.KillContainer(docker.KillContainerOptions{ID: container.ID}) + Warning.Printf("Attaching container %s to weave network failed: %s", container.ID, string(output)) + return errors.New(string(output)) } return nil } From 4f73ef73bbae418a47fd03e441f6a6ebb3d5525b Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 29 May 2015 13:33:00 +0100 Subject: [PATCH 10/24] weavewait should exit if it times out To match behaviour of proxy when interface fails to attach --- weavewait/main.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/weavewait/main.go b/weavewait/main.go index abd5bf76..9d1a2783 100644 --- a/weavewait/main.go +++ b/weavewait/main.go @@ -10,22 +10,22 @@ import ( ) func main() { - if _, err := net.EnsureInterface("ethwe", 20); err != nil { - fmt.Fprintln(os.Stderr, err) - } + _, err := net.EnsureInterface("ethwe", 20) + checkErr(err) if len(os.Args) <= 1 { os.Exit(0) } binary, err := exec.LookPath(os.Args[1]) + checkErr(err) + + checkErr(syscall.Exec(binary, os.Args[1:], os.Environ())) +} + +func checkErr(err error) { if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } - - if err := syscall.Exec(binary, os.Args[1:], os.Environ()); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } } From 1d6f1f75617af065bfa41cf685e9a9217a13a976 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 29 May 2015 17:34:17 +0100 Subject: [PATCH 11/24] Improve ipam status message before and after pending consensus --- ipam/allocator.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/ipam/allocator.go b/ipam/allocator.go index d7ec53cb..00f068de 100644 --- a/ipam/allocator.go +++ b/ipam/allocator.go @@ -456,10 +456,12 @@ func (alloc *Allocator) actorLoop(actionChan <-chan func()) { func (alloc *Allocator) string() string { var buf bytes.Buffer - fmt.Fprintf(&buf, "Allocator subnet %s/%d\n", alloc.subnetStart.String(), alloc.prefixLen) + fmt.Fprintf(&buf, "Allocator subnet %s/%d", alloc.subnetStart.String(), alloc.prefixLen) if alloc.ring.Empty() { - fmt.Fprintf(&buf, "Awaiting consensus: %s", alloc.paxos.String()) + if alloc.paxosTicker != nil { + fmt.Fprintf(&buf, " awaiting consensus: %s", alloc.paxos.String()) + } } else { localFreeSpace := alloc.space.NumFreeAddresses() remoteFreeSpace := alloc.ring.TotalRemoteFree() @@ -469,14 +471,14 @@ func (alloc *Allocator) string() string { fmt.Fprint(&buf, "Owned Ranges:") alloc.ring.FprintWithNicknames(&buf, alloc.nicknames) - if len(alloc.pendingAllocates)+len(alloc.pendingClaims) > 0 { - fmt.Fprintf(&buf, "\nPending requests for ") - for _, op := range alloc.pendingAllocates { - fmt.Fprintf(&buf, "%s, ", op.String()) - } - for _, op := range alloc.pendingClaims { - fmt.Fprintf(&buf, "%s, ", op.String()) - } + } + if len(alloc.pendingAllocates)+len(alloc.pendingClaims) > 0 { + fmt.Fprintf(&buf, "\nPending requests for ") + for _, op := range alloc.pendingAllocates { + fmt.Fprintf(&buf, "%s, ", op.String()) + } + for _, op := range alloc.pendingClaims { + fmt.Fprintf(&buf, "%s, ", op.String()) } } return buf.String() From 5f385a297cd6480371cb0b1b04d3c2a31f9751b2 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sun, 31 May 2015 11:51:34 +0100 Subject: [PATCH 12/24] remove bashism This was introduced in #780. --- weave | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weave b/weave index 4914a47f..dfff47ec 100755 --- a/weave +++ b/weave @@ -171,7 +171,7 @@ DNS_HTTP_PORT=6785 PROXY_PORT=12375 PROXY_CONTAINER_NAME=weaveproxy PROXY_HOST="localhost" -if [[ "$DOCKER_HOST" == "tcp://"* ]]; then +if [ "$DOCKER_HOST" != "${DOCKER_HOST#tcp://}" ] ; then PROXY_HOST=$(echo "$DOCKER_HOST" | sed -e "s|tcp://\([^:]*\):[0-9]*|\1|") fi From cd1cca3df26f93ce36199858a7a252f51e0b3b18 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Mon, 1 Jun 2015 10:55:01 +0100 Subject: [PATCH 13/24] Reformat output of pending ipam requests --- ipam/allocator.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ipam/allocator.go b/ipam/allocator.go index 00f068de..1fa2a0e8 100644 --- a/ipam/allocator.go +++ b/ipam/allocator.go @@ -473,12 +473,12 @@ func (alloc *Allocator) string() string { alloc.ring.FprintWithNicknames(&buf, alloc.nicknames) } if len(alloc.pendingAllocates)+len(alloc.pendingClaims) > 0 { - fmt.Fprintf(&buf, "\nPending requests for ") + fmt.Fprintf(&buf, "\nPending requests:") for _, op := range alloc.pendingAllocates { - fmt.Fprintf(&buf, "%s, ", op.String()) + fmt.Fprintf(&buf, "\n %s", op.String()) } for _, op := range alloc.pendingClaims { - fmt.Fprintf(&buf, "%s, ", op.String()) + fmt.Fprintf(&buf, "\n %s", op.String()) } } return buf.String() From a8c3551040212bb7307ece6dacf0ec9bacb1412a Mon Sep 17 00:00:00 2001 From: Alex Chan Date: Thu, 28 May 2015 10:10:16 +0100 Subject: [PATCH 14/24] Minor spelling corrections in docs --- docs/architecture.txt | 10 +++++----- site/building.md | 2 +- site/weavedns.md | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/architecture.txt b/docs/architecture.txt index 4dba5c45..daa56730 100644 --- a/docs/architecture.txt +++ b/docs/architecture.txt @@ -160,7 +160,7 @@ if a node receives a packet that is bigger than the next MTU, it is required to drop the packet and send back an ICMP 3,4 packet which informs the sending node of the next hop MTU (RFC 1191). In theory, these ICMP packets should have all the reverse NAT and so forth -applied, to make it all the way back to the sender. In practise this +applied, to make it all the way back to the sender. In practice, this does often work, but in some cases all ICMP are sometimes blocked, often by idiots who don't understand that ICMP is really the error channel of all network traffic. @@ -187,16 +187,16 @@ If weave determines that fragmentation is reliable then when weave sniffs large packets (i.e. packets larger than the MTU and thus don't have DF set) then weave will encapsulate these packets as necessary and similarly send them out as-is, without DF set, trusting to the -network to do all necessary fragementation and reassembly. +network to do all necessary fragmentation and reassembly. -However, if weave determines that fragementation is not reliable +However, if weave determines that fragmentation is not reliable between any two peers then it will manually fragment larger packets correctly according to the IP spec, and will then send them between weave peers with the DF flag set (i.e. the fragmentation will ensure -that the encapsulatated traffic will not be greater than the PMTU +that the encapsulated traffic will not be greater than the PMTU between weave peers). Because the fragmentation is done according to the IP spec, we don't need to do reassembly ourselves - on the -receiving weave, we jus inject all the fragments and rely on the +receiving weave, we just inject all the fragments and rely on the stack to do reassembly. Sometimes PMTU discovery doesn't work as ICMP packets sometimes get diff --git a/site/building.md b/site/building.md index 5b8eeede..5f344a21 100644 --- a/site/building.md +++ b/site/building.md @@ -170,7 +170,7 @@ $ vagrant ssh -c 'make -C src/github.com/weaveworks/weave' ``` you should then find container snapshot tarballs in the top-level -directory. You can use these snapshots with `docker load` agains a +directory. You can use these snapshots with `docker load` against a different host, e.g. ```bash diff --git a/site/weavedns.md b/site/weavedns.md index d3b55d4a..59c97948 100644 --- a/site/weavedns.md +++ b/site/weavedns.md @@ -163,7 +163,7 @@ $ weave launch-dns 10.2.254.1/24 --domain="mycompany.local." The local domain should end with `local.`, since these names are link-local as per [RFC6762](https://tools.ietf.org/html/rfc6762), -(though this is not strictly neccessary). +(though this is not strictly necessary). ## Using weaveDNS without `weave run` From adc5784fc9360be737ecbd4b6afd0cbee4cb5519 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Thu, 28 May 2015 13:36:32 +0100 Subject: [PATCH 15/24] expand weavedns example to cover multi-host --- site/weavedns.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/site/weavedns.md b/site/weavedns.md index 59c97948..b73d0180 100644 --- a/site/weavedns.md +++ b/site/weavedns.md @@ -52,9 +52,24 @@ not attempt to do load-balancing. Each weaveDNS container started with `launch-dns` needs to be given its own, unique, IP address, in a subnet that is a) common to all weaveDNS containers, b) disjoint from the application subnets, and c) -not in use on any of the hosts. In our example the weaveDNS address is -in subnet 10.2.254.0/24 and the application containers are in -subnet 10.2.1.0/24. +not in use on any of the hosts. + +In our example the weaveDNS address is in subnet 10.2.254.0/24 and the +application containers are in subnet 10.2.1.0/24. So, to launch and +use weaveDNS on a second host we would run: + +```bash +host2$ weave launch $HOST1 +host2$ weave launch-dns 10.2.254.2/24 +host2$ shell2=$(weave run --with-dns 10.2.1.36/24 -ti -h ubuntu2.weave.local ubuntu) +host2$ docker attach $shell2 + +# ping pingme +... +``` + +Notice the different IP address in the 10.2.254.0/24 subnet we gave to +`weave launch-dns`, compared to what we supplied on the first host. WeaveDNS containers can be stopped with `stop-dns`. From c983d9f39f8abc5c7c16828c287dda88e8030afd Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Thu, 28 May 2015 14:48:08 +0100 Subject: [PATCH 16/24] cosmetic --- site/weavedns.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/weavedns.md b/site/weavedns.md index b73d0180..8905bc90 100644 --- a/site/weavedns.md +++ b/site/weavedns.md @@ -39,7 +39,7 @@ $ weave run 10.2.1.25/24 -ti -h pingme.weave.local ubuntu $ shell1=$(weave run --with-dns 10.2.1.26/24 -ti -h ubuntu.weave.local ubuntu) $ docker attach $shell1 -# ping pingme +root@ubuntu:/# ping pingme ... ``` @@ -64,7 +64,7 @@ host2$ weave launch-dns 10.2.254.2/24 host2$ shell2=$(weave run --with-dns 10.2.1.36/24 -ti -h ubuntu2.weave.local ubuntu) host2$ docker attach $shell2 -# ping pingme +root@ubuntu2:/# ping pingme ... ``` From 2e208b49211b5609a710ce04e082782d8baffef9 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sun, 31 May 2015 09:03:45 +0100 Subject: [PATCH 17/24] cosmetic --- site/troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/troubleshooting.md b/site/troubleshooting.md index bca3fa28..2cbc0e07 100644 --- a/site/troubleshooting.md +++ b/site/troubleshooting.md @@ -126,7 +126,7 @@ not currently connected to. Each line contains some information about what went wrong the last time; whether it is attempting to connect or is waiting for a while before connecting again. -There may also be further sections for +There may also be further sections for [IP allocator](ipam.html#troubleshooting) and [weaveDNS](weavedns.html#troubleshooting). From 341d5ecbb606c53010643546aa81ae6968004033 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Mon, 1 Jun 2015 11:13:16 +0100 Subject: [PATCH 18/24] remove out-of-date info from ipam docs --- site/ipam.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/site/ipam.md b/site/ipam.md index e1ca81b9..836e980f 100644 --- a/site/ipam.md +++ b/site/ipam.md @@ -103,18 +103,8 @@ host3 has caught fire, we can go to one of the other hosts and run: Weave will take all the IP address ranges owned by host3 and transfer them to be owned by host1. The name "host3" is resolved via the 'nickname' feature of weave, which defaults to the local host -name. You can see the full set of range assignments in the output from -`weave status`, which will show the internal hex ID and nickname in -brackets, like this: - - Ring [10.2.1.1, 10.2.1.255) - 10.2.1.1 -> 96:e9:e2:2e:2d:bc (host1) (version: 3, free: 126) - 10.2.1.128 -> ea:84:25:9b:31:2e (host2) (version: 2, free: 64) - 10.2.1.192 -> ea:6c:21:09:cf:f0 (host3) (version: 1, free: 62) - -So, in our example, we could equivalently do: - - host1$ weave rmpeer ea:6c:21:09:cf:f0 +name. Alternatively, one can supply a peer name as shown in `weave +status`. ## Troubleshooting From 71d6f9cdfbb43a60116962edc09876402dfedf90 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Mon, 1 Jun 2015 13:23:23 +0100 Subject: [PATCH 19/24] [docs] re-ordering proxy doc sections --- site/proxy.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/site/proxy.md b/site/proxy.md index 27bca6c8..a7e06981 100644 --- a/site/proxy.md +++ b/site/proxy.md @@ -56,21 +56,6 @@ Multiple IP addresses and networks can be supplied in the `WEAVE_CIDR` variable by space-separating them, as in `WEAVE_CIDR="10.2.1.1/24 10.2.2.1/24"`. -## Usage with WeaveDNS - -Containers started via the proxy can be automatically configured to -use WeaveDNS for name resolution. To accomplish this we need to launch -the proxy with the `--with-dns` option - - host1$ weave launch - host1$ weave launch-dns 10.2.254.1/24 - host1$ weave launch-proxy --with-dns - -With this done, any containers launched through the proxy will use -weaveDNS for name resolution. WeaveDNS is used in addition to any dns -servers specified via the `--dns` option. More details on weaveDNS can -be found in the [weaveDNS documentation](weavedns.html). - ## Usage with IPAM To automatically assign a unique IP address to a container, weave must @@ -94,6 +79,21 @@ option. For example: More details on IPAM can be found in the [IPAM documentation](ipam.html). +## Usage with WeaveDNS + +Containers started via the proxy can be automatically configured to +use WeaveDNS for name resolution. To accomplish this we need to launch +the proxy with the `--with-dns` option + + host1$ weave launch + host1$ weave launch-dns 10.2.254.1/24 + host1$ weave launch-proxy --with-dns + +With this done, any containers launched through the proxy will use +weaveDNS for name resolution. WeaveDNS is used in addition to any dns +servers specified via the `--dns` option. More details on weaveDNS can +be found in the [weaveDNS documentation](weavedns.html). + ## Limitations * The proxy does not currently support TLS. From 6feaa72abde94721a7b490dfe05289124c338b26 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Mon, 1 Jun 2015 13:24:39 +0100 Subject: [PATCH 20/24] [docs] elaborating on proxy IPAM and DNS interaction --- site/proxy.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/site/proxy.md b/site/proxy.md index a7e06981..57914dab 100644 --- a/site/proxy.md +++ b/site/proxy.md @@ -76,8 +76,15 @@ without a `WEAVE_CIDR`, we can launch the proxy with the `--with-ipam` option. For example: host1$ weave launch-proxy --with-ipam + host1$ export DOCKER_HOST=tcp://host1:12375 -More details on IPAM can be found in the [IPAM documentation](ipam.html). +Now, containers will always be automatically assigned an IP address +and attached to the weave network when we start them. For example: + + host1$ docker run -ti ubuntu /bin/sh + +More details on IPAM can be found in the [IPAM +documentation](ipam.html). ## Usage with WeaveDNS @@ -89,10 +96,11 @@ the proxy with the `--with-dns` option host1$ weave launch-dns 10.2.254.1/24 host1$ weave launch-proxy --with-dns -With this done, any containers launched through the proxy will use -weaveDNS for name resolution. WeaveDNS is used in addition to any dns -servers specified via the `--dns` option. More details on weaveDNS can -be found in the [weaveDNS documentation](weavedns.html). +With this done, any containers connected via IPAM or `WEAVE_CIDR=...`, +which are launched through the proxy will use weaveDNS for name +resolution. WeaveDNS is used in addition to any dns servers specified +via the `--dns` option. More details on weaveDNS can be found in the +[weaveDNS documentation](weavedns.html). ## Limitations From 4f86a20824b46973ee21f9a96d89c7e8282a357d Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Mon, 1 Jun 2015 14:26:33 +0100 Subject: [PATCH 21/24] Add release 0.11.1 to CHANGELOG --- CHANGELOG.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b3c77ea..849eef43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,45 @@ +## Release 0.11.1 + +This is a bug fix release, addressing the following issues: + +- The IP Allocator could crash in some relatively rare + circumstances. #782/#783. +- When the proxy failed to attach a container to the weave network, + there was no failure indication and descriptive error anywhere, and + the application process would still start. Now an error is reported + to the client (i.e. typically the Docker CLI), recorded in the proxy + logs, and the container is terminated. #788/#799. +- `weave launch-proxy --with-ipam` failed to configure the entrypoint + and DNS unless a (possibly blank) `WEAVE_CIDR` was + specified. Affected containers could start the application process + w/o the weave network interface being available, and without + functioning name resolution for the weaveDNS domain. + #744/#747/#751/#752 +- The `weave status` output for the IP Allocator was misleadingly + conveying a sense of brokenness when no IP allocation requests had + been made yet. #787/#801 +- When invoking `weave launch-proxy` twice, the second invocation + would output a blank line and terminate with a success exit + status. Now it reports that the proxy is already running and exits + with a non-zero status. #767/#780 +- `weave launch-proxy` was not respecting WEAVEPROXY_DOCKER_ARGS, so + any user-supplied custom configuration for the weaveproxy container + was ignored. #755/#780 +- The proxy was not intercepting API calls to the unversioned (1.0) + Docker Remote API. Hence none of the weave functionality was + available when Docker clients were using that version of the + API. #770/#774/#777,#809 +- The proxy would crash when certain elements of the + `/containers/create` JSON were missing. We are not aware of any + Docker clients doing this, but it's been fixed regardless. #778/#777 + +More details in the [change +log](https://github.com/weaveworks/weave/issues?q=milestone%3A0.11.1). + +*NB: This release does not change the weave protocol version. +Therefore, when upgrading an existing 0.11 installation incrementally, +connectivity between peers will be retained.* + ## Release 0.11.0 **Highlights**: From 106f1c443421229630d11eb412e527f053337c12 Mon Sep 17 00:00:00 2001 From: Ilya Dmitrichenko Date: Fri, 5 Jun 2015 13:11:17 +0100 Subject: [PATCH 22/24] Respect `DOCKER_CLIENT_ARGS` in `weave run` (close #855) --- weave | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weave b/weave index dfff47ec..32d896c7 100755 --- a/weave +++ b/weave @@ -142,7 +142,7 @@ if [ "$1" = "run" ]; then fi collect_cidr_args "$@" shift $CIDR_COUNT - CONTAINER=$(docker run $DNS_ARGS -d "$@") + CONTAINER=$(docker $DOCKER_CLIENT_ARGS run $DNS_ARGS -d "$@") exec_remote attach $CIDR_ARGS $CONTAINER echo $CONTAINER exit 0 From 5f4756aa809f1ab7df596c0357c08ef13c1c2c0a Mon Sep 17 00:00:00 2001 From: Alvaro Saurin Date: Thu, 4 Jun 2015 13:32:53 +0200 Subject: [PATCH 23/24] Do not overwrite negLocal entries in the cache Unit tests --- nameserver/cache.go | 22 ++++++++++++++++------ nameserver/cache_test.go | 24 ++++++++++++++++++------ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/nameserver/cache.go b/nameserver/cache.go index 644814f0..30937375 100644 --- a/nameserver/cache.go +++ b/nameserver/cache.go @@ -5,13 +5,14 @@ import ( "container/heap" "errors" "fmt" - "github.com/benbjohnson/clock" - "github.com/miekg/dns" - . "github.com/weaveworks/weave/common" "math" "math/rand" "sync" "time" + + "github.com/benbjohnson/clock" + "github.com/miekg/dns" + . "github.com/weaveworks/weave/common" ) var ( @@ -145,9 +146,12 @@ func (e *cacheEntry) setReply(reply *dns.Msg, ttl int, flags uint8, now time.Tim prevValidUntil = e.validUntil } - e.Status = stResolved - e.Flags = flags - e.putTime = now + // make sure we do not overwrite noLocalReplies entries + if flags&CacheNoLocalReplies != 0 { + if e.Flags&CacheNoLocalReplies != 0 { + return false + } + } if ttl != nullTTL { e.validUntil = now.Add(time.Second * time.Duration(ttl)) @@ -161,8 +165,14 @@ func (e *cacheEntry) setReply(reply *dns.Msg, ttl int, flags uint8, now time.Tim } } e.validUntil = now.Add(time.Second * time.Duration(minTTL)) + } else { + Warning.Printf("[cache] no valid TTL could be calculated") } + e.Status = stResolved + e.Flags = flags + e.putTime = now + if reply != nil { e.reply = *reply e.ReplyLen = reply.Len() diff --git a/nameserver/cache_test.go b/nameserver/cache_test.go index b53d7529..9e4c5584 100644 --- a/nameserver/cache_test.go +++ b/nameserver/cache_test.go @@ -2,13 +2,14 @@ package nameserver import ( "fmt" + "net" + "testing" + "time" + "github.com/benbjohnson/clock" "github.com/miekg/dns" . "github.com/weaveworks/weave/common" wt "github.com/weaveworks/weave/testing" - "net" - "testing" - "time" ) // Check that the cache keeps its intended capacity constant @@ -195,12 +196,23 @@ func TestCacheEntries(t *testing.T) { question3 := &questionMsg3.Question[0] t.Logf("Checking that a entry with CacheNoLocalReplies return an error") - l.Put(questionMsg3, nil, nullTTL, CacheNoLocalReplies) + l.Put(questionMsg3, nil, negLocalTTL, CacheNoLocalReplies) resp, err = l.Get(questionMsg3, minUDPSize) wt.AssertNil(t, resp, "Get() response with CacheNoLocalReplies") - wt.AssertNotNil(t, err, "Get() error with CacheNoLocalReplies") + wt.AssertTrue(t, err == errNoLocalReplies, "Get() error with CacheNoLocalReplies") - clk.Add(time.Second * time.Duration(negLocalTTL+1)) + t.Logf("Checking that more Put's do not make the negative TTL longer") + clk.Add(time.Duration(negLocalTTL/2) * time.Second) + l.Put(questionMsg3, nil, negLocalTTL, CacheNoLocalReplies) + clk.Add(time.Duration(1) * time.Second) + l.Put(questionMsg3, nil, negLocalTTL, CacheNoLocalReplies) + clk.Add(time.Duration(1) * time.Second) + l.Put(questionMsg3, nil, negLocalTTL, CacheNoLocalReplies) + resp, err = l.Get(questionMsg3, minUDPSize) + wt.AssertNil(t, resp, "Get() response with CacheNoLocalReplies") + wt.AssertTrue(t, err == errNoLocalReplies, "Get() error with CacheNoLocalReplies") + + clk.Add(time.Duration(negLocalTTL/2) * time.Second) t.Logf("Checking that we get an expired response after %f seconds", negLocalTTL) resp, err = l.Get(questionMsg3, minUDPSize) wt.AssertNil(t, resp, "expired Get() response with CacheNoLocalReplies") From 93c1e755e6dec557981e67343295b46649469868 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Mon, 8 Jun 2015 16:31:24 +0100 Subject: [PATCH 24/24] Add release 0.11.2 to CHANGELOG --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 849eef43..5807d208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## Release 0.11.2 + +This is a bug fix release, addressing the following issues: + +- `weave run` did not respect DOCKER_CLIENT_ARGS. #855 +- Negative result cache did not expire if requeried within TTL. #845 + +More details in the [change +log](https://github.com/weaveworks/weave/issues?q=milestone%3A0.11.2). + +*NB: This release does not change the weave protocol version. +Therefore, when upgrading an existing 0.11 installation incrementally, +connectivity between peers will be retained.* + ## Release 0.11.1 This is a bug fix release, addressing the following issues: