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 object path */ 180 const std::string& getObjectPath() const 181 { 182 return objPath; 183 } 184 185 /** @brief Get the version ID */ 186 const std::string& getVersionId() const 187 { 188 return versionId; 189 } 190 191 private: 192 /** @brief Check if systemd state change is relevant to this object 193 * 194 * Instance specific interface to handle the detected systemd state 195 * change 196 * 197 * @param[in] msg - Data associated with subscribed signal 198 * 199 */ 200 void unitStateChange(sdbusplus::message::message& msg); 201 202 /** 203 * @brief Delete the version from Image Manager and the 204 * untar image from image upload dir. 205 */ 206 void deleteImageManagerObject(); 207 208 /** @brief Invoke the update service for the PSU 209 * 210 * @param[in] psuInventoryPath - The PSU inventory to be updated. 211 * 212 * @return true if the update starts, and false if it fails. 213 */ 214 bool doUpdate(const std::string& psuInventoryPath); 215 216 /** @brief Do PSU update one-by-one 217 * 218 * @return true if the update starts, and false if it fails. 219 */ 220 bool doUpdate(); 221 222 /** @brief Handle an update done event */ 223 void onUpdateDone(); 224 225 /** @brief Handle an update failure event */ 226 void onUpdateFailed(); 227 228 /** @brief Start PSU update */ 229 Status startActivation(); 230 231 /** @brief Finish PSU update */ 232 void finishActivation(); 233 234 /** @brief Check if the PSU is comaptible with this software*/ 235 bool isCompatible(const std::string& psuInventoryPath); 236 237 /** @brief Store the updated PSU image to persistent dir */ 238 void storeImage(); 239 240 /** @brief Construct the systemd service name 241 * 242 * @param[in] psuInventoryPath - The PSU inventory to be updated. 243 * 244 * @return The escaped string of systemd unit to do the PSU update. 245 */ 246 std::string getUpdateService(const std::string& psuInventoryPath); 247 248 /** @brief Persistent sdbusplus DBus bus connection */ 249 sdbusplus::bus::bus& bus; 250 251 /** @brief Persistent DBus object path */ 252 std::string objPath; 253 254 /** @brief Version id */ 255 std::string versionId; 256 257 /** @brief Used to subscribe to dbus systemd signals */ 258 sdbusplus::bus::match_t systemdSignals; 259 260 /** @brief The queue of psu objects to be updated */ 261 std::queue<std::string> psuQueue; 262 263 /** @brief The progress step for each PSU update is done */ 264 uint32_t progressStep; 265 266 /** @brief The PSU update systemd unit */ 267 std::string psuUpdateUnit; 268 269 /** @brief The PSU Inventory path of the current updating PSU */ 270 std::string currentUpdatingPsu; 271 272 /** @brief Persistent ActivationBlocksTransition dbus object */ 273 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition; 274 275 /** @brief Persistent ActivationProgress dbus object */ 276 std::unique_ptr<ActivationProgress> activationProgress; 277 278 /** @brief The AssociationInterface pointer */ 279 AssociationInterface* associationInterface; 280 281 /** @brief The PSU manufacturer of the software */ 282 std::string manufacturer; 283 284 /** @brief The PSU model of the software */ 285 std::string model; 286 }; 287 288 } // namespace updater 289 } // namespace software 290 } // namespace phosphor 291