Cut the comment bloat from the Podman playbooks

Comment blocks now stay within three lines and explain only the non-obvious. Long histories, include examples, and commented-out code are gone. No task, key, or value changed; the only data change is comment text inside the generated unit files.
This commit is contained in:
tanshu committed 2026-10-18 22:10:57 +05:30
1 parent 2aab1aec1e
commit 476a6d7cd0
85 files changed
+372 -2433

No files matched your search

+4 -16
View File
@@ -1,27 +1,15 @@
---
# Caddy is its own playbook (caddy/playbook.yml) and a rootless Quadlet unit
# there. These handlers run as the connection user, so `systemctl --user` and
# `podman exec` work without any XDG_RUNTIME_DIR juggling.
# Notified by this role when the Caddyfile changes. A reload keeps existing
# connections; a restart would briefly drop every hosted site.
#
# Note the config path: /etc/caddy/Caddyfile is the mount inside the container,
# not {{ caddyfile_path }}, which is the host side of it.
# A reload keeps live connections; a restart would drop every hosted site.
# The path is inside the container, not the host {{ caddyfile_path }}.
- name: Reload Caddy configuration
ansible.builtin.command: >-
podman exec {{ caddy_name }} caddy reload --config /etc/caddy/Caddyfile
changed_when: true
listen: "Reload Caddy"
# Notified by caddy/roles/register when this service's network unit, or the
# drop-in that attaches Caddy to it, is written. Quadlet has no live equivalent
# of `docker network connect`, so the container has to be recreated — a brief
# restart of every hosted site, not just this one. See caddy/readme.md,
# "Trade-off worth knowing".
#
# Defined after the reload above so that when both are notified the cheap
# config reload happens first.
# Quadlet cannot attach a network live, so Caddy must be recreated.
# Defined after the reload so the cheap reload runs first when both are notified.
- name: Restart Caddy
ansible.builtin.systemd_service:
name: "{{ caddy_name }}.service"
-10
View File
@@ -1,14 +1,4 @@
---
# Append this site's block to the shared Caddyfile.
#
# The Caddyfile is a bind mount into the Caddy container, so Caddy sees the
# change as soon as the file is written; the handler only asks Caddy to re-read
# it. That is a reload, not a restart, so the other hosted sites are untouched.
#
# blockinfile is idempotent on its own via the marker, so there is no need to
# slurp the file and compare first — which also matters because slurp *fails*
# when the Caddyfile does not exist yet, on a host where the Caddy playbook has
# not run. (The Docker-era version of this role did exactly that.)
- name: "Add the {{ host }} site block to the Caddyfile"
ansible.builtin.blockinfile:
+2 -12
View File
@@ -1,16 +1,6 @@
---
# Valkey is its own playbook (valkey/playbook.yml) and a rootless Quadlet unit
# there. This handler runs as the connection user, so `systemctl --user` works
# without setting XDG_RUNTIME_DIR.
#
# Required by valkey/roles/attach, which notifies it whenever this app's drop-in
# changes: a new drop-in changes the generated unit, so Valkey must be recreated
# to join the network — Quadlet has no live equivalent of
# `podman network connect`.
#
# The cost is a cold cache for every attached app, not lost data — but note that
# attached means every cache client, not just Yamtrack. See valkey/readme.md,
# "The trade-off".
# A new drop-in changes the generated unit, so Valkey must be recreated to join the network.
# That restarts every attached client, not just Yamtrack.
- name: Restart Valkey
ansible.builtin.systemd_service:
name: "{{ valkey_unit }}"
+3 -24
View File
@@ -1,31 +1,10 @@
---
# Attach this app's network to the shared Valkey unit.
#
# Valkey knows nothing about its clients, exactly like Caddy and Postgres: a
# service joins by dropping 50-yamtrack.conf and the shared
# 10-network-aliases.conf next to valkey.container. The canonical way to do that
# is the shared include below — it writes the same bytes every service writes,
# asserts that yamtrack.network already exists, and notifies the "Restart Valkey"
# handler defined in this role.
#
# `valkey` is the host REDIS_URL asks for — the container name, not the shared
# `redis` alias, which is there for the clients whose config.php says `redis`.
# The Docker-era container was given `redis://valkey:6379` too, so the URL is
# unchanged.
#
# This runs in the roles phase, which is after the register include in
# playbook.yml's pre_tasks has created yamtrack.network.
# Runs in the roles phase, after the register include in pre_tasks created the network.
- name: Attach Yamtrack to Valkey
ansible.builtin.include_tasks: "{{ playbook_dir }}/../valkey/roles/attach/tasks/main.yaml"
# On a first attach the drop-in is new, so Valkey has to be recreated to join
# yamtrack_net — and that restart is a *handler*, which by default runs at the
# end of the play, after the yamtrack role has already started the app. The app
# would then come up before `valkey` resolves, fail its own checks, and fail the
# play on a machine where nothing is actually wrong.
#
# Flushing applies the new drop-in before the app starts. On later runs the
# drop-in is unchanged, nothing is pending, and this is a no-op.
# The restart is a handler, so it would run after the yamtrack role starts the app.
# Flushing applies the new drop-in before the app starts; later runs are a no-op.
- name: Apply the Valkey network change before starting Yamtrack
ansible.builtin.meta: flush_handlers
+1 -6
View File
@@ -1,16 +1,11 @@
---
# All handlers run as the connection user ({{ podman_user }}), so systemctl
# --user works without setting XDG_RUNTIME_DIR.
- name: Reload systemd user units
ansible.builtin.command: systemctl --user daemon-reload
changed_when: true
listen: Reload systemd user units
# A changed environment file or unit file changes the generated unit, so
# Yamtrack is recreated. The database is a bind mount and the rest of /yamtrack
# is image content, so a recreate loses nothing — but it is a few seconds of
# downtime for the one site.
# A recreate keeps state in the bind mount but costs a few seconds of downtime.
- name: Restart Yamtrack
ansible.builtin.systemd_service:
name: "{{ unit_name }}"
+9 -37
View File
@@ -1,13 +1,6 @@
---
# Yamtrack as a rootless Podman Quadlet unit.
#
# Everything here runs as {{ podman_user }} — the connection user. No become, no
# XDG_RUNTIME_DIR: the SSH connection gave us a real PAM session, so systemd's
# user manager is reachable through the standard environment.
# /yamtrack/db is the image's state directory: db.sqlite3 plus its -wal/-shm
# sidecars, and nothing else worth keeping — staticfiles/ is built into the
# image and the code is read-only.
# /yamtrack/db holds db.sqlite3 and its WAL sidecars; everything else is image content.
- name: Ensure the Yamtrack data directory exists
ansible.builtin.file:
path: "{{ data_dir }}"
@@ -16,9 +9,7 @@
group: "{{ podman_user }}"
mode: '0755'
# The app's secrets and cache coordinates are consumed by systemd
# (EnvironmentFile= in the Quadlet unit), not by Ansible, so this has to be
# written before the unit starts. Mode 0600: it holds SECRET.
# Written before the unit starts; 0600 keeps SECRET out of the world-readable unit.
- name: Write the environment file
ansible.builtin.template:
src: yamtrack.env.j2
@@ -48,9 +39,7 @@
state: started
daemon_reload: true
rescue:
# systemd reports "control process exited with error code" and nothing
# else, which is useless for the usual failures (an unattached network, an
# unreachable cache, a bad volume). Pull the real reason out.
# systemd reports only a generic exit error, so collect the real reason.
- name: Collect Yamtrack diagnostics
ansible.builtin.command: "{{ item }}"
loop:
@@ -69,22 +58,15 @@
ansible.builtin.fail:
msg: "Yamtrack did not start — see the diagnostics above."
# Quadlet honours [Install] WantedBy= when it generates the unit, so
# `systemctl --user enable` is neither needed nor possible on a generated unit.
#
# `is-active` says the container is running; it does not say the app can serve.
# The entrypoint runs migrations before supervisord starts nginx, gunicorn,
# celery and beat, and `Restart=always` means even a crash-looping container is
# reported active — so the checks below are the ones that matter.
# Quadlet honours WantedBy=, so systemctl enable is neither needed nor possible on a generated unit.
# is-active still reports active for a crash-looping container, so the checks below matter.
- name: Verify Yamtrack is running
ansible.builtin.command: "systemctl --user is-active {{ unit_name }}"
register: yamtrack_active
changed_when: false
failed_when: yamtrack_active.stdout != 'active'
# `valkey` is the host the environment file actually asks for; it resolves from
# ContainerName= on the shared unit, which valkey/roles/attach joined to this
# app's network.
# The app expects the valkey host; attach joined the shared unit to this app's network.
- name: Confirm Yamtrack can resolve its cache
ansible.builtin.command: >-
podman exec {{ container_name }} getent hosts {{ valkey_container }}
@@ -98,19 +80,9 @@
{{ valkey_container }} resolves as
{{ yamtrack_cache_lookup.stdout | default('(no answer)') }}
# `is-active` says the container is running; the image's own HEALTHCHECK is what
# says the app works. It wgets http://127.0.0.1:8000/health/, and that view
# checks all four things this deployment can get wrong — the cache, the database,
# Redis and Celery — so a green result here is the app being genuinely ready.
#
# Running the image's check rather than one written here means depending on
# nothing the play has to know: no curl or wget wrapper of our own, and no
# hardcoded path that a later image tag could move. `podman exec <c> wget -qO-
# http://127.0.0.1:{{ container_port }}/health/` prints the per-check breakdown
# when this fails; see readme.md, "Verification".
#
# The start period (30s) plus the entrypoint's migrations are why this allows
# three minutes rather than one.
# The image's own HEALTHCHECK covers the cache, database, Redis and Celery, so a pass means ready.
# Running the image's check means the play depends on no path or tool of its own.
# The start period plus migrations is why this allows three minutes.
- name: Wait for Yamtrack to pass its own health check
ansible.builtin.command: "podman healthcheck run {{ container_name }}"
register: yamtrack_health