zuul/zuul
Ian Wienand 9462c9e466 zuul_console: fix python 3 support
send() requires a bytes-like object in Python 3, ensure the error
message is encoded correctly.

---

Some debugging notes might come in handy for the future here.  This
problem appeared in a fairly specific part of the test cases when
setting "ansible_python_interpreter" to /usr/bin/python3.  The remote
streaming test has a task that is designed to fail [1]:

 - hosts: all
   tasks:
     - name: Remote shell task with python exception
       command: echo foo
       args:
         chdir: /remote-shelltask/somewhere/that/does/not/exist
       failed_when: false

We see that Ansible ships over a payload and tries to run it, but it
raises an exception very early.

 <192.168.122.1> SSH: EXEC ssh -C ...  '/bin/sh -c '"'"'/usr/bin/python3 && sleep 0'"'"''
 <192.168.122.1> Failed to connect to the host via ssh:
 Traceback (most recent call last):
   File "<stdin>", line 114, in <module>
   File "<stdin>", line 106, in _ansiballz_main
   ...
   File "/tmp/ansible_command_payload_tieedyzs/__main__.py", line 263, in main
 FileNotFoundError: [Errno 2] No such file or directory: '/remote-shelltask/somewhere/that/does/not/exist'

When this task started, the Ansible task callbacks in the zuul_stream
callback plugin have setup a thread that listens for the console
output being sent by the remote zuul_console daemon started earlier in
the playbook [2].  This listening thread is sitting in a recv()
waiting for some streaming data to log [3].

There will be no remote log file for zuul_console to stream back,
because this task failed before it even got started.  What should
happen is the "[Zuul] Log not found" message should be sent back and
logic in [4] will match this and stop this thread.

When this does *not* happen, such as when this send() raises an
exception because of wrong data type, the task ends anyway and Ansible
moves on to make the end-of-task callbacks in zuul_stream (actually
there's a bunch of looping happening, but let's ignore those details).
This ends up in _stop_streamers() [5] which attempts to join(30) the
streaming thread.  Under normal circumstances, this thread should be
finished and the join() successful.  However, because the target
thread is stuck in a recv(), the 30-second timeout begins.  The clue
to this is in the logs you eventually get:

 [Zuul] Log Stream did not terminate

So eventually, Zuul would have made progress here and given up on
waiting for the thread to finish properly.  However, 30 seconds is a
long time to the unit-test and pushes the job over it's timeout.

Thus your end result is that when using Python 3 Zuul aborts the job,
and the test rather mysteriously fails!

[1] 3f8b36aa0b/tests/fixtures/config/remote-zuul-stream/git/org_project/playbooks/command.yaml (L93)
[2] 3f8b36aa0b/tests/fixtures/config/remote-zuul-stream/git/org_project/playbooks/command.yaml (L93)
[3] 3f8b36aa0b/zuul/ansible/base/callback/zuul_stream.py (L14)
[4] 3f8b36aa0b/zuul/ansible/base/callback/zuul_stream.py (L174)
[5] 3f8b36aa0b/zuul/ansible/base/callback/zuul_stream.py (L271)

This is tested in the follow-on I2b3bc6d4f873b7d653cfaccd1598464583c561e7

Change-Id: I7cdcfc760975871f7fa9949da1015d7cec92ee67
2019-09-18 13:58:45 +10:00
..
ansible zuul_console: fix python 3 support 2019-09-18 13:58:45 +10:00
cmd Use a requests session to simplify auth'd calls 2019-08-01 19:40:37 +00:00
connection Annotate some logs in the scheduler with event id 2019-05-17 06:06:11 +02:00
driver Merge "Better error handling for the PagureAPIClient" 2019-09-16 11:35:31 +00:00
execution_context Add wrapper driver execution context 2017-08-18 16:35:12 -07:00
executor Pass zuul_success to cleanup playbooks 2019-09-11 10:20:50 -07:00
lib Update ara to >=0.16.5 to support ansible 2.8 2019-08-06 16:48:49 -07:00
manager manager: specify report failure in logs 2019-08-20 06:44:56 -07:00
merger Check refs and revs for repo needing updates 2019-08-27 09:56:48 -07:00
reporter Add support for item.change for pipeline start-message formater 2019-06-20 16:42:40 +02:00
source Annotate canMerge check with event id 2019-07-12 12:34:57 +02:00
sphinx Add zuul-sphinx as a requirement 2017-08-07 14:56:17 -07:00
trigger Annotate logs in the zuul driver with event ids 2019-05-17 06:06:11 +02:00
web Provide buildset.uuid in /builds API result 2019-08-06 10:50:18 +02:00
__init__.py Initial commit. 2012-05-29 14:49:32 -07:00
_setup_hook.py Revert "Create zuul/web/static on demand" 2019-06-04 09:57:04 -07:00
change_matcher.py Fix wrong matched project template 2018-08-02 12:19:15 +02:00
configloader.py Add option to report build page 2019-08-08 09:46:53 -07:00
exceptions.py web: add tenant and project scoped, JWT-protected actions 2019-07-10 12:11:14 +02:00
model.py Annotate QueueItem logger 2019-08-23 15:29:58 +02:00
nodepool.py Annotate logs around finished builds 2019-05-30 19:21:31 +02:00
rpcclient.py Zuul CLI: allow access via REST 2019-07-30 10:46:17 +02:00
rpclistener.py Web: plug the authorization engine 2019-07-30 15:32:31 +00:00
scheduler.py Add option to report build page 2019-08-08 09:46:53 -07:00
version.py Report git sha in status page version 2018-04-27 10:21:43 -07:00
zk.py Ensure correct lexical sorting of node requests 2019-03-14 15:39:23 +01:00