From a315b1e85d1392626e7592dbe06bb3ff35bb3ee8 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Mon, 6 Dec 2021 17:50:27 +0100 Subject: [PATCH] Add support for more environment variables. (#846) * Add support for more environment variables. The parameters --replication-quorum, --candidate-priority, and --name can now also be passed from the environment variables PG_AUTOCTL_REPLICATION_QUORUM, PG_AUTOCTL_CANDIDATE_PRIORITY, and PG_AUTOCTL_NODE_NAME. This allows easier Dockerfile "control-at-a-distance" integration style, where all the containers are the same with the same command, but the environment is where you can inject container/node/pod specific options. Co-authored-by: Jelte Fennema --- src/bin/pg_autoctl/cli_common.c | 54 +++++++++++++++++++++++++++++++++ src/bin/pg_autoctl/defaults.h | 5 +++ tests/test_auth.py | 13 ++++---- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/bin/pg_autoctl/cli_common.c b/src/bin/pg_autoctl/cli_common.c index be0239972..ead5d1a70 100644 --- a/src/bin/pg_autoctl/cli_common.c +++ b/src/bin/pg_autoctl/cli_common.c @@ -112,6 +112,60 @@ cli_common_keeper_getopts(int argc, char **argv, /* default to a "primary" in citus node_role terms */ LocalOptionConfig.citusRole = CITUS_ROLE_PRIMARY; + /* add support for environment variable for some of the options */ + if (env_exists(PG_AUTOCTL_NODE_NAME)) + { + if (!get_env_copy(PG_AUTOCTL_NODE_NAME, + LocalOptionConfig.name, + sizeof(LocalOptionConfig.name))) + { + /* errors have already been logged */ + exit(EXIT_CODE_BAD_ARGS); + } + } + + if (env_exists(PG_AUTOCTL_CANDIDATE_PRIORITY)) + { + char prio[BUFSIZE] = { 0 }; + + if (!get_env_copy(PG_AUTOCTL_CANDIDATE_PRIORITY, prio, sizeof(prio))) + { + /* errors have already been logged */ + exit(EXIT_CODE_BAD_ARGS); + } + + int candidatePriority = strtol(prio, NULL, 10); + if (errno == EINVAL || candidatePriority < 0 || candidatePriority > 100) + { + log_fatal("PG_AUTOCTL_CANDIDATE_PRIORITY environment variable is not valid." + " Valid values are integers from 0 to 100. "); + exit(EXIT_CODE_BAD_ARGS); + } + + LocalOptionConfig.pgSetup.settings.candidatePriority = candidatePriority; + } + + if (env_exists(PG_AUTOCTL_REPLICATION_QUORUM)) + { + char quorum[BUFSIZE] = { 0 }; + + if (!get_env_copy(PG_AUTOCTL_REPLICATION_QUORUM, quorum, sizeof(quorum))) + { + /* errors have already been logged */ + exit(EXIT_CODE_BAD_ARGS); + } + + bool replicationQuorum = false; + if (!parse_bool(quorum, &replicationQuorum)) + { + log_fatal("PG_AUTOCTL_REPLICATION_QUORUM environment variable is not valid." + " Valid values are \"true\" or \"false\"."); + exit(EXIT_CODE_BAD_ARGS); + } + + LocalOptionConfig.pgSetup.settings.replicationQuorum = replicationQuorum; + } + optind = 0; while ((c = getopt_long(argc, argv, diff --git a/src/bin/pg_autoctl/defaults.h b/src/bin/pg_autoctl/defaults.h index 41b6298cc..edea9ea01 100644 --- a/src/bin/pg_autoctl/defaults.h +++ b/src/bin/pg_autoctl/defaults.h @@ -29,6 +29,11 @@ /* environment variable for --monitor, when used instead of --pgdata */ #define PG_AUTOCTL_MONITOR "PG_AUTOCTL_MONITOR" +/* environment variable for --candidate-priority and --replication-quorum */ +#define PG_AUTOCTL_NODE_NAME "PG_AUTOCTL_NODE_NAME" +#define PG_AUTOCTL_CANDIDATE_PRIORITY "PG_AUTOCTL_CANDIDATE_PRIORITY" +#define PG_AUTOCTL_REPLICATION_QUORUM "PG_AUTOCTL_REPLICATION_QUORUM" + /* default values for the pg_autoctl settings */ #define POSTGRES_PORT 5432 #define POSTGRES_DEFAULT_LISTEN_ADDRESSES "*" diff --git a/tests/test_auth.py b/tests/test_auth.py index 7cf51e8a7..173d2b8d4 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -68,12 +68,12 @@ def test_003_init_secondary(): node1.get_synchronous_standby_names_local(), "ANY 1 (pgautofailover_standby_2)", ) + + # Prevent regression from bug fixed in PR #839 logs = node2.logs("STDERR") - match = re.search( - "Failed to connect to .*, retrying until the server is ready", logs - ) + match = re.search("Failed to CHECKPOINT before restart", logs) if match: - print("Found connection failure in logs: ", match[0]) + print("Found CHECKPOINT in logs: ", match[0]) assert not match node2.run() @@ -95,8 +95,9 @@ def test_005_logging_of_passwords(): logs = node2.logs() assert monitor_password not in logs assert "password=****" in logs - # We are still logging passwords when the pguri is incomplete and when printing settings, - # so assert that it's not there in other cases: + + # We are still logging passwords when the pguri is incomplete and when + # printing settings, so assert that it's not there in other cases: assert not re.search( "^(?!primary_conninfo|Failed to find).*%s.*$" % replication_password, logs,