From d459b92186d0db551231f386721da8976cd61a2c Mon Sep 17 00:00:00 2001 From: Ian Barwick Date: Tue, 14 Nov 2017 19:30:25 +0900 Subject: [PATCH] Add configuration file "passfile" This will enable a custom .pgpass to be included in "primary_conninfo" (provided it's supported by the libpq version on the standby). --- configfile.c | 3 +++ configfile.h | 3 ++- dbutils.c | 29 ++++++++++++++++++++++++++++- dbutils.h | 1 + repmgr-action-standby.c | 11 +++++++++++ repmgr.conf.sample | 2 +- 6 files changed, 46 insertions(+), 3 deletions(-) diff --git a/configfile.c b/configfile.c index 40e1aa9e..99cc4622 100644 --- a/configfile.c +++ b/configfile.c @@ -315,6 +315,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList * memset(options->recovery_min_apply_delay, 0, sizeof(options->recovery_min_apply_delay)); options->recovery_min_apply_delay_provided = false; options->use_primary_conninfo_password = false; + memset(options->passfile, 0, sizeof(options->passfile)); /*----------------- * repmgrd settings @@ -495,6 +496,8 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList * } else if (strcmp(name, "use_primary_conninfo_password") == 0) options->use_primary_conninfo_password = parse_bool(value, name, error_list); + else if (strcmp(name, "passfile") == 0) + strncpy(options->passfile, value, sizeof(options->passfile)); /* node check settings */ else if (strcmp(name, "archive_ready_warning") == 0) diff --git a/configfile.h b/configfile.h index 13504e77..e122636f 100644 --- a/configfile.h +++ b/configfile.h @@ -90,6 +90,7 @@ typedef struct char recovery_min_apply_delay[MAXLEN]; bool recovery_min_apply_delay_provided; bool use_primary_conninfo_password; + char passfile[MAXPGPATH]; /* node check settings */ int archive_ready_warning; @@ -153,7 +154,7 @@ typedef struct /* log settings */ \ "", "", "", DEFAULT_LOG_STATUS_INTERVAL, \ /* standby action settings */ \ - false, "", "", { NULL, NULL }, "", false, false, \ + false, "", "", { NULL, NULL }, "", false, false, "", \ /* node check settings */ \ DEFAULT_ARCHIVE_READY_WARNING, DEFAULT_ARCHIVE_READY_CRITICAL, \ DEFAULT_REPLICATION_LAG_WARNING, DEFAULT_REPLICATION_LAG_CRITICAL, \ diff --git a/dbutils.c b/dbutils.c index ac839076..ee29325f 100644 --- a/dbutils.c +++ b/dbutils.c @@ -594,7 +594,7 @@ parse_conninfo_string(const char *conninfo_str, t_conninfo_param_list *param_lis (option->val != NULL && option->val[0] == '\0')) continue; - /* Ignore application_name */ + /* Ignore settings specific to the upstream node */ if (ignore_local_params == true) { if (strcmp(option->keyword, "application_name") == 0) @@ -678,6 +678,33 @@ param_list_to_string(t_conninfo_param_list *param_list) } +/* + * check whether the libpq version in use recognizes the "passfile" parameter + * (should be 9.6 and later) + */ +bool +has_passfile(void) +{ + PQconninfoOption *defs = PQconndefaults(); + PQconninfoOption *def = NULL; + bool has_passfile = false; + + for (def = defs; def->keyword; def++) + { + if (strcmp(def->keyword, "passfile") == 0) + { + has_passfile = true; + break; + } + } + + PQconninfoFree(defs); + + return has_passfile; +} + + + /* ===================== */ /* transaction functions */ /* ===================== */ diff --git a/dbutils.h b/dbutils.h index 5fbfb16c..02618757 100644 --- a/dbutils.h +++ b/dbutils.h @@ -357,6 +357,7 @@ void param_set_ine(t_conninfo_param_list *param_list, const char *param, const char *param_get(t_conninfo_param_list *param_list, const char *param); bool parse_conninfo_string(const char *conninfo_str, t_conninfo_param_list *param_list, char *errmsg, bool ignore_local_params); char *param_list_to_string(t_conninfo_param_list *param_list); +bool has_passfile(void); /* transaction functions */ bool begin_transaction(PGconn *conn); diff --git a/repmgr-action-standby.c b/repmgr-action-standby.c index dcd63238..606a776b 100644 --- a/repmgr-action-standby.c +++ b/repmgr-action-standby.c @@ -4970,6 +4970,17 @@ write_primary_conninfo(char *line, t_conninfo_param_list *param_list) } } + /* passfile provided as configuration option */ + if (config_file_options.passfile[0] != '\n') + { + /* check if the libpq we're using supports "passfile=" */ + if (has_passfile() == true) + { + appendPQExpBuffer(&conninfo_buf, " passfile="); + appendConnStrVal(&conninfo_buf, config_file_options.passfile); + } + } + escaped = escape_recovery_conf_value(conninfo_buf.data); maxlen_snprintf(line, "primary_conninfo = '%s'\n", escaped); diff --git a/repmgr.conf.sample b/repmgr.conf.sample index 9f7da40a..bb08ed87 100644 --- a/repmgr.conf.sample +++ b/repmgr.conf.sample @@ -134,7 +134,7 @@ #use_primary_conninfo_password=false # explicitly set "password" in recovery.conf's # "primary_conninfo" parameter using the value contained # in the environment variable PGPASSWORD - +#passfile='' # path to .pgpass file to include in "primary_conninfo" #------------------------------------------------------------------------------ # external command options #------------------------------------------------------------------------------