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

Commit 7a959df

Browse files
committed
handles an edge case where peer claimed to own the action (to reclaim) but no longer
exists hence lock persists foever, fix makes a peer own the reclaim when nonexistent node found Fixes #3386
1 parent a73330f commit 7a959df

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

prog/kube-utils/main.go

+19-4
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func reclaimRemovedPeers(kube kubernetes.Interface, weave weaveClient, cml *conf
105105
common.Log.Warnln("[kube-peers] not removing myself", peer)
106106
continue
107107
}
108-
changed, err := reclaimPeer(weave, cml, peer.PeerName, myPeerName)
108+
changed, err := reclaimPeer(weave, cml, storedPeerList, peer.PeerName, myPeerName)
109109
if err != nil {
110110
return err
111111
}
@@ -125,17 +125,32 @@ func reclaimRemovedPeers(kube kubernetes.Interface, weave weaveClient, cml *conf
125125
// actions the reclaim.
126126
// Return a bool to show whether we attempted to change anything,
127127
// and an error if something went wrong.
128-
func reclaimPeer(weave weaveClient, cml *configMapAnnotations, peerName string, myPeerName string) (changed bool, err error) {
128+
func reclaimPeer(weave weaveClient, cml *configMapAnnotations, storedPeerList *peerList, peerName string, myPeerName string) (changed bool, err error) {
129129
common.Log.Debugln("[kube-peers] Preparing to remove disappeared peer", peerName)
130130
okToRemove := false
131+
nonExistentPeer := false
132+
131133
// 3. Check if there is an existing annotation with key X
132-
if existingAnnotation, found := cml.GetAnnotation(KubePeersPrefix + peerName); found {
134+
existingAnnotation, found := cml.GetAnnotation(KubePeersPrefix + peerName)
135+
if found {
133136
common.Log.Debugln("[kube-peers] Existing annotation", existingAnnotation)
134137
// 4. If annotation already contains my identity, ok;
135138
if existingAnnotation == myPeerName {
136139
okToRemove = true
140+
} else {
141+
// handle an edge case where peer claimed to own the action to reclaim but no longer
142+
// exists hence lock persists foever
143+
peerExists := false
144+
for _, peer := range storedPeerList.Peers {
145+
if existingAnnotation == peer.PeerName {
146+
peerExists = true
147+
break
148+
}
149+
}
150+
nonExistentPeer = !peerExists
137151
}
138-
} else {
152+
}
153+
if !found || nonExistentPeer {
139154
// 5. If non-existent, write an annotation with key X and contents "my identity"
140155
common.Log.Debugln("[kube-peers] Noting I plan to remove ", peerName)
141156
if err := cml.UpdateAnnotation(KubePeersPrefix+peerName, myPeerName); err == nil {

prog/kube-utils/peerlist_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ func TestPeerListFuzz(t *testing.T) {
137137
found := storedPeerList.contains(peerName(i))
138138
require.True(t, found, "peer %d not found in stored list", i)
139139

140-
_, err = reclaimPeer(mockWeave{}, cml, peerName(i), fmt.Sprintf("deleter-%d", i))
140+
_, err = reclaimPeer(mockWeave{}, cml, storedPeerList, peerName(i), fmt.Sprintf("deleter-%d", i))
141141
require.NoError(t, err)
142142

143143
storedPeerList, err = cml.GetPeerList()

0 commit comments

Comments
 (0)