Files
weave/ipam/allocate.go
T
Martynas Pumputis f50fbc002e Change ipam Universe from Range to CIDR
There was no code to initialize it as anything else, and this lets us
bake in an assumption that it will always be a CIDR.
2016-06-01 17:06:31 +01:00

76 lines
2.0 KiB
Go

package ipam
import (
"fmt"
"github.com/weaveworks/weave/net/address"
)
type allocateResult struct {
addr address.Address
err error
}
type allocate struct {
resultChan chan<- allocateResult
ident string
r address.CIDR // Subnet we are trying to allocate within
isContainer bool
hasBeenCancelled func() bool
}
// Try returns true if the request is completed, false if pending
func (g *allocate) Try(alloc *Allocator) bool {
if g.hasBeenCancelled() {
g.Cancel()
return true
}
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.Range().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.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 == "_" {
g.ident = addr.String()
}
alloc.debugln("Allocated", addr, "for", g.ident, "in", g.r)
alloc.addOwned(g.ident, address.MakeCIDR(g.r, addr), g.isContainer)
g.resultChan <- allocateResult{addr, nil}
return true
}
// out of space
donors := alloc.ring.ChoosePeersToAskForSpace(g.r.Addr, g.r.Range().End)
for _, donor := range donors {
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)
break
}
}
return false
}
func (g *allocate) Cancel() {
g.resultChan <- allocateResult{err: &errorCancelled{"Allocate", g.ident}}
}
func (g *allocate) ForContainer(ident string) bool {
return g.ident == ident
}