From 2377c417e40bbbcc64173a64ab989dc8c894c10b Mon Sep 17 00:00:00 2001 From: Oleksii Kliukin Date: Thu, 10 Sep 2015 16:05:10 +0200 Subject: [PATCH] Fix etcd and zookeper interactions with initialize key. Fix unittests as well. --- patroni/dcs.py | 1 - patroni/etcd.py | 4 ++-- patroni/zookeeper.py | 9 ++++++--- tests/test_zookeeper.py | 10 +++++----- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/patroni/dcs.py b/patroni/dcs.py index 0c2bb9f7..bdba4004 100644 --- a/patroni/dcs.py +++ b/patroni/dcs.py @@ -73,7 +73,6 @@ class Cluster(namedtuple('Cluster', 'initialize,leader,last_leader_operation,mem class AbstractDCS: __metaclass__ = abc.ABCMeta - initialize_key = '/initialize' _INITIALIZE = 'initialize' _LEADER = 'leader' diff --git a/patroni/etcd.py b/patroni/etcd.py index d5730ffe..e24fa66b 100644 --- a/patroni/etcd.py +++ b/patroni/etcd.py @@ -233,7 +233,7 @@ class Etcd(AbstractDCS): @catch_etcd_errors def initialize(self): - return self.client.write(self.client_path(self.initialize_key), self._name, prevExist=False) + return self.client.write(self.initialize_path, self._name, prevExist=False) @catch_etcd_errors def delete_leader(self): @@ -241,7 +241,7 @@ class Etcd(AbstractDCS): @catch_etcd_errors def cancel_initialization(self): - return self.client.delete(self.client_path(self.initialize_key), prevValue=self._name) + return self.client.delete(self.initialize_path, prevValue=self._name) def watch(self, timeout): # watch on leader key changes if it is defined and current node is not lock owner diff --git a/patroni/zookeeper.py b/patroni/zookeeper.py index 7245b1a3..7c01f278 100644 --- a/patroni/zookeeper.py +++ b/patroni/zookeeper.py @@ -4,7 +4,7 @@ import requests import time from kazoo.client import KazooClient, KazooState -from kazoo.exceptions import NoNodeError, NodeExistsError +from kazoo.exceptions import NoNodeError, NodeExistsError, KazooException from patroni.dcs import AbstractDCS, Cluster, DCSError, Leader, Member, parse_connection_string from patroni.utils import sleep from requests.exceptions import RequestException @@ -222,8 +222,11 @@ class ZooKeeper(AbstractDCS): def cancel_initialization(self): node = self.get_node(self.initialize_path) - if node and node == self._name: - self.client.delete(self.initialize_path) + if node and node[0] == self._name: + try: + self.client.retry(self.client.delete, self.initialize_path, version=node[1].mzxid) + except KazooException: + logger.exception("Unable to delete initialize key") def watch(self, timeout): self.cluster_event.wait(timeout) diff --git a/tests/test_zookeeper.py b/tests/test_zookeeper.py index 3da71f02..0a95d0bc 100644 --- a/tests/test_zookeeper.py +++ b/tests/test_zookeeper.py @@ -71,8 +71,8 @@ class MockKazooClient: if self.leader: return ('foo', ZnodeStat(0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0)) return ('foo', ZnodeStat(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - elif path.endswith(patroni.zookeeper.ZooKeeper.initialize_key): - return 'foo' + elif path.endswith('/initialize'): + return ('foo', ZnodeStat(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) def get_children(self, path, watch=None, include_data=False): return ['foo', 'bar', 'buzz'] @@ -95,8 +95,8 @@ class MockKazooClient: return self.leader = True raise Exception - elif path.endswith(patroni.zookeeper.ZooKeeper.initialize_key): - raise Exception + elif path.endswith('/initialize'): + raise NoNodeError def set_hosts(self, hosts, randomize_hosts=None): pass @@ -154,7 +154,7 @@ class TestZooKeeper(unittest.TestCase): self.assertFalse(self.zk.initialize()) def test_cancel_initialization(self): - self.assertRaises(Exception, self.zk.cancel_initialization) + self.zk.cancel_initialization() def test_touch_member(self): self.zk.touch_member('new')