global_config.py revision 0afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181
1ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh"""A singleton class for accessing global config values 2ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh 3ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighprovides access to global configuration file 4ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh""" 5ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh 6ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh__author__ = 'raphtee@google.com (Travis Miller)' 7ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh 8ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighimport os 98375088a4ed43357a7abe1b6cab83c0e5ce79cfamblighimport sys 10ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighimport ConfigParser 11ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighimport error 12ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh 13f97513351c77d4d47bbe30063b7faca25d530667mblighdirname = os.path.dirname(sys.modules[__name__].__file__) 140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanskiDEFAULT_CONFIG_FILE = os.path.abspath(os.path.join(dirname, 150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski "../../global_config.ini")) 160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanskiDEFAULT_SHADOW_FILE = os.path.abspath(os.path.join(dirname, 170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski "../../shadow_config.ini")) 180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 19104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh 20ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighclass ConfigError(error.AutotestError): 210afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski pass 22ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh 23ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh 24104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mblighclass ConfigValueError(ConfigError): 250afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski pass 26104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh 27104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh 28ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighclass global_config(object): 290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski config = None 300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski config_file = DEFAULT_CONFIG_FILE 310afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski shadow_file = DEFAULT_SHADOW_FILE 320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 340afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski def set_config_files(self, config_file=DEFAULT_CONFIG_FILE, 350afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski shadow_file=DEFAULT_SHADOW_FILE): 360afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.config_file = config_file 370afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.shadow_file = shadow_file 380afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.config = None 390afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 400afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 410afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski def get_config_value(self, section, key, type=str, default=None): 420afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if self.config == None: 430afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.parse_config_file() 440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 450afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski try: 460afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski val = self.config.get(section, key) 470afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski except: 480afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if default == None: 490afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski msg = ("Value '%s' not found in section '%s'" % 500afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski (key, section)) 510afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski raise ConfigError(msg) 520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski else: 530afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return default 540afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 550afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return self.convert_value(key, section, val, type, default) 560afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 580afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski def merge_configs(self, shadow_config): 590afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # overwrite whats in config with whats in shadow_config 600afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski sections = shadow_config.sections() 610afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski for section in sections: 620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # add the section if need be 630afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if not self.config.has_section(section): 640afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.config.add_section(section) 650afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # now run through all options and set them 660afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski options = shadow_config.options(section) 670afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski for option in options: 680afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski val = shadow_config.get(section, option) 690afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.config.set(section, option, val) 700afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 710afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 720afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski def parse_config_file(self): 730afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if not os.path.exists(self.config_file): 740afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski raise ConfigError('%s not found' % (self.config_file)) 750afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.config = ConfigParser.ConfigParser() 760afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.config.read(self.config_file) 770afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 780afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # now also read the shadow file if there is one 790afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # this will overwrite anything that is found in the 800afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # other config 810afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if os.path.exists(self.shadow_file): 820afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski shadow_config = ConfigParser.ConfigParser() 830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski shadow_config.read(self.shadow_file) 840afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # now we merge shadow into global 850afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski self.merge_configs(shadow_config) 860afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 870afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 880afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # the values that are pulled from ini 890afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # are strings. But we should attempt to 900afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # convert them to other types if needed. 910afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski def convert_value(self, key, section, value, type, default): 920afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # strip off leading and trailing white space 930afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski sval = value.strip() 940afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 950afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski # if length of string is zero then return None 960afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if len(sval) == 0: 970afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if type == str: 980afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return "" 990afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski elif type == bool: 1000afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return False 1010afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski elif type == int: 1020afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return 0 1030afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski elif type == float: 1040afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return 0.0 1050afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski else: 1060afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return None 1070afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 1080afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if type == bool: 1090afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski if sval.lower() == "false": 1100afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return False 1110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski else: 1120afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return True 1130afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 1140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski try: 1150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski conv_val = type(sval) 1160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski return conv_val 1170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski except: 1180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski msg = ("Could not covert %s in section %s" % 1190afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski (key, section)) 1200afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski raise ConfigValueError(msg) 1210afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 1220afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 1230afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski# insure the class is a singleton. Now the symbol global_config 124ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh# will point to the one and only one instace of the class 125ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighglobal_config = global_config() 126