blob: dcc011441a87b7a532d8d21be2181726d9cc4289 [file] [log] [blame]
Norman James65a295a2015-09-26 22:21:10 -05001#!/usr/bin/env python
2
3import os
4import sys
5import gobject
6import dbus
7import dbus.service
8import dbus.mainloop.glib
9import cPickle
10import json
11
12if (len(sys.argv) < 2):
13 print "Usage: inventory_manager.py [system name]"
14 exit(1)
15System = __import__(sys.argv[1])
16import Openbmc
17
18DBUS_NAME = 'org.openbmc.managers.Inventory'
19OBJ_NAME = '/org/openbmc/managers/Inventory'
20FRUS = System.FRU_INSTANCES
21FRU_PATH = System.FRU_PATH
22
23## accessor class to FRU data structure
24class Fru:
25 def __init__(self,fru):
26 ## validation
27 if (FRUS.has_key(fru) == False):
28 # TODO: event log
29 raise Exception("Invalid FRU path: "+fru)
30
31 self.fru = fru
32
33 def getField(self,field):
34 if (FRUS[self.fru].has_key(field) == False):
35 # TODO: event log
36 raise Exception("Invalid field: "+field)
37
38 return FRUS[self.fru][field]
39
40 def isFru(self):
41 return FRUS[self.fru]['fru']
42
43 def update(self,data):
44 for k in data.keys():
45 FRUS[self.fru][k] = data[k]
46
47 def isCached(self):
48 return True
49
50 def getCacheFilename(self):
51 global FRU_PATH
52 filename = FRU_PATH+self.fru.replace('/','.')
53 return filename
54
55 def saveToCache(self):
56 if (self.isCached() == False):
57 return
58 print "Caching: "+self.fru
59 output = open(self.getCacheFilename(), 'wb')
60 ## just pickle dict not whole object
61 print FRUS[self.fru]
62 cPickle.dump(FRUS[self.fru],output)
63 output.close()
64
65 def loadFromCache(self):
66 if (self.isCached() == False):
67 return;
68 ## overlay with pickled data
69 filename=self.getCacheFilename()
70 if (os.path.isfile(filename)):
71 print "Loading from cache: "+filename
72 p = open(filename, 'rb')
73 data2 = cPickle.load(p)
74 for k in data2.keys():
75 FRUS[self.fru][k] = data2[k]
76
77 def __str__(self):
78 r = "Fru: "+str(self.fru_id)+"\n"
79 for f in self.data.keys():
80 r = r+f+" = "+str(self.data[f])+"\n"
81 return r
82
83
84
85class InventoryManager(dbus.service.Object):
86 def __init__(self,bus,name):
87 dbus.service.Object.__init__(self,bus,name)
88
89 bus.add_signal_receiver(self.UpdateFruHandler,
90 signal_name = 'UpdateFru')
91
92 self.fru_db = {}
93 self.fru_id_lookup = {}
94 self.sensor_id_lookup = {}
95
96 for fru_path in FRUS.keys():
97 self.addFru(fru_path)
98 f = FRUS[fru_path]
99 if (f.has_key('fru_id')):
100 self.fru_id_lookup[f['fru_id']] = fru_path
101 if (f.has_key('sensor_id')):
102 self.sensor_id_lookup[f['sensor_id']] = fru_path
103
104
105 def UpdateFruHandler(self,fru_id,data):
106 self.updateFru(fru_id,data)
107
108 @dbus.service.method(DBUS_NAME,
109 in_signature='y', out_signature='s')
110 def getFruSensor(self,sensor_id):
111 if (self.sensor_id_lookup.has_key(sensor_id) == False):
112 return ""
113 return self.sensor_id_lookup[sensor_id]
114
115 def addFru(self,fru_path):
116 new_fru = Fru(fru_path)
117 new_fru.loadFromCache()
118 self.fru_db[fru_path] = new_fru
119
120 @dbus.service.method(DBUS_NAME,
121 in_signature='ia{sv}', out_signature='')
122 def updateFruFromId(self,fru_id,data):
123 iid = int(fru_id)
124 if (self.fru_id_lookup.has_key(iid) == False):
125 # TODO: event log
126 print "fru id "+str(iid)+" not found"
127 else:
128 self.updateFru(self.fru_id_lookup[iid],data)
129
130
131 @dbus.service.method(DBUS_NAME,
132 in_signature='sa{sv}', out_signature='')
133 def updateFru(self,fru_path,data):
134 ## translate dbus data into basic data types
135 clean_data = {}
136 for k in data.keys():
137 d = Openbmc.DbusProperty(k,data[k])
138 clean_data[str(k)] = d.getBaseValue()
139
140 if (self.fru_db.has_key(fru_path)):
141 ## update properties then save to cache
142 print "Updating FRU: "+fru_path
143 self.fru_db[fru_path].update(clean_data)
144 self.fru_db[fru_path].saveToCache()
145
146
147 @dbus.service.method(DBUS_NAME,
148 in_signature='', out_signature='a{sa{sv}}')
149 def getFrus(self):
150 return FRUS
151
152
153if __name__ == '__main__':
154 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
155 bus = dbus.SessionBus()
156 name = dbus.service.BusName(DBUS_NAME,bus)
157 obj = InventoryManager(bus,OBJ_NAME)
158 mainloop = gobject.MainLoop()
159
160 print "Running Inventory Manager"
161 mainloop.run()
162