1 #pragma once
2 
3 #include <sdbusplus/server.hpp>
4 #include <xyz/openbmc_project/Software/Activation/server.hpp>
5 #include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp>
6 #include "xyz/openbmc_project/Software/ExtendedVersion/server.hpp"
7 #include "xyz/openbmc_project/Software/RedundancyPriority/server.hpp"
8 #include "xyz/openbmc_project/Software/ActivationProgress/server.hpp"
9 #include "org/openbmc/Associations/server.hpp"
10 
11 namespace openpower
12 {
13 namespace software
14 {
15 namespace updater
16 {
17 
18 using AssociationList =
19     std::vector<std::tuple<std::string, std::string, std::string>>;
20 using ActivationInherit = sdbusplus::server::object::object<
21     sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
22     sdbusplus::xyz::openbmc_project::Software::server::Activation,
23     sdbusplus::org::openbmc::server::Associations>;
24 using ActivationBlocksTransitionInherit = sdbusplus::server::object::object<
25     sdbusplus::xyz::openbmc_project::Software::server::
26         ActivationBlocksTransition>;
27 using RedundancyPriorityInherit = sdbusplus::server::object::object<
28     sdbusplus::xyz::openbmc_project::Software::server::RedundancyPriority>;
29 using ActivationProgressInherit = sdbusplus::server::object::object<
30     sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
31 
32 namespace sdbusRule = sdbusplus::bus::match::rules;
33 
34 class ItemUpdater;
35 class Activation;
36 class RedundancyPriority;
37 
38 /** @class RedundancyPriority
39  *  @brief OpenBMC RedundancyPriority implementation
40  *  @details A concrete implementation for
41  *  xyz.openbmc_project.Software.RedundancyPriority DBus API.
42  */
43 class RedundancyPriority : public RedundancyPriorityInherit
44 {
45   public:
46     /** @brief Constructs RedundancyPriority.
47      *
48      *  @param[in] bus    - The Dbus bus object
49      *  @param[in] path   - The Dbus object path
50      *  @param[in] parent - Parent object.
51      *  @param[in] value  - The redundancyPriority value
52      */
53     RedundancyPriority(sdbusplus::bus::bus& bus, const std::string& path,
54                        Activation& parent, uint8_t value) :
55         RedundancyPriorityInherit(bus, path.c_str(), true),
56         parent(parent), bus(bus), path(path)
57     {
58         // Set Property
59         priority(value);
60         std::vector<std::string> interfaces({interface});
61         bus.emit_interfaces_added(path.c_str(), interfaces);
62     }
63 
64     ~RedundancyPriority()
65     {
66         std::vector<std::string> interfaces({interface});
67         bus.emit_interfaces_removed(path.c_str(), interfaces);
68     }
69 
70     /** @brief Overloaded Priority property set function
71      *
72      *  @param[in] value - uint8_t
73      *
74      *  @return Success or exception thrown
75      */
76     uint8_t priority(uint8_t value) override;
77 
78     /** @brief Priority property get function
79      *
80      * @returns uint8_t - The Priority value
81      */
82     using RedundancyPriorityInherit::priority;
83 
84     /** @brief Parent Object. */
85     Activation& parent;
86 
87   private:
88     // TODO Remove once openbmc/openbmc#1975 is resolved
89     static constexpr auto interface =
90         "xyz.openbmc_project.Software.RedundancyPriority";
91     sdbusplus::bus::bus& bus;
92     std::string path;
93 };
94 
95 /** @class ActivationBlocksTransition
96  *  @brief OpenBMC ActivationBlocksTransition implementation.
97  *  @details A concrete implementation for
98  *  xyz.openbmc_project.Software.ActivationBlocksTransition DBus API.
99  */
100 class ActivationBlocksTransition : public ActivationBlocksTransitionInherit
101 {
102   public:
103     /** @brief Constructs ActivationBlocksTransition.
104      *
105      * @param[in] bus    - The Dbus bus object
106      * @param[in] path   - The Dbus object path
107      */
108     ActivationBlocksTransition(sdbusplus::bus::bus& bus,
109                                const std::string& path) :
110         ActivationBlocksTransitionInherit(bus, path.c_str(), true),
111         bus(bus), path(path)
112     {
113         std::vector<std::string> interfaces({interface});
114         bus.emit_interfaces_added(path.c_str(), interfaces);
115     }
116 
117     ~ActivationBlocksTransition()
118     {
119         std::vector<std::string> interfaces({interface});
120         bus.emit_interfaces_removed(path.c_str(), interfaces);
121     }
122 
123   private:
124     // TODO Remove once openbmc/openbmc#1975 is resolved
125     static constexpr auto interface =
126         "xyz.openbmc_project.Software.ActivationBlocksTransition";
127     sdbusplus::bus::bus& bus;
128     std::string path;
129 };
130 
131 class ActivationProgress : public ActivationProgressInherit
132 {
133   public:
134     /** @brief Constructs ActivationProgress.
135      *
136      * @param[in] bus    - The Dbus bus object
137      * @param[in] path   - The Dbus object path
138      */
139     ActivationProgress(sdbusplus::bus::bus& bus, const std::string& path) :
140         ActivationProgressInherit(bus, path.c_str(), true), bus(bus), path(path)
141     {
142         progress(0);
143         std::vector<std::string> interfaces({interface});
144         bus.emit_interfaces_added(path.c_str(), interfaces);
145     }
146 
147     ~ActivationProgress()
148     {
149         std::vector<std::string> interfaces({interface});
150         bus.emit_interfaces_removed(path.c_str(), interfaces);
151     }
152 
153   private:
154     // TODO Remove once openbmc/openbmc#1975 is resolved
155     static constexpr auto interface =
156         "xyz.openbmc_project.Software.ActivationProgress";
157     sdbusplus::bus::bus& bus;
158     std::string path;
159 };
160 
161 /** @class Activation
162  *  @brief OpenBMC activation software management implementation.
163  *  @details A concrete implementation for
164  *  xyz.openbmc_project.Software.Activation DBus API.
165  */
166 class Activation : public ActivationInherit
167 {
168   public:
169     /** @brief Constructs Activation Software Manager
170      *
171      * @param[in] bus    - The Dbus bus object
172      * @param[in] path   - The Dbus object path
173      * @param[in] parent - Parent object.
174      * @param[in] versionId  - The software version id
175      * @param[in] extVersion - The extended version
176      * @param[in] activationStatus - The status of Activation
177      * @param[in] assocs - Association objects
178      */
179     Activation(sdbusplus::bus::bus& bus, const std::string& path,
180                ItemUpdater& parent, std::string& versionId,
181                std::string& extVersion,
182                sdbusplus::xyz::openbmc_project::Software::server::Activation::
183                    Activations activationStatus,
184                AssociationList& assocs) :
185         ActivationInherit(bus, path.c_str(), true),
186         bus(bus), path(path), parent(parent), versionId(versionId),
187         systemdSignals(
188             bus,
189             sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
190                 sdbusRule::path("/org/freedesktop/systemd1") +
191                 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
192             std::bind(std::mem_fn(&Activation::unitStateChange), this,
193                       std::placeholders::_1))
194     {
195         // Enable systemd signals
196         subscribeToSystemdSignals();
197         // Set Properties.
198         extendedVersion(extVersion);
199         activation(activationStatus);
200         associations(assocs);
201 
202         // Emit deferred signal.
203         emit_object_added();
204     }
205 
206     /** @brief Activation property get function
207      *
208      *  @returns One of Activation::Activations
209      */
210     using ActivationInherit::activation;
211 
212     /** @brief Overloaded Activation property setter function
213      *
214      *  @param[in] value - One of Activation::Activations
215      *
216      *  @return Success or exception thrown
217      */
218     Activations activation(Activations value) override;
219 
220     /** @brief Overloaded requestedActivation property setter function
221      *
222      *  @param[in] value - One of Activation::RequestedActivations
223      *
224      *  @return Success or exception thrown
225      */
226     RequestedActivations
227         requestedActivation(RequestedActivations value) override;
228 
229     /** @brief Check if systemd state change is relevant to this object
230      *
231      * Instance specific interface to handle the detected systemd state
232      * change
233      *
234      * @param[in]  msg       - Data associated with subscribed signal
235      *
236      */
237     void unitStateChange(sdbusplus::message::message& msg);
238 
239     /**
240      * @brief subscribe to the systemd signals
241      *
242      * This object needs to capture when it's systemd targets complete
243      * so it can keep it's state updated
244      *
245      **/
246     void subscribeToSystemdSignals();
247 
248     /**
249      * @brief unsubscribe from the systemd signals
250      *
251      * Once the activation process has completed successfully, we can
252      * safely unsubscribe from systemd signals.
253      *
254      **/
255     void unsubscribeFromSystemdSignals();
256 
257     /** @brief Persistent sdbusplus DBus bus connection */
258     sdbusplus::bus::bus& bus;
259 
260     /** @brief Persistent DBus object path */
261     std::string path;
262 
263     /** @brief Parent Object. */
264     ItemUpdater& parent;
265 
266     /** @brief Version id */
267     std::string versionId;
268 
269     /** @brief Persistent ActivationBlocksTransition dbus object */
270     std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
271 
272     /** @brief Persistent ActivationProgress dbus object */
273     std::unique_ptr<ActivationProgress> activationProgress;
274 
275     /** @brief Persistent RedundancyPriority dbus object */
276     std::unique_ptr<RedundancyPriority> redundancyPriority;
277 
278     /** @brief Used to subscribe to dbus systemd signals **/
279     sdbusplus::bus::match_t systemdSignals;
280 
281     /** @brief Tracks whether the read-only & read-write volumes have been
282      *created as part of the activation process. **/
283     bool ubiVolumesCreated = false;
284 
285     /** @brief activation status property get function
286      *
287      * @returns Activations - The activation value
288      */
289     using ActivationInherit::activation;
290 
291   private:
292     /**
293      * @brief Deletes the version from Image Manager and the
294      *        untar image from image upload dir.
295      */
296     void deleteImageManagerObject();
297 
298     /** @brief Member function for clarity & brevity at activation start */
299     void startActivation();
300 
301     /** @brief Member function for clarity & brevity at activation end */
302     void finishActivation();
303 };
304 
305 } // namespace updater
306 } // namespace software
307 } // namespace openpower
308