add D-Bus interface for unstructured HTTP push
Add the D-Bus interface for unstructured HTTP push update. Unstructured
HTTP push updates are discouraged in favor of Multipart-form based
updates, hence D-Bus interface has been added only for BMC updates for
backward compatibility. Fore more details refer to [1].
Tested:
```
> curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/octet-stream" -X POST -T obmc-phosphor-image-romulus-20240529184214.static.mtd.tar https://${bmc}/redfish/v1/UpdateService/update
{
"@odata.id": "/redfish/v1/TaskService/Tasks/0",
"@odata.type": "#Task.v1_4_3.Task",
"Id": "0",
"TaskState": "Running",
"TaskStatus": "OK"
}
```
[1]: https://www.dmtf.org/sites/default/files/standards/documents/DSP2062_1.0.1.pdf
Change-Id: I365c0c188190032cb191940072399d9abd8a87b3
Signed-off-by: Jagpal Singh Gill <paligill@gmail.com>
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index 2888cbf..9a399af 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -995,17 +995,10 @@
inline void
processUpdateRequest(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request& req, std::string_view body,
+ task::Payload&& payload, std::string_view body,
const std::string& applyTime,
std::vector<std::string>& targets)
{
- std::string applyTimeNewVal;
-
- if (!convertApplyTime(asyncResp->res, applyTime, applyTimeNewVal))
- {
- return;
- }
-
MemoryFileDescriptor memfd("update-image");
if (memfd.fd == -1)
{
@@ -1026,10 +1019,9 @@
return;
}
- task::Payload payload(req);
if (!targets.empty() && targets[0] == BMCWEB_REDFISH_MANAGER_URI_NAME)
{
- startUpdate(asyncResp, std::move(payload), memfd, applyTimeNewVal,
+ startUpdate(asyncResp, std::move(payload), memfd, applyTime,
"/xyz/openbmc_project/software/bmc",
"xyz.openbmc_project.Software.Manager");
}
@@ -1040,12 +1032,12 @@
dbus::utility::getSubTreePaths(
"/xyz/openbmc_project/software", 1, interfaces,
[asyncResp, payload = std::move(payload), memfd = std::move(memfd),
- applyTimeNewVal,
+ applyTime,
targets](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse&
subtree) mutable {
getSwInfo(asyncResp, std::move(payload), std::move(memfd),
- applyTimeNewVal, targets[0], ec, subtree);
+ applyTime, targets[0], ec, subtree);
});
}
}
@@ -1067,8 +1059,17 @@
if constexpr (BMCWEB_REDFISH_UPDATESERVICE_USE_DBUS)
{
- processUpdateRequest(asyncResp, req, multipart->uploadData,
- *multipart->applyTime, multipart->targets);
+ std::string applyTimeNewVal;
+ if (!convertApplyTime(asyncResp->res, *multipart->applyTime,
+ applyTimeNewVal))
+ {
+ return;
+ }
+ task::Payload payload(req);
+
+ processUpdateRequest(asyncResp, std::move(payload),
+ multipart->uploadData, applyTimeNewVal,
+ multipart->targets);
}
else
{
@@ -1082,6 +1083,33 @@
}
}
+inline void doHTTPUpdate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const crow::Request& req)
+{
+ if constexpr (BMCWEB_REDFISH_UPDATESERVICE_USE_DBUS)
+ {
+ task::Payload payload(req);
+ // HTTP push only supports BMC updates (with ApplyTime as immediate) for
+ // backwards compatibility. Specific component updates will be handled
+ // through Multipart form HTTP push.
+ std::vector<std::string> targets;
+ targets.emplace_back(BMCWEB_REDFISH_MANAGER_URI_NAME);
+
+ processUpdateRequest(
+ asyncResp, std::move(payload), req.body(),
+ "xyz.openbmc_project.Software.ApplyTime.RequestedApplyTimes.Immediate",
+ targets);
+ }
+ else
+ {
+ // Setup callback for when new software detected
+ monitorForSoftwareAvailable(asyncResp, req,
+ "/redfish/v1/UpdateService");
+
+ uploadImageFile(asyncResp->res, req.body());
+ }
+}
+
inline void
handleUpdateServicePost(App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
@@ -1098,11 +1126,7 @@
// multipart/form-data
if (bmcweb::asciiIEquals(contentType, "application/octet-stream"))
{
- // Setup callback for when new software detected
- monitorForSoftwareAvailable(asyncResp, req,
- "/redfish/v1/UpdateService");
-
- uploadImageFile(asyncResp->res, req.body());
+ doHTTPUpdate(asyncResp, req);
}
else if (contentType.starts_with("multipart/form-data"))
{