bmc/general_systemd: Support systemd status reporting

We should be able to figure out the service status without using a file
since systemd exposes all of this information on DBus

Tested:
    Ran on a system and created services that trigger different types of
    behavior during verification to simulate running for a couple
    seconds and succeeding and failure. Also tested failing as quickly
    as possible to ensure the signal capturing is working correctly.

Change-Id: I26358dae7e908a93b710587121fa104dd40ea661
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/bmc/general_systemd.hpp b/bmc/general_systemd.hpp
index c7fe4cb..a8d9a88 100644
--- a/bmc/general_systemd.hpp
+++ b/bmc/general_systemd.hpp
@@ -4,16 +4,56 @@
 
 #include <memory>
 #include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
 #include <string>
 
 namespace ipmi_flash
 {
 
+class SystemdNoFile : public TriggerableActionInterface
+{
+  public:
+    static std::unique_ptr<TriggerableActionInterface>
+        CreateSystemdNoFile(sdbusplus::bus::bus&& bus,
+                            const std::string& service,
+                            const std::string& mode);
+
+    SystemdNoFile(sdbusplus::bus::bus&& bus, const std::string& service,
+                  const std::string& mode) :
+        bus(std::move(bus)),
+        triggerService(service), mode(mode)
+    {
+    }
+
+    SystemdNoFile(const SystemdNoFile&) = delete;
+    SystemdNoFile& operator=(const SystemdNoFile&) = delete;
+    // sdbusplus match requires us to be pinned
+    SystemdNoFile(SystemdNoFile&&) = delete;
+    SystemdNoFile& operator=(SystemdNoFile&&) = delete;
+
+    bool trigger() override;
+    void abort() override;
+    ActionStatus status() override;
+
+    const std::string& getMode() const;
+
+  private:
+    sdbusplus::bus::bus bus;
+    const std::string triggerService;
+    const std::string mode;
+
+    std::optional<sdbusplus::bus::match::match> jobMonitor;
+    std::optional<std::string> job;
+    ActionStatus currentStatus = ActionStatus::unknown;
+
+    void match(sdbusplus::message::message& m);
+};
+
 /**
  * Representation of what is used for triggering an action with systemd and
  * checking the result by reading a file.
  */
-class SystemdWithStatusFile : public TriggerableActionInterface
+class SystemdWithStatusFile : public SystemdNoFile
 {
   public:
     /**
@@ -34,62 +74,15 @@
 
     SystemdWithStatusFile(sdbusplus::bus::bus&& bus, const std::string& path,
                           const std::string& service, const std::string& mode) :
-        bus(std::move(bus)),
-        checkPath(path), triggerService(service), mode(mode)
+        SystemdNoFile(std::move(bus), service, mode),
+        checkPath(path)
     {
     }
 
-    ~SystemdWithStatusFile() = default;
-    SystemdWithStatusFile(const SystemdWithStatusFile&) = delete;
-    SystemdWithStatusFile& operator=(const SystemdWithStatusFile&) = delete;
-    SystemdWithStatusFile(SystemdWithStatusFile&&) = default;
-    SystemdWithStatusFile& operator=(SystemdWithStatusFile&&) = default;
-
-    bool trigger() override;
-    void abort() override;
     ActionStatus status() override;
 
-    const std::string getMode() const;
-
   private:
-    sdbusplus::bus::bus bus;
     const std::string checkPath;
-    const std::string triggerService;
-    const std::string mode;
-};
-
-class SystemdNoFile : public TriggerableActionInterface
-{
-  public:
-    static std::unique_ptr<TriggerableActionInterface>
-        CreateSystemdNoFile(sdbusplus::bus::bus&& bus,
-                            const std::string& service,
-                            const std::string& mode);
-
-    SystemdNoFile(sdbusplus::bus::bus&& bus, const std::string& service,
-                  const std::string& mode) :
-        bus(std::move(bus)),
-        triggerService(service), mode(mode)
-    {
-    }
-
-    ~SystemdNoFile() = default;
-    SystemdNoFile(const SystemdNoFile&) = delete;
-    SystemdNoFile& operator=(const SystemdNoFile&) = delete;
-    SystemdNoFile(SystemdNoFile&&) = default;
-    SystemdNoFile& operator=(SystemdNoFile&&) = default;
-
-    bool trigger() override;
-    void abort() override;
-    ActionStatus status() override;
-
-    const std::string getMode() const;
-
-  private:
-    sdbusplus::bus::bus bus;
-    const std::string triggerService;
-    const std::string mode;
-    ActionStatus state = ActionStatus::unknown;
 };
 
 } // namespace ipmi_flash