diff --git a/patroni/postgresql/config.py b/patroni/postgresql/config.py index 10df64b4..d3db7254 100644 --- a/patroni/postgresql/config.py +++ b/patroni/postgresql/config.py @@ -6,6 +6,7 @@ import socket import stat import time +from patroni.exceptions import PatroniException from six.moves.urllib_parse import urlparse, parse_qsl, unquote from urllib3.response import HTTPHeaderDict @@ -334,7 +335,10 @@ class ConfigHandler(object): self._standby_signal = os.path.join(postgresql.data_dir, 'standby.signal') self._auto_conf = os.path.join(postgresql.data_dir, 'postgresql.auto.conf') self._auto_conf_mtime = None - self._pgpass = config.get('pgpass') or os.path.join(os.path.expanduser('~'), 'pgpass') + self._pgpass = os.path.abspath(config.get('pgpass') or os.path.join(os.path.expanduser('~'), 'pgpass')) + if os.path.exists(self._pgpass) and not os.path.isfile(self._pgpass): + raise PatroniException("'{}' exists and it's not a file, check your `postgresql.pgpass` configuration" + .format(self._pgpass)) self._passfile = None self._passfile_mtime = None self._synchronous_standby_names = None @@ -360,6 +364,8 @@ class ConfigHandler(object): if "stats_temp_directory" in self._server_parameters: self.try_to_create_dir(self._server_parameters["stats_temp_directory"], "'{}' is defined in stats_temp_directory, {}") + self.try_to_create_dir(os.path.dirname(self._pgpass), + "'{}' is defined in `postgresql.pgpass`, {}") @property def _configuration_to_save(self): diff --git a/tests/test_postgresql.py b/tests/test_postgresql.py index b620b8f5..6331a06b 100644 --- a/tests/test_postgresql.py +++ b/tests/test_postgresql.py @@ -8,7 +8,7 @@ import time from mock import Mock, MagicMock, PropertyMock, patch, mock_open from patroni.async_executor import CriticalTask from patroni.dcs import Cluster, ClusterConfig, Member, RemoteMember, SyncState -from patroni.exceptions import PostgresConnectionException +from patroni.exceptions import PostgresConnectionException, PatroniException from patroni.postgresql import Postgresql, STATE_REJECT, STATE_NO_RESPONSE from patroni.postgresql.postmaster import PostmasterProcess from patroni.postgresql.slots import SlotsHandler @@ -695,3 +695,8 @@ class TestPostgresql(BaseTestPostgresql): self.p.cancellable.cancel() self.assertFalse(self.p.start()) self.assertTrue(self.p.pending_restart) + + @patch('os.path.exists', Mock(return_value=True)) + @patch('os.path.isfile', Mock(return_value=False)) + def test_pgpass_is_dir(self): + self.assertRaises(PatroniException, self.setUp)