mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-11 21:26:44 +00:00
Cache key was just the absolute path, so every read after the first returned a cached dict regardless of subsequent file rewrites. The assumption "the file does not change while my process runs" held for short-lived CLI tools but not for an Ansible play, where roles like sys-token-store rewrite tokens.yml multiple times via the `copy:` module (a path the in-process Python cache cannot observe). Two seemingly unrelated regressions traced back to the same stale cache: * sys-svc-mail's "Mailu was preloaded" assertion read users.no-reply via a stale tokens.yml and aborted the play with `failed=1`. * sys-front-inj-matomo disabled `inj_enabled.matomo` for every domain whose Domain-Config-Phase ran after the matomo bootstrap had persisted users.administrator.tokens['web-app-matomo'] but before the cache could see the new mtime, dropping the matomo.js script from those pages. Switch the cache key to `(path, st_mtime_ns, st_size)` so an out-of-band `copy:` write surfaces on the very next read in the same process. Stale entries for the same path are evicted on miss to keep the cache bounded under repeated rewrites. Per-hit cost adds two stat() calls (sub-µs each on a warm inode); negligible compared to the YAML parse it short-circuits. Verified: dashboard "matomo tracking assets" Playwright test went from failing in baseline to passing in iter2 of the role-meta-refactor deploy loop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Shared Utilities (utils/)
This directory contains shared Python helpers used by custom modules and plugins.
Purpose
Use utils/ for reusable code that should not be duplicated across:
library/modules,plugins/action/,plugins/filter/,plugins/lookup/.
Typical shared utilities:
- API clients,
- validation/conversion helpers,
- path and configuration helpers,
- cross-plugin/module domain logic.
- Shared HTTP(S) connection handler for multiple modules.
- Common validation or transformation functions for user input.
- Utility functions for interacting with Docker, LDAP, etc.
- Grouped helper packages such as
utils/domains/for related domain logic.
Design Guidelines
- Keep helpers focused and composable.
- Avoid side effects during import.
- Prefer explicit function/class APIs over implicit globals.
- Keep dependencies minimal so modules/plugins stay lightweight.
Example Import
from utils.domains.primary_domain import get_primary_domain
What Does Not Belong Here
- Standalone executable modules (put in
library/). - Ansible plugin entrypoints (put in
plugins/*).
References
- Module utilities: https://docs.ansible.com/ansible/latest/dev_guide/developing_module_utilities.html
- Plugin development: https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html