Fix problem requiring two Delete calls to remove an image

- Remove Delete inheritance and method from Version object.
- Add Delete inheritance and method to Activation object.
- Add a listener in the image Manager for deleted Versions and remove
  its 'backup' copy of the Version.

Resolves openbmc/openbmc#2086

Change-Id: If41783319cf1ff5b840b747ba457d0570bc52918
Signed-off-by: Eddie James <eajames@us.ibm.com>
diff --git a/activation.cpp b/activation.cpp
index af8f1e9..9d2ba4a 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -34,6 +34,11 @@
     return;
 }
 
+void Activation::delete_()
+{
+    parent.erase(versionId);
+}
+
 auto Activation::activation(Activations value) ->
         Activations
 {
diff --git a/activation.hpp b/activation.hpp
index d22ed91..cf4b5c2 100644
--- a/activation.hpp
+++ b/activation.hpp
@@ -6,6 +6,7 @@
 #include "xyz/openbmc_project/Software/RedundancyPriority/server.hpp"
 #include "xyz/openbmc_project/Software/ActivationProgress/server.hpp"
 #include "org/openbmc/Associations/server.hpp"
+#include "xyz/openbmc_project/Object/Delete/server.hpp"
 
 namespace phosphor
 {
@@ -18,7 +19,8 @@
      std::vector<std::tuple<std::string, std::string, std::string>>;
 using ActivationInherit = sdbusplus::server::object::object<
     sdbusplus::xyz::openbmc_project::Software::server::Activation,
-    sdbusplus::org::openbmc::server::Associations>;
+    sdbusplus::org::openbmc::server::Associations,
+    sdbusplus::xyz::openbmc_project::Object::server::Delete>;
 using ActivationBlocksTransitionInherit = sdbusplus::server::object::object<
  sdbusplus::xyz::openbmc_project::Software::server::ActivationBlocksTransition>;
 using RedundancyPriorityInherit = sdbusplus::server::object::object<
@@ -263,6 +265,11 @@
          */
         void unsubscribeFromSystemdSignals();
 
+        /**
+         * @brief delete the d-bus object.
+         */
+        void delete_() override;
+
         /** @brief Persistent sdbusplus DBus bus connection */
         sdbusplus::bus::bus& bus;
 
diff --git a/image_manager.cpp b/image_manager.cpp
index 5242d8b..357d3c2 100644
--- a/image_manager.cpp
+++ b/image_manager.cpp
@@ -172,10 +172,7 @@
                                   objPath,
                                   version,
                                   purpose,
-                                  imageDirPath.string(),
-                                  std::bind(&Manager::erase,
-                                            this,
-                                            std::placeholders::_1))));
+                                  imageDirPath.string())));
 
     return 0;
 }
@@ -196,6 +193,29 @@
     this->versions.erase(entryId);
 }
 
