mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-29 01:44:36 -04:00
Accept settings in snake case in Docker image (#74327)
Closes #74036. Since some orchestration platforms forbid periods in environment variable names, allow Docker users to pass settings to ES using an alternative name scheme. For example: bootstrap.memory_lock ...becomes: ES_BOOTSTRAP_MEMORY__LOCK The setting name is uppercased, prefixed, all underscores are converted to double underscores, and all periods are converted to underscores.
This commit is contained in:
parent
e4df4d7205
commit
d08b851a5b
3 changed files with 85 additions and 5 deletions
|
@ -111,7 +111,7 @@ if [[ "$ES_DISTRIBUTION_TYPE" == "docker" ]]; then
|
||||||
|
|
||||||
# Parse Docker env vars to customize Elasticsearch
|
# Parse Docker env vars to customize Elasticsearch
|
||||||
#
|
#
|
||||||
# e.g. Setting the env var cluster.name=testcluster
|
# e.g. Setting the env var cluster.name=testcluster or ES_CLUSTER_NAME=testcluster
|
||||||
#
|
#
|
||||||
# will cause Elasticsearch to be invoked with -Ecluster.name=testcluster
|
# will cause Elasticsearch to be invoked with -Ecluster.name=testcluster
|
||||||
#
|
#
|
||||||
|
@ -122,11 +122,35 @@ if [[ "$ES_DISTRIBUTION_TYPE" == "docker" ]]; then
|
||||||
while IFS='=' read -r envvar_key envvar_value
|
while IFS='=' read -r envvar_key envvar_value
|
||||||
do
|
do
|
||||||
# Elasticsearch settings need to have at least two dot separated lowercase
|
# Elasticsearch settings need to have at least two dot separated lowercase
|
||||||
# words, e.g. `cluster.name`
|
# words, e.g. `cluster.name`, or uppercased with underscore separators and
|
||||||
if [[ "$envvar_key" =~ ^[a-z0-9_]+\.[a-z0-9_]+ ]]; then
|
# prefixed with `ES_`, e.g. `ES_CLUSTER_NAME`. Underscores in setting names
|
||||||
if [[ ! -z $envvar_value ]]; then
|
# are escaped by writing them as a double-underscore e.g. "__"
|
||||||
|
if [[ ! -z "$envvar_value" ]]; then
|
||||||
|
if [[ "$envvar_key" =~ ^[a-z0-9_]+\.[a-z0-9_]+ ]]; then
|
||||||
es_opt="-E${envvar_key}=${envvar_value}"
|
es_opt="-E${envvar_key}=${envvar_value}"
|
||||||
es_arg_array+=("${es_opt}")
|
es_arg_array+=("${es_opt}")
|
||||||
|
elif [[ "$envvar_key" =~ ^ES(_{1,2}[A-Z]+)+$ ]]; then
|
||||||
|
case "$envvar_key" in
|
||||||
|
# Do nothing for these. Not all of these are actually exported into the environment by our scripts,
|
||||||
|
# and so don't appear in the output of the `env` command, but it's better to be safe than sorry
|
||||||
|
# in case a user exported them in their own shell for some reason.
|
||||||
|
ES_DISTRIBUTION_FLAVOR) ;;
|
||||||
|
ES_DISTRIBUTION_TYPE) ;;
|
||||||
|
ES_HOME) ;;
|
||||||
|
ES_JAVA_HOME) ;;
|
||||||
|
ES_JAVA_OPTS) ;;
|
||||||
|
ES_KEYSTORE_PASSPHRASE_FILE) ;;
|
||||||
|
ES_LOG_STYLE) ;;
|
||||||
|
ES_PATH_CONF) ;;
|
||||||
|
ES_SD_NOTIFY) ;;
|
||||||
|
ES_TMPDIR) ;;
|
||||||
|
*)
|
||||||
|
# The long-hand sed `y` command works in any sed variant.
|
||||||
|
envvar_key="$(echo "$envvar_key" | sed -e 's/^ES_//; s/_/./g ; s/\.\./_/g; y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' )"
|
||||||
|
es_opt="-E${envvar_key}=${envvar_value}"
|
||||||
|
es_arg_array+=("${es_opt}")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done <<< "$(env)"
|
done <<< "$(env)"
|
||||||
|
|
|
@ -339,7 +339,19 @@ over the configuration files in the image.
|
||||||
|
|
||||||
You can set individual {es} configuration parameters using Docker environment variables.
|
You can set individual {es} configuration parameters using Docker environment variables.
|
||||||
The <<docker-compose-file, sample compose file>> and the
|
The <<docker-compose-file, sample compose file>> and the
|
||||||
<<docker-cli-run-dev-mode, single-node example>> use this method.
|
<<docker-cli-run-dev-mode, single-node example>> use this method. You can
|
||||||
|
use the setting name directly as the environment variable name. If
|
||||||
|
you cannot do this, for example because your orchestration platform forbids
|
||||||
|
periods in environment variable names, then you can use an alternative
|
||||||
|
style by converting the setting name as follows.
|
||||||
|
|
||||||
|
. Change the setting name to uppercase
|
||||||
|
. Prefix it with `ES_`
|
||||||
|
. Escape any underscores (`_`) by duplicating them
|
||||||
|
. Convert all periods (`.`) to underscores (`_`)
|
||||||
|
|
||||||
|
For example, `-e bootstrap.memory_lock=true` becomes
|
||||||
|
`-e ES_BOOTSTRAP_MEMORY__LOCK=true`.
|
||||||
|
|
||||||
To use the contents of a file to set an environment variable, suffix the environment
|
To use the contents of a file to set an environment variable, suffix the environment
|
||||||
variable name with `_FILE`. This is useful for passing secrets such as passwords to {es}
|
variable name with `_FILE`. This is useful for passing secrets such as passwords to {es}
|
||||||
|
|
|
@ -486,6 +486,50 @@ public class DockerTests extends PackagingTestCase {
|
||||||
assertThat(result.stdout, containsString("java.net.UnknownHostException: this.is.not.valid"));
|
assertThat(result.stdout, containsString("java.net.UnknownHostException: this.is.not.valid"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that settings are applied when they are supplied as environment variables with names that are:
|
||||||
|
* <ul>
|
||||||
|
* <li>Prefixed with {@code ES_}</li>
|
||||||
|
* <li>All uppercase</li>
|
||||||
|
* <li>Dots (periods) are converted to underscores</li>
|
||||||
|
* <li>Underscores in setting names are escaped by doubling them</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public void test086EnvironmentVariablesInSnakeCaseAreTranslated() {
|
||||||
|
// Note the double-underscore in the var name here, which retains the underscore in translation
|
||||||
|
installation = runContainer(distribution(), builder().envVars(Map.of("ES_XPACK_SECURITY_FIPS__MODE_ENABLED", "false")));
|
||||||
|
|
||||||
|
final Optional<String> commandLine = sh.run("bash -c 'COLUMNS=2000 ps ax'").stdout.lines()
|
||||||
|
.filter(line -> line.contains("org.elasticsearch.bootstrap.Elasticsearch"))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
assertThat(commandLine.isPresent(), equalTo(true));
|
||||||
|
|
||||||
|
assertThat(commandLine.get(), containsString("-Expack.security.fips_mode.enabled=false"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that environment variables that do not match the criteria for translation to settings are ignored.
|
||||||
|
*/
|
||||||
|
public void test087EnvironmentVariablesInIncorrectFormatAreIgnored() {
|
||||||
|
final Map<String, String> envVars = new HashMap<>();
|
||||||
|
// No ES_ prefix
|
||||||
|
envVars.put("XPACK_SECURITY_FIPS__MODE_ENABLED", "false");
|
||||||
|
// Not underscore-separated
|
||||||
|
envVars.put("ES.XPACK.SECURITY.FIPS_MODE.ENABLED", "false");
|
||||||
|
// Not uppercase
|
||||||
|
envVars.put("es_xpack_security_fips__mode_enabled", "false");
|
||||||
|
installation = runContainer(distribution(), builder().envVars(envVars));
|
||||||
|
|
||||||
|
final Optional<String> commandLine = sh.run("bash -c 'COLUMNS=2000 ps ax'").stdout.lines()
|
||||||
|
.filter(line -> line.contains("org.elasticsearch.bootstrap.Elasticsearch"))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
assertThat(commandLine.isPresent(), equalTo(true));
|
||||||
|
|
||||||
|
assertThat(commandLine.get(), not(containsString("-Expack.security.fips_mode.enabled=false")));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the elasticsearch-certutil tool has been shipped correctly,
|
* Check whether the elasticsearch-certutil tool has been shipped correctly,
|
||||||
* and if present then it can execute.
|
* and if present then it can execute.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue