mirror of
https://pagure.io/fm-orchestrator.git
synced 2026-04-04 11:20:00 +08:00
Re-factor configuration loading, fix default topics (shall be a list),
update docs.
This commit is contained in:
28
README.rst
28
README.rst
@@ -383,3 +383,31 @@ E.g. ``"scmurl": "git://pkgs.stg.fedoraproject.org/modules/testmodule.git?#020ea
|
||||
The toplevel directory containing the trees for each architecture of a module.
|
||||
This field is only present when a module finished building, i.e. with the
|
||||
states 'done' or 'ready'.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
MBS configures itself according to the environment where it runs + according to
|
||||
the following rules (all of them are evaluated from top to bottom):
|
||||
|
||||
- DevConfiguration is the initial configuration chosen.
|
||||
- If configuration file is found within its final installation location,
|
||||
ProdConfiguration is assumed.
|
||||
- If Flask app running within mod_wsgi is detected,
|
||||
ProdConfiguration is assumed.
|
||||
- If environment variables determining configuration file/section are found,
|
||||
they are used for configuration. Following environment variables are
|
||||
recognized:
|
||||
|
||||
- `MBS_CONFIG_FILE`: Overrides default configuration file location,
|
||||
typically `/etc/module-build-service/config.py`.
|
||||
- `MBS_CONFIG_SECTION`: Overrides configuration section.
|
||||
|
||||
It is possible to set these values in httpd using `SetEnv`,
|
||||
anywhere in `/etc/profile.d/` etc.
|
||||
|
||||
- If test-runtime environment is detected,
|
||||
TestConfiguration is used, otherwise...
|
||||
- if `MODULE_BUILD_SERVICE_DEVELOPER_ENV` is set to some reasonable
|
||||
value, DevConfiguration is forced and `config.py` is used directly from the
|
||||
MBS's develop instance. For more information see `docs/CONTRIBUTING.rst`.
|
||||
|
||||
@@ -133,9 +133,11 @@ Environment
|
||||
The environment variable `MODULE_BUILD_SERVICE_DEVELOPER_ENV`, which if
|
||||
set to "1", indicates to the Module Build Service that the development
|
||||
configuration should be used. Docker and Vagrant are being run with this
|
||||
environment variable set.
|
||||
environment variable set. This overrides all configuration settings and forces
|
||||
usage of DevConfiguration section in `conf/config.py` from MBS's develop
|
||||
instance.
|
||||
|
||||
Anytime, you can do::
|
||||
Prior to starting MBS, you can force development mode::
|
||||
|
||||
$ export MODULE_BUILD_SERVICE_DEVELOPER_ENV=1
|
||||
|
||||
|
||||
@@ -31,34 +31,77 @@ from os import sys
|
||||
|
||||
from module_build_service import logger
|
||||
|
||||
try:
|
||||
conf_module = 'mbs_runtime_config'
|
||||
mbs_runtime_config = imp.load_source(conf_module,
|
||||
'/etc/module-build-service/config.py')
|
||||
except:
|
||||
conf_module = 'conf.config'
|
||||
|
||||
|
||||
def init_config(app):
|
||||
_init_app_config(app)
|
||||
return Config(app)
|
||||
|
||||
|
||||
def _init_app_config(app):
|
||||
""" Configure app
|
||||
""" Configure MBS and the Flask app
|
||||
"""
|
||||
app.config.from_envvar("MBS_SETTINGS", silent=True)
|
||||
here = sys.path[0]
|
||||
config_module = None
|
||||
config_file = '/etc/module-build-service/config.py'
|
||||
config_section = 'DevConfiguration'
|
||||
|
||||
# automagically detect production environment:
|
||||
# - existing and readable config_file presets ProdConfiguration
|
||||
try:
|
||||
with open(config_file):
|
||||
config_section = 'ProdConfiguration'
|
||||
except:
|
||||
pass
|
||||
# - Flask app within mod_wsgi presets ProdConfiguration
|
||||
flask_app_env = hasattr(app, 'request') and hasattr(app.request, 'environ')
|
||||
if flask_app_env and any([var.startswith('mod_wsgi.')
|
||||
for var in app.request.environ]):
|
||||
config_section = 'ProdConfiguration'
|
||||
# try getting config_file from os.environ
|
||||
if 'MBS_CONFIG_FILE' in os.environ:
|
||||
config_file = os.environ['MBS_CONFIG_FILE']
|
||||
# try getting config_section from os.environ
|
||||
if 'MBS_CONFIG_SECTION' in os.environ:
|
||||
config_section = os.environ['MBS_CONFIG_SECTION']
|
||||
# preferably get these values from Flask app
|
||||
if flask_app_env:
|
||||
# try getting config_file from Flask app
|
||||
if 'MBS_CONFIG_FILE' in app.request.environ:
|
||||
config_file = app.request.environ['MBS_CONFIG_FILE']
|
||||
# try getting config_section from Flask app
|
||||
if 'MBS_CONFIG_SECTION' in app.request.environ:
|
||||
config_section = app.request.environ['MBS_CONFIG_SECTION']
|
||||
# TestConfiguration shall only be used for running tests, otherwise...
|
||||
if any(['nosetests' in arg or 'noserunner.py' in arg for arg in sys.argv]):
|
||||
app.config.from_object('%s.TestConfiguration' % conf_module)
|
||||
elif 'MODULE_BUILD_SERVICE_DEVELOPER_ENV' in os.environ and \
|
||||
os.environ['MODULE_BUILD_SERVICE_DEVELOPER_ENV'].lower() in (
|
||||
'1', 'on', 'true', 'y', 'yes'):
|
||||
app.config.from_object('%s.DevConfiguration' % conf_module)
|
||||
elif here not in ('/usr/bin', '/bin', '/usr/local/bin'):
|
||||
app.config.from_object('%s.DevConfiguration' % conf_module)
|
||||
else:
|
||||
app.config.from_object('%s.ProdConfiguration' % conf_module)
|
||||
config_section = 'TestConfiguration'
|
||||
from conf import config
|
||||
config_module = config
|
||||
# ...MODULE_BUILD_SERVICE_DEVELOPER_ENV has always the last word
|
||||
# and overrides anything previously set before!
|
||||
# Again, check Flask app (preferably) or fallback to os.environ.
|
||||
# In any of the following cases, use configuration directly from MBS package
|
||||
# -> /conf/config.py.
|
||||
elif (flask_app_env and
|
||||
'MODULE_BUILD_SERVICE_DEVELOPER_ENV' in app.request.environ):
|
||||
if app.request.environ['MODULE_BUILD_SERVICE_DEVELOPER_ENV'].lower() in (
|
||||
'1', 'on', 'true', 'y', 'yes'):
|
||||
config_section = 'DevConfiguration'
|
||||
from conf import config
|
||||
config_module = config
|
||||
elif ('MODULE_BUILD_SERVICE_DEVELOPER_ENV' in os.environ and
|
||||
os.environ['MODULE_BUILD_SERVICE_DEVELOPER_ENV'].lower() in (
|
||||
'1', 'on', 'true', 'y', 'yes')):
|
||||
config_section = 'DevConfiguration'
|
||||
from conf import config
|
||||
config_module = config
|
||||
# try loading configuration from file
|
||||
if not config_module:
|
||||
try:
|
||||
config_module = imp.load_source('mbs_runtime_config',
|
||||
config_file)
|
||||
except:
|
||||
raise SystemError("Configuration file {} was not found."
|
||||
.format(config_file))
|
||||
|
||||
# finally configure MBS and the Flask app
|
||||
config_section_obj = getattr(config_module, config_section)
|
||||
conf = Config(config_section_obj)
|
||||
app.config.from_object(config_section_obj)
|
||||
return conf
|
||||
|
||||
|
||||
class Config(object):
|
||||
@@ -199,7 +242,7 @@ class Config(object):
|
||||
'desc': 'The messaging system to use.'},
|
||||
'messaging_topic_prefix': {
|
||||
'type': list,
|
||||
'default': 'org.fedoraproject.prod',
|
||||
'default': ['org.fedoraproject.prod'],
|
||||
'desc': 'The messaging system topic prefixes which we are interested in.'},
|
||||
'amq_recv_addresses': {
|
||||
'type': list,
|
||||
@@ -251,26 +294,23 @@ class Config(object):
|
||||
'desc': 'Global network retry interval for read/write operations, in seconds.'},
|
||||
}
|
||||
|
||||
def __init__(self, app=None):
|
||||
def __init__(self, conf_section_obj):
|
||||
"""
|
||||
Initialize the Config object with defaults.
|
||||
|
||||
If Flask app is given, override/enrich the configuration defaults
|
||||
with Flask config values/items.
|
||||
Initialize the Config object with defaults and then override them
|
||||
with runtime values.
|
||||
"""
|
||||
|
||||
# set defaults
|
||||
for name, values in self._defaults.items():
|
||||
self.set_item(name, values['default'])
|
||||
|
||||
# we don't check whether app is Flask instance, we simply assume it
|
||||
# so there's no need of import flask
|
||||
if app is not None:
|
||||
# override defaults
|
||||
for key, value in app.config.items():
|
||||
# lower keys
|
||||
key = key.lower()
|
||||
self.set_item(key, value)
|
||||
# override defaults
|
||||
for key in dir(conf_section_obj):
|
||||
# skip keys starting with underscore
|
||||
if key.startswith('_'):
|
||||
continue
|
||||
# set item (lower key)
|
||||
self.set_item(key.lower(), getattr(conf_section_obj, key))
|
||||
|
||||
def set_item(self, key, value):
|
||||
"""Set value for configuration item as self.key = value"""
|
||||
|
||||
Reference in New Issue
Block a user