Firmware update over Redfish

Author: Andrew Geissler (geissonator)

Created: 2019-02-11

Problem Description

OpenBMC is moving to Redfish as its standard for out of band management. Redfish has its own API's and methods for updating firmware on a system and implementing those is going to require some changes (and potential upstream work with the DMTF).

The goal of this design document is to lay out the required changes of moving OpenBMC's existing firmware update implementation over to Redfish.

Background and References

The existing firmware update details for OpenBMC can be found here. It uses a custom REST api for uploading and then activating the input image.

The Redfish schema for firmware update can be found here. Note the referenced doc points to the most recent version of the schema and that is what you'll want to load into your browser (at the time of this writing it is v1_4_0).

Some differences between the Redfish API and OpenBMC's existing API:

  • Redfish has a single upload and update API. OpenBMC has a concept of uploading an image with one API and then activating with another.
  • Redfish does not support multiple firmware images being associated with the same target. OpenBMC does have support for this concept (for example when a target like the BMC has multiple flash chips associated with it). A discussion has been started with the DMTF on this within Issue 3357
    • OpenBMC has the concept of a priority that allows a user to chose an image associated with a target for activation. This allows a user to easily switch back and forth between multiple images for a single target without uploading each image every time.
  • Redfish does not support deleting a firmware image (this happens by default when a new image is uploaded)
  • Redfish does support the ability to update multiple targets with the same image with the same command. OpenBMC does not support this currently.
  • Redfish has support via a SimpleUpdate action which allows the user to pass in a variety of remote locations to retrieve a file from (FTP, HTTP, SCP, ...). Existing OpenBMC only has support for TFTP.
  • Redfish has the ability to schedule when a firmware update is applied (Immediate, OnReset, AtMaintenanceWindowStart...). Existing OpenBMC firmware has no concept of this.

A lot of companies that are implementing Redfish have chosen to create OEM commands for their firmware update implementations (ref a, ref b).

Redfish firmware update within OpenBMC has already started within bmcweb and this design will be proposing enhancements to that as a base.

Requirements

Breaking this into two sections. The first is what should be done for the next OpenBMC 2.7 release. The other section is future items that will get done, but not guaranteed for the 2.7 release. The goal with 2.7 is to have feature parity with what the existing OpenBMC REST api's provide.

2.7 Requirements

  • Support FirmwareInventory definition for BMC and BIOS under UpdateService
    • Support FirmwareVersion under Managers/BMC
    • Support BiosVersion under Systems/system
  • Support firmware update for all supported targets (BMC, BIOS) using existing Redfish API's (/redfish/v1/UpdateService)
    • Note that after further discussion with the DMTF, the existing UpdateService is considered to be OEM. Issue 3296 addresses this and will be implemented by OpenBMC once approved. The existing API will continue to be supported within the Redfish specification so the OpenBMC 2.7 release will support this.
    • Must provide status to user on their image during an update
  • Support a subset of ApplyTime (Immediate, OnReset)
  • Support a TFTP based SimpleUpdate
    • This must be configurable (enable/disable) via compile option within bmcweb

Future Requirements

Note: TODO: The goal of this section is to document at a high level what will be required post 2.7 release. An update to this design document will be required before these requirements are implemented. They are here to ensure nothing in the base design would inhibit the ability to implement these later.

  • Support new concept defined in PR 3420 to be able to support multiple firmware images for a single target.
  • Support new UpdateService firmware update implementation defined in Issue 3296
  • Support firmware update for other targets (power supplies, voltage regulators, ...)
  • Support to update multiple targets with the same firmware image at once
  • Support scheduling of when update occurs (Maintenance windows)
  • Support remaining TransferProtocolTypes in UpdateService (CIFS, FTP, SFTP, HTTP, HTTPS, NSF, SCP, NFS)
    • TODO: Any update mechanism that doesn't have transport security on its own, like FTP, needs a secondary verification mechanism. Update mechanisms that have transport security need a way to adjust the trusted root certificates.
  • Support the Task schema to provide progress to user during upload and activation phases

Proposed Design

Update An Image

The pseudo flow for an update is:

Discover UpdateService location
HttpPushUri = GET https://${bmc}/redfish/v1/UpdateService
POST ApplyTime property in
  UpdateService/HttpPushUriOptions->HttpPushUriApplyTime object
  (Immediate or OnReset)
POST <image> https://${bmc}/${HttpPushUri}

