| #!/usr/bin/env python3 |
| |
| import yaml |
| import argparse |
| |
| from typing import NamedTuple |
| |
| |
| class RptSensor(NamedTuple): |
| name: str |
| entityId: int |
| typeId: int |
| evtType: int |
| sensorId: int |
| fru: int |
| targetPath: str |
| |
| |
| entityIds = { |
| 'dimm': 32, |
| 'core': 208, |
| 'cpu': 3, |
| 'gpu': 216, |
| 'gpu_mem': 217, |
| 'tpm': 3, |
| 'state/host0': 33, # Different interfaces using different entity ID |
| # and this requires extra fix. |
| # {'state/host0', 34}, |
| # {'state/host0', 35}, |
| 'turbo': 3, |
| 'fan': 29, |
| 'vdd_temp': 218, |
| 'power': 10, |
| 'voltage': 10, |
| 'current': 10, |
| 'temperature/pcie': 35, |
| 'temperature/ambient': 64, |
| 'occ': 210, |
| 'control/volatile': 33, |
| } |
| |
| extraIds = { |
| 'RebootPolicy': 33, |
| 'Progress': 34, |
| 'RebootAttempts': 34, |
| 'OperatingSystem.Status': 35 |
| } |
| |
| |
| def openYaml(f): |
| return yaml.load(open(f)) |
| |
| |
| def saveYaml(y, f): |
| yaml.dump(y, open(f, "w")) |
| |
| |
| def getEntityId(p, i): |
| for k, v in entityIds.items(): |
| if k in p: |
| if k == 'state/host0': |
| # get id from extraIds |
| for ek, ev in extraIds.items(): |
| if ek in i: |
| return ev |
| raise Exception("Unable to find entity id:", p, i) |
| else: |
| return v |
| raise Exception('Unable to find entity id:', p) |
| |
| |
| # Global entity instances |
| entityInstances = {} |
| |
| |
| def getEntityInstance(id): |
| instanceId = entityInstances.get(id, 0) |
| instanceId = instanceId + 1 |
| entityInstances[id] = instanceId |
| print("EntityId:", id, "InstanceId:", instanceId) |
| return instanceId |
| |
| |
| def loadRpt(rptFile): |
| sensors = [] |
| with open(rptFile) as f: |
| next(f) |
| next(f) |
| for line in f: |
| fields = line.strip().split('|') |
| fields = list(map(str.strip, fields)) |
| sensor = RptSensor( |
| fields[0], |
| int(fields[2], 16) if fields[2] else None, |
| int(fields[3], 16) if fields[3] else None, |
| int(fields[4], 16) if fields[4] else None, |
| int(fields[5], 16) if fields[5] else None, |
| int(fields[7], 16) if fields[7] else None, |
| fields[9]) |
| # print(sensor) |
| sensors.append(sensor) |
| return sensors |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser( |
| description='Yaml tool for updating ipmi sensor yaml config') |
| parser.add_argument('-i', '--input', required=True, dest='input', |
| help='The ipmi sensor yaml config') |
| parser.add_argument('-o', '--output', required=True, dest='output', |
| help='The output yaml file') |
| parser.add_argument('-r', '--rpt', dest='rpt', |
| help='The .rpt file generated by op-build') |
| parser.add_argument('-e', '--entity', action='store_true', |
| help='Fix entities') |
| |
| args = parser.parse_args() |
| args = vars(args) |
| |
| if args['input'] is None or args['output'] is None: |
| parser.print_help() |
| exit(1) |
| |
| y = openYaml(args['input']) |
| |
| sensorIds = list(y.keys()) |
| if args['rpt']: |
| rptSensors = loadRpt(args['rpt']) |
| for s in rptSensors: |
| if s.sensorId is not None and s.sensorId not in sensorIds: |
| print("Sensor ID:", s.sensorId, |
| " not in yaml, path", s.targetPath) |
| # TODO: add new items in yaml with missing sensors |
| return |
| |
| if args['entity']: |
| # Fix entities |
| for i in y: |
| path = y[i]['path'] |
| intf = list(y[i]['interfaces'].keys())[0] |
| entityId = getEntityId(path, intf) |
| y[i]['entityID'] = entityId |
| y[i]['entityInstance'] = getEntityInstance(entityId) |
| print(y[i]['path'], "id:", entityId, |
| "instance:", y[i]['entityInstance']) |
| |
| saveYaml(y, args['output']) |
| |
| |
| if __name__ == "__main__": |
| main() |