Refactor: Make createActivation() common
The function is almost the same for ubi and static layout, except a few
differences that creates the ubi objects.
Add below pure virtual functions for ubi to create ubi specific objects
* createActivationObject()
* createVersionObject()
Then it is possible to move most of the code in createActivation() into
the commone one.
Tested: On the last commit of the patch series, run code update and
factory reset on Witherspoon and all work fine.
Change-Id: Ieb3e783bc5b251529a55909f9e9f644230b274e7
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/activation.hpp b/activation.hpp
index 7e8eec5..29ef0e4 100644
--- a/activation.hpp
+++ b/activation.hpp
@@ -180,8 +180,8 @@
* @param[in] assocs - Association objects
*/
Activation(sdbusplus::bus::bus& bus, const std::string& path,
- ItemUpdater& parent, std::string& versionId,
- std::string& extVersion,
+ ItemUpdater& parent, const std::string& versionId,
+ const std::string& extVersion,
sdbusplus::xyz::openbmc_project::Software::server::Activation::
Activations activationStatus,
AssociationList& assocs) :
diff --git a/item_updater.cpp b/item_updater.cpp
index 06f3bc8..f321b02 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -4,6 +4,7 @@
#include "xyz/openbmc_project/Common/error.hpp"
+#include <filesystem>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
@@ -13,9 +14,114 @@
{
namespace updater
{
+namespace server = sdbusplus::xyz::openbmc_project::Software::server;
+namespace fs = std::filesystem;
+
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
using namespace phosphor::logging;
+void ItemUpdater::createActivation(sdbusplus::message::message& m)
+{
+ using SVersion = server::Version;
+ using VersionPurpose = SVersion::VersionPurpose;
+ namespace msg = sdbusplus::message;
+ namespace variant_ns = msg::variant_ns;
+
+ sdbusplus::message::object_path objPath;
+ std::map<std::string, std::map<std::string, msg::variant<std::string>>>
+ interfaces;
+ m.read(objPath, interfaces);
+
+ std::string path(std::move(objPath));
+ std::string filePath;
+ auto purpose = VersionPurpose::Unknown;
+ std::string version;
+
+ for (const auto& intf : interfaces)
+ {
+ if (intf.first == VERSION_IFACE)
+ {
+ for (const auto& property : intf.second)
+ {
+ if (property.first == "Purpose")
+ {
+ // Only process the Host and System images
+ auto value = SVersion::convertVersionPurposeFromString(
+ variant_ns::get<std::string>(property.second));
+
+ if (value == VersionPurpose::Host ||
+ value == VersionPurpose::System)
+ {
+ purpose = value;
+ }
+ }
+ else if (property.first == "Version")
+ {
+ version = variant_ns::get<std::string>(property.second);
+ }
+ }
+ }
+ else if (intf.first == FILEPATH_IFACE)
+ {
+ for (const auto& property : intf.second)
+ {
+ if (property.first == "Path")
+ {
+ filePath = variant_ns::get<std::string>(property.second);
+ }
+ }
+ }
+ }
+ if ((filePath.empty()) || (purpose == VersionPurpose::Unknown))
+ {
+ return;
+ }
+
+ // Version id is the last item in the path
+ auto pos = path.rfind("/");
+ if (pos == std::string::npos)
+ {
+ log<level::ERR>("No version id found in object path",
+ entry("OBJPATH=%s", path.c_str()));
+ return;
+ }
+
+ auto versionId = path.substr(pos + 1);
+
+ if (activations.find(versionId) == activations.end())
+ {
+ // Determine the Activation state by processing the given image dir.
+ auto activationState = server::Activation::Activations::Invalid;
+ AssociationList associations = {};
+ if (validateImage(filePath))
+ {
+ activationState = server::Activation::Activations::Ready;
+ // Create an association to the host inventory item
+ associations.emplace_back(std::make_tuple(
+ ACTIVATION_FWD_ASSOCIATION, ACTIVATION_REV_ASSOCIATION,
+ HOST_INVENTORY_PATH));
+ }
+
+ fs::path manifestPath(filePath);
+ manifestPath /= MANIFEST_FILE;
+ std::string extendedVersion =
+ (Version::getValue(
+ manifestPath.string(),
+ std::map<std::string, std::string>{{"extended_version", ""}}))
+ .begin()
+ ->second;
+
+ auto activation = createActivationObject(
+ path, versionId, extendedVersion, activationState, associations);
+ activations.emplace(versionId, std::move(activation));
+
+ auto versionPtr =
+ createVersionObject(path, versionId, version, purpose, filePath);
+ versions.emplace(versionId, std::move(versionPtr));
+ }
+ return;
+}
+
void ItemUpdater::createActiveAssociation(const std::string& path)
{
assocs.emplace_back(
diff --git a/item_updater.hpp b/item_updater.hpp
index 0e4c45c..8b1bf0d 100644
--- a/item_updater.hpp
+++ b/item_updater.hpp
@@ -170,7 +170,27 @@
*
* @param[in] msg - Data associated with subscribed signal
*/
- virtual void createActivation(sdbusplus::message::message& msg) = 0;
+ virtual void createActivation(sdbusplus::message::message& msg);
+
+ /** @brief Create Activation object */
+ virtual std::unique_ptr<Activation> createActivationObject(
+ const std::string& path, const std::string& versionId,
+ const std::string& extVersion,
+ sdbusplus::xyz::openbmc_project::Software::server::Activation::
+ Activations activationStatus,
+ AssociationList& assocs) = 0;
+
+ /** @brief Create Version object */
+ virtual std::unique_ptr<Version>
+ createVersionObject(const std::string& objPath,
+ const std::string& versionId,
+ const std::string& versionString,
+ sdbusplus::xyz::openbmc_project::Software::server::
+ Version::VersionPurpose versionPurpose,
+ const std::string& filePath) = 0;
+
+ /** @brief Validate if image is valid or not */
+ virtual bool validateImage(const std::string& path) = 0;
/** @brief Persistent sdbusplus D-Bus bus connection. */
sdbusplus::bus::bus& bus;
diff --git a/ubi/item_updater_ubi.cpp b/ubi/item_updater_ubi.cpp
index f576b3c..875847f 100644
--- a/ubi/item_updater_ubi.cpp
+++ b/ubi/item_updater_ubi.cpp
@@ -35,110 +35,34 @@
constexpr auto MBOXD_INTERFACE = "org.openbmc.mboxd";
constexpr auto MBOXD_PATH = "/org/openbmc/mboxd";
-void ItemUpdaterUbi::createActivation(sdbusplus::message::message& m)
+std::unique_ptr<Activation> ItemUpdaterUbi::createActivationObject(
+ const std::string& path, const std::string& versionId,
+ const std::string& extVersion,
+ sdbusplus::xyz::openbmc_project::Software::server::Activation::Activations
+ activationStatus,
+ AssociationList& assocs)
{
- using SVersion = server::Version;
- using VersionPurpose = SVersion::VersionPurpose;
- namespace msg = sdbusplus::message;
- namespace variant_ns = msg::variant_ns;
+ return std::make_unique<ActivationUbi>(
+ bus, path, *this, versionId, extVersion, activationStatus, assocs);
+}
- sdbusplus::message::object_path objPath;
- std::map<std::string, std::map<std::string, msg::variant<std::string>>>
- interfaces;
- m.read(objPath, interfaces);
+std::unique_ptr<Version> ItemUpdaterUbi::createVersionObject(
+ const std::string& objPath, const std::string& versionId,
+ const std::string& versionString,
+ sdbusplus::xyz::openbmc_project::Software::server::Version::VersionPurpose
+ versionPurpose,
+ const std::string& filePath)
+{
+ auto version = std::make_unique<Version>(
+ bus, objPath, *this, versionId, versionString, versionPurpose, filePath,
+ std::bind(&ItemUpdaterUbi::erase, this, std::placeholders::_1));
+ version->deleteObject = std::make_unique<Delete>(bus, objPath, *version);
+ return version;
+}
- std::string path(std::move(objPath));
- std::string filePath;
- auto purpose = VersionPurpose::Unknown;
- std::string version;
-
- for (const auto& intf : interfaces)
- {
- if (intf.first == VERSION_IFACE)
- {
- for (const auto& property : intf.second)
- {
- if (property.first == "Purpose")
- {
- // Only process the Host and System images
- auto value = SVersion::convertVersionPurposeFromString(
- variant_ns::get<std::string>(property.second));
-
- if (value == VersionPurpose::Host ||
- value == VersionPurpose::System)
- {
- purpose = value;
- }
- }
- else if (property.first == "Version")
- {
- version = variant_ns::get<std::string>(property.second);
- }
- }
- }
- else if (intf.first == FILEPATH_IFACE)
- {
- for (const auto& property : intf.second)
- {
- if (property.first == "Path")
- {
- filePath = variant_ns::get<std::string>(property.second);
- }
- }
- }
- }
- if ((filePath.empty()) || (purpose == VersionPurpose::Unknown))
- {
- return;
- }
-
- // Version id is the last item in the path
- auto pos = path.rfind("/");
- if (pos == std::string::npos)
- {
- log<level::ERR>("No version id found in object path",
- entry("OBJPATH=%s", path.c_str()));
- return;
- }
-
- auto versionId = path.substr(pos + 1);
-
- if (activations.find(versionId) == activations.end())
- {
- // Determine the Activation state by processing the given image dir.
- auto activationState = server::Activation::Activations::Invalid;
- AssociationList associations = {};
- if (validateSquashFSImage(filePath) == 0)
- {
- activationState = server::Activation::Activations::Ready;
- // Create an association to the host inventory item
- associations.emplace_back(std::make_tuple(
- ACTIVATION_FWD_ASSOCIATION, ACTIVATION_REV_ASSOCIATION,
- HOST_INVENTORY_PATH));
- }
-
- fs::path manifestPath(filePath);
- manifestPath /= MANIFEST_FILE;
- std::string extendedVersion =
- (Version::getValue(
- manifestPath.string(),
- std::map<std::string, std::string>{{"extended_version", ""}}))
- .begin()
- ->second;
-
- activations.insert(std::make_pair(
- versionId, std::make_unique<ActivationUbi>(
- bus, path, *this, versionId, extendedVersion,
- activationState, associations)));
-
- auto versionPtr = std::make_unique<Version>(
- bus, path, *this, versionId, version, purpose, filePath,
- std::bind(&ItemUpdaterUbi::erase, this, std::placeholders::_1));
- versionPtr->deleteObject =
- std::make_unique<Delete>(bus, path, *versionPtr);
- versions.insert(std::make_pair(versionId, std::move(versionPtr)));
- }
- return;
+bool ItemUpdaterUbi::validateImage(const std::string& path)
+{
+ return validateSquashFSImage(path) == 0;
}
void ItemUpdaterUbi::processPNORImage()
diff --git a/ubi/item_updater_ubi.hpp b/ubi/item_updater_ubi.hpp
index ec9d05c..5de51d3 100644
--- a/ubi/item_updater_ubi.hpp
+++ b/ubi/item_updater_ubi.hpp
@@ -48,12 +48,22 @@
static std::string determineId(const std::string& symlinkPath);
private:
- /** @brief Callback function for Software.Version match.
- * @details Creates an Activation D-Bus object.
- *
- * @param[in] msg - Data associated with subscribed signal
- */
- void createActivation(sdbusplus::message::message& msg) override;
+ std::unique_ptr<Activation> createActivationObject(
+ const std::string& path, const std::string& versionId,
+ const std::string& extVersion,
+ sdbusplus::xyz::openbmc_project::Software::server::Activation::
+ Activations activationStatus,
+ AssociationList& assocs) override;
+
+ std::unique_ptr<Version>
+ createVersionObject(const std::string& objPath,
+ const std::string& versionId,
+ const std::string& versionString,
+ sdbusplus::xyz::openbmc_project::Software::server::
+ Version::VersionPurpose versionPurpose,
+ const std::string& filePath) override;
+
+ bool validateImage(const std::string& path) override;
/** @brief Host factory reset - clears PNOR partitions for each
* Activation D-Bus object */