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