Add logging and repmgr command sanity checks

This commit is contained in:
Ian Barwick
2017-04-20 00:32:04 +09:00
parent 76e8c4624e
commit 8968cfe735
10 changed files with 745 additions and 11 deletions

View File

@@ -14,15 +14,32 @@
/* global configuration structures */
t_runtime_options runtime_options = T_RUNTIME_OPTIONS_INITIALIZER;
/* Collate command line errors and warnings here for friendlier reporting */
ItemList cli_errors = { NULL, NULL };
ItemList cli_warnings = { NULL, NULL };
int
main(int argc, char **argv)
{
int optindex;
int c, targ;
char *repmgr_node_type = NULL;
char *repmgr_action = NULL;
bool valid_repmgr_node_type_found = true;
int action = NO_ACTION;
char *dummy_action = "";
set_progname(argv[0]);
/*
* Tell the logger we're a command-line program - this will
* ensure any output logged before the logger is initialized
* will be formatted correctly
*/
logger_output_mode = OM_COMMAND_LINE;
while ((c = getopt_long(argc, argv, "?Vd:h:p:U:S:D:f:R:w:k:FWIvb:rcL:tm:C:", long_options,
&optindex)) != -1)
{
@@ -75,6 +92,93 @@ main(int argc, char **argv)
progname());
exit(1);
}
/* Exit here already if errors in command line options found */
if (cli_errors.head != NULL)
{
exit_with_errors();
}
/*
* Determine the node type and action; following are valid:
*
* { MASTER | PRIMARY } REGISTER |
* STANDBY {REGISTER | UNREGISTER | CLONE [node] | PROMOTE | FOLLOW [node] | SWITCHOVER | REWIND} |
* WITNESS { CREATE | REGISTER | UNREGISTER } |
* BDR { REGISTER | UNREGISTER } |
* CLUSTER { CROSSCHECK | MATRIX | SHOW | CLEANUP }
*
* [node] is an optional hostname, provided instead of the -h/--host optipn
*/
if (optind < argc)
{
repmgr_node_type = argv[optind++];
}
if (optind < argc)
{
repmgr_action = argv[optind++];
}
else
{
repmgr_action = dummy_action;
}
if (repmgr_node_type != NULL)
{
if (strcasecmp(repmgr_node_type, "MASTER") == 0 || strcasecmp(repmgr_node_type, "PRIMARY") == 0 )
{
if (strcasecmp(repmgr_action, "REGISTER") == 0)
action = MASTER_REGISTER;
}
else
{
valid_repmgr_node_type_found = false;
}
}
if (action == NO_ACTION)
{
PQExpBufferData command_error;
initPQExpBuffer(&command_error);
if (repmgr_node_type == NULL)
{
appendPQExpBuffer(&command_error,
_("no repmgr command provided"));
}
else if (valid_repmgr_node_type_found == false && repmgr_action[0] == '\0')
{
appendPQExpBuffer(&command_error,
_("unknown repmgr node type '%s'"),
repmgr_node_type);
}
else if (repmgr_action[0] == '\0')
{
appendPQExpBuffer(&command_error,
_("no action provided for node type '%s'"),
repmgr_node_type);
}
else
{
appendPQExpBuffer(&command_error,
_("unknown repmgr action '%s %s'"),
repmgr_node_type,
repmgr_action);
}
item_list_append(&cli_errors, command_error.data);
}
/*
* Sanity checks for command line parameters completed by now;
* any further errors will be runtime ones
*/
if (cli_errors.head != NULL)
{
exit_with_errors();
}
return SUCCESS;
}
@@ -83,7 +187,7 @@ static void
do_help(void)
{
printf(_("%s: replication management tool for PostgreSQL\n"), progname());
printf(_("\n"));
puts("");
/* add a big friendly warning if root is executing "repmgr --help" */
if (geteuid() == 0)
@@ -93,6 +197,49 @@ do_help(void)
printf(_(" **************************************************\n"));
puts("");
}
printf(_("Usage:\n"));
printf(_("Usage:\n"));
printf(_(" %s [OPTIONS] master register\n"), progname());
puts("");
printf(_("General options:\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_(" -V, --version output version information, then exit\n"));
puts("");
printf(_("General configuration options:\n"));
printf(_(" -f, --config-file=PATH path to the configuration file\n"));
puts("");
}
static void
exit_with_errors(void)
{
fprintf(stderr, _("The following command line errors were encountered:\n"));
print_error_list(&cli_errors, LOG_ERR);
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname());
exit(ERR_BAD_CONFIG);
}
static void
print_error_list(ItemList *error_list, int log_level)
{
ItemListCell *cell;
for (cell = error_list->head; cell; cell = cell->next)
{
fprintf(stderr, " ");
switch(log_level)
{
/* Currently we only need errors and warnings */
case LOG_ERROR:
log_error("%s", cell->string);
break;
case LOG_WARNING:
log_warning("%s", cell->string);
break;
}
}
}