diff --git a/ipam/allocate.go b/ipam/allocate.go index ebb30217..e8950e37 100644 --- a/ipam/allocate.go +++ b/ipam/allocate.go @@ -59,7 +59,7 @@ func (g *allocate) Try(alloc *Allocator) bool { } func (g *allocate) Cancel() { - g.resultChan <- allocateResult{0, fmt.Errorf("Allocate request for %s cancelled", g.ident)} + g.resultChan <- allocateResult{0, &errorCancelled{"Allocate", g.ident}} } func (g *allocate) ForContainer(ident string) bool { diff --git a/ipam/allocator.go b/ipam/allocator.go index 28f2e449..a55e35c7 100644 --- a/ipam/allocator.go +++ b/ipam/allocator.go @@ -184,6 +184,15 @@ func hasBeenCancelled(cancelChan <-chan bool) func() bool { } } +type errorCancelled struct { + kind string + ident string +} + +func (e *errorCancelled) Error() string { + return fmt.Sprintf("%s request for %s cancelled", e.kind, e.ident) +} + // Actor client API // Allocate (Sync) - get new IP address for container with given name in range diff --git a/ipam/claim.go b/ipam/claim.go index 5e79d7d1..2515afd2 100644 --- a/ipam/claim.go +++ b/ipam/claim.go @@ -95,7 +95,7 @@ func (c *claim) deniedBy(alloc *Allocator, owner router.PeerName) { } func (c *claim) Cancel() { - c.sendResult(fmt.Errorf("Operation cancelled.")) + c.sendResult(&errorCancelled{"Claim", c.ident}) } func (c *claim) ForContainer(ident string) bool { diff --git a/ipam/http.go b/ipam/http.go index a8e62880..40874108 100644 --- a/ipam/http.go +++ b/ipam/http.go @@ -33,12 +33,18 @@ func (alloc *Allocator) handleHTTPAllocate(dockerCli *docker.Client, w http.Resp closedChan := w.(http.CloseNotifier).CloseNotify() addr, err := alloc.Allocate(ident, subnet.HostRange(), closedChan) if err != nil { + if _, ok := err.(*errorCancelled); ok { // cancellation is not really an error + common.Log.Infoln("[allocator]:", err.Error()) + fmt.Fprint(w, "cancelled") + return + } badRequest(w, err) return } if checkAlive && dockerCli != nil && dockerCli.IsContainerNotRunning(ident) { common.Log.Infof("[allocator] '%s' is not running: freeing %s", ident, addr) alloc.Free(ident, addr) + fmt.Fprint(w, "cancelled") return } diff --git a/weave b/weave index f3220ff2..4b132a4e 100755 --- a/weave +++ b/weave @@ -919,6 +919,8 @@ ipam_cidrs() { if [ "$IPAM_CIDRS" = "404 page not found" ] ; then echo "No IP address supplied (use the -iprange option on 'weave launch' to enable IP address allocation)" >&2 return 1 + elif [ "$IPAM_CIDRS" = "cancelled" ] ; then + return 0 fi ALL_CIDRS="$IPAM_CIDRS" fi @@ -933,8 +935,9 @@ ipam_cidrs() { if [ "$CIDR" = "404 page not found" ] ; then echo "IP address allocation must be enabled to use 'net:'" >&2 return 1 - fi - if ! is_cidr "$CIDR" ; then + elif [ "$CIDR" = "cancelled" ] ; then + return 0 + elif ! is_cidr "$CIDR" ; then echo "$CIDR" >&2 return 1 fi @@ -1486,6 +1489,10 @@ case "$COMMAND" in CONTAINER=$(container_id $1) create_bridge ipam_cidrs$ATTACH_TYPE $CONTAINER $CIDR_ARGS + if [ "$IPAM_CIDRS" = "cancelled" ] ; then + echo "cancelled" >&2 + exit 0 + fi if [ -n "$REWRITE_HOSTS" ] && command_exists weavehosts ; then PATH_AND_NAME=$(docker inspect -f '{{.HostsPath}} {{.Config.Hostname}}' $CONTAINER) weavehosts $PATH_AND_NAME $ALL_CIDRS