From 832fe2f0b06e7d4fd8a8fd4b336acf40b9b4998b Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 30 Nov 2017 19:47:31 +0000 Subject: [PATCH] Update local copy of annotations even after error e.g. if we get a clash because someone else has updated the data, it returns the new data so we should work off that next time. Also re-fetch the Annotations every time round the main loop for safety. --- prog/kube-peers/annotations.go | 38 ++++++++++++++-------------------- prog/kube-peers/main.go | 3 +++ 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/prog/kube-peers/annotations.go b/prog/kube-peers/annotations.go index dd8b2db8..86915618 100644 --- a/prog/kube-peers/annotations.go +++ b/prog/kube-peers/annotations.go @@ -130,46 +130,40 @@ func (cml *configMapAnnotations) UpdatePeerList(list peerList) error { return cml.UpdateAnnotation(KubePeersAnnotationKey, string(recordBytes)) } -func (cml *configMapAnnotations) UpdateAnnotation(key, value string) error { +func (cml *configMapAnnotations) UpdateAnnotation(key, value string) (err error) { if cml.cm == nil { return errors.New("endpoint not initialized, call Init first") } - cm := cml.cm - cm.Annotations[key] = value - cm, err := cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm) - if err == nil { - cml.cm = cm - } + // speculatively change the state, then replace with whatever comes back + // from Update(), which will be the latest on the server whatever happened + cml.cm.Annotations[key] = value + cml.cm, err = cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm) return err } -func (cml *configMapAnnotations) RemoveAnnotation(key string) error { +func (cml *configMapAnnotations) RemoveAnnotation(key string) (err error) { if cml.cm == nil { return errors.New("endpoint not initialized, call Init first") } - cm := cml.cm - delete(cm.Annotations, key) - cm, err := cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm) - if err == nil { - cml.cm = cm - } + // speculatively change the state, then replace with whatever comes back + // from Update(), which will be the latest on the server whatever happened + delete(cml.cm.Annotations, key) + cml.cm, err = cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm) return err } -func (cml *configMapAnnotations) RemoveAnnotationsWithValue(valueToRemove string) error { +func (cml *configMapAnnotations) RemoveAnnotationsWithValue(valueToRemove string) (err error) { if cml.cm == nil { return errors.New("endpoint not initialized, call Init first") } - cm := cml.cm - for key, value := range cm.Annotations { + // speculatively change the state, then replace with whatever comes back + // from Update(), which will be the latest on the server whatever happened + for key, value := range cml.cm.Annotations { if value == valueToRemove { - delete(cm.Annotations, key) + delete(cml.cm.Annotations, key) } } - cm, err := cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm) - if err == nil { - cml.cm = cm - } + cml.cm, err = cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm) return err } diff --git a/prog/kube-peers/main.go b/prog/kube-peers/main.go index 03a15225..1961f70c 100644 --- a/prog/kube-peers/main.go +++ b/prog/kube-peers/main.go @@ -98,6 +98,9 @@ func checkIamInPeerList(cml *configMapAnnotations, c *kubernetes.Clientset, peer // Kubernetes, remove it from Weave IPAM func reclaimRemovedPeers(weave *weaveapi.Client, cml *configMapAnnotations, nodes []nodeInfo, myPeerName string) error { for { + if err := cml.Init(); err != nil { + return err + } // 1. Compare peers stored in the peerList against all peers reported by k8s now. storedPeerList, err := cml.GetPeerList() if err != nil {