#pragma once #include "config.h" #include "activation_listener.hpp" #include "association_interface.hpp" #include "types.hpp" #include "version.hpp" #include #include #include #include #include #include #include #include class TestActivation; namespace phosphor { namespace software { namespace updater { namespace sdbusRule = sdbusplus::bus::match::rules; using ActivationBlocksTransitionInherit = sdbusplus::server::object_t; /** @class ActivationBlocksTransition * @brief OpenBMC ActivationBlocksTransition implementation. * @details A concrete implementation for * xyz.openbmc_project.Software.ActivationBlocksTransition DBus API. */ class ActivationBlocksTransition : public ActivationBlocksTransitionInherit { public: /** @brief Constructs ActivationBlocksTransition. * * @param[in] bus - The Dbus bus object * @param[in] path - The Dbus object path */ ActivationBlocksTransition(sdbusplus::bus_t& bus, const std::string& path) : ActivationBlocksTransitionInherit(bus, path.c_str(), action::emit_interface_added), bus(bus) { enableRebootGuard(); } ~ActivationBlocksTransition() { disableRebootGuard(); } private: sdbusplus::bus_t& bus; /** @brief Enables a Guard that blocks any BMC reboot commands */ void enableRebootGuard(); /** @brief Disables any guard that was blocking the BMC reboot */ void disableRebootGuard(); }; using ActivationProgressInherit = sdbusplus::server::object_t< sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>; class ActivationProgress : public ActivationProgressInherit { public: /** @brief Constructs ActivationProgress. * * @param[in] bus - The Dbus bus object * @param[in] path - The Dbus object path */ ActivationProgress(sdbusplus::bus_t& bus, const std::string& path) : ActivationProgressInherit(bus, path.c_str(), action::emit_interface_added) { progress(0); } }; using ActivationInherit = sdbusplus::server::object_t< sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion, sdbusplus::xyz::openbmc_project::Software::server::Activation, sdbusplus::xyz::openbmc_project::Association::server::Definitions, sdbusplus::xyz::openbmc_project::Common::server::FilePath>; /** @class Activation * @brief OpenBMC activation software management implementation. * @details A concrete implementation for * xyz.openbmc_project.Software.Activation DBus API. */ class Activation : public ActivationInherit { public: friend class ::TestActivation; using Status = Activations; /** @brief Constructs Activation Software Manager * * @param[in] bus - The Dbus bus object * @param[in] path - The Dbus object path * @param[in] versionId - The software version id * @param[in] extVersion - The extended version * @param[in] activationStatus - The status of Activation * @param[in] assocs - Association objects * @param[in] filePath - The image filesystem path */ Activation(sdbusplus::bus_t& bus, const std::string& objPath, const std::string& versionId, const std::string& extVersion, Status activationStatus, const AssociationList& assocs, const std::string& filePath, AssociationInterface* associationInterface, ActivationListener* activationListener) : ActivationInherit(bus, objPath.c_str(), ActivationInherit::action::defer_emit), bus(bus), objPath(objPath), versionId(versionId), systemdSignals( bus, sdbusRule::type::signal() + sdbusRule::member("JobRemoved") + sdbusRule::path("/org/freedesktop/systemd1") + sdbusRule::interface("org.freedesktop.systemd1.Manager"), std::bind(&Activation::unitStateChange, this, std::placeholders::_1)), associationInterface(associationInterface), activationListener(activationListener) { // Set Properties. extendedVersion(extVersion); activation(activationStatus); associations(assocs); path(filePath); auto info = Version::getExtVersionInfo(extVersion); manufacturer = info["manufacturer"]; model = info["model"]; // Emit deferred signal. emit_object_added(); } /** @brief Overloaded Activation property setter function * * @param[in] value - One of Activation::Activations * * @return Success or exception thrown */ Status activation(Status value) override; /** @brief Activation */ using ActivationInherit::activation; /** @brief Overloaded requestedActivation property setter function * * @param[in] value - One of Activation::RequestedActivations * * @return Success or exception thrown */ RequestedActivations requestedActivation(RequestedActivations value) override; /** @brief Get the object path */ const std::string& getObjectPath() const { return objPath; } /** @brief Get the version ID */ const std::string& getVersionId() const { return versionId; } private: /** @brief Check if systemd state change is relevant to this object * * Instance specific interface to handle the detected systemd state * change * * @param[in] msg - Data associated with subscribed signal * */ void unitStateChange(sdbusplus::message_t& msg); /** * @brief Delete the version from Image Manager and the * untar image from image upload dir. */ void deleteImageManagerObject(); /** @brief Invoke the update service for the PSU * * @param[in] psuInventoryPath - The PSU inventory to be updated. * * @return true if the update starts, and false if it fails. */ bool doUpdate(const std::string& psuInventoryPath); /** @brief Do PSU update one-by-one * * @return true if the update starts, and false if it fails. */ bool doUpdate(); /** @brief Handle an update done event */ void onUpdateDone(); /** @brief Handle an update failure event */ void onUpdateFailed(); /** @brief Start PSU update */ Status startActivation(); /** @brief Finish PSU update */ void finishActivation(); /** @brief Check if the PSU is compatible with this software*/ bool isCompatible(const std::string& psuInventoryPath); /** @brief Store the updated PSU image to persistent dir */ void storeImage(); /** @brief Construct the systemd service name * * @param[in] psuInventoryPath - The PSU inventory to be updated. * * @return The escaped string of systemd unit to do the PSU update. */ std::string getUpdateService(const std::string& psuInventoryPath); /** @brief Persistent sdbusplus DBus bus connection */ sdbusplus::bus_t& bus; /** @brief Persistent DBus object path */ std::string objPath; /** @brief Version id */ std::string versionId; /** @brief Used to subscribe to dbus systemd signals */ sdbusplus::bus::match_t systemdSignals; /** @brief The queue of psu objects to be updated */ std::queue psuQueue; /** @brief The progress step for each PSU update is done */ uint32_t progressStep; /** @brief The PSU update systemd unit */ std::string psuUpdateUnit; /** @brief The PSU Inventory path of the current updating PSU */ std::string currentUpdatingPsu; /** @brief Persistent ActivationBlocksTransition dbus object */ std::unique_ptr activationBlocksTransition; /** @brief Persistent ActivationProgress dbus object */ std::unique_ptr activationProgress; /** @brief The AssociationInterface pointer */ AssociationInterface* associationInterface; /** @brief The activationListener pointer */ ActivationListener* activationListener; /** @brief The PSU manufacturer of the software */ std::string manufacturer; /** @brief The PSU model of the software */ std::string model; }; } // namespace updater } // namespace software } // namespace phosphor