@ -24,6 +24,7 @@ import fnmatch
from ansible . compat . six import iteritems
from ansible import constants as C
from ansible . errors import AnsibleError
from ansible . module_utils . six import cmp
from ansible . playbook . block import Block
from ansible . playbook . task import Task
from ansible . playbook . role_include import IncludeRole
@ -48,6 +49,7 @@ class HostState:
self . cur_rescue_task = 0
self . cur_always_task = 0
self . cur_role = None
self . cur_role_task = None
self . cur_dep_chain = None
self . run_state = PlayIterator . ITERATING_SETUP
self . fail_state = PlayIterator . FAILED_NONE
@ -120,6 +122,8 @@ class HostState:
new_state . cur_rescue_task = self . cur_rescue_task
new_state . cur_always_task = self . cur_always_task
new_state . cur_role = self . cur_role
if self . cur_role_task :
new_state . cur_role_task = self . cur_role_task [ : ]
new_state . run_state = self . run_state
new_state . fail_state = self . fail_state
new_state . pending_setup = self . pending_setup
@ -276,12 +280,53 @@ class PlayIterator:
parent = parent . _parent
return False
def _get_cur_task ( s , depth = 0 ) :
res = [ s . run_state , depth , s . cur_block , - 1 ]
if s . run_state == self . ITERATING_TASKS :
if s . tasks_child_state :
res = _get_cur_task ( s . tasks_child_state , depth = depth + 1 )
else :
res [ - 1 ] = s . cur_regular_task
elif s . run_state == self . ITERATING_RESCUE :
if s . rescue_child_state :
res = _get_cur_task ( s . rescue_child_state , depth = depth + 1 )
else :
res [ - 1 ] = s . cur_rescue_task
elif s . run_state == self . ITERATING_ALWAYS :
if s . always_child_state :
res = _get_cur_task ( s . always_child_state , depth = depth + 1 )
else :
res [ - 1 ] = s . cur_always_task
return res
def _role_task_cmp ( s ) :
'''
tt is a tuple made of the regular / rescue / always task number
from the current state of the host .
'''
if not s . cur_role_task :
return 1
cur_task = _get_cur_task ( s )
res = cmp ( cur_task [ 0 ] , s . cur_role_task [ 0 ] )
if res == 0 :
res = cmp ( cur_task [ 1 ] , s . cur_role_task [ 1 ] )
if res == 0 :
res = cmp ( cur_task [ 2 ] , s . cur_role_task [ 2 ] )
if res == 0 :
res = cmp ( cur_task [ 3 ] , s . cur_role_task [ 3 ] )
return res
if task and task . _role :
# if we had a current role, mark that role as completed
if s . cur_role and _roles_are_different ( task . _role , s . cur_role ) and host . name in s . cur_role . _had_task_run and \
not _role_is_child ( s . cur_role ) and not peek :
s . cur_role . _completed [ host . name ] = True
if s . cur_role :
role_diff = _roles_are_different ( task . _role , s . cur_role )
role_child = _role_is_child ( s . cur_role )
tasks_cmp = _role_task_cmp ( s )
host_done = host . name in s . cur_role . _had_task_run
if ( role_diff or ( not role_diff and tasks_cmp < = 0 ) ) and host_done and not role_child and not peek :
s . cur_role . _completed [ host . name ] = True
s . cur_role = task . _role
s . cur_role_task = _get_cur_task ( s )
s . cur_dep_chain = task . get_dep_chain ( )
if not peek :