mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 07:07:04 +02:00
MINOR: haproxy: Add -cc
argument
This patch adds the `-cc` (check condition) argument to evaluate conditions on startup and return the result as the exit code. As an example this can be used to easily check HAProxy's version in scripts: haproxy -cc 'version_atleast(2.4)' This resolves GitHub issue #1246. Co-authored-by: Tim Duesterhus <tim@bastelstu.be>
This commit is contained in:
parent
29c6cd7d8a
commit
fc0cceb08a
@ -802,6 +802,9 @@ Comments may be placed on the same line if needed after a '#', they will be
|
||||
ignored. The directives are tokenized like other configuration directives, and
|
||||
as such it is possible to use environment variables in conditions.
|
||||
|
||||
Conditions can also be evaluated on startup with the -cc parameter.
|
||||
See "3. Starting HAProxy" in the management doc.
|
||||
|
||||
The conditions are currently limited to:
|
||||
|
||||
- an empty string, always returns "false"
|
||||
|
@ -195,6 +195,10 @@ list of options is :
|
||||
to bind. The exit status is zero if everything is OK, or non-zero if an
|
||||
error is encountered. Presence of warnings will be reported if any.
|
||||
|
||||
-cc : evaluates a condition as used within a conditional block of the
|
||||
configuration. The exit status is zero if the condition is true, 1 if the
|
||||
condition is false or 2 if an error is encountered.
|
||||
|
||||
-d : enable debug mode. This disables daemon mode, forces the process to stay
|
||||
in foreground and to show incoming and outgoing events. It must never be
|
||||
used in an init script.
|
||||
|
@ -126,6 +126,7 @@ void free_email_alert(struct proxy *p);
|
||||
const char *cfg_find_best_match(const char *word, const struct list *list, int section, const char **extra);
|
||||
int warnifnotcap(struct proxy *proxy, int cap, const char *file, int line, const char *arg, const char *hint);
|
||||
int failifnotcap(struct proxy *proxy, int cap, const char *file, int line, const char *arg, const char *hint);
|
||||
int cfg_eval_condition(char **args, char **err, const char **errptr);
|
||||
|
||||
/* simplified way to define a section parser */
|
||||
#define REGISTER_CONFIG_SECTION(name, parse, post) \
|
||||
|
@ -38,6 +38,7 @@
|
||||
#define MODE_MWORKER_WAIT 0x100 /* Master Worker wait mode */
|
||||
#define MODE_ZERO_WARNING 0x200 /* warnings cause a failure */
|
||||
#define MODE_DIAG 0x400 /* extra warnings */
|
||||
#define MODE_CHECK_CONDITION 0x800 /* -cc mode */
|
||||
|
||||
/* list of last checks to perform, depending on config options */
|
||||
#define LSTCHK_CAP_BIND 0x00000001 /* check that we can bind to any port */
|
||||
|
13
reg-tests/startup/check_condition.vtc
Normal file
13
reg-tests/startup/check_condition.vtc
Normal file
@ -0,0 +1,13 @@
|
||||
varnishtest "Tests the -cc argument"
|
||||
|
||||
#REQUIRE_VERSION=2.5
|
||||
feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'"
|
||||
|
||||
shell {
|
||||
$HAPROXY_PROGRAM -cc "version_atleast(2.4)"
|
||||
! $HAPROXY_PROGRAM -cc "version_atleast(1024)"
|
||||
|
||||
$HAPROXY_PROGRAM -cc "streq(foo,'foo')"
|
||||
$HAPROXY_PROGRAM -cc "streq(\"foo bar\",'foo bar')"
|
||||
! $HAPROXY_PROGRAM -cc "streq(foo,bar)"
|
||||
} -run
|
@ -1736,7 +1736,7 @@ static const struct cond_pred_kw *cfg_lookup_cond_pred(const char *str)
|
||||
* and only in this case), 0 if the condition is false, 1 if it's true. If
|
||||
* <errptr> is not NULL, it's set to the first invalid character on error.
|
||||
*/
|
||||
static int cfg_eval_condition(char **args, char **err, const char **errptr)
|
||||
int cfg_eval_condition(char **args, char **err, const char **errptr)
|
||||
{
|
||||
const struct cond_pred_kw *cond_pred = NULL;
|
||||
const char *end_ptr;
|
||||
|
@ -570,6 +570,7 @@ static void usage(char *name)
|
||||
#endif
|
||||
" -q quiet mode : don't display messages\n"
|
||||
" -c check mode : only check config files and exit\n"
|
||||
" -cc check condition : evaluate a condition and exit\n"
|
||||
" -n sets the maximum total # of connections (uses ulimit -n)\n"
|
||||
" -m limits the usable amount of memory (in MB)\n"
|
||||
" -N sets the default, per-proxy maximum # of connections (%d)\n"
|
||||
@ -1464,6 +1465,7 @@ static void init(int argc, char **argv)
|
||||
struct proxy *px;
|
||||
struct post_check_fct *pcf;
|
||||
int ideal_maxconn;
|
||||
char *check_condition = NULL;
|
||||
|
||||
global.mode = MODE_STARTING;
|
||||
old_argv = copy_argv(argc, argv);
|
||||
@ -1619,6 +1621,12 @@ static void init(int argc, char **argv)
|
||||
global.tune.options |= GTUNE_RESOLVE_DONTFAIL;
|
||||
else if (*flag == 'd')
|
||||
arg_mode |= MODE_DEBUG;
|
||||
else if (*flag == 'c' && flag[1] == 'c') {
|
||||
arg_mode |= MODE_CHECK_CONDITION;
|
||||
argv++;
|
||||
argc--;
|
||||
check_condition = *argv;
|
||||
}
|
||||
else if (*flag == 'c')
|
||||
arg_mode |= MODE_CHECK;
|
||||
else if (*flag == 'D')
|
||||
@ -1752,7 +1760,7 @@ static void init(int argc, char **argv)
|
||||
|
||||
global.mode |= (arg_mode & (MODE_DAEMON | MODE_MWORKER | MODE_FOREGROUND | MODE_VERBOSE
|
||||
| MODE_QUIET | MODE_CHECK | MODE_DEBUG | MODE_ZERO_WARNING
|
||||
| MODE_DIAG));
|
||||
| MODE_DIAG | MODE_CHECK_CONDITION));
|
||||
|
||||
if (getenv("HAPROXY_MWORKER_WAIT_ONLY")) {
|
||||
unsetenv("HAPROXY_MWORKER_WAIT_ONLY");
|
||||
@ -1787,6 +1795,58 @@ static void init(int argc, char **argv)
|
||||
|
||||
usermsgs_clr("config");
|
||||
|
||||
if (global.mode & MODE_CHECK_CONDITION) {
|
||||
int result;
|
||||
|
||||
uint32_t err;
|
||||
const char *errptr;
|
||||
char *errmsg = NULL;
|
||||
|
||||
char *args[MAX_LINE_ARGS+1];
|
||||
int arg = sizeof(args) / sizeof(*args);
|
||||
size_t outlen = strlen(check_condition) + 1;
|
||||
|
||||
err = parse_line(check_condition, check_condition, &outlen, args, &arg,
|
||||
PARSE_OPT_DQUOTE | PARSE_OPT_SQUOTE | PARSE_OPT_BKSLASH,
|
||||
&errptr);
|
||||
|
||||
if (err & PARSE_ERR_QUOTE) {
|
||||
ha_alert("Syntax Error in condition: Unmatched quote.\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (err & PARSE_ERR_HEX) {
|
||||
ha_alert("Syntax Error in condition: Truncated or invalid hexadecimal sequence.\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (err & (PARSE_ERR_TOOLARGE|PARSE_ERR_OVERLAP)) {
|
||||
ha_alert("Error in condition: Line too long.\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (err & PARSE_ERR_TOOMANY) {
|
||||
ha_alert("Error in condition: Too many words.\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
ha_alert("Unhandled error in condition, please report this to the developers.\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
result = cfg_eval_condition(args, &errmsg, &errptr);
|
||||
|
||||
if (result < 0) {
|
||||
if (errmsg)
|
||||
ha_alert("Failed to evaluate condition: %s\n", errmsg);
|
||||
|
||||
exit(2);
|
||||
}
|
||||
|
||||
exit(result ? 0 : 1);
|
||||
}
|
||||
|
||||
/* in wait mode, we don't try to read the configuration files */
|
||||
if (!(global.mode & MODE_MWORKER_WAIT)) {
|
||||
char *env_cfgfiles = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user