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