| #!/usr/bin/python -u |
| |
| import sys |
| #from gi.repository import GObject |
| import gobject |
| import dbus |
| import dbus.service |
| import dbus.mainloop.glib |
| import cPickle |
| import glob |
| import os |
| |
| if (len(sys.argv) < 2): |
| print "Usage: property_manager.py [system name]" |
| exit(1) |
| System = __import__(sys.argv[1]) |
| import Openbmc |
| |
| DBUS_NAME = 'org.openbmc.managers.Property' |
| OBJ_NAME = '/org/openbmc/managers/Property' |
| INTF_NAME = 'org.openbmc.managers.Property' |
| |
| class PropertyManager(dbus.service.Object): |
| def __init__(self,bus,name): |
| dbus.service.Object.__init__(self,bus,name) |
| if not os.path.exists(System.CACHE_PATH): |
| os.makedirs(System.CACHE_PATH) |
| |
| |
| bus.add_signal_receiver(self.PropertyChangedHandler, |
| dbus_interface = 'org.freedesktop.DBus.Properties', |
| signal_name = 'PropertiesChanged', sender_keyword='bus_name', path_keyword='path') |
| |
| bus.add_signal_receiver(self.RegisterPersistantInterface, |
| dbus_interface = 'org.openbmc.PersistantInterface', |
| signal_name = 'Register', sender_keyword='bus_name', path_keyword='path') |
| |
| self.registered_interfaces = {} |
| |
| |
| def RegisterPersistantInterface(self,interface_name, bus_name = None, path = None): |
| interface_name = str(interface_name) |
| print "Registering cached object (interface): "+path+" ("+interface_name+")" |
| self.registered_interfaces[interface_name] = True |
| self.loadFromCache(bus_name,path,interface_name) |
| |
| |
| def PropertyChangedHandler(self, interface_name, changed_properties, |
| invalidated_properties, bus_name = None, path = None): |
| ## TODO: just save all properties, probably should journal changes instead |
| if (self.registered_interfaces.has_key(interface_name)): |
| self.saveToCache(bus_name,path,interface_name) |
| |
| def getCacheFilename(self,obj_path,intf_name): |
| name = obj_path.replace('/','.') |
| filename = System.CACHE_PATH+name[1:]+"@"+intf_name+".props" |
| return filename |
| |
| def getCacheFilenames(self,obj_path): |
| name = obj_path.replace('/','.') |
| path = System.CACHE_PATH+name[1:]+"\@*" |
| return glob.glob(path) |
| |
| def saveToCache(self, bus_name, object_path, interface_name): |
| print "Caching: "+object_path |
| try: |
| obj = bus.get_object(bus_name,object_path) |
| intf = dbus.Interface(obj,"org.freedesktop.DBus.Properties") |
| props = intf.GetAll(interface_name) |
| output = open(self.getCacheFilename(object_path,interface_name), 'wb') |
| ## save properties |
| dbus_props = {} |
| for p in props.keys(): |
| dbus_prop = Openbmc.DbusVariable(p,props[p]) |
| dbus_props[str(p)] = dbus_prop.getBaseValue() |
| cPickle.dump(dbus_props,output) |
| except Exception as e: |
| print "ERROR: "+str(e) |
| finally: |
| output.close() |
| |
| def loadFromCache(self,bus_name, object_path, interface_name): |
| ## overlay with pickled data |
| filename=self.getCacheFilename(object_path,interface_name) |
| if (os.path.isfile(filename)): |
| print "Loading from cache: "+filename |
| try: |
| p = open(filename, 'rb') |
| data = cPickle.load(p) |
| obj = bus.get_object(bus_name,object_path) |
| ## TODO: don't use exception to determine whether interface is implemented |
| try: |
| intf = dbus.Interface(obj,"org.openbmc.Object.Properties") |
| props = intf.SetMultiple(interface_name,data) |
| except TypeError as t: |
| print "SetMultiple interface doesn't exist, doing 1 set a time" |
| intf = dbus.Interface(obj,dbus.PROPERTIES_IFACE) |
| for prop in data: |
| intf.Set(interface_name,prop,data[prop]) |
| |
| |
| except Exception as e: |
| print "ERROR: Loading cache file: " +str(e) |
| finally: |
| p.close() |
| |
| |
| if __name__ == '__main__': |
| dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) |
| bus = Openbmc.getDBus() |
| name = dbus.service.BusName(DBUS_NAME,bus) |
| obj = PropertyManager(bus,OBJ_NAME) |
| mainloop = gobject.MainLoop() |
| |
| print "Running Property Manager" |
| mainloop.run() |
| |