FW Update: Task: Update messages
This adds reporting of percent updated and changes
"staged" to paused to indicate some further action
must happen to change state to Completed.
Tested: validator passed
"Messages": [
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has started.",
"MessageArgs": [
"2"
],
"MessageId": "TaskEvent.1.0.1.TaskStarted",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 5 percent complete.",
"MessageArgs": [
"2",
5
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 10 percent complete.",
"MessageArgs": [
"2",
10
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 15 percent complete.",
"MessageArgs": [
"2",
15
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 20 percent complete.",
"MessageArgs": [
"2",
20
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 25 percent complete.",
"MessageArgs": [
"2",
25
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 30 percent complete.",
"MessageArgs": [
"2",
30
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 35 percent complete.",
"MessageArgs": [
"2",
35
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 40 percent complete.",
"MessageArgs": [
"2",
40
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 45 percent complete.",
"MessageArgs": [
"2",
45
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 50 percent complete.",
"MessageArgs": [
"2",
50
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 55 percent complete.",
"MessageArgs": [
"2",
55
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 60 percent complete.",
"MessageArgs": [
"2",
60
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 65 percent complete.",
"MessageArgs": [
"2",
65
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 70 percent complete.",
"MessageArgs": [
"2",
70
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 75 percent complete.",
"MessageArgs": [
"2",
75
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 80 percent complete.",
"MessageArgs": [
"2",
80
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 85 percent complete.",
"MessageArgs": [
"2",
85
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 90 percent complete.",
"MessageArgs": [
"2",
90
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 95 percent complete.",
"MessageArgs": [
"2",
95
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has changed to progress 100 percent complete.",
"MessageArgs": [
"2",
100
],
"MessageId": "TaskEvent.1.0.1.TaskProgressChanged",
"Resolution": "None.",
"Severity": "OK"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has been paused.",
"MessageArgs": [
"2"
],
"MessageId": "TaskEvent.1.0.1.TaskPaused",
"Resolution": "None.",
"Severity": "Warning"
},
{
"@odata.type": "#Message.v1_0_0.Message",
"Message": "The task with id 2 has Completed.",
"MessageArgs": [
"2"
],
"MessageId": "TaskEvent.1.0.1.TaskCompletedOK",
"Resolution": "None.",
"Severity": "OK"
}
],
Change-Id: I32103e53486d459fe945a8b451d2092232c12e83
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/redfish-core/lib/task.hpp b/redfish-core/lib/task.hpp
index cbae67b..a746239 100644
--- a/redfish-core/lib/task.hpp
+++ b/redfish-core/lib/task.hpp
@@ -168,28 +168,8 @@
std::chrono::system_clock::now());
}
- void startTimer(const std::chrono::seconds &timeout)
+ void extendTimer(const std::chrono::seconds &timeout)
{
- match = std::make_unique<sdbusplus::bus::match::match>(
- static_cast<sdbusplus::bus::bus &>(*crow::connections::systemBus),
- matchStr,
- [self = shared_from_this()](sdbusplus::message::message &message) {
- boost::system::error_code ec;
-
- // callback to return True if callback is done, callback needs
- // to update status itself if needed
- if (self->callback(ec, message, self) == task::completed)
- {
- self->timer.cancel();
- self->finishTask();
-
- // reset the match after the callback was successful
- boost::asio::post(
- crow::connections::systemBus->get_io_context(),
- [self] { self->match.reset(); });
- return;
- }
- });
timer.expires_after(timeout);
timer.async_wait(
[self = shared_from_this()](boost::system::error_code ec) {
@@ -211,6 +191,36 @@
messages::taskAborted(std::to_string(self->index)));
self->callback(ec, msg, self);
});
+ }
+
+ void startTimer(const std::chrono::seconds &timeout)
+ {
+ if (match)
+ {
+ return;
+ }
+ match = std::make_unique<sdbusplus::bus::match::match>(
+ static_cast<sdbusplus::bus::bus &>(*crow::connections::systemBus),
+ matchStr,
+ [self = shared_from_this()](sdbusplus::message::message &message) {
+ boost::system::error_code ec;
+
+ // callback to return True if callback is done, callback needs
+ // to update status itself if needed
+ if (self->callback(ec, message, self) == task::completed)
+ {
+ self->timer.cancel();
+ self->finishTask();
+
+ // reset the match after the callback was successful
+ boost::asio::post(
+ crow::connections::systemBus->get_io_context(),
+ [self] { self->match.reset(); });
+ return;
+ }
+ });
+
+ extendTimer(timeout);
messages.emplace_back(messages::taskStarted(std::to_string(index)));
}
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index 60d6673..9dacbcd 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -131,51 +131,99 @@
std::string iface;
boost::container::flat_map<
- std::string, std::variant<std::string>>
+ std::string,
+ std::variant<std::string, uint8_t>>
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;
- }
std::string index =
std::to_string(taskData->index);
+ msg.read(iface, values);
- if (boost::ends_with(*state, "Invalid") ||
- boost::ends_with(*state, "Failed"))
+ if (iface == "xyz.openbmc_project.Software."
+ "Activation")
{
- taskData->state = "Exception";
- taskData->status = "Warning";
- taskData->messages.emplace_back(
- messages::taskAborted(index));
- return task::completed;
+ 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::taskAborted(index));
+ return task::completed;
+ }
+
+ if (boost::ends_with(*state, "Staged"))
+ {
+ taskData->state = "Stopping";
+ taskData->messages.emplace_back(
+ messages::taskPaused(index));
+
+ // its staged, set a long timer to
+ // allow them time to complete the
+ // update (probably cycle the
+ // system) if this expires then
+ // task will be cancelled
+ taskData->extendTimer(
+ std::chrono::hours(5));
+ return !task::completed;
+ }
+
+ if (boost::ends_with(*state, "Active"))
+ {
+ taskData->messages.emplace_back(
+ messages::taskCompletedOK(
+ index));
+ taskData->state = "Completed";
+ return task::completed;
+ }
}
-
- if (boost::ends_with(*state, "Staged"))
+ else if (iface ==
+ "xyz.openbmc_project.Software."
+ "ActivationProgress")
{
- taskData->state = "Pending";
- return !task::completed;
- }
+ auto findProgress =
+ values.find("Progress");
+ if (findProgress == values.end())
+ {
+ return !task::completed;
+ }
+ uint8_t *progress =
+ std::get_if<uint8_t>(
+ &(findProgress->second));
- if (boost::ends_with(*state, "Active"))
- {
+ if (progress == nullptr)
+ {
+ taskData->messages.emplace_back(
+ messages::internalError());
+ return task::completed;
+ }
taskData->messages.emplace_back(
- messages::taskCompletedOK(index));
- taskData->state = "Completed";
- return task::completed;
+ messages::taskProgressChanged(
+ index, static_cast<size_t>(
+ *progress)));
+
+ // if we're getting status updates it's
+ // still alive, update timer
+ taskData->extendTimer(
+ std::chrono::minutes(5));
}
// as firmware update often results in a
@@ -186,8 +234,7 @@
},
"type='signal',interface='org.freedesktop.DBus."
"Properties',"
- "member='PropertiesChanged',arg0='xyz.openbmc_"
- "project.Software.Activation',path='" +
+ "member='PropertiesChanged',path='" +
objPath.str + "'");
task->startTimer(std::chrono::minutes(5));
task->populateResp(asyncResp->res);