mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-23 15:16:29 +00:00
Add option --no-upstream-connection and parse Barman conninfo string
This commit is contained in:
261
repmgr.c
261
repmgr.c
@@ -147,7 +147,7 @@ static bool read_backup_label(const char *local_data_directory, struct BackupLab
|
||||
|
||||
static void initialize_conninfo_params(t_conninfo_param_list *param_list, bool set_defaults);
|
||||
static void param_set(t_conninfo_param_list *param_list, const char *param, const char *value);
|
||||
|
||||
static bool parse_conninfo_string(const char *conninfo_str, t_conninfo_param_list *param_list, char *errmsg);
|
||||
static void parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_options *backup_options);
|
||||
|
||||
/* Global variables */
|
||||
@@ -223,6 +223,7 @@ main(int argc, char **argv)
|
||||
{"csv", no_argument, NULL, OPT_CSV},
|
||||
{"node", required_argument, NULL, OPT_NODE},
|
||||
{"without-barman", no_argument, NULL, OPT_WITHOUT_BARMAN},
|
||||
{"no-upstream-connection", no_argument, NULL, OPT_NO_UPSTREAM_CONNECTION},
|
||||
{"version", no_argument, NULL, 'V'},
|
||||
/* Following options deprecated */
|
||||
{"local-port", required_argument, NULL, 'l'},
|
||||
@@ -501,6 +502,9 @@ main(int argc, char **argv)
|
||||
case OPT_WITHOUT_BARMAN:
|
||||
runtime_options.without_barman = true;
|
||||
break;
|
||||
case OPT_NO_UPSTREAM_CONNECTION:
|
||||
runtime_options.no_upstream_connection = true;
|
||||
break;
|
||||
|
||||
/* deprecated options - output a warning */
|
||||
case 'l':
|
||||
@@ -1706,6 +1710,9 @@ do_standby_clone(void)
|
||||
bool upstream_record_found = false;
|
||||
int upstream_node_id;
|
||||
|
||||
|
||||
char datadir_list_filename[MAXLEN];
|
||||
|
||||
/*
|
||||
* conninfo params for the actual upstream node (which might be different
|
||||
* to the node we're cloning from)
|
||||
@@ -1839,24 +1846,84 @@ do_standby_clone(void)
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
/* Sanity check barman connection and installation, */
|
||||
if (mode == barman)
|
||||
{
|
||||
char command[MAXLEN];
|
||||
bool command_ok;
|
||||
/*
|
||||
* Check that there is at least one valid backup
|
||||
*/
|
||||
|
||||
log_info(_("Connecting to Barman server to verify backup for %s\n"), options.cluster_name);
|
||||
|
||||
maxlen_snprintf(command, "%s show-backup %s latest > /dev/null",
|
||||
make_barman_ssh_command(),
|
||||
options.cluster_name);
|
||||
command_ok = local_command(command, NULL);
|
||||
if (command_ok == false)
|
||||
{
|
||||
log_err(_("No valid backup for server %s was found in the Barman catalogue\n"),
|
||||
options.cluster_name);
|
||||
log_hint(_("Refer to the Barman documentation for more information\n"));
|
||||
|
||||
// ERR_BARMAN
|
||||
exit(ERR_INTERNAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the local repmgr subdirectory
|
||||
*/
|
||||
|
||||
maxlen_snprintf(local_repmgr_directory, "%s/repmgr", local_data_directory );
|
||||
maxlen_snprintf(datadir_list_filename, "%s/data.txt", local_repmgr_directory);
|
||||
|
||||
if (!create_pg_dir(local_repmgr_directory, runtime_options.force))
|
||||
{
|
||||
log_err(_("unable to use directory %s ...\n"),
|
||||
local_repmgr_directory);
|
||||
log_hint(_("use -F/--force option to force this directory to be overwritten\n"));
|
||||
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch server parameters from Barman
|
||||
*/
|
||||
|
||||
maxlen_snprintf(command, "%s show-server %s > %s/show-server.txt",
|
||||
make_barman_ssh_command(),
|
||||
options.cluster_name,
|
||||
local_repmgr_directory);
|
||||
(void)local_command(command, NULL);
|
||||
|
||||
// XXX check success
|
||||
}
|
||||
|
||||
|
||||
// XXX set this to "repmgr ?
|
||||
//param_set(&source_conninfo, "application_name", options.node_name);
|
||||
|
||||
/* Attempt to connect to the upstream server to verify its configuration */
|
||||
log_info(_("connecting to upstream node\n"));
|
||||
source_conn = establish_db_connection_by_params((const char**)source_conninfo.keywords, (const char**)source_conninfo.values, false);
|
||||
|
||||
/*
|
||||
* Unless in barman mode, exit with an error;
|
||||
* establish_db_connection_by_params() will have already logged an error message
|
||||
*/
|
||||
if (mode != barman && PQstatus(source_conn) != CONNECTION_OK)
|
||||
if (runtime_options.no_upstream_connection == false)
|
||||
{
|
||||
PQfinish(source_conn);
|
||||
exit(ERR_DB_CON);
|
||||
/* Attempt to connect to the upstream server to verify its configuration */
|
||||
log_info(_("connecting to upstream node\n"));
|
||||
|
||||
source_conn = establish_db_connection_by_params((const char**)source_conninfo.keywords, (const char**)source_conninfo.values, false);
|
||||
|
||||
/*
|
||||
* Unless in barman mode, exit with an error;
|
||||
* establish_db_connection_by_params() will have already logged an error message
|
||||
*/
|
||||
if (mode != barman && PQstatus(source_conn) != CONNECTION_OK)
|
||||
{
|
||||
PQfinish(source_conn);
|
||||
exit(ERR_DB_CON);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX insert into above if()
|
||||
/*
|
||||
* If a connection was established, perform some sanity checks on the
|
||||
* provided upstream connection
|
||||
@@ -1906,20 +1973,12 @@ do_standby_clone(void)
|
||||
primary_conn = source_conn;
|
||||
}
|
||||
}
|
||||
// XXX + --no-upstream-connection
|
||||
|
||||
// now set up conninfo params for the actual upstream, as we may be cloning from a different node
|
||||
// if upstream conn
|
||||
// get upstream node rec directly
|
||||
|
||||
if (options.upstream_node == NO_UPSTREAM_NODE)
|
||||
{
|
||||
upstream_node_id = get_master_node_id(source_conn, options.cluster_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
upstream_node_id = options.upstream_node;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1929,6 +1988,11 @@ do_standby_clone(void)
|
||||
t_node_info upstream_node_record = T_NODE_INFO_INITIALIZER;
|
||||
int query_result;
|
||||
|
||||
if (options.upstream_node == NO_UPSTREAM_NODE)
|
||||
upstream_node_id = get_master_node_id(source_conn, options.cluster_name);
|
||||
else
|
||||
upstream_node_id = options.upstream_node;
|
||||
|
||||
query_result = get_node_record(source_conn, options.cluster_name, upstream_node_id, &upstream_node_record);
|
||||
|
||||
if (query_result)
|
||||
@@ -1937,21 +2001,19 @@ do_standby_clone(void)
|
||||
strncpy(upstream_conninfo_str, upstream_node_record.conninfo_str, MAXLEN);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (mode == barman)
|
||||
{
|
||||
// attempt to get upstream node rec via Barman:
|
||||
// - get barman connstr
|
||||
// - parse to list (no set defaults)
|
||||
// - set dbname to the one provided by the user
|
||||
|
||||
char conninfo_on_barman[MAXLEN];
|
||||
|
||||
/*
|
||||
* We don't have an upstream connection - attempt to connect
|
||||
* to the upstream via the barman server to fetch the upstream's conninfo
|
||||
* Here we don't have a connection to the upstream node, and are executing
|
||||
* in Barman mode - we can try and connect via the Barman server to extract
|
||||
* the upstream node's conninfo string.
|
||||
*
|
||||
* To do this we need to extract Barman's conninfo string, replace the database
|
||||
* name with the repmgr one (they could well be different) and remotely execute
|
||||
* psql.
|
||||
*/
|
||||
get_barman_property(conninfo_on_barman, "conninfo", local_repmgr_directory);
|
||||
|
||||
<<<<<<< HEAD
|
||||
create_recovery_file(local_data_directory, &upstream_conninfo, conninfo_on_barman);
|
||||
|
||||
/*char buf[MAXLEN];
|
||||
@@ -1968,6 +2030,49 @@ do_standby_clone(void)
|
||||
break;
|
||||
}
|
||||
|
||||
=======
|
||||
char barman_conninfo_str[MAXLEN];
|
||||
t_conninfo_param_list barman_conninfo;
|
||||
char *errmsg = NULL;
|
||||
bool parse_success;
|
||||
PQExpBufferData command_output;
|
||||
|
||||
char buf[MAXLEN];
|
||||
|
||||
// XXX barman also returns "streaming_conninfo" - what's the difference?
|
||||
get_barman_property(barman_conninfo_str, "conninfo", local_repmgr_directory);
|
||||
|
||||
initialize_conninfo_params(&barman_conninfo, false);
|
||||
|
||||
parse_success = parse_conninfo_string(barman_conninfo_str, &barman_conninfo, errmsg);
|
||||
|
||||
if(parse_success == false)
|
||||
{
|
||||
log_err(_("Unable to parse barman conninfo string \"%s\":\n%s\n"),
|
||||
barman_conninfo_str, errmsg);
|
||||
// ERR_BARMAN
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
/* Overwrite database name */
|
||||
param_set(&barman_conninfo, "database", runtime_options.dbname);
|
||||
|
||||
{
|
||||
int c;
|
||||
printf("conninfo str: %s; size: %i\n", barman_conninfo_str, barman_conninfo.size);
|
||||
for (c = 0; c < barman_conninfo.size && barman_conninfo.keywords[c] != NULL; c++)
|
||||
{
|
||||
printf("%s: %s\n", barman_conninfo.keywords[c], barman_conninfo.values[c]);
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
if (options.upstream_node == NO_UPSTREAM_NODE)
|
||||
upstream_node_id = get_master_node_id(source_conn, options.cluster_name);
|
||||
else
|
||||
upstream_node_id = options.upstream_node;
|
||||
|
||||
initPQExpBuffer(&command_output);
|
||||
maxlen_snprintf(buf,
|
||||
"ssh %s \"psql -Aqt \\\"%s\\\" -c \\\""
|
||||
@@ -1980,7 +2085,7 @@ do_standby_clone(void)
|
||||
(void)local_command(buf, &command_output);
|
||||
maxlen_snprintf(buf, "%s", command_output.data);
|
||||
string_remove_trailing_newlines(buf);
|
||||
maxlen_snprintf(line, "primary_conninfo = '%s'\n", buf);*/
|
||||
maxlen_snprintf(line, "primary_conninfo = '%s'\n", buf);
|
||||
}
|
||||
|
||||
printf("upstream found? %c\n", upstream_record_found == true ? 'y' : 'n');
|
||||
@@ -2036,30 +2141,19 @@ do_standby_clone(void)
|
||||
{
|
||||
/* parse returned upstream conninfo string to recovery primary_conninfo params*/
|
||||
|
||||
PQconninfoOption *connOptions;
|
||||
PQconninfoOption *option;
|
||||
char *errmsg = NULL;
|
||||
|
||||
connOptions = PQconninfoParse(upstream_conninfo_str, &errmsg);
|
||||
bool parse_success;
|
||||
|
||||
printf("upstr conn: %s\n", upstream_conninfo_str);
|
||||
if (connOptions == NULL)
|
||||
|
||||
parse_success = parse_conninfo_string(upstream_conninfo_str, &upstream_conninfo, errmsg);
|
||||
if (parse_success == false)
|
||||
{
|
||||
log_err(_("Unable to parse conninfo string \"%s\" for upstream node %i\n"),
|
||||
upstream_conninfo_str, upstream_node_id);
|
||||
log_err(_("Unable to parse conninfo string \"%s\" for upstream node %i:\n%s\n"),
|
||||
upstream_conninfo_str, upstream_node_id, errmsg);
|
||||
PQfinish(source_conn);
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
for (option = connOptions; option && option->keyword; option++)
|
||||
{
|
||||
/* Ignore non-set or blank parameter values*/
|
||||
if((option->val == NULL) ||
|
||||
(option->val != NULL && option->val[0] == '\0'))
|
||||
continue;
|
||||
|
||||
param_set(&upstream_conninfo, option->keyword, option->val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2236,7 +2330,6 @@ do_standby_clone(void)
|
||||
char buf[MAXLEN];
|
||||
char backup_directory[MAXLEN];
|
||||
char backup_id[MAXLEN] = "";
|
||||
char datadir_list_filename[MAXLEN];
|
||||
char *p, *q;
|
||||
PQExpBufferData command_output;
|
||||
TablespaceDataList tablespace_list = { NULL, NULL };
|
||||
@@ -2247,49 +2340,6 @@ do_standby_clone(void)
|
||||
|
||||
if (mode == barman)
|
||||
{
|
||||
bool command_ok;
|
||||
/*
|
||||
* Check that there is at least one valid backup
|
||||
*/
|
||||
|
||||
maxlen_snprintf(command, "%s show-backup %s latest > /dev/null",
|
||||
make_barman_ssh_command(),
|
||||
options.cluster_name);
|
||||
command_ok = local_command(command, NULL);
|
||||
if (command_ok == false)
|
||||
{
|
||||
log_err(_("No valid backup for server %s was found in the Barman catalogue\n"),
|
||||
options.barman_server);
|
||||
log_hint(_("Refer to the Barman documentation for more information\n"));
|
||||
exit(ERR_INTERNAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the local repmgr subdirectory
|
||||
*/
|
||||
|
||||
maxlen_snprintf(local_repmgr_directory, "%s/repmgr", local_data_directory );
|
||||
maxlen_snprintf(datadir_list_filename, "%s/data.txt", local_repmgr_directory);
|
||||
|
||||
if (!create_pg_dir(local_repmgr_directory, runtime_options.force))
|
||||
{
|
||||
log_err(_("unable to use directory %s ...\n"),
|
||||
local_repmgr_directory);
|
||||
log_hint(_("use -F/--force option to force this directory to be overwritten\n"));
|
||||
r = ERR_BAD_CONFIG;
|
||||
retval = ERR_BAD_CONFIG;
|
||||
goto stop_backup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch server parameters from Barman
|
||||
*/
|
||||
|
||||
maxlen_snprintf(command, "%s show-server %s > %s/show-server.txt",
|
||||
make_barman_ssh_command(),
|
||||
options.cluster_name,
|
||||
local_repmgr_directory);
|
||||
(void)local_command(command, NULL);
|
||||
|
||||
/*
|
||||
* Locate Barman's backup directory
|
||||
@@ -5231,6 +5281,8 @@ do_witness_unregister(void)
|
||||
}
|
||||
|
||||
|
||||
// XXX + --no-upstream-connection
|
||||
|
||||
static void
|
||||
do_help(void)
|
||||
{
|
||||
@@ -6983,6 +7035,29 @@ param_set(t_conninfo_param_list *param_list, const char *param, const char *valu
|
||||
*/
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_conninfo_string(const char *conninfo_str, t_conninfo_param_list *param_list, char *errmsg)
|
||||
{
|
||||
PQconninfoOption *connOptions;
|
||||
PQconninfoOption *option;
|
||||
|
||||
connOptions = PQconninfoParse(conninfo_str, &errmsg);
|
||||
|
||||
if (connOptions == NULL)
|
||||
return false;
|
||||
|
||||
for (option = connOptions; option && option->keyword; option++)
|
||||
{
|
||||
/* Ignore non-set or blank parameter values*/
|
||||
if((option->val == NULL) ||
|
||||
(option->val != NULL && option->val[0] == '\0'))
|
||||
continue;
|
||||
|
||||
param_set(param_list, option->keyword, option->val);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
|
||||
4
repmgr.h
4
repmgr.h
@@ -58,6 +58,7 @@
|
||||
#define OPT_CSV 8
|
||||
#define OPT_NODE 9
|
||||
#define OPT_WITHOUT_BARMAN 10
|
||||
#define OPT_NO_UPSTREAM_CONNECTION 11
|
||||
|
||||
/* deprecated command line options */
|
||||
#define OPT_INITDB_NO_PWPROMPT 999
|
||||
@@ -85,6 +86,7 @@ typedef struct
|
||||
bool ignore_external_config_files;
|
||||
bool csv_mode;
|
||||
bool without_barman;
|
||||
bool no_upstream_connection;
|
||||
char masterport[MAXLEN];
|
||||
/*
|
||||
* configuration file parameters which can be overridden on the
|
||||
@@ -108,7 +110,7 @@ typedef struct
|
||||
char recovery_min_apply_delay[MAXLEN];
|
||||
} t_runtime_options;
|
||||
|
||||
#define T_RUNTIME_OPTIONS_INITIALIZER { "", "", "", "", "", "", "", DEFAULT_WAL_KEEP_SEGMENTS, false, false, false, false, false, false, false, false, false, false, false, "", "", "", "", "fast", "", 0, 0, "", ""}
|
||||
#define T_RUNTIME_OPTIONS_INITIALIZER { "", "", "", "", "", "", "", DEFAULT_WAL_KEEP_SEGMENTS, false, false, false, false, false, false, false, false, false, false, false, false, "", "", "", "", "fast", "", 0, 0, "", ""}
|
||||
|
||||
struct BackupLabel
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user