global_config.py revision 104e9ce7a74041fd673ceac5c8b0bc67c74edcd5
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
13104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
14ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighclass ConfigError(error.AutotestError):
15ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh	pass
16ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh
17ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh
18104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mblighclass ConfigValueError(ConfigError):
19104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh	pass
20104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
21104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
22ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighclass global_config(object):
23ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh
24ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh	config = None
25ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh
26104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh	def get_config_value(self, section, key, type=str, default=None):
27ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh	        if self.config == None:
28ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh	        	self.parse_config_file()
29ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh
30ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh	        try:
31104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh                	val = self.config.get(section, key)
32104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh                except:
33104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh                        if default == None:
34104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh                                msg = ("Value '%s' not found in section '%s'" %
35104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh                                      (key, section))
36104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh                                raise ConfigError(msg)
37104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh                        else:
38104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh                                return default
39104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
40104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		return self.convert_value(key, section, val, type, default)
41104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
42104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
43104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh	def merge_configs(self, shadow_config):
44104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		# overwrite whats in config with whats in shadow_config
45104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		sections = shadow_config.sections()
46104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		for section in sections:
47104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			# add the section if need be
48104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			if not self.config.has_section(section):
49104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh				self.config.add_section(section)
50104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			# now run through all options and set them
51104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			options = shadow_config.options(section)
52104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			for option in options:
53104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh				val = shadow_config.get(section, option)
54104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh				self.config.set(section, option, val)
55104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
56104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
57ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh	def parse_config_file(self):
58ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh		dirname = os.path.dirname(sys.modules[__name__].__file__)
59ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh		root = os.path.abspath(os.path.join(dirname, "../../"))
60ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh		config_file = os.path.join(root, "global_config.ini")
61ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh		self.config = ConfigParser.ConfigParser()
62ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh		self.config.read(config_file)
63ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh
64104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		# now also read the shadow file if there is one
65104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		# this will overwrite anything that is found in the
66104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		# other config
67104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		config_file = os.path.join(root, "shadow_config.ini")
68104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		if os.path.exists(config_file):
69104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			shadow_config = ConfigParser.ConfigParser()
70104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			shadow_config.read(config_file)
71104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			# now we merge shadow into global
72104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			self.merge_configs(shadow_config)
73104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
74104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
75104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh	# the values that are pulled from ini
76104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh	# are strings.  But we should attempt to
77104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh	# convert them to other types if needed.
78104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh	def convert_value(self, key, section, value, type, default):
79104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		# strip off leading and trailing white space
80104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		sval = value.strip()
81104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
82104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		# if length of string is zero then return None
83104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		if len(sval) == 0:
84104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			if type == str:
85104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh				return ""
86104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			elif type == bool:
87104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh				return False
88104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			elif type == int:
89104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh				return 0
90104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			elif type == float:
91104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh				return 0.0
92104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			else:
93104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh				return None
94104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
95104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		if type == bool:
96104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			if sval.lower() == "false":
97104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh				return False
98104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			else:
99104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh				return True
100104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
101104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		try:
102104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			conv_val = type(sval)
103104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			return conv_val
104104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh		except:
105104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			msg = ("Could not covert %s in section %s" %
106104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh				(key, section))
107104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh			raise ConfigValueError(msg)
108104e9ce7a74041fd673ceac5c8b0bc67c74edcd5mbligh
109ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh
110ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh# insure the class is a singleton.  Now the symbol global_config
111ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mbligh# will point to the one and only one instace of the class
112ed4d6ddc79993492b22aeeb36574b3cb7c8bad44mblighglobal_config = global_config()
113