Project

General

Profile

Actions

Bug #10260

closed

interactive-on-error doesn't stop contextutil.nested tasks, but should

Added by Dan Mick over 9 years ago. Updated over 9 years ago.

Status:
Resolved
Priority:
Normal
Assignee:
-
Category:
-
% Done:

0%

Source:
other
Tags:
Backport:
Regression:
Severity:
3 - minor
Reviewed:
Affected Versions:
ceph-qa-suite:
Crash signature (v1):
Crash signature (v2):

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.

Actions #1

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
Actions #2

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()

Actions #3

Updated by Zack Cerza over 9 years ago

I don't understand the first half of the patch. Why is that necessary?

Actions #4

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.

Actions #5

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()
Actions #6

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()

Actions

Also available in: Atom PDF