blob: a68bd60a489bf552cc90b60fc060589c7c8102b7 [file] [log] [blame]
Jakob Juelich934f0dc2014-10-14 18:21:13 -07001#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
9Three databases are used with django (a default and one for tko tables,
10which always must be the global database, plus a readonly connection to the
11global 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
20In case an instance is running on a shard, a global database must explicitly
21be set. Instead of failing over from global to local, an exception will be
22raised in that case.
23
24The complexity to do this, is combined in this file.
25"""
26
27
28# Don't import anything that needs django here: Django may not be configured
29# on the builders, and this is also used by tko/db.py so failures like this
30# may occur: http://crbug.com/421565
31import common
32from autotest_lib.client.common_lib import global_config
33
34config = global_config.global_config
35SHARD_HOSTNAME = config.get_config_value('SHARD', 'shard_hostname',
36 default=None)
37
38
39def _get_config(config_key, **kwargs):
40 """Retrieves a config value for the specified key.
41
42 @param config_key: The string key associated with the desired config value.
43 @param **kwargs: Additional arguments to be passed to
44 global_config.get_config_value.
45
46 @return: The config value, as returned by
47 global_config.global_config.get_config_value().
48 """
49 return config.get_config_value('AUTOTEST_WEB', config_key, **kwargs)
50
51
52def _get_global_config(config_key, default=config._NO_DEFAULT_SPECIFIED, **kwargs):
53 """Retrieves a global config value for the specified key.
54
55 If the value can't be found, this will happen:
56 - if no default value was specified, and this is run on a shard instance,
57 a ConfigError will be raised.
58 - if a default value is set or this is run on a non-shard instancee, the
59 non-global value is returned
60
61 @param config_key: The string key associated with the desired config value.
62 @param default: The default value to return if the value couldn't be looked
63 up; neither with global_db_ nor no prefix.
64 @param **kwargs: Additional arguments to be passed to
65 global_config.get_config_value.
66
67 @return: The config value, as returned by
68 global_config.global_config.get_config_value().
69 """
70 try:
71 return _get_config('global_db_' + config_key, **kwargs)
72 except global_config.ConfigError:
73 if SHARD_HOSTNAME and default == config._NO_DEFAULT_SPECIFIED:
74 # When running on a shard, fail loudly if the global_db_ prefixed
75 # settings aren't present.
76 raise
77 return _get_config(config_key, default=default, **kwargs)
78
79
80def _get_readonly_config(config_key, default=config._NO_DEFAULT_SPECIFIED,
81 **kwargs):
82 """Retrieves a readonly config value for the specified key.
83
84 If no value can be found, the value of non readonly but global value
85 is returned instead.
86
87 @param config_key: The string key associated with the desired config value.
88 @param default: The default value to return if the value couldn't be looked
89 up; neither with readonly_, global_db_ nor no prefix.
90 @param **kwargs: Additional arguments to be passed to
91 global_config.get_config_value.
92
93 @return: The config value, as returned by
94 global_config.global_config.get_config_value().
95 """
96 try:
97 return _get_config('readonly_' + config_key, **kwargs)
98 except global_config.ConfigError:
99 return _get_global_config(config_key, default=default, **kwargs)
100
101
102def _get_database_config(getter):
103 """Create a configuration dictionary that can be passed to Django.
104
105 @param config_prefix: If specified, this function will try to prefix lookup
106 keys from global_config with this. If those values
107 don't exist, the normal key without the prefix will
108 be used.
109
110 @return A dictionary that can be used in the Django DATABASES setting.
111 """
112 config = {
113 'ENGINE': 'autotest_lib.frontend.db.backends.afe',
114 'PORT': '',
115 'HOST': getter('host'),
116 'NAME': getter('database'),
117 'USER': getter('user'),
118 'PASSWORD': getter('password', default=''),
119 'READONLY_HOST': getter('readonly_host', default=getter('host')),
120 'READONLY_USER': getter('readonly_user', default=getter('user')),
121 }
122 if config['READONLY_USER'] != config['USER']:
123 config['READONLY_PASSWORD'] = getter('readonly_password', default='')
124 else:
125 config['READONLY_PASSWORD'] = config['PASSWORD']
126 return config
127
128
129def get_global_db_config():
130 """Returns settings for the global database as required by django.
131
132 @return: A dictionary that can be used in the Django DATABASES setting.
133 """
134 return _get_database_config(getter=_get_global_config)
135
136
137def get_default_db_config():
138 """Returns settings for the default/local database as required by django.
139
140 @return: A dictionary that can be used in the Django DATABASES setting.
141 """
142 return _get_database_config(getter=_get_config)
143
144
145def get_readonly_db_config():
146 """Returns settings for the readonly database as required by django.
147
148 @return: A dictionary that can be used in the Django DATABASES setting.
149 """
150 return _get_database_config(getter=_get_readonly_config)