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