Create error log on fail

Use elog to create error log on fail.
Resolves openbmc/openbmc#1352

Change-Id: I1c362390110c5b3fcae3335a0bd0a7dd11540883
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 587248f..8bbf0c8 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,6 +19,15 @@
 	version.cpp \
 	image_manager.cpp
 
+nobase_nodist_include_HEADERS = \
+	xyz/openbmc_project/Software/Version/error.hpp
+
+BUILT_SOURCES = \
+	xyz/openbmc_project/Software/Version/error.cpp \
+	xyz/openbmc_project/Software/Version/error.hpp
+
+CLEANFILES = ${BUILT_SOURCES}
+
 phosphor_download_manager_SOURCES = \
 	download_manager.cpp \
 	download_manager_main.cpp
@@ -35,6 +44,14 @@
 	$(PHOSPHOR_LOGGING_LIBS) \
 	-lstdc++fs
 
+xyz/openbmc_project/Software/Version/error.hpp: ${top_srcdir}/xyz/openbmc_project/Software/Version.errors.yaml
+	@mkdir -p `dirname $@`
+	$(SDBUSPLUSPLUS) -r $(srcdir) error exception-header xyz.openbmc_project.Software.Version > $@
+
+xyz/openbmc_project/Software/Version/error.cpp: ${top_srcdir}/xyz/openbmc_project/Software/Version.errors.yaml
+	@mkdir -p `dirname $@`
+	$(SDBUSPLUSPLUS) -r $(srcdir) error exception-cpp xyz.openbmc_project.Software.Version > $@
+
 phosphor_version_software_manager_CXXFLAGS = $(generic_cxxflags)
 phosphor_version_software_manager_LDFLAGS = $(generic_ldflags)
 phosphor_download_manager_CXXFLAGS = $(generic_cxxflags)
diff --git a/configure.ac b/configure.ac
index 8f04258..a446e9f 100755
--- a/configure.ac
+++ b/configure.ac
@@ -18,6 +18,10 @@
     AC_MSG_ERROR(["Requires sdbusplus package."]))
 PKG_CHECK_MODULES([PHOSPHOR_LOGGING], [phosphor-logging],,\
     AC_MSG_ERROR(["Requires phosphor-logging package."]))
+# Check for sdbus++
+AC_PATH_PROG([SDBUSPLUSPLUS], [sdbus++])
+AS_IF([test "x$SDBUSPLUSPLUS" == "x"],
+    AC_MSG_ERROR(["Requires sdbus++"]))
 
 # Checks for library functions
 LT_INIT # Required for systemd linking
