| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 1 | import os | 
 | 2 | import uuid | 
 | 3 | import logging | 
 | 4 | import functools | 
 | 5 |  | 
 | 6 | import yaml | 
 | 7 |  | 
 | 8 | try: | 
 | 9 |     from petname import Generate as pet_generate | 
 | 10 | except ImportError: | 
 | 11 |     def pet_generate(x, y): | 
 | 12 |         return str(uuid.uuid4()) | 
 | 13 |  | 
| koder aka kdanilov | 57ce4db | 2015-04-25 21:25:51 +0300 | [diff] [blame] | 14 | from pretty_yaml import dumps | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 15 |  | 
 | 16 | cfg_dict = {} | 
 | 17 |  | 
 | 18 |  | 
| koder aka kdanilov | fd2cfa5 | 2015-05-20 03:17:42 +0300 | [diff] [blame^] | 19 | class NoData(object): | 
 | 20 |     @classmethod | 
 | 21 |     def get(cls, name, x): | 
 | 22 |         return cls | 
 | 23 |  | 
 | 24 |  | 
 | 25 | class 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 |  | 
 | 36 | cfg = Config() | 
 | 37 | cfg.__dict__ = cfg_dict | 
 | 38 |  | 
 | 39 |  | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 40 | def mkdirs_if_unxists(path): | 
 | 41 |     if not os.path.exists(path): | 
 | 42 |         os.makedirs(path) | 
 | 43 |  | 
 | 44 |  | 
| koder aka kdanilov | fd2cfa5 | 2015-05-20 03:17:42 +0300 | [diff] [blame^] | 45 | def 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', | 
 | 53 |         text_report_file='report.txt', | 
 | 54 |         log_file='log.txt', | 
 | 55 |         sensor_storage='sensor_storage', | 
 | 56 |         nodes_report_file='nodes.yaml', | 
 | 57 |         results='results', | 
 | 58 |         hwinfo_directory='hwinfo', | 
 | 59 |         hwreport_fname='hwinfo.txt', | 
 | 60 |         raw_results='raw_results.yaml') | 
 | 61 |  | 
 | 62 |     res = dict((k, in_var_dir(v)) for k, v in res.items()) | 
 | 63 |     res['var_dir'] = results_dir | 
 | 64 |     return res | 
 | 65 |  | 
 | 66 |  | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 67 | def load_config(file_name, explicit_folder=None): | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 68 |     cfg_dict.update(yaml.load(open(file_name).read())) | 
 | 69 |  | 
| koder aka kdanilov | fd2cfa5 | 2015-05-20 03:17:42 +0300 | [diff] [blame^] | 70 |     var_dir = cfg_dict.get('internal', {}).get('var_dir_root', '/tmp') | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 71 |     run_uuid = None | 
 | 72 |     if explicit_folder is None: | 
 | 73 |         for i in range(10): | 
 | 74 |             run_uuid = pet_generate(2, "_") | 
 | 75 |             results_dir = os.path.join(var_dir, run_uuid) | 
 | 76 |             if not os.path.exists(results_dir): | 
 | 77 |                 break | 
 | 78 |         else: | 
 | 79 |             run_uuid = str(uuid.uuid4()) | 
 | 80 |             results_dir = os.path.join(var_dir, run_uuid) | 
| koder aka kdanilov | 4a510ee | 2015-04-21 18:50:42 +0300 | [diff] [blame] | 81 |         cfg_dict['run_uuid'] = run_uuid.replace('_', '-') | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 82 |     else: | 
 | 83 |         results_dir = explicit_folder | 
 | 84 |  | 
| koder aka kdanilov | fd2cfa5 | 2015-05-20 03:17:42 +0300 | [diff] [blame^] | 85 |     cfg_dict.update(get_test_files(results_dir)) | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 86 |     mkdirs_if_unxists(cfg_dict['var_dir']) | 
 | 87 |  | 
