KVM test: Add helpers to control the TAP/bridge
[autotest-zwu.git] / client / common_lib / global_config.py
blob24a93ea13becef1131f4e580f19aa8290007dfdd
1 """A singleton class for accessing global config values
3 provides access to global configuration file
4 """
6 __author__ = 'raphtee@google.com (Travis Miller)'
8 import os, sys, ConfigParser, logging
9 from autotest_lib.client.common_lib import error
12 class ConfigError(error.AutotestError):
13 pass
16 class ConfigValueError(ConfigError):
17 pass
21 common_lib_dir = os.path.dirname(sys.modules[__name__].__file__)
22 client_dir = os.path.dirname(common_lib_dir)
23 root_dir = os.path.dirname(client_dir)
25 # Check if the config files are at autotest's root dir
26 # This will happen if client is executing inside a full autotest tree, or if
27 # other entry points are being executed
28 global_config_path_root = os.path.join(root_dir, 'global_config.ini')
29 shadow_config_path_root = os.path.join(root_dir, 'shadow_config.ini')
30 config_in_root = (os.path.exists(global_config_path_root) and
31 os.path.exists(shadow_config_path_root))
33 # Check if the config files are at autotest's client dir
34 # This will happen if a client stand alone execution is happening
35 global_config_path_client = os.path.join(client_dir, 'global_config.ini')
36 config_in_client = os.path.exists(global_config_path_client)
38 if config_in_root:
39 DEFAULT_CONFIG_FILE = global_config_path_root
40 DEFAULT_SHADOW_FILE = shadow_config_path_root
41 RUNNING_STAND_ALONE_CLIENT = False
42 elif config_in_client:
43 DEFAULT_CONFIG_FILE = global_config_path_client
44 DEFAULT_SHADOW_FILE = None
45 RUNNING_STAND_ALONE_CLIENT = True
46 else:
47 DEFAULT_CONFIG_FILE = None
48 DEFAULT_SHADOW_FILE = None
49 RUNNING_STAND_ALONE_CLIENT = True
51 class global_config(object):
52 _NO_DEFAULT_SPECIFIED = object()
54 config = None
55 config_file = DEFAULT_CONFIG_FILE
56 shadow_file = DEFAULT_SHADOW_FILE
57 running_stand_alone_client = RUNNING_STAND_ALONE_CLIENT
60 def check_stand_alone_client_run(self):
61 return self.running_stand_alone_client
64 def set_config_files(self, config_file=DEFAULT_CONFIG_FILE,
65 shadow_file=DEFAULT_SHADOW_FILE):
66 self.config_file = config_file
67 self.shadow_file = shadow_file
68 self.config = None
71 def _handle_no_value(self, section, key, default):
72 if default is self._NO_DEFAULT_SPECIFIED:
73 msg = ("Value '%s' not found in section '%s'" %
74 (key, section))
75 raise ConfigError(msg)
76 else:
77 return default
80 def get_section_values(self, section):
81 """
82 Return a config parser object containing a single section of the
83 global configuration, that can be later written to a file object.
85 @param section: Section we want to turn into a config parser object.
86 @return: ConfigParser() object containing all the contents of section.
87 """
88 cfgparser = ConfigParser.ConfigParser()
89 cfgparser.add_section(section)
90 for option, value in self.config.items(section):
91 cfgparser.set(section, option, value)
92 return cfgparser
95 def get_config_value(self, section, key, type=str,
96 default=_NO_DEFAULT_SPECIFIED, allow_blank=False):
97 self._ensure_config_parsed()
99 try:
100 val = self.config.get(section, key)
101 except ConfigParser.Error:
102 return self._handle_no_value(section, key, default)
104 if not val.strip() and not allow_blank:
105 return self._handle_no_value(section, key, default)
107 return self._convert_value(key, section, val, type)
110 def override_config_value(self, section, key, new_value):
112 Override a value from the config file with a new value.
114 self._ensure_config_parsed()
115 self.config.set(section, key, new_value)
118 def reset_config_values(self):
120 Reset all values to those found in the config files (undoes all
121 overrides).
123 self.parse_config_file()
126 def _ensure_config_parsed(self):
127 if self.config is None:
128 self.parse_config_file()
131 def merge_configs(self, shadow_config):
132 # overwrite whats in config with whats in shadow_config
133 sections = shadow_config.sections()
134 for section in sections:
135 # add the section if need be
136 if not self.config.has_section(section):
137 self.config.add_section(section)
138 # now run through all options and set them
139 options = shadow_config.options(section)
140 for option in options:
141 val = shadow_config.get(section, option)
142 self.config.set(section, option, val)
145 def parse_config_file(self):
146 self.config = ConfigParser.ConfigParser()
147 if self.config_file and os.path.exists(self.config_file):
148 self.config.read(self.config_file)
149 else:
150 raise ConfigError('%s not found' % (self.config_file))
152 # now also read the shadow file if there is one
153 # this will overwrite anything that is found in the
154 # other config
155 if self.shadow_file and os.path.exists(self.shadow_file):
156 shadow_config = ConfigParser.ConfigParser()
157 shadow_config.read(self.shadow_file)
158 # now we merge shadow into global
159 self.merge_configs(shadow_config)
162 # the values that are pulled from ini
163 # are strings. But we should attempt to
164 # convert them to other types if needed.
165 def _convert_value(self, key, section, value, value_type):
166 # strip off leading and trailing white space
167 sval = value.strip()
169 # if length of string is zero then return None
170 if len(sval) == 0:
171 if value_type == str:
172 return ""
173 elif value_type == bool:
174 return False
175 elif value_type == int:
176 return 0
177 elif value_type == float:
178 return 0.0
179 elif value_type == list:
180 return []
181 else:
182 return None
184 if value_type == bool:
185 if sval.lower() == "false":
186 return False
187 else:
188 return True
190 if value_type == list:
191 # Split the string using ',' and return a list
192 return [val.strip() for val in sval.split(',')]
194 try:
195 conv_val = value_type(sval)
196 return conv_val
197 except:
198 msg = ("Could not convert %s value %r in section %s to type %s" %
199 (key, sval, section, value_type))
200 raise ConfigValueError(msg)
203 # insure the class is a singleton. Now the symbol global_config
204 # will point to the one and only one instace of the class
205 global_config = global_config()