# Finish the 2026-04-23 DB-off-NFS migration by removing pfi-postgres's # residual dependency on ana-nas's /mnt/db NFS export. # # Postgres on pfi-postgres is already running from local disk # (/var/lib/postgresql/13/main); /mnt/db is still mounted but # nothing writes to it. This playbook pulls the fstab line, unmounts, # and removes the empty mountpoint — eliminating ana-nas from # pfi-postgres's fault domain entirely. # # The old pre-migration data directories on ana-nas (pfi-mongo/, # pfi-postgres/) are NOT touched. They remain as a cold archive of # the pre-migration state and cost nothing to keep. # # Usage: # scripts/elway pfi-postgres --playbook playbooks/decouple-pfi-postgres-from-ana-nas.yaml # # Safe to re-run: every mutation is creates-gated or when-gated, so a # second invocation is a no-op. vars: fstab: /etc/fstab mount_point: /mnt/db nfs_source: "10.250.50.50:/mnt/db" steps: # ── pre-flight confirmations ──────────────────────────────────────── - name: Confirm Postgres IS running off local disk (not /mnt/db) # changed_when: false — we're attesting, not changing. Fails hard # if Postgres somehow ended up on the NFS path we're about to # unmount. shell: ps -ef | grep -v grep | grep 'postgres.*-D' | grep -q '/var/lib/postgresql' changed_when: "false" - name: Confirm /mnt/db has no open files (nothing writing to it) # lsof exits non-zero if no matches found — that's what we want. # Invert with `!`. If the mount point IS in use we want the # playbook to halt so the user can investigate. shell: "! sudo lsof +D {{ mount_point }} 2>/dev/null | grep -v '^COMMAND'" sudo: true changed_when: "false" # ── unmount + fstab ──────────────────────────────────────────────── - name: Remove fstab entry for {{ nfs_source }} shell: sed -i "\\|^{{ nfs_source }}[[:space:]]|d" {{ fstab }} sudo: true # Idempotency: if the line is already absent, the sed is a no-op # but still reports "changed" since sed always rewrites the file. # `when:` gate below makes it truly idempotent. when: "grep -qE '^{{ nfs_source }}[[:space:]]' {{ fstab }}" - name: Unmount {{ mount_point }} shell: umount {{ mount_point }} sudo: true # Only run if currently mounted. when: "mountpoint -q {{ mount_point }}" - name: Remove empty mountpoint dir shell: rmdir {{ mount_point }} sudo: true # Only if the dir exists AND is empty (rmdir fails on non-empty, # which is the safety we want). The `creates: null` pattern # doesn't apply here; we use a when: that checks both conditions. when: "[ -d {{ mount_point }} ] && [ -z \"$(ls -A {{ mount_point }} 2>/dev/null)\" ]" # ── tell systemd to forget the old mount unit ────────────────────── - name: Reload systemd so the synthesized mnt-db.mount unit clears shell: systemctl daemon-reload sudo: true changed_when: "false" verify: - name: fstab no longer references /mnt/db shell: "! grep -qE '^{{ nfs_source }}[[:space:]]' {{ fstab }}" changed_when: "false" - name: /mnt/db is not a mountpoint shell: "! mountpoint -q {{ mount_point }}" changed_when: "false" - name: No systemd mnt-db.mount unit remains active # Don't grep for "active" — "inactive" contains it as a substring. # `is-active` returns 0 only when the unit is truly active; invert. shell: "! systemctl is-active mnt-db.mount >/dev/null 2>&1" changed_when: "false" - name: Postgres is still running (we didn't accidentally break it) shell: systemctl is-active postgresql changed_when: "false" - name: Postgres still listening on :5432 shell: "ss -tln | grep -q ':5432'" changed_when: "false"