blob: e87d20c91671f9249c3ab59ace41da634a457e87 [file] [log] [blame]
Gunnar Millsec1b41c2017-05-02 12:20:36 -05001#pragma once
2
Gunnar Millsb0ce9962018-09-07 13:39:10 -05003#include "config.h"
4
5#include "flash.hpp"
Jayashankar Padatha0135602019-04-22 16:22:58 +05306#include "utils.hpp"
Gunnar Millsb0ce9962018-09-07 13:39:10 -05007#include "xyz/openbmc_project/Software/ActivationProgress/server.hpp"
8#include "xyz/openbmc_project/Software/RedundancyPriority/server.hpp"
9
Saqib Khanb0774702017-05-23 16:02:41 -050010#include <sdbusplus/server.hpp>
John Wang85c356f2019-09-11 16:20:13 +080011#include <xyz/openbmc_project/Association/Definitions/server.hpp>
Gunnar Millsec1b41c2017-05-02 12:20:36 -050012#include <xyz/openbmc_project/Software/Activation/server.hpp>
Saqib Khanb0774702017-05-23 16:02:41 -050013#include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp>
Lei YU90532252018-05-24 11:15:24 +080014
15#ifdef WANT_SIGNATURE_VERIFY
16#include <experimental/filesystem>
17#endif
18
Gunnar Millsec1b41c2017-05-02 12:20:36 -050019namespace phosphor
20{
21namespace software
22{
23namespace updater
24{
25
Lei YU90532252018-05-24 11:15:24 +080026#ifdef WANT_SIGNATURE_VERIFY
27namespace fs = std::experimental::filesystem;
28#endif
29
Gunnar Millsb60add12017-08-24 16:41:42 -050030using AssociationList =
Adriana Kobylak2285fe02018-02-27 15:36:59 -060031 std::vector<std::tuple<std::string, std::string, std::string>>;
Gunnar Millsec1b41c2017-05-02 12:20:36 -050032using ActivationInherit = sdbusplus::server::object::object<
Gunnar Millsf5eaf392017-08-22 16:36:55 -050033 sdbusplus::xyz::openbmc_project::Software::server::Activation,
John Wang85c356f2019-09-11 16:20:13 +080034 sdbusplus::xyz::openbmc_project::Association::server::Definitions>;
Saqib Khanb0774702017-05-23 16:02:41 -050035using ActivationBlocksTransitionInherit = sdbusplus::server::object::object<
Adriana Kobylak2285fe02018-02-27 15:36:59 -060036 sdbusplus::xyz::openbmc_project::Software::server::
37 ActivationBlocksTransition>;
Saqib Khan4c1aec02017-07-06 11:46:13 -050038using RedundancyPriorityInherit = sdbusplus::server::object::object<
39 sdbusplus::xyz::openbmc_project::Software::server::RedundancyPriority>;
Michael Tritz0edd4ad2017-07-26 14:27:42 -050040using ActivationProgressInherit = sdbusplus::server::object::object<
41 sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
Saqib Khan4c1aec02017-07-06 11:46:13 -050042
Jayashankar Padatha0135602019-04-22 16:22:58 +053043constexpr auto applyTimeImmediate =
44 "xyz.openbmc_project.Software.ApplyTime.RequestedApplyTimes.Immediate";
45constexpr auto applyTimeIntf = "xyz.openbmc_project.Software.ApplyTime";
46constexpr auto dbusPropIntf = "org.freedesktop.DBus.Properties";
47constexpr auto applyTimeObjPath = "/xyz/openbmc_project/software/apply_time";
48constexpr auto applyTimeProp = "RequestedApplyTime";
49
Michael Tritzbed88af2017-07-19 16:00:06 -050050namespace sdbusRule = sdbusplus::bus::match::rules;
51
Saqib Khan4c1aec02017-07-06 11:46:13 -050052class ItemUpdater;
53class Activation;
54class RedundancyPriority;
55
56/** @class RedundancyPriority
57 * @brief OpenBMC RedundancyPriority implementation
58 * @details A concrete implementation for
59 * xyz.openbmc_project.Software.RedundancyPriority DBus API.
60 */
61class RedundancyPriority : public RedundancyPriorityInherit
62{
Adriana Kobylak2285fe02018-02-27 15:36:59 -060063 public:
64 /** @brief Constructs RedundancyPriority.
65 *
66 * @param[in] bus - The Dbus bus object
67 * @param[in] path - The Dbus object path
68 * @param[in] parent - Parent object.
69 * @param[in] value - The redundancyPriority value
70 * @param[in] freePriority - Call freePriorioty, default to true
71 */
72 RedundancyPriority(sdbusplus::bus::bus& bus, const std::string& path,
73 Activation& parent, uint8_t value,
74 bool freePriority = true) :
75 RedundancyPriorityInherit(bus, path.c_str(), true),
76 parent(parent), bus(bus), path(path)
77 {
78 // Set Property
79 if (freePriority)
Saqib Khan4c1aec02017-07-06 11:46:13 -050080 {
Adriana Kobylak2285fe02018-02-27 15:36:59 -060081 priority(value);
82 }
83 else
84 {
85 sdbusPriority(value);
Saqib Khan140fcb12017-08-07 09:06:57 -050086 }
87
Adriana Kobylak2285fe02018-02-27 15:36:59 -060088 std::vector<std::string> interfaces({interface});
89 bus.emit_interfaces_added(path.c_str(), interfaces);
90 }
Saqib Khan4c1aec02017-07-06 11:46:13 -050091
Adriana Kobylak2285fe02018-02-27 15:36:59 -060092 ~RedundancyPriority()
93 {
94 std::vector<std::string> interfaces({interface});
95 bus.emit_interfaces_removed(path.c_str(), interfaces);
96 }
Saqib Khan4c1aec02017-07-06 11:46:13 -050097
Gunnar Millse11a2022018-03-23 12:04:48 -050098 /** @brief Overridden Priority property set function, calls freePriority
Adriana Kobylak2285fe02018-02-27 15:36:59 -060099 * to bump the duplicated priority values.
100 *
101 * @param[in] value - uint8_t
102 *
103 * @return Success or exception thrown
104 */
105 uint8_t priority(uint8_t value) override;
Adriana Kobylakb77551c2017-10-27 12:46:23 -0500106
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600107 /** @brief Non-Overriden Priority property set function
108 *
109 * @param[in] value - uint8_t
110 *
111 * @return Success or exception thrown
112 */
113 uint8_t sdbusPriority(uint8_t value);
Saqib Khan4c1aec02017-07-06 11:46:13 -0500114
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600115 /** @brief Priority property get function
116 *
117 * @returns uint8_t - The Priority value
118 */
119 using RedundancyPriorityInherit::priority;
Saqib Khan140fcb12017-08-07 09:06:57 -0500120
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600121 /** @brief Parent Object. */
122 Activation& parent;
123
124 private:
125 // TODO Remove once openbmc/openbmc#1975 is resolved
126 static constexpr auto interface =
127 "xyz.openbmc_project.Software.RedundancyPriority";
128 sdbusplus::bus::bus& bus;
129 std::string path;
Saqib Khan4c1aec02017-07-06 11:46:13 -0500130};
Saqib Khanb0774702017-05-23 16:02:41 -0500131
132/** @class ActivationBlocksTransition
133 * @brief OpenBMC ActivationBlocksTransition implementation.
134 * @details A concrete implementation for
135 * xyz.openbmc_project.Software.ActivationBlocksTransition DBus API.
136 */
137class ActivationBlocksTransition : public ActivationBlocksTransitionInherit
138{
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600139 public:
140 /** @brief Constructs ActivationBlocksTransition.
141 *
142 * @param[in] bus - The Dbus bus object
143 * @param[in] path - The Dbus object path
144 */
145 ActivationBlocksTransition(sdbusplus::bus::bus& bus,
146 const std::string& path) :
147 ActivationBlocksTransitionInherit(bus, path.c_str(), true),
148 bus(bus), path(path)
149 {
150 std::vector<std::string> interfaces({interface});
151 bus.emit_interfaces_added(path.c_str(), interfaces);
152 enableRebootGuard();
153 }
Saqib Khan140fcb12017-08-07 09:06:57 -0500154
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600155 ~ActivationBlocksTransition()
156 {
157 std::vector<std::string> interfaces({interface});
158 bus.emit_interfaces_removed(path.c_str(), interfaces);
159 disableRebootGuard();
160 }
Saqib Khan140fcb12017-08-07 09:06:57 -0500161
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600162 private:
163 // TODO Remove once openbmc/openbmc#1975 is resolved
164 static constexpr auto interface =
165 "xyz.openbmc_project.Software.ActivationBlocksTransition";
166 sdbusplus::bus::bus& bus;
167 std::string path;
Saqib Khanf37cefc2017-09-12 08:44:41 -0500168
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600169 /** @brief Enables a Guard that blocks any BMC reboot commands */
170 void enableRebootGuard();
Saqib Khanf37cefc2017-09-12 08:44:41 -0500171
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600172 /** @brief Disables any guard that was blocking the BMC reboot */
173 void disableRebootGuard();
Saqib Khanb0774702017-05-23 16:02:41 -0500174};
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500175
Michael Tritz0edd4ad2017-07-26 14:27:42 -0500176class ActivationProgress : public ActivationProgressInherit
177{
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600178 public:
179 /** @brief Constructs ActivationProgress.
180 *
181 * @param[in] bus - The Dbus bus object
182 * @param[in] path - The Dbus object path
183 */
184 ActivationProgress(sdbusplus::bus::bus& bus, const std::string& path) :
185 ActivationProgressInherit(bus, path.c_str(), true), bus(bus), path(path)
186 {
187 progress(0);
188 std::vector<std::string> interfaces({interface});
189 bus.emit_interfaces_added(path.c_str(), interfaces);
190 }
Saqib Khan140fcb12017-08-07 09:06:57 -0500191
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600192 ~ActivationProgress()
193 {
194 std::vector<std::string> interfaces({interface});
195 bus.emit_interfaces_removed(path.c_str(), interfaces);
196 }
Saqib Khan140fcb12017-08-07 09:06:57 -0500197
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600198 private:
199 // TODO Remove once openbmc/openbmc#1975 is resolved
200 static constexpr auto interface =
201 "xyz.openbmc_project.Software.ActivationProgress";
202 sdbusplus::bus::bus& bus;
203 std::string path;
Michael Tritz0edd4ad2017-07-26 14:27:42 -0500204};
205
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500206/** @class Activation
207 * @brief OpenBMC activation software management implementation.
208 * @details A concrete implementation for
209 * xyz.openbmc_project.Software.Activation DBus API.
210 */
Lei YU1be8d502018-06-20 11:48:36 +0800211class Activation : public ActivationInherit, public Flash
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500212{
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600213 public:
214 /** @brief Constructs Activation Software Manager
215 *
216 * @param[in] bus - The Dbus bus object
217 * @param[in] path - The Dbus object path
218 * @param[in] parent - Parent object.
219 * @param[in] versionId - The software version id
220 * @param[in] activationStatus - The status of Activation
221 * @param[in] assocs - Association objects
222 */
223 Activation(sdbusplus::bus::bus& bus, const std::string& path,
224 ItemUpdater& parent, std::string& versionId,
225 sdbusplus::xyz::openbmc_project::Software::server::Activation::
226 Activations activationStatus,
227 AssociationList& assocs) :
228 ActivationInherit(bus, path.c_str(), true),
229 bus(bus), path(path), parent(parent), versionId(versionId),
230 systemdSignals(
231 bus,
232 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
233 sdbusRule::path("/org/freedesktop/systemd1") +
234 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
235 std::bind(std::mem_fn(&Activation::unitStateChange), this,
236 std::placeholders::_1))
237 {
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600238 // Set Properties.
239 activation(activationStatus);
240 associations(assocs);
Gunnar Millsb60add12017-08-24 16:41:42 -0500241
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600242 // Emit deferred signal.
243 emit_object_added();
244 }
Gunnar Mills2ce7da22017-05-04 15:37:56 -0500245
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600246 /** @brief Overloaded Activation property setter function
247 *
248 * @param[in] value - One of Activation::Activations
249 *
250 * @return Success or exception thrown
251 */
252 Activations activation(Activations value) override;
Saqib Khanb0774702017-05-23 16:02:41 -0500253
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600254 /** @brief Activation */
255 using ActivationInherit::activation;
Leonel Gonzaleze4233682017-07-07 14:38:25 -0500256
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600257 /** @brief Overloaded requestedActivation property setter function
258 *
259 * @param[in] value - One of Activation::RequestedActivations
260 *
261 * @return Success or exception thrown
262 */
263 RequestedActivations
264 requestedActivation(RequestedActivations value) override;
Saqib Khanb0774702017-05-23 16:02:41 -0500265
Adriana Kobylak9f89e2e2018-05-30 13:16:20 -0500266 /** @brief Overloaded write flash function */
267 void flashWrite() override;
268
Adriana Kobylak3ce563a2018-06-06 16:41:15 -0500269 /** @brief Overloaded function that acts on service file state changes */
270 void onStateChanges(sdbusplus::message::message&) override;
271
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600272 /** @brief Check if systemd state change is relevant to this object
273 *
274 * Instance specific interface to handle the detected systemd state
275 * change
276 *
277 * @param[in] msg - Data associated with subscribed signal
278 *
279 */
280 void unitStateChange(sdbusplus::message::message& msg);
Michael Tritzbed88af2017-07-19 16:00:06 -0500281
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600282 /**
283 * @brief subscribe to the systemd signals
284 *
285 * This object needs to capture when it's systemd targets complete
286 * so it can keep it's state updated
287 *
288 */
289 void subscribeToSystemdSignals();
Michael Tritzbed88af2017-07-19 16:00:06 -0500290
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600291 /**
292 * @brief unsubscribe from the systemd signals
293 *
294 * systemd signals are only of interest during the activation process.
295 * Once complete, we want to unsubscribe to avoid unnecessary calls of
296 * unitStateChange().
297 *
298 */
299 void unsubscribeFromSystemdSignals();
Michael Tritzf2b5e0d2017-07-25 14:39:34 -0500300
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600301 /**
302 * @brief Deletes the version from Image Manager and the
303 * untar image from image upload dir.
304 */
305 void deleteImageManagerObject();
Saqib Khanee13e832017-10-23 12:53:11 -0500306
Jayashankar Padatha0135602019-04-22 16:22:58 +0530307 /**
308 * @brief Determine the configured image apply time value
309 *
310 * @return true if the image apply time value is immediate
311 **/
312 bool checkApplyTimeImmediate();
313
314 /**
315 * @brief Reboot the BMC. Called when ApplyTime is immediate.
316 *
317 * @return none
318 **/
319 void rebootBmc();
320
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600321 /** @brief Persistent sdbusplus DBus bus connection */
322 sdbusplus::bus::bus& bus;
Gunnar Mills2ce7da22017-05-04 15:37:56 -0500323
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600324 /** @brief Persistent DBus object path */
325 std::string path;
Gunnar Mills2ce7da22017-05-04 15:37:56 -0500326
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600327 /** @brief Parent Object. */
328 ItemUpdater& parent;
Saqib Khan4c1aec02017-07-06 11:46:13 -0500329
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600330 /** @brief Version id */
331 std::string versionId;
Saqib Khanb0774702017-05-23 16:02:41 -0500332
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600333 /** @brief Persistent ActivationBlocksTransition dbus object */
334 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
Saqib Khan4c1aec02017-07-06 11:46:13 -0500335
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600336 /** @brief Persistent RedundancyPriority dbus object */
337 std::unique_ptr<RedundancyPriority> redundancyPriority;
Michael Tritzbed88af2017-07-19 16:00:06 -0500338
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600339 /** @brief Persistent ActivationProgress dbus object */
340 std::unique_ptr<ActivationProgress> activationProgress;
Michael Tritz0edd4ad2017-07-26 14:27:42 -0500341
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600342 /** @brief Used to subscribe to dbus systemd signals **/
343 sdbusplus::bus::match_t systemdSignals;
Michael Tritzbed88af2017-07-19 16:00:06 -0500344
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600345 /** @brief Tracks whether the read-write volume has been created as
346 * part of the activation process. **/
347 bool rwVolumeCreated = false;
Michael Tritzbed88af2017-07-19 16:00:06 -0500348
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600349 /** @brief Tracks whether the read-only volume has been created as
350 * part of the activation process. **/
351 bool roVolumeCreated = false;
Adriana Kobylak166bdf32018-04-09 14:24:06 -0500352
353 /** @brief Tracks if the service that updates the U-Boot environment
354 * variables has completed. **/
355 bool ubootEnvVarsUpdated = false;
Lei YU90532252018-05-24 11:15:24 +0800356
357#ifdef WANT_SIGNATURE_VERIFY
358 private:
359 /** @brief Verify signature of the images.
360 *
361 * @param[in] imageDir - The path of images to verify
362 * @param[in] confDir - The path of configs for verification
363 *
364 * @return true if verification successful and false otherwise
365 */
366 bool verifySignature(const fs::path& imageDir, const fs::path& confDir);
367
368 /** @brief Called when image verification fails. */
369 void onVerifyFailed();
370#endif
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500371};
372
373} // namespace updater
374} // namespace software
375} // namespace phosphor