diff --git a/elog-errors.hpp b/elog-errors.hpp
new file mode 100644
index 0000000..5461ef6
--- /dev/null
+++ b/elog-errors.hpp
@@ -0,0 +1,271 @@
+// This file was autogenerated.  Do not edit!
+// See elog-gen.py for more details
+#pragma once
+
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <sdbusplus/exception.hpp>
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog.hpp>
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Software
+{
+namespace Version
+{
+namespace Error
+{
+    struct UnTarFailure;
+} // namespace Error
+} // namespace Version
+} // namespace Software
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Software
+{
+namespace Version
+{
+namespace Error
+{
+    struct InternalFailure;
+} // namespace Error
+} // namespace Version
+} // namespace Software
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Software
+{
+namespace Version
+{
+namespace Error
+{
+    struct ManifestFileFailure;
+} // namespace Error
+} // namespace Version
+} // namespace Software
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+
+namespace phosphor
+{
+
+namespace logging
+{
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Software
+{
+namespace Version
+{
+namespace _UnTarFailure
+{
+
+struct PATH
+{
+    static constexpr auto str = "PATH=%s";
+    static constexpr auto str_short = "PATH";
+    using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
+    explicit constexpr PATH(const char* a) : _entry(entry(str, a)) {};
+    type _entry;
+};
+
+}  // namespace _UnTarFailure
+
+struct UnTarFailure : public sdbusplus::exception_t
+{
+    static constexpr auto errName = "xyz.openbmc_project.Software.Version.UnTarFailure";
+    static constexpr auto errDesc = "An error occurred during untar.";
+    static constexpr auto L = level::ERR;
+    using PATH = _UnTarFailure::PATH;
+    using metadata_types = std::tuple<PATH>;
+
+    const char* name() const noexcept
+    {
+        return errName;
+    }
+
+    const char* description() const noexcept
+    {
+        return errDesc;
+    }
+
+    const char* what() const noexcept
+    {
+        return errName;
+    }
+};
+
+} // namespace Version
+} // namespace Software
+} // namespace openbmc_project
+} // namespace xyz
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Software::Version::Error::UnTarFailure>
+{
+    using type = xyz::openbmc_project::Software::Version::UnTarFailure;
+};
+
+}
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Software
+{
+namespace Version
+{
+namespace _ManifestFileFailure
+{
+
+struct PATH
+{
+    static constexpr auto str = "PATH=%s";
+    static constexpr auto str_short = "PATH";
+    using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
+    explicit constexpr PATH(const char* a) : _entry(entry(str, a)) {};
+    type _entry;
+};
+
+}  // namespace _ManifestFileFailure
+
+struct ManifestFileFailure : public sdbusplus::exception_t
+{
+    static constexpr auto errName = "xyz.openbmc_project.Software.Version.ManifestFileFailure";
+    static constexpr auto errDesc = "An error when reading the Manifest file.";
+    static constexpr auto L = level::ERR;
+    using PATH = _ManifestFileFailure::PATH;
+    using metadata_types = std::tuple<PATH>;
+
+    const char* name() const noexcept
+    {
+        return errName;
+    }
+
+    const char* description() const noexcept
+    {
+        return errDesc;
+    }
+
+    const char* what() const noexcept
+    {
+        return errName;
+    }
+};
+
+} // namespace Version
+} // namespace Software
+} // namespace openbmc_project
+} // namespace xyz
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Software::Version::Error::ManifestFileFailure>
+{
+    using type = xyz::openbmc_project::Software::Version::ManifestFileFailure;
+};
+
+}
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Software
+{
+namespace Version
+{
+namespace _InternalFailure
+{
+
+struct FAIL
+{
+    static constexpr auto str = "FAIL=%s";
+    static constexpr auto str_short = "FAIL";
+    using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
+    explicit constexpr FAIL(const char* a) : _entry(entry(str, a)) {};
+    type _entry;
+};
+
+}  // namespace _InternalFailure
+
+struct InternalFailure : public sdbusplus::exception_t
+{
+    static constexpr auto errName = "xyz.openbmc_project.Software.Version.InternalFailure";
+    static constexpr auto errDesc = "The operation failed internally during processing the image.";
+    static constexpr auto L = level::ERR;
+    using FAIL = _InternalFailure::FAIL;
+    using metadata_types = std::tuple<FAIL>;
+
+    const char* name() const noexcept
+    {
+        return errName;
+    }
+
+    const char* description() const noexcept
+    {
+        return errDesc;
+    }
+
+    const char* what() const noexcept
+    {
+        return errName;
+    }
+};
+
+} // namespace Version
+} // namespace Software
+} // namespace openbmc_project
+} // namespace xyz
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Software::Version::Error::InternalFailure>
+{
+    using type = xyz::openbmc_project::Software::Version::InternalFailure;
+};
+
+}
+
+
+} // namespace logging
+
+} // namespace phosphor
diff --git a/image_manager.cpp b/image_manager.cpp
index 235a5d6..bc6c96f 100644
--- a/image_manager.cpp
+++ b/image_manager.cpp
@@ -8,6 +8,9 @@
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <elog-errors.hpp>
+#include <xyz/openbmc_project/Software/Version/error.hpp>
 #include "config.h"
 #include "version.hpp"
 #include "watch.hpp"
@@ -21,6 +24,7 @@
 {
 
 using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Software::Version::Error;
 namespace fs = std::experimental::filesystem;
 
 struct RemovablePath
@@ -40,6 +44,9 @@
     {
         log<level::ERR>("Error tarball does not exist",
                         entry("FILENAME=%s", tarFilePath));
+        report<ManifestFileFailure>(xyz::openbmc_project::Software::Version::
+                                    ManifestFileFailure::PATH(
+                                        tarFilePath.c_str()));
         return -1;
 
     }
@@ -52,6 +59,8 @@
     {
         log<level::ERR>("Error occured during mkdtemp",
                         entry("ERRNO=%d", errno));
+        report<InternalFailure>(xyz::openbmc_project::Software::Version::
+                                InternalFailure::FAIL("mkdtemp"));
         return -1;
     }
 
@@ -70,6 +79,9 @@
         // execl only returns on fail
         log<level::ERR>("Failed to untar file",
                         entry("FILENAME=%s", tarFilePath));
+        report<ManifestFileFailure>(xyz::openbmc_project::Software::Version::
+                                    ManifestFileFailure::PATH(
+                                        manifestPath.c_str()));
         return -1;
     }
     else if (pid > 0)
