blob: 3b038039a53f1cd05e0ca9b9114bcc27d2d5acff [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);
54 }
55
56 ~ActivationBlocksTransition()
57 {
58 std::vector<std::string> interfaces({interface});
59 bus.emit_interfaces_removed(path.c_str(), interfaces);
60 }
61
62 private:
63 // TODO Remove once openbmc/openbmc#1975 is resolved
64 static constexpr auto interface =
65 "xyz.openbmc_project.Software.ActivationBlocksTransition";
66 sdbusplus::bus::bus& bus;
67 std::string path;
68};
69
Lei YU90c8a8b2019-09-11 17:20:03 +080070using ActivationProgressInherit = sdbusplus::server::object::object<
71 sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
72
73class ActivationProgress : public ActivationProgressInherit
74{
75 public:
76 /** @brief Constructs ActivationProgress.
77 *
78 * @param[in] bus - The Dbus bus object
79 * @param[in] path - The Dbus object path
80 */
81 ActivationProgress(sdbusplus::bus::bus& bus, const std::string& path) :
82 ActivationProgressInherit(bus, path.c_str(), true), bus(bus), path(path)
83 {
84 progress(0);
85 std::vector<std::string> interfaces({interface});
86 bus.emit_interfaces_added(path.c_str(), interfaces);
87 }
88
89 ~ActivationProgress()
90 {
91 std::vector<std::string> interfaces({interface});
92 bus.emit_interfaces_removed(path.c_str(), interfaces);
93 }
94
95 private:
96 // TODO Remove once openbmc/openbmc#1975 is resolved
97 static constexpr auto interface =
98 "xyz.openbmc_project.Software.ActivationProgress";
99 sdbusplus::bus::bus& bus;
100 std::string path;
101};
102
Lei YU01539e72019-07-31 10:57:38 +0800103using ActivationInherit = sdbusplus::server::object::object<
104 sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
Lei YU91029442019-08-01 15:57:31 +0800105 sdbusplus::xyz::openbmc_project::Software::server::Activation,
Lei YU99301372019-09-29 16:27:12 +0800106 sdbusplus::xyz::openbmc_project::Association::server::Definitions,
107 sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
Lei YU01539e72019-07-31 10:57:38 +0800108
109/** @class Activation
110 * @brief OpenBMC activation software management implementation.
111 * @details A concrete implementation for
112 * xyz.openbmc_project.Software.Activation DBus API.
113 */
114class Activation : public ActivationInherit
115{
116 public:
Lei YUff83c2a2019-09-12 13:55:18 +0800117 friend class ::TestActivation;
Lei YU12c9f4c2019-09-11 15:08:15 +0800118 using Status = Activations;
Lei YUff83c2a2019-09-12 13:55:18 +0800119
Lei YU01539e72019-07-31 10:57:38 +0800120 /** @brief Constructs Activation Software Manager
121 *
122 * @param[in] bus - The Dbus bus object
123 * @param[in] path - The Dbus object path
124 * @param[in] versionId - The software version id
125 * @param[in] extVersion - The extended version
126 * @param[in] activationStatus - The status of Activation
Lei YU91029442019-08-01 15:57:31 +0800127 * @param[in] assocs - Association objects
Lei YU99301372019-09-29 16:27:12 +0800128 * @param[in] filePath - The image filesystem path
Lei YU01539e72019-07-31 10:57:38 +0800129 */
Lei YU99301372019-09-29 16:27:12 +0800130 Activation(sdbusplus::bus::bus& bus, const std::string& objPath,
Lei YU01539e72019-07-31 10:57:38 +0800131 const std::string& versionId, const std::string& extVersion,
Lei YU7f2a2152019-09-16 16:50:18 +0800132 Status activationStatus, const AssociationList& assocs,
Lei YUffb36532019-10-15 13:55:24 +0800133 const std::string& filePath,
Lei YU99301372019-09-29 16:27:12 +0800134 AssociationInterface* associationInterface,
Lei YUffb36532019-10-15 13:55:24 +0800135 ActivationListener* activationListener) :
Lei YU99301372019-09-29 16:27:12 +0800136 ActivationInherit(bus, objPath.c_str(), true),
137 bus(bus), objPath(objPath), versionId(versionId),
Lei YU12c9f4c2019-09-11 15:08:15 +0800138 systemdSignals(
139 bus,
140 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
141 sdbusRule::path("/org/freedesktop/systemd1") +
142 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
143 std::bind(&Activation::unitStateChange, this,
Lei YU7f2a2152019-09-16 16:50:18 +0800144 std::placeholders::_1)),
Lei YUffb36532019-10-15 13:55:24 +0800145 associationInterface(associationInterface),
146 activationListener(activationListener)
Lei YU01539e72019-07-31 10:57:38 +0800147 {
148 // Set Properties.
149 extendedVersion(extVersion);
150 activation(activationStatus);
Lei YU91029442019-08-01 15:57:31 +0800151 associations(assocs);
Lei YU99301372019-09-29 16:27:12 +0800152 path(filePath);
Lei YU01539e72019-07-31 10:57:38 +0800153
Lei YU9edb7332019-09-19 14:46:19 +0800154 auto info = Version::getExtVersionInfo(extVersion);
155 manufacturer = info["manufacturer"];
156 model = info["model"];
157
Lei YU01539e72019-07-31 10:57:38 +0800158 // Emit deferred signal.
159 emit_object_added();
160 }
161
162 /** @brief Overloaded Activation property setter function
163 *
164 * @param[in] value - One of Activation::Activations
165 *
166 * @return Success or exception thrown
167 */
Lei YUff83c2a2019-09-12 13:55:18 +0800168 Status activation(Status value) override;
Lei YU01539e72019-07-31 10:57:38 +0800169
170 /** @brief Activation */
171 using ActivationInherit::activation;
172
173 /** @brief Overloaded requestedActivation property setter function
174 *
175 * @param[in] value - One of Activation::RequestedActivations
176 *
177 * @return Success or exception thrown
178 */
179 RequestedActivations
180 requestedActivation(RequestedActivations value) override;
181
Lei YU63f9e712019-10-12 15:16:55 +0800182 /** @brief Get the object path */
183 const std::string& getObjectPath() const
184 {
185 return objPath;
186 }
187
Lei YUa5c47bb2019-09-29 11:28:53 +0800188 /** @brief Get the version ID */
189 const std::string& getVersionId() const
190 {
191 return versionId;
192 }
Lei YU12c9f4c2019-09-11 15:08:15 +0800193
194 private:
195 /** @brief Check if systemd state change is relevant to this object
196 *
197 * Instance specific interface to handle the detected systemd state
198 * change
199 *
200 * @param[in] msg - Data associated with subscribed signal
201 *
202 */
203 void unitStateChange(sdbusplus::message::message& msg);
204
Lei YUd0bbfa92019-09-11 16:10:54 +0800205 /**
206 * @brief Delete the version from Image Manager and the
207 * untar image from image upload dir.
208 */
209 void deleteImageManagerObject();
210
Lei YUff83c2a2019-09-12 13:55:18 +0800211 /** @brief Invoke the update service for the PSU
212 *
213 * @param[in] psuInventoryPath - The PSU inventory to be updated.
214 *
215 * @return true if the update starts, and false if it fails.
216 */
217 bool doUpdate(const std::string& psuInventoryPath);
218
219 /** @brief Do PSU update one-by-one
220 *
221 * @return true if the update starts, and false if it fails.
222 */
223 bool doUpdate();
224
225 /** @brief Handle an update done event */
226 void onUpdateDone();
227
228 /** @brief Handle an update failure event */
229 void onUpdateFailed();
230
Lei YU12c9f4c2019-09-11 15:08:15 +0800231 /** @brief Start PSU update */
Lei YUff83c2a2019-09-12 13:55:18 +0800232 Status startActivation();
Lei YU12c9f4c2019-09-11 15:08:15 +0800233
234 /** @brief Finish PSU update */
235 void finishActivation();
236
Lei YU9edb7332019-09-19 14:46:19 +0800237 /** @brief Check if the PSU is comaptible with this software*/
238 bool isCompatible(const std::string& psuInventoryPath);
239
Lei YU2e0e2de2019-09-26 16:42:23 +0800240 /** @brief Store the updated PSU image to persistent dir */
241 void storeImage();
242
Lei YUe8945ea2019-09-29 17:25:31 +0800243 /** @brief Construct the systemd service name
244 *
245 * @param[in] psuInventoryPath - The PSU inventory to be updated.
246 *
247 * @return The escaped string of systemd unit to do the PSU update.
248 */
249 std::string getUpdateService(const std::string& psuInventoryPath);
250
Lei YU01539e72019-07-31 10:57:38 +0800251 /** @brief Persistent sdbusplus DBus bus connection */
252 sdbusplus::bus::bus& bus;
253
254 /** @brief Persistent DBus object path */
Lei YU99301372019-09-29 16:27:12 +0800255 std::string objPath;
Lei YU01539e72019-07-31 10:57:38 +0800256
Lei YUa5c47bb2019-09-29 11:28:53 +0800257 /** @brief Version id */
258 std::string versionId;
259
Lei YU12c9f4c2019-09-11 15:08:15 +0800260 /** @brief Used to subscribe to dbus systemd signals */
261 sdbusplus::bus::match_t systemdSignals;
262
Lei YUff83c2a2019-09-12 13:55:18 +0800263 /** @brief The queue of psu objects to be updated */
264 std::queue<std::string> psuQueue;
265
266 /** @brief The progress step for each PSU update is done */
267 uint32_t progressStep;
268
Lei YU12c9f4c2019-09-11 15:08:15 +0800269 /** @brief The PSU update systemd unit */
270 std::string psuUpdateUnit;
Lei YU81c67722019-09-11 16:47:29 +0800271
Lei YU7f2a2152019-09-16 16:50:18 +0800272 /** @brief The PSU Inventory path of the current updating PSU */
273 std::string currentUpdatingPsu;
274
Lei YU81c67722019-09-11 16:47:29 +0800275 /** @brief Persistent ActivationBlocksTransition dbus object */
276 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
Lei YU90c8a8b2019-09-11 17:20:03 +0800277
278 /** @brief Persistent ActivationProgress dbus object */
279 std::unique_ptr<ActivationProgress> activationProgress;
Lei YU7f2a2152019-09-16 16:50:18 +0800280
281 /** @brief The AssociationInterface pointer */
282 AssociationInterface* associationInterface;
Lei YU9edb7332019-09-19 14:46:19 +0800283
Lei YUffb36532019-10-15 13:55:24 +0800284 /** @brief The activationListener pointer */
285 ActivationListener* activationListener;
286
Lei YU9edb7332019-09-19 14:46:19 +0800287 /** @brief The PSU manufacturer of the software */
288 std::string manufacturer;
289
290 /** @brief The PSU model of the software */
291 std::string model;
Lei YU01539e72019-07-31 10:57:38 +0800292};
293
294} // namespace updater
295} // namespace software
296} // namespace phosphor