Create Version and Activation objects for current PNOR image
On BMC boot, create the Software version and activation that
points to the current PNOR version by reading:
/var/lib/phosphor-software-manager/pnor/ro
Resolves openbmc/openbmc#1762
Change-Id: I46ddb37491a1a230699da9f3acbd3fcff23dc538
Signed-off-by: Saqib Khan <khansa@us.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index cf9197d..d188b56 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,6 +7,7 @@
openpower_update_manager_SOURCES = \
activation.cpp \
+ version.cpp \
item_updater.cpp \
item_updater_main.cpp
diff --git a/item_updater.cpp b/item_updater.cpp
index 3edfb0c..7a56775 100755
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -3,6 +3,7 @@
#include <fstream>
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/Software/Version/server.hpp>
+#include "version.hpp"
#include "config.h"
#include "item_updater.hpp"
#include "activation.hpp"
@@ -101,7 +102,9 @@
fs::path manifestPath(filePath);
manifestPath /= MANIFEST_FILE;
- auto extendedVersion = ItemUpdater::getExtendedVersion(manifestPath);
+ 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<Activation>(
@@ -123,43 +126,44 @@
return;
}
-std::string ItemUpdater::getExtendedVersion(const std::string& manifestFilePath)
+void ItemUpdater::processPNORImage()
{
- constexpr auto extendedVersionKey = "extended_version=";
- constexpr auto extendedVersionKeySize = strlen(extendedVersionKey);
- if (manifestFilePath.empty())
+ fs::path pnorTOC(PNOR_RO_ACTIVE_PATH);
+ pnorTOC /= PNOR_TOC_FILE;
+ std::ifstream efile(pnorTOC.c_str());
+ if (efile.good() != 1)
{
- log<level::ERR>("Error MANIFESTFilePath is empty");
- throw std::runtime_error("MANIFESTFilePath is empty");
+ log<level::INFO>("Error PNOR current version is empty");
+ return;
}
-
- std::string extendedVersion{};
- std::ifstream efile;
- std::string line;
- efile.exceptions(std::ifstream::failbit
- | std::ifstream::badbit
- | std::ifstream::eofbit);
-
- try
- {
- efile.open(manifestFilePath);
- while (getline(efile, line))
- {
- if (line.compare(0, extendedVersionKeySize,
- extendedVersionKey) == 0)
- {
- extendedVersion = line.substr(extendedVersionKeySize);
- break;
- }
- }
- efile.close();
- }
- catch (const std::exception& e)
- {
- log<level::ERR>("Error in reading Host MANIFEST file");
- }
- return extendedVersion;
+ auto keyValues = Version::getValue(pnorTOC.string(),
+ std::map<std::string, std::string> {{"version", ""},
+ {"extended_version", ""}});
+ std::string version = keyValues.at("version");
+ std::string extendedVersion = keyValues.at("extended_version");
+ auto id = Version::getId(version);
+ auto purpose = server::Version::VersionPurpose::Host;
+ auto path = std::string{SOFTWARE_OBJPATH} + '/' + id;
+ auto activationState = server::Activation::Activations::Active;
+ activations.insert(std::make_pair(
+ id,
+ std::make_unique<Activation>(
+ bus,
+ path,
+ *this,
+ id,
+ extendedVersion,
+ activationState)));
+ versions.insert(std::make_pair(
+ id,
+ std::make_unique<Version>(
+ bus,
+ path,
+ version,
+ purpose,
+ "")));
+ return;
}
int ItemUpdater::validateSquashFSImage(const std::string& filePath)
diff --git a/item_updater.hpp b/item_updater.hpp
index 6409698..2a71905 100755
--- a/item_updater.hpp
+++ b/item_updater.hpp
@@ -39,6 +39,7 @@
this,
std::placeholders::_1))
{
+ processPNORImage();
}
/** @brief Sets the given priority free by incrementing
@@ -50,6 +51,11 @@
*/
void freePriority(uint8_t value);
+ /**
+ * @brief Create and populate the active PNOR Version.
+ */
+ void processPNORImage();
+
private:
/** @brief Callback function for Software.Version match.
* @details Creates an Activation dbus object.
@@ -59,15 +65,6 @@
void createActivation(sdbusplus::message::message& msg);
/**
- * @brief Get the extended version from the specified file.
- *
- * @param[in] manifestFilePath - File to read.
- *
- * @return The extended version.
- */
- static std::string getExtendedVersion(const std::string&
- manifestFilePath);
- /**
* @brief Validates the presence of SquashFS iamge in the image dir.
*
* @param[in] filePath - The path to the SquashfFS image.
diff --git a/version.cpp b/version.cpp
new file mode 100644
index 0000000..6cdc723
--- /dev/null
+++ b/version.cpp
@@ -0,0 +1,87 @@
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <fstream>
+#include <stdexcept>
+#include <phosphor-logging/log.hpp>
+#include "version.hpp"
+#include <phosphor-logging/elog-errors.hpp>
+#include "xyz/openbmc_project/Common/error.hpp"
+
+namespace openpower
+{
+namespace software
+{
+namespace updater
+{
+
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using namespace phosphor::logging;
+
+std::string Version::getId(const std::string& version)
+{
+ std::stringstream hexId;
+
+ if (version.empty())
+ {
+ log<level::ERR>("Error version is empty");
+ elog<InvalidArgument>(xyz::openbmc_project::Common::InvalidArgument::
+ ARGUMENT_NAME("Version"),
+ xyz::openbmc_project::Common::InvalidArgument::
+ ARGUMENT_VALUE(version.c_str()));
+ }
+
+ // Only want 8 hex digits.
+ hexId << std::hex << ((std::hash<std::string> {}(
+ version)) & 0xFFFFFFFF);
+ return hexId.str();
+}
+
+std::map<std::string, std::string> Version::getValue(
+ const std::string& filePath, std::map<std::string, std::string> keys)
+{
+
+ if (filePath.empty())
+ {
+ log<level::ERR>("Error filePath is empty");
+ elog<InvalidArgument>(xyz::openbmc_project::Common::InvalidArgument::
+ ARGUMENT_NAME("FilePath"),
+ xyz::openbmc_project::Common::InvalidArgument::
+ ARGUMENT_VALUE(filePath.c_str()));
+ }
+
+ std::ifstream efile;
+ std::string line;
+ efile.exceptions(std::ifstream::failbit
+ | std::ifstream::badbit
+ | std::ifstream::eofbit);
+
+ try
+ {
+ efile.open(filePath);
+ while (getline(efile, line))
+ {
+ for(auto& key : keys)
+ {
+ auto value = key.first + "=";
+ auto keySize = value.length();
+ if (line.compare(0, keySize, value) == 0)
+ {
+ key.second = line.substr(keySize);
+ break;
+ }
+ }
+ }
+ efile.close();
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("Error in reading file");
+ }
+
+ return keys;
+}
+
+} // namespace updater
+} // namespace software
+} // namespace openpower
diff --git a/version.hpp b/version.hpp
index 573255c..23bf604 100644
--- a/version.hpp
+++ b/version.hpp
@@ -46,6 +46,28 @@
// Emit deferred signal.
emit_object_added();
}
+
+ /**
+ * @brief Read the manifest file to get the value of the key.
+ *
+ * @param[in] filePath - The path to file which contains the value
+ * of keys.
+ * @param[in] keys - A map of keys with empty values.
+ *
+ * @return The map of keys with filled values.
+ **/
+ static std::map<std::string, std::string> getValue(
+ const std::string& filePath,
+ std::map<std::string, std::string> keys);
+
+ /**
+ * @brief Get the Version id.
+ *
+ * @param[in] version - The image version.
+ *
+ * @return The id.
+ */
+ static std::string getId(const std::string& version);
};
} // namespace updater