blob: cd902178bc23beda837bec05b3fd7b07d9b1a8cf [file] [log] [blame]
Lei YU01539e72019-07-31 10:57:38 +08001#pragma once
2
3#include "config.h"
4
Lei YUffb36532019-10-15 13:55:24 +08005#include "activation_listener.hpp"
Lei YU7f2a2152019-09-16 16:50:18 +08006#include "association_interface.hpp"
Lei YU91029442019-08-01 15:57:31 +08007#include "types.hpp"
Lei YU9edb7332019-09-19 14:46:19 +08008#include "version.hpp"
Lei YU91029442019-08-01 15:57:31 +08009
Lei YU01539e72019-07-31 10:57:38 +080010#include <sdbusplus/server.hpp>
Lei YU91029442019-08-01 15:57:31 +080011#include <xyz/openbmc_project/Association/Definitions/server.hpp>
Lei YU99301372019-09-29 16:27:12 +080012#include <xyz/openbmc_project/Common/FilePath/server.hpp>
Lei YU01539e72019-07-31 10:57:38 +080013#include <xyz/openbmc_project/Software/Activation/server.hpp>
Lei YU81c67722019-09-11 16:47:29 +080014#include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp>
Lei YU90c8a8b2019-09-11 17:20:03 +080015#include <xyz/openbmc_project/Software/ActivationProgress/server.hpp>
Lei YU01539e72019-07-31 10:57:38 +080016#include <xyz/openbmc_project/Software/ExtendedVersion/server.hpp>
17
Patrick Williams5670b182023-05-10 07:50:50 -050018#include <queue>
Shawn McCarney487e2e12024-11-25 17:19:46 -060019#include <string>
Patrick Williams5670b182023-05-10 07:50:50 -050020
Lei YUff83c2a2019-09-12 13:55:18 +080021class TestActivation;
22
Lei YU01539e72019-07-31 10:57:38 +080023namespace phosphor
24{
25namespace software
26{
27namespace updater
28{
29
Lei YU12c9f4c2019-09-11 15:08:15 +080030namespace sdbusRule = sdbusplus::bus::match::rules;
31
Patrick Williams374fae52022-07-22 19:26:55 -050032using ActivationBlocksTransitionInherit =
33 sdbusplus::server::object_t<sdbusplus::xyz::openbmc_project::Software::
34 server::ActivationBlocksTransition>;
Lei YU81c67722019-09-11 16:47:29 +080035
36/** @class ActivationBlocksTransition
37 * @brief OpenBMC ActivationBlocksTransition implementation.
38 * @details A concrete implementation for
39 * xyz.openbmc_project.Software.ActivationBlocksTransition DBus API.
40 */
41class ActivationBlocksTransition : public ActivationBlocksTransitionInherit
42{
43 public:
George Liu66a54ad2024-08-23 13:53:39 +080044 ActivationBlocksTransition() = delete;
45 ActivationBlocksTransition(const ActivationBlocksTransition&) = delete;
46 ActivationBlocksTransition&
47 operator=(const ActivationBlocksTransition&) = delete;
48 ActivationBlocksTransition(ActivationBlocksTransition&&) = delete;
49 ActivationBlocksTransition&
50 operator=(ActivationBlocksTransition&&) = delete;
51
Lei YU81c67722019-09-11 16:47:29 +080052 /** @brief Constructs ActivationBlocksTransition.
53 *
54 * @param[in] bus - The Dbus bus object
55 * @param[in] path - The Dbus object path
56 */
Patrick Williams374fae52022-07-22 19:26:55 -050057 ActivationBlocksTransition(sdbusplus::bus_t& bus, const std::string& path) :
Albert Zhangf356fdc2020-03-02 09:24:17 +080058 ActivationBlocksTransitionInherit(bus, path.c_str(),
59 action::emit_interface_added),
60 bus(bus)
Lei YU81c67722019-09-11 16:47:29 +080061 {
Lei YU8afeee52019-10-21 15:25:35 +080062 enableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080063 }
64
George Liu047d9942024-08-23 13:44:31 +080065 ~ActivationBlocksTransition() override
Lei YU81c67722019-09-11 16:47:29 +080066 {
Lei YU8afeee52019-10-21 15:25:35 +080067 disableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080068 }
69
70 private:
Patrick Williams374fae52022-07-22 19:26:55 -050071 sdbusplus::bus_t& bus;
Lei YU8afeee52019-10-21 15:25:35 +080072
73 /** @brief Enables a Guard that blocks any BMC reboot commands */
74 void enableRebootGuard();
75
76 /** @brief Disables any guard that was blocking the BMC reboot */
77 void disableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080078};
79
Patrick Williams374fae52022-07-22 19:26:55 -050080using ActivationProgressInherit = sdbusplus::server::object_t<
Lei YU90c8a8b2019-09-11 17:20:03 +080081 sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
82
83class ActivationProgress : public ActivationProgressInherit
84{
85 public:
86 /** @brief Constructs ActivationProgress.
87 *
88 * @param[in] bus - The Dbus bus object
89 * @param[in] path - The Dbus object path
90 */
Patrick Williams374fae52022-07-22 19:26:55 -050091 ActivationProgress(sdbusplus::bus_t& bus, const std::string& path) :
Albert Zhangf356fdc2020-03-02 09:24:17 +080092 ActivationProgressInherit(bus, path.c_str(),
93 action::emit_interface_added)
Lei YU90c8a8b2019-09-11 17:20:03 +080094 {
95 progress(0);
Lei YU90c8a8b2019-09-11 17:20:03 +080096 }
Lei YU90c8a8b2019-09-11 17:20:03 +080097};
98
Patrick Williams374fae52022-07-22 19:26:55 -050099using ActivationInherit = sdbusplus::server::object_t<
Lei YU01539e72019-07-31 10:57:38 +0800100 sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
Lei YU91029442019-08-01 15:57:31 +0800101 sdbusplus::xyz::openbmc_project::Software::server::Activation,
Lei YU99301372019-09-29 16:27:12 +0800102 sdbusplus::xyz::openbmc_project::Association::server::Definitions,
103 sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
Lei YU01539e72019-07-31 10:57:38 +0800104
105/** @class Activation
106 * @brief OpenBMC activation software management implementation.
107 * @details A concrete implementation for
108 * xyz.openbmc_project.Software.Activation DBus API.
109 */
110class Activation : public ActivationInherit
111{
112 public:
Lei YUff83c2a2019-09-12 13:55:18 +0800113 friend class ::TestActivation;
Lei YU12c9f4c2019-09-11 15:08:15 +0800114 using Status = Activations;
Lei YUff83c2a2019-09-12 13:55:18 +0800115
Lei YU01539e72019-07-31 10:57:38 +0800116 /** @brief Constructs Activation Software Manager
117 *
118 * @param[in] bus - The Dbus bus object
119 * @param[in] path - The Dbus object path
120 * @param[in] versionId - The software version id
121 * @param[in] extVersion - The extended version
122 * @param[in] activationStatus - The status of Activation
Lei YU91029442019-08-01 15:57:31 +0800123 * @param[in] assocs - Association objects
Lei YU99301372019-09-29 16:27:12 +0800124 * @param[in] filePath - The image filesystem path
Lei YU01539e72019-07-31 10:57:38 +0800125 */
Patrick Williams374fae52022-07-22 19:26:55 -0500126 Activation(sdbusplus::bus_t& bus, const std::string& objPath,
Lei YU01539e72019-07-31 10:57:38 +0800127 const std::string& versionId, const std::string& extVersion,
Lei YU7f2a2152019-09-16 16:50:18 +0800128 Status activationStatus, const AssociationList& assocs,
Lei YUffb36532019-10-15 13:55:24 +0800129 const std::string& filePath,
Lei YU99301372019-09-29 16:27:12 +0800130 AssociationInterface* associationInterface,
Lei YUffb36532019-10-15 13:55:24 +0800131 ActivationListener* activationListener) :
Tang Yiwei434ae482022-04-16 13:55:21 +0800132 ActivationInherit(bus, objPath.c_str(),
133 ActivationInherit::action::defer_emit),
Lei YU99301372019-09-29 16:27:12 +0800134 bus(bus), objPath(objPath), versionId(versionId),
Lei YU12c9f4c2019-09-11 15:08:15 +0800135 systemdSignals(
136 bus,
137 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
138 sdbusRule::path("/org/freedesktop/systemd1") +
139 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
140 std::bind(&Activation::unitStateChange, this,
Lei YU7f2a2152019-09-16 16:50:18 +0800141 std::placeholders::_1)),
Lei YUffb36532019-10-15 13:55:24 +0800142 associationInterface(associationInterface),
143 activationListener(activationListener)
Lei YU01539e72019-07-31 10:57:38 +0800144 {
145 // Set Properties.
146 extendedVersion(extVersion);
147 activation(activationStatus);
Lei YU91029442019-08-01 15:57:31 +0800148 associations(assocs);
Lei YU99301372019-09-29 16:27:12 +0800149 path(filePath);
Lei YU01539e72019-07-31 10:57:38 +0800150
151 // Emit deferred signal.
152 emit_object_added();
153 }
154
155 /** @brief Overloaded Activation property setter function
156 *
157 * @param[in] value - One of Activation::Activations
158 *
159 * @return Success or exception thrown
160 */
Lei YUff83c2a2019-09-12 13:55:18 +0800161 Status activation(Status value) override;
Lei YU01539e72019-07-31 10:57:38 +0800162
163 /** @brief Activation */
164 using ActivationInherit::activation;
165
166 /** @brief Overloaded requestedActivation property setter function
167 *
168 * @param[in] value - One of Activation::RequestedActivations
169 *
170 * @return Success or exception thrown
171 */
172 RequestedActivations
173 requestedActivation(RequestedActivations value) override;
174
Shawn McCarney17c2c942024-12-10 17:32:30 -0600175 /** @brief Overloaded ExtendedVersion property setter function
176 *
177 * @param[in] value - Extended version value
178 *
179 * @return New value of property
180 */
181 std::string extendedVersion(std::string value) override;
182
Lei YU63f9e712019-10-12 15:16:55 +0800183 /** @brief Get the object path */
184 const std::string& getObjectPath() const
185 {
186 return objPath;
187 }
188
Lei YUa5c47bb2019-09-29 11:28:53 +0800189 /** @brief Get the version ID */
190 const std::string& getVersionId() const
191 {
192 return versionId;
193 }
Lei YU12c9f4c2019-09-11 15:08:15 +0800194
195 private:
196 /** @brief Check if systemd state change is relevant to this object
197 *
198 * Instance specific interface to handle the detected systemd state
199 * change
200 *
201 * @param[in] msg - Data associated with subscribed signal
202 *
203 */
Patrick Williams374fae52022-07-22 19:26:55 -0500204 void unitStateChange(sdbusplus::message_t& msg);
Lei YU12c9f4c2019-09-11 15:08:15 +0800205
Lei YUd0bbfa92019-09-11 16:10:54 +0800206 /**
207 * @brief Delete the version from Image Manager and the
208 * untar image from image upload dir.
209 */
210 void deleteImageManagerObject();
211
Lei YUff83c2a2019-09-12 13:55:18 +0800212 /** @brief Invoke the update service for the PSU
213 *
214 * @param[in] psuInventoryPath - The PSU inventory to be updated.
215 *
216 * @return true if the update starts, and false if it fails.
217 */
218 bool doUpdate(const std::string& psuInventoryPath);
219
220 /** @brief Do PSU update one-by-one
221 *
222 * @return true if the update starts, and false if it fails.
223 */
224 bool doUpdate();
225
226 /** @brief Handle an update done event */
227 void onUpdateDone();
228
229 /** @brief Handle an update failure event */
230 void onUpdateFailed();
231
Lei YU12c9f4c2019-09-11 15:08:15 +0800232 /** @brief Start PSU update */
Lei YUff83c2a2019-09-12 13:55:18 +0800233 Status startActivation();
Lei YU12c9f4c2019-09-11 15:08:15 +0800234
235 /** @brief Finish PSU update */
236 void finishActivation();
237
Shawn McCarney46ea3882024-12-10 11:25:38 -0600238 /** @brief Check if the PSU is present */
239 bool isPresent(const std::string& psuInventoryPath);
240
Manojkiran Eda33cf9f02024-06-17 14:40:44 +0530241 /** @brief Check if the PSU is compatible with this software*/
Lei YU9edb7332019-09-19 14:46:19 +0800242 bool isCompatible(const std::string& psuInventoryPath);
243
Lei YU2e0e2de2019-09-26 16:42:23 +0800244 /** @brief Store the updated PSU image to persistent dir */
245 void storeImage();
246
Lei YUe8945ea2019-09-29 17:25:31 +0800247 /** @brief Construct the systemd service name
248 *
Shawn McCarney487e2e12024-11-25 17:19:46 -0600249 * @details Throws an exception if an error occurs
250 *
Lei YUe8945ea2019-09-29 17:25:31 +0800251 * @param[in] psuInventoryPath - The PSU inventory to be updated.
252 *
253 * @return The escaped string of systemd unit to do the PSU update.
254 */
255 std::string getUpdateService(const std::string& psuInventoryPath);
256
Lei YU01539e72019-07-31 10:57:38 +0800257 /** @brief Persistent sdbusplus DBus bus connection */
Patrick Williams374fae52022-07-22 19:26:55 -0500258 sdbusplus::bus_t& bus;
Lei YU01539e72019-07-31 10:57:38 +0800259
260 /** @brief Persistent DBus object path */
Lei YU99301372019-09-29 16:27:12 +0800261 std::string objPath;
Lei YU01539e72019-07-31 10:57:38 +0800262
Lei YUa5c47bb2019-09-29 11:28:53 +0800263 /** @brief Version id */
264 std::string versionId;
265
Lei YU12c9f4c2019-09-11 15:08:15 +0800266 /** @brief Used to subscribe to dbus systemd signals */
267 sdbusplus::bus::match_t systemdSignals;
268
Lei YUff83c2a2019-09-12 13:55:18 +0800269 /** @brief The queue of psu objects to be updated */
270 std::queue<std::string> psuQueue;
271
272 /** @brief The progress step for each PSU update is done */
273 uint32_t progressStep;
274
Lei YU12c9f4c2019-09-11 15:08:15 +0800275 /** @brief The PSU update systemd unit */
276 std::string psuUpdateUnit;
Lei YU81c67722019-09-11 16:47:29 +0800277
Lei YU7f2a2152019-09-16 16:50:18 +0800278 /** @brief The PSU Inventory path of the current updating PSU */
279 std::string currentUpdatingPsu;
280
Lei YU81c67722019-09-11 16:47:29 +0800281 /** @brief Persistent ActivationBlocksTransition dbus object */
282 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
Lei YU90c8a8b2019-09-11 17:20:03 +0800283
284 /** @brief Persistent ActivationProgress dbus object */
285 std::unique_ptr<ActivationProgress> activationProgress;
Lei YU7f2a2152019-09-16 16:50:18 +0800286
287 /** @brief The AssociationInterface pointer */
288 AssociationInterface* associationInterface;
Lei YU9edb7332019-09-19 14:46:19 +0800289
Lei YUffb36532019-10-15 13:55:24 +0800290 /** @brief The activationListener pointer */
291 ActivationListener* activationListener;
292
Lei YU9edb7332019-09-19 14:46:19 +0800293 /** @brief The PSU manufacturer of the software */
294 std::string manufacturer;
295
296 /** @brief The PSU model of the software */
297 std::string model;
Lei YU01539e72019-07-31 10:57:38 +0800298};
299
300} // namespace updater
301} // namespace software
302} // namespace phosphor