blob: 11505525d1391f3e77b8fb2485251d312bbe2161 [file] [log] [blame]
Norman James362a80f2015-09-14 14:04:39 -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: fru_manager.py [system name]"
14 exit(1)
15System = __import__(sys.argv[1])
16import Openbmc
17
18DBUS_NAME = 'org.openbmc.managers.Frus'
19OBJ_NAME = '/org/openbmc/managers/Frus'
20FRU_PATH = System.FRU_PATH
21
22class Fru:
23 def __init__(self,fru_id,data):
24 if (data.has_key('ftype') == False):
25 raise Exception("Fru must have ftype")
26
27 self.fru_id = fru_id
28 self.data = { 'fru_id' : fru_id }
29 self.ftype = data['ftype']
30 self.update(data)
31
32 def getField(self,field):
33 return self.data[field]
34
35 def getId(self):
36 return self.fru_id
37
38 def update(self,data):
39 for k in data.keys():
40 self.data[k] = data[k]
41
42 def isCached(self):
43 is_cached = False
44 if (self.data.has_key('cache')):
45 if (self.data['cache']):
46 is_cached = True
47 return is_cached
48
49 def saveToCache(self):
50 if (self.isCached() == False):
51 return
52 global FRU_PATH
53 print "Caching: "+str(self.fru_id)
54 filename = FRU_PATH+"fru_"+str(self.fru_id)
55 output = open(filename, 'wb')
56 ## just pickle dict not whole object
57 cPickle.dump(self.data,output)
58 output.close()
59
60 def loadFromCache(self):
61 if (self.isCached() == False):
62 return;
63 ## overlay with pickled data
64 global FRU_PATH
65 filename = FRU_PATH+"fru_"+str(self.fru_id)
66
67 if (os.path.isfile(filename)):
68 print "Loading from cache: "+filename
69 p = open(filename, 'rb')
70 data2 = cPickle.load(p)
71 for k in data2.keys():
72 self.data[k] = data2[k]
73 def toJson(self):
74 return json.dumps(self.data)
75
76 def __str__(self):
77 r = "Fru: "+str(self.fru_id)+"\n"
78 for f in self.data.keys():
79 r = r+f+" = "+str(self.data[f])+"\n"
80 return r
81
82
83
84class FruManager(dbus.service.Object):
85 def __init__(self,bus,name):
86 dbus.service.Object.__init__(self,bus,name)
87
88 bus.add_signal_receiver(self.UpdateFruHandler,
89 signal_name = 'UpdateFru')
90
91 self.fru_db = {}
92 for fid in System.FRUS.keys():
93 self.updateFru(fid,System.FRUS[fid])
94
95
96 #@dbus.service.signal(DBUS_NAME)
97 #def OpenBmcRunning(self):
98 # pass
99 def UpdateFruHandler(self,fru_id,data):
100 self.updateFru(fru_id,data)
101
102 @dbus.service.method(DBUS_NAME,
103 in_signature='isv', out_signature='')
104 def updateFruField(self,fru_id,field,value):
105 data = { field : value }
106 self.updateFru(fru_id,data)
107
108 @dbus.service.method(DBUS_NAME,
109 in_signature='ia{sv}', out_signature='')
110 def updateFru(self,fru_id,data):
111 ## translate dbus data into basic data types
112 for k in data.keys():
113 d = Openbmc.DbusProperty(k,data[k])
114 data[k] = d.getBaseValue()
115
116 if (self.fru_db.has_key(fru_id)):
117 ## update properties then save to cache
118 print "Updating FRU: "+str(fru_id)
119 self.fru_db[fru_id].update(data)
120 self.fru_db[fru_id].saveToCache()
121 else:
122 ## fru doesn't exist, so add
123 ## then overlay with data from cache
124 print "Adding FRU: "+str(fru_id)
125 fru = Fru(fru_id,data)
126 self.fru_db[fru_id] = fru
127 fru.loadFromCache()
128
129
130 @dbus.service.method(DBUS_NAME,
131 in_signature='', out_signature='s')
132 def getFrus(self):
133 r = ""
134 for f in self.fru_db.keys():
135 r=r+"["+self.fru_db[f].toJson()+"],"
136 return r
137
138
139if __name__ == '__main__':
140 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
141 bus = dbus.SessionBus()
142 name = dbus.service.BusName(DBUS_NAME,bus)
143 obj = FruManager(bus,OBJ_NAME)
144 mainloop = gobject.MainLoop()
145
146 print "Running Fru Manager"
147 mainloop.run()
148