@@ -79,6 +91,8 @@
     else
     {
         log<level::ERR>("fork() failed.");
+        report<InternalFailure>(xyz::openbmc_project::Software::Version::
+                                InternalFailure::FAIL("fork"));
         return -1;
     }
 
@@ -86,6 +100,9 @@
     if (!fs::is_regular_file(manifestPath))
     {
         log<level::ERR>("Error No manifest file");
+        report<ManifestFileFailure>(xyz::openbmc_project::Software::Version::
+                                    ManifestFileFailure::PATH(
+                                        manifestPath.c_str()));
         return -1;
     }
 
@@ -94,6 +111,9 @@
     if (version.empty())
     {
         log<level::ERR>("Error unable to read version from manifest file");
+        report<ManifestFileFailure>(xyz::openbmc_project::Software::Version::
+                                    ManifestFileFailure::PATH(
+                                        manifestPath.c_str()));
         return -1;
     }
 
@@ -102,6 +122,9 @@
     if (purposeString.empty())
     {
         log<level::ERR>("Error unable to read purpose from manifest file");
+        report<ManifestFileFailure>(xyz::openbmc_project::Software::Version::
+                                    ManifestFileFailure::PATH(
+                                        manifestPath.c_str()));
         return -1;
     }
 
@@ -136,6 +159,8 @@
     {
         log<level::ERR>("Error occured during mkdir",
                         entry("ERRNO=%d", errno));
+        report<InternalFailure>(xyz::openbmc_project::Software::Version::
+                                InternalFailure::FAIL("mkdir"));
         return -1;
     }
 
@@ -168,11 +193,15 @@
     if (tarFilePath.empty())
     {
         log<level::ERR>("Error TarFilePath is empty");
+        report<UnTarFailure>(xyz::openbmc_project::Software::Version::
+                             UnTarFailure::PATH(tarFilePath.c_str()));
         return -1;
     }
     if (extractDirPath.empty())
     {
         log<level::ERR>("Error ExtractDirPath is empty");
+        report<UnTarFailure>(xyz::openbmc_project::Software::Version::
+                             UnTarFailure::PATH(tarFilePath.c_str()));
         return -1;
     }
 
@@ -190,6 +219,8 @@
         // execl only returns on fail
         log<level::ERR>("Failed to untar file",
                         entry("FILENAME=%s", tarFilePath));
+        report<UnTarFailure>(xyz::openbmc_project::Software::Version::
+                             UnTarFailure::PATH(tarFilePath.c_str()));
         return -1;
     }
     else if (pid > 0)
@@ -199,6 +230,8 @@
     else
     {
         log<level::ERR>("fork() failed.");
+        report<UnTarFailure>(xyz::openbmc_project::Software::Version::
+                             UnTarFailure::PATH(tarFilePath.c_str()));
         return -1;
     }
 
diff --git a/xyz/openbmc_project/Software/Version.errors.yaml b/xyz/openbmc_project/Software/Version.errors.yaml
new file mode 100644
index 0000000..67d6c20
--- /dev/null
+++ b/xyz/openbmc_project/Software/Version.errors.yaml
@@ -0,0 +1,6 @@
+- name: UnTarFailure
+  description: An error occurred during untar.
+- name: ManifestFileFailure
+  description: An error when reading the Manifest file.
+- name: InternalFailure
+  description: The operation failed internally during processing the image.
diff --git a/xyz/openbmc_project/Software/Version.metadata.yaml b/xyz/openbmc_project/Software/Version.metadata.yaml
new file mode 100644
index 0000000..5e749c9
--- /dev/null
+++ b/xyz/openbmc_project/Software/Version.metadata.yaml
@@ -0,0 +1,15 @@
+- name: UnTarFailure
+  level: ERR
+  meta:
+    - str: "PATH=%s"
+      type: string
+- name: ManifestFileFailure
+  level: ERR
+  meta:
+    - str: "PATH=%s"
+      type: string
+- name: InternalFailure
+  level: ERR
+  meta:
+    - str: "FAIL=%s"
+      type: string