1#!/usr/bin/env python
2
3# Contributors Listed Below - COPYRIGHT 2016
4# [+] International Business Machines Corp.
5#
6#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11#     http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16# implied. See the License for the specific language governing
17# permissions and limitations under the License.
18
19import obmc.mapper
20import obmc.utils.dtree
21import obmc.utils.pathtree
22import dbus
23import os
24import subprocess
25import tempfile
26
27
28def transform(path, o):
29    if not o:
30        # discard empty path elements
31        # and empty objects
32        return None
33
34    for name, value in o.items():
35        if any(value == x for x in ['', []]):
36            # discard empty properties
37            del o[name]
38            continue
39
40        if any(name == x for x in ['endpoints']):
41            # discard associations
42            del o[name]
43            continue
44
45        # fix up properties/values to follow DT conventions
46        rename = name
47        revalue = value
48
49        # make is-fru a real boolean
50        if rename == 'is_fru':
51            revalue = 'True' if revalue == 1 else 'False'
52
53        # swap underscore/space for dash in property name
54        rename = rename.replace('_', '-')
55        rename = rename.replace(' ', '-')
56
57        # convert to lower case
58        rename = rename.lower()
59
60        # strip trailing whitespace from strings
61        rename = rename.rstrip()
62        if isinstance(revalue, basestring):
63            revalue = revalue.rstrip()
64
65        # update if any changes were made
66        if name != rename or value != revalue:
67            o[rename] = revalue
68            del o[name]
69
70    path_elements = filter(bool, path.split('/'))
71    path = "/%s" % '/'.join(path_elements[4:-1])
72    # inject the location property
73    o['location'] = "Physical:%s" % path
74
75    # flatten the tree into a single 'bmc/inventory' node
76    path = "/%s" % '/'.join(['bmc', 'inventory', path_elements[-1]])
77    return path, o
78
79
80if __name__ == '__main__':
81    bus = dbus.SystemBus()
82    objs = obmc.utils.pathtree.PathTree()
83
84    mapper = obmc.mapper.Mapper(bus)
85    for path, props in \
86            mapper.enumerate_subtree(
87                path='/org/openbmc/inventory/system').iteritems():
88        item = transform(path, props)
89        if item:
90            objs[item[0]] = item[1]
91
92    rpipe, wpipe = os.pipe()
93    rpipe = os.fdopen(rpipe, 'r')
94    wpipe = os.fdopen(wpipe, 'a')
95
96    wpipe.write('/dts-v1/;')
97    obmc.utils.dtree.dts_encode(objs.dumpd(), wpipe)
98    wpipe.close()
99    h, tmpfile = tempfile.mkstemp()
100    try:
101        wfile = os.fdopen(h, 'w')
102        subprocess.call(
103            ['dtc', '-O', 'dtb'],
104            stdin=rpipe,
105            stdout=wfile)
106        rpipe.close()
107        wfile.close()
108
109        print "Uploading inventory to PNOR in dtb format..."
110        subprocess.call(['pflash', '-f', '-e', '-p', tmpfile, '-P', 'BMC_INV'])
111    except:
112        os.remove(tmpfile)
113        raise
114
115    os.remove(tmpfile)
116