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