uses "hash-type consistent", and the quality of the distribution will depend
on the quality of the keys.
+healthchec <name>
+ May be used in the following contexts: tcp, http
+
+ Specify the health-check sectino to use to perform check on the server.
+
+ Argument :
+ <name> is the health-check section name.
+
+ Thanks to this option, it is possible to use a pre-server health-check
+ configuration instead of using the proxy configuration. See also "healthcheck
+ section".
+
id <value>
May be used in the following contexts: tcp, http, log
map virt@acme
+12.9. Healthchecks
+------------------
+
+It is possible to globally declare several health-checks that could be used by
+servers across all the configuration, overriding the local proxy configuration.
+
+healthcheck <name>
+ Created a new healthcheck with name <name>. This name must be unique. It
+ should be used on server line to reference a specific health-check section.
+
+type <type>
+ Defines the health-check type. This parameter is mandatory. Following types
+ of health-check are supported:
+
+ * tcp-check
+ * httpchk
+ * ssl-hello-chk
+ * smtpchk
+ * pgsql-check
+ * redis-check
+ * mysql-check
+ * ldap-check
+ * spop-check
+
+ Each type uses the same parameters, if any, than the corresponding proxy's
+ option. For instance, the method, the uri... may be speficied for the
+ "httpchk" type:
+
+ Examples :
+ healthcheck my-http-check
+ type httpchk GET /health HTTP/1.1 %[srv_name]
+
+ See also : "option tcp-check", "option httpchk", "option ssl-hello-chk",
+ "option smtpchk", "option mysql-check", "option pgsql-check",
+ "option redis-check", "option ldap-check and "option spop-check"
+
+http-check comment <string>
+http-check connect [default] [port <expr>] [addr <ip>] [send-proxy]
+ [via-socks4] [ssl] [sni <sni>] [alpn <alpn>] [linger]
+ [proto <name>] [comment <msg>]
+http-check disable-on-404
+http-check expect [min-recv <int>] [comment <msg>]
+ [ok-status <st>] [error-status <st>] [tout-status <st>]
+ [on-success <fmt>] [on-error <fmt>] [status-code <expr>]
+ [!] <match> <pattern>
+http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]
+ [hdr <name> <fmt>]* [{ body <string> | body-lf <fmt> }]
+ [comment <msg>]
+http-check send-state
+http-check set-var(<var-name>[,<cond>...]) <expr>
+http-check set-var-fmt(<var-name>[,<cond>...]) <fmt>
+http-check unset-var(<var-name>)
+ Add a specific http-check rule for a "httpchk" healthcheck. The same syntax
+ than the corresponding proxy's directives is used. See the corresponding proxy
+ documentation for details.
+
+tcp-check comment <string>
+tcp-check connect [default] [port <expr>] [addr <ip>] [send-proxy] [via-socks4]
+ [ssl] [sni <sni>] [alpn <alpn>] [linger]
+ [proto <name>] [comment <msg>]
+tcp-check expect [min-recv <int>] [comment <msg>]
+ [ok-status <st>] [error-status <st>] [tout-status <st>]
+ [on-success <fmt>] [on-error <fmt>] [status-code <expr>]
+ [!] <match> <pattern>
+tcp-check send <data> [comment <msg>]
+tcp-check send-lf <fmt> [comment <msg>]
+tcp-check send-binary <hexstring> [comment <msg>]
+tcp-check send-binary-lf <hexfmt> [comment <msg>]
+tcp-check set-var(<var-name>[,<cond>...]) <expr>
+tcp-check set-var-fmt(<var-name>[,<cond>...]) <fmt>
+tcp-check unset-var(<var-name>)
+ Add a specific tcp-check rule for a "tcp-check" healthcheck. The same syntax
+ than the corresponding proxy's directives is used. See the corresponding proxy
+ documentation for details.
+
/*
* Local variables:
* fill-column: 79
struct tcpcheck {
struct tcpcheck_ruleset *rs; /* The tcp-check ruleset to use */
+ char *healthcheck; /* name of the healthcheck section (NULL if not used) */
struct list preset_vars; /* The list of variable to preset before executing the ruleset */
unsigned int flags; /* TCPCHECK_FL_* */
};
* done for health-check : the proxy is the owner of the rules / vars
* in this case.
*/
- if (check->state & CHK_ST_AGENT) {
+ if (check->state & CHK_ST_AGENT || check->tcpcheck->healthcheck) {
free_tcpcheck_vars(&check->tcpcheck->preset_vars);
+ ha_free(&check->tcpcheck->healthcheck);
ha_free(&check->tcpcheck);
}
srv_minmax_conn_apply(newsrv);
+ *err_code |= check_server_tcpcheck(newsrv);
+ if (*err_code & (ERR_ABORT|ERR_FATAL))
+ goto out;
+
/* this will also properly set the transport layer for
* prod and checks
* if default-server have use_ssl, prerare ssl init
return ret;
}
+int check_server_tcpcheck(struct server *srv)
+{
+ struct tcpcheck_ruleset *rs;
+ int err_code = 0;
+
+ if (srv->check.tcpcheck->healthcheck) {
+ rs = find_tcpcheck_ruleset(srv->check.tcpcheck->healthcheck);
+ if (!rs) {
+ ha_alert("parsing [%s:%d]: healthcheck section '%s' not found for server '%s'.\n",
+ srv->conf.file, srv->conf.line, srv->check.tcpcheck->healthcheck, srv->id);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ if (!dup_tcpcheck_vars(&srv->check.tcpcheck->preset_vars, &rs->conf.preset_vars)) {
+ ha_alert("parsing [%s:%d]: unable to duplicate preset variables for server '%s'.\n",
+ srv->conf.file, srv->conf.line, srv->id);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ srv->check.tcpcheck->rs = rs;
+ srv->check.tcpcheck->flags = rs->conf.flags;
+
+ err_code = check_tcpcheck_ruleset(srv->proxy, rs);
+ }
+
+ out:
+ return err_code;
+}
+
void deinit_proxy_tcpcheck(struct proxy *px)
{
free_tcpcheck_vars(&px->tcpcheck.preset_vars);
return err_code;
}
+/* Parse the "healthcheck" server keyword */
+static int srv_parse_healthcheck(char **args, int *cur_arg, struct proxy *curpx, struct server *srv,
+ char **errmsg)
+{
+ int err_code = 0;
+
+ if (!*args[*cur_arg+1]) {
+ memprintf(errmsg, "'%s' expects a healthcheck name as argument.", args[*cur_arg]);
+ err_code |= ERR_ALERT | ERR_ABORT;
+ goto out;
+ }
+
+ if (srv->check.tcpcheck->healthcheck) {
+ /* a healthcheck section was already defined. Replace it */
+ ha_free(&srv->check.tcpcheck->healthcheck);
+ }
+ else {
+ srv->check.tcpcheck = calloc(1, sizeof(*srv->check.tcpcheck));
+ if (srv->check.tcpcheck == NULL) {
+ memprintf(errmsg, "out of memory");
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ LIST_INIT(&srv->check.tcpcheck->preset_vars);
+ }
+
+ if (!memprintf(&srv->check.tcpcheck->healthcheck, "*healthcheck-%s", args[*cur_arg+1])) {
+ ha_free(&srv->check.tcpcheck);
+ memprintf(errmsg, "out of memory");
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+
+ out:
+ return err_code;
+}
+
static struct cfg_kw_list cfg_kws = {ILH, {
{ CFG_LISTEN, "http-check", proxy_parse_httpcheck },
{ CFG_LISTEN, "tcp-check", proxy_parse_tcpcheck },
INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
REGISTER_CONFIG_SECTION("healthcheck", cfg_parse_healthchecks, cfg_post_parse_healthchecks);
+
+/* register "server" line keywords */
+static struct srv_kw_list srv_kws = { "CHK", { }, {
+ { "healthcheck", srv_parse_healthcheck, 1, 1, 1 }, /* The healthcheck section to use */
+ { NULL, NULL, 0 },
+}};
+
+INITCALL1(STG_REGISTER, srv_register_keywords, &srv_kws);