Skip to content
This repository was archived by the owner on Jun 20, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1174 from weaveworks/1128-iprange-error
Browse files Browse the repository at this point in the history
More helpful error message when --ip-alloc-range mismatched

Closes #1128.
  • Loading branch information
rade committed Jul 17, 2015
2 parents 2ca0fb9 + 2dbf838 commit 358ae3a
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 13 deletions.
6 changes: 5 additions & 1 deletion ipam/allocator.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func NewAllocator(ourName router.PeerName, ourUID router.PeerUID, ourNickname st
return &Allocator{
ourName: ourName,
universe: universe,
ring: ring.New(universe.Start, address.Add(universe.Start, universe.Size()), ourName),
ring: ring.New(universe.Start, universe.End, ourName),
owned: make(map[string][]address.Address),
paxos: paxos.NewNode(ourName, ourUID, quorum),
nicknames: map[router.PeerName]string{ourName: ourNickname},
Expand Down Expand Up @@ -643,6 +643,10 @@ func (alloc *Allocator) update(sender router.PeerName, msg []byte) error {
// shouldn't get updates for a empty Ring. But tolerate
// them just in case.
if data.Ring != nil {
if data.Ring.Range() != alloc.universe {
return fmt.Errorf("Incompatible IP allocation range %s; ours is %s",
data.Ring.Range().AsCIDRString(), alloc.universe.AsCIDRString())
}
err = alloc.ring.Merge(*data.Ring)
if !alloc.ring.Empty() {
alloc.pruneNicknames()
Expand Down
24 changes: 13 additions & 11 deletions ipam/ring/ring.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,14 @@ func (r *Ring) assertInvariants() {

// Errors returned by Merge
var (
ErrNotSorted = errors.New("Ring not sorted")
ErrTokenRepeated = errors.New("Token appears twice in ring")
ErrTokenOutOfRange = errors.New("Token is out of range")
ErrDifferentSubnets = errors.New("IP Allocator with different subnet detected")
ErrNewerVersion = errors.New("Received new version for entry I own!")
ErrInvalidEntry = errors.New("Received invalid state update!")
ErrEntryInMyRange = errors.New("Received new entry in my range!")
ErrNoFreeSpace = errors.New("No free space found!")
ErrInvalidTimeout = errors.New("dt must be greater than 0")
ErrNotFound = errors.New("No entries for peer found")
ErrNotSorted = errors.New("Ring not sorted")
ErrTokenRepeated = errors.New("Token appears twice in ring")
ErrTokenOutOfRange = errors.New("Token is out of range")
ErrDifferentRange = errors.New("Received range differs from ours!")
ErrNewerVersion = errors.New("Received new version for entry I own!")
ErrInvalidEntry = errors.New("Received invalid state update!")
ErrEntryInMyRange = errors.New("Received new entry in my range!")
ErrNotFound = errors.New("No entries for peer found")
)

func (r *Ring) checkInvariants() error {
Expand Down Expand Up @@ -92,6 +90,10 @@ func New(start, end address.Address, peer router.PeerName) *Ring {
return ring
}

func (r *Ring) Range() address.Range {
return address.Range{Start: r.Start, End: r.End}
}

// 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 {
Expand Down Expand Up @@ -187,7 +189,7 @@ func (r *Ring) Merge(gossip Ring) error {
}

if r.Start != gossip.Start || r.End != gossip.End {
return ErrDifferentSubnets
return ErrDifferentRange
}

// Now merge their ring with yours, in a temporary ring.
Expand Down
2 changes: 1 addition & 1 deletion ipam/ring/ring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func TestMergeErrors(t *testing.T) {
// Should Merge two rings for different ranges
ring2 = New(start, middle, peer2name)
ring2.Entries = []*entry{}
require.True(t, ring1.Merge(*ring2) == ErrDifferentSubnets, "Expected ErrDifferentSubnets")
require.True(t, ring1.Merge(*ring2) == ErrDifferentRange, "Expected ErrDifferentRange")

// Cannot Merge newer version of entry I own
ring2 = New(start, end, peer2name)
Expand Down
11 changes: 11 additions & 0 deletions net/address/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ func (r Range) String() string { return fmt.Sprintf("[%s-%s)", r.Sta
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 }

func (r Range) AsCIDRString() string {
prefixLen := 32
for size := r.Size(); size > 1; size = size / 2 {
if size%2 != 0 { // Size not a power of two; cannot be expressed as a CIDR.
return r.String()
}
prefixLen--
}
return CIDR{Start: r.Start, PrefixLen: prefixLen}.String()
}

type CIDR struct {
Start Address
PrefixLen int
Expand Down

0 comments on commit 358ae3a

Please sign in to comment.