pytools: obmcutil: Implement verbose mode

Verbose output is limited to state change requests at the moment, as
they are the operations that take significant amounts of time. Further,
the verbose output is implemented as following the tail of the journal
until the requested state change either succeeds or fails.

In testing it was observed that the journal output tends to lag the
DBus event that signals the completion of the state transition. As such
the patch adds a tuning parameter defining a further waiting period
beyond the receipt of the completion signal so that the verbose output
looks "reasonable". The default value of the tuning parameter was
roughly chosen to correlate well with the journal output on a
Witherspoon system for the `poweron` command.

Change-Id: I847e2bfeba55d6a3d7d1f7ff1ba1901993c9b505
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/pytools/obmcutil b/pytools/obmcutil
index aee294b..a18d970 100644
--- a/pytools/obmcutil
+++ b/pytools/obmcutil
@@ -6,6 +6,10 @@
 
 from dbus.mainloop.glib import DBusGMainLoop
 import gobject
+import os
+import signal
+import time
+from subprocess import Popen
 
 descriptors = {
     'power': {
@@ -91,6 +95,9 @@
 
     property_listener.success = True
 
+    if args.wait and args.verbose:
+        pid = Popen(["/bin/journalctl", "-f", "--no-pager"]).pid
+
     if args.wait:
         sig_match = dbus_bus.add_signal_receiver(property_listener, "JobRemoved")
 
@@ -100,6 +107,11 @@
         mainloop.run()
         sig_match.remove()
 
+    if args.wait and args.verbose:
+        # wait some time for the journal output
+        time.sleep(args.wait_tune)
+        os.kill(pid, signal.SIGTERM)
+
     return property_listener.success
 
 def run_one_command(dbus_bus, descriptor, args):
@@ -144,8 +156,13 @@
     dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
 
     parser = argparse.ArgumentParser()
+    parser.add_argument('--verbose', '-v', action='store_true',
+            help="Verbose output")
     parser.add_argument('--wait', '-w', action='store_true',
             help='Block until the state transition succeeds or fails')
+    parser.add_argument('--wait-tune', '-t', nargs='?', default=8, type=float,
+            # help='Seconds to wait for journal output to complete after receiving DBus signal',
+            help=argparse.SUPPRESS)
     parser.add_argument('recipe', choices=sorted(descriptors.keys()))
     args = parser.parse_args()