Repository navigation
Spell HTTP/2 for the installed Nginx and roll back a rejected vhost - #67
Merged
Merged
Conversation
The domain vhost wrote `http2 on;`, which Nginx only parses from 1.25.1; Debian 12 ships 1.22.1, so `nginx -t` failed with `unknown directive "http2"`. The role now reads the installed version with `nginx -v` (also in check mode, failing the converge when it cannot be parsed) and writes `listen 443 ssl http2;` below 1.25.1. Output on 1.25.1 and later is unchanged. A rejected render used to stay on disk and enabled, so the next reload (a certbot hook, a reboot) broke every site on the host. Each render, link and `nginx -t` now runs in a block whose rescue restores the previous file (kept in memory with slurp, so no backup file lands where Nginx reads), or removes a new file and a link this run created, then fails with Nginx's error. The rescue ends in a failure, so with force_handlers off (neither the playbook, ansible.cfg nor the engine set it) the queued reload never runs. Nginx is started only after the first configuration test passes. Fixes #66 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
Two fixes in
engine/ansible/roles/cloudfall_nginx_site, as agreed on the issue.http2 on;, which Nginx only parses from 1.25.1; on Debian 12's 1.22.1nginx -tfailed withunknown directive "http2". The role now runsnginx -vright after installing Nginx (changed_when: false,check_mode: falseso the template renders in check mode too), asserts the stderr parses asnginx version: nginx/X.Y.Z(failing the converge with the output when it doesn't), and recordscloudfall_nginx_site_version. The template uses Ansible'sversiontest:listen 443 ssl http2;/listen [::]:443 ssl http2;below 1.25.1, the currentlisten 443 ssl;+http2 on;from 1.25.1. The rendered output on >= 1.25.1 is byte-identical to before (checked against the old template for 1.25.1 and 1.27.4, TLS and bootstrap).nginx -tsequences (HTTP-only before issuance, TLS after) now run through one included file,tasks/apply_virtual_host.yml. Before rendering it stats the vhost and itssites-enabledlink and keeps the current file's content withslurp(in memory, so no backup file is ever written where Nginx reads). On failure the rescue restores the previous file with its owner, group and mode, or removes a new file and a link this run created (a link that existed before stays), then fails with Nginx's stderr. The link handling follows the existingsites-availablecondition via acloudfall_nginx_site_linkfact (empty when the path is elsewhere).ansible.builtin.fail, so the queuedReload Nginxdoes not run as long asforce_handlersis off; neitherdomains.yml,engine/ansible/ansible.cfgnor the engine sets it. Even with it on, the reload would load the already restored state.Enable Nginx(start) now runs after the first configuration test instead of before it, so a rejected vhost never reaches a starting server. The finalnginx -tnow runs before the certbot timer is enabled rather than after.No change to the Domain schema or the receipt. Check mode keeps skipping
nginx -tand the rescue rolls nothing back there.Test notes
engine/tests/test_nginx_site_templates.py: renders with Ansible's own tests registered andtrim_blocks(the template module's default); new cases for 1.22.1, 1.24.0, 1.25.0 (ssl http2, nohttp2 on;) and 1.25.1, 1.26.3, 1.27.10 (unchanged block)engine/tests/test_nginx_site_role.py(new, same harness astest_time_role.py, Ansible's Templar): version parsing fromnginx -vstderr (incl. an(Ubuntu)suffix) and rejection of unparseable output or a failed probe; which rescue steps run for new file/new link, existing file/existing link, existing file/new link, a path outside sites-available, and check mode; the failure message carries Nginx's error; the link path factuv run ruff check .,uv run mypy,uv run pytest(517 passed),uv run cloudfall config validate --project config/examples,uv run ansible-lint engine/ansible(production profile), inventory render andansible-playbook --syntax-checkfor all 12 playbooksFixes #66
🤖 Generated with Claude Code