1#pylint: disable-msg=C0111 2 3# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7"""Helpers to load database settings. 8 9Four databases are used with django (a default and one for tko tables, 10which always must be the global database, a readonly connection to the 11global database, and a connection to server database). 12 13In order to save configuration overhead, settings that aren't set for the 14desired database type, should be obtained from the setting with the next lower 15priority. The order is: 16readonly -> global -> local. 17I.e. this means if `readonly_host` is not set, `global_db_host` will be used. If 18that is also not set, `host` (the local one) will be used. 19 20server database setting falls back to local database setting. That is, if 21`server_db_host` is not set, `host`(the local one) will be used. 22 23In case an instance is running on a shard, a global database must explicitly 24be set. Instead of failing over from global to local, an exception will be 25raised in that case. 26 27The complexity to do this, is combined in this file. 28""" 29 30 31# Don't import anything that needs django here: Django may not be configured 32# on the builders, and this is also used by tko/db.py so failures like this 33# may occur: http://crbug.com/421565 34import common 35from autotest_lib.client.common_lib import global_config 36 37config = global_config.global_config 38SHARD_HOSTNAME = config.get_config_value('SHARD', 'shard_hostname', 39 default=None) 40 41 42def _get_config(config_key, section='AUTOTEST_WEB', **kwargs): 43 """Retrieves a config value for the specified key. 44 45 @param config_key: The string key associated with the desired config value. 46 @param section: Section of global config to read config. Default is set to 47 AUTOTEST_WEB. 48 @param **kwargs: Additional arguments to be passed to 49 global_config.get_config_value. 50 51 @return: The config value, as returned by 52 global_config.global_config.get_config_value(). 53 """ 54 return config.get_config_value(section, config_key, **kwargs) 55 56 57def _get_global_config(config_key, default=config._NO_DEFAULT_SPECIFIED, 58 **kwargs): 59 """Retrieves a global config value for the specified key. 60 61 If the value can't be found, this will happen: 62 - if no default value was specified, and this is run on a shard instance, 63 a ConfigError will be raised. 64 - if a default value is set or this is run on a non-shard instancee, the 65 non-global value is returned 66 67 @param config_key: The string key associated with the desired config value. 68 @param default: The default value to return if the value couldn't be looked 69 up; neither with global_db_ nor no prefix. 70 @param **kwargs: Additional arguments to be passed to 71 global_config.get_config_value. 72 73 @return: The config value, as returned by 74 global_config.global_config.get_config_value(). 75 """ 76 try: 77 return _get_config('global_db_' + config_key, **kwargs) 78 except global_config.ConfigError: 79 if SHARD_HOSTNAME and default == config._NO_DEFAULT_SPECIFIED: 80 # When running on a shard, fail loudly if the global_db_ prefixed 81 # settings aren't present. 82 raise 83 return _get_config(config_key, default=default, **kwargs) 84 85 86def _get_readonly_config(config_key, default=config._NO_DEFAULT_SPECIFIED, 87 **kwargs): 88 """Retrieves a readonly config value for the specified key. 89 90 If no value can be found, the value of non readonly but global value 91 is returned instead. 92 93 @param config_key: The string key associated with the desired config value. 94 @param default: The default value to return if the value couldn't be looked 95 up; neither with readonly_, global_db_ nor no prefix. 96 @param **kwargs: Additional arguments to be passed to 97 global_config.get_config_value. 98 99 @return: The config value, as returned by 100 global_config.global_config.get_config_value(). 101 """ 102 try: 103 return _get_config('readonly_' + config_key, **kwargs) 104 except global_config.ConfigError: 105 return _get_global_config(config_key, default=default, **kwargs) 106 107 108def _get_server_db_config(config_key, default=config._NO_DEFAULT_SPECIFIED, 109 **kwargs): 110 """Retrieves a config value for the specified key for server database. 111 112 The order of searching for the specified config_key is: 113 section: AUTOTEST_SERVER_DB 114 section: AUTOTEST_WEB 115 supplied default 116 117 @param config_key: The string key associated with the desired config value. 118 @param default: The default value to return if the value couldn't be looked 119 up; neither with global_db_ nor no prefix. 120 @param **kwargs: Additional arguments to be passed to 121 global_config.get_config_value. 122 123 @return: The config value, as returned by 124 global_config.global_config.get_config_value(). 125 """ 126 try: 127 return _get_config(config_key, section='AUTOTEST_SERVER_DB', **kwargs) 128 except global_config.ConfigError: 129 return _get_config(config_key, default=default, **kwargs) 130 131 132def _get_database_config(getter): 133 """Create a configuration dictionary that can be passed to Django. 134 135 @param getter: A function to call to get configuration values. 136 137 @return A dictionary that can be used in the Django DATABASES setting. 138 """ 139 config = { 140 'ENGINE': 'autotest_lib.frontend.db.backends.afe', 141 'PORT': getter('port', default=''), 142 'HOST': getter('host'), 143 'NAME': getter('database'), 144 'USER': getter('user'), 145 'PASSWORD': getter('password', default=''), 146 'READONLY_HOST': getter('readonly_host', default=getter('host')), 147 'READONLY_USER': getter('readonly_user', default=getter('user')), 148 } 149 if config['READONLY_USER'] != config['USER']: 150 config['READONLY_PASSWORD'] = getter('readonly_password', default='') 151 else: 152 config['READONLY_PASSWORD'] = config['PASSWORD'] 153 return config 154 155 156def get_global_db_config(): 157 """Returns settings for the global database as required by django. 158 159 @return: A dictionary that can be used in the Django DATABASES setting. 160 """ 161 return _get_database_config(getter=_get_global_config) 162 163 164def get_default_db_config(): 165 """Returns settings for the default/local database as required by django. 166 167 @return: A dictionary that can be used in the Django DATABASES setting. 168 """ 169 return _get_database_config(getter=_get_config) 170 171 172def get_readonly_db_config(): 173 """Returns settings for the readonly database as required by django. 174 175 @return: A dictionary that can be used in the Django DATABASES setting. 176 """ 177 return _get_database_config(getter=_get_readonly_config) 178 179 180def get_server_db_config(): 181 """Returns settings for the server database as required by django. 182 183 @return: A dictionary that can be used in the Django DATABASES setting. 184 """ 185 return _get_database_config(getter=_get_server_db_config) 186