make rmpeer report on size of transferred space, and not fail
Closes #2058.
This commit is contained in:
1 parent
c48eefa82d
commit
62d823850c
5 files changed
+34
-27
No files matched your search
+21
-10
@@ -376,29 +376,40 @@ func (alloc *Allocator) Shutdown() {
|
||||
<-doneChan
|
||||
}
|
||||
|
||||
// AdminTakeoverRanges (Sync) - take over the ranges owned by a given peer.
|
||||
// AdminTakeoverRanges (Sync) - take over the ranges owned by a given
|
||||
// peer, and return how much space was transferred in the process.
|
||||
// Only done on adminstrator command.
|
||||
func (alloc *Allocator) AdminTakeoverRanges(peerNameOrNickname string) error {
|
||||
resultChan := make(chan error)
|
||||
func (alloc *Allocator) AdminTakeoverRanges(peerNameOrNickname string) address.Count {
|
||||
resultChan := make(chan address.Count)
|
||||
alloc.actionChan <- func() {
|
||||
peername, err := alloc.lookupPeername(peerNameOrNickname)
|
||||
if err != nil {
|
||||
resultChan <- fmt.Errorf("Cannot find peer '%s'", peerNameOrNickname)
|
||||
alloc.warnf("attempt to take over range from unknown peer '%s'", peerNameOrNickname)
|
||||
resultChan <- address.Count(0)
|
||||
return
|
||||
}
|
||||
|
||||
alloc.debugln("AdminTakeoverRanges:", peername)
|
||||
if peername == alloc.ourName {
|
||||
resultChan <- fmt.Errorf("Cannot take over ranges from yourself!")
|
||||
alloc.warnf("attempt to take over range from ourself")
|
||||
resultChan <- address.Count(0)
|
||||
return
|
||||
}
|
||||
|
||||
newRanges, err := alloc.ring.Transfer(peername, alloc.ourName)
|
||||
if err == nil && len(newRanges) > 0 {
|
||||
alloc.space.AddRanges(newRanges)
|
||||
alloc.gossip.GossipBroadcast(alloc.Gossip())
|
||||
newRanges := alloc.ring.Transfer(peername, alloc.ourName)
|
||||
|
||||
if len(newRanges) == 0 {
|
||||
resultChan <- address.Count(0)
|
||||
return
|
||||
}
|
||||
resultChan <- err
|
||||
|
||||
before := alloc.space.NumFreeAddressesInRange(alloc.universe)
|
||||
alloc.space.AddRanges(newRanges)
|
||||
after := alloc.space.NumFreeAddressesInRange(alloc.universe)
|
||||
|
||||
alloc.gossip.GossipBroadcast(alloc.Gossip())
|
||||
|
||||
resultChan <- after - before
|
||||
}
|
||||
return <-resultChan
|
||||
}
|
||||
|
||||
@@ -336,13 +336,18 @@ func TestTransfer(t *testing.T) {
|
||||
router.Flush()
|
||||
alloc2.gossip.GossipBroadcast(alloc3.Gossip())
|
||||
router.Flush()
|
||||
|
||||
free2 := alloc2.NumFreeAddresses(subnet.Range())
|
||||
free3 := alloc3.NumFreeAddresses(subnet.Range())
|
||||
|
||||
router.RemovePeer(alloc2.ourName)
|
||||
router.RemovePeer(alloc3.ourName)
|
||||
alloc2.Stop()
|
||||
alloc3.Stop()
|
||||
router.Flush()
|
||||
require.NoError(t, alloc1.AdminTakeoverRanges(alloc2.ourName.String()))
|
||||
require.NoError(t, alloc1.AdminTakeoverRanges(alloc3.ourName.String()))
|
||||
|
||||
require.Equal(t, free2+1, alloc1.AdminTakeoverRanges(alloc2.ourName.String()))
|
||||
require.Equal(t, free3+1, alloc1.AdminTakeoverRanges(alloc3.ourName.String()))
|
||||
router.Flush()
|
||||
|
||||
require.Equal(t, address.Count(1024), alloc1.NumFreeAddresses(subnet.Range()))
|
||||
|
||||
+2
-6
@@ -151,11 +151,7 @@ func (alloc *Allocator) HandleHTTP(router *mux.Router, defaultSubnet address.CID
|
||||
|
||||
router.Methods("DELETE").Path("/peer/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ident := mux.Vars(r)["id"]
|
||||
if err := alloc.AdminTakeoverRanges(ident); err != nil {
|
||||
badRequest(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(204)
|
||||
transferred := alloc.AdminTakeoverRanges(ident)
|
||||
fmt.Fprintf(w, "%d IPs taken over from %s\n", transferred, ident)
|
||||
})
|
||||
}
|
||||
+2
-8
@@ -498,28 +498,22 @@ func (r *Ring) PickPeerForTransfer(isValid func(mesh.PeerName) bool) mesh.PeerNa
|
||||
|
||||
// Transfer will mark all entries associated with 'from' peer as owned by 'to' peer
|
||||
// and return ranges indicating the new space we picked up
|
||||
func (r *Ring) Transfer(from, to mesh.PeerName) ([]address.Range, error) {
|
||||
func (r *Ring) Transfer(from, to mesh.PeerName) []address.Range {
|
||||
r.assertInvariants()
|
||||
defer r.assertInvariants()
|
||||
defer r.updateExportedVariables()
|
||||
|
||||
var newRanges []address.Range
|
||||
found := false
|
||||
|
||||
for i, entry := range r.Entries {
|
||||
if entry.Peer == from {
|
||||
found = true
|
||||
entry.Peer = to
|
||||
entry.Version++
|
||||
newRanges = append(newRanges, address.Range{Start: entry.Token, End: r.Entries.entry(i + 1).Token})
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
|
||||
return r.splitRangesOverZero(newRanges), nil
|
||||
return r.splitRangesOverZero(newRanges)
|
||||
}
|
||||
|
||||
// Contains returns true if addr is in this ring
|
||||
|
||||
@@ -24,6 +24,7 @@ Assume you had started the three peers in the example earlier, and
|
||||
then host3 caught fire, you can go to one of the other hosts and run:
|
||||
|
||||
host1$ weave rmpeer host3
|
||||
524288 IPs taken over from host3
|
||||
|
||||
Weave Net takes all the IP address ranges owned by host3 and transfers
|
||||
them to be owned by host1. The name "host3" is resolved via the
|
||||
@@ -36,4 +37,4 @@ status`.
|
||||
* [Address Allocation with IP Address Management (IPAM)](/site/ipam/overview-init-ipam.md)
|
||||
* [Automatic Allocation Across Multiple Subnets](/site/ipam/allocation-multi-ipam.md)
|
||||
* [Isolating Applications on a Weave Network](/site/using-weave/isolating-applications.md)
|
||||
|
||||
|
||||
Reference in new issue
Block a user