blob: e891bd43ecd34a91469f0d998025b6c12254f18f [file] [log] [blame]
Norman James9d0f65f2015-10-26 17:13:13 -05001#!/usr/bin/python -u
2
3import sys
4#from gi.repository import GObject
5import gobject
6import dbus
7import dbus.service
8import dbus.mainloop.glib
9import cPickle
10import glob
11import os
12
13if (len(sys.argv) < 2):
14 print "Usage: property_manager.py [system name]"
15 exit(1)
16System = __import__(sys.argv[1])
17import Openbmc
18
19DBUS_NAME = 'org.openbmc.managers.Property'
20OBJ_NAME = '/org/openbmc/managers/Property'
21INTF_NAME = 'org.openbmc.managers.Property'
22
23class PropertyManager(dbus.service.Object):
24 def __init__(self,bus,name):
25 dbus.service.Object.__init__(self,bus,name)
26 if not os.path.exists(System.CACHE_PATH):
27 os.makedirs(System.CACHE_PATH)
28
29
30 bus.add_signal_receiver(self.PropertyChangedHandler,
31 dbus_interface = 'org.freedesktop.DBus.Properties',
32 signal_name = 'PropertiesChanged', sender_keyword='bus_name', path_keyword='path')
33
34 bus.add_signal_receiver(self.RegisterPersistantInterface,
35 dbus_interface = 'org.openbmc.PersistantInterface',
36 signal_name = 'Register', sender_keyword='bus_name', path_keyword='path')
37
38 self.registered_interfaces = {}
39
40
41 def RegisterPersistantInterface(self,interface_name, bus_name = None, path = None):
42 interface_name = str(interface_name)
43 print "Registering cached object (interface): "+path+" ("+interface_name+")"
44 self.registered_interfaces[interface_name] = True
45 self.loadFromCache(bus_name,path,interface_name)
46
47
48 def PropertyChangedHandler(self, interface_name, changed_properties,
49 invalidated_properties, bus_name = None, path = None):
50 ## TODO: just save all properties, probably should journal changes instead
51 if (self.registered_interfaces.has_key(interface_name)):
52 self.saveToCache(bus_name,path,interface_name)
53
54 def getCacheFilename(self,obj_path,intf_name):
55 name = obj_path.replace('/','.')
56 filename = System.CACHE_PATH+name[1:]+"@"+intf_name+".props"
57 return filename
58
59 def getCacheFilenames(self,obj_path):
60 name = obj_path.replace('/','.')
61 path = System.CACHE_PATH+name[1:]+"\@*"
62 return glob.glob(path)
63
64 def saveToCache(self, bus_name, object_path, interface_name):
65 print "Caching: "+object_path
66 try:
67 obj = bus.get_object(bus_name,object_path)
68 intf = dbus.Interface(obj,"org.freedesktop.DBus.Properties")
69 props = intf.GetAll(interface_name)
70 output = open(self.getCacheFilename(object_path,interface_name), 'wb')
71 ## save properties
72 dbus_props = {}
73 for p in props.keys():
74 dbus_prop = Openbmc.DbusVariable(p,props[p])
75 dbus_props[str(p)] = dbus_prop.getBaseValue()
76 cPickle.dump(dbus_props,output)
77 except Exception as e:
78 print "ERROR: "+str(e)
79 finally:
80 output.close()
81
82 def loadFromCache(self,bus_name, object_path, interface_name):
83 ## overlay with pickled data
84 filename=self.getCacheFilename(object_path,interface_name)
85 if (os.path.isfile(filename)):
86 print "Loading from cache: "+filename
87 try:
88 p = open(filename, 'rb')
89 data = cPickle.load(p)
90 obj = bus.get_object(bus_name,object_path)
91 ## TODO: don't use exception to determine whether interface is implemented
92 try:
93 intf = dbus.Interface(obj,"org.openbmc.Object.Properties")
94 props = intf.SetMultiple(interface_name,data)
95 except TypeError as t:
96 print "SetMultiple interface doesn't exist, doing 1 set a time"
97 intf = dbus.Interface(obj,dbus.PROPERTIES_IFACE)
98 for prop in data:
99 intf.Set(interface_name,prop,data[prop])
100
101
102 except Exception as e:
103 print "ERROR: Loading cache file: " +str(e)
104 finally:
105 p.close()
106
107
108if __name__ == '__main__':
109 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
110 bus = Openbmc.getDBus()
111 name = dbus.service.BusName(DBUS_NAME,bus)
112 obj = PropertyManager(bus,OBJ_NAME)
113 mainloop = gobject.MainLoop()
114
115 print "Running Property Manager"
116 mainloop.run()
117