Initial config file infrastructure

Also unify command line option structure/parsing so everything's
in the same order in the code.
This commit is contained in:
Ian Barwick
2017-04-20 09:41:50 +09:00
parent 8968cfe735
commit 0fb4876256
5 changed files with 189 additions and 17 deletions

View File

@@ -10,6 +10,9 @@
#include "config.h"
const static char *_progname = NULL;
static void _parse_config(t_configuration_options *options, ItemList *error_list);
static void exit_with_errors(ItemList *config_errors);
void
set_progname(const char *argv0)
@@ -23,6 +26,47 @@ progname(void)
return _progname;
}
bool
load_config(const char *config_file, bool verbose, t_configuration_options *options, char *argv0)
{
return true;
}
bool
parse_config(t_configuration_options *options)
{
/* Collate configuration file errors here for friendlier reporting */
static ItemList config_errors = { NULL, NULL };
_parse_config(options, &config_errors);
if (config_errors.head != NULL)
{
exit_with_errors(&config_errors);
}
return true;
}
static void
_parse_config(t_configuration_options *options, ItemList *error_list)
{
}
bool
reload_config(t_configuration_options *orig_options)
{
return true;
}
static void
exit_with_errors(ItemList *config_errors)
{
}
void
item_list_append(ItemList *item_list, char *error_message)
{

View File

@@ -18,6 +18,17 @@ typedef struct
} t_configuration_options;
/*
* The following will initialize the structure with a minimal set of options;
* actual defaults are set in parse_config() before parsing the configuration file
*/
#define T_CONFIGURATION_OPTIONS_INITIALIZER { \
/* node settings */ \
UNKNOWN_NODE_ID, "", \
/* log settings */ \
"", "", ""}
typedef struct ItemListCell
{
struct ItemListCell *next;
@@ -34,8 +45,10 @@ typedef struct ItemList
void set_progname(const char *argv0);
const char *progname(void);
bool load_config(const char *config_file, bool verbose, t_configuration_options *options, char *argv0);
bool parse_config(t_configuration_options *options);
bool reload_config(t_configuration_options *orig_options);
void item_list_append(ItemList *item_list, char *error_message);
#endif

View File

@@ -6,6 +6,10 @@
* This module is a command-line utility to easily setup a cluster of
* hot standby servers for an HA environment
*
* Commands implemented are:
*
* [ MASTER | PRIMARY ] REGISTER
*
*/
#include "repmgr.h"
@@ -13,6 +17,7 @@
/* global configuration structures */
t_runtime_options runtime_options = T_RUNTIME_OPTIONS_INITIALIZER;
t_configuration_options config_file_options = T_CONFIGURATION_OPTIONS_INITIALIZER;
/* Collate command line errors and warnings here for friendlier reporting */
ItemList cli_errors = { NULL, NULL };
@@ -22,7 +27,7 @@ int
main(int argc, char **argv)
{
int optindex;
int c, targ;
int c;
char *repmgr_node_type = NULL;
char *repmgr_action = NULL;
@@ -30,17 +35,20 @@ main(int argc, char **argv)
int action = NO_ACTION;
char *dummy_action = "";
bool config_file_parsed = false;
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
* will be formatted correctly. Can be overriden with "--log-to-file".
*/
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,
while ((c = getopt_long(argc, argv, "?Vf:vtFb:", long_options,
&optindex)) != -1)
{
/*
@@ -55,7 +63,7 @@ main(int argc, char **argv)
* Options which cause repmgr to exit in this block;
* these are the only ones which can be executed as root user
*/
case OPT_HELP:
case OPT_HELP: /* --help */
do_help();
exit(SUCCESS);
case '?':
@@ -69,10 +77,60 @@ main(int argc, char **argv)
case 'V':
printf("%s %s\n", progname(), REPMGR_VERSION);
exit(SUCCESS);
/* general options */
/* general configuration options
* ----------------------------- */
/* -f/--config-file */
case 'f':
strncpy(runtime_options.config_file, optarg, MAXLEN);
break;
/* -F/--force */
case 'F':
runtime_options.force = true;
break;
/* -b/--pg_bindir */
case 'b':
strncpy(runtime_options.pg_bindir, optarg, MAXLEN);
break;
/* logging options
* --------------- */
/* -L/--log-level */
case 'L':
{
int detected_log_level = detect_log_level(optarg);
if (detected_log_level != -1)
{
strncpy(runtime_options.loglevel, optarg, MAXLEN);
}
else
{
PQExpBufferData invalid_log_level;
initPQExpBuffer(&invalid_log_level);
appendPQExpBuffer(&invalid_log_level, _("Invalid log level \"%s\" provided"), optarg);
item_list_append(&cli_errors, invalid_log_level.data);
termPQExpBuffer(&invalid_log_level);
}
break;
}
/* --log-to-file */
case OPT_LOG_TO_FILE:
runtime_options.log_to_file = true;
logger_output_mode = OM_DAEMON;
break;
/* --terse */
case 't':
runtime_options.terse = true;
break;
/* --verbose */
case 'v':
runtime_options.verbose = true;
break;
}
}
@@ -179,6 +237,33 @@ main(int argc, char **argv)
exit_with_errors();
}
/*
* The configuration file is not required for some actions (e.g. 'standby clone'),
* however if available we'll parse it anyway for options like 'log_level',
* 'use_replication_slots' etc.
*/
config_file_parsed = load_config(runtime_options.config_file,
runtime_options.verbose,
&config_file_options,
argv[0]);
/*
* Initialize the logger. We've previously requested STDERR logging only
* to ensure the repmgr command doesn't have its output diverted to a logging
* facility (which usually doesn't make sense for a command line program).
*
* If required (e.g. when calling repmgr from repmgrd), this behaviour can be
* overridden with "--log-to-file".
*/
logger_init(&config_file_options, progname());
if (runtime_options.verbose)
logger_set_verbose();
if (runtime_options.terse)
logger_set_terse();
return SUCCESS;
}
@@ -206,7 +291,17 @@ do_help(void)
printf(_(" -V, --version output version information, then exit\n"));
puts("");
printf(_("General configuration options:\n"));
printf(_(" -b, --pg_bindir=PATH path to PostgreSQL binaries (optional)\n"));
printf(_(" -f, --config-file=PATH path to the configuration file\n"));
printf(_(" -F, --force force potentially dangerous operations to happen\n"));
puts("");
printf(_("Logging options:\n"));
printf(_(" -L, --log-level set log level (overrides configuration file; default: NOTICE)\n"));
printf(_(" --log-to-file log to file (or logging facility) defined in repmgr.conf\n"));
printf(_(" -t, --terse don't display hints and other non-critical output\n"));
printf(_(" -v, --verbose display additional log output (useful for debugging)\n"));
printf(_("\n"));
puts("");
}

