# patroni.postgresql.config module

class patroni.postgresql.config.ConfigHandler(postgresql: Postgresql, config: Dict[str, Any])

  Bases: `object`

  CMDLINE_OPTIONS = <CaseInsensitiveDict{'listen_addresses': (None, <function _false_validator>, 90100), 'port': (None, <function _false_validator>, 90100), 'cluster_name': (None, <function _false_validator>, 90500), 'wal_level': ('hot_standby', <patroni.validator.EnumValidator object>, 90100), 'hot_standby': ('on', <function _bool_is_true_validator>, 90100), 'max_connections': (100, <patroni.validator.IntValidator object>, 90100), 'max_wal_senders': (10, <patroni.validator.IntValidator object>, 90100), 'wal_keep_segments': (8, <patroni.validator.IntValidator object>, 90100), 'wal_keep_size': ('128MB', <patroni.validator.IntValidator object>, 130000), 'max_prepared_transactions': (0, <patroni.validator.IntValidator object>, 90100), 'max_locks_per_transaction': (64, <patroni.validator.IntValidator object>, 90100), 'track_commit_timestamp': ('off', <function _bool_validator>, 90500), 'max_replication_slots': (10, <patroni.validator.IntValidator object>, 90400), 'max_worker_processes': (8, <patroni.validator.IntValidator object>, 90400), 'wal_log_hints': ('on', <function _bool_validator>, 90400)} at 72e0338defd0>
  _RECOVERY_PARAMETERS = <CaseInsensitiveSet('archive_cleanup_command', 'pause_at_recovery_target', 'primary_conninfo', 'primary_slot_name', 'promote_trigger_file', 'recovery_end_command', 'recovery_min_apply_delay', 'recovery_target', 'recovery_target_action', 'recovery_target_inclusive', 'recovery_target_lsn', 'recovery_target_name', 'recovery_target_time', 'recovery_target_timeline', 'recovery_target_xid', 'restore_command', 'standby_mode', 'trigger_file') at 72e0338e2190>
  __init__(postgresql: Postgresql, config: Dict[str, Any]) → None
  _adjust_recovery_parameters() → None
  _check_passfile(passfile: str, wanted_primary_conninfo: Dict[str, Any]) → bool
  _check_primary_conninfo(primary_conninfo: Dict[str, Any], wanted_primary_conninfo: Dict[str, Any]) → bool
  property _configuration_to_save: List[str]
  _get_pg_settings(names: Collection[str]) → Dict[Any, Tuple[Any, ...]]
  _get_tcp_local_address() → str
  static _get_unix_local_address(unix_socket_directories: str) → str
  static _handle_wal_buffers(old_values: Dict[Any, Tuple[Any, ...]], changes: CaseInsensitiveDict) → None
  static _pgpass_content(record: Dict[str, Any]) → str | None

    Generate content of pgpassfile based on connection parameters.

    Note

    In case if `host` is a comma separated string we generate one line per host.

    Parameters:

      record – `dict` object with connection parameters.

    Returns:

      a string with generated content of pgpassfile or `None` if there is no `password`.

  _read_recovery_params() → Tuple[CaseInsensitiveDict | None, bool]

    Read current recovery parameters values.

    Note

    We query Postgres only if we detected that Postgresql was restarted or when at least one of the following files was updated:

    > - `postgresql.conf`;

    > - `postgresql.auto.conf`;

    > - `passfile` that is used in the `primary_conninfo`.

    Returns:

      a tuple with two elements:

      - `CaseInsensitiveDict` object with current values of recovery parameters, or `None` if no configuration files were updated;

      - `True` if new values of recovery parameters were queried, `False` otherwise.

  _read_recovery_params_pre_v12() → Tuple[CaseInsensitiveDict | None, bool]
  property _recovery_parameters_to_compare: CaseInsensitiveSet
  static _remove_file_if_exists(name: str) → None
  _sanitize_auto_conf() → None
  property _triggerfile_wrong_name: str
  _write_recovery_params(fd: ConfigWriter, recovery_params: CaseInsensitiveDict) → None
  append_pg_hba(config: List[str]) → bool
  build_recovery_params(member: Leader | Member | None) → CaseInsensitiveDict
  check_directories() → None
  check_recovery_conf(member: Leader | Member | None) → Tuple[bool, bool]

    Returns a tuple. The first boolean element indicates that recovery params don’t match and the second is set to True if the restart is required in order to apply new values

  property config_dir: str
  config_writer(filename: str) → Iterator[ConfigWriter]

    Create `ConfigWriter` object and set permissions on a filename.

    Parameters:

      filename – path to a config file.

    Yields:

      `ConfigWriter` object.

  property effective_configuration: CaseInsensitiveDict

    It might happen that the current value of one (or more) below parameters stored in the controldata is higher than the value stored in the global cluster configuration.

    Example: max_connections in global configuration is 100, but in controldata Current max_connections setting: 200. If we try to start postgres with max_connections=100, it will immediately exit. As a workaround we will start it with the values from controldata and set pending_restart to true as an indicator that current values of parameters are not matching expectations.

  format_dsn(params: Dict[str, Any]) → str

    Format connection string from connection parameters.

    Note

    only parameters from the below list are considered and values are escaped.

    Parameters:

      params – `dict` object with connection parameters.

    Returns:

      a connection string in a format “key1=value2 key2=value2”

  get(key: str, default: Any | None = None) → Any | None
  get_server_parameters(config: Dict[str, Any]) → CaseInsensitiveDict
  property hba_file: str | None
  property ident_file: str | None
  load_current_server_parameters() → None

    Read GUC’s values from `pg_settings` when Patroni is joining the the postgres that is already running.

  property pg_hba_conf: str
  property pg_version: int

    Current full postgres version if instance is running, major version otherwise.

    We can only use `postgres --version` output if major version there equals to the one in data directory. If it is not the case, we should use major version from the `PG_VERSION` file.

  property postgresql_conf: str
  primary_conninfo_params(member: Leader | Member | None) → Dict[str, Any] | None
  recovery_conf_exists() → bool
  reload_config(config: Dict[str, Any], sighup: bool = False) → None
  remove_recovery_conf() → None
  replace_pg_hba() → bool | None

    Replace pg_hba.conf content in the PGDATA if hba_file is not defined in the postgresql.parameters and pg_hba is defined in postgresql configuration section.

    Returns:

      True if pg_hba.conf was rewritten.

  replace_pg_ident() → bool | None

    Replace pg_ident.conf content in the PGDATA if ident_file is not defined in the postgresql.parameters and pg_ident is defined in the postgresql section.

    Returns:

      True if pg_ident.conf was rewritten.

  property replication: Dict[str, Any]
  resolve_connection_addresses() → None

    Calculates and sets local and remote connection urls and options.

    This method sets:

      - `Postgresql.connection_string` attribute, which is later written to the member key in DCS as `conn_url`.

      - `ConfigHandler.local_replication_address` attribute, which is used for replication connections to local postgres.

      - `ConnectionPool.conn_kwargs` attribute, which is used for superuser connections to local postgres.

    Note

    If there is a valid directory in `postgresql.parameters.unix_socket_directories` in the Patroni configuration and `postgresql.use_unix_socket` and/or `postgresql.use_unix_socket_repl` are set to `True`, we respectively use unix sockets for superuser and replication connections to local postgres.

    If there is a requirement to use unix sockets, but nothing is set in the `postgresql.parameters.unix_socket_directories`, we omit a `host` in connection parameters relying on the ability of `libpq` to connect via some default unix socket directory.

    If unix sockets are not requested we “switch” to TCP, preferring to use `localhost` if it is possible to deduce that Postgres is listening on a local interface address.

    Otherwise we just used the first address specified in the `listen_addresses` GUC.

  restore_command() → str | None
  restore_configuration_files() → None

    restore a previously saved postgresql.conf

  property rewind_credentials: Dict[str, Any]
  save_configuration_files(check_custom_bootstrap: bool = False) → bool

    copy postgresql.conf to postgresql.conf.backup to be able to retrieve configuration files - originally stored as symlinks, those are normally skipped by pg_basebackup - in case of WAL-E basebackup (see http://comments.gmane.org/gmane.comp.db.postgresql.wal-e/239)

  set_file_permissions(filename: str) → None

    Set permissions of file filename according to the expected permissions.

    Note

    Use original umask if the file is not under PGDATA, use PGDATA permissions otherwise.

    Parameters:

      filename – path to a file which permissions might need to be adjusted.

  set_synchronous_standby_names(value: str | None) → bool | None

    Updates synchronous_standby_names and reloads if necessary. :returns: True if value was updated.

  setup_server_parameters() → None
  property superuser: Dict[str, Any]
  property synchronous_standby_names: str | None

    Get `synchronous_standby_names` value configured by the user.

    Returns:

      value of `synchronous_standby_names` in the Patroni configuration, if any, otherwise `None`.

  property triggerfile_good_name: str
  try_to_create_dir(d: str, msg: str) → None
  write_pgpass(record: Dict[str, Any]) → Dict[str, str]

    Maybe creates `_passfile` based on connection parameters.

    Parameters:

      record – `dict` object with connection parameters.

    Returns:

      a copy of environment variables, that will include `PGPASSFILE` in case if the file was written.

  write_postgresql_conf(configuration: CaseInsensitiveDict | None = None) → None
  write_recovery_conf(recovery_params: CaseInsensitiveDict) → None

class patroni.postgresql.config.ConfigWriter(filename: str)

  Bases: `object`

  __init__(filename: str) → None
  static escape(value: Any) → str
  write_param(param: str, value: Any) → None
  writeline(line: str) → None
  writelines(lines: List[str | None]) → None

patroni.postgresql.config._bool_is_true_validator(value: Any) → bool

patroni.postgresql.config._bool_validator(value: Any) → bool

patroni.postgresql.config._conninfo_dsn_parse(dsn: str) → Dict[str, str] | None

      >>> r = _conninfo_dsn_parse(" host = 'host' dbname = db\\ name requiressl=1 ")
      >>> r == {'dbname': 'db name', 'host': 'host', 'requiressl': '1'}
      True
      >>> _conninfo_dsn_parse('requiressl = 0\\') == {'requiressl': '0'}
      True
      >>> _conninfo_dsn_parse("host=a foo = '") is None
      True
      >>> _conninfo_dsn_parse("host=a foo = ") is None
      True
      >>> _conninfo_dsn_parse("1") is None
      True

patroni.postgresql.config._conninfo_parse(value: str) → Dict[str, str] | None

  Very simple equivalent of psycopg2.extensions.parse_dsn introduced in 2.7.0. Exists just for compatibility with 2.5.4+.

      >>> r = _conninfo_parse('postgresql://foo/postgres')
      >>> r == {'dbname': 'postgres', 'host': 'foo'}
      True
      >>> r = _conninfo_parse(" host = 'host' dbname = db\\ name requiressl=1 ")
      >>> r == {'dbname': 'db name', 'host': 'host', 'sslmode': 'require'}
      True
      >>> _conninfo_parse('requiressl = 0\\') == {'sslmode': 'prefer'}
      True

patroni.postgresql.config._conninfo_uri_parse(dsn: str) → Dict[str, str]

      >>> r = _conninfo_uri_parse('postgresql://u%2Fse:pass@:%2f123/db%2Fsdf?application_name=mya%2Fpp&ssl=true')
      >>> r == {'application_name': 'mya/pp', 'dbname': 'db/sdf', 'sslmode': 'require',              'password': 'pass', 'port': '/123', 'user': 'u/se'}
      True
      >>> r = _conninfo_uri_parse('postgresql://u%2Fse:pass@[::1]/db%2Fsdf?application_name=mya%2Fpp&ssl=true')
      >>> r == {'application_name': 'mya/pp', 'dbname': 'db/sdf', 'host': '::1', 'sslmode': 'require',              'password': 'pass', 'user': 'u/se'}
      True

patroni.postgresql.config._false_validator(value: Any) → bool

patroni.postgresql.config.get_param_diff(old_value: Any, new_value: Any, vartype: str | None = None, unit: str | None = None) → Dict[str, str]

  Get a dictionary representing a single PG parameter’s value diff.

  Parameters:

    - old_value – current `str` parameter value.

    - new_value – `str` value of the parameter after a restart.

    - vartype – the target type to parse old/new_value. See `vartype` argument of `maybe_convert_from_base_unit()`.

    - unit – unit of old/new_value. See `base_unit` argument of `maybe_convert_from_base_unit()`.

  Returns:

    a `dict` object that contains two keys: `old_value` and `new_value` with their values casted to `str` and converted from base units (if possible).

patroni.postgresql.config.mtime(filename: str) → float | None

patroni.postgresql.config.parse_dsn(value: str) → Dict[str, str] | None

  Compatibility layer on top of function from psycopg2/psycopg3, which parses connection strings. In this function sets the sslmode, ‘gssencmode’, and channel_binding to prefer and sslnegotiation to postgres if they are not present in the connection string. This is necessary to simplify comparison of the old and the new values.

      >>> r = parse_dsn('postgresql://foo/postgres')
      >>> r == {'dbname': 'postgres', 'host': 'foo', 'sslmode': 'prefer', 'gssencmode': 'prefer',              'channel_binding': 'prefer', 'sslnegotiation': 'postgres'}
      True
      >>> r = parse_dsn(" host = 'host' dbname = db\\ name requiressl=1 ")
      >>> r == {'dbname': 'db name', 'host': 'host', 'sslmode': 'require',              'gssencmode': 'prefer', 'channel_binding': 'prefer', 'sslnegotiation': 'postgres'}
      True
      >>> parse_dsn('requiressl = 0\\') == {'sslmode': 'prefer', 'gssencmode': 'prefer',                                            'channel_binding': 'prefer', 'sslnegotiation': 'postgres'}
      True
      >>> parse_dsn('foo=bar') == {'foo': 'bar', 'sslmode': 'prefer', 'gssencmode': 'prefer',                                 'channel_binding': 'prefer', 'sslnegotiation': 'postgres'}
      True

patroni.postgresql.config.read_param_value(value: str) → Tuple[None, None] | Tuple[str, int]

patroni.postgresql.config.read_recovery_param_value(value: str) → str | None

      >>> read_recovery_param_value('') is None
      True
      >>> read_recovery_param_value("'") is None
      True
      >>> read_recovery_param_value("''a") is None
      True
      >>> read_recovery_param_value('a b') is None
      True
      >>> read_recovery_param_value("'''") is None
      True
      >>> read_recovery_param_value("'\\") is None
      True
      >>> read_recovery_param_value("'a' s#") is None
      True
      >>> read_recovery_param_value("'\\'''' #a")
      "''"
      >>> read_recovery_param_value('asd')
      'asd'

patroni.postgresql.config.strip_comment(value: str) → str