diff --git a/src/bin/pg_autoctl/cli_common.c b/src/bin/pg_autoctl/cli_common.c index 4b835ab28..794c00ae8 100644 --- a/src/bin/pg_autoctl/cli_common.c +++ b/src/bin/pg_autoctl/cli_common.c @@ -407,6 +407,28 @@ cli_common_keeper_getopts(int argc, char **argv, break; } + case 'e': + { + /* { "replication-password", required_argument, NULL, 'e' } */ + strlcpy(LocalOptionConfig.replication_password, optarg, + MAXCONNINFO); + log_trace("--replication-password ****"); + break; + } + + case 'w': + { + /* + * { "monitor-password", required_argument, NULL, 'w' } + * The pgautofailover_monitor health-check role currently uses a + * hardcoded password (PG_AUTOCTL_HEALTH_PASSWORD). Accept the + * option so pg_autoctl node run can pass it without error; it + * is otherwise unused at this time. + */ + log_trace("--monitor-password ****"); + break; + } + case 'V': { /* keeper_cli_print_version prints version and exits. */ diff --git a/src/bin/pg_autoctl/cli_do_misc.c b/src/bin/pg_autoctl/cli_do_misc.c index 188faa88f..377e7f75f 100644 --- a/src/bin/pg_autoctl/cli_do_misc.c +++ b/src/bin/pg_autoctl/cli_do_misc.c @@ -322,15 +322,105 @@ keeper_cli_pgsetup_is_ready(int argc, char **argv) } +/* timeout parsed by keeper_cli_pgsetup_wait_getopts, consumed by wait_until_ready */ +static int pgsetup_wait_timeout = 30; + /* - * keeper_cli_discover_pg_setup implements the CLI to discover a PostgreSQL - * setup thanks to PGDATA and other environment variables. + * keeper_cli_pgsetup_wait_getopts parses --pgdata and --timeout for the + * "pgsetup wait" subcommand. + */ +int +keeper_cli_pgsetup_wait_getopts(int argc, char **argv) +{ + int c, option_index = 0; + + static struct option long_options[] = { + { "pgdata", required_argument, NULL, 'D' }, + { "timeout", required_argument, NULL, 't' }, + { "version", no_argument, NULL, 'V' }, + { "verbose", no_argument, NULL, 'v' }, + { "quiet", no_argument, NULL, 'q' }, + { "help", no_argument, NULL, 'h' }, + { NULL, 0, NULL, 0 } + }; + + optind = 0; + + while ((c = getopt_long(argc, argv, "D:t:Vvqh", + long_options, &option_index)) != -1) + { + switch (c) + { + case 'D': + { + strlcpy(keeperOptions.pgSetup.pgdata, optarg, MAXPGPATH); + log_trace("--pgdata %s", optarg); + break; + } + + case 't': + { + if (!stringToInt(optarg, &pgsetup_wait_timeout) || + pgsetup_wait_timeout <= 0) + { + log_fatal( + "--timeout argument is not a valid positive integer: \"%s\"", + optarg); + exit(EXIT_CODE_BAD_ARGS); + } + log_trace("--timeout %d", pgsetup_wait_timeout); + break; + } + + case 'V': + { + keeper_cli_print_version(argc, argv); + break; + } + + case 'v': + { + log_set_level(LOG_DEBUG); + break; + } + + case 'q': + { + log_set_level(LOG_ERROR); + break; + } + + case 'h': + { + commandline_help(stderr); + exit(EXIT_CODE_QUIT); + break; + } + + default: + { + commandline_help(stderr); + exit(EXIT_CODE_BAD_ARGS); + break; + } + } + } + + /* publish parsed options */ + keeperOptions.pgSetup.pgdata[0] = + keeperOptions.pgSetup.pgdata[0]; /* no-op, already set above */ + + return optind; +} + + +/* + * keeper_cli_pgsetup_wait_until_ready waits until the local Postgres server + * is ready to accept connections, up to --timeout seconds (default 30). */ void keeper_cli_pgsetup_wait_until_ready(int argc, char **argv) { - int timeout = 30; - ConfigFilePaths pathnames = { 0 }; LocalPostgresServer postgres = { 0 }; PostgresSetup *pgSetup = &(postgres.postgresSetup); @@ -343,7 +433,8 @@ keeper_cli_pgsetup_wait_until_ready(int argc, char **argv) log_debug("Initialized pgSetup, now calling pg_setup_wait_until_is_ready()"); - bool pgIsReady = pg_setup_wait_until_is_ready(pgSetup, timeout, LOG_INFO); + bool pgIsReady = + pg_setup_wait_until_is_ready(pgSetup, pgsetup_wait_timeout, LOG_INFO); log_info("Postgres status is: \"%s\"", pmStatusToString(pgSetup->pm_status)); diff --git a/src/bin/pg_autoctl/cli_do_root.c b/src/bin/pg_autoctl/cli_do_root.c index a7f6a86f8..9ee0752c7 100644 --- a/src/bin/pg_autoctl/cli_do_root.c +++ b/src/bin/pg_autoctl/cli_do_root.c @@ -186,9 +186,18 @@ CommandLine do_pgsetup_wait_until_ready = make_command("wait", "Wait until the local Postgres server is ready", "[option ...]", + " --pgdata path to data directory\n" + " --timeout seconds to wait, default 30\n", + keeper_cli_pgsetup_wait_getopts, + keeper_cli_pgsetup_wait_until_ready); + +CommandLine do_pgsetup_hba_lan = + make_command("hba-lan", + "Add LAN CIDR trust rules to pg_hba.conf and reload", + "[option ...]", KEEPER_CLI_WORKER_SETUP_OPTIONS, keeper_cli_keeper_setup_getopts, - keeper_cli_pgsetup_wait_until_ready); + keeper_cli_pgsetup_hba_lan); CommandLine do_pgsetup_startup_logs = make_command("logs", @@ -213,6 +222,7 @@ CommandLine *do_pgsetup[] = { &do_pgsetup_wait_until_ready, &do_pgsetup_startup_logs, &do_pgsetup_tune, + &do_pgsetup_hba_lan, NULL }; diff --git a/src/bin/pg_autoctl/cli_do_root.h b/src/bin/pg_autoctl/cli_do_root.h index bc129ad04..888f68f9f 100644 --- a/src/bin/pg_autoctl/cli_do_root.h +++ b/src/bin/pg_autoctl/cli_do_root.h @@ -98,8 +98,10 @@ void keeper_cli_enable_synchronous_replication(int argc, char **argv); void keeper_cli_disable_synchronous_replication(int argc, char **argv); void keeper_cli_pgsetup_pg_ctl(int argc, char **argv); +void keeper_cli_pgsetup_hba_lan(int argc, char **argv); void keeper_cli_pgsetup_discover(int argc, char **argv); void keeper_cli_pgsetup_is_ready(int argc, char **argv); +int keeper_cli_pgsetup_wait_getopts(int argc, char **argv); void keeper_cli_pgsetup_wait_until_ready(int argc, char **argv); void keeper_cli_pgsetup_startup_logs(int argc, char **argv); void keeper_cli_pgsetup_tune(int argc, char **argv); diff --git a/src/bin/pg_autoctl/cli_drop_node.c b/src/bin/pg_autoctl/cli_drop_node.c index 0dc4f5ab6..a16e52a6f 100644 --- a/src/bin/pg_autoctl/cli_drop_node.c +++ b/src/bin/pg_autoctl/cli_drop_node.c @@ -84,7 +84,8 @@ CommandLine drop_node_command = " --pgport drop the node with given hostname and pgport\n" " --destroy also destroy Postgres database\n" " --force force dropping the node from the monitor\n" - " --wait how many seconds to wait, default to 60 \n", + " --wait how many seconds to wait, default to 60\n" + " --no-wait drop the node without waiting for confirmation\n", cli_drop_node_getopts, cli_drop_node); @@ -104,6 +105,7 @@ cli_drop_node_getopts(int argc, char **argv) { "monitor", required_argument, NULL, 'm' }, { "destroy", no_argument, NULL, 'd' }, { "force", no_argument, NULL, 'F' }, + { "no-wait", no_argument, NULL, 'W' }, { "hostname", required_argument, NULL, 'n' }, { "pgport", required_argument, NULL, 'p' }, { "formation", required_argument, NULL, 'f' }, @@ -160,6 +162,14 @@ cli_drop_node_getopts(int argc, char **argv) break; } + case 'W': + { + /* --no-wait: set timeout to zero so the notification loop is skipped */ + options.listen_notifications_timeout = 0; + log_trace("--no-wait"); + break; + } + case 'n': { strlcpy(options.hostname, optarg, _POSIX_HOST_NAME_MAX);