Matt Spinler | 3048ecc | 2018-03-28 10:15:12 -0500 | [diff] [blame^] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | '''Generates 2 reports about OpenBMC error logs: |
| 4 | |
| 5 | 1) Dumps every error defined in the errors.yaml files passed in |
| 6 | into a single JSON file that looks like: |
| 7 | |
| 8 | { |
| 9 | "desc":"Callout IIC device", |
| 10 | "error":"xyz.openbmc_project.Common.Callout.Error.IIC", |
| 11 | "file":"xyz/openbmc_project/Common/Callout.errors.yaml", |
| 12 | "metadata":[ |
| 13 | "CALLOUT_IIC_BUS", |
| 14 | "CALLOUT_IIC_ADDR", |
| 15 | "Inherits xyz.openbmc_project.Common.Callout.Error.Device" |
| 16 | ] |
| 17 | } |
| 18 | |
| 19 | 2) Crosschecks this generated JSON with the IBM error policy table, |
| 20 | showing if any errors are in one file but not the other. |
| 21 | |
| 22 | ''' |
| 23 | |
| 24 | import argparse |
| 25 | import os |
| 26 | import json |
| 27 | import yaml |
| 28 | |
| 29 | |
| 30 | def get_errors(yaml_dirs): |
| 31 | '''Finds all of the errors in all of the error YAML files in |
| 32 | the directories passed in.''' |
| 33 | |
| 34 | all_errors = [] |
| 35 | for yaml_dir in yaml_dirs: |
| 36 | error_data = [] |
| 37 | yaml_files = get_yaml(yaml_dir) |
| 38 | |
| 39 | for yaml_file in yaml_files: |
| 40 | all_errors += read_error_yaml(yaml_dir, yaml_file) |
| 41 | |
| 42 | return all_errors |
| 43 | |
| 44 | |
| 45 | def read_error_yaml(yaml_dir, yaml_file): |
| 46 | '''Returns a list of dictionary objects reflecting the error YAML.''' |
| 47 | |
| 48 | all_errors = [] |
| 49 | |
| 50 | #xyz/openbmc_project/x.errors.yaml -> xyz.openbmc_project.x.Error |
| 51 | error_base = yaml_file.replace(os.sep, '.') |
| 52 | error_base = error_base.replace('.errors.yaml', '') |
| 53 | error_base += '.Error.' |
| 54 | |
| 55 | #Also needs to look up the metadata from the .metadata.yaml files |
| 56 | metadata_file = yaml_file.replace('errors.yaml', 'metadata.yaml') |
| 57 | metadata = [] |
| 58 | |
| 59 | if os.path.exists(os.path.join(yaml_dir, metadata_file)): |
| 60 | with open(os.path.join(yaml_dir, metadata_file)) as mfd: |
| 61 | metadata = yaml.safe_load(mfd.read()) |
| 62 | |
| 63 | with open(os.path.join(yaml_dir, yaml_file)) as fd: |
| 64 | data = yaml.safe_load(fd.read()) |
| 65 | |
| 66 | for e in data: |
| 67 | error = {} |
| 68 | error['error'] = error_base + e['name'] |
| 69 | error['desc'] = e['description'] |
| 70 | error['metadata'] = get_metadata(e['name'], metadata) |
| 71 | error['file'] = yaml_file |
| 72 | all_errors.append(error) |
| 73 | |
| 74 | return all_errors |
| 75 | |
| 76 | |
| 77 | def get_metadata(name, metadata): |
| 78 | #TODO |
| 79 | data = [] |
| 80 | return data |
| 81 | |
| 82 | |
| 83 | def get_yaml(yaml_dir): |
| 84 | '''Finds all of the *.errors.yaml files in the directory passed in. |
| 85 | Returns a list of entries like xyz/openbmc_project/Common.Errors.yaml. |
| 86 | ''' |
| 87 | |
| 88 | err_files = [] |
| 89 | metadata_files = [] |
| 90 | if os.path.exists(yaml_dir): |
| 91 | for directory, _, files in os.walk(yaml_dir): |
| 92 | if not files: |
| 93 | continue |
| 94 | |
| 95 | err_files += map( |
| 96 | lambda f: os.path.relpath( |
| 97 | os.path.join(directory, f), |
| 98 | yaml_dir), |
| 99 | filter(lambda f: f.endswith('.errors.yaml'), files)) |
| 100 | |
| 101 | return err_files |
| 102 | |
| 103 | |
| 104 | if __name__ == '__main__': |
| 105 | |
| 106 | parser = argparse.ArgumentParser(description='Error log policy reports') |
| 107 | |
| 108 | parser.add_argument('-y', '--yaml_dirs', |
| 109 | dest='yaml_dirs', |
| 110 | default='.', |
| 111 | help='Comma separated list of error YAML dirs') |
| 112 | parser.add_argument('-e', '--error_file', |
| 113 | dest='error_file', |
| 114 | default='obmc-errors.json', |
| 115 | help='Output Error report file') |
| 116 | parser.add_argument('-p', '--policy', |
| 117 | dest='policy_file', |
| 118 | default='condensed.json', |
| 119 | help='Condensed policy in JSON') |
| 120 | |
| 121 | args = parser.parse_args() |
| 122 | |
| 123 | dirs = args.yaml_dirs.split(',') |
| 124 | errors = get_errors(dirs) |
| 125 | |
| 126 | with open(args.error_file, 'w') as outfile: |
| 127 | json.dump(errors, outfile, sort_keys=True, |
| 128 | indent=2, separators=(',', ':')) |
| 129 | |
| 130 | #TODO: crosschecking |