openbmc / bmcweb

A do everything Redfish, KVM, GUI, and DBus webserver for OpenBMC
Apache License 2.0
166 stars 135 forks source link

Firmware update doesn't give progress status #75

Closed gkeishin closed 5 years ago

gkeishin commented 5 years ago

Upload image

$ curl -k -H "X-Auth-Token: $bmc_token" -H "Content-Type: application/octet-stream" -X POST -T ./obmc-phosphor-image-witherspoon.ubi.mtd.tar https://${BMC_IP}/redfish/v1/UpdateService
{
  "@Message.ExtendedInfo": [
    {
      "@odata.type": "/redfish/v1/$metadata#Message.v1_0_0.Message",
      "Message": "Successfully Completed Request",
      "MessageArgs": [],
      "MessageId": "Base.1.4.0.Success",
      "Resolution": "None",
      "Severity": "OK"
    }
  ]
}

From the journald, I can see the image is uploaded and untared

$  curl -k -H "X-Auth-Token: $bmc_token" -X GET https://${BMC_IP}/redfish/v1/UpdateService/FirmwareInventory
{
  "@odata.context": "/redfish/v1/$metadata#SoftwareInventoryCollection.SoftwareInventoryCollection",
  "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory",
  "@odata.type": "#SoftwareInventoryCollection.SoftwareInventoryCollection",
  "Members": [
    {
      "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/9a8028ec"
    },
    {
      "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/dd4a932d"
    }
  ],
  "Members@odata.count": 2,
  "Name": "Software Inventory Collection",
  "error": {
    "@Message.ExtendedInfo": [
      {
        "@odata.type": "/redfish/v1/$metadata#Message.v1_0_0.Message",
        "Message": "The request failed due to an internal service error.  The service is still operational.",
        "MessageArgs": [],
        "MessageId": "Base.1.4.0.InternalError",
        "Resolution": "Resubmit the request.  If the problem persists, consider resetting the service.",
        "Severity": "Critical"
      }
    ],
    "code": "Base.1.4.0.InternalError",
    "message": "The request failed due to an internal service error.  The service is still operational."
  }
}

So I dont see the image I'm trying to update, so I checked the /tmp/images/8d2586e3 and found the magic id 8d2586e3

$  curl -k -H "X-Auth-Token: $bmc_token" -X GET https://${BMC_IP}/redfish/v1/UpdateService/FirmwareInventory/8d2586e3
{
  "@odata.context": "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory",
  "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/8d2586e3",
  "@odata.type": "#SoftwareInventory.v1_1_0.SoftwareInventory",
  "Description": "BMC update",
  "Id": "8d2586e3",
  "Members@odata.count": 1,
  "Name": "Software Inventory",
  "RelatedItem": [
    {
      "@odata.id": "/redfish/v1/Managers/bmc"
    }
  ],
  "Status": {
    "Health": "OK",
    "HealthRollup": "OK",
    "State": "Enabled"
  },
  "Updateable": false,
  "Version": "2.7.0-dev-430-g7443ee8"
}

So now I can see the image properties but I dont know for sure if the update is completed or not. I know for sure the update hasnt completed since I see the install is going on when I query the GET request on the image id of the code update in progress..

Couple of things:

  1. How do I know if the update is in progress or not ? without looking at the traces but from redfish interface o/p.
  2. When we do GET /redfish/v1/UpdateService/FirmwareInventory during update it throws error in above o/p, could we do it better response data there
gkeishin commented 5 years ago

@geissonator if there are way how to detect without looking at the journald that would help here..

edtanous commented 5 years ago

Redfish would probably recommend TaskService for this kind of long running operation.

geissonator commented 5 years ago

Yeah there's a big discussion ongoing within the DMTF on code update and task services. I think it's best to let that settle and come back to Redfish UpdateService in OpenBMC release 2.8. We have the basics in place now for 2.7 so if people need it, it's there. Lets wait for the DMTF to sort things out a bit more before we do much more work.

With that said, similar things can be done that were recommended via the REST service update path. Like pre-hashing the image to figure out the identifier and then polling for that to show up in the firmware inventory.

I'm thinking I should use this issue to properly fill in the "Status" field. Only set it to OK/Enabled once the update has completed?

geissonator commented 5 years ago

My proposal here is the following:

Change doGet on /redfish/v1/UpdateService/FirmwareInventory/ to return all software inventory items (not just what we do now, xyz.openbmc_project.Software.Activation.Activations.Active)

We then change the code in the get of "/redfish/v1/UpdateService/FirmwareInventory/swID/" to put the correct "Status" in the returned object. It's currently hard coded to this:

res.jsonValue["Status"]["Health"] = "OK";
res.jsonValue["Status"]["HealthRollup"] = "OK";
res.jsonValue["Status"]["State"] = "Enabled";

The possible software states are defined in https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software/Activation.interface.yaml. Here's a proposed mapping to the Redfish Status for them:

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

Redfish Status object is defined in http://redfish.dmtf.org/schemas/v1/Resource.json#/definitions/Status

If this looks ok to people I can get a design doc update loaded into gerrit with this. This would give user of the Redfish UpdateService more insight into what firmware is available and it's different states.

geissonator commented 5 years ago

Design doc update is in https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/21986