diff --git a/roles/docker/tasks/infrastructure/caddy.yml b/roles/docker/tasks/infrastructure/caddy.yml index 6fa3c79..c4dff8d 100644 --- a/roles/docker/tasks/infrastructure/caddy.yml +++ b/roles/docker/tasks/infrastructure/caddy.yml @@ -14,11 +14,29 @@ become: true when: vault_dir2opds is defined -- name: Generate bcrypt hash for dir2opds basic auth +# bcrypt uses a random salt, so a fresh hash would change the Caddyfile (and +# restart Caddy) on every run. Reuse the deployed hash while it still matches +# the vault password; only make a new one when it doesn't. +- name: Get bcrypt hash for dir2opds basic auth ansible.builtin.shell: | - htpasswd -bnB "{{ vault_dir2opds.basic_auth_user }}" "{{ vault_dir2opds.basic_auth_password }}" | awk -F: '{print $1, $2}' + set -eu + cur=$(awk -v u="$AUTH_USER" '/basic_?auth/ {b=1} b && $1 == u {print $2; exit}' \ + /opt/stacks/caddy/Caddyfile 2>/dev/null || true) + if [ -n "$cur" ]; then + tmp=$(mktemp); trap 'rm -f "$tmp"' EXIT + printf '%s:%s\n' "$AUTH_USER" "$cur" > "$tmp" + if htpasswd -vb "$tmp" "$AUTH_USER" "$AUTH_PASS" >/dev/null 2>&1; then + echo "$AUTH_USER $cur" + exit 0 + fi + fi + htpasswd -bnB "$AUTH_USER" "$AUTH_PASS" | awk -F: 'NF {print $1, $2}' + environment: + AUTH_USER: "{{ vault_dir2opds.basic_auth_user }}" + AUTH_PASS: "{{ vault_dir2opds.basic_auth_password }}" register: dir2opds_basic_auth_hash_result changed_when: false + check_mode: false no_log: true when: vault_dir2opds is defined