blob: 61ff66677560ce5f5aeb05b909f1d952b27db95e [file] [log] [blame]
Lei YU01539e72019-07-31 10:57:38 +08001#pragma once
2
3#include "config.h"
4
5#include "activation.hpp"
Lei YU7f2a2152019-09-16 16:50:18 +08006#include "association_interface.hpp"
Lei YU91029442019-08-01 15:57:31 +08007#include "types.hpp"
Lei YU5e0dcb32019-08-02 18:04:34 +08008#include "utils.hpp"
Lei YU01539e72019-07-31 10:57:38 +08009#include "version.hpp"
10
Lei YU5e0dcb32019-08-02 18:04:34 +080011#include <phosphor-logging/log.hpp>
Lei YU01539e72019-07-31 10:57:38 +080012#include <sdbusplus/server.hpp>
Lei YU91029442019-08-01 15:57:31 +080013#include <xyz/openbmc_project/Association/Definitions/server.hpp>
Lei YU01539e72019-07-31 10:57:38 +080014#include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>
15
Patrick Williams5670b182023-05-10 07:50:50 -050016#include <filesystem>
17
Lei YUf77189f2019-08-07 14:26:30 +080018class TestItemUpdater;
19
Lei YU01539e72019-07-31 10:57:38 +080020namespace phosphor
21{
22namespace software
23{
24namespace updater
25{
26
27class Version;
28
Patrick Williams374fae52022-07-22 19:26:55 -050029using ItemUpdaterInherit = sdbusplus::server::object_t<
Lei YUa5c47bb2019-09-29 11:28:53 +080030 sdbusplus::xyz::openbmc_project::Association::server::Definitions>;
31
Lei YU01539e72019-07-31 10:57:38 +080032namespace MatchRules = sdbusplus::bus::match::rules;
33
Lei YU58c26e32019-09-27 17:52:06 +080034namespace fs = std::filesystem;
35
Lei YU01539e72019-07-31 10:57:38 +080036/** @class ItemUpdater
37 * @brief Manages the activation of the PSU version items.
38 */
Patrick Williams5670b182023-05-10 07:50:50 -050039class ItemUpdater :
40 public ItemUpdaterInherit,
41 public AssociationInterface,
42 public ActivationListener
Lei YU01539e72019-07-31 10:57:38 +080043{
Lei YUf77189f2019-08-07 14:26:30 +080044 friend class ::TestItemUpdater;
45
Lei YU01539e72019-07-31 10:57:38 +080046 public:
47 /** @brief Constructs ItemUpdater
48 *
49 * @param[in] bus - The D-Bus bus object
50 * @param[in] path - The D-Bus path
51 */
Patrick Williams374fae52022-07-22 19:26:55 -050052 ItemUpdater(sdbusplus::bus_t& bus, const std::string& path) :
Lei YU01539e72019-07-31 10:57:38 +080053 ItemUpdaterInherit(bus, path.c_str()), bus(bus),
54 versionMatch(bus,
55 MatchRules::interfacesAdded() +
56 MatchRules::path(SOFTWARE_OBJPATH),
57 std::bind(std::mem_fn(&ItemUpdater::createActivation),
Faisal Awada760053d2024-05-16 13:31:32 -050058 this, std::placeholders::_1)),
59 psuInterfaceMatch(
60 bus,
61 MatchRules::interfacesAdded() +
62 MatchRules::path("/xyz/openbmc_project/inventory") +
63 MatchRules::sender("xyz.openbmc_project.Inventory.Manager"),
64 std::bind(std::mem_fn(&ItemUpdater::onPSUInterfaceAdded), this,
65 std::placeholders::_1))
Lei YU01539e72019-07-31 10:57:38 +080066 {
Faisal Awada760053d2024-05-16 13:31:32 -050067 processPSUImageAndSyncToLatest();
Lei YU01539e72019-07-31 10:57:38 +080068 }
69
70 /** @brief Deletes version
71 *
72 * @param[in] versionId - Id of the version to delete
73 */
Lei YUa5c47bb2019-09-29 11:28:53 +080074 void erase(const std::string& versionId);
Lei YU01539e72019-07-31 10:57:38 +080075
Lei YU91029442019-08-01 15:57:31 +080076 /** @brief Creates an active association to the
77 * newly active software image
78 *
79 * @param[in] path - The path to create the association to.
80 */
Lei YU7f2a2152019-09-16 16:50:18 +080081 void createActiveAssociation(const std::string& path) override;
Lei YU91029442019-08-01 15:57:31 +080082
Lei YUad90ad52019-08-06 11:19:28 +080083 /** @brief Add the functional association to the
Lei YU91029442019-08-01 15:57:31 +080084 * new "running" PSU images
85 *
Lei YUad90ad52019-08-06 11:19:28 +080086 * @param[in] path - The path to add the association to.
Lei YU91029442019-08-01 15:57:31 +080087 */
Lei YU7f2a2152019-09-16 16:50:18 +080088 void addFunctionalAssociation(const std::string& path) override;
Lei YU91029442019-08-01 15:57:31 +080089
Lei YUa8b966f2020-03-18 10:32:24 +080090 /** @brief Add the updateable association to the
91 * "running" PSU software image
92 *
93 * @param[in] path - The path to create the association.
94 */
95 void addUpdateableAssociation(const std::string& path) override;
96
Lei YU91029442019-08-01 15:57:31 +080097 /** @brief Removes the associations from the provided software image path
98 *
99 * @param[in] path - The path to remove the association from.
100 */
Lei YU7f2a2152019-09-16 16:50:18 +0800101 void removeAssociation(const std::string& path) override;
Lei YU91029442019-08-01 15:57:31 +0800102
Lei YUffb36532019-10-15 13:55:24 +0800103 /** @brief Notify a PSU is updated
104 *
105 * @param[in] versionId - The versionId of the activation
106 * @param[in] psuInventoryPath - The PSU inventory path that is updated
107 */
108 void onUpdateDone(const std::string& versionId,
109 const std::string& psuInventoryPath) override;
110
Lei YU7f2a2152019-09-16 16:50:18 +0800111 private:
Lei YU01539e72019-07-31 10:57:38 +0800112 /** @brief Callback function for Software.Version match.
113 * @details Creates an Activation D-Bus object.
114 *
115 * @param[in] msg - Data associated with subscribed signal
116 */
Patrick Williams374fae52022-07-22 19:26:55 -0500117 void createActivation(sdbusplus::message_t& msg);
Lei YU01539e72019-07-31 10:57:38 +0800118
Lei YUa2c2cd72019-08-09 15:54:10 +0800119 using Properties =
120 std::map<std::string, utils::UtilsInterface::PropertyType>;
121
Lei YUad90ad52019-08-06 11:19:28 +0800122 /** @brief Callback function for PSU inventory match.
123 * @details Update an Activation D-Bus object for PSU inventory.
124 *
125 * @param[in] msg - Data associated with subscribed signal
126 */
Patrick Williams374fae52022-07-22 19:26:55 -0500127 void onPsuInventoryChangedMsg(sdbusplus::message_t& msg);
Lei YUa2c2cd72019-08-09 15:54:10 +0800128
129 /** @brief Callback function for PSU inventory match.
130 * @details Update an Activation D-Bus object for PSU inventory.
131 *
132 * @param[in] psuPath - The PSU inventory path
133 * @param[in] properties - The updated properties
134 */
135 void onPsuInventoryChanged(const std::string& psuPath,
136 const Properties& properties);
Lei YUad90ad52019-08-06 11:19:28 +0800137
Lei YU01539e72019-07-31 10:57:38 +0800138 /** @brief Create Activation object */
139 std::unique_ptr<Activation> createActivationObject(
140 const std::string& path, const std::string& versionId,
Lei YU58c26e32019-09-27 17:52:06 +0800141 const std::string& extVersion, Activation::Status activationStatus,
Lei YU99301372019-09-29 16:27:12 +0800142 const AssociationList& assocs, const std::string& filePath);
Lei YU01539e72019-07-31 10:57:38 +0800143
144 /** @brief Create Version object */
145 std::unique_ptr<Version>
146 createVersionObject(const std::string& objPath,
147 const std::string& versionId,
148 const std::string& versionString,
149 sdbusplus::xyz::openbmc_project::Software::server::
Lei YU99301372019-09-29 16:27:12 +0800150 Version::VersionPurpose versionPurpose);
Lei YU01539e72019-07-31 10:57:38 +0800151
Lei YUbd3b0072019-08-08 13:09:50 +0800152 /** @brief Create Activation and Version object for PSU inventory
153 * @details If the same version exists for multiple PSUs, just add
154 * related association, instead of creating new objects.
155 * */
Lei YUad90ad52019-08-06 11:19:28 +0800156 void createPsuObject(const std::string& psuInventoryPath,
157 const std::string& psuVersion);
158
Lei YUbd3b0072019-08-08 13:09:50 +0800159 /** @brief Remove Activation and Version object for PSU inventory
Manojkiran Eda33cf9f02024-06-17 14:40:44 +0530160 * @details If the same version exists for multiple PSUs, just remove
Lei YUbd3b0072019-08-08 13:09:50 +0800161 * related association.
162 * If the version has no association, the Activation and
163 * Version object will be removed
164 */
165 void removePsuObject(const std::string& psuInventoryPath);
166
Lei YUad90ad52019-08-06 11:19:28 +0800167 /**
168 * @brief Create and populate the active PSU Version.
169 */
170 void processPSUImage();
171
Lei YU58c26e32019-09-27 17:52:06 +0800172 /** @brief Create PSU Version from stored images */
173 void processStoredImage();
174
175 /** @brief Scan a directory and create PSU Version from stored images */
176 void scanDirectory(const fs::path& p);
177
Lei YU65207482019-10-11 16:39:36 +0800178 /** @brief Get the versionId of the latest PSU version */
179 std::optional<std::string> getLatestVersionId();
180
Lei YU63f9e712019-10-12 15:16:55 +0800181 /** @brief Update PSUs to the latest version */
182 void syncToLatestImage();
183
184 /** @brief Invoke the activation via DBus */
185 void invokeActivation(const std::unique_ptr<Activation>& activation);
186
Faisal Awada760053d2024-05-16 13:31:32 -0500187 /** @brief Callback function for interfaces added signal.
188 *
189 * This method is called when a new interface is added. It updates the
190 * internal status map and process the new PSU if it's present.
191 *
192 * @param[in] msg - Data associated with subscribed signal
193 */
194 void onPSUInterfaceAdded(sdbusplus::message_t& msg);
195
196 /**
197 * @brief Handles the processing of PSU images.
198 *
199 * This function responsible for invoking the sequence of processing PSU
200 * images, processing stored images, and syncing to the latest firmware
201 * image.
202 */
203 void processPSUImageAndSyncToLatest();
204
Lei YU01539e72019-07-31 10:57:38 +0800205 /** @brief Persistent sdbusplus D-Bus bus connection. */
Patrick Williams374fae52022-07-22 19:26:55 -0500206 sdbusplus::bus_t& bus;
Lei YU01539e72019-07-31 10:57:38 +0800207
208 /** @brief Persistent map of Activation D-Bus objects and their
209 * version id */
210 std::map<std::string, std::unique_ptr<Activation>> activations;
211
212 /** @brief Persistent map of Version D-Bus objects and their
213 * version id */
214 std::map<std::string, std::unique_ptr<Version>> versions;
215
Lei YUbd3b0072019-08-08 13:09:50 +0800216 /** @brief The reference map of PSU Inventory objects and the
217 * Activation*/
218 std::map<std::string, const std::unique_ptr<Activation>&>
219 psuPathActivationMap;
220
Lei YUad90ad52019-08-06 11:19:28 +0800221 /** @brief sdbusplus signal match for PSU Software*/
Lei YU01539e72019-07-31 10:57:38 +0800222 sdbusplus::bus::match_t versionMatch;
Lei YU91029442019-08-01 15:57:31 +0800223
Lei YUad90ad52019-08-06 11:19:28 +0800224 /** @brief sdbusplus signal matches for PSU Inventory */
225 std::vector<sdbusplus::bus::match_t> psuMatches;
226
Lei YU91029442019-08-01 15:57:31 +0800227 /** @brief This entry's associations */
228 AssociationList assocs;
Lei YU65207482019-10-11 16:39:36 +0800229
230 /** @brief A collection of the version strings */
231 std::set<std::string> versionStrings;
Lei YU1517f5f2019-10-14 16:44:42 +0800232
233 /** @brief A struct to hold the PSU present status and model */
234 struct psuStatus
235 {
236 bool present;
237 std::string model;
238 };
239
240 /** @brief The map of PSU inventory path and the psuStatus
241 *
242 * It is used to handle psu inventory changed event, that only create psu
243 * software object when a PSU is present and the model is retrieved */
244 std::map<std::string, psuStatus> psuStatusMap;
Faisal Awada760053d2024-05-16 13:31:32 -0500245
246 /** @brief Signal match for PSU interfaces added.
247 *
248 * This match listens for D-Bus signals indicating new interface has been
249 * added. When such a signal received, it triggers the
250 * `onInterfacesAdded` method to handle the new PSU.
251 */
252 sdbusplus::bus::match_t psuInterfaceMatch;
Lei YU01539e72019-07-31 10:57:38 +0800253};
254
255} // namespace updater
256} // namespace software
257} // namespace phosphor