Compare commits

..
9 Commits
7 changed files with 15 additions and 18 deletions
+5 -5
View File
@@ -34,9 +34,9 @@ Scenario: check local configuration reload
Then I receive a response code 202
Scenario: check dynamic configuration change via DCS
Given I run patronictl.py edit-config -s 'ttl=10' -s 'loop_wait=2' -p 'max_connections=101' --force batman
Then I receive a response returncode 0
And I receive a response output "+loop_wait: 2"
Given I issue a PATCH request to http://127.0.0.1:8008/config with {"ttl": 10, "loop_wait": 2, "postgresql": {"parameters": {"max_connections": 101}}}
Then I receive a response code 200
And I receive a response loop_wait 2
And Response on GET http://127.0.0.1:8008/patroni contains pending_restart after 11 seconds
When I issue a GET request to http://127.0.0.1:8008/config
Then I receive a response code 200
@@ -65,8 +65,8 @@ Scenario: check API requests for the primary-replica pair in the pause mode
Then postgres1 role is the secondary after 15 seconds
Scenario: check the failover via the API in the pause mode
Given I issue a POST request to http://127.0.0.1:8008/failover with {"leader": "postgres0", "candidate": "postgres1"}
Then I receive a response code 200
Given I run patronictl.py failover batman --master postgres0 --candidate postgres1 --force
Then I receive a response returncode 0
And postgres1 is a leader after 5 seconds
And postgres1 role is the primary after 10 seconds
And postgres0 role is the secondary after 10 seconds
+2 -2
View File
@@ -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 st in self.server.patroni.ha.fetch_nodes_statuses(members):
if st.failover_limitation() is None:
for _, reachable, _, _, tags in self.server.patroni.ha.fetch_nodes_statuses(members):
if reachable and not tags.get('nofailover', False):
return None
return 'failover is not possible: no good candidates have been found'
+5 -5
View File
@@ -903,14 +903,14 @@ def apply_config_changes(before_editing, data, kvpairs):
if prefix == ('postgresql', 'parameters'):
path = ['.'.join(path)]
key = path[0]
if len(path) == 1:
if value is None:
config.pop(key, None)
config.pop(path[0], None)
else:
config[key] = value
config[path[0]] = value
else:
if not isinstance(config.get(key), dict):
key = path[0]
if key not in config:
config[key] = {}
set_path_value(config[key], path[1:], value, prefix + (key,))
if config[key] == {}:
@@ -1017,7 +1017,7 @@ def edit_config(obj, cluster_name, force, quiet, kvpairs, pgkvpairs, apply_filen
return
if force or click.confirm('Apply these changes?'):
if not dcs.set_config_value(json.dumps(changed_data), cluster.config.index):
if not dcs.set_config_value(json.dumps(changed_data), cluster.config.modify_index):
raise PatroniCtlException("Config modification aborted due to concurrent changes")
click.echo("Configuration changed")
-1
View File
@@ -26,7 +26,6 @@ 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):
+1 -1
View File
@@ -1 +1 @@
__version__ = '1.3.2'
__version__ = '1.3'
+2 -3
View File
@@ -6,7 +6,6 @@ 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
@@ -39,7 +38,7 @@ class MockPostgresql(object):
class MockWatchdog(object):
is_healthy = False
is_healthy = True
class MockHa(object):
@@ -65,7 +64,7 @@ class MockHa(object):
@staticmethod
def fetch_nodes_statuses(members):
return [_MemberStatus(None, True, None, None, {}, False)]
return [[None, True, None, None, {}]]
@staticmethod
def schedule_future_restart(data):
-1
View File
@@ -135,7 +135,6 @@ class TestWatchdog(unittest.TestCase):
self.assertIsNone(wd.disable())
self.assertIsNone(wd.keepalive())
@patch('platform.system', Mock(return_value='Linux'))
def test_config_reload(self):
watchdog = Watchdog({'ttl': 30, 'loop_wait': 15, 'watchdog': {'mode': 'required'}})
self.assertTrue(watchdog.activate())