mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-25 14:53:37 +00:00
Handle the case when initialize flag is not set and leader is present.
This commit is contained in:
+20
-14
@@ -6,6 +6,7 @@ import yaml
|
||||
|
||||
from patroni.api import RestApiServer
|
||||
from patroni.etcd import Etcd
|
||||
from patroni.exceptions import DCSError
|
||||
from patroni.ha import Ha
|
||||
from patroni.postgresql import Postgresql
|
||||
from patroni.utils import setup_signal_handlers, sleep, reap_children
|
||||
@@ -59,21 +60,26 @@ class Patroni:
|
||||
# is data directory empty?
|
||||
if self.postgresql.data_directory_empty():
|
||||
while True:
|
||||
# racing to initialize
|
||||
if self.ha.dcs.initialize():
|
||||
try:
|
||||
self.postgresql.bootstrap()
|
||||
except:
|
||||
# bail out and clean the initialize flag.
|
||||
self.cleanup_on_failed_initialization()
|
||||
raise
|
||||
self.ha.dcs.take_leader()
|
||||
break
|
||||
else:
|
||||
leader = self.ha.dcs.current_leader()
|
||||
if leader and self.postgresql.bootstrap(leader):
|
||||
try:
|
||||
cluster = self.ha.dcs.get_cluster()
|
||||
if not cluster.is_unlocked(): # the leader already exists
|
||||
if not cluster.initialize:
|
||||
self.ha.dcs.initialize()
|
||||
self.postgresql.bootstrap(cluster.leader)
|
||||
break
|
||||
sleep(5)
|
||||
# racing to initialize
|
||||
elif not cluster.initialize and self.ha.dcs.initialize():
|
||||
try:
|
||||
self.postgresql.bootstrap()
|
||||
except:
|
||||
# bail out and clean the initialize flag.
|
||||
self.cleanup_on_failed_initialization()
|
||||
raise
|
||||
self.ha.dcs.take_leader()
|
||||
break
|
||||
except DCSError:
|
||||
logger.info('waiting on DCS')
|
||||
sleep(5)
|
||||
elif self.postgresql.is_running():
|
||||
self.postgresql.load_replication_slots()
|
||||
|
||||
|
||||
+35
-2
@@ -9,7 +9,7 @@ import yaml
|
||||
|
||||
from mock import Mock, patch
|
||||
from patroni.api import RestApiServer
|
||||
from patroni.dcs import Cluster, Member
|
||||
from patroni.dcs import Cluster, Member, Leader
|
||||
from patroni.etcd import Etcd
|
||||
from patroni.exceptions import PostgresException
|
||||
from patroni import Patroni, main
|
||||
@@ -42,6 +42,30 @@ class Mock_BaseServer__is_shut_down:
|
||||
pass
|
||||
|
||||
|
||||
def get_cluster(initialize, leader):
|
||||
return Cluster(initialize, leader, None, None)
|
||||
|
||||
|
||||
def get_cluster_not_initialized_without_leader():
|
||||
return get_cluster(None, None)
|
||||
|
||||
|
||||
def get_cluster_initialized_without_leader():
|
||||
return get_cluster(True, None)
|
||||
|
||||
|
||||
def get_cluster_not_initialized_with_leader():
|
||||
return get_cluster(False, Leader(0, 0, 0,
|
||||
Member(0, 'leader', 'postgres://replicator:[email protected]:5435/postgres',
|
||||
None, None, 28)))
|
||||
|
||||
|
||||
def get_cluster_initialized_with_leader():
|
||||
return get_cluster(True, Leader(0, 0, 0,
|
||||
Member(0, 'leader', 'postgres://replicator:[email protected]:5435/postgres',
|
||||
None, None, 28)))
|
||||
|
||||
|
||||
class TestPatroni(unittest.TestCase):
|
||||
|
||||
def __init__(self, method_name='runTest'):
|
||||
@@ -129,24 +153,31 @@ class TestPatroni(unittest.TestCase):
|
||||
|
||||
def test_patroni_initialize(self):
|
||||
self.p.ha.dcs.client.write = etcd_write
|
||||
self.p.ha.dcs.client.read = etcd_read
|
||||
self.p.touch_member = self.touch_member
|
||||
self.p.postgresql.data_directory_empty = true
|
||||
self.p.ha.dcs.initialize = true
|
||||
self.p.postgresql.initialize = true
|
||||
self.p.postgresql.start = true
|
||||
self.p.ha.dcs.get_cluster = get_cluster_not_initialized_without_leader
|
||||
self.p.initialize()
|
||||
|
||||
self.p.ha.dcs.initialize = false
|
||||
self.p.ha.dcs.get_cluster = get_cluster_initialized_with_leader
|
||||
time.sleep = time_sleep
|
||||
self.p.ha.dcs.client.read = etcd_read
|
||||
self.p.initialize()
|
||||
|
||||
self.p.ha.dcs.current_leader = nop
|
||||
self.p.ha.dcs.get_cluster = get_cluster_initialized_without_leader
|
||||
self.assertRaises(SleepException, self.p.initialize)
|
||||
|
||||
self.p.postgresql.data_directory_empty = false
|
||||
self.p.initialize()
|
||||
|
||||
self.p.ha.dcs.get_cluster = get_cluster_not_initialized_with_leader
|
||||
self.p.postgresql.data_directory_empty = true
|
||||
self.p.initialize()
|
||||
|
||||
def test_schedule_next_run(self):
|
||||
self.p.next_run = time.time() - self.p.nap_time - 1
|
||||
self.p.schedule_next_run()
|
||||
@@ -156,6 +187,8 @@ class TestPatroni(unittest.TestCase):
|
||||
|
||||
def test_cleanup_on_initialization(self):
|
||||
self.p.ha.dcs.client.write = etcd_write
|
||||
self.p.ha.dcs.client.read = etcd_read
|
||||
self.p.ha.dcs.get_cluster = get_cluster_not_initialized_without_leader
|
||||
self.p.touch_member = self.touch_member
|
||||
self.p.postgresql.data_directory_empty = true
|
||||
self.p.ha.dcs.initialize = true
|
||||
|
||||
@@ -6,6 +6,7 @@ import unittest
|
||||
|
||||
from patroni.dcs import Cluster, Leader, Member
|
||||
from patroni.postgresql import Postgresql
|
||||
from test_ha import true, false
|
||||
|
||||
|
||||
def nop(*args, **kwargs):
|
||||
@@ -217,3 +218,9 @@ class TestPostgresql(unittest.TestCase):
|
||||
self.p.start()
|
||||
self.p.query = self.mock_query
|
||||
self.assertTrue(self.p.stop())
|
||||
|
||||
def test_move_data_directory(self):
|
||||
self.p.is_running = is_running
|
||||
os.rename = nop
|
||||
os.path.isdir = true
|
||||
self.p.move_data_directory()
|
||||
|
||||
Reference in New Issue
Block a user