Bug #10260
closedinteractive-on-error doesn't stop contextutil.nested tasks, but should
0%
Description
With a standard-idiom set of subtasks inside one task, if any of them fail, all the preceding tasks' finally clauses (exit handlers) will be run before the master "run_tasks" gets control and implements the interactive-on-error.
I think, as Josh suggests, that contextutil.nested() should also implement the interactive-on-error test/REPL invocation.
Updated by Dan Mick over 9 years ago
- Subject changed from interactive-on-error doesn't apply to contextutil.nested to interactive-on-error doesn't stop contextutil.nested tasks, but should
Updated by Dan Mick over 9 years ago
This repulsive hack works, and avoids changing every nested() call, just to demonstrate the point:
--- a/teuthology/contextutil.py +++ b/teuthology/contextutil.py @@ -19,6 +19,10 @@ def nested(*managers): exits = [] vars = [] exc = (None, None, None) + ctx = None + if not callable(managers[0]): + ctx = managers[0] + managers = managers[1:] try: for mgr_fn in managers: mgr = mgr_fn() @@ -30,6 +34,10 @@ def nested(*managers): except Exception: log.exception('Saw exception from nested tasks') exc = sys.exc_info() + if ctx and ctx.config.get('interactive-on-error'): + from .task import interactive + log.warning('Saw failure, going into interactive mode...') + interactive.task(ctx=ctx, config=None) finally: while exits: exit = exits.pop()
Updated by Zack Cerza over 9 years ago
I don't understand the first half of the patch. Why is that necessary?
Updated by Dan Mick over 9 years ago
As we discussed: we need to get at the job config somehow; this is a hack because it tunnels 'ctx' as a manager, and then extracts it, because managers must be callables, but ctx is not.
Some other way to access per-job config is in Zack's mind at the moment, but the obvious way to stick with the current structure more cleanly is to add a first 'ctx' param to all the nested() callers.
Updated by Dan Mick over 9 years ago
Zack suggested (maybe, if I understood correctly) something like
--- a/teuthology/run.py +++ b/teuthology/run.py @@ -187,6 +187,10 @@ def main(ctx): fetch_tasks_if_needed(ctx.config) + # store on global config + if ctx.config['interactive-on-error']: + teuthology.config.config.interactive_on_error = True + try: run_tasks(tasks=ctx.config['tasks'], ctx=ctx) finally:
and then we could do
--- a/teuthology/contextutil.py +++ b/teuthology/contextutil.py @@ -3,6 +3,7 @@ import sys import logging import time import itertools +from teuthology.config import config log = logging.getLogger(__name__) @@ -30,6 +31,10 @@ def nested(*managers): except Exception: log.exception('Saw exception from nested tasks') exc = sys.exc_info() + if config.interactive_on_error: + from .task import interactive + log.warning('Saw failure, going into interactive mode...') + interactive.task(ctx=ctx, config=None) finally: while exits: exit = exits.pop()
Updated by Dan Mick over 9 years ago
....but of course in this case one still needs the actual ctx for the call to interactive.task()
Updated by Dan Mick over 9 years ago
- Status changed from New to Resolved