From 73f1a04d5fcabbb7e8dce484ba63df2b91582c4b Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Tue, 1 Mar 2016 14:54:30 -0800 Subject: [PATCH] Deal in subnets, not ranges, when requesting address allocation --- ipam/allocate.go | 12 ++++++------ ipam/allocator.go | 2 +- ipam/allocator_test.go | 16 ++++++++-------- ipam/http.go | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ipam/allocate.go b/ipam/allocate.go index c37a52bf..8146e0c9 100644 --- a/ipam/allocate.go +++ b/ipam/allocate.go @@ -14,7 +14,7 @@ type allocateResult struct { type allocate struct { resultChan chan<- allocateResult ident string - r address.Range // Range we are trying to allocate within + r address.CIDR // Subnet we are trying to allocate within hasBeenCancelled func() bool } @@ -25,21 +25,21 @@ func (g *allocate) Try(alloc *Allocator) bool { return true } - if addrs := alloc.ownedInRange(g.ident, g.r); len(addrs) > 0 { + if addrs := alloc.ownedInRange(g.ident, g.r.Range()); len(addrs) > 0 { // If we had heard that this container died, resurrect it delete(alloc.dead, g.ident) // delete is no-op if key not in map g.resultChan <- allocateResult{addrs[0].Addr, nil} return true } - if !alloc.universe.Overlaps(g.r) { + if !alloc.universe.Overlaps(g.r.Range()) { g.resultChan <- allocateResult{err: fmt.Errorf("range %s out of bounds: %s", g.r, alloc.universe)} return true } alloc.establishRing() - if ok, addr := alloc.space.Allocate(g.r); ok { + if ok, addr := alloc.space.Allocate(g.r.HostRange()); ok { // If caller hasn't supplied a unique ID, file it under the IP address // which lets the caller then release the address using DELETE /ip/address if g.ident == "_" { @@ -52,9 +52,9 @@ func (g *allocate) Try(alloc *Allocator) bool { } // out of space - donors := alloc.ring.ChoosePeersToAskForSpace(g.r.Start, g.r.End) + donors := alloc.ring.ChoosePeersToAskForSpace(g.r.Addr, g.r.Range().End) for _, donor := range donors { - if err := alloc.sendSpaceRequest(donor, g.r); err != nil { + if err := alloc.sendSpaceRequest(donor, g.r.Range()); err != nil { alloc.debugln("Problem asking peer", donor, "for space:", err) } else { alloc.debugln("Decided to ask peer", donor, "for space in range", g.r) diff --git a/ipam/allocator.go b/ipam/allocator.go index 3442515f..f9d67fe0 100644 --- a/ipam/allocator.go +++ b/ipam/allocator.go @@ -195,7 +195,7 @@ func (e *errorCancelled) Error() string { // Allocate (Sync) - get new IP address for container with given name in range // if there isn't any space in that range we block indefinitely -func (alloc *Allocator) Allocate(ident string, r address.Range, hasBeenCancelled func() bool) (address.Address, error) { +func (alloc *Allocator) Allocate(ident string, r address.CIDR, hasBeenCancelled func() bool) (address.Address, error) { resultChan := make(chan allocateResult) op := &allocate{resultChan: resultChan, ident: ident, r: r, hasBeenCancelled: hasBeenCancelled} alloc.doOperation(op, &alloc.pendingAllocates) diff --git a/ipam/allocator_test.go b/ipam/allocator_test.go index 55a631e7..5bc5557f 100644 --- a/ipam/allocator_test.go +++ b/ipam/allocator_test.go @@ -41,11 +41,11 @@ func TestAllocFree(t *testing.T) { _, cidr2, _ := address.ParseCIDR(subnet2) alloc.claimRingForTesting() - addr1, err := alloc.Allocate(container1, cidr1.HostRange(), returnFalse) + addr1, err := alloc.Allocate(container1, cidr1, returnFalse) require.NoError(t, err) require.Equal(t, testAddr1, addr1.String(), "address") - addr2, err := alloc.Allocate(container1, cidr2.HostRange(), returnFalse) + addr2, err := alloc.Allocate(container1, cidr2, returnFalse) require.NoError(t, err) require.Equal(t, testAddr2, addr2.String(), "address") @@ -54,28 +54,28 @@ func TestAllocFree(t *testing.T) { require.Equal(t, []address.Address{addr1, addr2}, addrs) // Ask for another address for a different container and check it's different - addr1b, _ := alloc.Allocate(container2, cidr1.HostRange(), returnFalse) + addr1b, _ := alloc.Allocate(container2, cidr1, returnFalse) if addr1b.String() == testAddr1 { t.Fatalf("Expected different address but got %s", addr1b.String()) } // Ask for the first container again and we should get the same addresses again - addr1a, _ := alloc.Allocate(container1, cidr1.HostRange(), returnFalse) + addr1a, _ := alloc.Allocate(container1, cidr1, returnFalse) require.Equal(t, testAddr1, addr1a.String(), "address") - addr2a, _ := alloc.Allocate(container1, cidr2.HostRange(), returnFalse) + addr2a, _ := alloc.Allocate(container1, cidr2, returnFalse) require.Equal(t, testAddr2, addr2a.String(), "address") // Now delete the first container, and we should get its addresses back require.NoError(t, alloc.Delete(container1)) - addr3, _ := alloc.Allocate(container3, cidr1.HostRange(), returnFalse) + addr3, _ := alloc.Allocate(container3, cidr1, returnFalse) require.Equal(t, testAddr1, addr3.String(), "address") - addr4, _ := alloc.Allocate(container3, cidr2.HostRange(), returnFalse) + addr4, _ := alloc.Allocate(container3, cidr2, returnFalse) require.Equal(t, testAddr2, addr4.String(), "address") alloc.ContainerDied(container2) // Resurrect - addr1c, err := alloc.Allocate(container2, cidr1.HostRange(), returnFalse) + addr1c, err := alloc.Allocate(container2, cidr1, returnFalse) require.NoError(t, err) require.Equal(t, addr1b, addr1c, "address") diff --git a/ipam/http.go b/ipam/http.go index 2f103869..f3525808 100644 --- a/ipam/http.go +++ b/ipam/http.go @@ -40,7 +40,7 @@ func writeAddresses(w http.ResponseWriter, cidrs []address.CIDR) { func (alloc *Allocator) handleHTTPAllocate(dockerCli *docker.Client, w http.ResponseWriter, ident string, checkAlive bool, subnet address.CIDR) { closedChan := w.(http.CloseNotifier).CloseNotify() - addr, err := alloc.Allocate(ident, subnet.HostRange(), + addr, err := alloc.Allocate(ident, subnet, func() bool { select { case <-closedChan: