Skip to content

Converge one Domain and record the vhost a run replaced - #133

Merged
shipmill-romamo[bot] merged 3 commits into
mainfrom
feat/116-converge-one-domain
Oct 27, 2026
Merged

shipmill-romamo[bot] merged 3 commits into
mainfrom
feat/116-converge-one-domain

Conversation

@shipmill-romamo

Copy link
Copy Markdown
Contributor

Summary

The engine side of spec 004 (docs/specs/004-domains-apply.md):

  • domains.yml takes cloudfall_domains_domain_id and renders only that Domain; without it the loop is the same as before. The playbook edit is the loop: expression only
  • The converge_domains MCP tool gains an optional domain. Given, the SDK looks the Domain up in the validated config, runs domains.yml with --limit <proxy.server> and the domain id, so no other host is contacted; an unknown id exits PRECONDITION (lifecycle_domain_missing) before the inventory render. Omitted, the argv and extra vars are exactly today's. The tool's handling moved into cloudfall.lifecycle.converge_domains (DomainsRun), and run_engine_playbook takes an optional limit
  • cloudfall_nginx_site hashes the file at proxy.configurationPath once, before its first render, and the receipt records it as previousConfigurationSha256 (null when no file was there). The receipt schema gains the optional field (sha256 or null), so receipts without it still load

The cloudfall domains apply command is #117; the criteria here are proven at the engine and MCP layer.

Fixes #116

Test plan

  • engine/tests/test_domains_one_domain.py: the real domains.yml loop evaluated with Ansible's templating (S-004-2, S-004-17); the role's own receipt tasks run for real by ansible-playbook on localhost against a hand-written vhost and against no file, receipt validated against the schema (S-004-11)
  • sdk/tests/test_domains_converge.py: argv of the run for one Domain (--limit h2, the domain id) and without one (unchanged), unknown id refused before any step, a failing playbook (a rejected nginx -t) surfaces as lifecycle_execution_failed, which the tool answers as ENGINE_STEP_FAILED (S-004-2, S-004-13, S-004-17); converge_domains over the real mcp serve stdio transport with an unknown domain (S-004-17); services status loads a receipt without the field, with null, and with a hash, and refuses a malformed one (S-004-12)
  • uv run ruff check ., uv run mypy, ansible-playbook --syntax-check on domains.yml, and the tests of the touched files pass locally. ansible-lint engine/ansible reported only role-not-found syntax errors on playbooks this PR doesn't touch, because ANSIBLE_CONFIG could not be set in this session; CI sets it
  • Not run: a live domains.yml on a Debian host with Nginx. The full suite is left to CI

Plan

  • Serves: quality bar
  • Files: engine/ansible/playbooks/domains.yml, engine/ansible/roles/cloudfall_nginx_site/tasks/main.yml, config/schemas/v1/deployment-receipt.schema.json, sdk/src/cloudfall/lifecycle.py, sdk/src/cloudfall/app.py, engine/tests/test_domains_one_domain.py, sdk/tests/test_domains_converge.py, changelog.d/116-converge-one-domain.md
  • Order: schema field first, then the role's hash and receipt field, then the playbook's domain filter, then the SDK limit and the MCP tool's domain, each with its test
  • Proof: S-004-2, S-004-11, S-004-12, S-004-13, S-004-17 (specs.py coverage --spec 004)

🤖 Generated with Claude Code

shipmill-romamo Bot and others added 3 commits October 27, 2026 10:27
domains.yml takes cloudfall_domains_domain_id and renders only that
Domain; the converge_domains MCP tool gains an optional domain that
limits the run to the Domain's proxy server and refuses an unknown id
before the inventory render. Without it the tool runs as before.

The nginx site role hashes the file at proxy.configurationPath before
its first render, and the DeploymentReceipt records it as
previousConfigurationSha256 (null when no file was there). The schema
change is additive, so older receipts still load.

Fixes #116

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A link at proxy.configurationPath (the Debian sites-enabled layout) gave
stat no checksum, so the receipt task failed after the render went live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…attern

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@shipmill-romamo
shipmill-romamo Bot force-pushed the feat/116-converge-one-domain branch from 2769e37 to 21ee8e5 Compare October 27, 2026 08:39
@shipmill-romamo

Copy link
Copy Markdown
Contributor Author

@romamo Decided without waiting: converge_domains gains an optional domain input, every domain receipt gains previousConfigurationSha256, and a one-Domain run is limited with ansible-playbook --limit <proxy server>.

Why: S-004-2, S-004-11 and S-004-17 ask for exactly this; the receipt field is optional, so older receipts still load. Without domain, the tool runs exactly as today. Review made the hash follow a symlinked vhost (the usual sites-enabled layout), which otherwise failed after the new vhost was live.
Not taken: filtering only inside the playbook, which would still connect to every server.

Reply with a comment starting with veto before 2026-10-28 08:45 UTC to reverse it, adding what you want instead if you like. A later veto still counts and gets a follow-up.

@shipmill-romamo shipmill-romamo Bot added the decided An agent decided at notify; the maintainer may veto label Oct 27, 2026
@shipmill-romamo
shipmill-romamo Bot merged commit 16dcbe1 into main Oct 27, 2026
1 check passed
@shipmill-romamo
shipmill-romamo Bot deleted the feat/116-converge-one-domain branch October 27, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

decided An agent decided at notify; the maintainer may veto

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Converge one Domain in domains.yml and record the previous vhost hash (S-004-2, 11, 12, 13, 17)

0 participants