| koder aka kdanilov | 57ce4db | 2015-04-25 21:25:51 +0300 | [diff] [blame] | 88 |     if explicit_folder is not None: | 
| koder aka kdanilov | fd2cfa5 | 2015-05-20 03:17:42 +0300 | [diff] [blame^] | 89 |         with open(cfg_dict['run_params_file']) as fd: | 
| koder aka kdanilov | 57ce4db | 2015-04-25 21:25:51 +0300 | [diff] [blame] | 90 |             cfg_dict['run_uuid'] = yaml.load(fd)['run_uuid'] | 
 | 91 |         run_uuid = cfg_dict['run_uuid'] | 
 | 92 |     else: | 
| koder aka kdanilov | fd2cfa5 | 2015-05-20 03:17:42 +0300 | [diff] [blame^] | 93 |         with open(cfg_dict['run_params_file'], 'w') as fd: | 
| koder aka kdanilov | 57ce4db | 2015-04-25 21:25:51 +0300 | [diff] [blame] | 94 |             fd.write(dumps({'run_uuid': cfg_dict['run_uuid']})) | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 95 |  | 
| koder aka kdanilov | 4af1c1d | 2015-05-18 15:48:58 +0300 | [diff] [blame] | 96 |     mkdirs_if_unxists(cfg_dict['sensor_storage']) | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 97 |  | 
| koder aka kdanilov | 4af1c1d | 2015-05-18 15:48:58 +0300 | [diff] [blame] | 98 |     if 'sensors_remote_path' not in cfg_dict: | 
 | 99 |         cfg_dict['sensors_remote_path'] = '/tmp/sensors' | 
 | 100 |  | 
| koder aka kdanilov | afd9874 | 2015-04-24 01:27:22 +0300 | [diff] [blame] | 101 |     testnode_log_root = cfg_dict.get('testnode_log_root', '/var/wally') | 
 | 102 |     testnode_log_dir = os.path.join(testnode_log_root, "{0}/{{name}}") | 
| koder aka kdanilov | 2066daf | 2015-04-23 21:05:41 +0300 | [diff] [blame] | 103 |     cfg_dict['default_test_local_folder'] = \ | 
| koder aka kdanilov | afd9874 | 2015-04-24 01:27:22 +0300 | [diff] [blame] | 104 |         testnode_log_dir.format(cfg_dict['run_uuid']) | 
| koder aka kdanilov | 2066daf | 2015-04-23 21:05:41 +0300 | [diff] [blame] | 105 |  | 
| koder aka kdanilov | fd2cfa5 | 2015-05-20 03:17:42 +0300 | [diff] [blame^] | 106 |     mkdirs_if_unxists(cfg_dict['results']) | 
| koder aka kdanilov | f86d7af | 2015-05-06 04:01:54 +0300 | [diff] [blame] | 107 |     mkdirs_if_unxists(cfg_dict['hwinfo_directory']) | 
 | 108 |  | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 109 |  | 
 | 110 | def color_me(color): | 
 | 111 |     RESET_SEQ = "\033[0m" | 
 | 112 |     COLOR_SEQ = "\033[1;%dm" | 
 | 113 |  | 
 | 114 |     color_seq = COLOR_SEQ % (30 + color) | 
 | 115 |  | 
 | 116 |     def closure(msg): | 
 | 117 |         return color_seq + msg + RESET_SEQ | 
 | 118 |     return closure | 
 | 119 |  | 
 | 120 |  | 
 | 121 | class ColoredFormatter(logging.Formatter): | 
 | 122 |     BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8) | 
 | 123 |  | 
 | 124 |     colors = { | 
 | 125 |         'WARNING': color_me(YELLOW), | 
 | 126 |         'DEBUG': color_me(BLUE), | 
 | 127 |         'CRITICAL': color_me(YELLOW), | 
 | 128 |         'ERROR': color_me(RED) | 
 | 129 |     } | 
 | 130 |  | 
 | 131 |     def __init__(self, msg, use_color=True, datefmt=None): | 
 | 132 |         logging.Formatter.__init__(self, msg, datefmt=datefmt) | 
 | 133 |         self.use_color = use_color | 
 | 134 |  | 
 | 135 |     def format(self, record): | 
 | 136 |         orig = record.__dict__ | 
 | 137 |         record.__dict__ = record.__dict__.copy() | 
 | 138 |         levelname = record.levelname | 
 | 139 |  | 
 | 140 |         prn_name = levelname + ' ' * (8 - len(levelname)) | 
 | 141 |         if levelname in self.colors: | 
 | 142 |             record.levelname = self.colors[levelname](prn_name) | 
 | 143 |         else: | 
 | 144 |             record.levelname = prn_name | 
 | 145 |  | 
