Some sanoid packages (e.g. on Ubuntu 26.04) don't ship /etc/sanoid, so the config template failed with 'Destination directory does not exist'. Create the directory explicitly, and copy the packaged sanoid.defaults.conf into it (sanoid requires it beside sanoid.conf) so the first timer run succeeds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
205 lines
5.7 KiB
YAML
205 lines
5.7 KiB
YAML
---
|
|
# ── ZFS snapshots (files stream) via sanoid ─────────────────────────────────
|
|
- name: Install sanoid (snapshots + syncoid replication)
|
|
ansible.builtin.apt:
|
|
name: sanoid
|
|
state: present
|
|
when: backup_snapshots_enabled
|
|
|
|
- name: Ensure the sanoid config directory exists
|
|
ansible.builtin.file:
|
|
path: /etc/sanoid
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
when: backup_snapshots_enabled
|
|
|
|
- name: Locate the packaged sanoid.defaults.conf
|
|
ansible.builtin.shell: "dpkg -L sanoid | grep -m1 sanoid.defaults.conf"
|
|
register: sanoid_defaults_src
|
|
changed_when: false
|
|
failed_when: false
|
|
when: backup_snapshots_enabled
|
|
|
|
- name: Install sanoid.defaults.conf (sanoid needs it next to sanoid.conf)
|
|
ansible.builtin.copy:
|
|
remote_src: true
|
|
src: "{{ sanoid_defaults_src.stdout }}"
|
|
dest: /etc/sanoid/sanoid.defaults.conf
|
|
force: false
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
when:
|
|
- backup_snapshots_enabled
|
|
- sanoid_defaults_src.stdout | default('') | length > 0
|
|
- sanoid_defaults_src.stdout != '/etc/sanoid/sanoid.defaults.conf'
|
|
|
|
- name: Configure sanoid snapshot policy
|
|
ansible.builtin.template:
|
|
src: sanoid.conf.j2
|
|
dest: /etc/sanoid/sanoid.conf
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
when: backup_snapshots_enabled
|
|
|
|
- name: Enable the sanoid timer
|
|
ansible.builtin.systemd:
|
|
name: sanoid.timer
|
|
enabled: true
|
|
state: started
|
|
when: backup_snapshots_enabled
|
|
|
|
# ── Per-database dumps (DB stream) ──────────────────────────────────────────
|
|
- name: Install the DB backup script
|
|
ansible.builtin.template:
|
|
src: heleos-db-backup.sh.j2
|
|
dest: /usr/local/sbin/heleos-db-backup.sh
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
when: db_backup_enabled
|
|
|
|
- name: Install the DB backup service + timer
|
|
ansible.builtin.copy:
|
|
dest: "/etc/systemd/system/{{ item.name }}"
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
content: "{{ item.content }}"
|
|
loop:
|
|
- name: heleos-db-backup.service
|
|
content: |
|
|
[Unit]
|
|
Description=heleos per-database dumps (rotated)
|
|
After=docker.service
|
|
Requires=docker.service
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/usr/local/sbin/heleos-db-backup.sh
|
|
- name: heleos-db-backup.timer
|
|
content: |
|
|
[Unit]
|
|
Description=Run heleos DB backups on a schedule
|
|
|
|
[Timer]
|
|
OnCalendar={{ db_backup_oncalendar }}
|
|
Persistent=true
|
|
|
|
[Install]
|
|
WantedBy=timers.target
|
|
loop_control:
|
|
label: "{{ item.name }}"
|
|
when: db_backup_enabled
|
|
notify: Reload systemd
|
|
|
|
- name: Enable the DB backup timer
|
|
ansible.builtin.systemd:
|
|
name: heleos-db-backup.timer
|
|
enabled: true
|
|
daemon_reload: true
|
|
state: started
|
|
when: db_backup_enabled
|
|
|
|
# ── Offsite: files (syncoid / zfs send) ─────────────────────────────────────
|
|
- name: Install the ZFS offsite script
|
|
ansible.builtin.template:
|
|
src: heleos-zfs-offsite.sh.j2
|
|
dest: /usr/local/sbin/heleos-zfs-offsite.sh
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
when: zfs_offsite_target | length > 0
|
|
|
|
- name: Install the ZFS offsite service + timer
|
|
ansible.builtin.copy:
|
|
dest: "/etc/systemd/system/{{ item.name }}"
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
content: "{{ item.content }}"
|
|
loop:
|
|
- name: heleos-zfs-offsite.service
|
|
content: |
|
|
[Unit]
|
|
Description=heleos offsite ZFS replication (syncoid)
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/usr/local/sbin/heleos-zfs-offsite.sh
|
|
- name: heleos-zfs-offsite.timer
|
|
content: |
|
|
[Unit]
|
|
Description=Run heleos offsite ZFS replication on a schedule
|
|
|
|
[Timer]
|
|
OnCalendar={{ zfs_offsite_oncalendar }}
|
|
Persistent=true
|
|
|
|
[Install]
|
|
WantedBy=timers.target
|
|
loop_control:
|
|
label: "{{ item.name }}"
|
|
when: zfs_offsite_target | length > 0
|
|
notify: Reload systemd
|
|
|
|
- name: Enable the ZFS offsite timer
|
|
ansible.builtin.systemd:
|
|
name: heleos-zfs-offsite.timer
|
|
enabled: true
|
|
daemon_reload: true
|
|
state: started
|
|
when: zfs_offsite_target | length > 0
|
|
|
|
# ── Offsite: DB dumps (rsync) ───────────────────────────────────────────────
|
|
- name: Install the DB offsite script
|
|
ansible.builtin.template:
|
|
src: heleos-db-offsite.sh.j2
|
|
dest: /usr/local/sbin/heleos-db-offsite.sh
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
when: db_offsite_target | length > 0
|
|
|
|
- name: Install the DB offsite service + timer
|
|
ansible.builtin.copy:
|
|
dest: "/etc/systemd/system/{{ item.name }}"
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
content: "{{ item.content }}"
|
|
loop:
|
|
- name: heleos-db-offsite.service
|
|
content: |
|
|
[Unit]
|
|
Description=heleos offsite DB dump sync (rsync)
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/usr/local/sbin/heleos-db-offsite.sh
|
|
- name: heleos-db-offsite.timer
|
|
content: |
|
|
[Unit]
|
|
Description=Run heleos offsite DB sync on a schedule
|
|
|
|
[Timer]
|
|
OnCalendar={{ db_offsite_oncalendar }}
|
|
Persistent=true
|
|
|
|
[Install]
|
|
WantedBy=timers.target
|
|
loop_control:
|
|
label: "{{ item.name }}"
|
|
when: db_offsite_target | length > 0
|
|
notify: Reload systemd
|
|
|
|
- name: Enable the DB offsite timer
|
|
ansible.builtin.systemd:
|
|
name: heleos-db-offsite.timer
|
|
enabled: true
|
|
daemon_reload: true
|
|
state: started
|
|
when: db_offsite_target | length > 0
|