From f8b3703d6e97694e2ff216bb80a0818625a54e92 Mon Sep 17 00:00:00 2001 From: Alexander Kukushkin Date: Fri, 28 Jul 2017 15:38:55 +0200 Subject: [PATCH] Bugfix: failover via API didn't work due to change in _MemberStatus (#489) Originally fetch_nodes_statuses was returning a tuple, later it was wrapped into namedtuple _MemberStatus and recently _MemberStatus was extened with watchdog_failed field, but api.py was still relying on usual tuple and checking failover limitations on it's own instead of calling `failover_limitation` method. --- patroni/api.py | 4 ++-- patroni/ha.py | 1 + patroni/version.py | 2 +- tests/test_api.py | 5 +++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/patroni/api.py b/patroni/api.py index 327cf779..801b36ba 100644 --- a/patroni/api.py +++ b/patroni/api.py @@ -300,8 +300,8 @@ class RestApiHandler(BaseHTTPRequestHandler): members = [m for m in cluster.members if m.name != cluster.leader.name and m.api_url] if not members: return 'failover is not possible: cluster does not have members except leader' - for _, reachable, _, _, tags in self.server.patroni.ha.fetch_nodes_statuses(members): - if reachable and not tags.get('nofailover', False): + for st in self.server.patroni.ha.fetch_nodes_statuses(members): + if st.failover_limitation() is None: return None return 'failover is not possible: no good candidates have been found' diff --git a/patroni/ha.py b/patroni/ha.py index 8d27b6b5..90c7def5 100644 --- a/patroni/ha.py +++ b/patroni/ha.py @@ -26,6 +26,7 @@ class _MemberStatus(namedtuple('_MemberStatus', 'member,reachable,in_recovery,wa in_recovery - `!True` if pg_is_in_recovery() == true wal_position - value of `replayed_location` or `location` from JSON, dependin on its role. tags - dictionary with values of different tags (i.e. nofailover) + watchdog_failed - indicates that watchdog is required by configuration but not available or failed """ @classmethod def from_api_response(cls, member, json): diff --git a/patroni/version.py b/patroni/version.py index 6f4fa58f..72837bdc 100644 --- a/patroni/version.py +++ b/patroni/version.py @@ -1 +1 @@ -__version__ = '1.3' +__version__ = '1.3.1' diff --git a/tests/test_api.py b/tests/test_api.py index 02277c76..37d05ece 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -6,6 +6,7 @@ import unittest from mock import Mock, patch from patroni.api import RestApiHandler, RestApiServer from patroni.dcs import ClusterConfig, Member +from patroni.ha import _MemberStatus from patroni.utils import tzutc from six import BytesIO as IO from six.moves import BaseHTTPServer @@ -38,7 +39,7 @@ class MockPostgresql(object): class MockWatchdog(object): - is_healthy = True + is_healthy = False class MockHa(object): @@ -64,7 +65,7 @@ class MockHa(object): @staticmethod def fetch_nodes_statuses(members): - return [[None, True, None, None, {}]] + return [_MemberStatus(None, True, None, None, {}, False)] @staticmethod def schedule_future_restart(data):