ItemUpdater: Validate BMC squashfs image

- Validate the image dir by checking its content.
- Set Activation to "Active" if current image,
  "Ready" if validation passed and "Invalid" if
  validation fails

Resolves openbmc/openbmc#1629

Change-Id: I5f1c42fb2ba93c849ea8653c9e81c737ae27c814
Signed-off-by: Saqib Khan <khansa@us.ibm.com>
diff --git a/item_updater.cpp b/item_updater.cpp
index 81afd6d..bc382e8 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -1,8 +1,10 @@
+#include <fstream>
 #include <string>
 #include <phosphor-logging/log.hpp>
 #include "config.h"
 #include "item_updater.hpp"
 #include "xyz/openbmc_project/Software/Version/server.hpp"
+#include <experimental/filesystem>
 
 namespace phosphor
 {
@@ -15,6 +17,9 @@
 namespace server = sdbusplus::xyz::openbmc_project::Software::server;
 
 using namespace phosphor::logging;
+namespace fs = std::experimental::filesystem;
+
+constexpr auto bmcImage = "image-rofs";
 
 void ItemUpdater::createActivation(sdbusplus::message::message& msg)
 {
@@ -63,19 +68,57 @@
 
     if (activations.find(versionId) == activations.end())
     {
-        // For now set all BMC code versions to active
-        constexpr auto activationState =
-                server::Activation::Activations::Active;
-
-        activations.insert(
-                std::make_pair(
-                        versionId,
-                        std::make_unique<Activation>(
-                                bus, path, versionId, activationState)));
+        // Determine the Activation state by processing the given image dir.
+        auto activationState = server::Activation::Activations::Invalid;
+        ItemUpdater::ActivationStatus result = ItemUpdater::
+                     validateSquashFSImage(versionId);
+        if (result == ItemUpdater::ActivationStatus::ready)
+        {
+            activationState = server::Activation::Activations::Ready;
+        }
+        else if (result == ItemUpdater::ActivationStatus::active)
+        {
+            activationState = server::Activation::Activations::Active;
+        }
+        activations.insert(std::make_pair(
+                                        versionId,
+                                        std::make_unique<Activation>(
+                                            bus,
+                                            path,
+                                            versionId,
+                                            activationState)));
     }
     return;
 }
 
+ItemUpdater::ActivationStatus ItemUpdater::validateSquashFSImage(
+             const std::string& versionId)
+{
+
+    // TODO openbmc/openbmc#1715 Check the Common.FilePath to
+    //      determine the active image.
+    fs::path imageDirPath(IMG_UPLOAD_DIR);
+    imageDirPath /= versionId;
+    if (!fs::is_directory(imageDirPath))
+    {
+        return ItemUpdater::ActivationStatus::active;
+    }
+
+    fs::path file(imageDirPath);
+    file /= bmcImage;
+    std::ifstream efile(file.c_str());
+
+    if (efile.good() == 1)
+    {
+        return ItemUpdater::ActivationStatus::ready;
+    }
+    else
+    {
+        log<level::ERR>("Failed to find the SquashFS image.");
+        return ItemUpdater::ActivationStatus::invalid;
+    }
+}
+
 } // namespace updater
 } // namespace software
 } // namespace phosphor