Create IBM ConfigFile base directory

The ConfigFile upload fails when the /var/lib/obmc directory is not
available at BMC

This commit changes the base directory to /var/lib/bmcweb
The subdirectories for the configfiles and locks
are created under this new path

Migration strategy of this directory and files:
 This is IBM only feature, compiled under the IBM_MANAGEMENT_CONSOLE flag
 There is no system out yet which is running this code
 Internal IBM stake holders are in agreement with the changes

Tested by :
  1. Tested configfile upload on a BMC where the base directory is not
available
  2. Tested the configfile upload on a factory BMC. Verified it creates
     the base directories and the upload is successful
  3. Tested the configfile usecases for delete and delete-all
  4. Tested the acquire-lock functionality
  5. Ran lock unit test successfully

Signed-off-by: Sunitha Harish <sunharis@in.ibm.com>
Change-Id: Ic3f5f5d0ba0b37950fd397ec835b4fa7babdaa9b
diff --git a/include/ibm/locks.hpp b/include/ibm/locks.hpp
index 3054791..0b47471 100644
--- a/include/ibm/locks.hpp
+++ b/include/ibm/locks.hpp
@@ -3,6 +3,7 @@
 #include <boost/algorithm/string.hpp>
 #include <boost/container/flat_map.hpp>
 #include <boost/endian/conversion.hpp>
+#include <include/ibm/utils.hpp>
 #include <logging.hpp>
 #include <nlohmann/json.hpp>
 
@@ -36,7 +37,8 @@
 using SessionFlags = std::pair<SType, SType>;
 using ListOfSessionIds = std::vector<std::string>;
 static constexpr const char* fileName =
