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