Skip to content

Add automatic ascender_stats_* job artifacts (changed/failed flags and host lists)#562

Open
fernandorocagonzalez wants to merge 2 commits into
ctrliq:mainfrom
fernandorocagonzalez:feat-505-auto-stats
Open

Add automatic ascender_stats_* job artifacts (changed/failed flags and host lists)#562
fernandorocagonzalez wants to merge 2 commits into
ctrliq:mainfrom
fernandorocagonzalez:feat-505-auto-stats

Conversation

@fernandorocagonzalez

@fernandorocagonzalez fernandorocagonzalez commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Related to #505, where @cigamit asked for a "Changed" connector ("only traverses the path if something reported as changed in the playbook before it, or maybe only the hosts that reported as change traverse"). Complementary to #561.

Every finished playbook job (jobs launched from job templates; project updates, inventory syncs and ad hoc commands are not affected) now automatically contributes a set of ascender_stats_* keys to its artifacts, computed from the final playbook_on_stats event — no set_stats needed in the playbook:

Key Value
ascender_stats_changed true when any host reported a change
ascender_stats_failed true when any host failed or was unreachable
ascender_stats_changed_hosts / ascender_stats_non_changed_hosts sorted host name lists
ascender_stats_failed_hosts / ascender_stats_non_failed_hosts sorted host name lists
ascender_stats_hosts_truncated true when the host lists were omitted (see below)

Because these are regular artifacts, everything that already works for set_stats data works for them:

Configuration

  • ASCENDER_AUTO_STATS_ENABLED (default true): master switch, exposed in the settings API (Jobs category).
  • ASCENDER_AUTO_STATS_MAX_HOSTS (default 100): when a play involves more hosts than this, the four host name lists are omitted (and ascender_stats_hosts_truncated set) so artifacts stay small as they accumulate through ancestor_artifacts in long workflows; the boolean flags are always kept.

Both can be overridden per job or per workflow with extra variables of the same name (workflow extra vars reach every spawned job), e.g. disable the feature for one noisy workflow, or raise the host cap only where the lists are needed. A negative ASCENDER_AUTO_STATS_MAX_HOSTS override through extra vars is ignored in favor of the setting, which is itself validated with min_value=0.

Implementation notes

  • Single write point in RunnerCallback.event_handler: the automatic keys are merged into the same delay_update(artifacts=...) used for set_stats data, so there is no second writer racing on the artifacts field. Keys set by the playbook via set_stats always win on collision, and _ansible_no_log redaction is unaffected.
  • "Failed" matches the existing job event semantics (failures + dark), the same computation JobHostSummary is built from.
  • The extra-vars override is resolved once per job at the stats event — the per-event hot path (the "danger zone" warned about in event_handler) is untouched.
  • Only playbook jobs produce these keys (not project/inventory updates or ad hoc commands).
  • When artifacts of sibling jobs are aggregated (slices of a sliced job template, nodes of a nested workflow, parents converging into one child), the ascender_stats_* keys are merged instead of last writer wins: booleans get OR-ed and the host lists unioned, so a failed host reported by slice 1 is still visible after a clean slice 2 finishes. If any side was truncated the merged lists are dropped. All other artifact keys keep the usual update semantics.

Test plan

  • 13 new unit tests in test_runner_callback.py: stats computation, truncation, enable/cap resolution (setting vs extra var, string coercion, negative override), set_stats precedence on merge, non-job callbacks unaffected.
  • 5 new unit tests in test_workflow_unit.py for the sibling merge (boolean OR, host list union, truncation, one-sided keys, plain keys untouched).
  • Existing suites pass: unit tasks/, functional api/test_settings.py (one pre-existing failure on main unrelated to this change), models/test_job.py, models/test_workflow.py, awx/conf/tests.
  • flake8 + black clean.

@cigamit cigamit self-assigned this Jul 3, 2026
@cigamit cigamit added the enhancement New feature or request label Jul 3, 2026
@cigamit cigamit requested a review from Copilot July 3, 2026 23:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds automatic awx_stats_* job artifacts derived from the final playbook_on_stats event so downstream workflow nodes (and conditional connectors) can branch on “changed/failed” outcomes and (optionally) per-host lists without requiring set_stats in playbooks.

Changes:

  • Compute and merge automatic awx_stats_* artifacts on playbook_on_stats, with set_stats values taking precedence on key collisions.
  • Introduce settings/API configuration for enabling the feature and capping host list size (AWX_ENABLE_TEMPLATE_STATS, AWX_AUTO_STATS_MAX_HOSTS), plus per-job/workflow extra-var overrides.
  • Add unit tests and workflow documentation describing the new artifacts and settings.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docs/workflow.md Documents the new automatic awx_stats_* artifacts and how they propagate through workflows.
