diff --git a/ipam/address/address.go b/ipam/address/address.go index 194a09db..f97d44c8 100644 --- a/ipam/address/address.go +++ b/ipam/address/address.go @@ -15,11 +15,13 @@ type Range struct { Start, End Address // [Start, End); Start <= End } -func MakeRange(start Address, size Offset) Range { return Range{Start: start, End: Add(start, size)} } -func (r Range) Size() Offset { return Subtract(r.End, r.Start) } -func (r Range) String() string { return fmt.Sprintf("[%s-%s)", r.Start, r.End) } -func (r1 Range) Overlaps(r2 Range) bool { return !(r1.Start >= r2.End || r1.End <= r2.Start) } -func (r Range) Contains(addr Address) bool { return addr >= r.Start && addr < r.End } +func NewRange(start Address, size Offset) Range { + return Range{Start: start, End: Add(start, size)} +} +func (r Range) Size() Offset { return Subtract(r.End, r.Start) } +func (r Range) String() string { return fmt.Sprintf("[%s-%s)", r.Start, r.End) } +func (r Range) Overlaps(or Range) bool { return !(r.Start >= or.End || r.End <= or.Start) } +func (r Range) Contains(addr Address) bool { return addr >= r.Start && addr < r.End } type CIDR struct { Start Address @@ -46,12 +48,12 @@ func ParseCIDR(s string) (Address, CIDR, error) { func (cidr CIDR) Size() Offset { return 1 << uint(32-cidr.PrefixLen) } -// End is exclusive, same as in Range -func (cidr CIDR) End() Address { return Add(cidr.Start, cidr.Size()) } -func (cidr CIDR) Range() Range { return Range{Start: cidr.Start, End: Add(cidr.Start, cidr.Size())} } +func (cidr CIDR) Range() Range { + return NewRange(cidr.Start, cidr.Size()) +} func (cidr CIDR) HostRange() Range { // Respect RFC1122 exclusions of first and last addresses - return Range{Start: cidr.Start + 1, End: cidr.End() - 1} + return NewRange(cidr.Start+1, cidr.Size()-2) } func (cidr CIDR) String() string { diff --git a/ipam/allocate.go b/ipam/allocate.go index 59239b80..f4ffa2e9 100644 --- a/ipam/allocate.go +++ b/ipam/allocate.go @@ -12,9 +12,9 @@ type allocateResult struct { type allocate struct { resultChan chan<- allocateResult - hasBeenCancelled func() bool ident string r address.Range // Range we are trying to allocate within + hasBeenCancelled func() bool } // Try returns true if the request is completed, false if pending diff --git a/ipam/allocator.go b/ipam/allocator.go index 036b8e31..80a3ae73 100644 --- a/ipam/allocator.go +++ b/ipam/allocator.go @@ -176,17 +176,18 @@ func hasBeenCancelled(cancelChan <-chan bool) func() bool { // Actor client API -// Allocate (Sync) - get IP address for container with given name -// if there isn't any space we block indefinitely +// Allocate (Sync) - get new IP address for container with given name in range +// if there isn't any space in that range we block indefinitely func (alloc *Allocator) Allocate(ident string, r address.Range, cancelChan <-chan bool) (address.Address, error) { resultChan := make(chan allocateResult) - op := &allocate{r: r, resultChan: resultChan, ident: ident, + op := &allocate{resultChan: resultChan, ident: ident, r: r, hasBeenCancelled: hasBeenCancelled(cancelChan)} alloc.doOperation(op, &alloc.pendingAllocates) result := <-resultChan 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) alloc.actionChan <- func() { diff --git a/ipam/claim.go b/ipam/claim.go index f17bd477..8d96e6e2 100644 --- a/ipam/claim.go +++ b/ipam/claim.go @@ -9,9 +9,9 @@ import ( type claim struct { resultChan chan<- error - hasBeenCancelled func() bool ident string addr address.Address + hasBeenCancelled func() bool } // Try returns true for success (or failure), false if we need to try again later diff --git a/ipam/ring/ring.go b/ipam/ring/ring.go index 910c87c6..fcdb362e 100644 --- a/ipam/ring/ring.go +++ b/ipam/ring/ring.go @@ -91,18 +91,6 @@ func New(start, end address.Address, peer router.PeerName) *Ring { return ring } -// TotalRemoteFree returns the approximate number of free IPs -// on other hosts. -func (r *Ring) TotalRemoteFree() address.Offset { - result := address.Offset(0) - for _, entry := range r.Entries { - if entry.Peer != r.Peer { - result += entry.Free - } - } - return result -} - // Returns the distance between two tokens on this ring, dealing // with ranges which cross the origin func (r *Ring) distance(start, end address.Address) address.Offset { @@ -341,10 +329,6 @@ func (r *Ring) ClaimForPeers(peers []router.PeerName) { common.Assert(pos == r.End) } -func (r *Ring) ClaimItAll() { - r.ClaimForPeers([]router.PeerName{r.Peer}) -} - func (r *Ring) FprintWithNicknames(w io.Writer, m map[router.PeerName]string) { for _, entry := range r.Entries { nickname, found := m[entry.Peer] diff --git a/ipam/ring/ring_test.go b/ipam/ring/ring_test.go index 11aa47f9..ce63a38e 100644 --- a/ipam/ring/ring_test.go +++ b/ipam/ring/ring_test.go @@ -716,6 +716,10 @@ func TestFuzzRingHard(t *testing.T) { } } +func (r *Ring) ClaimItAll() { + r.ClaimForPeers([]router.PeerName{r.Peer}) +} + func (es entries) String() string { var buffer bytes.Buffer fmt.Fprintf(&buffer, "[") diff --git a/ipam/space/space.go b/ipam/space/space.go index 72b8b6ec..1d912370 100644 --- a/ipam/space/space.go +++ b/ipam/space/space.go @@ -9,8 +9,6 @@ import ( "github.com/weaveworks/weave/ipam/address" ) -type Addr address.Address - type Space struct { // ours and free represent a set of addresses as a sorted // sequences of ranges. Even elements give the inclusive diff --git a/ipam/space/space_test.go b/ipam/space/space_test.go index 8ab0f369..46a135c5 100644 --- a/ipam/space/space_test.go +++ b/ipam/space/space_test.go @@ -1,7 +1,6 @@ package space import ( - "reflect" "testing" "github.com/weaveworks/weave/ipam/address" @@ -62,12 +61,12 @@ func TestLowlevel(t *testing.T) { s := New() wt.AssertEquals(t, s.NumFreeAddresses(), address.Offset(0)) - ok, got := s.Allocate(address.MakeRange(0, 1000)) + ok, got := s.Allocate(address.NewRange(0, 1000)) wt.AssertFalse(t, ok, "allocate in empty space should fail") s.Add(100, 100) wt.AssertEquals(t, s.NumFreeAddresses(), address.Offset(100)) - ok, got = s.Allocate(address.MakeRange(0, 1000)) + ok, got = s.Allocate(address.NewRange(0, 1000)) wt.AssertTrue(t, ok && got == 100, "allocate") wt.AssertEquals(t, s.NumFreeAddresses(), address.Offset(99)) wt.AssertNoErr(t, s.Claim(150)) @@ -77,19 +76,19 @@ func TestLowlevel(t *testing.T) { wt.AssertErrorInterface(t, s.Free(0), (*error)(nil), "free not allocated") wt.AssertErrorInterface(t, s.Free(100), (*error)(nil), "double free") - r, ok := s.Donate(address.MakeRange(0, 1000)) + r, ok := s.Donate(address.NewRange(0, 1000)) wt.AssertTrue(t, ok && r.Start == 125 && r.Size() == 25, "donate") // test Donate when addresses are scarce s = New() - r, ok = s.Donate(address.MakeRange(0, 1000)) + r, ok = s.Donate(address.NewRange(0, 1000)) wt.AssertTrue(t, !ok, "donate on empty space should fail") s.Add(0, 3) wt.AssertNoErr(t, s.Claim(0)) wt.AssertNoErr(t, s.Claim(2)) - r, ok = s.Donate(address.MakeRange(0, 1000)) + r, ok = s.Donate(address.NewRange(0, 1000)) wt.AssertTrue(t, ok && r.Start == 1 && r.End == 2, "donate") - r, ok = s.Donate(address.MakeRange(0, 1000)) + r, ok = s.Donate(address.NewRange(0, 1000)) wt.AssertTrue(t, !ok, "donate should fail") } @@ -110,12 +109,12 @@ func TestSpaceAllocate(t *testing.T) { wt.AssertEquals(t, space1.NumFreeAddresses(), address.Offset(20)) space1.assertInvariants() - _, addr1 := space1.Allocate(address.MakeRange(start, size)) + _, addr1 := space1.Allocate(address.NewRange(start, size)) wt.AssertEqualString(t, addr1.String(), testAddr1, "address") wt.AssertEquals(t, space1.NumFreeAddresses(), address.Offset(19)) space1.assertInvariants() - _, addr2 := space1.Allocate(address.MakeRange(start, size)) + _, addr2 := space1.Allocate(address.NewRange(start, size)) wt.AssertFalse(t, addr2.String() == testAddr1, "address") wt.AssertEquals(t, space1.NumFreeAddresses(), address.Offset(18)) wt.AssertEquals(t, space1.NumFreeAddressesInRange(address.Range{Start: ip(testAddr1), End: ip(testAddrx)}), address.Offset(13)) @@ -140,7 +139,7 @@ func TestSpaceFree(t *testing.T) { containerID = "deadbeef" ) - entireRange := address.MakeRange(ip(testAddr1), 20) + entireRange := address.NewRange(ip(testAddr1), 20) space := makeSpace(ip(testAddr1), 20) // Check we are prepared to give up the entire space @@ -192,10 +191,6 @@ func TestSpaceFree(t *testing.T) { wt.AssertEquals(t, space.OwnedRanges(), []address.Range{address.Range{Start: ip("10.0.3.4"), End: ip("10.0.3.24")}}) } -func (s1 *Space) Equal(s2 *Space) bool { - return reflect.DeepEqual(s1.ours, s2.ours) && reflect.DeepEqual(s1.free, s2.free) -} - func TestDonateSimple(t *testing.T) { const ( testAddr1 = "10.0.1.0" @@ -210,7 +205,7 @@ func TestDonateSimple(t *testing.T) { ps1 := makeSpace(ipAddr1, size) // Empty space set should split in two and give me the second half - r, ok := ps1.Donate(address.MakeRange(ip(testAddr1), size)) + r, ok := ps1.Donate(address.NewRange(ip(testAddr1), size)) numGivenUp := r.Size() wt.AssertTrue(t, ok, "Donate result") wt.AssertEqualString(t, r.Start.String(), "10.0.1.24", "Invalid start") @@ -220,7 +215,7 @@ func TestDonateSimple(t *testing.T) { // Now check we can give the rest up. count := 0 // count to avoid infinite loop for ; count < 1000; count++ { - r, ok := ps1.Donate(address.MakeRange(ip(testAddr1), size)) + r, ok := ps1.Donate(address.NewRange(ip(testAddr1), size)) if !ok { break } @@ -240,7 +235,7 @@ func TestDonateHard(t *testing.T) { // Fill a fresh space spaceset := makeSpace(start, size) for i := address.Offset(0); i < size; i++ { - ok, _ := spaceset.Allocate(address.MakeRange(start, size)) + ok, _ := spaceset.Allocate(address.NewRange(start, size)) wt.AssertTrue(t, ok, "Failed to get IP!") } @@ -253,7 +248,7 @@ func TestDonateHard(t *testing.T) { } // Now split - newRange, ok := spaceset.Donate(address.MakeRange(start, size)) + newRange, ok := spaceset.Donate(address.NewRange(start, size)) wt.AssertTrue(t, ok, "GiveUpSpace result") wt.AssertEquals(t, newRange.Start, ip("10.0.1.23")) wt.AssertEquals(t, newRange.Size(), address.Offset(24))