From 3b0ea900cd92762f39c2f656ae2d20e7abf20efe Mon Sep 17 00:00:00 2001 From: Christopher Winslett Date: Wed, 13 May 2015 16:37:14 -0700 Subject: [PATCH] followers without a leader based on feedback from @CyberDem0n and closes #3 --- governor.py | 2 +- helpers/ha.py | 1 + helpers/postgresql.py | 19 +++++++++++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/governor.py b/governor.py index 31081f07..c3847bd2 100755 --- a/governor.py +++ b/governor.py @@ -55,7 +55,7 @@ if postgresql.data_directory_empty(): else: time.sleep(5) else: - postgresql.write_recovery_conf({"address": "postgres://169.0.0.1:5432"}) + postgresql.follow_no_leader() postgresql.start() while True: diff --git a/helpers/ha.py b/helpers/ha.py index 80736420..bd770524 100644 --- a/helpers/ha.py +++ b/helpers/ha.py @@ -59,6 +59,7 @@ class Ha: self.state_handler.demote(self.fetch_current_leader()) return "demoting self because i am not the healthiest node" elif self.fetch_current_leader() is None: + self.state_handler.follow_no_leader() return "waiting on leader to be elected because i am not the healthiest node" else: self.state_handler.follow_the_leader(self.fetch_current_leader()) diff --git a/helpers/postgresql.py b/helpers/postgresql.py index 387ff19a..f6bbcd69 100644 --- a/helpers/postgresql.py +++ b/helpers/postgresql.py @@ -158,15 +158,18 @@ class Postgresql: f.close() def write_recovery_conf(self, leader_hash): - leader = urlparse(leader_hash["address"]) - f = open("%s/recovery.conf" % self.data_dir, "w") f.write(""" standby_mode = 'on' primary_slot_name = '%(recovery_slot)s' -primary_conninfo = 'user=%(user)s password=%(password)s host=%(hostname)s port=%(port)s sslmode=prefer sslcompression=1' recovery_target_timeline = 'latest' -""" % {"recovery_slot": self.name, "user": leader.username, "password": leader.password, "hostname": leader.hostname, "port": leader.port}) +""" % {"recovery_slot": self.name}) + if leader_hash is not None: + leader = urlparse(leader_hash["address"]) + f.write(""" +primary_conninfo = 'user=%(user)s password=%(password)s host=%(hostname)s port=%(port)s sslmode=prefer sslcompression=1' + """ % {"user": leader.username, "password": leader.password, "hostname": leader.hostname, "port": leader.port}) + if "recovery_conf" in self.config: for name, value in self.config["recovery_conf"].iteritems(): f.write("%s = '%s'\n" % (name, value)) @@ -179,6 +182,14 @@ recovery_target_timeline = 'latest' self.restart() return True + def follow_no_leader(self): + print "initing leaderless follower" + if os.system("grep primary_conninfo %(data_dir)s/recovery.conf > /dev/null" % {"data_dir": self.data_dir}) == 0: + self.write_recovery_conf(None) + if self.is_running(): + self.restart() + return True + def promote(self): return os.system("pg_ctl promote -w -D %s" % self.data_dir) == 0