awx/settings/defaults.py Adds default values for AWX_ENABLE_TEMPLATE_STATS and AWX_AUTO_STATS_MAX_HOSTS.
awx/main/tests/unit/tasks/test_runner_callback.py Adds unit tests for stats artifact computation, truncation behavior, enable/disable logic, and merge precedence.
awx/main/tasks/callback.py Implements stats artifact computation and merge into job artifacts during playbook_on_stats.
awx/main/conf.py Exposes the new settings via the settings registry (Jobs category) with labels/help text.

Comment thread awx/main/tasks/callback.py
Comment thread docs/workflow.md Outdated
Comment thread awx/main/conf.py Outdated
@cigamit

cigamit commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Just an FYI, new variable names should probably include ascender instead of awx. Eventually its on the roadmap to change the name of most of the variables to expunge the awx name completely from the codebase.

@fernandorocagonzalez

Copy link
Copy Markdown
Contributor Author

Yes that was something I thought, since I saw there was already an ongoing effort to change references but was unsure. Will do

Every finished playbook job (jobs launched from job templates; project
updates, inventory syncs and ad hoc commands are not affected) now
automatically contributes a set of ascender_stats_* keys to its
artifacts, computed from the final playbook_on_stats event without
requiring set_stats in the playbook:

- ascender_stats_changed / ascender_stats_failed booleans (failed
  includes unreachable hosts, matching the job event semantics)
- ascender_stats_changed_hosts / ascender_stats_non_changed_hosts /
  ascender_stats_failed_hosts / ascender_stats_non_failed_hosts sorted
  host lists
- ascender_stats_hosts_truncated, set when the play involved more hosts
  than ASCENDER_AUTO_STATS_MAX_HOSTS (default 100), in which case the
  host lists are omitted so artifacts stay small as they propagate
  through workflows; the boolean flags are always kept

Since these are regular artifacts, they propagate to descendant
workflow nodes as extra vars and can drive conditional workflow
connectors (requested in ctrliq#505: traverse a path only when the previous
job reported changes). Keys set by the playbook via set_stats win over
the automatic ones on collision, and _ansible_no_log redaction is
unaffected.

The feature is gated by the ASCENDER_AUTO_STATS_ENABLED setting
(default true); both settings are exposed in the settings API (Jobs
category) and can be overridden per job or per workflow with extra
variables of the same name, resolved at the single per-job stats event
so the event handler hot path is untouched. A negative max hosts
override through extra vars is ignored in favor of the setting, which
is itself validated with min_value=0.
Every playbook job now emits the same ascender_stats_* key names, so
aggregating artifacts with plain dict.update() let the last finished
sibling mask the others: with a sliced job template, a failed host
reported by slice 1 disappeared if slice 2 finished clean afterwards,
so a conditional connector on ascender_stats_failed would not fire and
the per-host lists passed downstream were wrong. The same applied to
nested workflows and to several parents converging into one child.

The ascender_stats_* keys are now merged where sibling artifacts meet
(WorkflowJob.get_effective_artifacts and the ancestor artifacts built
in get_job_kwargs): booleans are OR-ed and the host lists unioned,
with truncation on any side dropping the merged lists. Everything
else keeps last-writer-wins, and within a single branch a node's own
output still supersedes what it inherited.
@fernandorocagonzalez fernandorocagonzalez changed the title Add automatic awx_stats_* job artifacts (changed/failed flags and host lists) Add automatic ascender_stats_* job artifacts (changed/failed flags and host lists) Jul 4, 2026
@fernandorocagonzalez

Copy link
Copy Markdown
Contributor Author

Done. All the new names now use the ascender prefix: the artifact keys are ascender_stats_* and the two settings are ASCENDER_AUTO_STATS_ENABLED (renamed from the old AWX_ENABLE_TEMPLATE_STATS, which was a poor name anyway since it had nothing to do with templates) and ASCENDER_AUTO_STATS_MAX_HOSTS. Existing AWX_* settings elsewhere in the codebase are untouched.

While at it I also addressed the review remarks: a negative ASCENDER_AUTO_STATS_MAX_HOSTS passed through extra vars is now ignored in favor of the validated setting (with tests for the negative and zero cases), and the docs plus the settings help text now say explicitly that only playbook jobs produce these keys (project updates, inventory syncs and ad hoc commands don't). Branch rewritten accordingly, unit tests, flake8 and black all green.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Development

Successfully merging this pull request may close these issues.

3 participants