View File

@@ -61,26 +61,32 @@
static struct option long_options[] =
{
/* general options */
{"version", no_argument, NULL, 'V'},
{"help", no_argument, NULL, OPT_HELP},
/* general configuration options */
{"config-file", required_argument, NULL, 'f'},
{"force", no_argument, NULL, 'F'},
{"pg_bindir", required_argument, NULL, 'b'},
/* logging options */
{"log-level", required_argument, NULL, 'L'},
{"log-to-file", no_argument, NULL, OPT_LOG_TO_FILE},
{"terse", required_argument, NULL, 't'},
{"verbose", no_argument, NULL, 'v'},
{"dbname", required_argument, NULL, 'd'},
{"host", required_argument, NULL, 'h'},
{"port", required_argument, NULL, 'p'},
{"username", required_argument, NULL, 'U'},
{"superuser", required_argument, NULL, 'S'},
{"pgdata", required_argument, NULL, 'D'},
{"config-file", required_argument, NULL, 'f'},
{"remote-user", required_argument, NULL, 'R'},
{"wal-keep-segments", required_argument, NULL, 'w'},
{"keep-history", required_argument, NULL, 'k'},
{"force", no_argument, NULL, 'F'},
{"wait", no_argument, NULL, 'W'},
{"verbose", no_argument, NULL, 'v'},
{"pg_bindir", required_argument, NULL, 'b'},
{"rsync-only", no_argument, NULL, 'r'},
{"fast-checkpoint", no_argument, NULL, 'c'},
{"log-level", required_argument, NULL, 'L'},
{"terse", required_argument, NULL, 't'},
{"mode", required_argument, NULL, 'm'},
{"remote-config-file", required_argument, NULL, 'C'},
{"check-upstream-config", no_argument, NULL, OPT_CHECK_UPSTREAM_CONFIG},
@@ -93,7 +99,6 @@ static struct option long_options[] =
{"no-upstream-connection", no_argument, NULL, OPT_NO_UPSTREAM_CONNECTION},
{"copy-external-config-files", optional_argument, NULL, OPT_COPY_EXTERNAL_CONFIG_FILES},
{"wait-sync", optional_argument, NULL, OPT_REGISTER_WAIT},
{"log-to-file", no_argument, NULL, OPT_LOG_TO_FILE},
{"upstream-conninfo", required_argument, NULL, OPT_UPSTREAM_CONNINFO},
{"replication-user", required_argument, NULL, OPT_REPLICATION_USER},
{"no-conninfo-password", no_argument, NULL, OPT_NO_CONNINFO_PASSWORD},
@@ -106,13 +111,24 @@ static struct option long_options[] =
typedef struct
{
/* general repmgr options */
/* general configuration options */
char config_file[MAXPGPATH];
bool force;
char pg_bindir[MAXLEN]; /* overrides setting in repmgr.conf */
/* logging options */
char loglevel[MAXLEN]; /* overrides setting in repmgr.conf */
bool log_to_file;
bool terse;
bool verbose;
} t_runtime_options;
#define T_RUNTIME_OPTIONS_INITIALIZER { \
/* general repmgr options */ \
""}
/* general configuration options */ \
"", false, "", \
/* logging options */ \
"", false, false, false}
static void do_help(void);

View File

@@ -20,4 +20,8 @@
#define MIN_SUPPORTED_VERSION "9.3"
#define MIN_SUPPORTED_VERSION_NUM 90300
#define NODE_NOT_FOUND -1
#define NO_UPSTREAM_NODE -1
#define UNKNOWN_NODE_ID -1
#endif