Settings.js: support syntax for default values

+---------------------------+---------------+------------------+
| Configuration string in   | Value of      | Resulting confi- |
| settings.json             | ENV_VAR       | guration value   |
|---------------------------|---------------|------------------|
| "${ENV_VAR}"              | "some_string" | "some_string"    |
| "${ENV_VAR}"              | "9001"        | 9001             |
| "${ENV_VAR}"              | undefined     | null             |
| "${ENV_VAR:some_default}" | "some_string" | "some_string"    |
| "${ENV_VAR:some_default}" | undefined     | "some_default"   |
+---------------------------+---------------+------------------+

Mention this briefly in the main README.md, also.

Closes #3578.
pull/3585/head
muxator 2019-03-21 01:37:19 +01:00 committed by muxator
parent c3bca6506e
commit 2955740a6e
4 changed files with 41 additions and 22 deletions

View File

@ -65,6 +65,7 @@ If cloning to a subdirectory within another project, you may need to do the foll
You can modify the settings in `settings.json`. You can modify the settings in `settings.json`.
If you need to handle multiple settings files, you can pass the path to a settings file to `bin/run.sh` using the `-s|--settings` option: this allows you to run multiple Etherpad instances from the same installation. If you need to handle multiple settings files, you can pass the path to a settings file to `bin/run.sh` using the `-s|--settings` option: this allows you to run multiple Etherpad instances from the same installation.
Similarly, `--credentials` can be used to give a settings override file, `--apikey` to give a different APIKEY.txt file and `--sessionkey` to give a non-default SESSIONKEY.txt. Similarly, `--credentials` can be used to give a settings override file, `--apikey` to give a different APIKEY.txt file and `--sessionkey` to give a non-default SESSIONKEY.txt.
**Each configuration parameter can also be set via an environment variable**, using the syntax `"${ENV_VAR}"` or `"${ENV_VAR:default_value}"`. For details, refer to `settings.json.template`.
Once you have access to your /admin section settings can be modified through the web browser. Once you have access to your /admin section settings can be modified through the web browser.
You should use a dedicated database such as "mysql", if you are planning on using etherpad-in a production environment, since the "dirtyDB" database driver is only for testing and/or development purposes. You should use a dedicated database such as "mysql", if you are planning on using etherpad-in a production environment, since the "dirtyDB" database driver is only for testing and/or development purposes.

View File

@ -14,7 +14,7 @@ cp ../settings.json.template settings.json
[ further edit your settings.json as needed] [ further edit your settings.json as needed]
``` ```
**Each configuration parameter can also be set via an environment variable**, using the syntax `"${ENV_VAR_NAME}"`. For details, refer to `settings.json.template`. **Each configuration parameter can also be set via an environment variable**, using the syntax `"${ENV_VAR}"` or `"${ENV_VAR:default_value}"`. For details, refer to `settings.json.template`.
Build the version you prefer: Build the version you prefer:
```bash ```bash

View File

@ -11,32 +11,37 @@
* ================================= * =================================
* *
* All the configuration values can be read from environment variables using the * All the configuration values can be read from environment variables using the
* syntax "${ENV_VAR}". * syntax "${ENV_VAR}" or "${ENV_VAR:default_value}".
*
* This is useful, for example, when running in a Docker container. * This is useful, for example, when running in a Docker container.
* *
* EXAMPLE: * EXAMPLE:
* "port": "${PORT}" * "port": "${PORT:9001}"
* "minify": "${MINIFY}" * "minify": "${MINIFY}"
* "skinName": "${SKIN_NAME}" * "skinName": "${SKIN_NAME:colibris}"
* *
* Would read the configuration values for those items from the environment * Would read the configuration values for those items from the environment
* variables PORT, MINIFY and SKIN_NAME. * variables PORT, MINIFY and SKIN_NAME.
* If PORT and SKIN_NAME variables were not defined, the default values 9001 and
* "colibris" would be used. The configuration value "minify", on the other
* hand, does not have a default indicated. Thus, if the environment variable
* MINIFY were undefined, "minify" would be null (do not do this).
* *
* REMARKS: * REMARKS:
* Please note that variable substitution always needs to be quoted. * Please note that variable substitution always needs to be quoted.
* *
* "port": 9001, <-- Literal values. When not using * "port": 9001, <-- Literal values. When not using
* "minify": false substitution, only strings must be quoted. * "minify": false substitution, only strings must be
* "skinName": "colibris" Booleans and numbers must not. * "skinName": "colibris" quoted. Booleans and numbers must not.
* *
* "port": "${PORT}" <-- CORRECT: if you want to use a variable * "port": "${PORT:9001}" <-- CORRECT: if you want to use a variable
* "minify": "${MINIFY}" substitution, put quotes around its name, * "minify": "${MINIFY:true}" substitution, put quotes around its name,
* "skinName": "${SKIN_NAME}" even if the required value is a number or a * "skinName": "${SKIN_NAME}" even if the required value is a number or
* boolean. * a boolean.
* Etherpad will take care of rewriting it to * Etherpad will take care of rewriting it
* the proper type if necessary. * to the proper type if necessary.
* *
* "port": ${PORT} <-- ERROR: this is not valid json. Quotes * "port": ${PORT:9001} <-- ERROR: this is not valid json. Quotes
* "minify": ${MINIFY} around variable names are missing. * "minify": ${MINIFY} around variable names are missing.
* "skinName": ${SKIN_NAME} * "skinName": ${SKIN_NAME}
* *

