1 #pragma once 2 3 #include "config.h" 4 5 #include "utils.hpp" 6 #include "xyz/openbmc_project/Software/ActivationProgress/server.hpp" 7 #include "xyz/openbmc_project/Software/ExtendedVersion/server.hpp" 8 #include "xyz/openbmc_project/Software/RedundancyPriority/server.hpp" 9 10 #include <sdbusplus/server.hpp> 11 #include <xyz/openbmc_project/Association/Definitions/server.hpp> 12 #include <xyz/openbmc_project/Software/Activation/server.hpp> 13 #include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp> 14 15 namespace openpower 16 { 17 namespace software 18 { 19 namespace updater 20 { 21 22 using AssociationList = 23 std::vector<std::tuple<std::string, std::string, std::string>>; 24 using ActivationInherit = sdbusplus::server::object::object< 25 sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion, 26 sdbusplus::xyz::openbmc_project::Software::server::Activation, 27 sdbusplus::xyz::openbmc_project::Association::server::Definitions>; 28 using ActivationBlocksTransitionInherit = sdbusplus::server::object::object< 29 sdbusplus::xyz::openbmc_project::Software::server:: 30 ActivationBlocksTransition>; 31 using RedundancyPriorityInherit = sdbusplus::server::object::object< 32 sdbusplus::xyz::openbmc_project::Software::server::RedundancyPriority>; 33 using ActivationProgressInherit = sdbusplus::server::object::object< 34 sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>; 35 36 constexpr auto applyTimeImmediate = 37 "xyz.openbmc_project.Software.ApplyTime.RequestedApplyTimes.Immediate"; 38 constexpr auto applyTimeIntf = "xyz.openbmc_project.Software.ApplyTime"; 39 constexpr auto dbusPropIntf = "org.freedesktop.DBus.Properties"; 40 constexpr auto applyTimeObjPath = "/xyz/openbmc_project/software/apply_time"; 41 constexpr auto applyTimeProp = "RequestedApplyTime"; 42 43 constexpr auto hostStateIntf = "xyz.openbmc_project.State.Host"; 44 constexpr auto hostStateObjPath = "/xyz/openbmc_project/state/host0"; 45 constexpr auto hostStateRebootProp = "RequestedHostTransition"; 46 constexpr auto hostStateRebootVal = 47 "xyz.openbmc_project.State.Host.Transition.Reboot"; 48 49 namespace sdbusRule = sdbusplus::bus::match::rules; 50 51 class ItemUpdater; 52 class Activation; 53 class RedundancyPriority; 54 55 /** @class RedundancyPriority 56 * @brief OpenBMC RedundancyPriority implementation 57 * @details A concrete implementation for 58 * xyz.openbmc_project.Software.RedundancyPriority DBus API. 59 */ 60 class RedundancyPriority : public RedundancyPriorityInherit 61 { 62 public: 63 /** @brief Constructs RedundancyPriority. 64 * 65 * @param[in] bus - The Dbus bus object 66 * @param[in] path - The Dbus object path 67 * @param[in] parent - Parent object. 68 * @param[in] value - The redundancyPriority value 69 */ 70 RedundancyPriority(sdbusplus::bus::bus& bus, const std::string& path, 71 Activation& parent, uint8_t value) : 72 RedundancyPriorityInherit(bus, path.c_str(), true), 73 parent(parent), bus(bus), path(path) 74 { 75 // Set Property 76 priority(value); 77 std::vector<std::string> interfaces({interface}); 78 bus.emit_interfaces_added(path.c_str(), interfaces); 79 } 80 81 virtual ~RedundancyPriority() 82 { 83 std::vector<std::string> interfaces({interface}); 84 bus.emit_interfaces_removed(path.c_str(), interfaces); 85 } 86 87 /** @brief Overloaded Priority property set function 88 * 89 * @param[in] value - uint8_t 90 * 91 * @return Success or exception thrown 92 */ 93 uint8_t priority(uint8_t value) override; 94 95 /** @brief Priority property get function 96 * 97 * @returns uint8_t - The Priority value 98 */ 99 using RedundancyPriorityInherit::priority; 100 101 /** @brief Parent Object. */ 102 Activation& parent; 103 104 private: 105 // TODO Remove once openbmc/openbmc#1975 is resolved 106 static constexpr auto interface = 107 "xyz.openbmc_project.Software.RedundancyPriority"; 108 sdbusplus::bus::bus& bus; 109 std::string path; 110 }; 111 112 /** @class ActivationBlocksTransition 113 * @brief OpenBMC ActivationBlocksTransition implementation. 114 * @details A concrete implementation for 115 * xyz.openbmc_project.Software.ActivationBlocksTransition DBus API. 116 */ 117 class ActivationBlocksTransition : public ActivationBlocksTransitionInherit 118 { 119 public: 120 /** @brief Constructs ActivationBlocksTransition. 121 * 122 * @param[in] bus - The Dbus bus object 123 * @param[in] path - The Dbus object path 124 */ 125 ActivationBlocksTransition(sdbusplus::bus::bus& bus, 126 const std::string& path) : 127 ActivationBlocksTransitionInherit(bus, path.c_str(), true), 128 bus(bus), path(path) 129 { 130 std::vector<std::string> interfaces({interface}); 131 bus.emit_interfaces_added(path.c_str(), interfaces); 132 } 133 134 ~ActivationBlocksTransition() 135 { 136 std::vector<std::string> interfaces({interface}); 137 bus.emit_interfaces_removed(path.c_str(), interfaces); 138 } 139 140 private: 141 // TODO Remove once openbmc/openbmc#1975 is resolved 142 static constexpr auto interface = 143 "xyz.openbmc_project.Software.ActivationBlocksTransition"; 144 sdbusplus::bus::bus& bus; 145 std::string path; 146 }; 147 148 class ActivationProgress : public ActivationProgressInherit 149 { 150 public: 151 /** @brief Constructs ActivationProgress. 152 * 153 * @param[in] bus - The Dbus bus object 154 * @param[in] path - The Dbus object path 155 */ 156 ActivationProgress(sdbusplus::bus::bus& bus, const std::string& path) : 157 ActivationProgressInherit(bus, path.c_str(), true), bus(bus), path(path) 158 { 159 progress(0); 160 std::vector<std::string> interfaces({interface}); 161 bus.emit_interfaces_added(path.c_str(), interfaces); 162 } 163 164 ~ActivationProgress() 165 { 166 std::vector<std::string> interfaces({interface}); 167 bus.emit_interfaces_removed(path.c_str(), interfaces); 168 } 169 170 private: 171 // TODO Remove once openbmc/openbmc#1975 is resolved 172 static constexpr auto interface = 173 "xyz.openbmc_project.Software.ActivationProgress"; 174 sdbusplus::bus::bus& bus; 175 std::string path; 176 }; 177 178 /** @class Activation 179 * @brief OpenBMC activation software management implementation. 180 * @details A concrete implementation for 181 * xyz.openbmc_project.Software.Activation DBus API. 182 */ 183 class Activation : public ActivationInherit 184 { 185 public: 186 /** @brief Constructs Activation Software Manager 187 * 188 * @param[in] bus - The Dbus bus object 189 * @param[in] path - The Dbus object path 190 * @param[in] parent - Parent object. 191 * @param[in] versionId - The software version id 192 * @param[in] extVersion - The extended version 193 * @param[in] activationStatus - The status of Activation 194 * @param[in] assocs - Association objects 195 */ 196 Activation(sdbusplus::bus::bus& bus, const std::string& path, 197 ItemUpdater& parent, const std::string& versionId, 198 const std::string& extVersion, 199 sdbusplus::xyz::openbmc_project::Software::server::Activation:: 200 Activations activationStatus, 201 AssociationList& assocs) : 202 ActivationInherit(bus, path.c_str(), true), 203 bus(bus), path(path), parent(parent), versionId(versionId), 204 systemdSignals( 205 bus, 206 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") + 207 sdbusRule::path("/org/freedesktop/systemd1") + 208 sdbusRule::interface("org.freedesktop.systemd1.Manager"), 209 std::bind(std::mem_fn(&Activation::unitStateChange), this, 210 std::placeholders::_1)) 211 { 212 // Set Properties. 213 extendedVersion(extVersion); 214 activation(activationStatus); 215 associations(assocs); 216 217 // Emit deferred signal. 218 emit_object_added(); 219 } 220 virtual ~Activation() = default; 221 222 /** @brief Activation property get function 223 * 224 * @returns One of Activation::Activations 225 */ 226 using ActivationInherit::activation; 227 228 /** @brief Overloaded requestedActivation property setter function 229 * 230 * @param[in] value - One of Activation::RequestedActivations 231 * 232 * @return Success or exception thrown 233 */ 234 RequestedActivations 235 requestedActivation(RequestedActivations value) override; 236 237 /** 238 * @brief subscribe to the systemd signals 239 * 240 * This object needs to capture when it's systemd targets complete 241 * so it can keep it's state updated 242 * 243 **/ 244 void subscribeToSystemdSignals(); 245 246 /** 247 * @brief unsubscribe from the systemd signals 248 * 249 * Once the activation process has completed successfully, we can 250 * safely unsubscribe from systemd signals. 251 * 252 **/ 253 void unsubscribeFromSystemdSignals(); 254 255 /** @brief Persistent sdbusplus DBus bus connection */ 256 sdbusplus::bus::bus& bus; 257 258 /** @brief Persistent DBus object path */ 259 std::string path; 260 261 /** @brief Parent Object. */ 262 ItemUpdater& parent; 263 264 /** @brief Version id */ 265 std::string versionId; 266 267 /** @brief Persistent ActivationBlocksTransition dbus object */ 268 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition; 269 270 /** @brief Persistent ActivationProgress dbus object */ 271 std::unique_ptr<ActivationProgress> activationProgress; 272 273 /** @brief Persistent RedundancyPriority dbus object */ 274 std::unique_ptr<RedundancyPriority> redundancyPriority; 275 276 /** @brief Used to subscribe to dbus systemd signals **/ 277 sdbusplus::bus::match_t systemdSignals; 278 279 /** @brief activation status property get function 280 * 281 * @returns Activations - The activation value 282 */ 283 using ActivationInherit::activation; 284 285 /** 286 * @brief Determine the configured image apply time value 287 * 288 * @return true if the image apply time value is immediate 289 **/ 290 bool checkApplyTimeImmediate(); 291 292 /** 293 * @brief Reboot the Host. Called when ApplyTime is immediate. 294 * 295 * @return none 296 **/ 297 void rebootHost(); 298 299 protected: 300 /** @brief Check if systemd state change is relevant to this object 301 * 302 * Instance specific interface to handle the detected systemd state 303 * change 304 * 305 * @param[in] msg - Data associated with subscribed signal 306 * 307 */ 308 virtual void unitStateChange(sdbusplus::message::message& msg) = 0; 309 310 /** 311 * @brief Deletes the version from Image Manager and the 312 * untar image from image upload dir. 313 */ 314 void deleteImageManagerObject(); 315 316 /** @brief Member function for clarity & brevity at activation start */ 317 virtual void startActivation() = 0; 318 319 /** @brief Member function for clarity & brevity at activation end */ 320 virtual void finishActivation() = 0; 321 322 #ifdef WANT_SIGNATURE_VERIFY 323 /** 324 * @brief Wrapper function for the signature verify function. 325 * Signature class verify function used for validating 326 * signed image. Also added additional logic to continue 327 * update process in lab environment by checking the 328 * fieldModeEnabled property. 329 * 330 * @param[in] pnorFileName - The PNOR filename in image dir 331 * 332 * @return true if successful signature validation or field 333 * mode is disabled. 334 * false for unsuccessful signature validation or 335 * any internal failure during the mapper call. 336 */ 337 bool validateSignature(const std::string& pnorFileName); 338 339 /** 340 * @brief Gets the fieldModeEnabled property value. 341 * 342 * @return fieldModeEnabled property value 343 * @error InternalFailure exception thrown 344 */ 345 bool fieldModeEnabled(); 346 #endif 347 }; 348 349 } // namespace updater 350 } // namespace software 351 } // namespace openpower 352