diff --git a/awx/lib/awx_display_callback/module.py b/awx/lib/awx_display_callback/module.py index f9249e25e1..0bb0099bdd 100644 --- a/awx/lib/awx_display_callback/module.py +++ b/awx/lib/awx_display_callback/module.py @@ -69,6 +69,9 @@ class BaseCallbackModule(CallbackBase): self.task_uuids = set() self.duplicate_task_counts = collections.defaultdict(lambda: 1) + self.play_uuids = set() + self.duplicate_play_counts = collections.defaultdict(lambda: 1) + @contextlib.contextmanager def capture_event_data(self, event, **event_data): event_data.setdefault('uuid', str(uuid.uuid4())) @@ -195,6 +198,24 @@ class BaseCallbackModule(CallbackBase): super(BaseCallbackModule, self).v2_playbook_on_include(included_file) def v2_playbook_on_play_start(self, play): + play_uuid = str(play._uuid) + if play_uuid in self.play_uuids: + # When this play UUID repeats, it means the play is using the + # free strategy (or serial:1) so different hosts may be running + # different tasks within a play (where duplicate UUIDS are common). + # + # When this is the case, modify the UUID slightly to append + # a counter so we can still _track_ duplicate events, but also + # avoid breaking the display in these scenarios. + self.duplicate_play_counts[play_uuid] += 1 + + play_uuid = '_'.join([ + play_uuid, + str(self.duplicate_play_counts[play_uuid]) + ]) + self.play_uuids.add(play_uuid) + play._uuid = play_uuid + self.set_play(play) if hasattr(play, 'hosts'): if isinstance(play.hosts, list):