View File

@ -400,8 +400,8 @@ function coerceValue(stringValue) {
/** /**
* Takes a javascript object containing Etherpad's configuration, and returns * Takes a javascript object containing Etherpad's configuration, and returns
* another object, in which all the string properties whose value is of the form * another object, in which all the string properties whose value is of the form
* "${ENV_VAR}" got their value replaced with the contents of the given * "${ENV_VAR}" or "${ENV_VAR:default_value}" got their value replaced with the
* environment variable. * contents of the given environment variable, or with a default value.
* *
* By definition, an environment variable's value is always a string. However, * By definition, an environment variable's value is always a string. However,
* the code base makes use of the various json types. To maintain compatiblity, * the code base makes use of the various json types. To maintain compatiblity,
@ -422,6 +422,8 @@ function coerceValue(stringValue) {
* | "${ENV_VAR}" | "some_string" | "some_string" | * | "${ENV_VAR}" | "some_string" | "some_string" |
* | "${ENV_VAR}" | "9001" | 9001 | * | "${ENV_VAR}" | "9001" | 9001 |
* | "${ENV_VAR}" | undefined | null | * | "${ENV_VAR}" | undefined | null |
* | "${ENV_VAR:some_default}" | "some_string" | "some_string" |
* | "${ENV_VAR:some_default}" | undefined | "some_default" |
* +---------------------------+---------------+------------------+ * +---------------------------+---------------+------------------+
* *
* IMPLEMENTATION NOTE: variable substitution is performed doing a round trip * IMPLEMENTATION NOTE: variable substitution is performed doing a round trip
@ -455,9 +457,10 @@ function lookupEnvironmentVariables(obj) {
/* /*
* Let's check if the string value looks like a variable expansion (e.g.: * Let's check if the string value looks like a variable expansion (e.g.:
* "${ENV_VAR}") * "${ENV_VAR}" or "${ENV_VAR:default_value}")
*/ */
const match = value.match(/^\$\{(.*)\}$/); // MUXATOR 2019-03-21: we could use named capture groups here once we migrate to nodejs v10
const match = value.match(/^\$\{([^:]*)(:(.*))?\}$/);
if (match === null) { if (match === null) {
// no match: use the value literally, without any substitution // no match: use the value literally, without any substitution
@ -465,12 +468,16 @@ function lookupEnvironmentVariables(obj) {
return value; return value;
} }
// we found the name of an environment variable. Let's read its value. /*
* We found the name of an environment variable. Let's read its actual value
* and its default value, if given
*/
const envVarName = match[1]; const envVarName = match[1];
const envVarValue = process.env[envVarName]; const envVarValue = process.env[envVarName];
const defaultValue = match[3];
if (envVarValue === undefined) { if ((envVarValue === undefined) && (defaultValue === undefined)) {
console.warn(`Environment variable "${envVarName}" does not contain any value for configuration key "${key}". Returning null. Please check your configuration and environment settings.`); console.warn(`Environment variable "${envVarName}" does not contain any value for configuration key "${key}", and no default was given. Returning null. Please check your configuration and environment settings.`);
/* /*
* We have to return null, because if we just returned undefined, the * We have to return null, because if we just returned undefined, the
@ -479,6 +486,12 @@ function lookupEnvironmentVariables(obj) {
return null; return null;
} }
if ((envVarValue === undefined) && (defaultValue !== undefined)) {
console.debug(`Environment variable "${envVarName}" not found for configuration key "${key}". Falling back to default value.`);
return coerceValue(defaultValue);
}
// envVarName contained some value. // envVarName contained some value.
/* /*