1# BMC Handler Configuration
2
3The BMC BLOB handler for the flash objects is configured at run-time via a json
4file or multiple json files. The json fields detail every aspect of how the
5handler should behave for a given blob id.
6
7There are three json configurations available by default:
8
9*   config-bios.json
10*   config-static-bmc-reboot.json
11*   config-static-bmc.json
12
13Let's break them down, what they contain and what it means, and then how to
14write your own. It's helpful to start here.
15
16## config-bios.json
17
18This file is generated from configuration and therefore some values can be
19replaced, here we're using the defaults.
20
21```
22[{
23    "blob": "/flash/bios",
24    "handler": {
25        "type": "file",
26        "path": "/tmp/bios-image"
27    },
28    "actions": {
29        "preparation": {
30            "type": "systemd",
31            "unit": "phosphor-ipmi-flash-bios-prepare.target"
32        },
33        "verification": {
34            "type": "fileSystemdVerify",
35            "unit": "phosphor-ipmi-flash-bios-verify.target",
36            "path": "/tmp/bios.verify"
37        },
38        "update": {
39            "type": "systemd",
40            "unit": "phosphor-ipmi-flash-bios-update.target"
41        }
42    }
43}]
44```
45
46Each json file is expected to be an array of flash handler configurations. You
47can define more than one handler inside a json file, or you can have one per
48file. It will make no difference. The file though, must contain an array.
49
50Beyond this, the flash handler configuration is a dictionary or object with
51three fields.
52
53*   `blob`
54*   `handler`
55*   `actions`
56
57### `blob`
58
59The `blob` field expects to hold a string. This string is the blob id that'll be
60presented to the host and registered with the blob manager. It must be unique
61among all blobs on a system and must start with `/flash/`. The uniqueness is not
62presently verified at any stage. If there is another blob id that matches, the
63first one loaded will be the first one hit during any calls from the host. It's
64generally unlikely that there will be a name collision.
65
66### `handler`
67
68The `handler` field expects to hold a dictionary or object with at least one
69field.
70
71*   `type`
72
73The `type` field expects a string and will control what other parameters are
74required. The type here refers to the handler for the incoming data associated
75with the flash image contents. The hash data is always done as a file, but the
76image data is configurable via the json.
77
78In the above configuration the `type` is set to `file`. The `file` type handler
79requires one parameter: `path`. The `path` here is the full file system path to
80where to write the bytes received into a file. In this case specifically the
81byte received will be written to `/tmp/bios-image`.
82
83### `actions`
84
85Because `phosphor-ipmi-flash` is a framework for sending data from the host to
86the BMC for updating various firmware, it needs to be told what to do to verify
87the data and cause an update. It additionally provides a mechanism for preparing
88the BMC to receive the data. On a low memory BMC, the preparation step can be
89used to shut down unnecessary services, etc.
90
91The actions are split into three fields:
92
93*   `preparation`
94*   `verification`
95*   `update`
96
97The `preparation`, `verification`, and `update` fields expect a `type` field,
98similarly to the `handler` field. This dictates what other parameters may be
99required.
100
101In this configuration the `preparation` type is `systemd`. The `systemd` type
102expects to receive a `unit`. The `unit` value is expected to be a string that is
103the name of the systemd unit to start. In this case, it'll start
104`phosphor-ipmi-flash-bios-prepare.target`. This can be a single service name, or
105a target.
106
107In this configuration the `verification` type is `fileSystemdVerify`. This is
108similar to the `systemd` type except it also expects a `path`. The `path` is
109used to read back the status of whatever was triggered via the `unit` field. Was
110the verification successful? Is the verification still in progress? This
111information is read back from the file specified by the `path` field.
112
113In this configuration the `update` type is `systemd`. This is the same object as
114with the `preparation` action. In this case, though the status cannot be read
115back with something useful. Typically, the `fileSystemdVerify` type should be
116used as it provides information on success.
117
118## config-static-bmc-reboot.json
119
120This file is generated from configuration and therefore some values can be
121replaced, here we're using the defaults.
122
123```
124[{
125    "blob": "/flash/image",
126    "handler": {
127        "type": "file",
128        "path": "/run/initramfs/bmc-image"
129    },
130    "actions": {
131        "preparation": {
132            "type": "systemd",
133            "unit": "phosphor-ipmi-flash-bmc-prepare.target"
134        },
135        "verification": {
136            "type": "fileSystemdVerify",
137            "unit": "phosphor-ipmi-flash-bmc-verify.target",
138            "path": "/tmp/bmc.verify"
139        },
140        "update": {
141            "type": "reboot"
142        }
143    }
144}]
145```
146
147Given the bios configuration, we can skip the parts of this configuration that
148are already explained. The new action type is `reboot`. This is a special action
149type that has no parameters. It will simply trigger a reboot via systemd.
150
151## config-static-bmc.json
152
153This file is generated from configuration and therefore some values can be
154replaced, here we're using the defaults.
155
156```
157[{
158    "blob": "/flash/image",
159    "handler": {
160        "type": "file",
161        "path": "/run/initramfs/bmc-image"
162    },
163    "actions": {
164        "preparation": {
165            "type": "systemd",
166            "unit": "phosphor-ipmi-flash-bmc-prepare.target"
167        },
168        "verification": {
169            "type": "fileSystemdVerify",
170            "unit": "phosphor-ipmi-flash-bmc-verify.target",
171            "path": "/tmp/bmc.verify"
172        },
173        "update": {
174            "type": "systemd",
175            "unit": "phosphor-ipmi-flash-bmc-update.target"
176        }
177    }
178}]
179```
180
181This configuration is of no significance in its difference.
182
183## Writing your own json Configuration
184
185If you wish to write your own json configuration, you simply create a legal json
186file containing an array of at least one entry. This array will define any
187entries you wish. You can provide multiple BMC update json configurations if you
188wish. There may be parameters you desire to pass to an update process, for
189instance, clearing the whitelisted files. In this case, it's trivial to create
190two targets. The first target performs a normal update, the second starts a
191service that performs the desired other update. You can leverage the
192default-provided configuration files, and also add your own to add additional
193support if desired.
194
195An entry, regardless, must contain a `blob`, a `handler`, and `actions`.
196
197### Handler Types
198
199A handler determines how the bytes from the host are stored.
200
201#### `file`
202
203The `file` handler type writes the bytes to a file path specified by the
204required parameter `path`.
205
206*   `path` - full file system path to where to write bytes.
207
208### Action Types
209
210Action types are used to define what to do for a specific requested action, such
211as "verify the blob contents."
212
213#### `systemd`
214
215The `systemd` type should be used when you wish to start a systemd service or
216target but only care about the status of whether or not you were able to start
217it, not whether it did what you ultimately wanted.
218
219*   `unit` - required - string - the systemd unit to start.
220*   `mode` - optional - string - default: replace - the mode for starting the
221    service.
222
223#### `fileSystemdVerify` & `fileSystemdUpdate`
224
225Because one may care about the result of their actions, the `fileSystemdVerify`
226and `fileSystemdUpdate` action type exists. It will start the service and when
227asked for a status, it'll read the contents of a file. Therefore, whatever is
228performing the action will want to update that file.
229
230*   `path` - required - string - the full file system path to where one finds
231    the status.
232*   `unit` - required - string - the systemd unit to start
233*   `mode` - optional - string - default: replace - the mode for starting the
234    service.
235
236#### `reboot`
237
238The `reboot` type causes a reboot via systemd. If this happens quickly enough,
239you may not receive a response over IPMI that your command succeeded.
240
241### Installing your own json configuration
242
243To install your own configuration(s) you can add your own bbappend file that
244appends to the install task. The json files are installed in
245`${D}${datadir}/phosphor-ipmi-flash/`
246
247## Adding your own handler type
248
249Firstly, welcome! The maintainers of this repository appreciate your
250contribution. A handler is just an implementation of the
251`ImageHandlerInterface`.
252
253Your handler must implement:
254
255*   `bool open(const std::string& path)`
256*   `void close()`
257*   `bool write(std::uint32_t offset, const std::vector<std::uint8_t>& data)`
258*   `int getSize()`
259
260The handler is meant to receive the bytes, and write the bytes.
261
262Once the object is defined you can specify a type and parameters here and in the
263`buildjson` module.
264
265## Adding your own action type
266
267Firstly, welcome! The maintainers of this repository appreciate your
268contribution. An action is just an implementation of the
269`TriggerableActionInterface`.
270
271Your action must implement:
272
273*   `bool trigger()`
274*   `void abort()`
275*   `ActionStatus status()`
276
277The abort method is not a guarantee.
278
279Once the object is defined you can specify a type and parameters here and in the
280`buildjson` module.
281