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