1 #pragma once 2 3 #include "config.h" 4 5 #include "activation.hpp" 6 #include "association_interface.hpp" 7 #include "types.hpp" 8 #include "utils.hpp" 9 #include "version.hpp" 10 11 #include <phosphor-logging/log.hpp> 12 #include <sdbusplus/server.hpp> 13 #include <xyz/openbmc_project/Association/Definitions/server.hpp> 14 #include <xyz/openbmc_project/Collection/DeleteAll/server.hpp> 15 16 #include <filesystem> 17 18 class TestItemUpdater; 19 20 namespace phosphor 21 { 22 namespace software 23 { 24 namespace updater 25 { 26 27 class Version; 28 29 using ItemUpdaterInherit = sdbusplus::server::object_t< 30 sdbusplus::xyz::openbmc_project::Association::server::Definitions>; 31 32 namespace MatchRules = sdbusplus::bus::match::rules; 33 34 namespace fs = std::filesystem; 35 36 /** @class ItemUpdater 37 * @brief Manages the activation of the PSU version items. 38 */ 39 class ItemUpdater : 40 public ItemUpdaterInherit, 41 public AssociationInterface, 42 public ActivationListener 43 { 44 friend class ::TestItemUpdater; 45 46 public: 47 /** @brief Constructs ItemUpdater 48 * 49 * @param[in] bus - The D-Bus bus object 50 * @param[in] path - The D-Bus path 51 */ 52 ItemUpdater(sdbusplus::bus_t& bus, const std::string& path) : 53 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), 58 this, std::placeholders::_1)) 59 { 60 processPSUImage(); 61 processStoredImage(); 62 syncToLatestImage(); 63 } 64 65 /** @brief Deletes version 66 * 67 * @param[in] versionId - Id of the version to delete 68 */ 69 void erase(const std::string& versionId); 70 71 /** @brief Creates an active association to the 72 * newly active software image 73 * 74 * @param[in] path - The path to create the association to. 75 */ 76 void createActiveAssociation(const std::string& path) override; 77 78 /** @brief Add the functional association to the 79 * new "running" PSU images 80 * 81 * @param[in] path - The path to add the association to. 82 */ 83 void addFunctionalAssociation(const std::string& path) override; 84 85 /** @brief Add the updateable association to the 86 * "running" PSU software image 87 * 88 * @param[in] path - The path to create the association. 89 */ 90 void addUpdateableAssociation(const std::string& path) override; 91 92 /** @brief Removes the associations from the provided software image path 93 * 94 * @param[in] path - The path to remove the association from. 95 */ 96 void removeAssociation(const std::string& path) override; 97 98 /** @brief Notify a PSU is updated 99 * 100 * @param[in] versionId - The versionId of the activation 101 * @param[in] psuInventoryPath - The PSU inventory path that is updated 102 */ 103 void onUpdateDone(const std::string& versionId, 104 const std::string& psuInventoryPath) override; 105 106 private: 107 /** @brief Callback function for Software.Version match. 108 * @details Creates an Activation D-Bus object. 109 * 110 * @param[in] msg - Data associated with subscribed signal 111 */ 112 void createActivation(sdbusplus::message_t& msg); 113 114 using Properties = 115 std::map<std::string, utils::UtilsInterface::PropertyType>; 116 117 /** @brief Callback function for PSU inventory match. 118 * @details Update an Activation D-Bus object for PSU inventory. 119 * 120 * @param[in] msg - Data associated with subscribed signal 121 */ 122 void onPsuInventoryChangedMsg(sdbusplus::message_t& msg); 123 124 /** @brief Callback function for PSU inventory match. 125 * @details Update an Activation D-Bus object for PSU inventory. 126 * 127 * @param[in] psuPath - The PSU inventory path 128 * @param[in] properties - The updated properties 129 */ 130 void onPsuInventoryChanged(const std::string& psuPath, 131 const Properties& properties); 132 133 /** @brief Create Activation object */ 134 std::unique_ptr<Activation> createActivationObject( 135 const std::string& path, const std::string& versionId, 136 const std::string& extVersion, Activation::Status activationStatus, 137 const AssociationList& assocs, const std::string& filePath); 138 139 /** @brief Create Version object */ 140 std::unique_ptr<Version> 141 createVersionObject(const std::string& objPath, 142 const std::string& versionId, 143 const std::string& versionString, 144 sdbusplus::xyz::openbmc_project::Software::server:: 145 Version::VersionPurpose versionPurpose); 146 147 /** @brief Create Activation and Version object for PSU inventory 148 * @details If the same version exists for multiple PSUs, just add 149 * related association, instead of creating new objects. 150 * */ 151 void createPsuObject(const std::string& psuInventoryPath, 152 const std::string& psuVersion); 153 154 /** @brief Remove Activation and Version object for PSU inventory 155 * @details If the same version exists for mutliple PSUs, just remove 156 * related association. 157 * If the version has no association, the Activation and 158 * Version object will be removed 159 */ 160 void removePsuObject(const std::string& psuInventoryPath); 161 162 /** 163 * @brief Create and populate the active PSU Version. 164 */ 165 void processPSUImage(); 166 167 /** @brief Create PSU Version from stored images */ 168 void processStoredImage(); 169 170 /** @brief Scan a directory and create PSU Version from stored images */ 171 void scanDirectory(const fs::path& p); 172 173 /** @brief Get the versionId of the latest PSU version */ 174 std::optional<std::string> getLatestVersionId(); 175 176 /** @brief Update PSUs to the latest version */ 177 void syncToLatestImage(); 178 179 /** @brief Invoke the activation via DBus */ 180 void invokeActivation(const std::unique_ptr<Activation>& activation); 181 182 /** @brief Persistent sdbusplus D-Bus bus connection. */ 183 sdbusplus::bus_t& bus; 184 185 /** @brief Persistent map of Activation D-Bus objects and their 186 * version id */ 187 std::map<std::string, std::unique_ptr<Activation>> activations; 188 189 /** @brief Persistent map of Version D-Bus objects and their 190 * version id */ 191 std::map<std::string, std::unique_ptr<Version>> versions; 192 193 /** @brief The reference map of PSU Inventory objects and the 194 * Activation*/ 195 std::map<std::string, const std::unique_ptr<Activation>&> 196 psuPathActivationMap; 197 198 /** @brief sdbusplus signal match for PSU Software*/ 199 sdbusplus::bus::match_t versionMatch; 200 201 /** @brief sdbusplus signal matches for PSU Inventory */ 202 std::vector<sdbusplus::bus::match_t> psuMatches; 203 204 /** @brief This entry's associations */ 205 AssociationList assocs; 206 207 /** @brief A collection of the version strings */ 208 std::set<std::string> versionStrings; 209 210 /** @brief A struct to hold the PSU present status and model */ 211 struct psuStatus 212 { 213 bool present; 214 std::string model; 215 }; 216 217 /** @brief The map of PSU inventory path and the psuStatus 218 * 219 * It is used to handle psu inventory changed event, that only create psu 220 * software object when a PSU is present and the model is retrieved */ 221 std::map<std::string, psuStatus> psuStatusMap; 222 }; 223 224 } // namespace updater 225 } // namespace software 226 } // namespace phosphor 227