Return all applicable results from Lookup

and stop erroring on Lookup not found; just return a blank result
This commit is contained in:
Bryan Boreham committed 2016-03-02 17:01:12 -08:00
1 parent 03563e847e
commit b6eec08247
5 files changed
+31 -22

No files matched your search

+4 -4
View File
@@ -25,15 +25,15 @@ func (g *allocate) Try(alloc *Allocator) bool {
return true
}
if addr, found := alloc.ownedInRange(g.ident, g.r); found {
if addrs := alloc.ownedInRange(g.ident, g.r); 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{addr, nil}
g.resultChan <- allocateResult{addrs[0], nil}
return true
}
if !alloc.universe.Overlaps(g.r) {
g.resultChan <- allocateResult{0, fmt.Errorf("range %s out of bounds: %s", g.r, alloc.universe)}
g.resultChan <- allocateResult{err: fmt.Errorf("range %s out of bounds: %s", g.r, alloc.universe)}
return true
}
@@ -66,7 +66,7 @@ func (g *allocate) Try(alloc *Allocator) bool {
}
func (g *allocate) Cancel() {
g.resultChan <- allocateResult{0, &errorCancelled{"Allocate", g.ident}}
g.resultChan <- allocateResult{err: &errorCancelled{"Allocate", g.ident}}
}
func (g *allocate) ForContainer(ident string) bool {
+9 -13
View File
@@ -203,18 +203,13 @@ func (alloc *Allocator) Allocate(ident string, r address.Range, hasBeenCancelled
return result.addr, result.err
}
// Lookup (Sync) - get existing IP address for container with given name in range
func (alloc *Allocator) Lookup(ident string, r address.Range) (address.Address, error) {
resultChan := make(chan allocateResult)
// Lookup (Sync) - get existing IP addresses for container with given name in range
func (alloc *Allocator) Lookup(ident string, r address.Range) ([]address.Address, error) {
resultChan := make(chan []address.Address)
alloc.actionChan <- func() {
if addr, found := alloc.ownedInRange(ident, r); found {
resultChan <- allocateResult{addr: addr}
return
}
resultChan <- allocateResult{err: fmt.Errorf("lookup: no address found for %s in range %s", ident, r)}
resultChan <- alloc.ownedInRange(ident, r)
}
result := <-resultChan
return result.addr, result.err
return <-resultChan, nil
}
// Claim an address that we think we should own (Sync)
@@ -861,13 +856,14 @@ func (alloc *Allocator) removeOwned(ident string, addrToFree address.Address) bo
return false
}
func (alloc *Allocator) ownedInRange(ident string, r address.Range) (address.Address, bool) {
func (alloc *Allocator) ownedInRange(ident string, r address.Range) []address.Address {
var a []address.Address
for _, addr := range alloc.owned[ident] {
if r.Contains(addr) {
return addr, true
a = append(a, addr)
}
}
return 0, false
return a
}
func (alloc *Allocator) findOwner(addr address.Address) string {
+4
View File
@@ -49,6 +49,10 @@ func TestAllocFree(t *testing.T) {
require.NoError(t, err)
require.Equal(t, testAddr2, addr2.String(), "address")
addrs, err := alloc.Lookup(container1, subnet)
require.NoError(t, err)
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)
if addr1b.String() == testAddr1 {
+13 -4
View File
@@ -29,6 +29,15 @@ func parseCIDR(w http.ResponseWriter, cidrStr string) (address.CIDR, bool) {
return cidr, true
}
func writeAddresses(w http.ResponseWriter, addrs []address.Address, subnet address.CIDR) {
for i, addr := range addrs {
fmt.Fprintf(w, "%s/%d", addr, subnet.PrefixLen)
if i < len(addrs)-1 {
w.Write([]byte{' '})
}
}
}
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(),
@@ -80,22 +89,22 @@ func (alloc *Allocator) HandleHTTP(router *mux.Router, defaultSubnet address.CID
router.Methods("GET").Path("/ip/{id}/{ip}/{prefixlen}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
if subnet, ok := parseCIDR(w, vars["ip"]+"/"+vars["prefixlen"]); ok {
addr, err := alloc.Lookup(vars["id"], subnet.HostRange())
addrs, err := alloc.Lookup(vars["id"], subnet.HostRange())
if err != nil {
http.NotFound(w, r)
return
}
fmt.Fprintf(w, "%s/%d", addr, subnet.PrefixLen)
writeAddresses(w, addrs, subnet)
}
})
router.Methods("GET").Path("/ip/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
addr, err := alloc.Lookup(mux.Vars(r)["id"], defaultSubnet.HostRange())
addrs, err := alloc.Lookup(mux.Vars(r)["id"], defaultSubnet.HostRange())
if err != nil {
http.NotFound(w, r)
return
}
fmt.Fprintf(w, "%s/%d", addr, defaultSubnet.PrefixLen)
writeAddresses(w, addrs, defaultSubnet)
})
router.Methods("POST").Path("/ip/{id}/{ip}/{prefixlen}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+1 -1
View File
@@ -1343,7 +1343,7 @@ ipam_cidrs() {
echo "IP address allocation must be enabled to use 'net:'" >&2
return 1
fi
elif ! is_cidr "$CIDR" ; then
elif [ -n "$CIDR" ] && ! is_cidr "$CIDR" ; then
echo "$CIDR" >&2
return 1
else