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