1#!/usr/bin/env python
2
3import os
4import sys
5# TODO: openbmc/openbmc#2994 remove python 2 support
6try:  # python 2
7    import gobject
8except ImportError:  # python 3
9    from gi.repository import GObject as gobject
10import dbus
11import dbus.service
12import dbus.mainloop.glib
13import obmc.dbuslib.propertycacher as PropertyCacher
14from obmc.dbuslib.bindings import get_dbus, DbusProperties, DbusObjectManager
15
16
17INTF_NAME = 'org.openbmc.InventoryItem'
18DBUS_NAME = 'org.openbmc.Inventory'
19
20FRUS = {}
21
22
23class Inventory(DbusProperties, DbusObjectManager):
24    def __init__(self, bus, name):
25        super(Inventory, self).__init__(
26            conn=bus,
27            object_path=name)
28
29
30class InventoryItem(DbusProperties):
31    def __init__(self, bus, name, data):
32        super(InventoryItem, self).__init__(
33            conn=bus,
34            object_path=name)
35
36        self.name = name
37
38        if 'present' not in data:
39            data['present'] = 'False'
40        if 'fault' not in data:
41            data['fault'] = 'False'
42        if 'version' not in data:
43            data['version'] = ''
44
45        self.SetMultiple(INTF_NAME, data)
46
47        # this will load properties from cache
48        PropertyCacher.load(name, INTF_NAME, self.properties)
49
50    @dbus.service.method(
51        INTF_NAME, in_signature='a{sv}', out_signature='')
52    def update(self, data):
53        self.SetMultiple(INTF_NAME, data)
54        PropertyCacher.save(self.name, INTF_NAME, self.properties)
55
56    @dbus.service.method(
57        INTF_NAME, in_signature='s', out_signature='')
58    def setPresent(self, present):
59        self.Set(INTF_NAME, 'present', present)
60        PropertyCacher.save(self.name, INTF_NAME, self.properties)
61
62    @dbus.service.method(
63        INTF_NAME, in_signature='s', out_signature='')
64    def setFault(self, fault):
65        self.Set(INTF_NAME, 'fault', fault)
66        PropertyCacher.save(self.name, INTF_NAME, self.properties)
67
68
69def getVersion():
70    version = "Error"
71    with open('/etc/os-release', 'r') as f:
72        for line in f:
73            p = line.rstrip('\n')
74            parts = line.rstrip('\n').split('=')
75            if (parts[0] == "VERSION_ID"):
76                version = parts[1]
77                version = version.strip('"')
78    return version
79
80
81if __name__ == '__main__':
82    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
83    bus = get_dbus()
84    mainloop = gobject.MainLoop()
85    obj_parent = Inventory(bus, '/org/openbmc/inventory')
86    INVENTORY_FILE = os.path.join(sys.prefix, 'share',
87                                  'inventory', 'inventory.json')
88
89    if os.path.exists(INVENTORY_FILE):
90        import json
91        with open(INVENTORY_FILE, 'r') as f:
92            try:
93                inv = json.load(f)
94            except ValueError:
95                print("Invalid JSON detected in " + INVENTORY_FILE)
96            else:
97                FRUS = inv
98    else:
99        try:
100            import obmc_system_config as System
101            FRUS = System.FRU_INSTANCES
102        except ImportError:
103            pass
104
105    for f in list(FRUS.keys()):
106        import obmc.inventory
107        obj_path = f.replace("<inventory_root>", obmc.inventory.INVENTORY_ROOT)
108        obj = InventoryItem(bus, obj_path, FRUS[f])
109        obj_parent.add(obj_path, obj)
110
111        # TODO:  this is a hack to update bmc inventory item with version
112        # should be done by flash object
113        if (FRUS[f]['fru_type'] == "BMC"):
114            version = getVersion()
115            obj.update({'version': version})
116
117    obj_parent.unmask_signals()
118    name = dbus.service.BusName(DBUS_NAME, bus)
119    print("Running Inventory Manager")
120    mainloop.run()
121
122# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
123