Skip to content

Commit

Permalink
Implement pg_autoctl enable|disable maintenance CLI. (#35)
Browse files Browse the repository at this point in the history
The feature was already there and the CLI hidden in our DEBUG tooling,
because we were not sure at the time of the initial implementation how to
expose the feature to our users.

Now that we have the enable|disable subcommands already, it looks like it is
a good fit for the maintenance feature.

Fixes #33.
  • Loading branch information
DimCitus committed Jul 2, 2019
1 parent 624f2a7 commit e6c7229
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 171 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ RUN PIPENV_PIPFILE=tests/Pipfile pipenv install --system --deploy

COPY Makefile ./
COPY ./src/ ./src
RUN make clean && make install -j8
RUN make -s clean && make -s install -j8

COPY ./tests/ ./tests

Expand Down
8 changes: 8 additions & 0 deletions docs/operations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ a secondary node::
> select pgautofailover.start_maintenance('nodename', 5432);
> select pgautofailover.stop_maintenance('nodename', 5432);

The command line tool ``pg_autoctl`` also exposes an API to schedule
maintenance operations on the current node, which must be a secondary node
at the moment when maintenance is requested::

$ pg_autoctl enable maintenance
...
$ pg_autoctl disable maintenance

When a standby node is in maintenance, the monitor sets the primary node
replication to WAIT_PRIMARY: in this role, the PostgreSQL streaming
replication is now asynchronous and the standby PostgreSQL server may be
Expand Down
8 changes: 4 additions & 4 deletions docs/ref/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -461,10 +461,12 @@ commands, only available in debug environments::
state Prints monitor's state of nodes in a given formation and group

pg_autoctl enable
secondary Enable secondary nodes on a formation
secondary Enable secondary nodes on a formation
maintenance Enable Postgres maintenance mode on this node

pg_autoctl disable
secondary Disable secondary nodes on a formation
secondary Disable secondary nodes on a formation
maintenance Disable Postgres maintenance mode on this node

pg_autoctl do
+ monitor Query a pg_auto_failover monitor
Expand All @@ -478,8 +480,6 @@ commands, only available in debug environments::
+ get Get information from the monitor
register Register the current node with the monitor
active Call in the pg_auto_failover Node Active protocol
pause Pause pg_auto_failover on this node
resume Resume pg_auto_failover on this node
version Check that monitor version is 1.0; alter extension update if not

pg_autoctl do monitor get
Expand Down
148 changes: 0 additions & 148 deletions src/bin/pg_autoctl/cli_do_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include "cli_common.h"
#include "commandline.h"
#include "defaults.h"
#include "fsm.h"
#include "keeper_config.h"
#include "keeper.h"
#include "monitor.h"
Expand All @@ -41,8 +40,6 @@ static void keeper_cli_monitor_get_other_node(int argc, char **argv);
static void keeper_cli_monitor_get_coordinator(int argc, char **argv);
static void keeper_cli_monitor_register_node(int argc, char **argv);
static void keeper_cli_monitor_node_active(int argc, char **argv);
static void cli_monitor_pause_node(int argc, char **argv);
static void cli_monitor_resume_node(int argc, char **argv);
static void cli_monitor_version(int argc, char **argv);


Expand Down Expand Up @@ -98,22 +95,6 @@ static CommandLine monitor_node_active_command =
keeper_cli_getopt_pgdata,
keeper_cli_monitor_node_active);

static CommandLine monitor_pause_node_command =
make_command("pause",
"Pause pg_auto_failover on this node",
" [ --pgdata ]",
KEEPER_CLI_PGDATA_OPTION,
keeper_cli_getopt_pgdata,
cli_monitor_pause_node);

static CommandLine monitor_resume_node_command =
make_command("resume",
"Resume pg_auto_failover on this node",
" [ --pgdata ]",
KEEPER_CLI_PGDATA_OPTION,
keeper_cli_getopt_pgdata,
cli_monitor_resume_node);

static CommandLine monitor_version_command =
make_command("version",
"Check that monitor version is "
Expand All @@ -128,8 +109,6 @@ static CommandLine *monitor_subcommands[] = {
&monitor_get_command,
&monitor_register_command,
&monitor_node_active_command,
&monitor_pause_node_command,
&monitor_resume_node_command,
&monitor_version_command,
NULL
};
Expand Down Expand Up @@ -448,133 +427,6 @@ keeper_cli_monitor_node_active(int argc, char **argv)
}


