blob: bc8930e437d73998bb1a3ea84bff9cf8d84891ec [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),
Patrick Williamsbab5ed92024-08-16 15:20:54 -040054 versionMatch(
55 bus,
56 MatchRules::interfacesAdded() + MatchRules::path(SOFTWARE_OBJPATH),
57 std::bind(std::mem_fn(&ItemUpdater::createActivation), this,
58 std::placeholders::_1)),
Faisal Awada760053d2024-05-16 13:31:32 -050059 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 */
Patrick Williamsbab5ed92024-08-16 15:20:54 -0400145 std::unique_ptr<Version> createVersionObject(
146 const std::string& objPath, const std::string& versionId,
147 const std::string& versionString,
148 sdbusplus::xyz::openbmc_project::Software::server::Version::
149 VersionPurpose versionPurpose);
Lei YU01539e72019-07-31 10:57:38 +0800150
Lei YUbd3b0072019-08-08 13:09:50 +0800151 /** @brief Create Activation and Version object for PSU inventory
152 * @details If the same version exists for multiple PSUs, just add
153 * related association, instead of creating new objects.
154 * */
Lei YUad90ad52019-08-06 11:19:28 +0800155 void createPsuObject(const std::string& psuInventoryPath,
156 const std::string& psuVersion);
157
Lei YUbd3b0072019-08-08 13:09:50 +0800158 /** @brief Remove Activation and Version object for PSU inventory
Manojkiran Eda33cf9f02024-06-17 14:40:44 +0530159 * @details If the same version exists for multiple PSUs, just remove
Lei YUbd3b0072019-08-08 13:09:50 +0800160 * related association.
161 * If the version has no association, the Activation and
162 * Version object will be removed
163 */
164 void removePsuObject(const std::string& psuInventoryPath);
165
Lei YUad90ad52019-08-06 11:19:28 +0800166 /**
167 * @brief Create and populate the active PSU Version.
168 */
169 void processPSUImage();
170
Lei YU58c26e32019-09-27 17:52:06 +0800171 /** @brief Create PSU Version from stored images */
172 void processStoredImage();
173
174 /** @brief Scan a directory and create PSU Version from stored images */
175 void scanDirectory(const fs::path& p);
176
Lei YU65207482019-10-11 16:39:36 +0800177 /** @brief Get the versionId of the latest PSU version */
178 std::optional<std::string> getLatestVersionId();
179
Lei YU63f9e712019-10-12 15:16:55 +0800180 /** @brief Update PSUs to the latest version */
181 void syncToLatestImage();
182
183 /** @brief Invoke the activation via DBus */
George Liu80c2daa2024-08-23 15:46:12 +0800184 static void invokeActivation(const std::unique_ptr<Activation>& activation);
Lei YU63f9e712019-10-12 15:16:55 +0800185
Faisal Awada760053d2024-05-16 13:31:32 -0500186 /** @brief Callback function for interfaces added signal.
187 *
188 * This method is called when a new interface is added. It updates the
189 * internal status map and process the new PSU if it's present.
190 *
191 * @param[in] msg - Data associated with subscribed signal
192 */
193 void onPSUInterfaceAdded(sdbusplus::message_t& msg);
194
195 /**
196 * @brief Handles the processing of PSU images.
197 *
198 * This function responsible for invoking the sequence of processing PSU
199 * images, processing stored images, and syncing to the latest firmware
200 * image.
201 */
202 void processPSUImageAndSyncToLatest();
203
Lei YU01539e72019-07-31 10:57:38 +0800204 /** @brief Persistent sdbusplus D-Bus bus connection. */
Patrick Williams374fae52022-07-22 19:26:55 -0500205 sdbusplus::bus_t& bus;
Lei YU01539e72019-07-31 10:57:38 +0800206
207 /** @brief Persistent map of Activation D-Bus objects and their
208 * version id */
209 std::map<std::string, std::unique_ptr<Activation>> activations;
210
211 /** @brief Persistent map of Version D-Bus objects and their
212 * version id */
213 std::map<std::string, std::unique_ptr<Version>> versions;
214
Lei YUbd3b0072019-08-08 13:09:50 +0800215 /** @brief The reference map of PSU Inventory objects and the
216 * Activation*/
217 std::map<std::string, const std::unique_ptr<Activation>&>
218 psuPathActivationMap;
219
Lei YUad90ad52019-08-06 11:19:28 +0800220 /** @brief sdbusplus signal match for PSU Software*/
Lei YU01539e72019-07-31 10:57:38 +0800221 sdbusplus::bus::match_t versionMatch;
Lei YU91029442019-08-01 15:57:31 +0800222
Lei YUad90ad52019-08-06 11:19:28 +0800223 /** @brief sdbusplus signal matches for PSU Inventory */
224 std::vector<sdbusplus::bus::match_t> psuMatches;
225
Lei YU91029442019-08-01 15:57:31 +0800226 /** @brief This entry's associations */
227 AssociationList assocs;
Lei YU65207482019-10-11 16:39:36 +0800228
229 /** @brief A collection of the version strings */
230 std::set<std::string> versionStrings;
Lei YU1517f5f2019-10-14 16:44:42 +0800231
232 /** @brief A struct to hold the PSU present status and model */
233 struct psuStatus
234 {
235 bool present;
236 std::string model;
237 };
238
239 /** @brief The map of PSU inventory path and the psuStatus
240 *
241 * It is used to handle psu inventory changed event, that only create psu
242 * software object when a PSU is present and the model is retrieved */
243 std::map<std::string, psuStatus> psuStatusMap;
Faisal Awada760053d2024-05-16 13:31:32 -0500244
245 /** @brief Signal match for PSU interfaces added.
246 *
247 * This match listens for D-Bus signals indicating new interface has been
248 * added. When such a signal received, it triggers the
249 * `onInterfacesAdded` method to handle the new PSU.
250 */
251 sdbusplus::bus::match_t psuInterfaceMatch;
Lei YU01539e72019-07-31 10:57:38 +0800252};
253
254} // namespace updater
255} // namespace software
256} // namespace phosphor