Surface Compose stdout on failure

Signed-off-by: Chris Houseknecht <chouseknecht@ansible.com>
reviewable/pr18780/r1
Chris Houseknecht 8 years ago
parent fba5883dd1
commit 0156cb942e

@ -452,6 +452,9 @@ HAS_COMPOSE = True
HAS_COMPOSE_EXC = None HAS_COMPOSE_EXC = None
MINIMUM_COMPOSE_VERSION = '1.7.0' MINIMUM_COMPOSE_VERSION = '1.7.0'
import sys
import re
try: try:
import yaml import yaml
except ImportError as exc: except ImportError as exc:
@ -463,6 +466,7 @@ from ansible.module_utils.basic import *
try: try:
from compose import __version__ as compose_version from compose import __version__ as compose_version
from compose.project import ProjectError
from compose.cli.command import project_from_options from compose.cli.command import project_from_options
from compose.service import ConvergenceStrategy, NoSuchImageError from compose.service import ConvergenceStrategy, NoSuchImageError
from compose.cli.main import convergence_strategy_from_opts, build_action_from_opts, image_type_from_opt from compose.cli.main import convergence_strategy_from_opts, build_action_from_opts, image_type_from_opt
@ -473,6 +477,7 @@ except ImportError as exc:
DEFAULT_TIMEOUT = 10 DEFAULT_TIMEOUT = 10
from ansible.module_utils.docker_common import * from ansible.module_utils.docker_common import *
from contextlib import contextmanager
AUTH_PARAM_MAPPING = { AUTH_PARAM_MAPPING = {
@ -484,7 +489,32 @@ AUTH_PARAM_MAPPING = {
u'tls_verify': u'--tlsverify' u'tls_verify': u'--tlsverify'
} }
@contextmanager
def stdout_redirector(path_name):
old_stdout = sys.stdout
fd = open(path_name, 'w')
sys.stdout = fd
try:
yield
finally:
sys.stdout = old_stdout
def get_stdout(path_name):
full_stdout = ''
last_line = ''
with open(path_name, 'r') as fd:
for line in fd:
# strip terminal format/color chars
new_line = re.sub(r'\x1b\[.+m', '', line.encode('ascii'))
full_stdout += new_line
if new_line.strip():
# Assuming last line contains the error message
last_line = new_line.strip().encode('utf-8')
fd.close()
os.remove(path_name)
return full_stdout, last_line
class ContainerManager(DockerBaseClass): class ContainerManager(DockerBaseClass):
def __init__(self, client): def __init__(self, client):
@ -649,19 +679,25 @@ class ContainerManager(DockerBaseClass):
result['actions'].append(result_action) result['actions'].append(result_action)
if not self.check_mode and result['changed']: if not self.check_mode and result['changed']:
_, fd_name = tempfile.mkstemp(prefix="ansible")
try: try:
do_build = build_action_from_opts(up_options) with stdout_redirector(fd_name):
self.log('Setting do_build to %s' % do_build) do_build = build_action_from_opts(up_options)
self.project.up( self.log('Setting do_build to %s' % do_build)
service_names=service_names, self.project.up(
start_deps=start_deps, service_names=service_names,
strategy=converge, start_deps=start_deps,
do_build=do_build, strategy=converge,
detached=detached, do_build=do_build,
remove_orphans=self.remove_orphans, detached=detached,
timeout=self.timeout) remove_orphans=self.remove_orphans,
timeout=self.timeout)
except Exception as exc: except Exception as exc:
self.client.fail("Error starting project - %s" % str(exc)) full_stdout, last_line= get_stdout(fd_name)
self.client.module.fail_json(msg="Error starting project %s" % str(exc), module_stderr=last_line,
module_stdout=full_stdout)
else:
get_stdout(fd_name)
if self.stopped: if self.stopped:
stop_output = self.cmd_stop(service_names) stop_output = self.cmd_stop(service_names)
@ -863,13 +899,17 @@ class ContainerManager(DockerBaseClass):
short_id=container.short_id short_id=container.short_id
)) ))
result['actions'].append(service_res) result['actions'].append(service_res)
if not self.check_mode and result['changed']: if not self.check_mode and result['changed']:
_, fd_name = tempfile.mkstemp(prefix="ansible")
try: try:
self.project.stop(service_names=service_names, timeout=self.timeout) with stdout_redirector(fd_name):
self.project.stop(service_names=service_names, timeout=self.timeout)
except Exception as exc: except Exception as exc:
self.client.fail("Error stopping services for %s - %s" % (self.project.name, str(exc))) full_stdout, last_line = get_stdout(fd_name)
self.client.module.fail_json(msg="Error stopping project %s" % str(exc), module_stderr=last_line,
module_stdout=full_stdout)
else:
get_stdout(fd_name)
return result return result
def cmd_restart(self, service_names): def cmd_restart(self, service_names):
@ -894,11 +934,16 @@ class ContainerManager(DockerBaseClass):
result['actions'].append(service_res) result['actions'].append(service_res)
if not self.check_mode and result['changed']: if not self.check_mode and result['changed']:
_, fd_name = tempfile.mkstemp(prefix="ansible")
try: try:
self.project.restart(service_names=service_names, timeout=self.timeout) with stdout_redirector(fd_name):
self.project.restart(service_names=service_names, timeout=self.timeout)
except Exception as exc: except Exception as exc:
self.client.fail("Error restarting services for %s - %s" % (self.project.name, str(exc))) full_stdout, last_line = get_stdout(fd_name)
self.client.module.fail_json(msg="Error restarting project %s" % str(exc), module_stderr=last_line,
module_stdout=full_stdout)
else:
get_stdout(fd_name)
return result return result
def cmd_scale(self): def cmd_scale(self):
@ -906,7 +951,6 @@ class ContainerManager(DockerBaseClass):
changed=False, changed=False,
actions=[] actions=[]
) )
for service in self.project.services: for service in self.project.services:
if service.name in self.scale: if service.name in self.scale:
service_res = dict( service_res = dict(

Loading…
Cancel
Save