feat(ansible): bundled first-party playbooks + built-in source
CI / lint (push) Successful in 2s
CI / unit (push) Successful in 7s
CI / integration (push) Successful in 2m16s
CI / publish (push) Successful in 55s

Ships a read-only "steward-builtin" source (steward/ansible/bundled/) that
always appears alongside operator-configured sources, with two playbooks:
- maintenance/docker_prune.yml — docker system prune for swarm/standalone
  nodes (safe by default; prune_all_images / prune_volumes extra-vars to
  widen). Schedule it against a swarm-node group for recurring cleanup (#869).
- host_agent/install.yml — installs/updates the host agent (mirrors
  install.sh: user, agent.py, config, hardened systemd unit), parameterised
  with steward_url + steward_token extra-vars.

get_sources() now prepends the builtin source. Tests updated to find the
configured git source by name; added coverage that the bundled playbooks are
discoverable.

Tasks #869 + agent-install (milestone #37).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-16 11:07:34 -04:00
parent 4a0a3ee46e
commit 656bda2e3d
5 changed files with 160 additions and 3 deletions
+18 -1
View File
@@ -10,6 +10,22 @@ logger = logging.getLogger(__name__)
INVENTORY_NAMES = {"hosts", "inventory", "inventory.yml", "inventory.ini"}
# Name of the always-present, read-only source of first-party playbooks shipped
# inside the app (maintenance tasks, host-agent install). Not operator-editable.
BUILTIN_SOURCE_NAME = "steward-builtin"
def _builtin_source() -> dict:
return {
"name": BUILTIN_SOURCE_NAME,
"type": "local",
"path": str((Path(__file__).parent / "bundled").resolve()),
"url": None,
"branch": "main",
"pull_interval_seconds": 0,
"http_token": "",
}
def get_sources(ansible_cfg: dict) -> list[dict]:
"""Return resolved source list from ansible config section.
@@ -33,7 +49,8 @@ def get_sources(ansible_cfg: dict) -> list[dict]:
"""
sources = ansible_cfg.get("sources", [])
cache_dir = ansible_cfg.get("cache_dir", "/var/cache/steward/ansible")
result = []
# Always expose the bundled first-party playbooks as a source.
result = [_builtin_source()]
for src in sources:
src_type = src.get("type", "local")
if src_type == "git":