global_config.py revision 773a86ebaa2e4e4cce213b8553aeb4b30c1f3a9d
1ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh"""A singleton class for accessing global config values 2ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh 3ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighprovides access to global configuration file 4ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh""" 5ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh 660cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi# The config values can be stored in 3 config files: 760cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi# global_config.ini 860cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi# moblab_config.ini 960cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi# shadow_config.ini 1060cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi# When the code is running in Moblab, config values in moblab config override 1160cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi# values in global config, and config values in shadow config override values 1260cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi# in both moblab and global config. 1360cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi# When the code is running in a non-Moblab host, moblab_config.ini is ignored. 1460cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi# Config values in shadow config will override values in global config. 1560cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi 16ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh__author__ = 'raphtee@google.com (Travis Miller)' 17ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh 1860cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shiimport os, sys, ConfigParser 1911788296e58691a3149355a4fc4a3fa1084c689dmblighfrom autotest_lib.client.common_lib import error 2060cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shifrom autotest_lib.client.common_lib import lsbrelease_utils 21104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh 22ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighclass ConfigError(error.AutotestError): 2360cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi """Configuration error.""" 240afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski pass 25ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh 26ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh 27104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mblighclass ConfigValueError(ConfigError): 2860cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi """Configuration value error, raised when value failed to be converted to 2960cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi expected type.""" 300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski pass 31104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh 32104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh 336d08b3c3fc2858ccd60a323008703179f93ae38blmr 346d08b3c3fc2858ccd60a323008703179f93ae38blmrcommon_lib_dir = os.path.dirname(sys.modules[__name__].__file__) 356d08b3c3fc2858ccd60a323008703179f93ae38blmrclient_dir = os.path.dirname(common_lib_dir) 366d08b3c3fc2858ccd60a323008703179f93ae38blmrroot_dir = os.path.dirname(client_dir) 376d08b3c3fc2858ccd60a323008703179f93ae38blmr 386d08b3c3fc2858ccd60a323008703179f93ae38blmr# Check if the config files are at autotest's root dir 396d08b3c3fc2858ccd60a323008703179f93ae38blmr# This will happen if client is executing inside a full autotest tree, or if 406d08b3c3fc2858ccd60a323008703179f93ae38blmr# other entry points are being executed 416d08b3c3fc2858ccd60a323008703179f93ae38blmrglobal_config_path_root = os.path.join(root_dir, 'global_config.ini') 4260cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shimoblab_config_path_root = os.path.join(root_dir, 'moblab_config.ini') 436d08b3c3fc2858ccd60a323008703179f93ae38blmrshadow_config_path_root = os.path.join(root_dir, 'shadow_config.ini') 4488434b12bf2c38f1099c0307b0313fe3f379364bChris Masoneconfig_in_root = os.path.exists(global_config_path_root) 456d08b3c3fc2858ccd60a323008703179f93ae38blmr 466d08b3c3fc2858ccd60a323008703179f93ae38blmr# Check if the config files are at autotest's client dir 476d08b3c3fc2858ccd60a323008703179f93ae38blmr# This will happen if a client stand alone execution is happening 486d08b3c3fc2858ccd60a323008703179f93ae38blmrglobal_config_path_client = os.path.join(client_dir, 'global_config.ini') 496d08b3c3fc2858ccd60a323008703179f93ae38blmrconfig_in_client = os.path.exists(global_config_path_client) 506d08b3c3fc2858ccd60a323008703179f93ae38blmr 516d08b3c3fc2858ccd60a323008703179f93ae38blmrif config_in_root: 526d08b3c3fc2858ccd60a323008703179f93ae38blmr DEFAULT_CONFIG_FILE = global_config_path_root 5360cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi if os.path.exists(moblab_config_path_root): 5460cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi DEFAULT_MOBLAB_FILE = moblab_config_path_root 5560cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi else: 5660cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi DEFAULT_MOBLAB_FILE = None 5788434b12bf2c38f1099c0307b0313fe3f379364bChris Masone if os.path.exists(shadow_config_path_root): 5888434b12bf2c38f1099c0307b0313fe3f379364bChris Masone DEFAULT_SHADOW_FILE = shadow_config_path_root 5988434b12bf2c38f1099c0307b0313fe3f379364bChris Masone else: 6088434b12bf2c38f1099c0307b0313fe3f379364bChris Masone DEFAULT_SHADOW_FILE = None 616d08b3c3fc2858ccd60a323008703179f93ae38blmr RUNNING_STAND_ALONE_CLIENT = False 626d08b3c3fc2858ccd60a323008703179f93ae38blmrelif config_in_client: 636d08b3c3fc2858ccd60a323008703179f93ae38blmr DEFAULT_CONFIG_FILE = global_config_path_client 6460cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi DEFAULT_MOBLAB_FILE = None 656d08b3c3fc2858ccd60a323008703179f93ae38blmr DEFAULT_SHADOW_FILE = None 666d08b3c3fc2858ccd60a323008703179f93ae38blmr RUNNING_STAND_ALONE_CLIENT = True 676d08b3c3fc2858ccd60a323008703179f93ae38blmrelse: 68da8fb97be0353f54eb7e62e132482d728684f200lmr DEFAULT_CONFIG_FILE = None 6960cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi DEFAULT_MOBLAB_FILE = None 70da8fb97be0353f54eb7e62e132482d728684f200lmr DEFAULT_SHADOW_FILE = None 71da8fb97be0353f54eb7e62e132482d728684f200lmr RUNNING_STAND_ALONE_CLIENT = True 726d08b3c3fc2858ccd60a323008703179f93ae38blmr 73773a86ebaa2e4e4cce213b8553aeb4b30c1f3a9dSimran Basiclass global_config_class(object): 7460cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi """Object to access config values.""" 75893db3d528e4c7d10ef5b7073dbf63670dffbccashoward _NO_DEFAULT_SPECIFIED = object() 76893db3d528e4c7d10ef5b7073dbf63670dffbccashoward 770afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski config = None 780afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski config_file = DEFAULT_CONFIG_FILE 7960cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi moblab_file=DEFAULT_MOBLAB_FILE 800afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski shadow_file = DEFAULT_SHADOW_FILE 816d08b3c3fc2858ccd60a323008703179f93ae38blmr running_stand_alone_client = RUNNING_STAND_ALONE_CLIENT 826d08b3c3fc2858ccd60a323008703179f93ae38blmr 836d08b3c3fc2858ccd60a323008703179f93ae38blmr 846d08b3c3fc2858ccd60a323008703179f93ae38blmr def check_stand_alone_client_run(self): 8560cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi """Check if this is a stand alone client that does not need config.""" 866d08b3c3fc2858ccd60a323008703179f93ae38blmr return self.running_stand_alone_client 870afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 880afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 890afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski def set_config_files(self, config_file=DEFAULT_CONFIG_FILE, 9060cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi shadow_file=DEFAULT_SHADOW_FILE, 9160cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi moblab_file=DEFAULT_MOBLAB_FILE): 920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.config_file = config_file 9360cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi self.moblab_file = moblab_file 940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.shadow_file = shadow_file 950afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.config = None 960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 98d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward def _handle_no_value(self, section, key, default): 99893db3d528e4c7d10ef5b7073dbf63670dffbccashoward if default is self._NO_DEFAULT_SPECIFIED: 100d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward msg = ("Value '%s' not found in section '%s'" % 101d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward (key, section)) 102d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward raise ConfigError(msg) 103d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward else: 104d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward return default 105d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward 106d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward 1076d08b3c3fc2858ccd60a323008703179f93ae38blmr def get_section_values(self, section): 1086d08b3c3fc2858ccd60a323008703179f93ae38blmr """ 1096d08b3c3fc2858ccd60a323008703179f93ae38blmr Return a config parser object containing a single section of the 1106d08b3c3fc2858ccd60a323008703179f93ae38blmr global configuration, that can be later written to a file object. 1116d08b3c3fc2858ccd60a323008703179f93ae38blmr 1126d08b3c3fc2858ccd60a323008703179f93ae38blmr @param section: Section we want to turn into a config parser object. 1136d08b3c3fc2858ccd60a323008703179f93ae38blmr @return: ConfigParser() object containing all the contents of section. 1146d08b3c3fc2858ccd60a323008703179f93ae38blmr """ 1156d08b3c3fc2858ccd60a323008703179f93ae38blmr cfgparser = ConfigParser.ConfigParser() 1166d08b3c3fc2858ccd60a323008703179f93ae38blmr cfgparser.add_section(section) 1176d08b3c3fc2858ccd60a323008703179f93ae38blmr for option, value in self.config.items(section): 1186d08b3c3fc2858ccd60a323008703179f93ae38blmr cfgparser.set(section, option, value) 1196d08b3c3fc2858ccd60a323008703179f93ae38blmr return cfgparser 1206d08b3c3fc2858ccd60a323008703179f93ae38blmr 1216d08b3c3fc2858ccd60a323008703179f93ae38blmr 122893db3d528e4c7d10ef5b7073dbf63670dffbccashoward def get_config_value(self, section, key, type=str, 123893db3d528e4c7d10ef5b7073dbf63670dffbccashoward default=_NO_DEFAULT_SPECIFIED, allow_blank=False): 124f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich """Get a configuration value 125f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich 126f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param section: Section the key is in. 127f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param key: The key to look up. 128f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param type: The expected type of the returned value. 129f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param default: A value to return in case the key couldn't be found. 130f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param allow_blank: If False, an empty string as a value is treated like 131f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich there was no value at all. If True, empty strings 132f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich will be returned like they were normal values. 133f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich 134f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @raises ConfigError: If the key could not be found and no default was 135f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich specified. 136f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich 137f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @return: The obtained value or default. 138f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich """ 13950c0e71efd37c04c5f441c7e4dd095632b54c35fshoward self._ensure_config_parsed() 1400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 1410afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski try: 1420afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski val = self.config.get(section, key) 143d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward except ConfigParser.Error: 144d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward return self._handle_no_value(section, key, default) 145d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward 146d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward if not val.strip() and not allow_blank: 147d1ee1dd3f3e5ac44f00d7a96deb815dbe1beedadshoward return self._handle_no_value(section, key, default) 1480afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 149893db3d528e4c7d10ef5b7073dbf63670dffbccashoward return self._convert_value(key, section, val, type) 1500afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 1510afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 152f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich # This order of parameters ensures this can be called similar to the normal 153f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich # get_config_value which is mostly called with (section, key, type). 154f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich def get_config_value_with_fallback(self, section, key, fallback_key, 155f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich type=str, fallback_section=None, 156f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich default=_NO_DEFAULT_SPECIFIED, **kwargs): 157f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich """Get a configuration value if it exists, otherwise use fallback. 158f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich 159f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich Tries to obtain a configuration value for a given key. If this value 160f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich does not exist, the value looked up under a different key will be 161f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich returned. 162f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich 163f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param section: Section the key is in. 164f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param key: The key to look up. 165f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param fallback_key: The key to use in case the original key wasn't 166f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich found. 167f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param type: data type the value should have. 168f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param fallback_section: The section the fallback key resides in. In 169f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich case none is specified, the the same section as 170f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich for the primary key is used. 171f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param default: Value to return if values could neither be obtained for 172f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich the key nor the fallback key. 173f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @param **kwargs: Additional arguments that should be passed to 174f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich get_config_value. 175f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich 176f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @raises ConfigError: If the fallback key doesn't exist and no default 177f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich was provided. 178f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich 179f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich @return: The value that was looked up for the key. If that didn't 180f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich exist, the value looked up for the fallback key will be 181f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich returned. If that also didn't exist, default will be returned. 182f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich """ 183f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich if fallback_section is None: 184f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich fallback_section = section 185f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich 186f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich try: 187f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich return self.get_config_value(section, key, type, **kwargs) 188f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich except ConfigError: 189f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich return self.get_config_value(fallback_section, fallback_key, 190f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich type, default=default, **kwargs) 191f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich 192f9c43d1e95e3c8375f62f1ae914d44d826e28a81Jakob Juelich 19350c0e71efd37c04c5f441c7e4dd095632b54c35fshoward def override_config_value(self, section, key, new_value): 19460cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi """Override a value from the config file with a new value. 19560cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi 19660cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi @param section: Name of the section. 19760cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi @param key: Name of the key. 19860cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi @param new_value: new value. 19950c0e71efd37c04c5f441c7e4dd095632b54c35fshoward """ 20050c0e71efd37c04c5f441c7e4dd095632b54c35fshoward self._ensure_config_parsed() 20150c0e71efd37c04c5f441c7e4dd095632b54c35fshoward self.config.set(section, key, new_value) 20250c0e71efd37c04c5f441c7e4dd095632b54c35fshoward 20350c0e71efd37c04c5f441c7e4dd095632b54c35fshoward 20450c0e71efd37c04c5f441c7e4dd095632b54c35fshoward def reset_config_values(self): 20550c0e71efd37c04c5f441c7e4dd095632b54c35fshoward """ 20650c0e71efd37c04c5f441c7e4dd095632b54c35fshoward Reset all values to those found in the config files (undoes all 20750c0e71efd37c04c5f441c7e4dd095632b54c35fshoward overrides). 20850c0e71efd37c04c5f441c7e4dd095632b54c35fshoward """ 20950c0e71efd37c04c5f441c7e4dd095632b54c35fshoward self.parse_config_file() 21050c0e71efd37c04c5f441c7e4dd095632b54c35fshoward 21150c0e71efd37c04c5f441c7e4dd095632b54c35fshoward 21250c0e71efd37c04c5f441c7e4dd095632b54c35fshoward def _ensure_config_parsed(self): 21360cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi """Make sure config files are parsed. 21460cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi """ 215d876f459fff6cc4994cab329b1f80c99a86edcbdmbligh if self.config is None: 21650c0e71efd37c04c5f441c7e4dd095632b54c35fshoward self.parse_config_file() 21750c0e71efd37c04c5f441c7e4dd095632b54c35fshoward 21850c0e71efd37c04c5f441c7e4dd095632b54c35fshoward 21960cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi def merge_configs(self, override_config): 22060cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi """Merge existing config values with the ones in given override_config. 22160cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi 22260cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi @param override_config: Configs to override existing config values. 22360cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi """ 22460cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi # overwrite whats in config with whats in override_config 22560cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi sections = override_config.sections() 2260afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski for section in sections: 2270afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # add the section if need be 2280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if not self.config.has_section(section): 2290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.config.add_section(section) 2300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # now run through all options and set them 23160cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi options = override_config.options(section) 2320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski for option in options: 23360cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi val = override_config.get(section, option) 2340afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.config.set(section, option, val) 2350afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 2360afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 2370afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski def parse_config_file(self): 23860cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi """Parse config files.""" 2390afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.config = ConfigParser.ConfigParser() 240da8fb97be0353f54eb7e62e132482d728684f200lmr if self.config_file and os.path.exists(self.config_file): 241da8fb97be0353f54eb7e62e132482d728684f200lmr self.config.read(self.config_file) 242da8fb97be0353f54eb7e62e132482d728684f200lmr else: 243da8fb97be0353f54eb7e62e132482d728684f200lmr raise ConfigError('%s not found' % (self.config_file)) 2440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 24560cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi # If it's running in Moblab, read moblab config file if exists, 24660cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi # overwrite the value in global config. 24760cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi if (lsbrelease_utils.is_moblab() and self.moblab_file and 24860cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi os.path.exists(self.moblab_file)): 24960cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi moblab_config = ConfigParser.ConfigParser() 25060cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi moblab_config.read(self.moblab_file) 25160cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi # now we merge moblab into global 25260cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi self.merge_configs(moblab_config) 25360cf6a9294dc53a9fe11dc9b28eaaea1ee69ca92Dan Shi 2540afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # now also read the shadow file if there is one 2550afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # this will overwrite anything that is found in the 2560afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # other config 2576d08b3c3fc2858ccd60a323008703179f93ae38blmr if self.shadow_file and os.path.exists(self.shadow_file): 2580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski shadow_config = ConfigParser.ConfigParser() 2590afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski shadow_config.read(self.shadow_file) 2600afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # now we merge shadow into global 2610afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.merge_configs(shadow_config) 2620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 2630afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 2640afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # the values that are pulled from ini 2650afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # are strings. But we should attempt to 2660afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # convert them to other types if needed. 267893db3d528e4c7d10ef5b7073dbf63670dffbccashoward def _convert_value(self, key, section, value, value_type): 2680afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # strip off leading and trailing white space 2690afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski sval = value.strip() 2700afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 2710afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # if length of string is zero then return None 2720afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if len(sval) == 0: 273a5f30c207b211e2bf57c6d4297734da54055af90showard if value_type == str: 2740afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return "" 275a5f30c207b211e2bf57c6d4297734da54055af90showard elif value_type == bool: 2760afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return False 277a5f30c207b211e2bf57c6d4297734da54055af90showard elif value_type == int: 2780afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return 0 279a5f30c207b211e2bf57c6d4297734da54055af90showard elif value_type == float: 2800afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return 0.0 281a5f30c207b211e2bf57c6d4297734da54055af90showard elif value_type == list: 282c5ddfd1f71caef9ec0c84c53ef7db42fcdc33e1cmbligh return [] 2830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski else: 2840afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return None 2850afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 286a5f30c207b211e2bf57c6d4297734da54055af90showard if value_type == bool: 2870afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if sval.lower() == "false": 2880afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return False 2890afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski else: 2900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return True 2910afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 292a5f30c207b211e2bf57c6d4297734da54055af90showard if value_type == list: 293c5ddfd1f71caef9ec0c84c53ef7db42fcdc33e1cmbligh # Split the string using ',' and return a list 294c5ddfd1f71caef9ec0c84c53ef7db42fcdc33e1cmbligh return [val.strip() for val in sval.split(',')] 295c5ddfd1f71caef9ec0c84c53ef7db42fcdc33e1cmbligh 2960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski try: 297a5f30c207b211e2bf57c6d4297734da54055af90showard conv_val = value_type(sval) 2980afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return conv_val 2990afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski except: 300a5f30c207b211e2bf57c6d4297734da54055af90showard msg = ("Could not convert %s value %r in section %s to type %s" % 301a5f30c207b211e2bf57c6d4297734da54055af90showard (key, sval, section, value_type)) 3020afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski raise ConfigValueError(msg) 3030afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 3040afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 30571206ef92012e5a5c36bbd1ae47e9176be04036dSimran Basi def get_sections(self): 30671206ef92012e5a5c36bbd1ae47e9176be04036dSimran Basi """Return a list of sections available.""" 30771206ef92012e5a5c36bbd1ae47e9176be04036dSimran Basi self._ensure_config_parsed() 30871206ef92012e5a5c36bbd1ae47e9176be04036dSimran Basi return self.config.sections() 30971206ef92012e5a5c36bbd1ae47e9176be04036dSimran Basi 31071206ef92012e5a5c36bbd1ae47e9176be04036dSimran Basi 3110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski# insure the class is a singleton. Now the symbol global_config 312ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh# will point to the one and only one instace of the class 313773a86ebaa2e4e4cce213b8553aeb4b30c1f3a9dSimran Basiglobal_config = global_config_class() 314