+void Manager::removeVersion(sdbusplus::message::message& msg)
+{
+    namespace mesg = sdbusplus::message;
+
+    mesg::object_path objPath;
+
+    msg.read(objPath);
+    std::string path(std::move(objPath));
+
+    // Version id is the last item in the path
+    auto pos = path.rfind("/");
+    if (pos == std::string::npos)
+    {
+        log<level::INFO>("No version id found in object path",
+                        entry("OBJPATH=%s", path));
+        return;
+    }
+
+    auto versionId = path.substr(pos + 1);
+
+    erase(versionId);
+}
+
 int Manager::unTar(const std::string& tarFilePath,
                    const std::string& extractDirPath)
 {
diff --git a/image_manager.hpp b/image_manager.hpp
index b0b8b89..5c69536 100644
--- a/image_manager.hpp
+++ b/image_manager.hpp
@@ -1,4 +1,5 @@
 #pragma once
+#include <sdbusplus/server.hpp>
 #include "version.hpp"
 
 namespace phosphor
@@ -8,6 +9,8 @@
 namespace manager
 {
 
+namespace MatchRules = sdbusplus::bus::match::rules;
+
 /** @class Manager
  *  @brief Contains a map of Version dbus objects.
  *  @details The software image manager class that contains the Version dbus
@@ -20,7 +23,16 @@
          *
          * @param[in] bus - The Dbus bus object
          */
-        Manager(sdbusplus::bus::bus& bus) : bus(bus){};
+        Manager(sdbusplus::bus::bus& bus) :
+                bus(bus),
+                versionMatch(
+                        bus,
+                        MatchRules::interfacesRemoved() +
+                        MatchRules::path(SOFTWARE_OBJPATH),
+                        std::bind(
+                                std::mem_fn(&Manager::removeVersion),
+                                this,
+                                std::placeholders::_1)){};
 
         /**
          * @brief Verify and untar the tarball. Verify the manifest file.
@@ -40,6 +52,13 @@
         void erase(std::string entryId);
 
     private:
+        /** @brief Callback function for Software.Version match.
+         *  @details Removes a version object.
+         *
+         * @param[in]  msg - Data associated with subscribed signal
+         */
+        void removeVersion(sdbusplus::message::message& msg);
+
         /** @brief Persistent map of Version dbus objects and their
           * version id */
         std::map<std::string, std::unique_ptr<Version>> versions;
@@ -47,6 +66,9 @@
         /** @brief Persistent sdbusplus DBus bus connection. */
         sdbusplus::bus::bus& bus;
 
+        /** @brief sdbusplus signal match for Software.Version */
+        sdbusplus::bus::match_t versionMatch;
+
         /**
          * @brief Untar the tarball.
          *
diff --git a/item_updater.cpp b/item_updater.cpp
index d230755..64bd270 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -130,10 +130,7 @@
                                 path,
                                 version,
                                 purpose,
-                                filePath,
-                                std::bind(&ItemUpdater::erase,
-                                          this,
-                                          std::placeholders::_1))));
+                                filePath)));
     }
     else
     {
@@ -221,10 +218,7 @@
                                      path,
                                      version,
                                      purpose,
-                                     "",
-                                     std::bind(&ItemUpdater::erase,
-                                       this,
-                                       std::placeholders::_1))));
+                                     "")));
         }
     }
     return;
diff --git a/version.cpp b/version.cpp
index 35df88f..b564416 100644
--- a/version.cpp
+++ b/version.cpp
@@ -101,15 +101,6 @@
     return version;
 }
 
-void Version::delete_()
-{
-    if (eraseCallback)
-    {
-        eraseCallback(getId(version()));
-    }
-}
-
 } // namespace manager
 } // namespace software
 } // namepsace phosphor
-
diff --git a/version.hpp b/version.hpp
old mode 100755
new mode 100644
index cbc2bd7..3d17213
--- a/version.hpp
+++ b/version.hpp
@@ -2,7 +2,6 @@
 
 #include <sdbusplus/bus.hpp>
 #include "xyz/openbmc_project/Software/Version/server.hpp"
-#include "xyz/openbmc_project/Object/Delete/server.hpp"
 #include "xyz/openbmc_project/Common/FilePath/server.hpp"
 #include <functional>
 
@@ -17,7 +16,6 @@
 
 using VersionInherit = sdbusplus::server::object::object<
     sdbusplus::xyz::openbmc_project::Software::server::Version,
-    sdbusplus::xyz::openbmc_project::Object::server::Delete,
     sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
 
 /** @class Version
@@ -35,18 +33,14 @@
          * @param[in] versionId      - The version identifier
          * @param[in] versionPurpose - The version purpose
          * @param[in] filePath       - The image filesystem path
-         * @param[in] callback       - The parent's erase callback
          */
         Version(sdbusplus::bus::bus& bus,
                 const std::string& objPath,
                 const std::string& versionId,
                 VersionPurpose versionPurpose,
-                const std::string& filePath,
-                eraseFunc callback) : VersionInherit(
+                const std::string& filePath) : VersionInherit(
                     bus, (objPath).c_str(), true)
         {
-            // Bind erase method
-            eraseCallback = callback;
             // Set properties.
             purpose(versionPurpose);
             version(versionId);
@@ -79,21 +73,8 @@
          * @return The version identifier.
          */
         static std::string getBMCVersion(const std::string& releaseFilePath);
-
-        /**
-         * @brief Delete the d-bus object and image.
-         */
-        void delete_() override;
-
-
-    private:
-        /**
-         * @brief The parent's erase callback.
-         */
-        eraseFunc eraseCallback;
 };
 
 } // namespace manager
 } // namespace software
 } // namespace phosphor
-