1 #pragma once 2 3 #include "config.h" 4 5 #include "association_interface.hpp" 6 #include "types.hpp" 7 #include "version.hpp" 8 9 #include <queue> 10 #include <sdbusplus/server.hpp> 11 #include <xyz/openbmc_project/Association/Definitions/server.hpp> 12 #include <xyz/openbmc_project/Common/FilePath/server.hpp> 13 #include <xyz/openbmc_project/Software/Activation/server.hpp> 14 #include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp> 15 #include <xyz/openbmc_project/Software/ActivationProgress/server.hpp> 16 #include <xyz/openbmc_project/Software/ExtendedVersion/server.hpp> 17 18 class TestActivation; 19 20 namespace phosphor 21 { 22 namespace software 23 { 24 namespace updater 25 { 26 27 namespace sdbusRule = sdbusplus::bus::match::rules; 28 29 using ActivationBlocksTransitionInherit = sdbusplus::server::object::object< 30 sdbusplus::xyz::openbmc_project::Software::server:: 31 ActivationBlocksTransition>; 32 33 /** @class ActivationBlocksTransition 34 * @brief OpenBMC ActivationBlocksTransition implementation. 35 * @details A concrete implementation for 36 * xyz.openbmc_project.Software.ActivationBlocksTransition DBus API. 37 */ 38 class ActivationBlocksTransition : public ActivationBlocksTransitionInherit 39 { 40 public: 41 /** @brief Constructs ActivationBlocksTransition. 42 * 43 * @param[in] bus - The Dbus bus object 44 * @param[in] path - The Dbus object path 45 */ 46 ActivationBlocksTransition(sdbusplus::bus::bus& bus, 47 const std::string& path) : 48 ActivationBlocksTransitionInherit(bus, path.c_str(), true), 49 bus(bus), path(path) 50 { 51 std::vector<std::string> interfaces({interface}); 52 bus.emit_interfaces_added(path.c_str(), interfaces); 53 } 54 55 ~ActivationBlocksTransition() 56 { 57 std::vector<std::string> interfaces({interface}); 58 bus.emit_interfaces_removed(path.c_str(), interfaces); 59 } 60 61 private: 62 // TODO Remove once openbmc/openbmc#1975 is resolved 63 static constexpr auto interface = 64 "xyz.openbmc_project.Software.ActivationBlocksTransition"; 65 sdbusplus::bus::bus& bus; 66 std::string path; 67 }; 68 69 using ActivationProgressInherit = sdbusplus::server::object::object< 70 sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>; 71 72 class ActivationProgress : public ActivationProgressInherit 73 { 74 public: 75 /** @brief Constructs ActivationProgress. 76 * 77 * @param[in] bus - The Dbus bus object 78 * @param[in] path - The Dbus object path 79 */ 80 ActivationProgress(sdbusplus::bus::bus& bus, const std::string& path) : 81 ActivationProgressInherit(bus, path.c_str(), true), bus(bus), path(path) 82 { 83 progress(0); 84 std::vector<std::string> interfaces({interface}); 85 bus.emit_interfaces_added(path.c_str(), interfaces); 86 } 87 88 ~ActivationProgress() 89 { 90 std::vector<std::string> interfaces({interface}); 91 bus.emit_interfaces_removed(path.c_str(), interfaces); 92 } 93 94 private: 95 // TODO Remove once openbmc/openbmc#1975 is resolved 96 static constexpr auto interface = 97 "xyz.openbmc_project.Software.ActivationProgress"; 98 sdbusplus::bus::bus& bus; 99 std::string path; 100 }; 101 102 using ActivationInherit = sdbusplus::server::object::object< 103 sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion, 104 sdbusplus::xyz::openbmc_project::Software::server::Activation, 105 sdbusplus::xyz::openbmc_project::Association::server::Definitions, 106 sdbusplus::xyz::openbmc_project::Common::server::FilePath>; 107 108 /** @class Activation 109 * @brief OpenBMC activation software management implementation. 110 * @details A concrete implementation for 111 * xyz.openbmc_project.Software.Activation DBus API. 112 */ 113 class Activation : public ActivationInherit 114 { 115 public: 116 friend class ::TestActivation; 117 using Status = Activations; 118 119 /** @brief Constructs Activation Software Manager 120 * 121 * @param[in] bus - The Dbus bus object 122 * @param[in] path - The Dbus object path 123 * @param[in] versionId - The software version id 124 * @param[in] extVersion - The extended version 125 * @param[in] activationStatus - The status of Activation 126 * @param[in] assocs - Association objects 127 * @param[in] filePath - The image filesystem path 128 */ 129 Activation(sdbusplus::bus::bus& bus, const std::string& objPath, 130 const std::string& versionId, const std::string& extVersion, 131 Status activationStatus, const AssociationList& assocs, 132 AssociationInterface* associationInterface, 133 const std::string& filePath) : 134 ActivationInherit(bus, objPath.c_str(), true), 135 bus(bus), objPath(objPath), versionId(versionId), 136 systemdSignals( 137 bus, 138 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") + 139 sdbusRule::path("/org/freedesktop/systemd1") + 140 sdbusRule::interface("org.freedesktop.systemd1.Manager"), 141 std::bind(&Activation::unitStateChange, this, 142 std::placeholders::_1)), 143 associationInterface(associationInterface) 144 { 145 // Set Properties. 146 extendedVersion(extVersion); 147 activation(activationStatus); 148 associations(assocs); 149 path(filePath); 150 151 auto info = Version::getExtVersionInfo(extVersion); 152 manufacturer = info["manufacturer"]; 153 model = info["model"]; 154 155 // Emit deferred signal. 156 emit_object_added(); 157 } 158 159 /** @brief Overloaded Activation property setter function 160 * 161 * @param[in] value - One of Activation::Activations 162 * 163 * @return Success or exception thrown 164 */ 165 Status activation(Status value) override; 166 167 /** @brief Activation */ 168 using ActivationInherit::activation; 169 170 /** @brief Overloaded requestedActivation property setter function 171 * 172 * @param[in] value - One of Activation::RequestedActivations 173 * 174 * @return Success or exception thrown 175 */ 176 RequestedActivations 177 requestedActivation(RequestedActivations value) override; 178 179 /** @brief Get the version ID */ 180 const std::string& getVersionId() const 181 { 182 return versionId; 183 } 184 185 private: 186 /** @brief Check if systemd state change is relevant to this object 187 * 188 * Instance specific interface to handle the detected systemd state 189 * change 190 * 191 * @param[in] msg - Data associated with subscribed signal 192 * 193 */ 194 void unitStateChange(sdbusplus::message::message& msg); 195 196 /** 197 * @brief Delete the version from Image Manager and the 198 * untar image from image upload dir. 199 */ 200 void deleteImageManagerObject(); 201 202 /** @brief Invoke the update service for the PSU 203 * 204 * @param[in] psuInventoryPath - The PSU inventory to be updated. 205 * 206 * @return true if the update starts, and false if it fails. 207 */ 208 bool doUpdate(const std::string& psuInventoryPath); 209 210 /** @brief Do PSU update one-by-one 211 * 212 * @return true if the update starts, and false if it fails. 213 */ 214 bool doUpdate(); 215 216 /** @brief Handle an update done event */ 217 void onUpdateDone(); 218 219 /** @brief Handle an update failure event */ 220 void onUpdateFailed(); 221 222 /** @brief Start PSU update */ 223 Status startActivation(); 224 225 /** @brief Finish PSU update */ 226 void finishActivation(); 227 228 /** @brief Check if the PSU is comaptible with this software*/ 229 bool isCompatible(const std::string& psuInventoryPath); 230 231 /** @brief Store the updated PSU image to persistent dir */ 232 void storeImage(); 233 234 /** @brief Construct the systemd service name 235 * 236 * @param[in] psuInventoryPath - The PSU inventory to be updated. 237 * 238 * @return The escaped string of systemd unit to do the PSU update. 239 */ 240 std::string getUpdateService(const std::string& psuInventoryPath); 241 242 /** @brief Persistent sdbusplus DBus bus connection */ 243 sdbusplus::bus::bus& bus; 244 245 /** @brief Persistent DBus object path */ 246 std::string objPath; 247 248 /** @brief Version id */ 249 std::string versionId; 250 251 /** @brief Used to subscribe to dbus systemd signals */ 252 sdbusplus::bus::match_t systemdSignals; 253 254 /** @brief The queue of psu objects to be updated */ 255 std::queue<std::string> psuQueue; 256 257 /** @brief The progress step for each PSU update is done */ 258 uint32_t progressStep; 259 260 /** @brief The PSU update systemd unit */ 261 std::string psuUpdateUnit; 262 263 /** @brief The PSU Inventory path of the current updating PSU */ 264 std::string currentUpdatingPsu; 265 266 /** @brief Persistent ActivationBlocksTransition dbus object */ 267 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition; 268 269 /** @brief Persistent ActivationProgress dbus object */ 270 std::unique_ptr<ActivationProgress> activationProgress; 271 272 /** @brief The AssociationInterface pointer */ 273 AssociationInterface* associationInterface; 274 275 /** @brief The PSU manufacturer of the software */ 276 std::string manufacturer; 277 278 /** @brief The PSU model of the software */ 279 std::string model; 280 }; 281 282 } // namespace updater 283 } // namespace software 284 } // namespace phosphor 285