1# Firmware update over Redfish
2
3Author: Andrew Geissler (geissonator)
4
5Created: 2019-02-11
6
7## Problem Description
8
9OpenBMC is moving to [Redfish][1] as its standard for out of band management.
10Redfish has its own API's and methods for updating firmware on a system and
11implementing those is going to require some changes (and potential upstream work
12with the DMTF).
13
14The goal of this design document is to lay out the required changes of moving
15OpenBMC's existing firmware update implementation over to Redfish.
16
17## Background and References
18
19The existing firmware update details for OpenBMC can be found [here][2]. It uses
20a custom REST api for uploading and then activating the input image.
21
22The Redfish schema for firmware update can be found [here][3]. Note the
23referenced doc points to the most recent version of the schema and that is what
24you'll want to load into your browser (at the time of this writing it is
25[v1_4_0][4]).
26
27Some differences between the Redfish API and OpenBMC's existing API:
28
29- Redfish has a single upload and update API. OpenBMC has a concept of uploading
30  an image with one API and then activating with another.
31- Redfish does not support multiple firmware images being associated with the
32  same target. OpenBMC does have support for this concept (for example when a
33  target like the BMC has multiple flash chips associated with it). A discussion
34  has been started with the DMTF on this within [Issue 3357][10]
35  - OpenBMC has the concept of a priority that allows a user to chose an image
36    associated with a target for activation. This allows a user to easily switch
37    back and forth between multiple images for a single target without uploading
38    each image every time.
39- Redfish does not support deleting a firmware image (this happens by default
40  when a new image is uploaded)
41- Redfish does support the ability to update multiple targets with the same
42  image with the same command. OpenBMC does not support this currently.
43- Redfish has support via a SimpleUpdate action which allows the user to pass in
44  a variety of remote locations to retrieve a file from (FTP, HTTP, SCP, ...).
45  Existing OpenBMC only has support for TFTP.
46- Redfish has the ability to schedule when a firmware update is applied
47  (Immediate, OnReset, AtMaintenanceWindowStart...). Existing OpenBMC firmware
48  has no concept of this.
49
50A lot of companies that are implementing Redfish have chosen to create OEM
51commands for their firmware update implementations ([ref a][5], [ref b][6]).
52
53Redfish firmware update within OpenBMC has already started within [bmcweb][7]
54and this design will be proposing enhancements to that as a base.
55
56## Requirements
57
58Breaking this into two sections. The first is what should be done for the next
59OpenBMC 2.7 release. The other section is future items that will get done, but
60not guaranteed for the 2.7 release. The goal with 2.7 is to have feature parity
61with what the existing OpenBMC REST api's provide.
62
63### 2.7 Requirements
64
65- Support FirmwareInventory definition for BMC and BIOS under UpdateService
66  - Support FirmwareVersion under Managers/BMC
67  - Support BiosVersion under Systems/system
68- Support firmware update for all supported targets (BMC, BIOS) using existing
69  Redfish API's (/redfish/v1/UpdateService)
70  - Note that after further discussion with the DMTF, the existing UpdateService
71    is considered to be OEM. [Issue 3296][11] addresses this and will be
72    implemented by OpenBMC once approved. The existing API will continue to be
73    supported within the Redfish specification so the OpenBMC 2.7 release will
74    support this.
75  - Must provide status to user on their image during an update
76- Support a subset of ApplyTime (Immediate, OnReset)
77- Support a TFTP based SimpleUpdate
78  - This must be configurable (enable/disable) via compile option within bmcweb
79
80### Future Requirements
81
82**Note:** TODO: The goal of this section is to document at a high level what
83will be required post 2.7 release. An update to this design document will be
84required before these requirements are implemented. They are here to ensure
85nothing in the base design would inhibit the ability to implement these later.
86
87- Support new concept defined in [PR 3420][12] to be able to support multiple
88  firmware images for a single target.
89- Support new UpdateService firmware update implementation defined in [Issue
90  3296][11]
91- Support firmware update for other targets (power supplies, voltage regulators,
92  ...)
93- Support to update multiple targets with the same firmware image at once
94- Support scheduling of when update occurs (Maintenance windows)
95- Support remaining TransferProtocolTypes in UpdateService (CIFS, FTP, SFTP,
96  HTTP, HTTPS, NSF, SCP, NFS)
97  - TODO: Any update mechanism that doesn't have transport security on its own,
98    like FTP, needs a secondary verification mechanism. Update mechanisms that
99    have transport security need a way to adjust the trusted root certificates.
100- Support the Task schema to provide progress to user during upload and
101  activation phases
102
103## Proposed Design
104
105### Update An Image
106
107The pseudo flow for an update is:
108
109```
110Discover UpdateService location
111HttpPushUri = GET https://${bmc}/redfish/v1/UpdateService
112POST ApplyTime property in
113  UpdateService/HttpPushUriOptions->HttpPushUriApplyTime object
114  (Immediate or OnReset)
115POST <image> https://${bmc}/${HttpPushUri}
116```
117
118This will cause the following on the back-end:
119
120- Receive the image
121- Copy it internally to the required location in the filesystem (/tmp/images)
122- Wait for the InterfacesAdded signal from /xyz/openbmc_project/software
123- Activate the new image
124- If ApplyTime is Immediate, reboot the BMC or Host
125- If ApplyTime is OnReset, do nothing (user will need to initiate host or bmc
126  reboot to apply image)
127
128Note that the ApplyTime property will be processed by the software management
129stack at the end of the activation. Note that the ApplyTime property is global
130to all firmware update packages and will be used for all subsequent firmware
131update packages.
132
133### Status of an Image
134
135The user needs to know the status of their firmware images, especially during an
136update. The Task concept is still being defined within the DMTF and will provide
137the full status of an image during upload and activate. Using the Status object
138associated with the software inventory items will be used as a mechanism to
139provide status of inventory items back to the user. Here is the mapping of
140[phosphor activation states][13] to [Redfish Status States][14].
141
142```
143NotReady   -> Disabled
144Invalid    -> Disabled
145Ready      -> Disabled
146Activating -> Updating
147Active     -> Enabled
148Failed     -> Disabled
149```
150
151### Change the Priority of an Image
152
153On OpenBMC systems that support multiple flash images for one target, there will
154still be pseudo support for this using Redfish. The first image will be uploaded
155to a system, written to flash chip 0, and activated. If another image is
156uploaded, it will be written to flash chip 1 and activated. The first image
157still exists in flash chip 0 and could be re-activated by the user.
158
159As defined in DMTF issue [3357][10], use the ActiveSoftwareImage concept within
160the Redfish Settings object to allow the user to select the image to activate
161during the next activation window. Internally OpenBMC has the concept of a
162priority being assigned to each image associated with a target. OpenBMC firmware
163will continue to do this, but will simply set the "ActiveSoftwareImage" image to
164priority 0 (highest) to ensure it is activated during the next activation
165window. After setting the priority to 0, the software manager automatically
166updates the priority of the other images as needed.
167
168### Remote Image Download Based Update
169
170As noted above, Redfish supports a SimpleUpdate object under the UpdateService.
171The SimpleUpdate schema supports a variety of transfer protocols (CIFS, FTP,
172TFTP, ...). The existing back end of OpenBMC only supports TFTP so initially
173that is all that will be supported via Redfish on OpenBMC.
174
175The Redfish API takes a parameter, ImageURI, which contains both the server
176address information and the name of the file. The back end software manager
177interface on OpenBMC requires two parameters, the TFTP server address and the
178file name so there will be some parsing required.
179
180The pseudo flow for an update is:
181
182```
183# Discover SimpleUpdate URI Action location
184GET https://${bmc}/redfish/v1/UpdateService
185
186# Configure when the new image should be applied
187POST ApplyTime property in
188  UpdateService/HttpPushUriOptions->HttpPushUriApplyTime object
189  (Immediate or OnReset)
190
191# Request OpenBMC to download from TFTP server and activate the image
192POST https://${bmc}/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate
193    [ImageURI=<tftp server ip>/<file name>, TransferProtocol=TFTP]
194```
195
196TFTP is an insecure protocol. There is no username or password associated with
197it and no validation of the input URL. OpenBMC does have signed image support
198which is, by default, part of the update process. The user must have
199administration authority to request this update so it is assumed they know what
200they are doing and the level of security available with TFTP.
201
202Due to the security concerns with TFTP, this feature will be disabled by default
203within bmcweb but can be enabled via a compile flag (see CMakeLists.txt within
204bmcweb repository for details).
205
206### Delete an Image
207
208No support for deleting an image will be provided (until the DMTF provides it).
209When new images are uploaded, they by default have no priority. When they are
210activated, they are given the highest priority and all other images have their
211priority updated as needed. When no more space is available in flash filesystem,
212the lowest priority image will be deleted when a new one is uploaded and
213activated.
214
215## Alternatives Considered
216
217Could simply create Redfish OEM api's that look like OpenBMC's current custom
218REST api's. The porting would be minimal but then OpenBMC would not conform to
219any standard Redfish API's. Other vendors have done this but the Redfish DMTF is
220making strides towards enhancing the UpdateService to contain the features
221required to make an enterprise based firmware update API. OpenBMC should just
222stay at the forefront of these DMTF changes and ensure they are implemented as
223they are released.
224
225## Impacts
226
227This will be using the existing D-Bus API's for firmware update internally so
228there should be minimal impact between the previous REST implementation.
229
230OpenBMC has two implementations of firmware update. Different systems have
231implemented different implementations. To be clear, this design will be using
232the D-Bus API's behind the [Software Version Management][8] implementation.
233
234## Testing
235
236End to end [tests][9] are being written for the firmware update of BMC and BIOS
237firmware, these must pass. Also unit tests must be written with the required
238D-Bus API's mocked to ensure proper code coverage.
239
240[1]: https://redfish.dmtf.org/
241[2]:
242  https://github.com/openbmc/docs/blob/master/architecture/code-update/code-update.md#steps-to-update
243[3]: http://redfish.dmtf.org/schemas/v1/UpdateService.json
244[4]:
245  http://redfish.dmtf.org/schemas/v1/UpdateService.v1_4_0.json#/definitions/UpdateService
246[5]: https://www.supermicro.com/manuals/other/RedfishRefGuide.pdf
247[6]:
248  https://github.com/dell/iDRAC-Redfish-Scripting/blob/master/Redfish%20Python/DeviceFirmwareDellUpdateServiceREDFISH.py
249[7]:
250  https://github.com/openbmc/bmcweb/blob/master/redfish-core/lib/update_service.hpp
251[8]:
252  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Software/README.md
253[9]: https://github.com/openbmc/openbmc-test-automation
254[10]: https://github.com/DMTF/Redfish/issues/3357
255[11]: https://github.com/DMTF/Redfish/pull/3296
256[12]: https://github.com/DMTF/Redfish/pull/3420
257[13]:
258  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Software/Activation.interface.yaml
259[14]: http://redfish.dmtf.org/schemas/v1/Resource.json#/definitions/Status
260