Return all applicable results from Lookup
and stop erroring on Lookup not found; just return a blank result
This commit is contained in:
1 parent
03563e847e
commit
b6eec08247
5 files changed
+31
-22
No files matched your search
+4
-4
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user