From 8cc0aa90b1c426accf9a4120455ba8c1114d3b91 Mon Sep 17 00:00:00 2001 From: Alexander Kukushkin Date: Tue, 26 May 2015 10:39:16 +0200 Subject: [PATCH 1/4] Fix typos when passing connection parameters to psycopg2. --- helpers/postgresql.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helpers/postgresql.py b/helpers/postgresql.py index 4726ddc4..5138662d 100644 --- a/helpers/postgresql.py +++ b/helpers/postgresql.py @@ -169,7 +169,8 @@ class Postgresql: if member.hostname == self.name: continue try: - member_conn = psycopg2.connect(parseurl(member.address)) + r = parseurl(member.address) + member_conn = psycopg2.connect(**r) member_conn.autocommit = True member_cursor = member_conn.cursor() member_cursor.execute( From 56daec0d6c94a48ac1826ab6935efde615980500 Mon Sep 17 00:00:00 2001 From: Alexander Kukushkin Date: Tue, 26 May 2015 15:53:57 +0200 Subject: [PATCH 2/4] Api: Bugfix for current_xlog_location in slaves. --- helpers/api.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/helpers/api.py b/helpers/api.py index f0d47e10..83aa619b 100644 --- a/helpers/api.py +++ b/helpers/api.py @@ -37,7 +37,9 @@ class RestApiHandler(BaseHTTPRequestHandler): cursor = self.server.cursor() cursor.execute("""SELECT to_char(pg_postmaster_start_time(), 'YYYY-MM-DD HH24:MI:SS.MS TZ'), pg_is_in_recovery(), - pg_current_xlog_location(), + CASE WHEN pg_is_in_recovery() + THEN null + ELSE pg_current_xlog_location() END, pg_last_xlog_receive_location(), pg_last_xlog_replay_location(), pg_is_in_recovery() AND pg_is_xlog_replay_paused()""") From 9968a66048157ba74d261b71766a8aaeae0d331b Mon Sep 17 00:00:00 2001 From: Alexander Kukushkin Date: Wed, 27 May 2015 11:08:06 +0200 Subject: [PATCH 3/4] helpers/postgresql.py Replace os.system with subprocess.call --- tests/test_governor.py | 7 ++++--- tests/test_postgresql.py | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/test_governor.py b/tests/test_governor.py index 34b46043..941d6d45 100644 --- a/tests/test_governor.py +++ b/tests/test_governor.py @@ -1,14 +1,15 @@ import os import psycopg2 -import unittest import requests +import subprocess import sys import time +import unittest import yaml from governor import Governor, main, sigchld_handler, sigterm_handler from test_ha import true, false -from test_postgresql import Postgresql, os_system, psycopg2_connect +from test_postgresql import Postgresql, subprocess_call, psycopg2_connect from test_etcd import requests_get, requests_put, requests_delete if sys.hexversion >= 0x03000000: @@ -38,7 +39,7 @@ class TestGovernor(unittest.TestCase): def set_up(self): self.touched = False - os.system = os_system + subprocess.call = subprocess_call psycopg2.connect = psycopg2_connect requests.get = requests_get requests.put = requests_put diff --git a/tests/test_postgresql.py b/tests/test_postgresql.py index 2e30b602..dc6fb512 100644 --- a/tests/test_postgresql.py +++ b/tests/test_postgresql.py @@ -1,13 +1,14 @@ import os import psycopg2 -import unittest import shutil +import subprocess +import unittest from helpers.etcd import Cluster, Member from helpers.postgresql import Postgresql -def os_system(cmd): +def subprocess_call(cmd, shell=False): return 0 @@ -89,7 +90,7 @@ class TestPostgresql(unittest.TestCase): super(TestPostgresql, self).__init__(method_name) def set_up(self): - os.system = os_system + subprocess.call = subprocess_call self.p = Postgresql({'name': 'test0', 'data_dir': 'data/test0', 'listen': '127.0.0.1, 127.0.0.2:5432', 'connect_address': '127.0.0.2:5432', 'replication': { 'username': 'replicator', 'password': 'rep-pass', 'network': '127.0.0.1/32'}, 'parameters': {'foo': 'bar'}, 'recovery_conf': {'foo': 'bar'}}) psycopg2.connect = psycopg2_connect From 56a9f52a1512f89dac142965d5d45035e9371430 Mon Sep 17 00:00:00 2001 From: Alexander Kukushkin Date: Wed, 27 May 2015 11:16:16 +0200 Subject: [PATCH 4/4] Replace os.system with subprocess.call --- helpers/postgresql.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/helpers/postgresql.py b/helpers/postgresql.py index 5138662d..868e9bbf 100644 --- a/helpers/postgresql.py +++ b/helpers/postgresql.py @@ -1,6 +1,7 @@ import logging import os import psycopg2 +import subprocess import sys import time @@ -42,7 +43,7 @@ class Postgresql: self.replication = config['replication'] self.recovery_conf = os.path.join(self.data_dir, 'recovery.conf') self.pid_path = os.path.join(self.data_dir, 'postmaster.pid') - self._pg_ctl = 'pg_ctl -w -D ' + self.data_dir + self._pg_ctl = ['pg_ctl', '-w', '-D', self.data_dir] self.local_address = self.get_local_address() connect_address = config.get('connect_address', None) or self.local_address @@ -98,7 +99,7 @@ class Postgresql: return not os.path.exists(self.data_dir) or os.listdir(self.data_dir) == [] def initialize(self): - ret = os.system(self._pg_ctl + ' initdb -o --encoding=UTF8') == 0 + ret = subprocess.call(self._pg_ctl + ['initdb', '-o', '--encoding=UTF8']) == 0 ret and self.write_pg_hba() return ret @@ -112,8 +113,8 @@ class Postgresql: try: os.environ['PGPASSFILE'] = pgpass - return os.system('pg_basebackup -R -D {data_dir} --host={host} --port={port} -U {user}'.format( - data_dir=self.data_dir, **r)) == 0 + return subprocess.call(['pg_basebackup', '-R', '-D', self.data_dir, + '--host=' + r['host'], '--port=' + str(r['port']), '-U', r['user']]) == 0 finally: os.environ.pop('PGPASSFILE') @@ -121,7 +122,7 @@ class Postgresql: return not self.query('SELECT pg_is_in_recovery()').fetchone()[0] def is_running(self): - return os.system(self._pg_ctl + ' status > /dev/null') == 0 + return subprocess.call(' '.join(self._pg_ctl) + ' status > /dev/null', shell=True) == 0 def start(self): if self.is_running(): @@ -133,18 +134,18 @@ class Postgresql: os.remove(self.pid_path) logger.info('Removed %s', self.pid_path) - ret = os.system(self._pg_ctl + ' start -o "{}"'.format(self.server_options())) == 0 + ret = subprocess.call(self._pg_ctl + ['start', '-o', self.server_options()]) == 0 ret and self.load_replication_slots() return ret def stop(self): - return os.system(self._pg_ctl + ' stop -m fast') != 0 + return subprocess.call(self._pg_ctl + ['stop', '-m', 'fast']) != 0 def reload(self): - return os.system(self._pg_ctl + ' reload') == 0 + return subprocess.call(self._pg_ctl + ['reload']) == 0 def restart(self): - return os.system(self._pg_ctl + ' restart -m fast') == 0 + return subprocess.call(self._pg_ctl + ['restart', '-m', 'fast']) == 0 def server_options(self): options = "--listen_addresses='{}' --port={}".format(self.listen_addresses, self.port) @@ -230,7 +231,7 @@ primary_conninfo = '{}' self.restart() def promote(self): - return os.system(self._pg_ctl + ' promote') == 0 + return subprocess.call(self._pg_ctl + ['promote']) == 0 def demote(self, leader): self.follow_the_leader(leader)