mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-26 16:46:28 +00:00
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:
44
config.c
44
config.c
@@ -10,6 +10,9 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
const static char *_progname = NULL;
|
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
|
void
|
||||||
set_progname(const char *argv0)
|
set_progname(const char *argv0)
|
||||||
@@ -23,6 +26,47 @@ progname(void)
|
|||||||
return _progname;
|
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
|
void
|
||||||
item_list_append(ItemList *item_list, char *error_message)
|
item_list_append(ItemList *item_list, char *error_message)
|
||||||
{
|
{
|
||||||
|
|||||||
17
config.h
17
config.h
@@ -18,6 +18,17 @@ typedef struct
|
|||||||
|
|
||||||
} t_configuration_options;
|
} 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
|
typedef struct ItemListCell
|
||||||
{
|
{
|
||||||
struct ItemListCell *next;
|
struct ItemListCell *next;
|
||||||
@@ -34,8 +45,10 @@ typedef struct ItemList
|
|||||||
void set_progname(const char *argv0);
|
void set_progname(const char *argv0);
|
||||||
const char *progname(void);
|
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);
|
void item_list_append(ItemList *item_list, char *error_message);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
105
repmgr-client.c
105
repmgr-client.c
@@ -6,6 +6,10 @@
|
|||||||
* This module is a command-line utility to easily setup a cluster of
|
* This module is a command-line utility to easily setup a cluster of
|
||||||
* hot standby servers for an HA environment
|
* hot standby servers for an HA environment
|
||||||
*
|
*
|
||||||
|
* Commands implemented are:
|
||||||
|
*
|
||||||
|
* [ MASTER | PRIMARY ] REGISTER
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "repmgr.h"
|
#include "repmgr.h"
|
||||||
@@ -13,6 +17,7 @@
|
|||||||
|
|
||||||
/* global configuration structures */
|
/* global configuration structures */
|
||||||
t_runtime_options runtime_options = T_RUNTIME_OPTIONS_INITIALIZER;
|
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 */
|
/* Collate command line errors and warnings here for friendlier reporting */
|
||||||
ItemList cli_errors = { NULL, NULL };
|
ItemList cli_errors = { NULL, NULL };
|
||||||
@@ -22,7 +27,7 @@ int
|
|||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int optindex;
|
int optindex;
|
||||||
int c, targ;
|
int c;
|
||||||
|
|
||||||
char *repmgr_node_type = NULL;
|
char *repmgr_node_type = NULL;
|
||||||
char *repmgr_action = NULL;
|
char *repmgr_action = NULL;
|
||||||
@@ -30,17 +35,20 @@ main(int argc, char **argv)
|
|||||||
int action = NO_ACTION;
|
int action = NO_ACTION;
|
||||||
char *dummy_action = "";
|
char *dummy_action = "";
|
||||||
|
|
||||||
|
bool config_file_parsed = false;
|
||||||
|
|
||||||
|
|
||||||
set_progname(argv[0]);
|
set_progname(argv[0]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tell the logger we're a command-line program - this will
|
* Tell the logger we're a command-line program - this will
|
||||||
* ensure any output logged before the logger is initialized
|
* 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;
|
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)
|
&optindex)) != -1)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -55,7 +63,7 @@ main(int argc, char **argv)
|
|||||||
* Options which cause repmgr to exit in this block;
|
* Options which cause repmgr to exit in this block;
|
||||||
* these are the only ones which can be executed as root user
|
* these are the only ones which can be executed as root user
|
||||||
*/
|
*/
|
||||||
case OPT_HELP:
|
case OPT_HELP: /* --help */
|
||||||
do_help();
|
do_help();
|
||||||
exit(SUCCESS);
|
exit(SUCCESS);
|
||||||
case '?':
|
case '?':
|
||||||
@@ -69,10 +77,60 @@ main(int argc, char **argv)
|
|||||||
case 'V':
|
case 'V':
|
||||||
printf("%s %s\n", progname(), REPMGR_VERSION);
|
printf("%s %s\n", progname(), REPMGR_VERSION);
|
||||||
exit(SUCCESS);
|
exit(SUCCESS);
|
||||||
/* general options */
|
|
||||||
|
/* general configuration options
|
||||||
|
* ----------------------------- */
|
||||||
|
|
||||||
|
/* -f/--config-file */
|
||||||
case 'f':
|
case 'f':
|
||||||
strncpy(runtime_options.config_file, optarg, MAXLEN);
|
strncpy(runtime_options.config_file, optarg, MAXLEN);
|
||||||
break;
|
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();
|
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;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +291,17 @@ do_help(void)
|
|||||||
printf(_(" -V, --version output version information, then exit\n"));
|
printf(_(" -V, --version output version information, then exit\n"));
|
||||||
puts("");
|
puts("");
|
||||||
printf(_("General configuration options:\n"));
|
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, --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("");
|
puts("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,26 +61,32 @@
|
|||||||
|
|
||||||
static struct option long_options[] =
|
static struct option long_options[] =
|
||||||
{
|
{
|
||||||
|
/* general options */
|
||||||
{"version", no_argument, NULL, 'V'},
|
{"version", no_argument, NULL, 'V'},
|
||||||
{"help", no_argument, NULL, OPT_HELP},
|
{"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'},
|
{"dbname", required_argument, NULL, 'd'},
|
||||||
{"host", required_argument, NULL, 'h'},
|
{"host", required_argument, NULL, 'h'},
|
||||||
{"port", required_argument, NULL, 'p'},
|
{"port", required_argument, NULL, 'p'},
|
||||||
{"username", required_argument, NULL, 'U'},
|
{"username", required_argument, NULL, 'U'},
|
||||||
{"superuser", required_argument, NULL, 'S'},
|
{"superuser", required_argument, NULL, 'S'},
|
||||||
{"pgdata", required_argument, NULL, 'D'},
|
{"pgdata", required_argument, NULL, 'D'},
|
||||||
{"config-file", required_argument, NULL, 'f'},
|
|
||||||
{"remote-user", required_argument, NULL, 'R'},
|
{"remote-user", required_argument, NULL, 'R'},
|
||||||
{"wal-keep-segments", required_argument, NULL, 'w'},
|
{"wal-keep-segments", required_argument, NULL, 'w'},
|
||||||
{"keep-history", required_argument, NULL, 'k'},
|
{"keep-history", required_argument, NULL, 'k'},
|
||||||
{"force", no_argument, NULL, 'F'},
|
|
||||||
{"wait", no_argument, NULL, 'W'},
|
{"wait", no_argument, NULL, 'W'},
|
||||||
{"verbose", no_argument, NULL, 'v'},
|
|
||||||
{"pg_bindir", required_argument, NULL, 'b'},
|
|
||||||
{"rsync-only", no_argument, NULL, 'r'},
|
{"rsync-only", no_argument, NULL, 'r'},
|
||||||
{"fast-checkpoint", no_argument, NULL, 'c'},
|
{"fast-checkpoint", no_argument, NULL, 'c'},
|
||||||
{"log-level", required_argument, NULL, 'L'},
|
|
||||||
{"terse", required_argument, NULL, 't'},
|
|
||||||
{"mode", required_argument, NULL, 'm'},
|
{"mode", required_argument, NULL, 'm'},
|
||||||
{"remote-config-file", required_argument, NULL, 'C'},
|
{"remote-config-file", required_argument, NULL, 'C'},
|
||||||
{"check-upstream-config", no_argument, NULL, OPT_CHECK_UPSTREAM_CONFIG},
|
{"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},
|
{"no-upstream-connection", no_argument, NULL, OPT_NO_UPSTREAM_CONNECTION},
|
||||||
{"copy-external-config-files", optional_argument, NULL, OPT_COPY_EXTERNAL_CONFIG_FILES},
|
{"copy-external-config-files", optional_argument, NULL, OPT_COPY_EXTERNAL_CONFIG_FILES},
|
||||||
{"wait-sync", optional_argument, NULL, OPT_REGISTER_WAIT},
|
{"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},
|
{"upstream-conninfo", required_argument, NULL, OPT_UPSTREAM_CONNINFO},
|
||||||
{"replication-user", required_argument, NULL, OPT_REPLICATION_USER},
|
{"replication-user", required_argument, NULL, OPT_REPLICATION_USER},
|
||||||
{"no-conninfo-password", no_argument, NULL, OPT_NO_CONNINFO_PASSWORD},
|
{"no-conninfo-password", no_argument, NULL, OPT_NO_CONNINFO_PASSWORD},
|
||||||
@@ -106,13 +111,24 @@ static struct option long_options[] =
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/* general repmgr options */
|
/* general configuration options */
|
||||||
char config_file[MAXPGPATH];
|
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;
|
} t_runtime_options;
|
||||||
|
|
||||||
#define T_RUNTIME_OPTIONS_INITIALIZER { \
|
#define T_RUNTIME_OPTIONS_INITIALIZER { \
|
||||||
/* general repmgr options */ \
|
/* general configuration options */ \
|
||||||
""}
|
"", false, "", \
|
||||||
|
/* logging options */ \
|
||||||
|
"", false, false, false}
|
||||||
|
|
||||||
static void do_help(void);
|
static void do_help(void);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user