Merge "XenAPI: remove xen tools"
diff --git a/.zuul.yaml b/.zuul.yaml
index a90df2f..cc29466 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -66,6 +66,7 @@
         LOGFILE: /opt/stack/logs/devstacklog.txt
         LOG_COLOR: false
         VERBOSE: true
+        VERBOSE_NO_TIMESTAMP: true
         NOVNC_FROM_PACKAGE: true
         ERROR_ON_CLONE: true
         # Gate jobs can't deal with nested virt. Disable it.
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 49cad05..1d02395 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -286,6 +286,18 @@
 
         LOG_COLOR=False
 
+When using the logfile, by default logs are sent to the console and
+the file.  You can set ``VERBOSE`` to ``false`` if you only wish the
+logs to be sent to the file (this may avoid having double-logging in
+some cases where you are capturing the script output and the log
+files).  If ``VERBOSE`` is ``true`` you can additionally set
+``VERBOSE_NO_TIMESTAMP`` to avoid timestamps being added to each
+output line sent to the console.  This can be useful in some
+situations where the console output is being captured by a runner or
+framework (e.g. Ansible) that adds its own timestamps.  Note that the
+log lines sent to the ``LOGFILE`` will still be prefixed with a
+timestamp.
+
 Logging the Service Output
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/nova b/lib/nova
index 8691c8e..d89d64e 100644
--- a/lib/nova
+++ b/lib/nova
@@ -1000,7 +1000,7 @@
         # because of the dom0/domU split. Just ignore for now.
         return
     fi
-    wait_for_compute 60
+    wait_for_compute $NOVA_READY_TIMEOUT
 }
 
 function start_nova {
diff --git a/roles/apache-logs-conf/tasks/main.yaml b/roles/apache-logs-conf/tasks/main.yaml
index bcc1353..bd64574 100644
--- a/roles/apache-logs-conf/tasks/main.yaml
+++ b/roles/apache-logs-conf/tasks/main.yaml
@@ -50,7 +50,7 @@
     with_items: "{{ redhat_apache_deref_logs.results }}"
     when:
       - item.stat.isreg or item.stat.islnk
-  when: ansible_os_family == 'Redhat'
+  when: ansible_os_family == 'RedHat'
   no_log: true
 
 - name: Ensure {{ stage_dir }}/apache_config apache_config exists
diff --git a/stack.sh b/stack.sh
index 9b496c0..1d1f12e 100755
--- a/stack.sh
+++ b/stack.sh
@@ -405,6 +405,7 @@
 
 # Set up logging level
 VERBOSE=$(trueorfalse True VERBOSE)
+VERBOSE_NO_TIMESTAMP=$(trueorfalse False VERBOSE)
 
 # Draw a spinner so the user knows something is happening
 function spinner {
@@ -470,8 +471,12 @@
     # stdout later.
     exec 3>&1
     if [[ "$VERBOSE" == "True" ]]; then
+        _of_args="-v"
+        if [[ "$VERBOSE_NO_TIMESTAMP" == "True" ]]; then
+            _of_args="$_of_args --no-timestamp"
+        fi
         # Set fd 1 and 2 to write the log file
-        exec 1> >( $TOP_DIR/tools/outfilter.py -v -o "${LOGFILE}" ) 2>&1
+        exec 1> >( $TOP_DIR/tools/outfilter.py $_of_args -o "${LOGFILE}" ) 2>&1
         # Set fd 6 to summary log file
         exec 6> >( $TOP_DIR/tools/outfilter.py -o "${SUMFILE}" )
     else
diff --git a/stackrc b/stackrc
index b7105d3..aebf152 100644
--- a/stackrc
+++ b/stackrc
@@ -813,6 +813,9 @@
 # Service startup timeout
 SERVICE_TIMEOUT=${SERVICE_TIMEOUT:-60}
 
+# Timeout for compute node registration in Nova
+NOVA_READY_TIMEOUT=${NOVA_READY_TIMEOUT:-$SERVICE_TIMEOUT}
+
 # Service graceful shutdown timeout
 SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT=${SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT:-5}
 
diff --git a/tools/outfilter.py b/tools/outfilter.py
index f82939b..cf09124 100755
--- a/tools/outfilter.py
+++ b/tools/outfilter.py
@@ -36,6 +36,13 @@
     parser.add_argument('-o', '--outfile',
                         help='Output file for content',
                         default=None)
+    # NOTE(ianw): This is intended for the case where your stdout is
+    # being captured by something like ansible which independently
+    # logs timestamps on the lines it receives.  Note that if using a
+    # output file, those log lines are still timestamped.
+    parser.add_argument('-b', '--no-timestamp', action='store_true',
+                        help='Do not prefix stdout with timestamp (bare)',
+                        default=False)
     parser.add_argument('-v', '--verbose', action='store_true',
                         default=False)
     return parser.parse_args()
@@ -50,33 +57,45 @@
     opts = get_options()
     outfile = None
     if opts.outfile:
-        outfile = open(opts.outfile, 'a', 0)
+        # note, binary mode so we can do unbuffered output.
+        outfile = open(opts.outfile, 'ab', 0)
 
     # Otherwise fileinput reprocess args as files
     sys.argv = []
-    while True:
-        line = sys.stdin.readline()
-        if not line:
-            return 0
 
+    for line in iter(sys.stdin.readline, ''):
         # put skip lines here
         if skip_line(line):
             continue
 
-        # This prevents us from nesting date lines, because
-        # we'd like to pull this in directly in Grenade and not double
-        # up on DevStack lines
+        # This prevents us from nesting date lines, because we'd like
+        # to pull this in directly in Grenade and not double up on
+        # DevStack lines.
+        # NOTE(ianw): we could actually strip the extra ts in "bare"
+        # mode (which came after this)? ... as we get more experience
+        # with zuulv3 native jobs and ansible capture it may become
+        # clearer what to do
         if HAS_DATE.search(line) is None:
             now = datetime.datetime.utcnow()
-            line = ("%s | %s" % (
+            ts_line = ("%s | %s" % (
                 now.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3],
                 line))
+        else:
+            ts_line = line
 
         if opts.verbose:
-            sys.stdout.write(line)
+            sys.stdout.write(line if opts.no_timestamp else ts_line)
             sys.stdout.flush()
+
         if outfile:
-            outfile.write(line)
+            # We've opened outfile as a binary file to get the
+            # non-buffered behaviour.  on python3, sys.stdin was
+            # opened with the system encoding and made the line into
+            # utf-8, so write the logfile out in utf-8 bytes.
+            if sys.version_info < (3,):
+                outfile.write(ts_line)
+            else:
+                outfile.write(ts_line.encode('utf-8'))
             outfile.flush()