| 1 | #!/usr/bin/env bash |
| 2 | # SPDX-License-Identifier: AGPL-3.0-or-later |
| 3 | # |
| 4 | # Postgres archive_command. Postgres calls this with two args: |
| 5 | # $1 = absolute path to the WAL segment in pgdata |
| 6 | # $2 = the segment filename |
| 7 | # |
| 8 | # Contract: exit 0 ONLY when the file is durably stored. Postgres |
| 9 | # refuses to recycle the segment until we report success — getting |
| 10 | # this wrong fills the disk. We use rclone copyto with --no-update- |
| 11 | # modtime so the bucket is the source of truth on retention. |
| 12 | # |
| 13 | # Wired by deploy/ansible/roles/postgres/templates/99_shithub_archive.conf. |
| 14 | |
| 15 | set -euo pipefail |
| 16 | |
| 17 | SRC="$1" |
| 18 | NAME="$2" |
| 19 | BUCKET="${SHITHUB_WAL_BUCKET:-spaces-prod:shithub-wal}" |
| 20 | |
| 21 | # Atomic-ish: rclone copyto streams to a temp object, then renames. |
| 22 | # --s3-no-check-bucket: scoped Spaces keys lack GetBucketLocation; the |
| 23 | # actual PUT works fine on a key with bucket-level readwrite. Matches |
| 24 | # the same flag in backup-daily.sh + sync-cross-region.sh. |
| 25 | rclone --config /etc/rclone-shithub.conf \ |
| 26 | --s3-no-check-bucket \ |
| 27 | --quiet \ |
| 28 | copyto "$SRC" "$BUCKET/$(date +%Y/%m/%d)/$NAME" |