blob: c760509208d7dabb1b6597d93cede52a1c11182c [file] [log] [blame]
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +03001import os
2import uuid
3import logging
4import functools
5
6import yaml
7
8try:
9 from petname import Generate as pet_generate
10except ImportError:
11 def pet_generate(x, y):
12 return str(uuid.uuid4())
13
koder aka kdanilov88407ff2015-05-26 15:35:57 +030014import pretty_yaml
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030015
16cfg_dict = {}
17
18
koder aka kdanilovfd2cfa52015-05-20 03:17:42 +030019class NoData(object):
20 @classmethod
21 def get(cls, name, x):
22 return cls
23
24
25class Config(object):
26 def get(self, name, defval=None):
27 obj = self.__dict__
28 for cname in name.split("."):
29 obj = obj.get(cname, NoData)
30
31 if obj is NoData:
32 return defval
33 return obj
34
35
36cfg = Config()
37cfg.__dict__ = cfg_dict
38
39
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030040def mkdirs_if_unxists(path):
41 if not os.path.exists(path):
42 os.makedirs(path)
43
44
koder aka kdanilovfd2cfa52015-05-20 03:17:42 +030045def get_test_files(results_dir):
46 in_var_dir = functools.partial(os.path.join, results_dir)
47
48 res = dict(
49 run_params_file='run_params.yaml',
50 saved_config_file='config.yaml',
51 vm_ids_fname='os_vm_ids',
52 html_report_file='{0}_report.html',
koder aka kdanilov88407ff2015-05-26 15:35:57 +030053 load_report_file='load_report.html',
koder aka kdanilovfd2cfa52015-05-20 03:17:42 +030054 text_report_file='report.txt',
55 log_file='log.txt',
56 sensor_storage='sensor_storage',
57 nodes_report_file='nodes.yaml',
58 results='results',
59 hwinfo_directory='hwinfo',
60 hwreport_fname='hwinfo.txt',
61 raw_results='raw_results.yaml')
62
63 res = dict((k, in_var_dir(v)) for k, v in res.items())
64 res['var_dir'] = results_dir
65 return res
66
67
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030068def load_config(file_name, explicit_folder=None):
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030069 cfg_dict.update(yaml.load(open(file_name).read()))
70
koder aka kdanilovfd2cfa52015-05-20 03:17:42 +030071 var_dir = cfg_dict.get('internal', {}).get('var_dir_root', '/tmp')
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030072 run_uuid = None
koder aka kdanilov88407ff2015-05-26 15:35:57 +030073
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030074 if explicit_folder is None:
75 for i in range(10):
76 run_uuid = pet_generate(2, "_")
77 results_dir = os.path.join(var_dir, run_uuid)
78 if not os.path.exists(results_dir):
79 break
80 else:
81 run_uuid = str(uuid.uuid4())
82 results_dir = os.path.join(var_dir, run_uuid)
koder aka kdanilov4a510ee2015-04-21 18:50:42 +030083 cfg_dict['run_uuid'] = run_uuid.replace('_', '-')
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030084 else:
koder aka kdanilov88407ff2015-05-26 15:35:57 +030085 if not os.path.isdir(explicit_folder):
86 ex2 = os.path.join(var_dir, explicit_folder)
87 if os.path.isdir(ex2):
88 explicit_folder = ex2
89 else:
90 raise RuntimeError("No such directory " + explicit_folder)
91
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030092 results_dir = explicit_folder
93
koder aka kdanilovfd2cfa52015-05-20 03:17:42 +030094 cfg_dict.update(get_test_files(results_dir))
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030095 mkdirs_if_unxists(cfg_dict['var_dir'])
96
koder aka kdanilov57ce4db2015-04-25 21:25:51 +030097 if explicit_folder is not None:
koder aka kdanilov88407ff2015-05-26 15:35:57 +030098 cfg_dict.update(load_run_params(cfg_dict['run_params_file']))
koder aka kdanilov57ce4db2015-04-25 21:25:51 +030099 run_uuid = cfg_dict['run_uuid']
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300100
koder aka kdanilov4af1c1d2015-05-18 15:48:58 +0300101 mkdirs_if_unxists(cfg_dict['sensor_storage'])
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300102
koder aka kdanilov4af1c1d2015-05-18 15:48:58 +0300103 if 'sensors_remote_path' not in cfg_dict:
104 cfg_dict['sensors_remote_path'] = '/tmp/sensors'
105
koder aka kdanilovafd98742015-04-24 01:27:22 +0300106 testnode_log_root = cfg_dict.get('testnode_log_root', '/var/wally')
107 testnode_log_dir = os.path.join(testnode_log_root, "{0}/{{name}}")
koder aka kdanilov2066daf2015-04-23 21:05:41 +0300108 cfg_dict['default_test_local_folder'] = \
koder aka kdanilovafd98742015-04-24 01:27:22 +0300109 testnode_log_dir.format(cfg_dict['run_uuid'])
koder aka kdanilov2066daf2015-04-23 21:05:41 +0300110
koder aka kdanilovfd2cfa52015-05-20 03:17:42 +0300111 mkdirs_if_unxists(cfg_dict['results'])
koder aka kdanilovf86d7af2015-05-06 04:01:54 +0300112 mkdirs_if_unxists(cfg_dict['hwinfo_directory'])
113
koder aka kdanilov88407ff2015-05-26 15:35:57 +0300114 return results_dir
115
116
117def save_run_params():
118 params = {
119 'comment': cfg_dict['comment'],
120 'run_uuid': cfg_dict['run_uuid']
121 }
122 with open(cfg_dict['run_params_file'], 'w') as fd:
123 fd.write(pretty_yaml.dumps(params))
124
125
126def load_run_params(run_params_file):
127 with open(run_params_file) as fd:
128 dt = yaml.load(fd)
129
130 return dict(run_uuid=dt['run_uuid'],
131 comment=dt.get('comment'))
132
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300133
134def color_me(color):
135 RESET_SEQ = "\033[0m"
136 COLOR_SEQ = "\033[1;%dm"
137
138 color_seq = COLOR_SEQ % (30 + color)
139
140 def closure(msg):
141 return color_seq + msg + RESET_SEQ
142 return closure
143
144
145class ColoredFormatter(logging.Formatter):
146 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
147
148 colors = {
149 'WARNING': color_me(YELLOW),
150 'DEBUG': color_me(BLUE),
151 'CRITICAL': color_me(YELLOW),
152 'ERROR': color_me(RED)
153 }
154
155 def __init__(self, msg, use_color=True, datefmt=None):
156 logging.Formatter.__init__(self, msg, datefmt=datefmt)
157 self.use_color = use_color
158
159 def format(self, record):
160 orig = record.__dict__
161 record.__dict__ = record.__dict__.copy()
162 levelname = record.levelname
163
164 prn_name = levelname + ' ' * (8 - len(levelname))
165 if levelname in self.colors:
166 record.levelname = self.colors[levelname](prn_name)
167 else:
168 record.levelname = prn_name
169
koder aka kdanilov6b1341a2015-04-21 22:44:21 +0300170 # super doesn't work here in 2.6 O_o
171 res = logging.Formatter.format(self, record)
172
173 # res = super(ColoredFormatter, self).format(record)
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300174
175 # restore record, as it will be used by other formatters
176 record.__dict__ = orig
177 return res
178
179
180def setup_loggers(def_level=logging.DEBUG, log_fname=None):
181 logger = logging.getLogger('wally')
182 logger.setLevel(logging.DEBUG)
183 sh = logging.StreamHandler()
184 sh.setLevel(def_level)
185
koder aka kdanilov168f6092015-04-19 02:33:38 +0300186 log_format = '%(asctime)s - %(levelname)s - %(name)-15s - %(message)s'
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300187 colored_formatter = ColoredFormatter(log_format, datefmt="%H:%M:%S")
188
189 sh.setFormatter(colored_formatter)
190 logger.addHandler(sh)
191
192 logger_api = logging.getLogger("wally.fuel_api")
193
194 if log_fname is not None:
195 fh = logging.FileHandler(log_fname)
koder aka kdanilov168f6092015-04-19 02:33:38 +0300196 log_format = '%(asctime)s - %(levelname)8s - %(name)-15s - %(message)s'
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300197 formatter = logging.Formatter(log_format, datefmt="%H:%M:%S")
198 fh.setFormatter(formatter)
199 fh.setLevel(logging.DEBUG)
200 logger.addHandler(fh)
201 logger_api.addHandler(fh)
koder aka kdanilovec1b9732015-04-23 20:43:29 +0300202 else:
203 fh = None
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300204
205 logger_api.addHandler(sh)
206 logger_api.setLevel(logging.WARNING)
koder aka kdanilovec1b9732015-04-23 20:43:29 +0300207
208 logger = logging.getLogger('paramiko')
209 logger.setLevel(logging.WARNING)
koder aka kdanilovafd98742015-04-24 01:27:22 +0300210 # logger.addHandler(sh)
koder aka kdanilovec1b9732015-04-23 20:43:29 +0300211 if fh is not None:
212 logger.addHandler(fh)