| koder aka kdanilov | 6b1341a | 2015-04-21 22:44:21 +0300 | [diff] [blame] | 146 |         # super doesn't work here in 2.6 O_o | 
 | 147 |         res = logging.Formatter.format(self, record) | 
 | 148 |  | 
 | 149 |         # res = super(ColoredFormatter, self).format(record) | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 150 |  | 
 | 151 |         # restore record, as it will be used by other formatters | 
 | 152 |         record.__dict__ = orig | 
 | 153 |         return res | 
 | 154 |  | 
 | 155 |  | 
 | 156 | def setup_loggers(def_level=logging.DEBUG, log_fname=None): | 
 | 157 |     logger = logging.getLogger('wally') | 
 | 158 |     logger.setLevel(logging.DEBUG) | 
 | 159 |     sh = logging.StreamHandler() | 
 | 160 |     sh.setLevel(def_level) | 
 | 161 |  | 
| koder aka kdanilov | 168f609 | 2015-04-19 02:33:38 +0300 | [diff] [blame] | 162 |     log_format = '%(asctime)s - %(levelname)s - %(name)-15s - %(message)s' | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 163 |     colored_formatter = ColoredFormatter(log_format, datefmt="%H:%M:%S") | 
 | 164 |  | 
 | 165 |     sh.setFormatter(colored_formatter) | 
 | 166 |     logger.addHandler(sh) | 
 | 167 |  | 
 | 168 |     logger_api = logging.getLogger("wally.fuel_api") | 
 | 169 |  | 
 | 170 |     if log_fname is not None: | 
 | 171 |         fh = logging.FileHandler(log_fname) | 
| koder aka kdanilov | 168f609 | 2015-04-19 02:33:38 +0300 | [diff] [blame] | 172 |         log_format = '%(asctime)s - %(levelname)8s - %(name)-15s - %(message)s' | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 173 |         formatter = logging.Formatter(log_format, datefmt="%H:%M:%S") | 
 | 174 |         fh.setFormatter(formatter) | 
 | 175 |         fh.setLevel(logging.DEBUG) | 
 | 176 |         logger.addHandler(fh) | 
 | 177 |         logger_api.addHandler(fh) | 
| koder aka kdanilov | ec1b973 | 2015-04-23 20:43:29 +0300 | [diff] [blame] | 178 |     else: | 
 | 179 |         fh = None | 
| koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 180 |  | 
 | 181 |     logger_api.addHandler(sh) | 
 | 182 |     logger_api.setLevel(logging.WARNING) | 
| koder aka kdanilov | ec1b973 | 2015-04-23 20:43:29 +0300 | [diff] [blame] | 183 |  | 
 | 184 |     logger = logging.getLogger('paramiko') | 
 | 185 |     logger.setLevel(logging.WARNING) | 
| koder aka kdanilov | afd9874 | 2015-04-24 01:27:22 +0300 | [diff] [blame] | 186 |     # logger.addHandler(sh) | 
| koder aka kdanilov | ec1b973 | 2015-04-23 20:43:29 +0300 | [diff] [blame] | 187 |     if fh is not None: | 
 | 188 |         logger.addHandler(fh) |