Added argument substitution to monitor scripts
This commit is contained in:
parent
466224b316
commit
2d600868f5
@ -81,22 +81,6 @@ This disables the assignment of master and slave roles to the Galera cluster nod
|
||||
```
|
||||
disable_master_role_setting=true
|
||||
```
|
||||
|
||||
### `script`
|
||||
|
||||
This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path. The user which is used to run MaxScale should have execution rights to the file itself and the directory it resides in.
|
||||
|
||||
```
|
||||
script=/home/user/script.sh
|
||||
```
|
||||
|
||||
### `events`
|
||||
|
||||
A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names.
|
||||
|
||||
```
|
||||
events=master_down,slave_down
|
||||
```
|
||||
|
||||
### `use_priority`
|
||||
|
||||
@ -106,6 +90,10 @@ Enable interaction with server priorities. This will allow the monitor to determ
|
||||
use_priority=true
|
||||
```
|
||||
|
||||
### Common Monitor Parameters
|
||||
|
||||
For a list of optional parameters that all monitors support, read the [Monitor Common](Monitor-Common.md) document.
|
||||
|
||||
## Interaction with Server Priorities
|
||||
|
||||
If the `use_priority` option is set and a server is configured with the `priority=<int>` parameter, galeramon will use that as the basis on which the master node is chosen. This requires the `disable_master_role_setting` to be undefined or disabled. The server with the lowest value in `priority` will be chosen as the master node when a replacement Galera node is promoted to a master server inside MaxScale.
|
||||
@ -135,24 +123,3 @@ priority=2
|
||||
In this example `node-1` is always used as the master if available. If `node-1` is not available, then the next node with the highest priority rank is used. In this case it would be `node-3`. If both `node-1` and `node-3` were down, then `node-2` would be used. Nodes without priority are considered as having the lowest priority rank and will be used only if all nodes with priority ranks are not available.
|
||||
|
||||
With priority ranks you can control the order in which MaxScale chooses the master node. This will allow for a controlled failure and replacement of nodes.
|
||||
|
||||
## Script events
|
||||
|
||||
Here is a table of all possible event types and their descriptions.
|
||||
|
||||
Event Name|Description
|
||||
----------|----------
|
||||
master_down|A Master server has gone down
|
||||
master_up|A Master server has come up
|
||||
slave_down|A Slave server has gone down
|
||||
slave_up|A Slave server has come up
|
||||
server_down|A server with no assigned role has gone down
|
||||
server_up|A server with no assigned role has come up
|
||||
synced_down|A synced Galera node has come up
|
||||
synced_up|A synced Galera node has gone down
|
||||
lost_master|A server lost Master status
|
||||
lost_slave|A server lost Slave status
|
||||
lost_synced|A Galera node lost synced status
|
||||
new_master|A new Master was detected
|
||||
new_slave|A new Slave was detected
|
||||
new_synced|A new synced Galera node was detected
|
||||
|
@ -67,41 +67,7 @@ This is a situation which can happen if all slave servers are unreachable or the
|
||||
```
|
||||
detect_stale_master=true
|
||||
```
|
||||
|
||||
### `script`
|
||||
|
||||
This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path. The user which is used to run MaxScale should have execution rights to the file itself and the directory it resides in.
|
||||
### Common Monitor Parameters
|
||||
|
||||
```
|
||||
script=/home/user/script.sh
|
||||
```
|
||||
|
||||
This script will be called with the following command line arguments.
|
||||
|
||||
```
|
||||
<name of the script> --event=<event type> --initiator=<server whose state changed> --nodelist=<list of all servers>
|
||||
```
|
||||
### `events`
|
||||
|
||||
A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names.
|
||||
|
||||
```
|
||||
events=master_down,slave_down
|
||||
```
|
||||
|
||||
## Script events
|
||||
|
||||
Here is a table of all possible event types and their descriptions.
|
||||
|
||||
Event Name|Description
|
||||
----------|----------
|
||||
master_down|A Master server has gone down
|
||||
master_up|A Master server has come up
|
||||
slave_down|A Slave server has gone down
|
||||
slave_up|A Slave server has come up
|
||||
server_down|A server with no assigned role has gone down
|
||||
server_up|A server with no assigned role has come up
|
||||
lost_master|A server lost Master status
|
||||
lost_slave|A server lost Slave status
|
||||
new_master|A new Master was detected
|
||||
new_slave|A new Slave was detected
|
||||
For a list of optional parameters that all monitors support, read the [Monitor Common](Monitor-Common.md) document.
|
||||
|
55
Documentation/Monitors/Monitor-Common.md
Normal file
55
Documentation/Monitors/Monitor-Common.md
Normal file
@ -0,0 +1,55 @@
|
||||
# Common Monitor Parameters
|
||||
|
||||
This document lists optional parameters that all current monitors support.
|
||||
|
||||
## Parameters
|
||||
|
||||
### `script`
|
||||
|
||||
This command will be executed when a server changes its state. The parameter should be an absolute path to a command or the command should be in the executable path. The user which is used to run MaxScale should have execution rights to the file itself and the directory it resides in.
|
||||
|
||||
```
|
||||
script=/home/user/myscript.sh initiator=$INITIATOR event=$EVENT live_nodes=$NODELIST
|
||||
```
|
||||
|
||||
The following substitutions will be made to the parameter value:
|
||||
|
||||
* `$INITIATOR` will be replaced with the IP and port of the server who initiated the event
|
||||
* `$EVENT` will be replaced with the name of the event
|
||||
* `$NODELIST` will be replaced with a list of server IPs and ports that are running
|
||||
|
||||
For example, the previous example will be executed as:
|
||||
|
||||
```
|
||||
/home/user/myscript.sh initiator=192.168.0.10:3306 event=master_down live_nodes=192.168.0.201:3306,192.168.0.121:3306
|
||||
```
|
||||
|
||||
### `events`
|
||||
|
||||
A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names.
|
||||
|
||||
```
|
||||
events=master_down,slave_down
|
||||
```
|
||||
|
||||
## Script events
|
||||
|
||||
Here is a table of all possible event types and their descriptions that the monitors can be called with.
|
||||
|
||||
Event Name|Description
|
||||
----------|----------
|
||||
master_down|A Master server has gone down
|
||||
master_up|A Master server has come up
|
||||
slave_down|A Slave server has gone down
|
||||
slave_up|A Slave server has come up
|
||||
server_down|A server with no assigned role has gone down
|
||||
server_up|A server with no assigned role has come up
|
||||
ndb_down|A MySQL Cluster node has gone down
|
||||
ndb_up|A MySQL Cluster node has come up
|
||||
lost_master|A server lost Master status
|
||||
lost_slave|A server lost Slave status
|
||||
lost_ndb|A MySQL Cluster node lost node membership
|
||||
new_master|A new Master was detected
|
||||
new_slave|A new Slave was detected
|
||||
new_ndb|A new MySQL Cluster node was found
|
||||
|
@ -83,27 +83,6 @@ This is a situation which can happen if all slave servers are unreachable or the
|
||||
```
|
||||
detect_stale_master=true
|
||||
```
|
||||
|
||||
### `script`
|
||||
|
||||
This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path. The user which is used to run MaxScale should have execution rights to the file itself and the directory it resides in.
|
||||
|
||||
```
|
||||
script=/home/user/script.sh
|
||||
```
|
||||
|
||||
This script will be called with the following command line arguments.
|
||||
|
||||
```
|
||||
<name of the script> --event=<event type> --initiator=<server whose state changed> --nodelist=<list of all servers>
|
||||
```
|
||||
### `events`
|
||||
|
||||
A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names.
|
||||
|
||||
```
|
||||
events=master_down,slave_down
|
||||
```
|
||||
|
||||
### `mysql51_replication`
|
||||
|
||||
@ -113,23 +92,9 @@ Enable support for MySQL 5.1 replication monitoring. This is needed if a MySQL s
|
||||
mysql51_replication=true
|
||||
```
|
||||
|
||||
## Script events
|
||||
|
||||
Here is a table of all possible event types and their descriptions.
|
||||
|
||||
Event Name|Description
|
||||
----------|----------
|
||||
master_down|A Master server has gone down
|
||||
master_up|A Master server has come up
|
||||
slave_down|A Slave server has gone down
|
||||
slave_up|A Slave server has come up
|
||||
server_down|A server with no assigned role has gone down
|
||||
server_up|A server with no assigned role has come up
|
||||
lost_master|A server lost Master status
|
||||
lost_slave|A server lost Slave status
|
||||
new_master|A new Master was detected
|
||||
new_slave|A new Slave was detected
|
||||
### Common Monitor Parameters
|
||||
|
||||
For a list of optional parameters that all monitors support, read the [Monitor Common](Monitor-Common.md) document.
|
||||
|
||||
## Example 1 - Monitor script
|
||||
|
||||
|
@ -54,49 +54,6 @@ This parameter controls the timeout for reading from a monitored server. It is i
|
||||
backend_read_timeout=2
|
||||
```
|
||||
|
||||
## MySQL Cluster Monitor optional parameters
|
||||
|
||||
These are optional parameters specific to the MySQL Cluster Monitor.
|
||||
|
||||
### `script`
|
||||
|
||||
This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path. The user which is used to run MaxScale should have execution rights to the file itself and the directory it resides in.
|
||||
|
||||
```
|
||||
script=/home/user/script.sh
|
||||
```
|
||||
|
||||
This script will be called with the following command line arguments.
|
||||
|
||||
```
|
||||
<name of the script> --event=<event type> --initiator=<server whose state changed> --nodelist=<list of all servers>
|
||||
```
|
||||
### `events`
|
||||
|
||||
A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names.
|
||||
|
||||
```
|
||||
events=master_down,slave_down
|
||||
```
|
||||
|
||||
## Script events
|
||||
|
||||
Here is a table of all possible event types and their descriptions that the MySQL Cluster monitor can be called with.
|
||||
|
||||
Event Name|Description
|
||||
----------|----------
|
||||
master_down|A Master server has gone down
|
||||
master_up|A Master server has come up
|
||||
slave_down|A Slave server has gone down
|
||||
slave_up|A Slave server has come up
|
||||
server_down|A server with no assigned role has gone down
|
||||
server_up|A server with no assigned role has come up
|
||||
ndb_down|A MySQL Cluster node has gone down
|
||||
ndb_up|A MySQL Cluster node has come up
|
||||
lost_master|A server lost Master status
|
||||
lost_slave|A server lost Slave status
|
||||
lost_ndb|A MySQL Cluster node lost node membership
|
||||
new_master|A new Master was detected
|
||||
new_slave|A new Slave was detected
|
||||
new_ndb|A new MySQL Cluster node was found
|
||||
### Common Monitor Parameters
|
||||
|
||||
For a list of optional parameters that all monitors support, read the [Monitor Common](Monitor-Common.md) document.
|
||||
|
@ -139,20 +139,20 @@ int externcmd_execute(EXTERNCMD* cmd)
|
||||
{
|
||||
int rval = 0;
|
||||
pid_t pid;
|
||||
|
||||
|
||||
pid = fork();
|
||||
|
||||
if(pid < 0)
|
||||
if (pid < 0)
|
||||
{
|
||||
char errbuf[STRERROR_BUFLEN];
|
||||
skygw_log_write(LOGFILE_ERROR, "Failed to execute command '%s', fork failed: [%d] %s",
|
||||
cmd->argv[0], errno, strerror_r(errno, errbuf, sizeof(errbuf)));
|
||||
rval = -1;
|
||||
}
|
||||
else if(pid == 0)
|
||||
else if (pid == 0)
|
||||
{
|
||||
/** Child process, execute command */
|
||||
execvp(cmd->argv[0],cmd->argv);
|
||||
execvp(cmd->argv[0], cmd->argv);
|
||||
_exit(1);
|
||||
}
|
||||
else
|
||||
@ -161,6 +161,54 @@ int externcmd_execute(EXTERNCMD* cmd)
|
||||
cmd->n_exec++;
|
||||
LOGIF(LD, skygw_log_write(LD, "[monitor_exec_cmd] Forked child process %d : %s.", pid, cmd));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitute all occurrences of @c match with @c replace in the arguments for @c cmd.
|
||||
* @param cmd External command
|
||||
* @param match Match string
|
||||
* @param replace Replacement string
|
||||
* @return true if replacement was successful, false on error
|
||||
*/
|
||||
bool externcmd_substitute_arg(EXTERNCMD* cmd, const char* match, const char* replace)
|
||||
{
|
||||
int err;
|
||||
bool rval = true;
|
||||
size_t errpos;
|
||||
pcre2_code *re = pcre2_compile((PCRE2_SPTR) match, PCRE2_ZERO_TERMINATED, 0, &err, &errpos, NULL);
|
||||
if (re)
|
||||
{
|
||||
for (int i = 0; cmd->argv[i] && rval; i++)
|
||||
{
|
||||
size_t size = strlen(cmd->argv[i]);
|
||||
char* dest = malloc(size);
|
||||
if (dest)
|
||||
{
|
||||
mxs_pcre2_result_t rc = mxs_pcre2_substitute(re, cmd->argv[i], replace, &dest, &size);
|
||||
switch (rc)
|
||||
{
|
||||
case MXS_PCRE2_ERROR:
|
||||
free(dest);
|
||||
rval = false;
|
||||
break;
|
||||
case MXS_PCRE2_MATCH:
|
||||
free(cmd->argv[i]);
|
||||
cmd->argv[i] = dest;
|
||||
break;
|
||||
case MXS_PCRE2_NOMATCH:
|
||||
free(dest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rval = false;
|
||||
LOGIF(LD, skygw_log_write(LD, "[monitor_exec_cmd] Forked child process %d : %s.", pid, cmd));
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ SERVER *server;
|
||||
server->server_chk_top = CHK_NUM_SERVER;
|
||||
server->server_chk_tail = CHK_NUM_SERVER;
|
||||
#endif
|
||||
server->name = strdup(servname);
|
||||
server->name = strndup(servname, MAX_SERVER_NAME_LEN);
|
||||
server->protocol = strdup(protocol);
|
||||
server->port = port;
|
||||
server->status = SERVER_RUNNING;
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <errno.h>
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
#include <maxscale_pcre2.h>
|
||||
|
||||
#define MAXSCALE_EXTCMD_ARG_MAX 256
|
||||
|
||||
typedef struct extern_cmd_t{
|
||||
@ -15,8 +17,10 @@ typedef struct extern_cmd_t{
|
||||
pid_t child; /*< PID of the child process */
|
||||
}EXTERNCMD;
|
||||
|
||||
char* externcmd_extract_command(const char* argstr);
|
||||
EXTERNCMD* externcmd_allocate(char* argstr);
|
||||
void externcmd_free(EXTERNCMD* cmd);
|
||||
int externcmd_execute(EXTERNCMD* cmd);
|
||||
bool externcmd_can_execute(char* argstr);
|
||||
bool externcmd_substitute_arg(EXTERNCMD* cmd, const char* re, const char* replace);
|
||||
bool externcmd_can_execute(const char* argstr);
|
||||
#endif
|
||||
|
@ -49,6 +49,8 @@
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#define MAX_SERVER_NAME_LEN 1024
|
||||
|
||||
/**
|
||||
* The server parameters used for weighting routing decissions
|
||||
*
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include <monitor_common.h>
|
||||
#include <maxscale_pcre2.h>
|
||||
|
||||
monitor_event_t mon_name_to_event(char* tok);
|
||||
|
||||
@ -225,23 +226,32 @@ case NEW_DONOR_EVENT:
|
||||
|
||||
}
|
||||
|
||||
void mon_append_node_names(MONITOR_SERVERS* start,char* str, int len)
|
||||
/**
|
||||
* Create a list of running servers
|
||||
* @param start Monitored servers
|
||||
* @param dest Destination where the string is formed
|
||||
* @param len Length of @c dest
|
||||
*/
|
||||
void mon_append_node_names(MONITOR_SERVERS* start, char* dest, int len)
|
||||
{
|
||||
MONITOR_SERVERS* ptr = start;
|
||||
bool first = true;
|
||||
int slen = strlen(str);
|
||||
char arr[256];
|
||||
while(ptr && slen < len)
|
||||
int slen = strlen(dest);
|
||||
char arr[MAX_SERVER_NAME_LEN + 32]; // Some extra space for port
|
||||
while (ptr && slen < len)
|
||||
{
|
||||
if(!first)
|
||||
{
|
||||
strncat(str,",",len);
|
||||
}
|
||||
first = false;
|
||||
sprintf(arr,"%s:%d",ptr->server->name,ptr->server->port);
|
||||
strncat(str,arr,len);
|
||||
ptr = ptr->next;
|
||||
slen = strlen(str);
|
||||
if(SERVER_IS_RUNNING(ptr->server))
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
strncat(dest, ",", len);
|
||||
}
|
||||
first = false;
|
||||
snprintf(arr, sizeof(arr), "%s:%d", ptr->server->name, ptr->server->port);
|
||||
strncat(dest, arr, len);
|
||||
slen = strlen(dest);
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,23 +312,26 @@ bool mon_print_fail_status(
|
||||
*/
|
||||
void monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script)
|
||||
{
|
||||
char argstr[PATH_MAX + MON_ARG_MAX + 1];
|
||||
EXTERNCMD* cmd;
|
||||
char nodelist[PATH_MAX + MON_ARG_MAX + 1] = {'\0'};
|
||||
char event[strlen(mon_get_event_name(ptr))];
|
||||
char initiator[strlen(ptr->server->name) + 24]; // Extra space for port
|
||||
|
||||
snprintf(argstr, PATH_MAX + MON_ARG_MAX,
|
||||
"%s --event=%s --initiator=%s:%d --nodelist=",
|
||||
script,
|
||||
mon_get_event_name(ptr),
|
||||
ptr->server->name,
|
||||
ptr->server->port);
|
||||
snprintf(initiator, sizeof(initiator), "%s:%d", ptr->server->name, ptr->server->port);
|
||||
snprintf(event, sizeof(event), "%s", mon_get_event_name(ptr));
|
||||
mon_append_node_names(mon->databases, nodelist, PATH_MAX + MON_ARG_MAX);
|
||||
|
||||
mon_append_node_names(mon->databases, argstr, PATH_MAX + MON_ARG_MAX);
|
||||
if ((cmd = externcmd_allocate(argstr)) == NULL)
|
||||
EXTERNCMD* cmd = externcmd_allocate(script);
|
||||
|
||||
if (cmd == NULL)
|
||||
{
|
||||
skygw_log_write(LE, "Failed to initialize script: %s", script);
|
||||
return;
|
||||
}
|
||||
|
||||
externcmd_substitute_arg(cmd, "[$]INITIATOR", initiator);
|
||||
externcmd_substitute_arg(cmd, "[$]EVENT", event);
|
||||
externcmd_substitute_arg(cmd, "[$]NODELIST", nodelist);
|
||||
|
||||
if (externcmd_execute(cmd))
|
||||
{
|
||||
skygw_log_write(LOGFILE_ERROR,
|
||||
|
Loading…
x
Reference in New Issue
Block a user