Skip to content

Commit f7aa104

Browse files
committed
docs: add explanatory comments to pgBackRest Ansible changes
Clarify the intent and rationale behind the less-obvious changes: - adminapi.sudoers.conf: explain the two pgbackrest sudo chains (NewRunner vs NewRunnerAs) and the wrapper/real-binary split - supabase-admin-agent.yml: explain why pgdata-chown is 0700 and pgdata-signal is 0755 - setup-pgbackrest.yml: explain the pgbackrest self-sudo entry, why conf.d needs setgid (02770), and why SAA log files must be pre-created before the agent runs - pgbackrest.conf: explain expire-auto change and why the [supabase] stanza was removed (SAA owns it via conf.d to avoid error [031])
1 parent 2e6bc99 commit f7aa104

4 files changed

Lines changed: 30 additions & 0 deletions

File tree

ansible/files/adminapi.sudoers.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,19 @@ Cmnd_Alias PGBOUNCER = /bin/systemctl start pgbouncer.service, /bin/systemctl st
1515
%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/common.sh
1616
%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/pgsodium_getkey.sh
1717
%adminapi ALL= NOPASSWD: /usr/bin/systemctl daemon-reload
18+
# pgBackRest wrapper scripts: constrained helpers called by supabase-admin-agent.
19+
# pgdata-chown runs as root (default); pgdata-signal runs as postgres so it can
20+
# create/remove signal files owned by that user.
1821
%adminapi ALL= NOPASSWD: /usr/local/lib/supabase-admin-agent/pgdata-chown
1922
%adminapi ALL=(postgres) NOPASSWD: /usr/local/lib/supabase-admin-agent/pgdata-signal
23+
# pgBackRest binary entries support two sudo chains used by supabase-admin-agent:
24+
# NewRunner() — adminapi → /usr/bin/pgbackrest wrapper → sudo -u pgbackrest real_binary
25+
# NewRunnerAs() — adminapi → sudo -u pgbackrest /usr/bin/pgbackrest → sudo -u pgbackrest real_binary
26+
# Both paths require the wrapper entry; NewRunner() additionally needs the real binary entry
27+
# because the wrapper itself calls sudo to drop privileges to the pgbackrest user.
2028
%adminapi ALL=(pgbackrest) NOPASSWD: /var/lib/pgbackrest/.nix-profile/bin/pgbackrest
2129
%adminapi ALL=(pgbackrest) NOPASSWD: /usr/bin/pgbackrest
30+
# pgBackRest restore stops PostgreSQL, restores PGDATA, then starts PostgreSQL.
2231
%adminapi ALL= NOPASSWD: /usr/bin/systemctl start postgresql.service
2332
%adminapi ALL= NOPASSWD: /usr/bin/systemctl stop postgresql.service
2433
%adminapi ALL= NOPASSWD: /usr/bin/systemctl reload postgresql.service

ansible/files/pgbackrest_config/pgbackrest.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,17 @@ archive-copy = y
44
backup-standby = prefer
55
compress-type = zst
66
delta = y
7+
# expire-auto=y allows pgBackRest to expire old backups automatically after
8+
# each new backup completes, keeping retention in sync without a separate
9+
# expire command. Previously n; changed to work correctly with SAA-managed backups.
710
expire-auto = y
811
link-all = y
912
log-level-console = info
1013
log-level-file = detail
1114
log-subprocess = y
1215
resume = n
1316
start-fast = y
17+
# Note: the [supabase] stanza (pg1-path, pg1-socket-path, pg1-user) has been
18+
# removed from this file. supabase-admin-agent owns that stanza and writes it
19+
# to /etc/pgbackrest/conf.d/ at enable time. Having the stanza in both places
20+
# causes pgBackRest error [031] (duplicate option).

ansible/tasks/internal/supabase-admin-agent.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
dest: /usr/local/lib/supabase-admin-agent/pgdata-chown
4646
owner: root
4747
group: root
48+
# 0700: always invoked via "sudo" (as root); no other user needs execute.
4849
mode: "0700"
4950

5051
- name: supabase-admin-agent - pgdata-signal script
@@ -53,6 +54,8 @@
5354
dest: /usr/local/lib/supabase-admin-agent/pgdata-signal
5455
owner: root
5556
group: root
57+
# 0755: invoked via "sudo -u postgres"; the postgres OS user needs the
58+
# world-execute bit since it is neither owner nor group member.
5659
mode: "0755"
5760

5861
- name: Setting arch (amd64)

ansible/tasks/setup-pgbackrest.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
- 'postgres ALL=(pgbackrest) NOPASSWD: /usr/bin/bash'
3131
- 'postgres ALL=(pgbackrest) NOPASSWD: /usr/bin/nix'
3232
- 'pgbackrest ALL=(pgbackrest) NOPASSWD: /usr/bin/bash'
33+
# Required for the NewRunnerAs() path: supabase-admin-agent runs the
34+
# /usr/bin/pgbackrest wrapper as the pgbackrest user, but the wrapper
35+
# internally calls "sudo -u pgbackrest <real_binary>". Without this entry
36+
# that inner sudo fails even though the outer caller is already pgbackrest.
3337
- 'pgbackrest ALL=(pgbackrest) NOPASSWD: /var/lib/pgbackrest/.nix-profile/bin/pgbackrest'
3438

3539
- name: Install pgBackRest
@@ -49,6 +53,9 @@
4953
path: "{{ backrest_dir['dir'] }}"
5054
state: directory
5155
loop:
56+
# conf.d is setgid (02770) so files written by adminapi (postgres group)
57+
# automatically inherit the postgres group. Without setgid, pgbackrest
58+
# (running as the pgbackrest user) cannot read conf files created by adminapi.
5259
- {dir: /etc/pgbackrest/conf.d, mode: '02770'}
5360
- {dir: /var/lib/pgbackrest}
5461
- {dir: /var/spool/pgbackrest}
@@ -58,6 +65,10 @@
5865
when:
5966
- nixpkg_mode
6067

68+
# supabase-admin-agent opens these log files with O_APPEND|O_WRONLY (no
69+
# O_CREATE). They must exist before SAA runs; a missing file causes the
70+
# pgBackRest enable command to fail before any backup work is attempted.
71+
# access_time/modification_time: preserve keeps this task idempotent.
6172
- name: Pre-create pgBackRest SAA log files
6273
ansible.builtin.file:
6374
access_time: preserve

0 commit comments

Comments
 (0)