blob: d10c02639c6c63ba6b9031e7dff0d656fe5434dc [file] [log] [blame]
Andrew Geisslerc830e0f2016-10-18 12:51:29 -05001#!/usr/bin/env python
2
3r"""
Deepak Kodihalli160d3e02017-01-17 04:25:22 -06004This script will parse error log yaml file(s) and generate
Andrew Geisslerc830e0f2016-10-18 12:51:29 -05005a header file which will then be used by the error logging client and
6server to collect and validate the error information generated by the
7openbmc software components.
8
9This code uses a mako template to provide the basic template of the header
10file we're going to generate. We then call it with information from the
11yaml to generate the header file.
Andrew Geisslerc830e0f2016-10-18 12:51:29 -050012"""
13
14from mako.template import Template
15from optparse import OptionParser
16import yaml
17import sys
18import os
19
Andrew Geissler184690d2016-11-03 08:06:31 -050020
Deepak Kodihalli160d3e02017-01-17 04:25:22 -060021def get_error_yaml_files(i_yaml_dir):
22 yaml_files = filter(
23 lambda file: file.endswith('.errors.yaml'),
24 os.listdir(i_yaml_dir))
25 return yaml_files
26
27
28def get_meta_yaml_file(i_error_yaml_file):
29 # the meta data will be defined in file name where we replace
30 # <Interface>.errors.yaml with <Interface>.metadata.yaml
31 meta_yaml = i_error_yaml_file.replace("errors", "metadata")
32 return meta_yaml
33
34
Deepak Kodihalli99161192017-01-16 04:00:07 -060035def get_cpp_type(i_type):
36 typeMap = {
37 'int16': 'int16_t',
38 'int32': 'int32_t',
39 'int64': 'int64_t',
40 'uint16': 'uint16_t',
41 'uint32': 'uint32_t',
42 'uint64': 'uint64_t',
43 'double': 'double',
44 # const char* aids usage of constexpr
45 'string': 'const char*'}
46
47 return typeMap[i_type]
48
49
Deepak Kodihalli160d3e02017-01-17 04:25:22 -060050def gen_elog_hpp(i_yaml_dir, i_output_hpp,
51 i_template_dir, i_elog_mako, i_error_namespace):
Andrew Geisslerc830e0f2016-10-18 12:51:29 -050052 r"""
Deepak Kodihalli160d3e02017-01-17 04:25:22 -060053 Read yaml file(s) under input yaml dir, grab the relevant data and call
54 the mako template to generate the output header file.
Andrew Geisslerc830e0f2016-10-18 12:51:29 -050055
56 Description of arguments:
Deepak Kodihalli160d3e02017-01-17 04:25:22 -060057 i_yaml_dir directory containing error yaml files
58 i_output_hpp name of the to be generated output hpp
59 i_template_dir directory containing error mako templates
60 i_elog_mako error mako template to render
Andrew Geisslerc830e0f2016-10-18 12:51:29 -050061 """
62
63 # Input parameters to mako template
Deepak Kodihalli160d3e02017-01-17 04:25:22 -060064 errors = list() # Main error codes
Andrew Geisslerc830e0f2016-10-18 12:51:29 -050065 error_msg = dict() # Error msg that corresponds to error code
66 error_lvl = dict() # Error code log level (debug, info, error, ...)
Andrew Geissler184690d2016-11-03 08:06:31 -050067 meta = list() # The meta data names associated (ERRNO, FILE_NAME, ...)
Andrew Geisslerc830e0f2016-10-18 12:51:29 -050068 meta_data = dict() # The meta data info (type, format)
69
Deepak Kodihalli160d3e02017-01-17 04:25:22 -060070 error_yamls = get_error_yaml_files(i_yaml_dir)
71
72 for error_yaml in error_yamls:
73 # Verify the error yaml file
74 error_yaml = "/".join((i_yaml_dir, error_yaml))
75 if (not (os.path.isfile(error_yaml))):
76 print "Can not find input yaml file " + error_yaml
77 exit(1)
78
79 # Verify the metadata yaml file
80 meta_yaml = get_meta_yaml_file(error_yaml)
81 if (not (os.path.isfile(meta_yaml))):
82 print "Can not find meta yaml file " + meta_yaml
83 exit(1)
84
85 # Verify the input mako file
86 template_path = "/".join((i_template_dir, i_elog_mako))
87 if (not (os.path.isfile(template_path))):
88 print "Can not find input template file " + template_path
89 exit(1)
90
91 get_elog_data(error_yaml,
92 meta_yaml,
93 # 3rd arg is a tuple
94 (errors,
95 error_msg,
96 error_lvl,
97 meta,
98 meta_data))
99
100 # Load the mako template and call it with the required data
101 yaml_dir = i_yaml_dir.strip("./")
102 yaml_dir = yaml_dir.strip("../")
103 template = Template(filename=template_path)
104 f = open(i_output_hpp, 'w')
105 f.write(template.render(
106 errors=errors, error_msg=error_msg,
107 error_lvl=error_lvl, meta=meta,
108 meta_data=meta_data, error_namespace=i_error_namespace))
109 f.close()
110
111
112def get_elog_data(i_elog_yaml,
113 i_elog_meta_yaml,
114 o_elog_data):
115 r"""
116 Parse the error and metadata yaml files in order to pull out
117 error metadata.
118
119 Description of arguments:
120 i_elog_yaml error yaml file
121 i_elog_meta_yaml metadata yaml file
122 o_elog_data error metadata
123 """
124 errors, error_msg, error_lvl, meta, meta_data = o_elog_data
125 ifile = yaml.safe_load(open(i_elog_yaml))
Andrew Geisslere8596302016-11-21 16:06:53 -0600126 mfile = yaml.safe_load(open(i_elog_meta_yaml))
Andrew Geissler5e81bfb2016-11-21 12:49:01 -0600127 for i in ifile:
Andrew Geisslere8596302016-11-21 16:06:53 -0600128 match = None
129 # Find the corresponding meta data for this entry
130 for m in mfile:
131 if m['name'] == i['name']:
132 match = m
133 break
134 if (match is None):
135 print "Error - Did not find meta data for " + i['name']
136 exit(1)
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600137 # Grab the main error and it's info
Deepak Kodihalli160d3e02017-01-17 04:25:22 -0600138 errors.append(i['name'])
Andrew Geissler5e81bfb2016-11-21 12:49:01 -0600139 error_msg[i['name']] = i['description']
Andrew Geisslere8596302016-11-21 16:06:53 -0600140 error_lvl[i['name']] = match['level']
Andrew Geissler184690d2016-11-03 08:06:31 -0500141 tmp_meta = []
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500142 # grab all the meta data fields and info
Andrew Geisslere8596302016-11-21 16:06:53 -0600143 for j in match['meta']:
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500144 str_short = j['str'].split('=')[0]
145 tmp_meta.append(str_short)
146 meta_data[str_short] = {}
147 meta_data[str_short]['str'] = j['str']
148 meta_data[str_short]['str_short'] = str_short
Deepak Kodihalli99161192017-01-16 04:00:07 -0600149 meta_data[str_short]['type'] = get_cpp_type(j['type'])
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500150 meta.append(tmp_meta)
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500151
152 # Debug
Andrew Geissler184690d2016-11-03 08:06:31 -0500153 # for i in errors:
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600154 # print "ERROR: " + errors[i]
155 # print " MSG: " + error_msg[errors[i]]
156 # print " LVL: " + error_lvl[errors[i]]
157 # print " META: "
158 # print meta[i]
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500159
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500160
161def main(i_args):
162 parser = OptionParser()
163
Andrew Geissler184690d2016-11-03 08:06:31 -0500164 parser.add_option("-m", "--mako", dest="elog_mako",
165 default="elog-gen-template.mako.hpp",
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600166 help="input mako template file to use")
Andrew Geissler184690d2016-11-03 08:06:31 -0500167
168 parser.add_option("-o", "--output", dest="output_hpp",
169 default="elog-gen.hpp",
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600170 help="output hpp to generate, elog-gen.hpp is default")
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500171
Deepak Kodihalli160d3e02017-01-17 04:25:22 -0600172 parser.add_option("-y", "--yamldir", dest="yamldir",
173 default="./example/xyz/openbmc_project/Example",
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600174 help="Base directory of yaml files to process")
175
176 parser.add_option("-t", "--templatedir", dest="templatedir",
177 default="phosphor-logging/templates/",
178 help="Base directory of files to process")
179
Deepak Kodihalli160d3e02017-01-17 04:25:22 -0600180 parser.add_option("-n", "--namespace", dest="error_namespace",
181 default="example/xyz/openbmc_project/Example",
182 help="Error d-bus namespace")
183
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500184 (options, args) = parser.parse_args(i_args)
185
Deepak Kodihalli160d3e02017-01-17 04:25:22 -0600186 gen_elog_hpp(options.yamldir,
187 options.output_hpp,
188 options.templatedir,
189 options.elog_mako,
190 options.error_namespace)
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500191
192# Only run if it's a script
193if __name__ == '__main__':
Andrew Geissler184690d2016-11-03 08:06:31 -0500194 main(sys.argv[1:])