diff --git a/patroni/postgresql.py b/patroni/postgresql.py index 7e1d2712..1ad69719 100644 --- a/patroni/postgresql.py +++ b/patroni/postgresql.py @@ -48,6 +48,7 @@ class Postgresql: self.replication = config['replication'] self.superuser = config['superuser'] self.admin = config['admin'] + self.pgpass = config.get('pgpass', None) or os.path.join(os.path.expanduser('~'), 'pgpass') self.pg_rewind = config.get('pg_rewind', {}) self.callback = config.get('callbacks', {}) self.use_slots = config.get('use_slots', True) @@ -176,12 +177,12 @@ class Postgresql: os.path.exists(self.trigger_file) and os.unlink(self.trigger_file) def write_pgpass(self, record): - pgpass = 'pgpass' - with open(pgpass, 'w') as f: + with open(self.pgpass, 'w') as f: os.fchmod(f.fileno(), 0o600) f.write('{host}:{port}:*:{user}:{password}\n'.format(**record)) + env = os.environ.copy() - env['PGPASSFILE'] = pgpass + env['PGPASSFILE'] = self.pgpass return env def sync_from_leader(self, leader): diff --git a/postgres0.yml b/postgres0.yml index a155b1cd..8747a3af 100644 --- a/postgres0.yml +++ b/postgres0.yml @@ -34,6 +34,7 @@ postgresql: data_dir: data/postgresql0 maximum_lag_on_failover: 1048576 # 1 megabyte in bytes use_slots: True + pgpass: /tmp/pgpass0 pg_rewind: username: postgres password: zalando diff --git a/postgres1.yml b/postgres1.yml index 94e33a42..dcf2f0cf 100644 --- a/postgres1.yml +++ b/postgres1.yml @@ -34,6 +34,7 @@ postgresql: data_dir: data/postgresql1 maximum_lag_on_failover: 1048576 # 1 megabyte in bytes use_slots: True + pgpass: /tmp/pgpass1 pg_rewind: username: postgres password: zalando diff --git a/tests/test_postgresql.py b/tests/test_postgresql.py index 83e93ec0..0ed04a15 100644 --- a/tests/test_postgresql.py +++ b/tests/test_postgresql.py @@ -210,10 +210,16 @@ class TestPostgresql(unittest.TestCase): self.assertFalse(self.p.restart()) self.assertEquals(self.p.state, 'restart failed (restarting)') + @patch.object(builtins, 'open', MagicMock()) + def test_write_pgpass(self): + self.p.write_pgpass({'host': 'localhost', 'port': '5432', 'user': 'foo', 'password': 'bar'}) + + @patch('patroni.postgresql.Postgresql.write_pgpass', MagicMock(return_value=dict())) def test_sync_from_leader(self): self.assertTrue(self.p.sync_from_leader(self.leader)) @patch('subprocess.call', side_effect=Exception("Test")) + @patch('patroni.postgresql.Postgresql.write_pgpass', MagicMock(return_value=dict())) def test_pg_rewind(self, mock_call): self.assertTrue(self.p.rewind(self.leader)) subprocess.call = mock_call @@ -222,6 +228,7 @@ class TestPostgresql(unittest.TestCase): @patch('patroni.postgresql.Postgresql.rewind', return_value=False) @patch('patroni.postgresql.Postgresql.remove_data_directory', MagicMock(return_value=True)) @patch('patroni.postgresql.Postgresql.single_user_mode', MagicMock(return_value=1)) + @patch('patroni.postgresql.Postgresql.write_pgpass', MagicMock(return_value=dict())) def test_follow_the_leader(self, mock_pg_rewind): self.p.demote() self.p.follow_the_leader(None) @@ -327,6 +334,7 @@ class TestPostgresql(unittest.TestCase): with patch('os.rename', Mock(side_effect=OSError())): self.p.move_data_directory() + @patch('patroni.postgresql.Postgresql.write_pgpass', MagicMock(return_value=dict())) def test_bootstrap(self): with patch('subprocess.call', Mock(return_value=1)): self.assertRaises(PostgresException, self.p.bootstrap)