task: add fwupdate support
This adds firmware update task service support. It adds
a match and updates the task value when the interface
changes.
Tested: On successful fwupdate task was created and
updated correctly. On failed fwupdate the status went
to failed.
Change-Id: Id12cc5d5270e8e45498b665e78601c5c30775323
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index 09602fb..ca9604b 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -1878,8 +1878,9 @@
if (!err)
{
taskData->messages.emplace_back(messages::success());
+ taskData->status = "Completed";
}
- return true;
+ return task::completed;
},
"type='signal',interface='org.freedesktop.DBus.Properties',"
"member='PropertiesChanged',arg0namespace='com.intel."
diff --git a/redfish-core/lib/task.hpp b/redfish-core/lib/task.hpp
index 12425c1..e95eb2e 100644
--- a/redfish-core/lib/task.hpp
+++ b/redfish-core/lib/task.hpp
@@ -30,6 +30,8 @@
static std::deque<std::shared_ptr<struct TaskData>> tasks;
+constexpr bool completed = true;
+
struct TaskData : std::enable_shared_from_this<TaskData>
{
private:
@@ -120,13 +122,9 @@
[self = shared_from_this()](sdbusplus::message::message &message) {
boost::system::error_code ec;
- // set to complete before callback incase user wants a different
- // status
- self->state = "Completed";
-
// callback to return True if callback is done, callback needs
// to update status itself if needed
- if (self->callback(ec, message, self))
+ if (self->callback(ec, message, self) == task::completed)
{
self->timer.cancel();
self->finishTask();
@@ -136,10 +134,6 @@
[self] { self->match.reset(); });
return;
}
-
- // set back to running if callback returns false to keep
- // callback alive
- self->state = "Running";
});
timer.expires_after(timeout);
timer.async_wait(
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index a47aca2..3ca7721 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -117,7 +117,77 @@
activateImage(objPath.str, objInfo[0].first);
if (asyncResp)
{
- redfish::messages::success(asyncResp->res);
+ std::shared_ptr<task::TaskData> task =
+ task::TaskData::createTask(
+ [](boost::system::error_code ec,
+ sdbusplus::message::message &msg,
+ const std::shared_ptr<task::TaskData>
+ &taskData) {
+ if (ec)
+ {
+ return task::completed;
+ }
+
+ std::string iface;
+ boost::container::flat_map<
+ std::string, std::variant<std::string>>
+ values;
+ msg.read(iface, values);
+ auto findActivation =
+ values.find("Activation");
+ if (findActivation == values.end())
+ {
+ return !task::completed;
+ }
+ std::string *state =
+ std::get_if<std::string>(
+ &(findActivation->second));
+
+ if (state == nullptr)
+ {
+ taskData->messages.emplace_back(
+ messages::internalError());
+ return task::completed;
+ }
+
+ if (boost::ends_with(*state, "Invalid") ||
+ boost::ends_with(*state, "Failed"))
+ {
+ taskData->state = "Exception";
+ taskData->status = "Warning";
+ taskData->messages.emplace_back(
+ messages::invalidObject(
+ "/redfish/v1/UpdateService/"));
+ return task::completed;
+ }
+
+ if (boost::ends_with(*state, "Staged"))
+ {
+ taskData->state = "Pending";
+ return !task::completed;
+ }
+
+ if (boost::ends_with(*state, "Active"))
+ {
+ taskData->messages.emplace_back(
+ messages::success());
+ taskData->state = "Completed";
+ return task::completed;
+ }
+
+ // as firmware update often results in a
+ // reboot, the task may never "complete"
+ // unless it is an error
+
+ return !task::completed;
+ },
+ "type='signal',interface='org.freedesktop.DBus."
+ "Properties',"
+ "member='PropertiesChanged',arg0='xyz.openbmc_"
+ "project.Software.Activation',path='" +
+ objPath.str + "'");
+ task->startTimer(std::chrono::minutes(5));
+ task->populateResp(asyncResp->res);
}
fwUpdateInProgress = false;
},