blob: 60ffbbc13a8ec0988e5a4033dd57b526fce477fe [file] [log] [blame]
gstepanov023c1e42015-04-08 15:50:19 +03001import os
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08002import sys
koder aka kdanilov2c473092015-03-29 17:12:13 +03003import Queue
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08004import pprint
koder aka kdanilove21d7472015-02-14 19:02:04 -08005import logging
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08006import argparse
koder aka kdanilov2c473092015-03-29 17:12:13 +03007import threading
8import collections
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08009
koder aka kdanilov66839a92015-04-11 13:22:31 +030010import yaml
koder aka kdanilov2c473092015-03-29 17:12:13 +030011from concurrent.futures import ThreadPoolExecutor
koder aka kdanilov6c491062015-04-09 22:33:13 +030012
koder aka kdanilov2c473092015-03-29 17:12:13 +030013import utils
koder aka kdanilov66839a92015-04-11 13:22:31 +030014import report
koder aka kdanilove06762a2015-03-22 23:32:09 +020015import ssh_utils
koder aka kdanilovda45e882015-04-06 02:24:42 +030016import start_vms
koder aka kdanilov66839a92015-04-11 13:22:31 +030017import pretty_yaml
koder aka kdanilove06762a2015-03-22 23:32:09 +020018from nodes import discover
koder aka kdanilov2c473092015-03-29 17:12:13 +030019from nodes.node import Node
koder aka kdanilov66839a92015-04-11 13:22:31 +030020from config import cfg_dict, load_config
koder aka kdanilov2c473092015-03-29 17:12:13 +030021from sensors.api import start_monitoring
koder aka kdanilov652cd802015-04-13 12:21:07 +030022from tests.itest import IOPerfTest, PgBenchTest
koder aka kdanilov66839a92015-04-11 13:22:31 +030023from formatters import format_results_for_console
koder aka kdanilov2c473092015-03-29 17:12:13 +030024
25
koder aka kdanilove21d7472015-02-14 19:02:04 -080026logger = logging.getLogger("io-perf-tool")
koder aka kdanilove21d7472015-02-14 19:02:04 -080027
28
koder aka kdanilov652cd802015-04-13 12:21:07 +030029def color_me(color):
30 RESET_SEQ = "\033[0m"
31 COLOR_SEQ = "\033[1;%dm"
32
33 color_seq = COLOR_SEQ % (30 + color)
34
35 def closure(msg):
36 return color_seq + msg + RESET_SEQ
37 return closure
38
39
40class ColoredFormatter(logging.Formatter):
41 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
42
43 colors = {
44 'WARNING': color_me(YELLOW),
45 'DEBUG': color_me(BLUE),
46 'CRITICAL': color_me(YELLOW),
47 'ERROR': color_me(RED)
48 }
49
50 def __init__(self, msg, use_color=True):
51 logging.Formatter.__init__(self, msg)
52 self.use_color = use_color
53
54 def format(self, record):
55 levelname = record.levelname
56
57 if levelname in self.colors:
58 record.levelname = self.colors[levelname](levelname)
59
60 return logging.Formatter.format(self, record)
61
62
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030063def setup_logger(logger, level=logging.DEBUG, log_fname=None):
koder aka kdanilov652cd802015-04-13 12:21:07 +030064 logger.setLevel(logging.DEBUG)
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030065 sh = logging.StreamHandler()
66 sh.setLevel(level)
Yulia Portnova7ddfa732015-02-24 17:32:58 +020067
koder aka kdanilov2c473092015-03-29 17:12:13 +030068 log_format = '%(asctime)s - %(levelname)-6s - %(name)s - %(message)s'
koder aka kdanilov652cd802015-04-13 12:21:07 +030069 colored_formatter = ColoredFormatter(log_format,
70 "%H:%M:%S")
71
koder aka kdanilov2c473092015-03-29 17:12:13 +030072 formatter = logging.Formatter(log_format,
73 "%H:%M:%S")
koder aka kdanilov652cd802015-04-13 12:21:07 +030074 sh.setFormatter(colored_formatter)
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030075 logger.addHandler(sh)
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080076
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030077 if log_fname is not None:
78 fh = logging.FileHandler(log_fname)
koder aka kdanilov652cd802015-04-13 12:21:07 +030079 fh.setFormatter(formatter)
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030080 fh.setLevel(logging.DEBUG)
81 logger.addHandler(fh)
koder aka kdanilov6c491062015-04-09 22:33:13 +030082
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080083
Yulia Portnova7ddfa732015-02-24 17:32:58 +020084def format_result(res, formatter):
koder aka kdanilove21d7472015-02-14 19:02:04 -080085 data = "\n{0}\n".format("=" * 80)
86 data += pprint.pformat(res) + "\n"
87 data += "{0}\n".format("=" * 80)
koder aka kdanilovfe056622015-02-19 08:46:15 -080088 templ = "{0}\n\n====> {1}\n\n{2}\n\n"
Yulia Portnova7ddfa732015-02-24 17:32:58 +020089 return templ.format(data, formatter(res), "=" * 80)
koder aka kdanilove21d7472015-02-14 19:02:04 -080090
91
koder aka kdanilov1c2b5112015-04-10 16:53:51 +030092class Context(object):
93 def __init__(self):
94 self.build_meta = {}
95 self.nodes = []
96 self.clear_calls_stack = []
97 self.openstack_nodes_ids = []
98
99
koder aka kdanilov5d589b42015-03-26 12:25:51 +0200100def connect_one(node):
101 try:
koder aka kdanilov2c473092015-03-29 17:12:13 +0300102 ssh_pref = "ssh://"
103 if node.conn_url.startswith(ssh_pref):
104 url = node.conn_url[len(ssh_pref):]
105 node.connection = ssh_utils.connect(url)
106 else:
107 raise ValueError("Unknown url type {0}".format(node.conn_url))
koder aka kdanilov3a6633e2015-03-26 18:20:00 +0200108 except Exception:
koder aka kdanilov2c473092015-03-29 17:12:13 +0300109 logger.exception("During connect to {0}".format(node))
koder aka kdanilov652cd802015-04-13 12:21:07 +0300110 raise
koder aka kdanilov5d589b42015-03-26 12:25:51 +0200111
112
113def connect_all(nodes):
koder aka kdanilov2c473092015-03-29 17:12:13 +0300114 logger.info("Connecting to nodes")
115 with ThreadPoolExecutor(32) as pool:
116 list(pool.map(connect_one, nodes))
koder aka kdanilovda45e882015-04-06 02:24:42 +0300117 logger.info("All nodes connected successfully")
koder aka kdanilov2c473092015-03-29 17:12:13 +0300118
119
120def save_sensors_data(q):
121 logger.info("Start receiving sensors data")
koder aka kdanilovda45e882015-04-06 02:24:42 +0300122 sensor_data = []
koder aka kdanilov2c473092015-03-29 17:12:13 +0300123 while True:
124 val = q.get()
125 if val is None:
koder aka kdanilovda45e882015-04-06 02:24:42 +0300126 q.put(sensor_data)
koder aka kdanilov2c473092015-03-29 17:12:13 +0300127 break
koder aka kdanilovda45e882015-04-06 02:24:42 +0300128 sensor_data.append(val)
koder aka kdanilov2c473092015-03-29 17:12:13 +0300129 logger.info("Sensors thread exits")
130
131
koder aka kdanilov652cd802015-04-13 12:21:07 +0300132def test_thread(test, node, barrier, res_q):
koder aka kdanilov2c473092015-03-29 17:12:13 +0300133 try:
134 logger.debug("Run preparation for {0}".format(node.conn_url))
135 test.pre_run(node.connection)
136 logger.debug("Run test for {0}".format(node.conn_url))
137 test.run(node.connection, barrier)
koder aka kdanilov652cd802015-04-13 12:21:07 +0300138 except Exception as exc:
koder aka kdanilov2c473092015-03-29 17:12:13 +0300139 logger.exception("In test {0} for node {1}".format(test, node))
koder aka kdanilov652cd802015-04-13 12:21:07 +0300140 res_q.put(exc)
koder aka kdanilov2c473092015-03-29 17:12:13 +0300141
142
143def run_tests(config, nodes):
144 tool_type_mapper = {
145 "io": IOPerfTest,
146 "pgbench": PgBenchTest,
147 }
148
149 test_nodes = [node for node in nodes
150 if 'testnode' in node.roles]
151
152 res_q = Queue.Queue()
153
koder aka kdanilov652cd802015-04-13 12:21:07 +0300154 for test_block in config:
155 for name, params in test_block.items():
156 logger.info("Starting {0} tests".format(name))
koder aka kdanilov2c473092015-03-29 17:12:13 +0300157
koder aka kdanilov652cd802015-04-13 12:21:07 +0300158 threads = []
159 barrier = utils.Barrier(len(test_nodes))
160 for node in test_nodes:
161 msg = "Starting {0} test on {1} node"
162 logger.debug(msg.format(name, node.conn_url))
163 test = tool_type_mapper[name](params, res_q.put)
164 th = threading.Thread(None, test_thread, None,
165 (test, node, barrier, res_q))
166 threads.append(th)
167 th.daemon = True
168 th.start()
koder aka kdanilov2c473092015-03-29 17:12:13 +0300169
koder aka kdanilov652cd802015-04-13 12:21:07 +0300170 def gather_results(res_q, results):
gstepanov023c1e42015-04-08 15:50:19 +0300171 while not res_q.empty():
koder aka kdanilov652cd802015-04-13 12:21:07 +0300172 val = res_q.get()
koder aka kdanilov66839a92015-04-11 13:22:31 +0300173
koder aka kdanilov652cd802015-04-13 12:21:07 +0300174 if isinstance(val, Exception):
175 msg = "Exception during test execution: {0}"
176 raise ValueError(msg.format(val.message))
177
178 results.append(val)
179
180 results = []
181
182 while True:
183 for th in threads:
184 th.join(1)
185 gather_results(res_q, results)
186
187 if all(not th.is_alive() for th in threads):
188 break
189
190 gather_results(res_q, results)
191 yield name, test.merge_results(results)
koder aka kdanilov2c473092015-03-29 17:12:13 +0300192
193
194def parse_args(argv):
195 parser = argparse.ArgumentParser(
196 description="Run disk io performance test")
197
198 parser.add_argument("-l", dest='extra_logs',
199 action='store_true', default=False,
200 help="print some extra log info")
201
gstepanov4861d712015-04-09 13:28:02 +0300202 parser.add_argument("-b", '--build_description',
203 type=str, default="Build info")
gstepanovaffcdb12015-04-07 17:18:29 +0300204 parser.add_argument("-i", '--build_id', type=str, default="id")
205 parser.add_argument("-t", '--build_type', type=str, default="GA")
206 parser.add_argument("-u", '--username', type=str, default="admin")
koder aka kdanilov66839a92015-04-11 13:22:31 +0300207 parser.add_argument("-p", '--post-process-only', default=None)
koder aka kdanilovda45e882015-04-06 02:24:42 +0300208 parser.add_argument("-o", '--output-dest', nargs="*")
209 parser.add_argument("config_file", nargs="?", default="config.yaml")
koder aka kdanilov2c473092015-03-29 17:12:13 +0300210
211 return parser.parse_args(argv[1:])
212
213
koder aka kdanilovda45e882015-04-06 02:24:42 +0300214def log_nodes_statistic(_, ctx):
215 nodes = ctx.nodes
koder aka kdanilov2c473092015-03-29 17:12:13 +0300216 logger.info("Found {0} nodes total".format(len(nodes)))
217 per_role = collections.defaultdict(lambda: 0)
218 for node in nodes:
219 for role in node.roles:
220 per_role[role] += 1
221
222 for role, count in sorted(per_role.items()):
223 logger.debug("Found {0} nodes with role {1}".format(count, role))
224
225
226def log_sensors_config(cfg):
koder aka kdanilov5d589b42015-03-26 12:25:51 +0200227 pass
228
229
koder aka kdanilovda45e882015-04-06 02:24:42 +0300230def connect_stage(cfg, ctx):
231 ctx.clear_calls_stack.append(disconnect_stage)
232 connect_all(ctx.nodes)
233
234
235def discover_stage(cfg, ctx):
koder aka kdanilov652cd802015-04-13 12:21:07 +0300236 if cfg.get('discover') is not None:
koder aka kdanilovda45e882015-04-06 02:24:42 +0300237 discover_objs = [i.strip() for i in cfg['discover'].strip().split(",")]
238 ctx.nodes.extend(discover.discover(discover_objs, cfg['clouds']))
239
240 for url, roles in cfg.get('explicit_nodes', {}).items():
241 ctx.nodes.append(Node(url, roles.split(",")))
242
243
244def deploy_sensors_stage(cfg_dict, ctx):
koder aka kdanilovda45e882015-04-06 02:24:42 +0300245 if 'sensors' not in cfg_dict:
246 return
247
koder aka kdanilov652cd802015-04-13 12:21:07 +0300248 ctx.clear_calls_stack.append(remove_sensors_stage)
koder aka kdanilovda45e882015-04-06 02:24:42 +0300249 cfg = cfg_dict.get('sensors')
250 sens_cfg = []
251
252 for role, sensors_str in cfg["roles_mapping"].items():
253 sensors = [sens.strip() for sens in sensors_str.split(",")]
254
255 collect_cfg = dict((sensor, {}) for sensor in sensors)
256
257 for node in ctx.nodes:
258 if role in node.roles:
259 sens_cfg.append((node.connection, collect_cfg))
260
261 log_sensors_config(sens_cfg)
262
263 ctx.sensor_cm = start_monitoring(cfg["receiver_uri"], None,
264 connected_config=sens_cfg)
265
266 ctx.sensors_control_queue = ctx.sensor_cm.__enter__()
267
268 th = threading.Thread(None, save_sensors_data, None,
269 (ctx.sensors_control_queue,))
270 th.daemon = True
271 th.start()
272 ctx.sensor_listen_thread = th
273
274
275def remove_sensors_stage(cfg, ctx):
276 ctx.sensors_control_queue.put(None)
277 ctx.sensor_listen_thread.join()
278 ctx.sensor_data = ctx.sensors_control_queue.get()
279
280
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300281def run_all_test(cfg, ctx):
koder aka kdanilovda45e882015-04-06 02:24:42 +0300282 ctx.results = []
283
gstepanov023c1e42015-04-08 15:50:19 +0300284 if 'start_test_nodes' in cfg['tests']:
285 params = cfg['tests']['start_test_nodes']['openstack']
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300286 os_nodes_ids = []
koder aka kdanilov6c491062015-04-09 22:33:13 +0300287
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300288 os_creds = params['creds']
289
290 if os_creds == 'fuel':
291 raise NotImplementedError()
292
293 elif os_creds == 'clouds':
294 os_cfg = cfg['clouds']['openstack']
295 tenant = os_cfg['OS_TENANT_NAME'].strip()
296 user = os_cfg['OS_USERNAME'].strip()
297 passwd = os_cfg['OS_PASSWORD'].strip()
298 auth_url = os_cfg['OS_AUTH_URL'].strip()
299
300 elif os_creds == 'ENV':
301 tenant = None
302 user = None
303 passwd = None
304 auth_url = None
305
306 else:
307 raise ValueError("Only 'ENV' creds are supported")
308
309 start_vms.nova_connect(user, passwd, tenant, auth_url)
310
311 new_nodes = []
312 for new_node, node_id in start_vms.launch_vms(params):
313 new_node.roles.append('testnode')
314 ctx.nodes.append(new_node)
315 os_nodes_ids.append(node_id)
316 new_nodes.append(new_node)
317
koder aka kdanilov66839a92015-04-11 13:22:31 +0300318 store_nodes_in_log(cfg, os_nodes_ids)
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300319 ctx.openstack_nodes_ids = os_nodes_ids
320
321 connect_all(new_nodes)
gstepanov023c1e42015-04-08 15:50:19 +0300322
koder aka kdanilovda45e882015-04-06 02:24:42 +0300323 if 'tests' in cfg:
koder aka kdanilov652cd802015-04-13 12:21:07 +0300324 ctx.results.extend(run_tests(cfg['tests'], ctx.nodes))
koder aka kdanilovda45e882015-04-06 02:24:42 +0300325
gstepanov023c1e42015-04-08 15:50:19 +0300326
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300327def shut_down_vms_stage(cfg, ctx):
koder aka kdanilov66839a92015-04-11 13:22:31 +0300328 vm_ids_fname = cfg_dict['vm_ids_fname']
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300329 if ctx.openstack_nodes_ids is None:
koder aka kdanilov66839a92015-04-11 13:22:31 +0300330 nodes_ids = open(vm_ids_fname).read().split()
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300331 else:
332 nodes_ids = ctx.openstack_nodes_ids
333
koder aka kdanilov652cd802015-04-13 12:21:07 +0300334 if len(nodes_ids) != 0:
335 logger.info("Removing nodes")
336 start_vms.clear_nodes(nodes_ids)
337 logger.info("Nodes has been removed")
gstepanov023c1e42015-04-08 15:50:19 +0300338
koder aka kdanilov66839a92015-04-11 13:22:31 +0300339 if os.path.exists(vm_ids_fname):
340 os.remove(vm_ids_fname)
gstepanov023c1e42015-04-08 15:50:19 +0300341
koder aka kdanilov66839a92015-04-11 13:22:31 +0300342
343def store_nodes_in_log(cfg, nodes_ids):
344 with open(cfg['vm_ids_fname'], 'w') as fd:
345 fd.write("\n".join(nodes_ids))
gstepanov023c1e42015-04-08 15:50:19 +0300346
347
348def clear_enviroment(cfg, ctx):
koder aka kdanilov66839a92015-04-11 13:22:31 +0300349 if os.path.exists(cfg_dict['vm_ids_fname']):
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300350 shut_down_vms_stage(cfg, ctx)
gstepanov023c1e42015-04-08 15:50:19 +0300351
352
353def run_tests_stage(cfg, ctx):
354 # clear nodes that possible were created on previous test running
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300355 # clear_enviroment(cfg, ctx) << fix OS connection
356 ctx.clear_calls_stack.append(shut_down_vms_stage)
357 run_all_test(cfg, ctx)
koder aka kdanilovda45e882015-04-06 02:24:42 +0300358
359
360def disconnect_stage(cfg, ctx):
koder aka kdanilov652cd802015-04-13 12:21:07 +0300361 ssh_utils.close_all_sessions()
362
koder aka kdanilovda45e882015-04-06 02:24:42 +0300363 for node in ctx.nodes:
364 if node.connection is not None:
365 node.connection.close()
366
367
koder aka kdanilov66839a92015-04-11 13:22:31 +0300368def yamable(data):
369 if isinstance(data, (tuple, list)):
370 return map(yamable, data)
371
372 if isinstance(data, unicode):
373 return str(data)
374
375 if isinstance(data, dict):
376 res = {}
377 for k, v in data.items():
378 res[yamable(k)] = yamable(v)
379 return res
380
381 return data
382
383
384def store_raw_results_stage(cfg, ctx):
385
386 raw_results = os.path.join(cfg_dict['var_dir'], 'raw_results.yaml')
387
388 if os.path.exists(raw_results):
389 cont = yaml.load(open(raw_results).read())
390 else:
391 cont = []
392
393 cont.extend(yamable(ctx.results))
394 raw_data = pretty_yaml.dumps(cont)
395
396 with open(raw_results, "w") as fd:
397 fd.write(raw_data)
398
399
400def console_report_stage(cfg, ctx):
401 for tp, data in ctx.results:
402 if 'io' == tp:
403 print format_results_for_console(data)
404
405
koder aka kdanilovda45e882015-04-06 02:24:42 +0300406def report_stage(cfg, ctx):
koder aka kdanilov652cd802015-04-13 12:21:07 +0300407 # html_report = report.make_io_report(ctx.results)
408 # html_rep_fname = cfg['html_report_file']
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300409
koder aka kdanilov652cd802015-04-13 12:21:07 +0300410 # with open(html_rep_fname, "w") as fd:
411 # fd.write(html_report)
412
413 # logger.info("Html report were stored in " + html_rep_fname)
414
415 text_rep_fname = cfg_dict['text_report_file']
416 with open(text_rep_fname, "w") as fd:
417 for tp, data in ctx.results:
418 if 'io' == tp:
419 fd.write(format_results_for_console(data))
420 fd.write("\n")
421 fd.flush()
422
423 logger.info("Text report were stored in " + text_rep_fname)
koder aka kdanilovda45e882015-04-06 02:24:42 +0300424
425
426def complete_log_nodes_statistic(cfg, ctx):
427 nodes = ctx.nodes
428 for node in nodes:
429 logger.debug(str(node))
430
431
koder aka kdanilov66839a92015-04-11 13:22:31 +0300432def load_data_from(var_dir):
433 def closure(cfg, ctx):
434 raw_results = os.path.join(var_dir, 'raw_results.yaml')
435 ctx.results = yaml.load(open(raw_results).read())
436 return closure
gstepanovcd256d62015-04-07 17:47:32 +0300437
438
koder aka kdanilov3f356262015-02-13 08:06:14 -0800439def main(argv):
koder aka kdanilove06762a2015-03-22 23:32:09 +0200440 opts = parse_args(argv)
koder aka kdanilov2c473092015-03-29 17:12:13 +0300441
koder aka kdanilov66839a92015-04-11 13:22:31 +0300442 if opts.post_process_only is not None:
443 stages = [
444 load_data_from(opts.post_process_only),
445 console_report_stage,
koder aka kdanilov652cd802015-04-13 12:21:07 +0300446 report_stage
koder aka kdanilov66839a92015-04-11 13:22:31 +0300447 ]
448 else:
449 stages = [
450 discover_stage,
451 log_nodes_statistic,
koder aka kdanilov66839a92015-04-11 13:22:31 +0300452 connect_stage,
koder aka kdanilov66839a92015-04-11 13:22:31 +0300453 deploy_sensors_stage,
454 run_tests_stage,
455 store_raw_results_stage,
456 console_report_stage,
457 report_stage
458 ]
459
gstepanovcd256d62015-04-07 17:47:32 +0300460 load_config(opts.config_file)
koder aka kdanilovf4b82c22015-04-11 13:35:25 +0300461
462 level = logging.DEBUG if opts.extra_logs else logging.WARNING
463 setup_logger(logger, level, cfg_dict['log_file'])
464
koder aka kdanilov652cd802015-04-13 12:21:07 +0300465 logger.info("All info would be stored into {0}".format(
466 cfg_dict['var_dir']))
gstepanovcd256d62015-04-07 17:47:32 +0300467
koder aka kdanilovda45e882015-04-06 02:24:42 +0300468 ctx = Context()
gstepanovaffcdb12015-04-07 17:18:29 +0300469 ctx.build_meta['build_id'] = opts.build_id
470 ctx.build_meta['build_descrption'] = opts.build_description
471 ctx.build_meta['build_type'] = opts.build_type
472 ctx.build_meta['username'] = opts.username
koder aka kdanilov6c491062015-04-09 22:33:13 +0300473
koder aka kdanilovda45e882015-04-06 02:24:42 +0300474 try:
475 for stage in stages:
476 logger.info("Start {0.__name__} stage".format(stage))
477 stage(cfg_dict, ctx)
478 finally:
479 exc, cls, tb = sys.exc_info()
480 for stage in ctx.clear_calls_stack[::-1]:
481 try:
482 logger.info("Start {0.__name__} stage".format(stage))
483 stage(cfg_dict, ctx)
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300484 except Exception as exc:
485 logger.exception("During {0.__name__} stage".format(stage))
koder aka kdanilov2c473092015-03-29 17:12:13 +0300486
koder aka kdanilovda45e882015-04-06 02:24:42 +0300487 if exc is not None:
488 raise exc, cls, tb
koder aka kdanilov2c473092015-03-29 17:12:13 +0300489
koder aka kdanilov652cd802015-04-13 12:21:07 +0300490 logger.info("All info stotored into {0}".format(cfg_dict['var_dir']))
koder aka kdanilove06762a2015-03-22 23:32:09 +0200491 return 0
koder aka kdanilov3f356262015-02-13 08:06:14 -0800492
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800493
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800494if __name__ == '__main__':
koder aka kdanilove06762a2015-03-22 23:32:09 +0200495 exit(main(sys.argv))