1# Config Files
2
3## Intent
4
5Configuration files are intended to represent the minimum amount of
6configuration required to describe a given piece of hardware. As such, they are
7intended to be simple, and are guided by the following principles.
8
91. Configuration files should be easy to write. If a tradeoff is to be made
10   between a config file being complex to write, and a reactor being complex to
11   write, the reactor will be the one to hold the complexity. Why?
12
13   - Configuration files will get replicated and built to support hundreds of
14     systems over time, and scale linearly with the number of systems. In
15     contrast, reactors tend to scale as a logarithm of system count, with each
16     new system supported adding fewer and fewer reactors. As such, pushing the
17     complexity to the reactors leads to fewer lines of code overall, even if
18     the reactor itself contains more complex actions.
19   - Reactor writers tend to be domain experts on their subsystem, and
20     intimately understand the constraints that are emplaced on that subsystem.
21     Config file writers are generally building support for a wide range of
22     reactors on a single piece of hardware, and will generally have less
23     knowledge of each individual reactors constraints.
24
252. Configuration files should trend toward one config file per physical piece of
26   hardware, and should avoid attempting to support multiple variations of a
27   given piece of hardware in a single file, even at the risk of duplicating
28   information. Why?
29
30   - Hardware constraints, bugs, and oddities are generally found over time. The
31     initial commit of a configuration file is far from the final time that
32     changes will be submitted. Having each individual piece of hardware in its
33     own file minimizes the change needed between different components when bugs
34     are found, or features are added.
35   - Having separate config files reduces the number of platforms that need to
36     be tested for any given config file change, thus limiting the "blast
37     radius" of particular kinds of changes, as well as making an explicit log
38     of what changed for a specific platform.
39   - Having one config file per piece of hardware makes it much easier and clear
40     for a user to determine if a piece of hardware is supported.
41   - Note: This is a "guideline" not a "rule". There are many cases of hardware
42     that despite having different part numbers, are actually physically
43     identical, and as such, the config files will never differ.
44     - Example: SAS modules and cards made by the same company, on the same
45       process, and branded with different manufacturers and part numbers.
46     - Non-Example: Power supplies. While all pmbus power supplies appear
47       similar, there tend to be significant differences in featuresets, bugs,
48       and OEM supported firmware features. As such, they require separate
49       config files.
50
513. Configuration files are not a long-term stable ABI. Why?
52
53   - Configuration files occasionally need to modify their schema in pursuit of
54     simplicity, or based on a greater understanding of the system level
55     constraints.
56   - The repo will ensure that all schema changes are enacted such that the
57     files in the repo will not be broken as a result of the schema change, and
58     will be carried forward. The recommended way to avoid merge problems is to
59     upstream your configurations.
60   - Note: This drives the requirement that config files shall not be checked
61     into OpenBMC meta layers.
62
634. Configurations should represent only the things that are _different_ and
64   undetectable between platforms. Why?
65   - There are many behaviors that the BMC has that are very easily detected at
66     runtime, or where the behavior can be identical between different
67     platforms. Things like timeouts, protocol versions, and communcation
68     channels can generally be represented with a default that works for all
69     platforms, and doesn't need to be an entity-configurable parameter. In
70     general, reducing the config files to _only_ the differences reduces
71     complexity, and explicitly bounds where dicsussion is needed for platform
72     differences, and where a difference is "supported" and "reasonable" to
73     maintain in the long run.
74
75## Configuration Syntax
76
77In most cases a server system is built with multiple hardware modules (circuit
78boards) such as baseboard, risers, and hot-swap backplanes. While it is
79perfectly legal to combine the JSON configuration information for all the
80hardware modules into a single file if desired, it is recommended to divide them
81into multiple configuration files. For example, there may be a baseboard JSON
82file (describes all devices on the baseboard) and a chassis JSON file (describes
83devices attached to the chassis). Other examples of entities might be removable
84power supplies, fans, and PCIe add in cards.
85
86Within a configuration file, there is a JSON object which consists of multiple
87"string : value" pairs. This Entity Manager defines the following strings.
88
89| String        | Example Value                                                       | Description                                                                                                                                                                                                                                                                                                   |
90| :------------ | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
91| "Name"        | `"X1000 1U Chassis"`                                                | Human readable name used for identification and sorting.                                                                                                                                                                                                                                                      |
92| "Probe"       | `"xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME':'FFPANEL'})"` | Statement which attempts to read from d-bus. The result determines if a configuration record should be applied. The value for probe can be set to “TRUE” in the case the record should always be applied, or set to more complex lookups, for instance a field in a FRU file that is exposed by the frudevice |
93| "Exposes"     | `[{"Name" : "CPU fan"}, ...]`                                       | An array of JSON objects which are valid if the probe result is successful. These objects describe the devices BMC can interact.                                                                                                                                                                              |
94| "Status"      | `"disabled"`                                                        | An indicator that allows for some records to be disabled by default.                                                                                                                                                                                                                                          |
95| "Bind\*"      | `"2U System Fan connector 1"`                                       | The record isn't complete and needs to be combined with another to be functional. The value is a unique reference to a record elsewhere.                                                                                                                                                                      |
96| "DisableNode" | `"Fan 1"`                                                           | Sets the status of another Entity to disabled.                                                                                                                                                                                                                                                                |
97
98Template strings in the form of "$identifier" may be used in configuration
99files. The following table describes the template strings currently defined.
100
101| Template String | Description                                                                                                                                                                                                                         |
102| :-------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
103| "$bus"          | During a I2C bus scan and when the "probe" command is successful, this template string is substituted with the bus number to which the device is connected.                                                                         |
104| "$address"      | When the "probe" is successful, this template string is substituted with the (7-bit) I2C address of the FRU device.                                                                                                                 |
105| "$index"        | A run-tim enumeration. This template string is substituted with a unique index value when the "probe" command is successful. This allows multiple identical devices (e.g., HSBPs) to exist in a system but each with a unique name. |
106
107## Configuration HowTos
108
109If you're just getting started and your goal is to add sensors dynamically,
110check out [My First Sensors](docs/my_first_sensors.md)
111
112## Configuration schema
113
114The config schema is documented in [README.md](schemas/README.md)
115
116## Configuration Records - Baseboard Example
117
118The configuration JSON files attempt to model the actual hardware modules which
119make up a complete system. An example baseboard JSON file shown below defines
120two fan connectors and two temperature sensors of TMP75 type. These objects are
121considered valid by BMC when the probe command (reads and compares the product
122name in FRU) is successful and this baseboard is named as "WFP baseboard".
123
124```json
125{
126  "Exposes": [
127    {
128      "Name": "1U System Fan connector 1",
129      "Pwm": 1,
130      "Status": "disabled",
131      "Tachs": [1, 2],
132      "Type": "IntelFanConnector"
133    },
134    {
135      "Name": "2U System Fan connector 1",
136      "Pwm": 1,
137      "Status": "disabled",
138      "Tachs": [1],
139      "Type": "IntelFanConnector"
140    },
141    {
142      "Address": "0x49",
143      "Bus": 6,
144      "Name": "Left Rear Temp",
145      "Thresholds": [
146        {
147          "Direction": "greater than",
148          "Name": "upper critical",
149          "Severity": 1,
150          "Value": 115
151        },
152        {
153          "Direction": "greater than",
154          "Name": "upper non critical",
155          "Severity": 0,
156          "Value": 110
157        },
158        {
159          "Direction": "less than",
160          "Name": "lower non critical",
161          "Severity": 0,
162          "Value": 5
163        },
164        {
165          "Direction": "less than",
166          "Name": "lower critical",
167          "Severity": 1,
168          "Value": 0
169        }
170      ],
171      "Type": "TMP75"
172    },
173    {
174      "Address": "0x48",
175      "Bus": 6,
176      "Name": "Voltage Regulator 1 Temp",
177      "Thresholds": [
178        {
179          "Direction": "greater than",
180          "Name": "upper critical",
181          "Severity": 1,
182          "Value": 115
183        },
184        {
185          "Direction": "greater than",
186          "Name": "upper non critical",
187          "Severity": 0,
188          "Value": 110
189        },
190        {
191          "Direction": "less than",
192          "Name": "lower non critical",
193          "Severity": 0,
194          "Value": 5
195        },
196        {
197          "Direction": "less than",
198          "Name": "lower critical",
199          "Severity": 1,
200          "Value": 0
201        }
202      ],
203      "Type": "TMP75"
204    }
205  ],
206  "Name": "WFP Baseboard",
207  "Probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME' : '.*WFT'})"
208}
209```
210
211[Full Configuration](https://github.com/openbmc/entity-manager/blob/master/configurations/WFT_Baseboard.json)
212
213## Configuration Records - Chassis Example
214
215Although fan connectors are considered a part of a baseboard, the physical fans
216themselves are considered as a part of a chassis. In order for a fan to be
217matched with a fan connector, the keyword "Bind" is used. The example below
218shows how a chassis fan named "Fan 1" is connected to the connector named "1U
219System Fan connector 1". When the probe command finds the correct product name
220in baseboard FRU, the fan and the connector are considered as being joined
221together.
222
223```json
224{
225  "Exposes": [
226    {
227      "BindConnector": "1U System Fan connector 1",
228      "Name": "Fan 1",
229      "Thresholds": [
230        {
231          "Direction": "less than",
232          "Name": "lower critical",
233          "Severity": 1,
234          "Value": 1750
235        },
236        {
237          "Direction": "less than",
238          "Name": "lower non critical",
239          "Severity": 0,
240          "Value": 2000
241        }
242      ],
243      "Type": "AspeedFan"
244    }
245  ]
246}
247```
248
249## Enabling Sensors
250
251As daemons can trigger off of shared types, sometimes some handshaking will be
252needed to enable sensors. Using the TMP75 sensor as an example, when the sensor
253object is enabled, the device tree must be updated before scanning may begin.
254The entity-manager can key off of different types and export devices for
255specific configurations. Once this is done, the baseboard temperature sensor
256daemon can scan the sensors.
257
258## C-Style Comments Support
259
260The configuration JSON file supports c-style comments base on the rules as
261below:
262
263- Single-line style comments (//) can be on a new line or at the end of a line
264  with contents.
265
266```json5
267{
268  // Single-line style comment (new line)
269  Key: "Value", // Single-line comment (end of content)
270}
271```
272
273- Multi-line style comments (/\* \*/) use the must be free-standing.
274
275```json5
276{
277  /* Multi-line style comment */
278  /*
279   * Multi-line style comments
280   */
281}
282```
283
284- When running autojson.py on a configuration JSON file, the comments will be
285  removed first and then get inserted back into the file in the line they came
286  from. If keys are resorted or the number of lines change, all bets for
287  correctness are off.
288
289- No attempts to re-indent multi-line comments will be made.
290
291In light of this, it is highly recommended to use a JSON formatter such as
292prettier before using this script and planning to move multi-line comments
293around after key resorting.
294