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        # convert to lower case
50        rename = rename.lower()
51
52        # force name to be a string
53        if rename == 'name' and isinstance(revalue, list):
54            revalue = ''.join([str(x) for x in revalue])
55
56        # make is-fru a real boolean
57        if rename == 'is_fru':
58            revalue = 'True' if revalue == 1 else 'False'
59
60        # swap underscore/space for dash in property name
61        rename = rename.replace('_', '-')
62        rename = rename.replace(' ', '-')
63
64        # strip trailing whitespace from strings
65        rename = rename.rstrip()
66        if isinstance(revalue, basestring):
67            revalue = revalue.rstrip()
68
69        # update if any changes were made
70        if name != rename or value != revalue:
71            o[rename] = revalue
72            del o[name]
73
74    path_elements = filter(bool, path.split('/'))
75    path = "/%s" % '/'.join(path_elements[4:-1])
76    # inject the location property
77    o['location'] = "Physical:%s" % path
78
79    # flatten the tree into a single 'bmc/inventory' node
80    path = "/%s" % '/'.join(['bmc', 'inventory', path_elements[-1]])
81    return path, o
82
83
84if __name__ == '__main__':
85    bus = dbus.SystemBus()
86    objs = obmc.utils.pathtree.PathTree()
87
88    mapper = obmc.mapper.Mapper(bus)
89    for path, props in \
90            mapper.enumerate_subtree(
91                path='/org/openbmc/inventory/system').iteritems():
92        item = transform(path, props)
93        if item:
94            objs[item[0]] = item[1]
95
96    rpipe, wpipe = os.pipe()
97    rpipe = os.fdopen(rpipe, 'r')
98    wpipe = os.fdopen(wpipe, 'a')
99
100    wpipe.write('/dts-v1/;')
101    obmc.utils.dtree.dts_encode(objs.dumpd(), wpipe)
102    wpipe.close()
103    h, tmpfile = tempfile.mkstemp()
104    try:
105        wfile = os.fdopen(h, 'w')
106        subprocess.call(
107            ['dtc', '-O', 'dtb'],
108            stdin=rpipe,
109            stdout=wfile)
110        rpipe.close()
111        wfile.close()
112
113        print "Uploading inventory to PNOR in dtb format..."
114        subprocess.call(['pflash', '-f', '-e', '-p', tmpfile, '-P', 'BMC_INV'])
115    except Exception:
116        os.remove(tmpfile)
117        raise
118
119    os.remove(tmpfile)
120