blob: dc708e98866318c08aa4cd3195245191aa900951 [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>
19
Lei YUff83c2a2019-09-12 13:55:18 +080020class TestActivation;
21
Lei YU01539e72019-07-31 10:57:38 +080022namespace phosphor
23{
24namespace software
25{
26namespace updater
27{
28
Lei YU12c9f4c2019-09-11 15:08:15 +080029namespace sdbusRule = sdbusplus::bus::match::rules;
30
Patrick Williams374fae52022-07-22 19:26:55 -050031using ActivationBlocksTransitionInherit =
32 sdbusplus::server::object_t<sdbusplus::xyz::openbmc_project::Software::
33 server::ActivationBlocksTransition>;
Lei YU81c67722019-09-11 16:47:29 +080034
35/** @class ActivationBlocksTransition
36 * @brief OpenBMC ActivationBlocksTransition implementation.
37 * @details A concrete implementation for
38 * xyz.openbmc_project.Software.ActivationBlocksTransition DBus API.
39 */
40class ActivationBlocksTransition : public ActivationBlocksTransitionInherit
41{
42 public:
George Liu66a54ad2024-08-23 13:53:39 +080043 ActivationBlocksTransition() = delete;
44 ActivationBlocksTransition(const ActivationBlocksTransition&) = delete;
45 ActivationBlocksTransition&
46 operator=(const ActivationBlocksTransition&) = delete;
47 ActivationBlocksTransition(ActivationBlocksTransition&&) = delete;
48 ActivationBlocksTransition&
49 operator=(ActivationBlocksTransition&&) = delete;
50
Lei YU81c67722019-09-11 16:47:29 +080051 /** @brief Constructs ActivationBlocksTransition.
52 *
53 * @param[in] bus - The Dbus bus object
54 * @param[in] path - The Dbus object path
55 */
Patrick Williams374fae52022-07-22 19:26:55 -050056 ActivationBlocksTransition(sdbusplus::bus_t& bus, const std::string& path) :
Albert Zhangf356fdc2020-03-02 09:24:17 +080057 ActivationBlocksTransitionInherit(bus, path.c_str(),
58 action::emit_interface_added),
59 bus(bus)
Lei YU81c67722019-09-11 16:47:29 +080060 {
Lei YU8afeee52019-10-21 15:25:35 +080061 enableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080062 }
63
George Liu047d9942024-08-23 13:44:31 +080064 ~ActivationBlocksTransition() override
Lei YU81c67722019-09-11 16:47:29 +080065 {
Lei YU8afeee52019-10-21 15:25:35 +080066 disableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080067 }
68
69 private:
Patrick Williams374fae52022-07-22 19:26:55 -050070 sdbusplus::bus_t& bus;
Lei YU8afeee52019-10-21 15:25:35 +080071
72 /** @brief Enables a Guard that blocks any BMC reboot commands */
73 void enableRebootGuard();
74
75 /** @brief Disables any guard that was blocking the BMC reboot */
76 void disableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080077};
78
Patrick Williams374fae52022-07-22 19:26:55 -050079using ActivationProgressInherit = sdbusplus::server::object_t<
Lei YU90c8a8b2019-09-11 17:20:03 +080080 sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
81
82class ActivationProgress : public ActivationProgressInherit
83{
84 public:
85 /** @brief Constructs ActivationProgress.
86 *
87 * @param[in] bus - The Dbus bus object
88 * @param[in] path - The Dbus object path
89 */
Patrick Williams374fae52022-07-22 19:26:55 -050090 ActivationProgress(sdbusplus::bus_t& bus, const std::string& path) :
Albert Zhangf356fdc2020-03-02 09:24:17 +080091 ActivationProgressInherit(bus, path.c_str(),
92 action::emit_interface_added)
Lei YU90c8a8b2019-09-11 17:20:03 +080093 {
94 progress(0);
Lei YU90c8a8b2019-09-11 17:20:03 +080095 }
Lei YU90c8a8b2019-09-11 17:20:03 +080096};
97
Patrick Williams374fae52022-07-22 19:26:55 -050098using ActivationInherit = sdbusplus::server::object_t<
Lei YU01539e72019-07-31 10:57:38 +080099 sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
Lei YU91029442019-08-01 15:57:31 +0800100 sdbusplus::xyz::openbmc_project::Software::server::Activation,
Lei YU99301372019-09-29 16:27:12 +0800101 sdbusplus::xyz::openbmc_project::Association::server::Definitions,
102 sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
Lei YU01539e72019-07-31 10:57:38 +0800103
104/** @class Activation
105 * @brief OpenBMC activation software management implementation.
106 * @details A concrete implementation for
107 * xyz.openbmc_project.Software.Activation DBus API.
108 */
109class Activation : public ActivationInherit
110{
111 public:
Lei YUff83c2a2019-09-12 13:55:18 +0800112 friend class ::TestActivation;
Lei YU12c9f4c2019-09-11 15:08:15 +0800113 using Status = Activations;
Lei YUff83c2a2019-09-12 13:55:18 +0800114
Lei YU01539e72019-07-31 10:57:38 +0800115 /** @brief Constructs Activation Software Manager
116 *
117 * @param[in] bus - The Dbus bus object
118 * @param[in] path - The Dbus object path
119 * @param[in] versionId - The software version id
120 * @param[in] extVersion - The extended version
121 * @param[in] activationStatus - The status of Activation
Lei YU91029442019-08-01 15:57:31 +0800122 * @param[in] assocs - Association objects
Lei YU99301372019-09-29 16:27:12 +0800123 * @param[in] filePath - The image filesystem path
Lei YU01539e72019-07-31 10:57:38 +0800124 */
Patrick Williams374fae52022-07-22 19:26:55 -0500125 Activation(sdbusplus::bus_t& bus, const std::string& objPath,
Lei YU01539e72019-07-31 10:57:38 +0800126 const std::string& versionId, const std::string& extVersion,
Lei YU7f2a2152019-09-16 16:50:18 +0800127 Status activationStatus, const AssociationList& assocs,
Lei YUffb36532019-10-15 13:55:24 +0800128 const std::string& filePath,
Lei YU99301372019-09-29 16:27:12 +0800129 AssociationInterface* associationInterface,
Lei YUffb36532019-10-15 13:55:24 +0800130 ActivationListener* activationListener) :
Tang Yiwei434ae482022-04-16 13:55:21 +0800131 ActivationInherit(bus, objPath.c_str(),
132 ActivationInherit::action::defer_emit),
Lei YU99301372019-09-29 16:27:12 +0800133 bus(bus), objPath(objPath), versionId(versionId),
Lei YU12c9f4c2019-09-11 15:08:15 +0800134 systemdSignals(
135 bus,
136 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
137 sdbusRule::path("/org/freedesktop/systemd1") +
138 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
139 std::bind(&Activation::unitStateChange, this,
Lei YU7f2a2152019-09-16 16:50:18 +0800140 std::placeholders::_1)),
Lei YUffb36532019-10-15 13:55:24 +0800141 associationInterface(associationInterface),
142 activationListener(activationListener)
Lei YU01539e72019-07-31 10:57:38 +0800143 {
144 // Set Properties.
145 extendedVersion(extVersion);
146 activation(activationStatus);
Lei YU91029442019-08-01 15:57:31 +0800147 associations(assocs);
Lei YU99301372019-09-29 16:27:12 +0800148 path(filePath);
Lei YU01539e72019-07-31 10:57:38 +0800149
Lei YU9edb7332019-09-19 14:46:19 +0800150 auto info = Version::getExtVersionInfo(extVersion);
151 manufacturer = info["manufacturer"];
152 model = info["model"];
153
Lei YU01539e72019-07-31 10:57:38 +0800154 // Emit deferred signal.
155 emit_object_added();
156 }
157
158 /** @brief Overloaded Activation property setter function
159 *
160 * @param[in] value - One of Activation::Activations
161 *
162 * @return Success or exception thrown
163 */
Lei YUff83c2a2019-09-12 13:55:18 +0800164 Status activation(Status value) override;
Lei YU01539e72019-07-31 10:57:38 +0800165
166 /** @brief Activation */
167 using ActivationInherit::activation;
168
169 /** @brief Overloaded requestedActivation property setter function
170 *
171 * @param[in] value - One of Activation::RequestedActivations
172 *
173 * @return Success or exception thrown
174 */
175 RequestedActivations
176 requestedActivation(RequestedActivations value) override;
177
Lei YU63f9e712019-10-12 15:16:55 +0800178 /** @brief Get the object path */
179 const std::string& getObjectPath() const
180 {
181 return objPath;
182 }
183
Lei YUa5c47bb2019-09-29 11:28:53 +0800184 /** @brief Get the version ID */
185 const std::string& getVersionId() const
186 {
187 return versionId;
188 }
Lei YU12c9f4c2019-09-11 15:08:15 +0800189
190 private:
191 /** @brief Check if systemd state change is relevant to this object
192 *
193 * Instance specific interface to handle the detected systemd state
194 * change
195 *
196 * @param[in] msg - Data associated with subscribed signal
197 *
198 */
Patrick Williams374fae52022-07-22 19:26:55 -0500199 void unitStateChange(sdbusplus::message_t& msg);
Lei YU12c9f4c2019-09-11 15:08:15 +0800200
Lei YUd0bbfa92019-09-11 16:10:54 +0800201 /**
202 * @brief Delete the version from Image Manager and the
203 * untar image from image upload dir.
204 */
205 void deleteImageManagerObject();
206
Lei YUff83c2a2019-09-12 13:55:18 +0800207 /** @brief Invoke the update service for the PSU
208 *
209 * @param[in] psuInventoryPath - The PSU inventory to be updated.
210 *
211 * @return true if the update starts, and false if it fails.
212 */
213 bool doUpdate(const std::string& psuInventoryPath);
214
215 /** @brief Do PSU update one-by-one
216 *
217 * @return true if the update starts, and false if it fails.
218 */
219 bool doUpdate();
220
221 /** @brief Handle an update done event */
222 void onUpdateDone();
223
224 /** @brief Handle an update failure event */
225 void onUpdateFailed();
226
Lei YU12c9f4c2019-09-11 15:08:15 +0800227 /** @brief Start PSU update */
Lei YUff83c2a2019-09-12 13:55:18 +0800228 Status startActivation();
Lei YU12c9f4c2019-09-11 15:08:15 +0800229
230 /** @brief Finish PSU update */
231 void finishActivation();
232
Manojkiran Eda33cf9f02024-06-17 14:40:44 +0530233 /** @brief Check if the PSU is compatible with this software*/
Lei YU9edb7332019-09-19 14:46:19 +0800234 bool isCompatible(const std::string& psuInventoryPath);
235
Lei YU2e0e2de2019-09-26 16:42:23 +0800236 /** @brief Store the updated PSU image to persistent dir */
237 void storeImage();
238
Lei YUe8945ea2019-09-29 17:25:31 +0800239 /** @brief Construct the systemd service name
240 *
241 * @param[in] psuInventoryPath - The PSU inventory to be updated.
242 *
243 * @return The escaped string of systemd unit to do the PSU update.
244 */
245 std::string getUpdateService(const std::string& psuInventoryPath);
246
Lei YU01539e72019-07-31 10:57:38 +0800247 /** @brief Persistent sdbusplus DBus bus connection */
Patrick Williams374fae52022-07-22 19:26:55 -0500248 sdbusplus::bus_t& bus;
Lei YU01539e72019-07-31 10:57:38 +0800249
250 /** @brief Persistent DBus object path */
Lei YU99301372019-09-29 16:27:12 +0800251 std::string objPath;
Lei YU01539e72019-07-31 10:57:38 +0800252
Lei YUa5c47bb2019-09-29 11:28:53 +0800253 /** @brief Version id */
254 std::string versionId;
255
Lei YU12c9f4c2019-09-11 15:08:15 +0800256 /** @brief Used to subscribe to dbus systemd signals */
257 sdbusplus::bus::match_t systemdSignals;
258
Lei YUff83c2a2019-09-12 13:55:18 +0800259 /** @brief The queue of psu objects to be updated */
260 std::queue<std::string> psuQueue;
261
262 /** @brief The progress step for each PSU update is done */
263 uint32_t progressStep;
264
Lei YU12c9f4c2019-09-11 15:08:15 +0800265 /** @brief The PSU update systemd unit */
266 std::string psuUpdateUnit;
Lei YU81c67722019-09-11 16:47:29 +0800267
Lei YU7f2a2152019-09-16 16:50:18 +0800268 /** @brief The PSU Inventory path of the current updating PSU */
269 std::string currentUpdatingPsu;
270
Lei YU81c67722019-09-11 16:47:29 +0800271 /** @brief Persistent ActivationBlocksTransition dbus object */
272 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
Lei YU90c8a8b2019-09-11 17:20:03 +0800273
274 /** @brief Persistent ActivationProgress dbus object */
275 std::unique_ptr<ActivationProgress> activationProgress;
Lei YU7f2a2152019-09-16 16:50:18 +0800276
277 /** @brief The AssociationInterface pointer */
278 AssociationInterface* associationInterface;
Lei YU9edb7332019-09-19 14:46:19 +0800279
Lei YUffb36532019-10-15 13:55:24 +0800280 /** @brief The activationListener pointer */
281 ActivationListener* activationListener;
282
Lei YU9edb7332019-09-19 14:46:19 +0800283 /** @brief The PSU manufacturer of the software */
284 std::string manufacturer;
285
286 /** @brief The PSU model of the software */
287 std::string model;
Lei YU01539e72019-07-31 10:57:38 +0800288};
289
290} // namespace updater
291} // namespace software
292} // namespace phosphor