Merge pull request #1174 from weaveworks/1128-iprange-error
More helpful error message when --ip-alloc-range mismatched Closes #1128.
This commit is contained in:
commit
358ae3a936
4 files changed
+30
-13
No files matched your search
+5
-1
@@ -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},
|
||||
@@ -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()
|
||||
|
||||
+13
-11
@@ -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 {
|
||||
@@ -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 {
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user