This will cause the following on the back-end:

  • Receive the image
  • Copy it internally to the required location in the filesystem (/tmp/images)
  • Wait for the InterfacesAdded signal from /xyz/openbmc_project/software
  • Activate the new image
  • If ApplyTime is Immediate, reboot the BMC or Host
  • If ApplyTime is OnReset, do nothing (user will need to initiate host or bmc reboot to apply image)

Note that the ApplyTime property will be processed by the software management stack at the end of the activation. Note that the ApplyTime property is global to all firmware update packages and will be used for all subsequent firmware update packages.

Status of an Image

The user needs to know the status of their firmware images, especially during an update. The Task concept is still being defined within the DMTF and will provide the full status of an image during upload and activate. Using the Status object associated with the software inventory items will be used as a mechanism to provide status of inventory items back to the user. Here is the mapping of phosphor activation states to Redfish Status States.

NotReady   -> Disabled
Invalid    -> Disabled
Ready      -> Disabled
Activating -> Updating
Active     -> Enabled
Failed     -> Disabled

Change the Priority of an Image

On OpenBMC systems that support multiple flash images for one target, there will still be pseudo support for this using Redfish. The first image will be uploaded to a system, written to flash chip 0, and activated. If another image is uploaded, it will be written to flash chip 1 and activated. The first image still exists in flash chip 0 and could be re-activated by the user.

As defined in DMTF issue 3357, use the ActiveSoftwareImage concept within the Redfish Settings object to allow the user to select the image to activate during the next activation window. Internally OpenBMC has the concept of a priority being assigned to each image associated with a target. OpenBMC firmware will continue to do this, but will simply set the "ActiveSoftwareImage" image to priority 0 (highest) to ensure it is activated during the next activation window. After setting the priority to 0, the software manager automatically updates the priority of the other images as needed.

Remote Image Download Based Update

As noted above, Redfish supports a SimpleUpdate object under the UpdateService. The SimpleUpdate schema supports a variety of transfer protocols (CIFS, FTP, TFTP, ...). The existing back end of OpenBMC only supports TFTP so initially that is all that will be supported via Redfish on OpenBMC.

The Redfish API takes a parameter, ImageURI, which contains both the server address information and the name of the file. The back end software manager interface on OpenBMC requires two parameters, the TFTP server address and the file name so there will be some parsing required.

The pseudo flow for an update is:

# Discover SimpleUpdate URI Action location
GET https://${bmc}/redfish/v1/UpdateService

# Configure when the new image should be applied
POST ApplyTime property in
  UpdateService/HttpPushUriOptions->HttpPushUriApplyTime object
  (Immediate or OnReset)

# Request OpenBMC to download from TFTP server and activate the image
POST https://${bmc}/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate
    [ImageURI=<tftp server ip>/<file name>, TransferProtocol=TFTP]

TFTP is an insecure protocol. There is no username or password associated with it and no validation of the input URL. OpenBMC does have signed image support which is, by default, part of the update process. The user must have administration authority to request this update so it is assumed they know what they are doing and the level of security available with TFTP.

Due to the security concerns with TFTP, this feature will be disabled by default within bmcweb but can be enabled via a compile flag (see CMakeLists.txt within bmcweb repository for details).

Delete an Image

No support for deleting an image will be provided (until the DMTF provides it). When new images are uploaded, they by default have no priority. When they are activated, they are given the highest priority and all other images have their priority updated as needed. When no more space is available in flash filesystem, the lowest priority image will be deleted when a new one is uploaded and activated.

Alternatives Considered

Could simply create Redfish OEM api's that look like OpenBMC's current custom REST api's. The porting would be minimal but then OpenBMC would not conform to any standard Redfish API's. Other vendors have done this but the Redfish DMTF is making strides towards enhancing the UpdateService to contain the features required to make an enterprise based firmware update API. OpenBMC should just stay at the forefront of these DMTF changes and ensure they are implemented as they are released.

Impacts

This will be using the existing D-Bus API's for firmware update internally so there should be minimal impact between the previous REST implementation.

OpenBMC has two implementations of firmware update. Different systems have implemented different implementations. To be clear, this design will be using the D-Bus API's behind the Software Version Management implementation.

Testing

End to end tests are being written for the firmware update of BMC and BIOS firmware, these must pass. Also unit tests must be written with the required D-Bus API's mocked to ensure proper code coverage.