fwstatus: Enhance state of firmware inventory
Currently there is no mechanism for a user to know the status of their
firmware update over redfish.
The primary focus of this commit is to provide status of a firmware
update. There is still some ongoing discussion on using the Health field
to better explain error conditions. A forum post with DMTF has been
opened for clarification in this area but this commit does get things
going in the right direction. It provides a user with the status of
their update and gives them a simple Enabled/Disabled to know if it
worked.
Tested:
- Firmware update in progress
curl -k -H "X-Auth-Token: $TOKEN" -X GET https://${BMC_IP}/redfish/v1/UpdateService/FirmwareInventory/92e57fc7
{
"@odata.context": "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory",
"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/92e57fc7",
"@odata.type": "#SoftwareInventory.v1_1_0.SoftwareInventory",
"Description": "BMC update",
"Id": "92e57fc7",
"Members@odata.count": 1,
"Name": "Software Inventory",
"RelatedItem": [
{
"@odata.id": "/redfish/v1/Managers/bmc"
}
],
"Status": {
"Health": "OK",
"HealthRollup": "OK",
"State": "Updating"
},
"Updateable": false,
"Version": "2.7.0-dev-926-g79ca37b3d"
}
- Firmware update complete
curl -k -H "X-Auth-Token: $TOKEN" -X GET https://${BMC_IP}/redfish/v1/UpdateService/FirmwareInventory/92e57fc7
{
"@odata.context": "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory",
"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/92e57fc7",
"@odata.type": "#SoftwareInventory.v1_1_0.SoftwareInventory",
"Description": "BMC update",
"Id": "92e57fc7",
"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-926-g79ca37b3d"
}
- Firmware update failed
(xyz.openbmc_project.Software.Activation.Activations.Failed)
curl -k -H "X-Auth-Token: $TOKEN" -X GET https://${BMC_IP}/redfish/v1/UpdateService/FirmwareInventory/3d02a163
{
"@odata.context": "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory",
"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/3d02a163",
"@odata.type": "#SoftwareInventory.v1_1_0.SoftwareInventory",
"Description": "BMC update",
"Id": "3d02a163",
"Members@odata.count": 1,
"Name": "Software Inventory",
"RelatedItem": [
{
"@odata.id": "/redfish/v1/Managers/bmc"
}
],
"Status": {
"Health": "OK",
"HealthRollup": "OK",
"State": "Disabled"
},
"Updateable": false,
"Version": "2.7.0-dev-940-geb79ec582"
}
- Firmware update status of Host
curl -k -H "X-Auth-Token: $TOKEN" -X GET https://${BMC_IP}/redfish/v1/UpdateService/FirmwareInventory/9a8028ec
{
"@odata.context": "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory",
"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/9a8028ec",
"@odata.type": "#SoftwareInventory.v1_1_0.SoftwareInventory",
"Description": "Host update",
"Id": "9a8028ec",
"Name": "Software Inventory",
"Status": {
"Health": "OK",
"HealthRollup": "OK",
"State": "Enabled"
},
"Updateable": false,
"Version": "IBM-witherspoon-OP9-v2.0.14-2.6"
}
Redfish validator had no additional errors
Change-Id: I26273227448cab1a20a20a7edd9d85d223727bb8
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
diff --git a/redfish-core/include/utils/fw_utils.hpp b/redfish-core/include/utils/fw_utils.hpp
index 18773ae..2341e8a 100644
--- a/redfish-core/include/utils/fw_utils.hpp
+++ b/redfish-core/include/utils/fw_utils.hpp
@@ -186,5 +186,89 @@
return;
}
+
+/**
+ * @brief Translate input fwState to Redfish state
+ *
+ * This function will return the corresponding Redfish state
+ *
+ * @param[i] fwState The OpenBMC firmware state
+ *
+ * @return The corresponding Redfish state
+ */
+std::string getRedfishFWState(const std::string &fwState)
+{
+ if (fwState == "xyz.openbmc_project.Software.Activation.Activations.Active")
+ {
+ return "Enabled";
+ }
+ else if (fwState ==
+ "xyz.openbmc_project.Software.Activation.Activations.Activating")
+ {
+ return "Updating";
+ }
+ else
+ {
+ BMCWEB_LOG_DEBUG << "Default fw state " << fwState << " to Disabled";
+ return "Disabled";
+ }
+}
+
+/**
+ * @brief Put status of input swId into json response
+ *
+ * This function will put the appropriate Redfish state of the input
+ * firmware id to ["Status"]["State"] within the json response
+ *
+ * @param[i,o] aResp Async response object
+ * @param[i] swId The software ID to get status for
+ * @param[i] dbusSvc The dbus service implementing the software object
+ *
+ * @return void
+ */
+void getFwStatus(std::shared_ptr<AsyncResp> asyncResp,
+ const std::shared_ptr<std::string> swId,
+ const std::string &dbusSvc)
+{
+ BMCWEB_LOG_DEBUG << "getFwStatus: swId " << *swId << " svc " << dbusSvc;
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp,
+ swId](const boost::system::error_code error_code,
+ const boost::container::flat_map<std::string, VariantType>
+ &propertiesList) {
+ if (error_code)
+ {
+ messages::internalError(asyncResp->res);
+ BMCWEB_LOG_ERROR
+ << "getFwStatus: Error trying to get Activation for "
+ << *swId;
+ return;
+ }
+ boost::container::flat_map<std::string, VariantType>::const_iterator
+ it = propertiesList.find("Activation");
+ if (it == propertiesList.end())
+ {
+ BMCWEB_LOG_DEBUG << "Can't find property \"Activation\"!";
+ messages::propertyMissing(asyncResp->res, "Activation");
+ return;
+ }
+ const std::string *swInvActivation =
+ std::get_if<std::string>(&it->second);
+ if (swInvActivation == nullptr)
+ {
+ BMCWEB_LOG_DEBUG << "wrong types for property\"Activation\"!";
+ messages::propertyValueTypeError(asyncResp->res, "",
+ "Activation");
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "getFwStatus: Activation " << *swInvActivation;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ getRedfishFWState(*swInvActivation);
+ },
+ dbusSvc, "/xyz/openbmc_project/software/" + *swId,
+ "org.freedesktop.DBus.Properties", "GetAll",
+ "xyz.openbmc_project.Software.Activation");
+}
} // namespace fw_util
} // namespace redfish
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index 7e08ec7..413e39c 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -499,58 +499,14 @@
}
std::string swId = obj.first.substr(idPos + 1);
- for (auto &conn : connections)
- {
- const std::string &connectionName = conn.first;
- BMCWEB_LOG_DEBUG << "connectionName = "
- << connectionName;
- BMCWEB_LOG_DEBUG << "obj.first = " << obj.first;
-
- crow::connections::systemBus->async_method_call(
- [asyncResp,
- swId](const boost::system::error_code error_code,
- const VariantType &activation) {
- BMCWEB_LOG_DEBUG
- << "safe returned in lambda function";
- if (error_code)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- const std::string *swActivationStatus =
- std::get_if<std::string>(&activation);
- if (swActivationStatus == nullptr)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- if (swActivationStatus != nullptr &&
- *swActivationStatus !=
- "xyz.openbmc_project.Software."
- "Activation."
- "Activations.Active")
- {
- // The activation status of this software is
- // not currently active, so does not need to
- // be listed in the response
- return;
- }
- nlohmann::json &members =
- asyncResp->res.jsonValue["Members"];
- members.push_back(
- {{"@odata.id", "/redfish/v1/UpdateService/"
- "FirmwareInventory/" +
- swId}});
- asyncResp->res
- .jsonValue["Members@odata.count"] =
- members.size();
- },
- connectionName, obj.first,
- "org.freedesktop.DBus.Properties", "Get",
- "xyz.openbmc_project.Software.Activation",
- "Activation");
- }
+ nlohmann::json &members =
+ asyncResp->res.jsonValue["Members"];
+ members.push_back(
+ {{"@odata.id", "/redfish/v1/UpdateService/"
+ "FirmwareInventory/" +
+ swId}});
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ members.size();
}
},
"xyz.openbmc_project.ObjectMapper",
@@ -617,7 +573,6 @@
res.jsonValue["Updateable"] = false;
res.jsonValue["Status"]["Health"] = "OK";
res.jsonValue["Status"]["HealthRollup"] = "OK";
- res.jsonValue["Status"]["State"] = "Enabled";
if (params.size() != 1)
{
@@ -662,6 +617,8 @@
continue;
}
+ fw_util::getFwStatus(asyncResp, swId, obj.second[0].first);
+
crow::connections::systemBus->async_method_call(
[asyncResp,
swId](const boost::system::error_code error_code,