Support non-ubifs layout

Add ubifs_layout as config argument, so a build could select if it
needs ubifs_layout feature or not.

Add code to update non-ubifs layout image by
1. Putting the bmc image in /run/initramfs;
2. Set its state as Active when it is ready to update
3. Let user to initiate the reboot request

Tested: Generate a tarball with Romulus bmc image and manifest,
        update it with REST API (image upload, activation, and reboot)
        Verify the code update works well in WebUI.

Change-Id: I5b122211fafb7cb9d96ee67317db139ed0b7d0a7
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/Makefile.am b/Makefile.am
index adba0e4..859b35d 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -39,7 +39,11 @@
 	item_updater.cpp \
 	item_updater_main.cpp
 
+if UBIFS_LAYOUT
 include ubi/Makefile.am.include
+else
+include static/Makefile.am.include
+endif
 
 if WANT_SIGNATURE_VERIFY_BUILD
 noinst_HEADERS += image_verify.hpp
diff --git a/activation.cpp b/activation.cpp
index 92de6a6..2979752 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -77,6 +77,7 @@
 
     if (value == softwareServer::Activation::Activations::Activating)
     {
+#ifdef UBIFS_LAYOUT
         if (rwVolumeCreated == false && roVolumeCreated == false)
         {
             // Enable systemd signals
@@ -160,6 +161,28 @@
                     softwareServer::Activation::Activations::Active);
             }
         }
+#else // !UBIFS_LAYOUT
+
+        parent.freeSpace();
+
+        flashWrite();
+
+        if (!redundancyPriority)
+        {
+            redundancyPriority =
+                std::make_unique<RedundancyPriority>(bus, path, *this, 0);
+        }
+
+        // Remove version object from image manager
+        Activation::deleteImageManagerObject();
+
+        // Create active association
+        parent.createActiveAssociation(path);
+
+        log<level::INFO>("BMC image ready, need reboot to get activated.");
+        return softwareServer::Activation::activation(
+            softwareServer::Activation::Activations::Active);
+#endif
     }
     else
     {
diff --git a/configure.ac b/configure.ac
index 8425af7..deaf110 100755
--- a/configure.ac
+++ b/configure.ac
@@ -156,6 +156,13 @@
     [AC_DEFINE([WANT_SYNC],[],[Enable sync of filesystem files.])])
 AM_CONDITIONAL([WANT_SYNC], [test "x$enable_sync_bmc_files" == "xyes"])
 
+# setup ubifs layout support
+AC_ARG_ENABLE([ubifs_layout],
+    AS_HELP_STRING([--enable-ubifs_layout], [Enable ubifs support.]))
+AS_IF([test "x$enable_ubifs_layout" == "xyes"], \
+    [AC_DEFINE([UBIFS_LAYOUT],[],[Enable ubifs support.])])
+AM_CONDITIONAL([UBIFS_LAYOUT], [test "x$enable_ubifs_layout" == "xyes"])
+
 # Check for header files.
 AC_CHECK_HEADER(systemd/sd-bus.h, ,[AC_MSG_ERROR([Could not find systemd/sd-bus.h...systemd development package required])])
 AC_CHECK_HEADER(sdbusplus/server.hpp, ,[AC_MSG_ERROR([Could not find sdbusplus/server.hpp...openbmc/sdbusplus package required])])
diff --git a/image_verify.hpp b/image_verify.hpp
index c40713c..3c9c2a4 100644
--- a/image_verify.hpp
+++ b/image_verify.hpp
@@ -29,8 +29,13 @@
     std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_destroy)>;
 
 // BMC flash image file name list.
+#ifdef UBIFS_LAYOUT
 const std::vector<std::string> bmcImages = {"image-kernel", "image-rofs",
                                             "image-rwfs", "image-u-boot"};
+#else
+const std::vector<std::string> bmcImages = {"image-bmc"};
+#endif
+
 /** @struct CustomFd
  *
  *  RAII wrapper for file descriptor.
diff --git a/static/Makefile.am.include b/static/Makefile.am.include
new file mode 100644
index 0000000..7bcfcb2
--- /dev/null
+++ b/static/Makefile.am.include
@@ -0,0 +1,2 @@
+phosphor_image_updater_SOURCES += \
+	%reldir%/flash.cpp
diff --git a/static/flash.cpp b/static/flash.cpp
new file mode 100644
index 0000000..59c7a67
--- /dev/null
+++ b/static/flash.cpp
@@ -0,0 +1,43 @@
+#include <experimental/filesystem>
+
+#include "activation.hpp"
+#include "config.h"
+#include "flash.hpp"
+#include "image_verify.hpp" // For bmcImages
+
+namespace
+{
+constexpr auto PATH_INITRAMFS = "/run/initramfs";
+} // anonymous
+
+namespace phosphor
+{
+namespace software
+{
+namespace updater
+{
+
+namespace fs = std::experimental::filesystem;
+
+void Activation::flashWrite()
+{
+    // For static layout code update, just put image in /run/initramfs.
+    // It expects user to trigger a reboot and an updater script will program
+    // the image to flash during reboot.
+    fs::path uploadDir(IMG_UPLOAD_DIR);
+    fs::path toPath(PATH_INITRAMFS);
+    for (auto& bmcImage : phosphor::software::image::bmcImages)
+    {
+        fs::copy_file(uploadDir / versionId / bmcImage, toPath / bmcImage,
+                      fs::copy_options::overwrite_existing);
+    }
+}
+
+void Activation::onStateChanges(sdbusplus::message::message& /*msg*/)
+{
+    // Empty
+}
+
+} // namespace updater
+} // namespace software
+} // namepsace phosphor