| #pylint: disable-msg=C0111 |
| |
| # Copyright (c) 2014 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Helpers to load database settings. |
| |
| Four databases are used with django (a default and one for tko tables, |
| which always must be the global database, a readonly connection to the |
| global database, and a connection to server database). |
| |
| In order to save configuration overhead, settings that aren't set for the |
| desired database type, should be obtained from the setting with the next lower |
| priority. The order is: |
| readonly -> global -> local. |
| I.e. this means if `readonly_host` is not set, `global_db_host` will be used. If |
| that is also not set, `host` (the local one) will be used. |
| |
| server database setting falls back to local database setting. That is, if |
| `server_db_host` is not set, `host`(the local one) will be used. |
| |
| In case an instance is running on a shard, a global database must explicitly |
| be set. Instead of failing over from global to local, an exception will be |
| raised in that case. |
| |
| The complexity to do this, is combined in this file. |
| """ |
| |
| |
| # Don't import anything that needs django here: Django may not be configured |
| # on the builders, and this is also used by tko/db.py so failures like this |
| # may occur: http://crbug.com/421565 |
| import common |
| from autotest_lib.client.common_lib import global_config |
| |
| config = global_config.global_config |
| SHARD_HOSTNAME = config.get_config_value('SHARD', 'shard_hostname', |
| default=None) |
| |
| |
| def _get_config(config_key, section='AUTOTEST_WEB', **kwargs): |
| """Retrieves a config value for the specified key. |
| |
| @param config_key: The string key associated with the desired config value. |
| @param section: Section of global config to read config. Default is set to |
| AUTOTEST_WEB. |
| @param **kwargs: Additional arguments to be passed to |
| global_config.get_config_value. |
| |
| @return: The config value, as returned by |
| global_config.global_config.get_config_value(). |
| """ |
| return config.get_config_value(section, config_key, **kwargs) |
| |
| |
| def _get_global_config(config_key, default=config._NO_DEFAULT_SPECIFIED, |
| **kwargs): |
| """Retrieves a global config value for the specified key. |
| |
| If the value can't be found, this will happen: |
| - if no default value was specified, and this is run on a shard instance, |
| a ConfigError will be raised. |
| - if a default value is set or this is run on a non-shard instancee, the |
| non-global value is returned |
| |
| @param config_key: The string key associated with the desired config value. |
| @param default: The default value to return if the value couldn't be looked |
| up; neither with global_db_ nor no prefix. |
| @param **kwargs: Additional arguments to be passed to |
| global_config.get_config_value. |
| |
| @return: The config value, as returned by |
| global_config.global_config.get_config_value(). |
| """ |
| try: |
| return _get_config('global_db_' + config_key, **kwargs) |
| except global_config.ConfigError: |
| if SHARD_HOSTNAME and default == config._NO_DEFAULT_SPECIFIED: |
| # When running on a shard, fail loudly if the global_db_ prefixed |
| # settings aren't present. |
| raise |
| return _get_config(config_key, default=default, **kwargs) |
| |
| |
| def _get_readonly_config(config_key, default=config._NO_DEFAULT_SPECIFIED, |
| **kwargs): |
| """Retrieves a readonly config value for the specified key. |
| |
| If no value can be found, the value of non readonly but global value |
| is returned instead. |
| |
| @param config_key: The string key associated with the desired config value. |
| @param default: The default value to return if the value couldn't be looked |
| up; neither with readonly_, global_db_ nor no prefix. |
| @param **kwargs: Additional arguments to be passed to |
| global_config.get_config_value. |
| |
| @return: The config value, as returned by |
| global_config.global_config.get_config_value(). |
| """ |
| try: |
| return _get_config('readonly_' + config_key, **kwargs) |
| except global_config.ConfigError: |
| return _get_global_config(config_key, default=default, **kwargs) |
| |
| |
| def _get_server_db_config(config_key, default=config._NO_DEFAULT_SPECIFIED, |
| **kwargs): |
| """Retrieves a config value for the specified key for server database. |
| |
| The order of searching for the specified config_key is: |
| section: AUTOTEST_SERVER_DB |
| section: AUTOTEST_WEB |
| supplied default |
| |
| @param config_key: The string key associated with the desired config value. |
| @param default: The default value to return if the value couldn't be looked |
| up; neither with global_db_ nor no prefix. |
| @param **kwargs: Additional arguments to be passed to |
| global_config.get_config_value. |
| |
| @return: The config value, as returned by |
| global_config.global_config.get_config_value(). |
| """ |
| try: |
| return _get_config(config_key, section='AUTOTEST_SERVER_DB', **kwargs) |
| except global_config.ConfigError: |
| return _get_config(config_key, default=default, **kwargs) |
| |
| |
| def _get_database_config(getter): |
| """Create a configuration dictionary that can be passed to Django. |
| |
| @param getter: A function to call to get configuration values. |
| |
| @return A dictionary that can be used in the Django DATABASES setting. |
| """ |
| config = { |
| 'ENGINE': 'autotest_lib.frontend.db.backends.afe', |
| 'PORT': getter('port', default=''), |
| 'HOST': getter('host'), |
| 'NAME': getter('database'), |
| 'USER': getter('user'), |
| 'PASSWORD': getter('password', default=''), |
| 'READONLY_HOST': getter('readonly_host', default=getter('host')), |
| 'READONLY_USER': getter('readonly_user', default=getter('user')), |
| } |
| if config['READONLY_USER'] != config['USER']: |
| config['READONLY_PASSWORD'] = getter('readonly_password', default='') |
| else: |
| config['READONLY_PASSWORD'] = config['PASSWORD'] |
| return config |
| |
| |
| def get_global_db_config(): |
| """Returns settings for the global database as required by django. |
| |
| @return: A dictionary that can be used in the Django DATABASES setting. |
| """ |
| return _get_database_config(getter=_get_global_config) |
| |
| |
| def get_default_db_config(): |
| """Returns settings for the default/local database as required by django. |
| |
| @return: A dictionary that can be used in the Django DATABASES setting. |
| """ |
| return _get_database_config(getter=_get_config) |
| |
| |
| def get_readonly_db_config(): |
| """Returns settings for the readonly database as required by django. |
| |
| @return: A dictionary that can be used in the Django DATABASES setting. |
| """ |
| return _get_database_config(getter=_get_readonly_config) |
| |
| |
| def get_server_db_config(): |
| """Returns settings for the server database as required by django. |
| |
| @return: A dictionary that can be used in the Django DATABASES setting. |
| """ |
| return _get_database_config(getter=_get_server_db_config) |