Merge pull request #395 from bigchaindb/feat/394/change-config-system

Change config precedence so that env variables can override config.
This commit is contained in:
Rodolphe Marques 2016-06-21 15:20:59 +02:00 committed by GitHub
commit cc20136cb1
4 changed files with 72 additions and 12 deletions

View File

@ -183,6 +183,20 @@ def set_config(config):
bigchaindb.config['CONFIGURED'] = True
def update_config(config):
"""Update bigchaindb.config with whatever is in the provided config dict,
and then set bigchaindb.config['CONFIGURED'] = True
Args:
config (dict): the config dict to read for changes
to the default config
"""
# Update the default config with whatever is in the passed config
update(bigchaindb.config, update_types(config, bigchaindb.config))
bigchaindb.config['CONFIGURED'] = True
def write_config(config, filename=None):
"""Write the provided configuration to a specific location.
@ -206,13 +220,18 @@ def autoconfigure(filename=None, config=None, force=False):
logger.debug('System already configured, skipping autoconfiguration')
return
newconfig = env_config(bigchaindb.config)
# start with the current configuration
newconfig = bigchaindb.config
# update configuration from file
try:
newconfig = update(newconfig, file_config(filename=filename))
except FileNotFoundError as e:
logger.warning('Cannot find config file `%s`.' % e.filename)
# override configuration with env variables
newconfig = env_config(newconfig)
if config:
newconfig = update(newconfig, config)

View File

@ -38,11 +38,11 @@ class Bigchain(object):
A Bigchain instance has several configuration parameters (e.g. host).
If a parameter value is passed as an argument to the Bigchain
__init__ method, then that is the value it will have.
Otherwise, the parameter value will be the value from the local
configuration file. If it's not set in that file, then the value
will come from an environment variable. If that environment variable
isn't set, then the parameter will have its default value (defined in
bigchaindb.__init__).
Otherwise, the parameter value will come from an environment variable.
If that environment variable isn't set, then the value
will come from the local configuration file. And if that variable
isn't in the local configuration file, then the parameter will have
its default value (defined in bigchaindb.__init__).
Args:
host (str): hostname where RethinkDB is running.

View File

@ -81,11 +81,13 @@ the `server` section accepts all the options specified in the
## Order of Precedence in Determining Configuration Values
All configuration values start with their default values (defined in `bigchaindb.__init__`), but a default value can be overriden by an environment variable, and a value set by an environment variable can be overriden by a value in a local configuration file (`$HOME/.bigchaindb` or the location specified by the `-c` command-line option).
All configuration values start with their default values (defined in `bigchaindb.__init__`), but a default value
can be overriden by a value in a local configuration file (`$HOME/.bigchaindb` or the location specified by the
`-c` command-line option), and a value set by a local configuration file can be overriden by a value in an environment variable
In summary, there is an order of precedence in reading configuration values:
1. local configuration file
2. environment variables
1. environment variables
2. local configuration file
3. default configuration file (defined in ``bigchaindb.__init__``)
This means that if the default configuration contains:
@ -93,6 +95,7 @@ This means that if the default configuration contains:
```json
{
"database": {
"name": "bigchain",
"host": "localhost",
"port": 28015
}
@ -103,7 +106,8 @@ while the local file `local.json` contains:
```json
{
"database": {
"host": "ec2-xx-xx-xxx-xxx.eu-central-1.compute.amazonaws.com"
"host": "ec2-xx-xx-xxx-xxx.eu-central-1.compute.amazonaws.com",
"port": 5000
}
}
@ -111,8 +115,7 @@ while the local file `local.json` contains:
and you run this command:
```
$ BIGCHAINDB_DATABASE_HOST=anotherhost.com \
BIGCHAINDB_DATABASE_PORT=4242 \
$ BIGCHAINDB_DATABASE_PORT=4242 \
BIGCHAINDB_KEYRING=pubkey0:pubkey1 \
bigchaindb -c local.json show-config
```

View File

@ -168,3 +168,41 @@ def test_autoconfigure_read_both_from_file_and_env(monkeypatch):
'consensus_plugin': 'default',
}
def test_autoconfigure_env_precedence(monkeypatch):
file_config = {
'database': {'host': 'test-host', 'name': 'bigchaindb', 'port': 28015}
}
monkeypatch.setattr('bigchaindb.config_utils.file_config', lambda *args, **kwargs: file_config)
monkeypatch.setattr('os.environ', {'BIGCHAINDB_DATABASE_NAME': 'test-dbname',
'BIGCHAINDB_DATABASE_PORT': '4242',
'BIGCHAINDB_SERVER_BIND': 'localhost:9985'})
import bigchaindb
from bigchaindb import config_utils
config_utils.autoconfigure()
assert bigchaindb.config['CONFIGURED']
assert bigchaindb.config['database']['host'] == 'test-host'
assert bigchaindb.config['database']['name'] == 'test-dbname'
assert bigchaindb.config['database']['port'] == 4242
assert bigchaindb.config['server']['bind'] == 'localhost:9985'
def test_update_config(monkeypatch):
import bigchaindb
from bigchaindb import config_utils
file_config = {
'database': {'host': 'test-host', 'name': 'bigchaindb', 'port': 28015}
}
monkeypatch.setattr('bigchaindb.config_utils.file_config', lambda *args, **kwargs: file_config)
config_utils.autoconfigure()
# update configuration, retaining previous changes
config_utils.update_config({'database': {'port': 28016, 'name': 'bigchaindb_other'}})
assert bigchaindb.config['database']['host'] == 'test-host'
assert bigchaindb.config['database']['name'] == 'bigchaindb_other'
assert bigchaindb.config['database']['port'] == 28016