Move default subnet outside of Allocator

This commit is contained in:
Bryan Boreham committed 2015-06-10 17:24:36 +01:00
1 parent 7e7a2227a0
commit 6536034ab6
8 files changed
+102 -114

No files matched your search

+5 -4
View File
@@ -21,10 +21,15 @@ plugin) uses to request IP addresses.
The commands supported by the allocator via the http interface are:
- Allocate: request one IP address for a container in a subnet
- Lookup: fetch the previously-allocated IP address for a container in a subnet
- Free: return an IP address that is currently allocated
- Claim: request a specific IP address for a container (e.g. because
it is already using that address)
Each http request either specifies a subnet, or if no subnet is
specified this is taken as a request to allocate in a pre-defined
default subnet.
The allocator also watches via the Docker event mechanism: if a
container dies then all IP addresses allocated to that container are
freed.
@@ -46,10 +51,6 @@ freed.
### The Allocation Process
Each allocation request either specifies a subnet to allocate within,
or if no subnet is specified this is taken as a request to allocate in
a pre-defined default subnet.
When a peer owns some range(s), it can allocate freely from within
those ranges to containers on the same machine. If it runs out of
space in a subnet (all owned ranges are full), it will ask another
+11 -45
View File
@@ -21,7 +21,7 @@ const (
msgRingUpdate
paxosInterval = time.Second * 5
minSubnetSize = 4 // first and last addresses are excluded, so 2 would be too small
MinSubnetSize = 4 // first and last addresses are excluded, so 2 would be too small
)
// operation represents something which Allocator wants to do, but
@@ -45,7 +45,6 @@ type operation interface {
type Allocator struct {
actionChan chan<- func()
ourName router.PeerName
defaultSubnet address.CIDR
universe address.CIDR // superset of all ranges
ring *ring.Ring // information on ranges owned by all peers
space space.Space // more detail on ranges owned by us
@@ -61,21 +60,16 @@ type Allocator struct {
}
// NewAllocator creates and initialises a new Allocator
func NewAllocator(ourName router.PeerName, ourUID router.PeerUID, ourNickname string, universeStr string, quorum uint) (*Allocator, error) {
universe, err := parseAndCheckCIDR(universeStr)
if err != nil {
return nil, err
}
func NewAllocator(ourName router.PeerName, ourUID router.PeerUID, ourNickname string, universe address.CIDR, quorum uint) *Allocator {
return &Allocator{
ourName: ourName,
universe: universe,
defaultSubnet: universe,
ring: ring.New(universe.Start, address.Add(universe.Start, universe.Size()), ourName),
owned: make(map[string][]address.Address),
paxos: paxos.NewNode(ourName, ourUID, quorum),
nicknames: map[router.PeerName]string{ourName: ourNickname},
now: time.Now,
}, nil
ourName: ourName,
universe: universe,
ring: ring.New(universe.Start, address.Add(universe.Start, universe.Size()), ourName),
owned: make(map[string][]address.Address),
paxos: paxos.NewNode(ourName, ourUID, quorum),
nicknames: map[router.PeerName]string{ourName: ourNickname},
now: time.Now,
}
}
// Start runs the allocator goroutine
@@ -182,23 +176,6 @@ func hasBeenCancelled(cancelChan <-chan bool) func() bool {
// Actor client API
func (alloc *Allocator) SetDefaultSubnet(subnetStr string) error {
subnet, err := parseAndCheckCIDR(subnetStr)
if err != nil {
return err
}
resultChan := make(chan error)
alloc.actionChan <- func() {
if !alloc.universe.Overlaps(subnet) {
resultChan <- fmt.Errorf("Default subnet %s out of bounds: %s", subnet, alloc.universe)
return
}
alloc.defaultSubnet = subnet
resultChan <- nil
}
return <-resultChan
}
// Allocate (Sync) - get IP address for container with given name
// if there isn't any space we block indefinitely
func (alloc *Allocator) Allocate(ident string, subnet address.CIDR, cancelChan <-chan bool) (address.CIDR, error) {
@@ -494,20 +471,9 @@ func (alloc *Allocator) actorLoop(actionChan <-chan func()) {
// Helper functions
func parseAndCheckCIDR(cidrStr string) (address.CIDR, error) {
_, cidr, err := address.ParseCIDR(cidrStr)
if err != nil {
return address.CIDR{}, err
}
if cidr.Size() < minSubnetSize {
return address.CIDR{}, fmt.Errorf("Allocation range smaller than minimum size %d: %s", minSubnetSize, cidrStr)
}
return cidr, nil
}
func (alloc *Allocator) string() string {
var buf bytes.Buffer
fmt.Fprintf(&buf, "Allocator range %s (default subnet %s)", alloc.universe, alloc.defaultSubnet)
fmt.Fprintf(&buf, "Allocator range %s", alloc.universe)
if alloc.ring.Empty() {
if alloc.paxosTicker != nil {
+29 -29
View File
@@ -32,7 +32,7 @@ func TestAllocFree(t *testing.T) {
spaceSize = 62 // 64 IP addresses in /26, minus .0 and .63
)
alloc := makeAllocatorWithMockGossip(t, "01:00:00:01:00:00", universe, 1)
alloc, subnet := makeAllocatorWithMockGossip(t, "01:00:00:01:00:00", universe, 1)
defer alloc.Stop()
_, cidr1, _ := address.ParseCIDR(subnet1)
_, cidr2, _ := address.ParseCIDR(subnet2)
@@ -67,7 +67,7 @@ func TestAllocFree(t *testing.T) {
alloc.ContainerDied(container2)
alloc.ContainerDied(container3)
wt.AssertEquals(t, alloc.NumFreeAddresses(), address.Offset(spaceSize))
wt.AssertEquals(t, alloc.NumFreeAddresses(subnet), address.Offset(spaceSize))
}
func TestBootstrap(t *testing.T) {
@@ -79,11 +79,11 @@ func TestBootstrap(t *testing.T) {
peerNameString = "02:00:00:02:00:00"
)
alloc1 := makeAllocatorWithMockGossip(t, ourNameString, testStart1+"/22", 2)
alloc1, subnet := makeAllocatorWithMockGossip(t, ourNameString, testStart1+"/22", 2)
defer alloc1.Stop()
// Simulate another peer on the gossip network
alloc2 := makeAllocatorWithMockGossip(t, peerNameString, testStart1+"/22", 2)
alloc2, _ := makeAllocatorWithMockGossip(t, peerNameString, testStart1+"/22", 2)
defer alloc2.Stop()
alloc1.OnGossipBroadcast(alloc2.Encode())
@@ -93,7 +93,7 @@ func TestBootstrap(t *testing.T) {
ExpectBroadcastMessage(alloc1, nil) // alloc1 will try to form consensus
done := make(chan bool)
go func() {
alloc1.Allocate("somecontainer", alloc1.defaultSubnet, nil)
alloc1.Allocate("somecontainer", subnet, nil)
done <- true
}()
time.Sleep(100 * time.Millisecond)
@@ -137,7 +137,7 @@ func TestAllocatorClaim(t *testing.T) {
testAddr1 = "10.0.3.1/30" // first address allocated should be .1 because .0 is network addr
)
alloc := makeAllocatorWithMockGossip(t, "01:00:00:01:00:00", universe, 1)
alloc, subnet := makeAllocatorWithMockGossip(t, "01:00:00:01:00:00", universe, 1)
defer alloc.Stop()
alloc.claimRingForTesting()
@@ -146,7 +146,7 @@ func TestAllocatorClaim(t *testing.T) {
err := alloc.Claim(container3, addr1, nil)
wt.AssertNoErr(t, err)
// Check we get this address back if we try an allocate
addr3, _ := alloc.Allocate(container3, alloc.defaultSubnet, nil)
addr3, _ := alloc.Allocate(container3, subnet, nil)
wt.AssertEqualString(t, addr3.String(), testAddr1, "address")
}
@@ -170,10 +170,10 @@ func TestCancel(t *testing.T) {
router := TestGossipRouter{make(map[router.PeerName]chan gossipMessage), 0.0}
alloc1 := makeAllocator("01:00:00:02:00:00", CIDR, 2)
alloc1, subnet := makeAllocator("01:00:00:02:00:00", CIDR, 2)
alloc1.SetInterfaces(router.connect(alloc1.ourName, alloc1))
alloc2 := makeAllocator("02:00:00:02:00:00", CIDR, 2)
alloc2, subnet := makeAllocator("02:00:00:02:00:00", CIDR, 2)
alloc2.SetInterfaces(router.connect(alloc2.ourName, alloc2))
alloc1.claimRingForTesting(alloc1, alloc2)
alloc2.claimRingForTesting(alloc1, alloc2)
@@ -185,9 +185,9 @@ func TestCancel(t *testing.T) {
alloc1.OnGossipBroadcast(alloc2.Encode())
// Get some IPs, so each allocator has some space
res1, _ := alloc1.Allocate("foo", alloc1.defaultSubnet, nil)
res1, _ := alloc1.Allocate("foo", subnet, nil)
common.Debug.Printf("res1 = %s", res1.String())
res2, _ := alloc2.Allocate("bar", alloc2.defaultSubnet, nil)
res2, _ := alloc2.Allocate("bar", subnet, nil)
common.Debug.Printf("res2 = %s", res2.String())
if res1 == res2 {
wt.Fatalf(t, "Error: got same ips!")
@@ -198,13 +198,13 @@ func TestCancel(t *testing.T) {
unpause := alloc2.pause()
// Use up all the IPs that alloc1 owns, so the allocation after this will prompt a request to alloc2
for i := 0; alloc1.NumFreeAddresses() > 0; i++ {
alloc1.Allocate(fmt.Sprintf("tmp%d", i), alloc1.defaultSubnet, nil)
for i := 0; alloc1.NumFreeAddresses(subnet) > 0; i++ {
alloc1.Allocate(fmt.Sprintf("tmp%d", i), subnet, nil)
}
cancelChan := make(chan bool, 1)
doneChan := make(chan bool)
go func() {
_, ok := alloc1.Allocate("baz", alloc1.defaultSubnet, cancelChan)
_, ok := alloc1.Allocate("baz", subnet, cancelChan)
doneChan <- ok == nil
}()
@@ -226,15 +226,15 @@ func TestGossipShutdown(t *testing.T) {
universe = "10.0.3.0/30"
)
alloc := makeAllocatorWithMockGossip(t, "01:00:00:01:00:00", universe, 1)
alloc, subnet := makeAllocatorWithMockGossip(t, "01:00:00:01:00:00", universe, 1)
defer alloc.Stop()
alloc.claimRingForTesting()
alloc.Allocate(container1, alloc.defaultSubnet, nil)
alloc.Allocate(container1, subnet, nil)
alloc.Shutdown()
_, err := alloc.Allocate(container2, alloc.defaultSubnet, nil) // trying to allocate after shutdown should fail
_, err := alloc.Allocate(container2, subnet, nil) // trying to allocate after shutdown should fail
wt.AssertFalse(t, err == nil, "no address")
CheckAllExpectedMessagesSent(alloc)
@@ -244,15 +244,15 @@ func TestTransfer(t *testing.T) {
const (
cidr = "10.0.1.7/22"
)
allocs, router := makeNetworkOfAllocators(3, cidr)
allocs, router, subnet := makeNetworkOfAllocators(3, cidr)
alloc1 := allocs[0]
alloc2 := allocs[1]
alloc3 := allocs[2] // This will be 'master' and get the first range
_, err := alloc2.Allocate("foo", alloc2.defaultSubnet, nil)
_, err := alloc2.Allocate("foo", subnet, nil)
wt.AssertTrue(t, err == nil, "Failed to get address")
_, err = alloc3.Allocate("bar", alloc3.defaultSubnet, nil)
_, err = alloc3.Allocate("bar", subnet, nil)
wt.AssertTrue(t, err == nil, "Failed to get address")
router.GossipBroadcast(alloc2.Gossip())
@@ -264,9 +264,9 @@ func TestTransfer(t *testing.T) {
wt.AssertSuccess(t, alloc1.AdminTakeoverRanges(alloc2.ourName.String()))
wt.AssertSuccess(t, alloc1.AdminTakeoverRanges(alloc3.ourName.String()))
wt.AssertEquals(t, alloc1.NumFreeAddresses(), address.Offset(1022))
wt.AssertEquals(t, alloc1.NumFreeAddresses(subnet), address.Offset(1022))
_, err = alloc1.Allocate("foo", alloc1.defaultSubnet, nil)
_, err = alloc1.Allocate("foo", subnet, nil)
wt.AssertTrue(t, err == nil, "Failed to get address")
alloc1.Stop()
}
@@ -276,13 +276,13 @@ func TestFakeRouterSimple(t *testing.T) {
const (
cidr = "10.0.1.7/22"
)
allocs, _ := makeNetworkOfAllocators(2, cidr)
allocs, _, subnet := makeNetworkOfAllocators(2, cidr)
defer stopNetworkOfAllocators(allocs)
alloc1 := allocs[0]
//alloc2 := allocs[1]
alloc1.Allocate("foo", alloc1.defaultSubnet, nil)
alloc1.Allocate("foo", subnet, nil)
}
func TestAllocatorFuzz(t *testing.T) {
@@ -295,7 +295,7 @@ func TestAllocatorFuzz(t *testing.T) {
concurrency = 10
cidr = "10.0.1.7/22"
)
allocs, _ := makeNetworkOfAllocators(nodes, cidr)
allocs, _, subnet := makeNetworkOfAllocators(nodes, cidr)
defer stopNetworkOfAllocators(allocs)
// Test state
@@ -339,7 +339,7 @@ func TestAllocatorFuzz(t *testing.T) {
allocIndex := rand.Int31n(nodes)
alloc := allocs[allocIndex]
//common.Info.Printf("Allocate: asking allocator %d", allocIndex)
addr, err := alloc.Allocate(name, alloc.defaultSubnet, nil)
addr, err := alloc.Allocate(name, subnet, nil)
if err != nil {
panic(fmt.Sprintf("Could not allocate addr"))
@@ -405,7 +405,7 @@ func TestAllocatorFuzz(t *testing.T) {
//common.Info.Printf("Asking for %s on allocator %d again", addr, res.alloc)
newAddr, _ := alloc.Allocate(res.name, alloc.defaultSubnet, nil)
newAddr, _ := alloc.Allocate(res.name, subnet, nil)
oldAddr, _, _ := address.ParseCIDR(addr)
if newAddr.Start != oldAddr {
panic(fmt.Sprintf("Got different address for repeat request for %s: %s != %s", res.name, newAddr, oldAddr))
@@ -464,9 +464,9 @@ func TestAllocatorFuzz(t *testing.T) {
}
func TestGossipSkew(t *testing.T) {
alloc1 := makeAllocatorWithMockGossip(t, "01:00:00:01:00:00", "10.0.1.0/22", 2)
alloc1, _ := makeAllocatorWithMockGossip(t, "01:00:00:01:00:00", "10.0.1.0/22", 2)
defer alloc1.Stop()
alloc2 := makeAllocatorWithMockGossip(t, "02:00:00:02:00:00", "10.0.1.0/22", 2)
alloc2, _ := makeAllocatorWithMockGossip(t, "02:00:00:02:00:00", "10.0.1.0/22", 2)
alloc2.now = func() time.Time { return time.Now().Add(time.Hour * 2) }
defer alloc2.Stop()
+3 -3
View File
@@ -16,7 +16,7 @@ func badRequest(w http.ResponseWriter, err error) {
}
// HandleHTTP wires up ipams HTTP endpoints to the provided mux.
func (alloc *Allocator) HandleHTTP(router *mux.Router) {
func (alloc *Allocator) HandleHTTP(router *mux.Router, defaultSubnet address.CIDR) {
router.Methods("PUT").Path("/ip/{id}/{ip}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
closedChan := w.(http.CloseNotifier).CloseNotify()
vars := mux.Vars(r)
@@ -50,7 +50,7 @@ func (alloc *Allocator) HandleHTTP(router *mux.Router) {
})
router.Methods("GET").Path("/ip/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
addr, err := alloc.Lookup(mux.Vars(r)["id"], alloc.defaultSubnet)
addr, err := alloc.Lookup(mux.Vars(r)["id"], defaultSubnet)
if err != nil {
http.NotFound(w, r)
return
@@ -84,7 +84,7 @@ func (alloc *Allocator) HandleHTTP(router *mux.Router) {
router.Methods("POST").Path("/ip/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
closedChan := w.(http.CloseNotifier).CloseNotify()
ident := mux.Vars(r)["id"]
newAddr, err := alloc.Allocate(ident, alloc.defaultSubnet, closedChan)
newAddr, err := alloc.Allocate(ident, defaultSubnet, closedChan)
if err != nil {
badRequest(w, err)
return
+9 -8
View File
@@ -13,6 +13,7 @@ import (
"github.com/gorilla/mux"
"github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/ipam/address"
wt "github.com/weaveworks/weave/testing"
)
@@ -38,12 +39,12 @@ func doHTTP(method string, url string) (resp *http.Response, err error) {
return http.DefaultClient.Do(req)
}
func listenHTTP(alloc *Allocator) int {
func listenHTTP(alloc *Allocator, subnet address.CIDR) int {
router := mux.NewRouter()
router.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, fmt.Sprintln(alloc))
})
alloc.HandleHTTP(router)
alloc.HandleHTTP(router, subnet)
httpListener, err := net.Listen("tcp", ":0")
if err != nil {
@@ -79,8 +80,8 @@ func TestHttp(t *testing.T) {
testAddr2 = "10.2.0.1/16"
)
alloc := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", universe, 1)
port := listenHTTP(alloc)
alloc, subnet := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", universe, 1)
port := listenHTTP(alloc, subnet)
alloc.claimRingForTesting()
cidr1a := HTTPPost(t, allocURL(port, testCIDR1, containerID))
@@ -119,9 +120,9 @@ func TestBadHttp(t *testing.T) {
testCIDR1 = "10.0.0.0/8"
)
alloc := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1)
alloc, subnet := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1)
defer alloc.Stop()
port := listenHTTP(alloc)
port := listenHTTP(alloc, subnet)
alloc.claimRingForTesting()
cidr1 := HTTPPost(t, allocURL(port, testCIDR1, containerID))
@@ -154,10 +155,10 @@ func impTestHTTPCancel(t *testing.T) {
testCIDR1 = "10.0.3.0/29"
)
alloc := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1)
alloc, subnet := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1)
defer alloc.Stop()
alloc.claimRingForTesting()
port := listenHTTP(alloc)
port := listenHTTP(alloc, subnet)
// Stop the alloc so nothing actually works
unpause := alloc.pause()
+16 -12
View File
@@ -128,27 +128,29 @@ func CheckAllExpectedMessagesSent(allocs ...*Allocator) {
}
}
func makeAllocator(name string, cidrStr string, quorum uint) *Allocator {
func makeAllocator(name string, cidrStr string, quorum uint) (*Allocator, address.CIDR) {
peername, err := router.PeerNameFromString(name)
if err != nil {
panic(err)
}
alloc, err := NewAllocator(peername, router.PeerUID(rand.Int63()),
"nick-"+name, cidrStr, quorum)
_, cidr, err := address.ParseCIDR(cidrStr)
if err != nil {
panic(err)
}
return alloc
alloc := NewAllocator(peername, router.PeerUID(rand.Int63()),
"nick-"+name, cidr, quorum)
return alloc, cidr
}
func makeAllocatorWithMockGossip(t *testing.T, name string, universeCIDR string, quorum uint) *Allocator {
alloc := makeAllocator(name, universeCIDR, quorum)
func makeAllocatorWithMockGossip(t *testing.T, name string, universeCIDR string, quorum uint) (*Allocator, address.CIDR) {
alloc, subnet := makeAllocator(name, universeCIDR, quorum)
gossip := &mockGossipComms{t: t, name: name}
alloc.SetInterfaces(gossip)
alloc.Start()
return alloc
return alloc, subnet
}
func (alloc *Allocator) claimRingForTesting(allocs ...*Allocator) {
@@ -160,10 +162,10 @@ func (alloc *Allocator) claimRingForTesting(allocs ...*Allocator) {
alloc.space.AddRanges(alloc.ring.OwnedRanges())
}
func (alloc *Allocator) NumFreeAddresses() address.Offset {
func (alloc *Allocator) NumFreeAddresses(subnet address.CIDR) address.Offset {
resultChan := make(chan address.Offset)
alloc.actionChan <- func() {
resultChan <- alloc.space.NumFreeAddressesInRange(alloc.defaultSubnet.Start+1, alloc.defaultSubnet.End()-1)
resultChan <- alloc.space.NumFreeAddressesInRange(subnet.Start+1, subnet.End()-1)
}
return <-resultChan
}
@@ -285,13 +287,15 @@ func (client TestGossipRouterClient) GossipBroadcast(update router.GossipData) e
return client.router.GossipBroadcast(update)
}
func makeNetworkOfAllocators(size int, cidr string) ([]*Allocator, TestGossipRouter) {
func makeNetworkOfAllocators(size int, cidr string) ([]*Allocator, TestGossipRouter, address.CIDR) {
gossipRouter := TestGossipRouter{make(map[router.PeerName]chan gossipMessage), 0.0}
allocs := make([]*Allocator, size)
var subnet address.CIDR
for i := 0; i < size; i++ {
alloc := makeAllocator(fmt.Sprintf("%02d:00:00:02:00:00", i),
var alloc *Allocator
alloc, subnet = makeAllocator(fmt.Sprintf("%02d:00:00:02:00:00", i),
cidr, uint(size/2+1))
alloc.SetInterfaces(gossipRouter.connect(alloc.ourName, alloc))
alloc.Start()
@@ -300,7 +304,7 @@ func makeNetworkOfAllocators(size int, cidr string) ([]*Allocator, TestGossipRou
gossipRouter.GossipBroadcast(allocs[size-1].Gossip())
time.Sleep(1000 * time.Millisecond)
return allocs, gossipRouter
return allocs, gossipRouter, subnet
}
func stopNetworkOfAllocators(allocs []*Allocator) {
+27 -12
View File
@@ -17,6 +17,7 @@ import (
. "github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/common/updater"
"github.com/weaveworks/weave/ipam"
"github.com/weaveworks/weave/ipam/address"
weavenet "github.com/weaveworks/weave/net"
weave "github.com/weaveworks/weave/router"
)
@@ -139,8 +140,9 @@ func main() {
log.Println("Our name is", router.Ourself)
var allocator *ipam.Allocator
var defaultSubnet address.CIDR
if iprangeCIDR != "" {
allocator = createAllocator(router, apiPath, iprangeCIDR, ipsubnetCIDR, determineQuorum(peerCount, peers))
allocator, defaultSubnet = createAllocator(router, apiPath, iprangeCIDR, ipsubnetCIDR, determineQuorum(peerCount, peers))
} else if peerCount > 0 {
log.Fatal("-initpeercount flag specified without -iprange")
} else {
@@ -156,7 +158,7 @@ func main() {
// so there is no point in doing "weave launch -httpaddr ''".
// This is here to support stand-alone use of weaver.
if httpAddr != "" {
go handleHTTP(router, httpAddr, allocator)
go handleHTTP(router, httpAddr, allocator, defaultSubnet)
}
SignalHandlerLoop(router)
@@ -196,23 +198,35 @@ func logFrameFunc(debug bool) weave.LogFrameFunc {
}
}
func createAllocator(router *weave.Router, apiPath string, ipRangeStr string, defaultSubnetStr string, quorum uint) *ipam.Allocator {
allocator, err := ipam.NewAllocator(router.Ourself.Peer.Name, router.Ourself.Peer.UID, router.Ourself.Peer.NickName, ipRangeStr, quorum)
func parseAndCheckCIDR(cidrStr string) address.CIDR {
_, cidr, err := address.ParseCIDR(cidrStr)
if err != nil {
log.Fatal(err)
}
allocator.SetInterfaces(router.NewGossip("IPallocation", allocator))
allocator.Start()
if cidr.Size() < ipam.MinSubnetSize {
log.Fatalf("Allocation range smaller than minimum size %d: %s", ipam.MinSubnetSize, cidrStr)
}
return cidr
}
func createAllocator(router *weave.Router, apiPath string, ipRangeStr string, defaultSubnetStr string, quorum uint) (*ipam.Allocator, address.CIDR) {
ipRange := parseAndCheckCIDR(ipRangeStr)
defaultSubnet := ipRange
if defaultSubnetStr != "" {
if err = allocator.SetDefaultSubnet(defaultSubnetStr); err != nil {
log.Fatal(err)
defaultSubnet = parseAndCheckCIDR(defaultSubnetStr)
if !ipRange.Overlaps(defaultSubnet) {
log.Fatalf("Default subnet %s out of bounds: %s", defaultSubnet, ipRange)
}
}
err = updater.Start(apiPath, allocator)
allocator := ipam.NewAllocator(router.Ourself.Peer.Name, router.Ourself.Peer.UID, router.Ourself.Peer.NickName, ipRange, quorum)
allocator.SetInterfaces(router.NewGossip("IPallocation", allocator))
allocator.Start()
err := updater.Start(apiPath, allocator)
if err != nil {
log.Fatal("Unable to start watcher", err)
}
return allocator
return allocator, defaultSubnet
}
// Pick a quorum size heuristically based on the number of peer
@@ -235,11 +249,11 @@ func determineQuorum(initPeerCountFlag int, peers []string) uint {
return quorum
}
func handleHTTP(router *weave.Router, httpAddr string, allocator *ipam.Allocator) {
func handleHTTP(router *weave.Router, httpAddr string, allocator *ipam.Allocator, defaultSubnet address.CIDR) {
muxRouter := mux.NewRouter()
if allocator != nil {
allocator.HandleHTTP(muxRouter)
allocator.HandleHTTP(muxRouter, defaultSubnet)
}
muxRouter.Methods("GET").Path("/status").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -247,6 +261,7 @@ func handleHTTP(router *weave.Router, httpAddr string, allocator *ipam.Allocator
fmt.Fprintln(w, router.Status())
if allocator != nil {
fmt.Fprintln(w, allocator.String())
fmt.Fprintln(w, "Allocator default subnet:", defaultSubnet)
}
})
+2 -1
View File
@@ -145,11 +145,12 @@ reports on the current status of the weave router and IP allocator:
````
weave router git-8f675f15c0b5
...
Allocator universe 10.2.0.0/16 (default subnet 10.2.1.0/24)
Allocator universe 10.2.0.0/16
Owned Ranges:
10.2.1.1 -> 96:e9:e2:2e:2d:bc (host1) (v3)
10.2.1.128 -> ea:84:25:9b:31:2e (host2) (v3)
10.2.1.192 -> ea:6c:21:09:cf:f0 (host3) (v9)
Allocator default subnet: 10.2.1.0/24
````
The first section covers the router; see the [troubleshooting