Files
weave/ipam/claim.go
T

81 lines
2.1 KiB
Go

package ipam
import (
"fmt"
"github.com/weaveworks/weave/net/address"
"github.com/weaveworks/weave/router"
)
type claim struct {
resultChan chan<- error
ident string
addr address.Address
hasBeenCancelled func() bool
}
// Try returns true for success (or failure), false if we need to try again later
func (c *claim) Try(alloc *Allocator) bool {
if (c.hasBeenCancelled)() {
c.Cancel()
return true
}
if !alloc.ring.Contains(c.addr) {
// Address not within our universe; assume user knows what they are doing
alloc.infof("Ignored address %s claimed by %s - not in our universe\n", c.addr, c.ident)
c.resultChan <- nil
return true
}
// If our ring doesn't know, it must be empty. We will have initiated the
// bootstrap of the ring, so wait until we find some owner for this
// range (might be us).
owner := alloc.ring.Owner(c.addr)
if owner == router.UnknownPeerName {
alloc.infof("Ring is empty; will try later.\n", c.addr, owner)
return false
}
if owner != alloc.ourName {
name, found := alloc.nicknames[owner]
if found {
name = " (" + name + ")"
}
c.resultChan <- fmt.Errorf("address %s is owned by other peer %s%s", c.addr.String(), owner, name)
return true
}
// We are the owner, check we haven't given it to another container
existingIdent := alloc.findOwner(c.addr)
if existingIdent == c.ident {
// same identifier is claiming same address; that's OK
c.resultChan <- nil
return true
}
if existingIdent == "" {
err := alloc.space.Claim(c.addr)
if err != nil {
c.resultChan <- err
return true
}
alloc.debugln("Claimed", c.addr, "for", c.ident)
alloc.addOwned(c.ident, c.addr)
c.resultChan <- nil
return true
}
// Addr already owned by container on this machine
c.resultChan <- fmt.Errorf("address %s is already owned by %s", c.addr.String(), existingIdent)
return true
}
func (c *claim) Cancel() {
c.resultChan <- fmt.Errorf("Operation cancelled.")
}
func (c *claim) String() string {
return fmt.Sprintf("Claim %s -> %s", c.ident, c.addr.String())
}
func (c *claim) ForContainer(ident string) bool {
return c.ident == ident
}