Fixes #36353 - Route Ansible task output per host - #117
Conversation
Buffer task headings until host events identify the targets so unrelated role tasks are not broadcast to every host. Assisted-By: Codex 5.6 Sol High
adamruzicka
left a comment
There was a problem hiding this comment.
The general idea seems to be sound. I have some time off coming up and I probably won't have time to properly test this properly.
What I'd like to see tested, even if just manually:
- a playbook with many hosts, where some plays (or just tasks) are scoped to specific hosts
- a playbook with many hosts and strategy: free
- a playbook with many hosts and strategy: serial 1
- a playbook where a task loops
- a playbook where a task delegates to a different host
| @task_outputs[task_uuid] = { | ||
| 'stdout' => event['stdout'], | ||
| 'uuid' => event['uuid'], | ||
| 'created' => event['created'] | ||
| } |
There was a problem hiding this comment.
| @task_outputs[task_uuid] = { | |
| 'stdout' => event['stdout'], | |
| 'uuid' => event['uuid'], | |
| 'created' => event['created'] | |
| } | |
| @task_outputs[task_uuid] = event.slice('stdout', 'uuid', 'created') |
There was a problem hiding this comment.
Okay, thanks. I've used event.slice in the follow-up commit.
| task_output = @task_outputs&.fetch(task_uuid, nil) | ||
| return unless task_output | ||
|
|
||
| @published_task_outputs ||= {} |
There was a problem hiding this comment.
nitpick: This could be a Set
There was a problem hiding this comment.
Okay, thanks. A Set makes sense here, so I've switched it over.
| if event['event'] == 'playbook_on_task_start' && remember_task_output(event) | ||
| # The following host events identify which hosts this task applies to. |
There was a problem hiding this comment.
This is a slightly clunky construct, could we split it into two? One function that would check if there is something to be remembered and then another one to actually do the remembering that would be called in the body?
There was a problem hiding this comment.
Thanks, that makes sense. I've split the predicate from remember_task_output in the follow-up commit.
|
Thanks for the suggested test cases. I tested this with These cases behaved as expected:
instead of one task heading per host. The same pattern affects I'll update the implementation to keep the task pending, capture the banner from the first host result, and publish it for the remaining matching hosts, with regression tests for both cases. |
|
I reran the requested scenarios against The After routing, the per-host output was: Loops emitted the heading once per participating host, and delegated results stayed attributed to the original hosts ( |
Capture task and handler headings from the first host result when free strategy task-start events contain no output. Assisted-By: Codex 5.6 Sol High
Summary
Fixes #36353.
Ansible emits
playbook_on_task_startwithout a host and follows it with host-specific events carrying the sametask_uuid. The runner broadcast every task heading immediately, so a role task that only ran on host A was also shown in host B's job details.Keep task headings until the subsequent host event identifies each actual target. Publish the heading once for each host that runs or skips the task, followed by that host's result output. Non-task global events and the per-host exit status handling remain unchanged.
Add a focused event-sequence test that verifies the task heading is not broadcast and is published only once for the participating host.
Testing
AI usage disclosure
Per the community discussion on AI policy, the issue was investigated and the changes, tests, and PR wording were prepared with the assistance of Codex 5.6 Sol High. The resulting changes were reviewed before submitting. The commit also includes an
Assisted-Bytrailer.