stderr) or info messages (from stdout).
"""
- def __init__(self, client, logger, func):
+ def __init__(self, client, logger, func, mangle_exc=True):
self.client = client
self.logger = logger
self.func = func
+ self.mangle_exc = mangle_exc
def __enter__(self):
self.stdout = self.client.modules.sys.stdout
# leave everything as it was
self.client.modules.sys.stdout = self.stdout
self.client.modules.sys.stdout = self.stderr
+ if not self.mangle_exc:
+ return False
if e_type is not None:
if hasattr(e_val, 'remote_traceback'):
self.logger.error(line)
return True # So that we eat up the traceback
else:
- raise e_type(e_val)
+ raise e_type
def write_log(self, lines, log_level):
logger = getattr(self.logger, log_level)
Wraps ``subprocess.check_call`` for a remote call via ``pushy``
doing all the capturing and logging nicely upon failure/success
+ The mangling of the traceback when an exception ocurrs, is because the
+ caller gets eating up by not being executed in the actual function of
+ a given module (e.g. ``centos/install.py``) but rather here, where the
+ stack trace is no longer relevant.
+
:param args: The args to be passed onto ``check_call``
"""
command = ' '.join(args)
**kw
)
- with context.remote(conn, logger, remote_call) as call:
- return call(args, *a, **kw)
+ with context.remote(conn, logger, remote_call, mangle_exc=False) as call:
+ try:
+ return call(args, *a, **kw)
+ except Exception as err:
+ import inspect
+ stack = inspect.getframeinfo(inspect.currentframe().f_back)
+ if hasattr(err, 'remote_traceback'):
+ logger.error('Traceback (most recent call last):')
+ logger.error(' File "%s", line %s, in %s' % (
+ stack[0],
+ stack[1],
+ stack[2])
+ )
+ err.remote_traceback.pop(0)
+ for line in err.remote_traceback:
+ if line:
+ logger.error(line)
+ else:
+ raise err