diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2904f6f..e810c5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -278,7 +278,7 @@ jobs: run: | conda install -y -c anaconda postgresql initdb -D test_db - pg_ctl -D test_db start + pg_ctl -D test_db -o "-d 5" start # start with debugging - name: Install pgsu run: | diff --git a/.gitignore b/.gitignore index 1f0253f..4e24c02 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ __pycache__ *.pyc .tox/ *.egg-info +.idea +.vscode +build/ +dist/ diff --git a/pgsu/__init__.py b/pgsu/__init__.py index 648e0c8..7c03db3 100644 --- a/pgsu/__init__.py +++ b/pgsu/__init__.py @@ -21,10 +21,15 @@ 'database': 'template1', } -# By default, try "sudo" only on Ubuntu -DEFAULT_TRY_SUDO = platform.system( -) == 'Linux' and 'Ubuntu' in platform.version() -DEFAULT_UNIX_USER = 'postgres' +# By default, try "sudo" only when 'postgres' user exists +DEFAULT_POSTGRES_UNIX_USER = 'postgres' +try: + import pwd + pwd.getpwnam(DEFAULT_POSTGRES_UNIX_USER) + DEFAULT_TRY_SUDO = True +except (KeyError, ModuleNotFoundError): + # user not found or pwd module not found (=not Unix) + DEFAULT_TRY_SUDO = False LOGGER = logging.getLogger('pgsu') LOGGER.setLevel(logging.DEBUG) @@ -63,7 +68,9 @@ def __init__(self, interactive=False, quiet=True, dsn=None, - determine_setup=True): + determine_setup=True, + try_sudo=DEFAULT_TRY_SUDO, + postgres_unix_user=DEFAULT_POSTGRES_UNIX_USER): """Store postgres connection info. :param interactive: use True for verdi commands @@ -72,7 +79,9 @@ def __init__(self, It is sufficient to provide only those values that deviate from the defaults. :param determine_setup: Whether to determine setup upon instantiation. You may set this to False and use the 'determine_setup()' method instead. - :param unix_user: UNIX user to try to "become", if connection via psycopg2 fails + :param try_sudo: If connection via psycopg2 fails, whether to try and use `sudo` to become + the `postgres_unix_user` and run commands using passwordless `psql`. + :param postgres_unix_user: UNIX user to try to "become", if connection via psycopg2 fails """ self.interactive = interactive if not quiet: @@ -88,9 +97,8 @@ def __init__(self, if dsn is not None: self.dsn.update(dsn) - # Used on Ubuntu only! - self.try_sudo = DEFAULT_TRY_SUDO - self.unix_user = DEFAULT_UNIX_USER + self.try_sudo = try_sudo + self.postgres_unix_user = postgres_unix_user if determine_setup: self.determine_setup() @@ -136,7 +144,7 @@ def determine_setup(self): # First try the host specified (works if 'host' has setting 'trust' in pg_hba.conf). # Then try local connection (works if 'local' has setting 'trust' in pg_hba.conf). # Then try 'host' localhost via TCP/IP. - for pg_host in unique_list([self.dsn.get('host'), None, 'localhost']): # yapf: disable + for pg_host in unique_list([self.dsn.get('host'), None, 'localhost']): # yapf: disable dsn['host'] = pg_host if _try_connect_psycopg(**dsn): @@ -149,10 +157,10 @@ def determine_setup(self): # Check if 'sudo' is available and try to become 'postgres'. if self.try_sudo: LOGGER.debug('Trying to connect by becoming the "%s" unix user...', - self.unix_user) + self.postgres_unix_user) if _sudo_exists(): dsn = self.dsn.copy() - dsn['user'] = self.unix_user + dsn['user'] = self.postgres_unix_user if _try_su_psql(interactive=self.interactive, dsn=dsn): self.dsn = dsn @@ -161,7 +169,7 @@ def determine_setup(self): else: LOGGER.info( 'Could not find `sudo` to become the the "%s" unix user.', - self.unix_user) + self.postgres_unix_user) self.setup_fail_counter += 1 return self._no_setup_detected() @@ -181,7 +189,8 @@ def _no_setup_detected(self): @property def is_connected(self): - """Whether connection to PostgreSQL cluster has been established.""" + """Whether successful way of connecting to PostgreSQL cluster has been determined. + """ return self.connection_mode in (PostgresConnectionMode.PSYCOPG, PostgresConnectionMode.PSQL) diff --git a/pyproject.toml b/pyproject.toml index 5c86010..3444549 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,6 @@ [tool.pylint.format] max-line-length = 120 +max-args = 7 [tool.pytest.ini_options] addopts = "--durations=0 --cov=pgsu"