diff --git a/pkg/tools/etcd_tools.go b/pkg/tools/etcd_tools.go index 101b43586d3..ccea211b726 100644 --- a/pkg/tools/etcd_tools.go +++ b/pkg/tools/etcd_tools.go @@ -92,6 +92,11 @@ func IsEtcdTestFailed(err error) bool { return isEtcdErrorNum(err, EtcdErrorCodeTestFailed) } +// IsEtcdNodeExist returns true iff err is an etcd node aleady exist error. +func IsEtcdNodeExist(err error) bool { + return isEtcdErrorNum(err, EtcdErrorCodeNodeExist) +} + // IsEtcdWatchStoppedByUser returns true iff err is a client triggered stop. func IsEtcdWatchStoppedByUser(err error) bool { return etcd.ErrWatchStoppedByUser == err @@ -232,15 +237,20 @@ func (h *EtcdHelper) AtomicUpdate(key string, ptrToType interface{}, tryUpdate E return err } - // First time this key has been used, just set. - if index == 0 { - return h.SetObj(key, ret) - } - data, err := h.Encoding.Encode(ret) if err != nil { return err } + + // First time this key has been used, try creating new value. + if index == 0 { + _, err = h.Client.Create(key, string(data), 0) + if IsEtcdNodeExist(err) { + continue + } + return err + } + _, err = h.Client.CompareAndSwap(key, string(data), 0, origBody, index) if IsEtcdTestFailed(err) { continue