Repository navigation
Read changed hosts from the play recap, not the last task - #80
Merged
Merged
Conversation
The tree callback rewrites each host's file after every task, so _preview saw only the last task's result: a run whose recap said changed=2 was recorded changed: [], and a verify run that changed a host was recorded verified. The check preview, the execution and the verify run now read each host's ok/changed/failed/unreachable counts from a callback the SDK ships (cloudfall_host_stats), written from the play stats on v2_playbook_on_stats. The tree callback, read by nothing else and deprecated in ansible-core, is no longer enabled. The plugin directory is put ahead of the callback path the team's ansible.cfg (or the operator's environment) already names, since setting ANSIBLE_CALLBACK_PLUGINS replaces it. Replay writes the same files. Fixes #76 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_previewsorted hosts intochanged/unchangedfrom the files Ansible'streecallback leaves, but that callback rewrites each host's file after every task, so only the last task's result survived. A run whose recap saidok=5 changed=2was recordedchanged: [], and a verify run withchanged=1was recordedverified. The check preview, the execution and the verify run all went through it.cloudfall/callback_plugins/cloudfall_host_stats.py: onv2_playbook_on_statsit writes one JSON file per host with itsok,changed,failedandunreachablecounts fromstats.summarize(host)run_commandenables it (ANSIBLE_CALLBACKS_ENABLED=cloudfall_host_stats,CLOUDFALL_HOST_STATS_DIR=<per-run dir>) and setsANSIBLE_CALLBACK_PLUGINSto the plugin's directory followed by the callback path Ansible would otherwise use (the operator's env, else the team'sansible.cfgwith relative entries resolved against it, else Ansible's default), read in process withConfigManagerincloudfall.ansible_api. Ansible has no append form for this variable, so this is how the team'scallback_pluginsis kept_previewmarks a hostchangedwhen itschangedcount is above 0, and fails fast (decision_host_stats_invalid) on a file without an integer count. The record schema is unchangedtreecallback is dropped: nothing else in sdk/, engine/, demo/, evaluations/ or docs/ reads it, and ansible-core deprecates it (removal in 2.23). The per-run directory moves fromdecisions/tree/<id>todecisions/host-stats/<id>recording._write_host_stats) writes the same files: a recorded changed host asok=1 changed=1, an unchanged one asok=1 changed=0. Recordings underexamples/anddemo/are untouchedPlaybookInvocation.treeis renamedhost_statsRecords already carrying wrong values are out of scope (see #77).
Test plan
sdk/tests/test_host_stats.pyansible-playbookonlocalhost(the suite already does this): a two-task playbook whose first task changes and whose last reports ok is recordedchangedin the check preview, the execution and the verify step, and the decision endsfailed, notverifiedcallback_loader, on anAggregateStatsbuilt in the testrun_commandkeeps the team'scallback_pluginsafter the plugin directory and no longer sets the tree variablestest_decision.pynow writes recap countsuv sync,uv run ruff check .,uv run mypy,uv run pytest(523 passed),uv run cloudfall config validate --project config/examplesall pass; nothing underengine/ansiblechanged.uv build --wheellistscloudfall/callback_plugins/cloudfall_host_stats.pyFixes #76
🤖 Generated with Claude Code