-    "/var/lib/obmc/bmc-console-mgmt/locks/ibm_mc_persistent_lock_data.json";
+    "/var/lib/bmcweb/ibm-management-console/locks/"
+    "ibm_mc_persistent_lock_data.json";
 
 class Lock
 {
@@ -44,21 +46,19 @@
     boost::container::flat_map<uint32_t, LockRequests> lockTable;
 
     /*
-     * This API implements the logic to persist the locks that are contained in
-     * the lock table into a json file.
-     */
-    void saveLocks();
-
-    /*
      * This API implements the logic to load the locks that are present in the
      * json file into the lock table.
      */
     void loadLocks();
 
-    bool createPersistentLockFilePath();
-
   protected:
     /*
+     * This API implements the logic to persist the locks that are contained in
+     * the lock table into a json file.
+     */
+    void saveLocks();
+
+    /*
      * This function implements the logic for validating an incoming
      * lock request/requests.
      *
@@ -189,37 +189,6 @@
     virtual ~Lock() = default;
 };
 
-inline bool Lock::createPersistentLockFilePath()
-{
-    // The path /var/lib/obmc will be created by initrdscripts
-    // Create the directories for the persistent lock file
-    std::error_code ec;
-    if (!std::filesystem::is_directory("/var/lib/obmc/bmc-console-mgmt", ec))
-    {
-        std::filesystem::create_directory("/var/lib/obmc/bmc-console-mgmt", ec);
-    }
-    if (ec)
-    {
-        BMCWEB_LOG_DEBUG
-            << "Failed to prepare bmc-console-mgmt directory. ec : " << ec;
-        return false;
-    }
-
-    if (!std::filesystem::is_directory("/var/lib/obmc/bmc-console-mgmt/locks",
-                                       ec))
-    {
-        std::filesystem::create_directory(
-            "/var/lib/obmc/bmc-console-mgmt/locks", ec);
-    }
-    if (ec)
-    {
-        BMCWEB_LOG_DEBUG
-            << "Failed to prepare persistent lock file directory. ec : " << ec;
-        return false;
-    }
-    return true;
-}
-
 inline void Lock::loadLocks()
 {
     std::ifstream persistentFile(fileName);
@@ -247,20 +216,16 @@
 inline void Lock::saveLocks()
 {
     std::error_code ec;
-    if (!std::filesystem::is_directory("/var/lib/obmc/bmc-console-mgmt/locks",
-                                       ec))
+    std::string_view path = "/var/lib/bmcweb/ibm-management-console/locks";
+    if (!crow::ibm_utils::createDirectory(path))
     {
-        if (!createPersistentLockFilePath())
-        {
-            BMCWEB_LOG_DEBUG << "Failed to create lock persistent path";
-            return;
-        }
+        BMCWEB_LOG_DEBUG << "Failed to create lock persistent path";
+        return;
     }
     std::ofstream persistentFile(fileName);
-    // set the permission of the file to 640
+    // set the permission of the file to 600
     std::filesystem::perms permission = std::filesystem::perms::owner_read |
-                                        std::filesystem::perms::owner_write |
-                                        std::filesystem::perms::group_read;
+                                        std::filesystem::perms::owner_write;
     std::filesystem::permissions(fileName, permission);
     nlohmann::json data;
     for (const auto& it : lockTable)
@@ -359,6 +324,9 @@
 
     auto conflict = isConflictWithTable(multiRequest);
 
+    // save the lock in the persistent file
+    saveLocks();
+
     BMCWEB_LOG_DEBUG << "Done with checking conflict with the locktable";
     return std::make_pair(false, conflict);
 }
@@ -548,8 +516,6 @@
         lockTable.emplace(std::pair<uint32_t, LockRequests>(
             transactionId, refLockRequestStructure));
 
-        // save the lock in the persistent file
-        saveLocks();
         return std::make_pair(false, transactionId);
     }
     BMCWEB_LOG_DEBUG
@@ -582,8 +548,6 @@
     transactionId = generateTransactionId();
     lockTable.emplace(std::make_pair(transactionId, refLockRequestStructure));
 
-    // save the lock in the persistent file
-    saveLocks();
     return std::make_pair(false, transactionId);
 }
 
diff --git a/include/ibm/management_console_rest.hpp b/include/ibm/management_console_rest.hpp
index 5e49a9a..d5ee590 100644
--- a/include/ibm/management_console_rest.hpp
+++ b/include/ibm/management_console_rest.hpp
@@ -42,47 +42,6 @@
 constexpr size_t maxBroadcastMsgSize =
     1000; // Allow Broadcast message size upto 1KB
 
-inline bool
-    createSaveAreaPath(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-{
-    // The path /var/lib/obmc will be created by initrdscripts
-    // Create the directories for the save-area files, when we get
-    // first file upload request
-    std::error_code ec;
-    if (!std::filesystem::is_directory("/var/lib/obmc/bmc-console-mgmt", ec))
-    {
-        std::filesystem::create_directory("/var/lib/obmc/bmc-console-mgmt", ec);
-    }
-    if (ec)
-    {
-        asyncResp->res.result(
-            boost::beast::http::status::internal_server_error);
-        asyncResp->res.jsonValue["Description"] = internalServerError;
-        BMCWEB_LOG_DEBUG
-            << "handleIbmPost: Failed to prepare save-area directory. ec : "
-            << ec;
-        return false;
-    }
-
-    if (!std::filesystem::is_directory(
-            "/var/lib/obmc/bmc-console-mgmt/save-area", ec))
-    {
-        std::filesystem::create_directory(
-            "/var/lib/obmc/bmc-console-mgmt/save-area", ec);
-    }
-    if (ec)
-    {
-        asyncResp->res.result(
-            boost::beast::http::status::internal_server_error);
-        asyncResp->res.jsonValue["Description"] = internalServerError;
-        BMCWEB_LOG_DEBUG
-            << "handleIbmPost: Failed to prepare save-area directory. ec : "
-            << ec;
-        return false;
-    }
-    return true;
-}
-
 inline void handleFilePut(const crow::Request& req,
                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const std::string& fileID)
@@ -101,7 +60,9 @@
 
     BMCWEB_LOG_DEBUG
         << "handleIbmPut: Request to create/update the save-area file";
-    if (!createSaveAreaPath(asyncResp))
+    std::string_view path =
+        "/var/lib/bmcweb/ibm-management-console/configfiles";
+    if (!crow::ibm_utils::createDirectory(path))
     {
         asyncResp->res.result(boost::beast::http::status::not_found);
         asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
@@ -109,7 +70,8 @@
     }
 
     std::ofstream file;
-    std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area");
+    std::filesystem::path loc(
+        "/var/lib/bmcweb/ibm-management-console/configfiles");
 
     // Get the current size of the savearea directory
     std::filesystem::recursive_directory_iterator iter(loc, ec);
@@ -234,6 +196,12 @@
     }
 
     file.open(loc, std::ofstream::out);
+
+    // set the permission of the file to 600
+    std::filesystem::perms permission = std::filesystem::perms::owner_write |
+                                        std::filesystem::perms::owner_read;
+    std::filesystem::permissions(loc, permission);
+
     if (file.fail())
     {
         BMCWEB_LOG_DEBUG << "Error while opening the file for writing";
@@ -244,6 +212,7 @@
         return;
     }
     file << data;
+
     std::string origin = "/ibm/v1/Host/ConfigFiles/" + fileID;
     // Push an event
     if (fileExists)
@@ -268,7 +237,8 @@
     handleConfigFileList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
     std::vector<std::string> pathObjList;
-    std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area");
+    std::filesystem::path loc(
+        "/var/lib/bmcweb/ibm-management-console/configfiles");
     if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
     {
         for (const auto& file : std::filesystem::directory_iterator(loc))
@@ -296,7 +266,8 @@
 {
     std::vector<std::string> pathObjList;
     std::error_code ec;
-    std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area");
+    std::filesystem::path loc(
+        "/var/lib/bmcweb/ibm-management-console/configfiles");
     if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
     {
         std::filesystem::remove_all(loc, ec);
@@ -334,8 +305,8 @@
                           const std::string& fileID)
 {
     BMCWEB_LOG_DEBUG << "HandleGet on SaveArea files on path: " << fileID;
-    std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area/" +
-                              fileID);
+    std::filesystem::path loc(
+        "/var/lib/bmcweb/ibm-management-console/configfiles/" + fileID);
     if (!std::filesystem::exists(loc))
     {
         BMCWEB_LOG_ERROR << loc << "Not found";
@@ -367,7 +338,8 @@
     handleFileDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                      const std::string& fileID)
 {
-    std::string filePath("/var/lib/obmc/bmc-console-mgmt/save-area/" + fileID);
+    std::string filePath("/var/lib/bmcweb/ibm-management-console/configfiles/" +
+                         fileID);
     BMCWEB_LOG_DEBUG << "Removing the file : " << filePath << "\n";
     std::ifstream fileOpen(filePath.c_str());
     if (static_cast<bool>(fileOpen))
diff --git a/include/ibm/utils.hpp b/include/ibm/utils.hpp
new file mode 100644
index 0000000..217b2f4
--- /dev/null
+++ b/include/ibm/utils.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <logging.hpp>
+
+#include <filesystem>
+#include <fstream>
+
+namespace crow
+{
+namespace ibm_utils
+{
+
+inline bool createDirectory(const std::string_view path)
+{
+    // Create persistent directory
+    std::error_code ec;
+
+    BMCWEB_LOG_DEBUG << "Creating persistent directory : " << path;
+
+    bool dirCreated = std::filesystem::create_directories(path, ec);
+
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR << "Failed to create persistent directory : " << path;
+        return false;
+    }
+
+    if (dirCreated)
+    {
+        // set the permission of the directory to 700
+        BMCWEB_LOG_DEBUG << "Setting the permission to 700";
+        std::filesystem::perms permission = std::filesystem::perms::owner_all;
+        std::filesystem::permissions(path, permission);
+    }
+    else
+    {
+        BMCWEB_LOG_DEBUG << path << " already exists";
+    }
+    return true;
+}
+
+} // namespace ibm_utils
+} // namespace crow