/*
* cli_monitor_pause_node calls the pgautofailover.start_maintenance() function
* on the monitor for the local node.
*/
static void
cli_monitor_pause_node(int argc, char **argv)
{
Keeper keeper = { 0 };
bool missing_pgdata_is_ok = true;
bool pg_is_not_running_is_ok = true;
pid_t pid;

keeper.config = keeperOptions;

(void) exit_unless_role_is_keeper(&(keeper.config));

keeper_config_read_file(&(keeper.config),
missing_pgdata_is_ok,
pg_is_not_running_is_ok);

if (!keeper_init(&keeper, &keeper.config))
{
log_fatal("Failed to initialise keeper, see above for details");
exit(EXIT_CODE_KEEPER);
}

if (!monitor_init(&(keeper.monitor), keeper.config.monitor_pguri))
{
log_fatal("Failed to initialize the monitor connection, "
"see above for details.");
exit(EXIT_CODE_MONITOR);
}

if (!monitor_start_maintenance(&(keeper.monitor),
keeper.config.nodename,
keeper.config.pgSetup.pgport))
{
log_fatal("Failed to start maintenance from the monitor, "
"see above for details");
exit(EXIT_CODE_MONITOR);
}

if (!read_pidfile(keeper.config.pathnames.pid, &pid))
{
log_error("Failed to read the keeper's PID file at \"%s\": "
"is the keeper running?", keeper.config.pathnames.pid);
exit(EXIT_CODE_KEEPER);
}

log_warn("Signaling the keeper process %d with SIGHUP so that "
"it calls pgautofailover.node_active() immediately.",
pid);

if (kill(pid, SIGHUP) != 0)
{
log_warn("Failed to send SIGHUP to the keeper's pid %d: %s",
pid, strerror(errno));
}

log_info("Node %s:%d will reach maintenance state soon",
keeper.config.nodename, keeper.config.pgSetup.pgport);
}


/*
* cli_monitor_resume_node calls pgautofailver.stop_maintenance(name, port) on
* the monitor.
*/
static void
cli_monitor_resume_node(int argc, char **argv)
{
Keeper keeper = { 0 };
bool missing_pgdata_is_ok = true;
bool pg_is_not_running_is_ok = true;
pid_t pid;

keeper.config = keeperOptions;

(void) exit_unless_role_is_keeper(&(keeper.config));

keeper_config_read_file(&(keeper.config),
missing_pgdata_is_ok,
pg_is_not_running_is_ok);

if (!keeper_init(&keeper, &keeper.config))
{
log_fatal("Failed to initialise keeper, see above for details");
exit(EXIT_CODE_KEEPER);
}

if (!monitor_init(&(keeper.monitor), keeper.config.monitor_pguri))
{
log_fatal("Failed to initialize the monitor connection, "
"see above for details.");
exit(EXIT_CODE_MONITOR);
}

if (!monitor_stop_maintenance(&(keeper.monitor),
keeper.config.nodename,
keeper.config.pgSetup.pgport))
{
log_fatal("Failed to stop maintenance from the monitor, "
"see above for details");
exit(EXIT_CODE_MONITOR);
}

if (!read_pidfile(keeper.config.pathnames.pid, &pid))
{
log_error("Failed to read the keeper's PID file at \"%s\": "
"is the keeper running?", keeper.config.pathnames.pid);
exit(EXIT_CODE_KEEPER);
}

log_warn("Signaling the keeper process %d with SIGHUP so that "
"it calls pgautofailover.node_active() immediately.", pid);

if (kill(pid, SIGHUP) != 0)
{
log_warn("Failed to send SIGHUP to the keeper's pid %d: %s",
pid, strerror(errno));
}

log_info("Node %s:%d will exit from maintenance state soon",
keeper.config.nodename, keeper.config.pgSetup.pgport);
}


/*
* cli_monitor_version ensures that the version of the monitor is the one that
* is expected by pg_autoctl too. When that's not the case, the command issues
Expand Down

0 comments on commit e6c7229

Please sign in to comment.