Verify machine name

Verifying machine name from os-release file vs MANIFEST file in
image. Also supporting backword compatibility for older version
where machine name is not defined.

Tested: tested this with latest image build and manifest file patch

Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
Change-Id: Icb0ac3f884ea1131e2ffd2bde6b8a37185dc55ea
diff --git a/image_manager.cpp b/image_manager.cpp
index 5b2ff49..422e1bf 100644
--- a/image_manager.cpp
+++ b/image_manager.cpp
@@ -106,6 +106,33 @@
         return -1;
     }
 
+    // Get running machine name
+    std::string currMachine = Version::getBMCMachine(OS_RELEASE_FILE);
+    if (currMachine.empty())
+    {
+        log<level::ERR>("Failed to read machine name from osRelease",
+                        entry("FILENAME=%s", OS_RELEASE_FILE));
+        return -1;
+    }
+
+    // Get machine name for image to be upgraded
+    std::string machineStr =
+        Version::getValue(manifestPath.string(), "MachineName");
+    if (!machineStr.empty())
+    {
+        if (machineStr != currMachine)
+        {
+            log<level::ERR>("BMC upgrade: Machine name doesn't match",
+                            entry("CURR_MACHINE=%s", currMachine.c_str()),
+                            entry("NEW_MACHINE=%s", machineStr.c_str()));
+            return -1;
+        }
+    }
+    else
+    {
+        log<level::WARNING>("No machine name in Manifest file");
+    }
+
     // Get purpose
     auto purposeString = Version::getValue(manifestPath.string(), "purpose");
     if (purposeString.empty())
diff --git a/version.cpp b/version.cpp
index ca7e29c..adaaeb9 100644
--- a/version.cpp
+++ b/version.cpp
@@ -93,6 +93,33 @@
     return (hexId.substr(0, 8));
 }
 
+std::string Version::getBMCMachine(const std::string& releaseFilePath)
+{
+    std::string machineKey = "OPENBMC_TARGET_MACHINE=";
+    std::string machine{};
+    std::ifstream efile(releaseFilePath);
+    std::string line;
+
+    while (getline(efile, line))
+    {
+        if (line.substr(0, machineKey.size()).find(machineKey) !=
+            std::string::npos)
+        {
+            std::size_t pos = line.find_first_of('"') + 1;
+            machine = line.substr(pos, line.find_last_of('"') - pos);
+            break;
+        }
+    }
+
+    if (machine.empty())
+    {
+        log<level::ERR>("Unable to find OPENBMC_TARGET_MACHINE");
+        elog<InternalFailure>();
+    }
+
+    return machine;
+}
+
 std::string Version::getBMCVersion(const std::string& releaseFilePath)
 {
     std::string versionKey = "VERSION_ID=";
diff --git a/version.hpp b/version.hpp
index ef0eef3..bf43957 100644
--- a/version.hpp
+++ b/version.hpp
@@ -120,6 +120,16 @@
     static std::string getId(const std::string& version);
 
     /**
+     * @brief Get the active BMC machine name string.
+     *
+     * @param[in] releaseFilePath - The path to the file which contains
+     *                              the release machine string.
+     *
+     * @return The machine name string (e.g. romulus, tiogapass).
+     */
+    static std::string getBMCMachine(const std::string& releaseFilePath);
+
+    /**
      * @brief Get the active BMC version string.
      *
      * @param[in] releaseFilePath - The path to the file which contains