use StringIO for output concatenation, minor other tweaks to previous commit

This commit is contained in:
Michael DeHaan 2012-08-11 11:59:14 -04:00
parent 3cc564c127
commit 301edb5b52

View file

@ -28,6 +28,7 @@ from ansible import errors
from ansible import __version__ from ansible import __version__
import ansible.constants as C import ansible.constants as C
import time import time
import StringIO
VERBOSITY=0 VERBOSITY=0
@ -120,6 +121,7 @@ def json_loads(data):
def parse_json(raw_data): def parse_json(raw_data):
''' this version for module return data only ''' ''' this version for module return data only '''
# ignore stuff like tcgetattr spewage or other warnings
data = filter_leading_non_json_lines(raw_data) data = filter_leading_non_json_lines(raw_data)
try: try:
@ -417,29 +419,30 @@ def do_encrypt(result, encrypt, salt_size=None, salt=None):
return result return result
def last_non_blank_line(lines): def last_non_blank_line(buf):
all_lines = lines.splitlines()
all_lines = buf.splitlines()
all_lines.reverse() all_lines.reverse()
for line in all_lines: for line in all_lines:
if (len(line) > 0): if (len(line) > 0):
return line return line
# shouldn't occur unless there's no output
return ""
return "" # we shouldn't come here (no lines?) but let's pretend nothing happend def filter_leading_non_json_lines(buf):
# We can't return all lines here because calling code expects only one '''
# line. And since we don't know which line to return we return an empty used to avoid random output from SSH at the top of JSON output, like messages from
# line. tcagetattr, or where dropbear spews MOTD on every single command (which is nuts).
need to filter anything which starts not with '{', '[', ', '=' or is an empty line.
filter only leading lines since multiline JSON is valid.
'''
def is_valid_json_line(line): filtered_lines = StringIO.StringIO()
return line.startswith('=') or line.startswith('{') or line.startswith('[') stop_filtering = False
for line in buf.splitlines():
def filter_leading_non_json_lines(lines): if stop_filtering or "=" in line or line.startswith('{') or line.startswith('['):
''' we need to filter anything which starts not with '{', '[', ', '=' or is an empty line. stop_filtering = True
But we filter only leading lines since multiline JSON is valid. ''' filtered_lines.write(line + '\n')
filtered_lines = '' return filtered_lines.getvalue()
no_more_filtering = False
for line in lines.splitlines():
if (no_more_filtering or is_valid_json_line(line)):
no_more_filtering = True
filtered_lines += line + '\n'
return filtered_lines