mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-24 14:46:56 +00:00
MEDIUM: config: allow to manipulate environment variables in the global section
With new init systems such as systemd, environment variables became a real mess because they're only considered on startup but not on reload since the init script's variables cannot be passed to the process that is signaled to reload. This commit introduces an alternative method consisting in making it possible to modify the environment from the global section with directives like "setenv", "unsetenv", "presetenv" and "resetenv". Since haproxy supports loading multiple config files, it now becomes possible to put the host-dependant variables in one file and to distribute the rest of the configuration to all nodes, without having to deal with the init system's deficiencies. Environment changes take effect immediately when the directives are processed, so it's possible to do perform the same operations as are usually performed in regular service config files.
This commit is contained in:
parent
ae79572f89
commit
1d54972789
@ -538,9 +538,12 @@ The following keywords are supported in the "global" section :
|
||||
- nbproc
|
||||
- node
|
||||
- pidfile
|
||||
- presetenv
|
||||
- resetenv
|
||||
- uid
|
||||
- ulimit-n
|
||||
- user
|
||||
- setenv
|
||||
- stats
|
||||
- ssl-default-bind-ciphers
|
||||
- ssl-default-bind-options
|
||||
@ -549,6 +552,7 @@ The following keywords are supported in the "global" section :
|
||||
- ssl-dh-param-file
|
||||
- ssl-server-verify
|
||||
- unix-bind
|
||||
- unsetenv
|
||||
- 51degrees-data-file
|
||||
- 51degrees-property-name-list
|
||||
- 51degrees-property-separator
|
||||
@ -778,6 +782,22 @@ pidfile <pidfile>
|
||||
the "-p" command line argument. The file must be accessible to the user
|
||||
starting the process. See also "daemon".
|
||||
|
||||
presetenv <name> <value>
|
||||
Sets environment variable <name> to value <value>. If the variable exists, it
|
||||
is NOT overwritten. The changes immediately take effect so that the next line
|
||||
in the configuration file sees the new value. See also "setenv", "resetenv",
|
||||
and "unsetenv".
|
||||
|
||||
resetenv [<name> ...]
|
||||
Removes all environment variables except the ones specified in argument. It
|
||||
allows to use a clean controlled environment before setting new values with
|
||||
setenv or unsetenv. Please note that some internal functions may make use of
|
||||
some environment variables, such as time manipulation functions, but also
|
||||
OpenSSL or even external checks. This must be used with extreme care and only
|
||||
after complete validation. The changes immediately take effect so that the
|
||||
next line in the configuration file sees the new environment. See also
|
||||
"setenv", "presetenv", and "unsetenv".
|
||||
|
||||
stats bind-process [ all | odd | even | <number 1-64>[-<number 1-64>] ] ...
|
||||
Limits the stats socket to a certain set of processes numbers. By default the
|
||||
stats socket is bound to all processes, causing a warning to be emitted when
|
||||
@ -806,6 +826,12 @@ server-state-file <file>
|
||||
configuration. See also "server-state-base" and "show servers state",
|
||||
"load-server-state-from-file" and "server-state-file-name"
|
||||
|
||||
setenv <name> <value>
|
||||
Sets environment variable <name> to value <value>. If the variable exists, it
|
||||
is overwritten. The changes immediately take effect so that the next line in
|
||||
the configuration file sees the new value. See also "presetenv", "resetenv",
|
||||
and "unsetenv".
|
||||
|
||||
ssl-default-bind-ciphers <ciphers>
|
||||
This setting is only available when support for OpenSSL was built in. It sets
|
||||
the default string describing the list of cipher algorithms ("cipher suite")
|
||||
@ -901,6 +927,15 @@ unix-bind [ prefix <prefix> ] [ mode <mode> ] [ user <user> ] [ uid <uid> ]
|
||||
both are specified, the "bind" statement has priority, meaning that the
|
||||
"unix-bind" settings may be seen as process-wide default settings.
|
||||
|
||||
unsetenv [<name> ...]
|
||||
Removes environment variables specified in arguments. This can be useful to
|
||||
hide some sensitive information that are occasionally inherited from the
|
||||
user's environment during some operations. Variables which did not exist are
|
||||
silently ignored so that after the operation, it is certain that none of
|
||||
these variables remain. The changes immediately take effect so that the next
|
||||
line in the configuration file will not see these variables. See also
|
||||
"setenv", "presetenv", and "resetenv".
|
||||
|
||||
user <user name>
|
||||
Similar to "uid" but uses the UID of user name <user name> from /etc/passwd.
|
||||
See also "uid" and "group".
|
||||
|
@ -1826,6 +1826,78 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
||||
goto out;
|
||||
#endif
|
||||
}
|
||||
else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
|
||||
if (alertif_too_many_args(3, file, linenum, args, &err_code))
|
||||
goto out;
|
||||
|
||||
if (*(args[2]) == 0) {
|
||||
Alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* "setenv" overwrites, "presetenv" only sets if not yet set */
|
||||
if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
|
||||
Alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[1], strerror(errno));
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(args[0], "unsetenv")) {
|
||||
int arg;
|
||||
|
||||
if (*(args[1]) == 0) {
|
||||
Alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (arg = 1; *args[arg]; arg++) {
|
||||
if (unsetenv(args[arg]) != 0) {
|
||||
Alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[arg], strerror(errno));
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(args[0], "resetenv")) {
|
||||
extern char **environ;
|
||||
char **env = environ;
|
||||
|
||||
/* args contain variable names to keep, one per argument */
|
||||
while (*env) {
|
||||
int arg;
|
||||
|
||||
/* look for current variable in among all those we want to keep */
|
||||
for (arg = 1; *args[arg]; arg++) {
|
||||
if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
|
||||
(*env)[strlen(args[arg])] == '=')
|
||||
break;
|
||||
}
|
||||
|
||||
/* delete this variable */
|
||||
if (!*args[arg]) {
|
||||
char *delim = strchr(*env, '=');
|
||||
|
||||
if (!delim || delim - *env >= trash.size) {
|
||||
Alert("parsing [%s:%d]: '%s' failed to unset invalid variable '%s'.\n", file, linenum, args[0], *env);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(trash.str, *env, delim - *env);
|
||||
trash.str[delim - *env] = 0;
|
||||
|
||||
if (unsetenv(trash.str) != 0) {
|
||||
Alert("parsing [%s:%d]: '%s' failed to unset variable '%s' : %s.\n", file, linenum, args[0], *env, strerror(errno));
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
env++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
struct cfg_kw_list *kwl;
|
||||
int index;
|
||||
|
Loading…
Reference in New Issue
Block a user