blumeops/ansible/roles/borgmatic/tasks/main.yml
Erich Blume f26105dea9 C1: borgmatic shower SQLite dump via ssh to ringtail
The shower dump hook referenced kubectl --context=k3s-ringtail, but
indri's kubeconfig deliberately doesn't carry the ringtail
credentials. Since PR #349 (2026-05-11), nightly borgmatic runs have
failed at the before_backup hook, aborting both sifaka-borg-backups
and borgbase-offsite.

Rewrite the dump to ssh into ringtail and run k3s kubectl there.
/etc/rancher/k3s/k3s.yaml on ringtail is mode 644, so no sudo is
needed; the ssh user (eblume) reads it directly. Dump file is
created in the pod via sqlite3.backup, copied to ringtail's host
filesystem via k3s kubectl cp, then scp'd back to indri.

Template gains a `ssh_host` field on dump entries — when set, uses
the ssh path; when absent (as for mealie), uses local kubectl with
the existing `context` field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 17:38:26 -07:00

116 lines
3.8 KiB
YAML

---
# Borgmatic is installed via mise (pipx) and called directly by LaunchAgents.
# This role manages installation, config, and the scheduled LaunchAgents.
- name: Install borgmatic via mise
ansible.builtin.command: mise install pipx:borgmatic@{{ borgmatic_version }}
register: borgmatic_install
changed_when: "'installed' in borgmatic_install.stderr"
- name: Ensure borgmatic config directory exists
ansible.builtin.file:
path: "{{ borgmatic_config_dir }}"
state: directory
mode: '0700'
# .pgpass is used by pg_dump for database backups
# Password is fetched in playbook pre_tasks as borgmatic_db_password
- name: Write .pgpass file for borgmatic PostgreSQL backups
ansible.builtin.copy:
content: |
# Managed by ansible (borgmatic role) - k8s PostgreSQL backup credentials
pg.ops.eblu.me:5432:*:borgmatic:{{ borgmatic_db_password }}
pg.ops.eblu.me:5433:*:borgmatic:{{ borgmatic_db_password }}
dest: ~/.pgpass
mode: '0600'
no_log: true
# BorgBase offsite backup - SSH key and host verification
- name: Deploy BorgBase SSH private key
ansible.builtin.copy:
content: "{{ borgbase_ssh_private_key }}\n"
dest: "{{ borgmatic_borgbase_ssh_key_path }}"
mode: '0600'
no_log: true
- name: Add BorgBase host keys to known_hosts
ansible.builtin.known_hosts:
name: "{{ item }}"
key: "{{ item }} ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGU0mISTyHBw9tBs6SuhSq8tvNM8m9eifQxM+88TowPO"
state: present
loop:
- u3ugi1x1.repo.borgbase.com
- xcrtl5tg.repo.borgbase.com
- name: Ensure k8s dump directory exists
ansible.builtin.file:
path: "{{ borgmatic_k8s_dump_dir }}"
state: directory
mode: '0700'
when: borgmatic_k8s_sqlite_dumps | length > 0
- name: Ensure ~/bin exists
ansible.builtin.file:
path: "{{ ansible_env.HOME }}/bin"
state: directory
mode: '0755'
when: borgmatic_k8s_sqlite_dumps | length > 0
- name: Deploy k8s SQLite dump helper script
ansible.builtin.template:
src: k8s-sqlite-dump.sh.j2
dest: "{{ ansible_env.HOME }}/bin/borgmatic-k8s-sqlite-dump"
mode: '0755'
when: borgmatic_k8s_sqlite_dumps | length > 0
- name: Deploy borgmatic configuration
ansible.builtin.template:
src: config.yaml.j2
dest: "{{ borgmatic_config }}"
mode: '0600'
- name: Deploy borgmatic LaunchAgent plist
ansible.builtin.template:
src: borgmatic.plist.j2
dest: ~/Library/LaunchAgents/mcquack.eblume.borgmatic.plist
mode: '0644'
notify: Reload borgmatic
- name: Check if borgmatic LaunchAgent is loaded
ansible.builtin.command: launchctl list mcquack.eblume.borgmatic
register: borgmatic_launchctl_check
changed_when: false
failed_when: false
- name: Load borgmatic LaunchAgent if not loaded
ansible.builtin.command: launchctl load ~/Library/LaunchAgents/mcquack.eblume.borgmatic.plist
when: borgmatic_launchctl_check.rc != 0
changed_when: true
failed_when: false
# --- Immich photo library backup (BorgBase offsite only) ---
- name: Deploy borgmatic photos configuration
ansible.builtin.template:
src: photos.yaml.j2
dest: "{{ borgmatic_photos_config }}"
mode: '0600'
- name: Deploy borgmatic-photos LaunchAgent plist
ansible.builtin.template:
src: borgmatic-photos.plist.j2
dest: ~/Library/LaunchAgents/mcquack.eblume.borgmatic-photos.plist
mode: '0644'
notify: Reload borgmatic-photos
- name: Check if borgmatic-photos LaunchAgent is loaded
ansible.builtin.command: launchctl list mcquack.eblume.borgmatic-photos
register: borgmatic_photos_launchctl_check
changed_when: false
failed_when: false
- name: Load borgmatic-photos LaunchAgent if not loaded
ansible.builtin.command: launchctl load ~/Library/LaunchAgents/mcquack.eblume.borgmatic-photos.plist
when: borgmatic_photos_launchctl_check.rc != 0
changed_when: true
failed_when: false