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