mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-26 00:26:30 +00:00
Initial config file structure definition and initialisation
This commit is contained in:
200
config.c
200
config.c
@@ -8,8 +8,13 @@
|
|||||||
|
|
||||||
#include "repmgr.h"
|
#include "repmgr.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
const static char *_progname = NULL;
|
const static char *_progname = NULL;
|
||||||
|
static char config_file_path[MAXPGPATH];
|
||||||
|
static bool config_file_provided = false;
|
||||||
|
bool config_file_found = false;
|
||||||
|
|
||||||
static void _parse_config(t_configuration_options *options, ItemList *error_list);
|
static void _parse_config(t_configuration_options *options, ItemList *error_list);
|
||||||
static void exit_with_errors(ItemList *config_errors);
|
static void exit_with_errors(ItemList *config_errors);
|
||||||
|
|
||||||
@@ -29,7 +34,123 @@ progname(void)
|
|||||||
bool
|
bool
|
||||||
load_config(const char *config_file, bool verbose, t_configuration_options *options, char *argv0)
|
load_config(const char *config_file, bool verbose, t_configuration_options *options, char *argv0)
|
||||||
{
|
{
|
||||||
return true;
|
struct stat stat_config;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a configuration file was provided, check it exists, otherwise
|
||||||
|
* emit an error and terminate. We assume that if a user explicitly
|
||||||
|
* provides a configuration file, they'll want to make sure it's
|
||||||
|
* used and not fall back to any of the defaults.
|
||||||
|
*/
|
||||||
|
if (config_file[0])
|
||||||
|
{
|
||||||
|
strncpy(config_file_path, config_file, MAXPGPATH);
|
||||||
|
canonicalize_path(config_file_path);
|
||||||
|
|
||||||
|
if (stat(config_file_path, &stat_config) != 0)
|
||||||
|
{
|
||||||
|
log_error(_("provided configuration file \"%s\" not found: %s"),
|
||||||
|
config_file,
|
||||||
|
strerror(errno)
|
||||||
|
);
|
||||||
|
exit(ERR_BAD_CONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose == true)
|
||||||
|
{
|
||||||
|
log_notice(_("using configuration file \"%s\""), config_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
config_file_provided = true;
|
||||||
|
config_file_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If no configuration file was provided, attempt to find a default file
|
||||||
|
* in this order:
|
||||||
|
* - current directory
|
||||||
|
* - /etc/repmgr.conf
|
||||||
|
* - default sysconfdir
|
||||||
|
*
|
||||||
|
* here we just check for the existence of the file; parse_config()
|
||||||
|
* will handle read errors etc.
|
||||||
|
*
|
||||||
|
* XXX modify this section so package maintainers can provide a patch
|
||||||
|
* specifying location of a distribution-specific configuration file
|
||||||
|
*/
|
||||||
|
if (config_file_provided == false)
|
||||||
|
{
|
||||||
|
char my_exec_path[MAXPGPATH];
|
||||||
|
char sysconf_etc_path[MAXPGPATH];
|
||||||
|
|
||||||
|
/* 1. "./repmgr.conf" */
|
||||||
|
if (verbose == true)
|
||||||
|
{
|
||||||
|
log_notice(_("looking for configuration file in current directory"));
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(config_file_path, MAXPGPATH, "./%s", CONFIG_FILE_NAME);
|
||||||
|
canonicalize_path(config_file_path);
|
||||||
|
|
||||||
|
if (stat(config_file_path, &stat_config) == 0)
|
||||||
|
{
|
||||||
|
config_file_found = true;
|
||||||
|
goto end_search;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2. "/etc/repmgr.conf" */
|
||||||
|
if (verbose == true)
|
||||||
|
{
|
||||||
|
log_notice(_("looking for configuration file in /etc"));
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(config_file_path, MAXPGPATH, "/etc/%s", CONFIG_FILE_NAME);
|
||||||
|
if (stat(config_file_path, &stat_config) == 0)
|
||||||
|
{
|
||||||
|
config_file_found = true;
|
||||||
|
goto end_search;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. default sysconfdir */
|
||||||
|
if (find_my_exec(argv0, my_exec_path) < 0)
|
||||||
|
{
|
||||||
|
log_error(_("%s: could not find own program executable"), argv0);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_etc_path(my_exec_path, sysconf_etc_path);
|
||||||
|
|
||||||
|
if (verbose == true)
|
||||||
|
{
|
||||||
|
log_notice(_("looking for configuration file in %s"), sysconf_etc_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(config_file_path, MAXPGPATH, "%s/%s", sysconf_etc_path, CONFIG_FILE_NAME);
|
||||||
|
if (stat(config_file_path, &stat_config) == 0)
|
||||||
|
{
|
||||||
|
config_file_found = true;
|
||||||
|
goto end_search;
|
||||||
|
}
|
||||||
|
|
||||||
|
end_search:
|
||||||
|
if (config_file_found == true)
|
||||||
|
{
|
||||||
|
if (verbose == true)
|
||||||
|
{
|
||||||
|
log_notice(_("configuration file found at: %s"), config_file_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (verbose == true)
|
||||||
|
{
|
||||||
|
log_notice(_("no configuration file provided or found"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parse_config(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -51,7 +172,84 @@ parse_config(t_configuration_options *options)
|
|||||||
static void
|
static void
|
||||||
_parse_config(t_configuration_options *options, ItemList *error_list)
|
_parse_config(t_configuration_options *options, ItemList *error_list)
|
||||||
{
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *s,
|
||||||
|
buf[MAXLINELENGTH];
|
||||||
|
char name[MAXLEN];
|
||||||
|
char value[MAXLEN];
|
||||||
|
|
||||||
|
/* For sanity-checking provided conninfo string */
|
||||||
|
PQconninfoOption *conninfo_options;
|
||||||
|
char *conninfo_errmsg = NULL;
|
||||||
|
|
||||||
|
bool node_id_found = false;
|
||||||
|
|
||||||
|
/* Initialize configuration options with sensible defaults */
|
||||||
|
|
||||||
|
/* node information */
|
||||||
|
options->node_id = UNKNOWN_NODE_ID;
|
||||||
|
options->upstream_node_id = NO_UPSTREAM_NODE;
|
||||||
|
memset(options->node_name, 0, sizeof(options->node_name));
|
||||||
|
memset(options->conninfo, 0, sizeof(options->conninfo));
|
||||||
|
memset(options->pg_bindir, 0, sizeof(options->pg_bindir));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* log settings
|
||||||
|
*
|
||||||
|
* note: the default for "loglevel" is set in log.c and does not need
|
||||||
|
* to be initialised here
|
||||||
|
*/
|
||||||
|
memset(options->logfacility, 0, sizeof(options->logfacility));
|
||||||
|
memset(options->logfile, 0, sizeof(options->logfile));
|
||||||
|
|
||||||
|
/* standby clone settings
|
||||||
|
* ----------------------- */
|
||||||
|
options->use_replication_slots = false;
|
||||||
|
memset(options->rsync_options, 0, sizeof(options->rsync_options));
|
||||||
|
memset(options->ssh_options, 0, sizeof(options->ssh_options));
|
||||||
|
memset(options->pg_basebackup_options, 0, sizeof(options->pg_basebackup_options));
|
||||||
|
memset(options->restore_command, 0, sizeof(options->restore_command));
|
||||||
|
options->tablespace_mapping.head = NULL;
|
||||||
|
options->tablespace_mapping.tail = NULL;
|
||||||
|
|
||||||
|
/* repmgrd settings
|
||||||
|
* ---------------- */
|
||||||
|
options->failover_mode = MANUAL_FAILOVER;
|
||||||
|
options->priority = DEFAULT_PRIORITY;
|
||||||
|
memset(options->promote_command, 0, sizeof(options->promote_command));
|
||||||
|
memset(options->follow_command, 0, sizeof(options->follow_command));
|
||||||
|
options->monitor_interval_secs = 2;
|
||||||
|
options->master_response_timeout = 60;
|
||||||
|
/* default to 6 reconnection attempts at intervals of 10 seconds */
|
||||||
|
options->reconnect_attempts = 6;
|
||||||
|
options->reconnect_interval = 10;
|
||||||
|
options->retry_promote_interval_secs = 300;
|
||||||
|
options->monitoring_history = false; /* new in 4.0, replaces --monitoring-history */
|
||||||
|
|
||||||
|
/* witness settings
|
||||||
|
* ---------------- */
|
||||||
|
|
||||||
|
/* default to resyncing repl_nodes table every 30 seconds on the witness server */
|
||||||
|
options->witness_repl_nodes_sync_interval_secs = 30;
|
||||||
|
|
||||||
|
/* service settings
|
||||||
|
* ---------------- */
|
||||||
|
memset(options->pg_ctl_options, 0, sizeof(options->pg_ctl_options));
|
||||||
|
memset(options->service_stop_command, 0, sizeof(options->service_stop_command));
|
||||||
|
memset(options->service_start_command, 0, sizeof(options->service_start_command));
|
||||||
|
memset(options->service_restart_command, 0, sizeof(options->service_restart_command));
|
||||||
|
memset(options->service_reload_command, 0, sizeof(options->service_reload_command));
|
||||||
|
memset(options->service_promote_command, 0, sizeof(options->service_promote_command));
|
||||||
|
|
||||||
|
/* event notification settings
|
||||||
|
* --------------------------- */
|
||||||
|
memset(options->event_notification_command, 0, sizeof(options->event_notification_command));
|
||||||
|
options->event_notifications.head = NULL;
|
||||||
|
options->event_notifications.tail = NULL;
|
||||||
|
|
||||||
|
/* barman settings */
|
||||||
|
memset(options->barman_server, 0, sizeof(options->barman_server));
|
||||||
|
memset(options->barman_config, 0, sizeof(options->barman_config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
124
config.h
124
config.h
@@ -8,26 +8,23 @@
|
|||||||
#ifndef _REPMGR_CONFIG_H_
|
#ifndef _REPMGR_CONFIG_H_
|
||||||
#define _REPMGR_CONFIG_H_
|
#define _REPMGR_CONFIG_H_
|
||||||
|
|
||||||
typedef struct
|
#define CONFIG_FILE_NAME "repmgr.conf"
|
||||||
|
#define MAXLINELENGTH 4096
|
||||||
|
extern bool config_file_found;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct EventNotificationListCell
|
||||||
{
|
{
|
||||||
int node_id;
|
struct EventNotificationListCell *next;
|
||||||
char node_name[MAXLEN];
|
char event_type[MAXLEN];
|
||||||
char loglevel[MAXLEN];
|
} EventNotificationListCell;
|
||||||
char logfacility[MAXLEN];
|
|
||||||
char logfile[MAXLEN];
|
|
||||||
|
|
||||||
} t_configuration_options;
|
typedef struct EventNotificationList
|
||||||
|
{
|
||||||
|
EventNotificationListCell *head;
|
||||||
|
EventNotificationListCell *tail;
|
||||||
|
} EventNotificationList;
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
||||||
{
|
{
|
||||||
@@ -42,6 +39,99 @@ typedef struct ItemList
|
|||||||
} ItemList;
|
} ItemList;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct TablespaceListCell
|
||||||
|
{
|
||||||
|
struct TablespaceListCell *next;
|
||||||
|
char old_dir[MAXPGPATH];
|
||||||
|
char new_dir[MAXPGPATH];
|
||||||
|
} TablespaceListCell;
|
||||||
|
|
||||||
|
typedef struct TablespaceList
|
||||||
|
{
|
||||||
|
TablespaceListCell *head;
|
||||||
|
TablespaceListCell *tail;
|
||||||
|
} TablespaceList;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* node information */
|
||||||
|
int node_id;
|
||||||
|
int upstream_node_id;
|
||||||
|
char node_name[MAXLEN];
|
||||||
|
char conninfo[MAXLEN];
|
||||||
|
char pg_bindir[MAXLEN];
|
||||||
|
|
||||||
|
/* log settings */
|
||||||
|
char loglevel[MAXLEN];
|
||||||
|
char logfacility[MAXLEN];
|
||||||
|
char logfile[MAXLEN];
|
||||||
|
|
||||||
|
/* standby clone settings */
|
||||||
|
bool use_replication_slots;
|
||||||
|
char rsync_options[MAXLEN];
|
||||||
|
char ssh_options[MAXLEN];
|
||||||
|
char pg_basebackup_options[MAXLEN];
|
||||||
|
char restore_command[MAXLEN];
|
||||||
|
TablespaceList tablespace_mapping;
|
||||||
|
|
||||||
|
/* repmgrd settings */
|
||||||
|
int failover_mode;
|
||||||
|
int priority;
|
||||||
|
char promote_command[MAXLEN];
|
||||||
|
char follow_command[MAXLEN];
|
||||||
|
int monitor_interval_secs;
|
||||||
|
int master_response_timeout;
|
||||||
|
int reconnect_attempts;
|
||||||
|
int reconnect_interval;
|
||||||
|
int retry_promote_interval_secs;
|
||||||
|
bool monitoring_history;
|
||||||
|
|
||||||
|
/* witness settings */
|
||||||
|
int witness_repl_nodes_sync_interval_secs;
|
||||||
|
|
||||||
|
/* service settings */
|
||||||
|
char pg_ctl_options[MAXLEN];
|
||||||
|
char service_stop_command[MAXLEN];
|
||||||
|
char service_start_command[MAXLEN];
|
||||||
|
char service_restart_command[MAXLEN];
|
||||||
|
char service_reload_command[MAXLEN];
|
||||||
|
char service_promote_command[MAXLEN];
|
||||||
|
|
||||||
|
/* event notification settings */
|
||||||
|
char event_notification_command[MAXLEN];
|
||||||
|
EventNotificationList event_notifications;
|
||||||
|
|
||||||
|
/* barman settings */
|
||||||
|
char barman_server[MAXLEN];
|
||||||
|
char barman_config[MAXLEN];
|
||||||
|
} 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 information */ \
|
||||||
|
UNKNOWN_NODE_ID, NO_UPSTREAM_NODE, "", "", "", \
|
||||||
|
/* log settings */ \
|
||||||
|
"", "", "", \
|
||||||
|
/* standby clone settings */ \
|
||||||
|
false, "", "", "", { NULL, NULL }, \
|
||||||
|
/* repmgrd settings */ \
|
||||||
|
MANUAL_FAILOVER, DEFAULT_PRIORITY, "", "", 2, 60, 6, 10, 300, false \
|
||||||
|
/* witness settings */ \
|
||||||
|
30, \
|
||||||
|
/* service settings */ \
|
||||||
|
"", "", "", "", "", "", \
|
||||||
|
/* event notification settings */ \
|
||||||
|
"", { NULL, NULL }, \
|
||||||
|
/* barman settings */ \
|
||||||
|
"", "" }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void set_progname(const char *argv0);
|
void set_progname(const char *argv0);
|
||||||
const char *progname(void);
|
const char *progname(void);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user