blob: 88e46c8e2cabd542234da1f25ed6ba727f591ec2 [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)
Deepak Kodihalli82b7de72017-01-17 07:59:29 -060069 parents = list()
Andrew Geisslerc830e0f2016-10-18 12:51:29 -050070
Deepak Kodihalli160d3e02017-01-17 04:25:22 -060071 error_yamls = get_error_yaml_files(i_yaml_dir)
72
73 for error_yaml in error_yamls:
74 # Verify the error yaml file
75 error_yaml = "/".join((i_yaml_dir, error_yaml))
76 if (not (os.path.isfile(error_yaml))):
77 print "Can not find input yaml file " + error_yaml
78 exit(1)
79
80 # Verify the metadata yaml file
81 meta_yaml = get_meta_yaml_file(error_yaml)
82 if (not (os.path.isfile(meta_yaml))):
83 print "Can not find meta yaml file " + meta_yaml
84 exit(1)
85
86 # Verify the input mako file
87 template_path = "/".join((i_template_dir, i_elog_mako))
88 if (not (os.path.isfile(template_path))):
89 print "Can not find input template file " + template_path
90 exit(1)
91
92 get_elog_data(error_yaml,
93 meta_yaml,
94 # 3rd arg is a tuple
95 (errors,
96 error_msg,
97 error_lvl,
98 meta,
Deepak Kodihalli82b7de72017-01-17 07:59:29 -060099 meta_data,
100 parents))
Deepak Kodihalli160d3e02017-01-17 04:25:22 -0600101
102 # Load the mako template and call it with the required data
103 yaml_dir = i_yaml_dir.strip("./")
104 yaml_dir = yaml_dir.strip("../")
105 template = Template(filename=template_path)
106 f = open(i_output_hpp, 'w')
107 f.write(template.render(
108 errors=errors, error_msg=error_msg,
109 error_lvl=error_lvl, meta=meta,
110 meta_data=meta_data, error_namespace=i_error_namespace))
111 f.close()
112
113
114def get_elog_data(i_elog_yaml,
115 i_elog_meta_yaml,
116 o_elog_data):
117 r"""
118 Parse the error and metadata yaml files in order to pull out
119 error metadata.
120
121 Description of arguments:
122 i_elog_yaml error yaml file
123 i_elog_meta_yaml metadata yaml file
124 o_elog_data error metadata
125 """
Deepak Kodihalli82b7de72017-01-17 07:59:29 -0600126 errors, error_msg, error_lvl, meta, meta_data, parents = o_elog_data
Deepak Kodihalli160d3e02017-01-17 04:25:22 -0600127 ifile = yaml.safe_load(open(i_elog_yaml))
Andrew Geisslere8596302016-11-21 16:06:53 -0600128 mfile = yaml.safe_load(open(i_elog_meta_yaml))
Andrew Geissler5e81bfb2016-11-21 12:49:01 -0600129 for i in ifile:
Andrew Geisslere8596302016-11-21 16:06:53 -0600130 match = None
131 # Find the corresponding meta data for this entry
132 for m in mfile:
133 if m['name'] == i['name']:
134 match = m
135 break
136 if (match is None):
137 print "Error - Did not find meta data for " + i['name']
138 exit(1)
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600139 # Grab the main error and it's info
Deepak Kodihalli160d3e02017-01-17 04:25:22 -0600140 errors.append(i['name'])
Deepak Kodihalli82b7de72017-01-17 07:59:29 -0600141 parent = None
142 if('inherits' in i):
143 # xyz.openbmc.Foo, we need Foo
144 # Get 0th inherited error (current support - single inheritance)
145 parent = i['inherits'][0].split(".").pop()
146 parents.append(parent)
Andrew Geissler5e81bfb2016-11-21 12:49:01 -0600147 error_msg[i['name']] = i['description']
Andrew Geisslere8596302016-11-21 16:06:53 -0600148 error_lvl[i['name']] = match['level']
Andrew Geissler184690d2016-11-03 08:06:31 -0500149 tmp_meta = []
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500150 # grab all the meta data fields and info
Andrew Geisslere8596302016-11-21 16:06:53 -0600151 for j in match['meta']:
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500152 str_short = j['str'].split('=')[0]
153 tmp_meta.append(str_short)
154 meta_data[str_short] = {}
155 meta_data[str_short]['str'] = j['str']
156 meta_data[str_short]['str_short'] = str_short
Deepak Kodihalli99161192017-01-16 04:00:07 -0600157 meta_data[str_short]['type'] = get_cpp_type(j['type'])
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500158 meta.append(tmp_meta)
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500159
160 # Debug
Andrew Geissler184690d2016-11-03 08:06:31 -0500161 # for i in errors:
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600162 # print "ERROR: " + errors[i]
163 # print " MSG: " + error_msg[errors[i]]
164 # print " LVL: " + error_lvl[errors[i]]
165 # print " META: "
166 # print meta[i]
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500167
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500168
169def main(i_args):
170 parser = OptionParser()
171
Andrew Geissler184690d2016-11-03 08:06:31 -0500172 parser.add_option("-m", "--mako", dest="elog_mako",
173 default="elog-gen-template.mako.hpp",
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600174 help="input mako template file to use")
Andrew Geissler184690d2016-11-03 08:06:31 -0500175
176 parser.add_option("-o", "--output", dest="output_hpp",
177 default="elog-gen.hpp",
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600178 help="output hpp to generate, elog-gen.hpp is default")
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500179
Deepak Kodihalli160d3e02017-01-17 04:25:22 -0600180 parser.add_option("-y", "--yamldir", dest="yamldir",
181 default="./example/xyz/openbmc_project/Example",
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600182 help="Base directory of yaml files to process")
183
184 parser.add_option("-t", "--templatedir", dest="templatedir",
185 default="phosphor-logging/templates/",
186 help="Base directory of files to process")
187
Deepak Kodihalli160d3e02017-01-17 04:25:22 -0600188 parser.add_option("-n", "--namespace", dest="error_namespace",
189 default="example/xyz/openbmc_project/Example",
190 help="Error d-bus namespace")
191
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500192 (options, args) = parser.parse_args(i_args)
193
Deepak Kodihalli160d3e02017-01-17 04:25:22 -0600194 gen_elog_hpp(options.yamldir,
195 options.output_hpp,
196 options.templatedir,
197 options.elog_mako,
198 options.error_namespace)
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500199
200# Only run if it's a script
201if __name__ == '__main__':
Andrew Geissler184690d2016-11-03 08:06:31 -0500202 main(sys.argv[1:])