blob: 95fe069b0eec9b6c2cbe9d67c1f79f4ef7ca6e69 [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 YUff83c2a2019-09-12 13:55:18 +080010#include <queue>
Lei YU01539e72019-07-31 10:57:38 +080011#include <sdbusplus/server.hpp>
Lei YU91029442019-08-01 15:57:31 +080012#include <xyz/openbmc_project/Association/Definitions/server.hpp>
Lei YU99301372019-09-29 16:27:12 +080013#include <xyz/openbmc_project/Common/FilePath/server.hpp>
Lei YU01539e72019-07-31 10:57:38 +080014#include <xyz/openbmc_project/Software/Activation/server.hpp>
Lei YU81c67722019-09-11 16:47:29 +080015#include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp>
Lei YU90c8a8b2019-09-11 17:20:03 +080016#include <xyz/openbmc_project/Software/ActivationProgress/server.hpp>
Lei YU01539e72019-07-31 10:57:38 +080017#include <xyz/openbmc_project/Software/ExtendedVersion/server.hpp>
18
Lei YUff83c2a2019-09-12 13:55:18 +080019class TestActivation;
20
Lei YU01539e72019-07-31 10:57:38 +080021namespace phosphor
22{
23namespace software
24{
25namespace updater
26{
27
Lei YU12c9f4c2019-09-11 15:08:15 +080028namespace sdbusRule = sdbusplus::bus::match::rules;
29
Lei YU81c67722019-09-11 16:47:29 +080030using ActivationBlocksTransitionInherit = sdbusplus::server::object::object<
31 sdbusplus::xyz::openbmc_project::Software::server::
32 ActivationBlocksTransition>;
33
34/** @class ActivationBlocksTransition
35 * @brief OpenBMC ActivationBlocksTransition implementation.
36 * @details A concrete implementation for
37 * xyz.openbmc_project.Software.ActivationBlocksTransition DBus API.
38 */
39class ActivationBlocksTransition : public ActivationBlocksTransitionInherit
40{
41 public:
42 /** @brief Constructs ActivationBlocksTransition.
43 *
44 * @param[in] bus - The Dbus bus object
45 * @param[in] path - The Dbus object path
46 */
47 ActivationBlocksTransition(sdbusplus::bus::bus& bus,
48 const std::string& path) :
Albert Zhangf356fdc2020-03-02 09:24:17 +080049 ActivationBlocksTransitionInherit(bus, path.c_str(),
50 action::emit_interface_added),
51 bus(bus)
Lei YU81c67722019-09-11 16:47:29 +080052 {
Lei YU8afeee52019-10-21 15:25:35 +080053 enableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080054 }
55
56 ~ActivationBlocksTransition()
57 {
Lei YU8afeee52019-10-21 15:25:35 +080058 disableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080059 }
60
61 private:
Lei YU81c67722019-09-11 16:47:29 +080062 sdbusplus::bus::bus& bus;
Lei YU8afeee52019-10-21 15:25:35 +080063
64 /** @brief Enables a Guard that blocks any BMC reboot commands */
65 void enableRebootGuard();
66
67 /** @brief Disables any guard that was blocking the BMC reboot */
68 void disableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080069};
70
Lei YU90c8a8b2019-09-11 17:20:03 +080071using ActivationProgressInherit = sdbusplus::server::object::object<
72 sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
73
74class ActivationProgress : public ActivationProgressInherit
75{
76 public:
77 /** @brief Constructs ActivationProgress.
78 *
79 * @param[in] bus - The Dbus bus object
80 * @param[in] path - The Dbus object path
81 */
82 ActivationProgress(sdbusplus::bus::bus& bus, const std::string& path) :
Albert Zhangf356fdc2020-03-02 09:24:17 +080083 ActivationProgressInherit(bus, path.c_str(),
84 action::emit_interface_added)
Lei YU90c8a8b2019-09-11 17:20:03 +080085 {
86 progress(0);
Lei YU90c8a8b2019-09-11 17:20:03 +080087 }
Lei YU90c8a8b2019-09-11 17:20:03 +080088};
89
Lei YU01539e72019-07-31 10:57:38 +080090using ActivationInherit = sdbusplus::server::object::object<
91 sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
Lei YU91029442019-08-01 15:57:31 +080092 sdbusplus::xyz::openbmc_project::Software::server::Activation,
Lei YU99301372019-09-29 16:27:12 +080093 sdbusplus::xyz::openbmc_project::Association::server::Definitions,
94 sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
Lei YU01539e72019-07-31 10:57:38 +080095
96/** @class Activation
97 * @brief OpenBMC activation software management implementation.
98 * @details A concrete implementation for
99 * xyz.openbmc_project.Software.Activation DBus API.
100 */
101class Activation : public ActivationInherit
102{
103 public:
Lei YUff83c2a2019-09-12 13:55:18 +0800104 friend class ::TestActivation;
Lei YU12c9f4c2019-09-11 15:08:15 +0800105 using Status = Activations;
Lei YUff83c2a2019-09-12 13:55:18 +0800106
Lei YU01539e72019-07-31 10:57:38 +0800107 /** @brief Constructs Activation Software Manager
108 *
109 * @param[in] bus - The Dbus bus object
110 * @param[in] path - The Dbus object path
111 * @param[in] versionId - The software version id
112 * @param[in] extVersion - The extended version
113 * @param[in] activationStatus - The status of Activation
Lei YU91029442019-08-01 15:57:31 +0800114 * @param[in] assocs - Association objects
Lei YU99301372019-09-29 16:27:12 +0800115 * @param[in] filePath - The image filesystem path
Lei YU01539e72019-07-31 10:57:38 +0800116 */
Lei YU99301372019-09-29 16:27:12 +0800117 Activation(sdbusplus::bus::bus& bus, const std::string& objPath,
Lei YU01539e72019-07-31 10:57:38 +0800118 const std::string& versionId, const std::string& extVersion,
Lei YU7f2a2152019-09-16 16:50:18 +0800119 Status activationStatus, const AssociationList& assocs,
Lei YUffb36532019-10-15 13:55:24 +0800120 const std::string& filePath,
Lei YU99301372019-09-29 16:27:12 +0800121 AssociationInterface* associationInterface,
Lei YUffb36532019-10-15 13:55:24 +0800122 ActivationListener* activationListener) :
Lei YU99301372019-09-29 16:27:12 +0800123 ActivationInherit(bus, objPath.c_str(), true),
124 bus(bus), objPath(objPath), versionId(versionId),
Lei YU12c9f4c2019-09-11 15:08:15 +0800125 systemdSignals(
126 bus,
127 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
128 sdbusRule::path("/org/freedesktop/systemd1") +
129 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
130 std::bind(&Activation::unitStateChange, this,
Lei YU7f2a2152019-09-16 16:50:18 +0800131 std::placeholders::_1)),
Lei YUffb36532019-10-15 13:55:24 +0800132 associationInterface(associationInterface),
133 activationListener(activationListener)
Lei YU01539e72019-07-31 10:57:38 +0800134 {
135 // Set Properties.
136 extendedVersion(extVersion);
137 activation(activationStatus);
Lei YU91029442019-08-01 15:57:31 +0800138 associations(assocs);
Lei YU99301372019-09-29 16:27:12 +0800139 path(filePath);
Lei YU01539e72019-07-31 10:57:38 +0800140
Lei YU9edb7332019-09-19 14:46:19 +0800141 auto info = Version::getExtVersionInfo(extVersion);
142 manufacturer = info["manufacturer"];
143 model = info["model"];
144
Lei YU01539e72019-07-31 10:57:38 +0800145 // Emit deferred signal.
146 emit_object_added();
147 }
148
149 /** @brief Overloaded Activation property setter function
150 *
151 * @param[in] value - One of Activation::Activations
152 *
153 * @return Success or exception thrown
154 */
Lei YUff83c2a2019-09-12 13:55:18 +0800155 Status activation(Status value) override;
Lei YU01539e72019-07-31 10:57:38 +0800156
157 /** @brief Activation */
158 using ActivationInherit::activation;
159
160 /** @brief Overloaded requestedActivation property setter function
161 *
162 * @param[in] value - One of Activation::RequestedActivations
163 *
164 * @return Success or exception thrown
165 */
166 RequestedActivations
167 requestedActivation(RequestedActivations value) override;
168
Lei YU63f9e712019-10-12 15:16:55 +0800169 /** @brief Get the object path */
170 const std::string& getObjectPath() const
171 {
172 return objPath;
173 }
174
Lei YUa5c47bb2019-09-29 11:28:53 +0800175 /** @brief Get the version ID */
176 const std::string& getVersionId() const
177 {
178 return versionId;
179 }
Lei YU12c9f4c2019-09-11 15:08:15 +0800180
181 private:
182 /** @brief Check if systemd state change is relevant to this object
183 *
184 * Instance specific interface to handle the detected systemd state
185 * change
186 *
187 * @param[in] msg - Data associated with subscribed signal
188 *
189 */
190 void unitStateChange(sdbusplus::message::message& msg);
191
Lei YUd0bbfa92019-09-11 16:10:54 +0800192 /**
193 * @brief Delete the version from Image Manager and the
194 * untar image from image upload dir.
195 */
196 void deleteImageManagerObject();
197
Lei YUff83c2a2019-09-12 13:55:18 +0800198 /** @brief Invoke the update service for the PSU
199 *
200 * @param[in] psuInventoryPath - The PSU inventory to be updated.
201 *
202 * @return true if the update starts, and false if it fails.
203 */
204 bool doUpdate(const std::string& psuInventoryPath);
205
206 /** @brief Do PSU update one-by-one
207 *
208 * @return true if the update starts, and false if it fails.
209 */
210 bool doUpdate();
211
212 /** @brief Handle an update done event */
213 void onUpdateDone();
214
215 /** @brief Handle an update failure event */
216 void onUpdateFailed();
217
Lei YU12c9f4c2019-09-11 15:08:15 +0800218 /** @brief Start PSU update */
Lei YUff83c2a2019-09-12 13:55:18 +0800219 Status startActivation();
Lei YU12c9f4c2019-09-11 15:08:15 +0800220
221 /** @brief Finish PSU update */
222 void finishActivation();
223
Lei YU9edb7332019-09-19 14:46:19 +0800224 /** @brief Check if the PSU is comaptible with this software*/
225 bool isCompatible(const std::string& psuInventoryPath);
226
Lei YU2e0e2de2019-09-26 16:42:23 +0800227 /** @brief Store the updated PSU image to persistent dir */
228 void storeImage();
229
Lei YUe8945ea2019-09-29 17:25:31 +0800230 /** @brief Construct the systemd service name
231 *
232 * @param[in] psuInventoryPath - The PSU inventory to be updated.
233 *
234 * @return The escaped string of systemd unit to do the PSU update.
235 */
236 std::string getUpdateService(const std::string& psuInventoryPath);
237
Lei YU01539e72019-07-31 10:57:38 +0800238 /** @brief Persistent sdbusplus DBus bus connection */
239 sdbusplus::bus::bus& bus;
240
241 /** @brief Persistent DBus object path */
Lei YU99301372019-09-29 16:27:12 +0800242 std::string objPath;
Lei YU01539e72019-07-31 10:57:38 +0800243
Lei YUa5c47bb2019-09-29 11:28:53 +0800244 /** @brief Version id */
245 std::string versionId;
246
Lei YU12c9f4c2019-09-11 15:08:15 +0800247 /** @brief Used to subscribe to dbus systemd signals */
248 sdbusplus::bus::match_t systemdSignals;
249
Lei YUff83c2a2019-09-12 13:55:18 +0800250 /** @brief The queue of psu objects to be updated */
251 std::queue<std::string> psuQueue;
252
253 /** @brief The progress step for each PSU update is done */
254 uint32_t progressStep;
255
Lei YU12c9f4c2019-09-11 15:08:15 +0800256 /** @brief The PSU update systemd unit */
257 std::string psuUpdateUnit;
Lei YU81c67722019-09-11 16:47:29 +0800258
Lei YU7f2a2152019-09-16 16:50:18 +0800259 /** @brief The PSU Inventory path of the current updating PSU */
260 std::string currentUpdatingPsu;
261
Lei YU81c67722019-09-11 16:47:29 +0800262 /** @brief Persistent ActivationBlocksTransition dbus object */
263 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
Lei YU90c8a8b2019-09-11 17:20:03 +0800264
265 /** @brief Persistent ActivationProgress dbus object */
266 std::unique_ptr<ActivationProgress> activationProgress;
Lei YU7f2a2152019-09-16 16:50:18 +0800267
268 /** @brief The AssociationInterface pointer */
269 AssociationInterface* associationInterface;
Lei YU9edb7332019-09-19 14:46:19 +0800270
Lei YUffb36532019-10-15 13:55:24 +0800271 /** @brief The activationListener pointer */
272 ActivationListener* activationListener;
273
Lei YU9edb7332019-09-19 14:46:19 +0800274 /** @brief The PSU manufacturer of the software */
275 std::string manufacturer;
276
277 /** @brief The PSU model of the software */
278 std::string model;
Lei YU01539e72019-07-31 10:57:38 +0800279};
280
281} // namespace updater
282} // namespace software
283} // namespace phosphor