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:
1 parent
2aab1aec1e
commit
476a6d7cd0
85 files changed
+372
-2433
No files matched your search
@@ -1,27 +1,14 @@
|
||||
---
|
||||
# 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 existing connections. A restart would briefly drop every hosted site.
|
||||
# The config path is inside the container, not caddyfile_path on the host.
|
||||
- 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 has no live equivalent of network connect, so Caddy is recreated and every hosted site restarts.
|
||||
# Defined after the reload so the cheap reload runs first.
|
||||
- name: Restart Caddy
|
||||
ansible.builtin.systemd_service:
|
||||
name: "{{ caddy_name }}.service"
|
||||
|
||||
@@ -1,15 +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.
|
||||
|
||||
- name: "Add the {{ host }} site block to the Caddyfile"
|
||||
ansible.builtin.blockinfile:
|
||||
path: "{{ caddyfile_path }}"
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
---
|
||||
# TriliumNext Notes 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.
|
||||
|
||||
# The image's data directory is one tree: document.db with its WAL sidecars,
|
||||
# config.ini, session_secret.txt, and the three subdirectories below. It is
|
||||
# created here as the copy target as much as for a fresh install.
|
||||
# The image keeps document.db, config.ini, session_secret.txt and the subdirectories below in this one tree.
|
||||
- name: Ensure the Trilium data directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ data_dir }}"
|
||||
@@ -16,12 +8,8 @@
|
||||
group: "{{ podman_user }}"
|
||||
mode: '0755'
|
||||
|
||||
# Trilium creates these itself on first start, at 0700 — which is exactly how
|
||||
# they are on monoco. Creating them here means a fresh host and a migrated one
|
||||
# look the same, and that the destinations named in readme.md exist before the
|
||||
# copy. log/ is where the app writes its daily log — which the play reads back
|
||||
# later as evidence that the container is writing to the host — and backup/ is
|
||||
# where its own zipped document.db backups land.
|
||||
# Trilium creates these at 0700 on first start. Creating them here makes a fresh host and a migrated one look the same.
|
||||
# log/ holds the daily log the play reads back as evidence, and backup/ holds the app's own zipped backups.
|
||||
- name: Ensure the app-managed subdirectories exist
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
@@ -34,11 +22,7 @@
|
||||
- "{{ tmp_dir }}"
|
||||
- "{{ backup_dir }}"
|
||||
|
||||
# Checked before the unit starts, because this is the one thing the play cannot
|
||||
# tell after the fact: with no document.db the app serves a brand new, empty
|
||||
# document, which is right for a fresh install and wrong for a migration whose
|
||||
# copy has not run yet. Once the app has started it creates the file itself and
|
||||
# the evidence is gone.
|
||||
# Check before the unit starts, because an empty document it creates hides whether the copy ever landed.
|
||||
- name: Check whether a document has been copied in
|
||||
ansible.builtin.stat:
|
||||
path: "{{ data_dir }}/document.db"
|
||||
@@ -64,15 +48,7 @@
|
||||
- Reload systemd user units
|
||||
- Restart Trilium
|
||||
|
||||
# Quadlet honours [Install] WantedBy= when it generates the unit, so
|
||||
# `systemctl --user enable` is neither needed nor possible on a generated unit.
|
||||
#
|
||||
# All three steps are in one block because they fail the same way and want the
|
||||
# same evidence. `systemctl start` reports success as soon as it has handed the
|
||||
# unit to systemd, so a container that dies a second later — `User=0` missing, a
|
||||
# network that was never attached, an unwritable data directory — surfaces here
|
||||
# as `activating`, or as a health check that never passes, with the real reason
|
||||
# only in the journal. Restart=always makes that a crash loop, not an error.
|
||||
# Quadlet honours [Install] WantedBy=, so the generated unit is never enabled.
|
||||
- name: Start and verify Trilium
|
||||
block:
|
||||
- name: Start Trilium
|
||||
@@ -82,9 +58,7 @@
|
||||
state: started
|
||||
daemon_reload: true
|
||||
|
||||
# Retried rather than checked once: the container is coming up, and podman
|
||||
# reports `activating` for the interval between systemd starting it and the
|
||||
# container's own readiness notification.
|
||||
# Retried because podman reports `activating` until the container signals readiness.
|
||||
- name: Verify Trilium is running
|
||||
ansible.builtin.command: "systemctl --user is-active {{ unit_name }}"
|
||||
register: trilium_active
|
||||
@@ -93,11 +67,7 @@
|
||||
delay: 5
|
||||
changed_when: false
|
||||
|
||||
# `is-active` says the container is running; it does not say the app can
|
||||
# serve. The unit defines the probe (HealthCmd=, see the template) because
|
||||
# the image ships none, so this runs exactly that command once,
|
||||
# synchronously, and fails while the app is still migrating or not yet
|
||||
# listening.
|
||||
# The image ships no health check, so the unit defines one and this runs it synchronously.
|
||||
- name: Wait for Trilium to pass its health check
|
||||
ansible.builtin.command: "podman healthcheck run {{ container_name }}"
|
||||
register: trilium_health
|
||||
@@ -106,10 +76,7 @@
|
||||
delay: 5
|
||||
changed_when: false
|
||||
rescue:
|
||||
# systemd reports "control process exited with error code" and nothing
|
||||
# else, which is useless for the usual failures. The journal is where the
|
||||
# entrypoint's own output is — that is where "su: Authentication failure"
|
||||
# or a failed bind mount shows up.
|
||||
# systemd only reports "control process exited with error code", so read the journal for the real reason.
|
||||
- name: Collect Trilium diagnostics
|
||||
ansible.builtin.command: "{{ item }}"
|
||||
loop:
|
||||
@@ -128,19 +95,8 @@
|
||||
ansible.builtin.fail:
|
||||
msg: "Trilium did not start — see the diagnostics above."
|
||||
|
||||
# The check that catches a missing or mistyped Volume= line, which is the one
|
||||
# failure here that is silent: the app would run perfectly well with document.db
|
||||
# in the container's writable layer — or in an anonymous volume, if the image
|
||||
# declares one — and lose it on the next recreate.
|
||||
#
|
||||
# It has to be a mount check and not a file check. Audiobookshelf can assert that
|
||||
# its database appeared on the host, because the app creates it; here the
|
||||
# migration puts document.db on the host *before* the app ever runs, so its
|
||||
# presence proves nothing about whether the container can see it.
|
||||
#
|
||||
# Both halves matter: the destination alone would still be satisfied by an
|
||||
# anonymous volume mounted where the bind mount should be, which is exactly the
|
||||
# silent case. `Source` is the path Quadlet passed to podman, verbatim.
|
||||
# A missing or mistyped Volume= line would run fine and lose document.db on the next recreate, so check the mount.
|
||||
# Both Source and Destination must match, since a destination-only check would pass an anonymous volume.
|
||||
- name: Read the running container's configuration back
|
||||
ansible.builtin.command: "podman inspect {{ container_name }}"
|
||||
register: trilium_inspect
|
||||
@@ -162,12 +118,7 @@
|
||||
check the Volume= line in the generated unit
|
||||
({{ quadlet_dir }}/{{ container_name }}.container).
|
||||
|
||||
# Evidence rather than a gate: with keep-id:uid=1000 mapped onto
|
||||
# {{ podman_user }}, what the app writes lands in {{ data_dir }} owned by
|
||||
# {{ podman_user }} — and the app writes a daily log the moment it starts. A log
|
||||
# touched in the last few minutes is that, visible from the host. It is reported
|
||||
# rather than asserted because a slow start can legitimately leave nothing here
|
||||
# yet; the mount assertion above is the hard check.
|
||||
# Evidence, not a gate: a log touched in the last five minutes shows the app writing into the host data directory, while a slow start may leave none.
|
||||
- name: Look for a log written since the unit started
|
||||
ansible.builtin.find:
|
||||
paths: "{{ log_dir }}"
|
||||
@@ -190,9 +141,7 @@
|
||||
path: "{{ data_dir }}/document.db"
|
||||
register: trilium_document_db_after
|
||||
|
||||
# A migrated document.db is a few megabytes; the empty one the app creates on a
|
||||
# fresh install is kilobytes. Worth printing, because it is the difference
|
||||
# between "the notes came across" and "the copy never ran".
|
||||
# A migrated document.db is megabytes; the empty one from a fresh install is kilobytes.
|
||||
- name: Report the document on the host
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
|
||||
Reference in new issue
Block a user