Firmware: Add ActiveSoftwareImage for the running image
ActiveSoftwareImage was added to Bios in v1_1_0 and Manager in v1_6_0.
What Redfish calls active is the functional or running image in
OpenBMC.
Reused getActiveFwVersion which means less D-Bus calls when
calling from Manager.
From https://redfish.dmtf.org/schemas/v1/Manager.v1_9_0.json
"ActiveSoftwareImage": {
...
"description": "The link to the software inventory resource that
represents the active firmware image for this manager.",
"longDescription": "This property shall contain a link to a resource
of type SoftwareInventory that represents the active firmware image for
this manager.",
"readonly": false,
"versionAdded": "v1_6_0"
PATCH support will come later.
Tested: Validator passes
Manager:
...
"FirmwareVersion": "2.9.0-dev-515-g92efac612-dirty",
...
"Links": {
"ActiveSoftwareImage": {
"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/82d3ec86"
},
"ManagerForChassis": [
{
"@odata.id": "/redfish/v1/Chassis/chassis"
}
],
...
System:
"BiosVersion": "IBM-witherspoon-OP9-v2.3-rc2-3.28",
Bios:
"ActiveSoftwareImage": {
"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/9f75c5ad"
}
},
Change-Id: Ia3583b4cb513bf36942a9dcbc4588615275bb2ad
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/redfish-core/include/utils/fw_utils.hpp b/redfish-core/include/utils/fw_utils.hpp
index 9aa5674..95d684f 100644
--- a/redfish-core/include/utils/fw_utils.hpp
+++ b/redfish-core/include/utils/fw_utils.hpp
@@ -2,6 +2,7 @@
#include <async_resp.hpp>
#include <string>
+#include <variant>
namespace redfish
{
@@ -20,19 +21,24 @@
*
* @param[i,o] aResp Async response object
* @param[i] fwVersionPurpose Indicates what target to look for
- * @param[i] jsonIdxStr Index in aResp->res.jsonValue to write fw ver
+ * @param[i] activeVersionPropName Index in aResp->res.jsonValue to write
+ * the running firmware version to
+ * @param[i] populateLinkToActiveImage Populate aResp->res "Links"
+ * "ActiveSoftwareImage" with a link to the running firmware image
*
* @return void
*/
void getActiveFwVersion(std::shared_ptr<AsyncResp> aResp,
const std::string& fwVersionPurpose,
- const std::string& jsonIdxStr)
+ const std::string& activeVersionPropName,
+ const bool populateLinkToActiveImage)
{
// Get active FW images
crow::connections::systemBus->async_method_call(
- [aResp, fwVersionPurpose,
- jsonIdxStr](const boost::system::error_code ec,
- const std::variant<std::vector<std::string>>& resp) {
+ [aResp, fwVersionPurpose, activeVersionPropName,
+ populateLinkToActiveImage](
+ const boost::system::error_code ec,
+ const std::variant<std::vector<std::string>>& resp) {
if (ec)
{
BMCWEB_LOG_ERROR << "error_code = " << ec;
@@ -72,7 +78,8 @@
// Now find service that hosts it
crow::connections::systemBus->async_method_call(
- [aResp, fw, swId, fwVersionPurpose, jsonIdxStr](
+ [aResp, fw, swId, fwVersionPurpose, activeVersionPropName,
+ populateLinkToActiveImage](
const boost::system::error_code ec,
const std::vector<std::pair<
std::string, std::vector<std::string>>>& objInfo) {
@@ -107,10 +114,13 @@
// Now grab its version info
crow::connections::systemBus->async_method_call(
- [aResp, swId, fwVersionPurpose, jsonIdxStr](
+ [aResp, swId, fwVersionPurpose,
+ activeVersionPropName, populateLinkToActiveImage](
const boost::system::error_code ec,
const boost::container::flat_map<
- std::string, VariantType>& propertiesList) {
+ std::string,
+ std::variant<bool, std::string, uint64_t,
+ uint32_t>>& propertiesList) {
if (ec)
{
BMCWEB_LOG_ERROR << "error_code = " << ec;
@@ -126,8 +136,10 @@
// "xyz.openbmc_project.Software.Version.VersionPurpose.Host"
boost::container::flat_map<
- std::string, VariantType>::const_iterator
- it = propertiesList.find("Purpose");
+ std::string,
+ std::variant<bool, std::string, uint64_t,
+ uint32_t>>::const_iterator it =
+ propertiesList.find("Purpose");
if (it == propertiesList.end())
{
BMCWEB_LOG_DEBUG
@@ -150,24 +162,45 @@
// Not purpose we're looking for
return;
}
- it = propertiesList.find("Version");
- if (it == propertiesList.end())
+ if (populateLinkToActiveImage)
{
- BMCWEB_LOG_DEBUG
- << "Can't find property \"Version\"!";
- messages::internalError(aResp->res);
- return;
+ // Firmware images are at
+ // /redfish/v1/UpdateService/FirmwareInventory/<Id>
+ // e.g. .../FirmwareInventory/82d3ec86
+ // Create the link to the running one
+ aResp->res
+ .jsonValue["Links"]
+ ["ActiveSoftwareImage"] = {
+ {"@odata.id",
+ "/redfish/v1/UpdateService/"
+ "FirmwareInventory/" +
+ swId}};
}
- const std::string* version =
- std::get_if<std::string>(&it->second);
- if (version == nullptr)
+ if (!activeVersionPropName.empty())
{
- BMCWEB_LOG_DEBUG
- << "Error getting fw version";
- messages::internalError(aResp->res);
- return;
+ it = propertiesList.find("Version");
+ if (it == propertiesList.end())
+ {
+ BMCWEB_LOG_DEBUG
+ << "Can't find property "
+ "\"Version\"!";
+ messages::internalError(aResp->res);
+ return;
+ }
+ const std::string* version =
+ std::get_if<std::string>(&it->second);
+ if (version == nullptr)
+ {
+ BMCWEB_LOG_DEBUG
+ << "Error getting fw version";
+ messages::internalError(aResp->res);
+ return;
+ }
+
+ aResp->res
+ .jsonValue[activeVersionPropName] =
+ *version;
}
- aResp->res.jsonValue[jsonIdxStr] = *version;
},
objInfo[0].first, fw,
"org.freedesktop.DBus.Properties", "GetAll",
@@ -268,16 +301,19 @@
crow::connections::systemBus->async_method_call(
[asyncResp,
swId](const boost::system::error_code error_code,
- const boost::container::flat_map<std::string, VariantType>&
- propertiesList) {
+ const boost::container::flat_map<
+ std::string, std::variant<bool, std::string, uint64_t,
+ uint32_t>>& propertiesList) {
if (error_code)
{
// not all fwtypes are updateable, this is ok
asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
return;
}
- boost::container::flat_map<std::string, VariantType>::const_iterator
- it = propertiesList.find("Activation");
+ boost::container::flat_map<
+ std::string, std::variant<bool, std::string, uint64_t,
+ uint32_t>>::const_iterator it =
+ propertiesList.find("Activation");
if (it == propertiesList.end())
{
BMCWEB_LOG_DEBUG << "Can't find property \"Activation\"!";
diff --git a/redfish-core/lib/bios.hpp b/redfish-core/lib/bios.hpp
index 9e0a294..0a0effa 100644
--- a/redfish-core/lib/bios.hpp
+++ b/redfish-core/lib/bios.hpp
@@ -2,6 +2,7 @@
#include "node.hpp"
+#include <utils/fw_utils.hpp>
namespace redfish
{
/**
@@ -30,6 +31,9 @@
asyncResp->res.jsonValue["Actions"]["#Bios.ResetBios"] = {
{"target",
"/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios"}};
+
+ // Get the ActiveSoftwareImage
+ fw_util::getActiveFwVersion(asyncResp, fw_util::biosPurpose, "", true);
}
};
/**
@@ -70,4 +74,4 @@
"xyz.openbmc_project.Common.FactoryReset", "Reset");
}
};
-} // namespace redfish
\ No newline at end of file
+} // namespace redfish
diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index bb7165e..7832e81 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -1754,7 +1754,7 @@
health->populate();
fw_util::getActiveFwVersion(asyncResp, fw_util::bmcPurpose,
- "FirmwareVersion");
+ "FirmwareVersion", true);
getLastResetTime(asyncResp);
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index 50e2b93..2baeaa7 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -534,7 +534,7 @@
// Grab the bios version
fw_util::getActiveFwVersion(
aResp, fw_util::biosPurpose,
- "BiosVersion");
+ "BiosVersion", false);
},
connection.first, path,
"org.freedesktop.DBus.Properties", "GetAll",