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`.
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.
**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.
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]
```
**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:
```bash

View File

@ -11,33 +11,38 @@
* =================================
*
* 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.
*
* EXAMPLE:
* "port": "${PORT}"
* "port": "${PORT:9001}"
* "minify": "${MINIFY}"
* "skinName": "${SKIN_NAME}"
* "skinName": "${SKIN_NAME:colibris}"
*
* Would read the configuration values for those items from the environment
* 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:
* Please note that variable substitution always needs to be quoted.
*
* "port": 9001, <-- Literal values. When not using
* "minify": false substitution, only strings must be quoted.
* "skinName": "colibris" Booleans and numbers must not.
* "port": 9001, <-- Literal values. When not using
* "minify": false substitution, only strings must be
* "skinName": "colibris" quoted. Booleans and numbers must not.
*
* "port": "${PORT}" <-- CORRECT: if you want to use a variable
* "minify": "${MINIFY}" substitution, put quotes around its name,
* "skinName": "${SKIN_NAME}" even if the required value is a number or a
* boolean.
* Etherpad will take care of rewriting it to
* the proper type if necessary.
* "port": "${PORT:9001}" <-- CORRECT: if you want to use a variable
* "minify": "${MINIFY:true}" substitution, put quotes around its name,
* "skinName": "${SKIN_NAME}" even if the required value is a number or
* a boolean.
* Etherpad will take care of rewriting it
* to the proper type if necessary.
*
* "port": ${PORT} <-- ERROR: this is not valid json. Quotes
* "minify": ${MINIFY} around variable names are missing.
* "port": ${PORT:9001} <-- ERROR: this is not valid json. Quotes
* "minify": ${MINIFY} around variable names are missing.
* "skinName": ${SKIN_NAME}
*
*/

View File

@ -400,8 +400,8 @@ function coerceValue(stringValue) {
/**
* Takes a javascript object containing Etherpad's configuration, and returns
* 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
* environment variable.
* "${ENV_VAR}" or "${ENV_VAR:default_value}" got their value replaced with the
* contents of the given environment variable, or with a default value.
*
* 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,
@ -422,6 +422,8 @@ function coerceValue(stringValue) {
* | "${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" |
* +---------------------------+---------------+------------------+
*
* 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.:
* "${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) {
// no match: use the value literally, without any substitution
@ -465,12 +468,16 @@ function lookupEnvironmentVariables(obj) {
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 envVarValue = process.env[envVarName];
const defaultValue = match[3];
if (envVarValue === undefined) {
console.warn(`Environment variable "${envVarName}" does not contain any value for configuration key "${key}". Returning null. Please check your configuration and environment settings.`);
if ((envVarValue === undefined) && (defaultValue === undefined)) {
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
@ -479,6 +486,12 @@ function lookupEnvironmentVariables(obj) {
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.
/*