blob: bc95065f2437f90c40c0b426d46227d11c0b80f0 [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) :
49 ActivationBlocksTransitionInherit(bus, path.c_str(), true),
50 bus(bus), path(path)
51 {
52 std::vector<std::string> interfaces({interface});
53 bus.emit_interfaces_added(path.c_str(), interfaces);
Lei YU8afeee52019-10-21 15:25:35 +080054 enableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080055 }
56
57 ~ActivationBlocksTransition()
58 {
59 std::vector<std::string> interfaces({interface});
60 bus.emit_interfaces_removed(path.c_str(), interfaces);
Lei YU8afeee52019-10-21 15:25:35 +080061 disableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080062 }
63
64 private:
65 // TODO Remove once openbmc/openbmc#1975 is resolved
66 static constexpr auto interface =
67 "xyz.openbmc_project.Software.ActivationBlocksTransition";
68 sdbusplus::bus::bus& bus;
69 std::string path;
Lei YU8afeee52019-10-21 15:25:35 +080070
71 /** @brief Enables a Guard that blocks any BMC reboot commands */
72 void enableRebootGuard();
73
74 /** @brief Disables any guard that was blocking the BMC reboot */
75 void disableRebootGuard();
Lei YU81c67722019-09-11 16:47:29 +080076};
77
Lei YU90c8a8b2019-09-11 17:20:03 +080078using ActivationProgressInherit = sdbusplus::server::object::object<
79 sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
80
81class ActivationProgress : public ActivationProgressInherit
82{
83 public:
84 /** @brief Constructs ActivationProgress.
85 *
86 * @param[in] bus - The Dbus bus object
87 * @param[in] path - The Dbus object path
88 */
89 ActivationProgress(sdbusplus::bus::bus& bus, const std::string& path) :
90 ActivationProgressInherit(bus, path.c_str(), true), bus(bus), path(path)
91 {
92 progress(0);
93 std::vector<std::string> interfaces({interface});
94 bus.emit_interfaces_added(path.c_str(), interfaces);
95 }
96
97 ~ActivationProgress()
98 {
99 std::vector<std::string> interfaces({interface});
100 bus.emit_interfaces_removed(path.c_str(), interfaces);
101 }
102
103 private:
104 // TODO Remove once openbmc/openbmc#1975 is resolved
105 static constexpr auto interface =
106 "xyz.openbmc_project.Software.ActivationProgress";
107 sdbusplus::bus::bus& bus;
108 std::string path;
109};
110
Lei YU01539e72019-07-31 10:57:38 +0800111using ActivationInherit = sdbusplus::server::object::object<
112 sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
Lei YU91029442019-08-01 15:57:31 +0800113 sdbusplus::xyz::openbmc_project::Software::server::Activation,
Lei YU99301372019-09-29 16:27:12 +0800114 sdbusplus::xyz::openbmc_project::Association::server::Definitions,
115 sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
Lei YU01539e72019-07-31 10:57:38 +0800116
117/** @class Activation
118 * @brief OpenBMC activation software management implementation.
119 * @details A concrete implementation for
120 * xyz.openbmc_project.Software.Activation DBus API.
121 */
122class Activation : public ActivationInherit
123{
124 public:
Lei YUff83c2a2019-09-12 13:55:18 +0800125 friend class ::TestActivation;
Lei YU12c9f4c2019-09-11 15:08:15 +0800126 using Status = Activations;
Lei YUff83c2a2019-09-12 13:55:18 +0800127
Lei YU01539e72019-07-31 10:57:38 +0800128 /** @brief Constructs Activation Software Manager
129 *
130 * @param[in] bus - The Dbus bus object
131 * @param[in] path - The Dbus object path
132 * @param[in] versionId - The software version id
133 * @param[in] extVersion - The extended version
134 * @param[in] activationStatus - The status of Activation
Lei YU91029442019-08-01 15:57:31 +0800135 * @param[in] assocs - Association objects
Lei YU99301372019-09-29 16:27:12 +0800136 * @param[in] filePath - The image filesystem path
Lei YU01539e72019-07-31 10:57:38 +0800137 */
Lei YU99301372019-09-29 16:27:12 +0800138 Activation(sdbusplus::bus::bus& bus, const std::string& objPath,
Lei YU01539e72019-07-31 10:57:38 +0800139 const std::string& versionId, const std::string& extVersion,
Lei YU7f2a2152019-09-16 16:50:18 +0800140 Status activationStatus, const AssociationList& assocs,
Lei YUffb36532019-10-15 13:55:24 +0800141 const std::string& filePath,
Lei YU99301372019-09-29 16:27:12 +0800142 AssociationInterface* associationInterface,
Lei YUffb36532019-10-15 13:55:24 +0800143 ActivationListener* activationListener) :
Lei YU99301372019-09-29 16:27:12 +0800144 ActivationInherit(bus, objPath.c_str(), true),
145 bus(bus), objPath(objPath), versionId(versionId),
Lei YU12c9f4c2019-09-11 15:08:15 +0800146 systemdSignals(
147 bus,
148 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
149 sdbusRule::path("/org/freedesktop/systemd1") +
150 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
151 std::bind(&Activation::unitStateChange, this,
Lei YU7f2a2152019-09-16 16:50:18 +0800152 std::placeholders::_1)),
Lei YUffb36532019-10-15 13:55:24 +0800153 associationInterface(associationInterface),
154 activationListener(activationListener)
Lei YU01539e72019-07-31 10:57:38 +0800155 {
156 // Set Properties.
157 extendedVersion(extVersion);
158 activation(activationStatus);
Lei YU91029442019-08-01 15:57:31 +0800159 associations(assocs);
Lei YU99301372019-09-29 16:27:12 +0800160 path(filePath);
Lei YU01539e72019-07-31 10:57:38 +0800161
Lei YU9edb7332019-09-19 14:46:19 +0800162 auto info = Version::getExtVersionInfo(extVersion);
163 manufacturer = info["manufacturer"];
164 model = info["model"];
165
Lei YU01539e72019-07-31 10:57:38 +0800166 // Emit deferred signal.
167 emit_object_added();
168 }
169
170 /** @brief Overloaded Activation property setter function
171 *
172 * @param[in] value - One of Activation::Activations
173 *
174 * @return Success or exception thrown
175 */
Lei YUff83c2a2019-09-12 13:55:18 +0800176 Status activation(Status value) override;
Lei YU01539e72019-07-31 10:57:38 +0800177
178 /** @brief Activation */
179 using ActivationInherit::activation;
180
181 /** @brief Overloaded requestedActivation property setter function
182 *
183 * @param[in] value - One of Activation::RequestedActivations
184 *
185 * @return Success or exception thrown
186 */
187 RequestedActivations
188 requestedActivation(RequestedActivations value) override;
189
Lei YU63f9e712019-10-12 15:16:55 +0800190 /** @brief Get the object path */
191 const std::string& getObjectPath() const
192 {
193 return objPath;
194 }
195
Lei YUa5c47bb2019-09-29 11:28:53 +0800196 /** @brief Get the version ID */
197 const std::string& getVersionId() const
198 {
199 return versionId;
200 }
Lei YU12c9f4c2019-09-11 15:08:15 +0800201
202 private:
203 /** @brief Check if systemd state change is relevant to this object
204 *
205 * Instance specific interface to handle the detected systemd state
206 * change
207 *
208 * @param[in] msg - Data associated with subscribed signal
209 *
210 */
211 void unitStateChange(sdbusplus::message::message& msg);
212
Lei YUd0bbfa92019-09-11 16:10:54 +0800213 /**
214 * @brief Delete the version from Image Manager and the
215 * untar image from image upload dir.
216 */
217 void deleteImageManagerObject();
218
Lei YUff83c2a2019-09-12 13:55:18 +0800219 /** @brief Invoke the update service for the PSU
220 *
221 * @param[in] psuInventoryPath - The PSU inventory to be updated.
222 *
223 * @return true if the update starts, and false if it fails.
224 */
225 bool doUpdate(const std::string& psuInventoryPath);
226
227 /** @brief Do PSU update one-by-one
228 *
229 * @return true if the update starts, and false if it fails.
230 */
231 bool doUpdate();
232
233 /** @brief Handle an update done event */
234 void onUpdateDone();
235
236 /** @brief Handle an update failure event */
237 void onUpdateFailed();
238
Lei YU12c9f4c2019-09-11 15:08:15 +0800239 /** @brief Start PSU update */
Lei YUff83c2a2019-09-12 13:55:18 +0800240 Status startActivation();
Lei YU12c9f4c2019-09-11 15:08:15 +0800241
242 /** @brief Finish PSU update */
243 void finishActivation();
244
Lei YU9edb7332019-09-19 14:46:19 +0800245 /** @brief Check if the PSU is comaptible with this software*/
246 bool isCompatible(const std::string& psuInventoryPath);
247
Lei YU2e0e2de2019-09-26 16:42:23 +0800248 /** @brief Store the updated PSU image to persistent dir */
249 void storeImage();
250
Lei YUe8945ea2019-09-29 17:25:31 +0800251 /** @brief Construct the systemd service name
252 *
253 * @param[in] psuInventoryPath - The PSU inventory to be updated.
254 *
255 * @return The escaped string of systemd unit to do the PSU update.
256 */
257 std::string getUpdateService(const std::string& psuInventoryPath);
258
Lei YU01539e72019-07-31 10:57:38 +0800259 /** @brief Persistent sdbusplus DBus bus connection */
260 sdbusplus::bus::bus& bus;
261
262 /** @brief Persistent DBus object path */
Lei YU99301372019-09-29 16:27:12 +0800263 std::string objPath;
Lei YU01539e72019-07-31 10:57:38 +0800264
Lei YUa5c47bb2019-09-29 11:28:53 +0800265 /** @brief Version id */
266 std::string versionId;
267
Lei YU12c9f4c2019-09-11 15:08:15 +0800268 /** @brief Used to subscribe to dbus systemd signals */
269 sdbusplus::bus::match_t systemdSignals;
270
Lei YUff83c2a2019-09-12 13:55:18 +0800271 /** @brief The queue of psu objects to be updated */
272 std::queue<std::string> psuQueue;
273
274 /** @brief The progress step for each PSU update is done */
275 uint32_t progressStep;
276
Lei YU12c9f4c2019-09-11 15:08:15 +0800277 /** @brief The PSU update systemd unit */
278 std::string psuUpdateUnit;
Lei YU81c67722019-09-11 16:47:29 +0800279
Lei YU7f2a2152019-09-16 16:50:18 +0800280 /** @brief The PSU Inventory path of the current updating PSU */
281 std::string currentUpdatingPsu;
282
Lei YU81c67722019-09-11 16:47:29 +0800283 /** @brief Persistent ActivationBlocksTransition dbus object */
284 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
Lei YU90c8a8b2019-09-11 17:20:03 +0800285
286 /** @brief Persistent ActivationProgress dbus object */
287 std::unique_ptr<ActivationProgress> activationProgress;
Lei YU7f2a2152019-09-16 16:50:18 +0800288
289 /** @brief The AssociationInterface pointer */
290 AssociationInterface* associationInterface;
Lei YU9edb7332019-09-19 14:46:19 +0800291
Lei YUffb36532019-10-15 13:55:24 +0800292 /** @brief The activationListener pointer */
293 ActivationListener* activationListener;
294
Lei YU9edb7332019-09-19 14:46:19 +0800295 /** @brief The PSU manufacturer of the software */
296 std::string manufacturer;
297
298 /** @brief The PSU model of the software */
299 std::string model;
Lei YU01539e72019-07-31 10:57:38 +0800300};
301
302} // namespace updater
303} // namespace software
304} // namespace phosphor