Files
DmitryandClaude Sonnet 5 baef2c49b3 feat: derive PBS backup jobs and audit VMIDs from the service registry
- pve-backup-jobs.yml: each job's vmid list is now computed from
  homelab_services by backup.job instead of a hand-maintained CSV. Adding a
  service no longer needs a separate edit here (the forgotten-edit failure
  mode that left CT 148 emergency-bot without a backup).
- roles/backup_audit/defaults: backup_audit_pbs_vmids derived from
  homelab_services by the monitoring.backup_audit_vmid flag; single shared
  freshness threshold backup_audit_pbs_max_age_hours (48).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uoq5AVK8mkBgg83Mq6o5V
2026-09-03 07:04:36 +03:00

128 lines
5.3 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Списки VMID выводятся из реестра homelab_services по полю backup.job, а не
# перечисляются вручную. Раньше добавление сервиса требовало отдельной правки
# здесь, и о ней легко было забыть — CT 148 emergency-bot до сих пор без бэкапа
# именно по этой причине.
- name: Configure Proxmox backup jobs
hosts: mini-pc
gather_facts: false
vars:
pve_backup_jobs:
- id: homelab-pbs-daily-cloud
comment: Daily PBS backup for cloud-pc service containers
node: cloud-pc
vmid: >-
{{ homelab_services.values() | selectattr('backup.job', 'defined')
| selectattr('backup.job', 'eq', 'homelab-pbs-daily-cloud')
| map(attribute='vmid') | sort | join(',') }}
storage: pbs
schedule: "02:10"
mode: snapshot
exclude_path: /var/lib/docker/fuse-overlayfs/*/merged
- id: homelab-pbs-daily-mini
comment: Daily PBS backup for mini-pc service containers
node: mini-pc
vmid: >-
{{ homelab_services.values() | selectattr('backup.job', 'defined')
| selectattr('backup.job', 'eq', 'homelab-pbs-daily-mini')
| map(attribute='vmid') | sort | join(',') }}
storage: pbs
schedule: "02:40"
mode: snapshot
exclude_path: /var/lib/docker/fuse-overlayfs/*/merged
- id: homelab-local-weekly-pbs
comment: Weekly local backup for PBS container rootfs/config
node: cloud-pc
vmid: >-
{{ homelab_services.values() | selectattr('backup.job', 'defined')
| selectattr('backup.job', 'eq', 'homelab-local-weekly-pbs')
| map(attribute='vmid') | sort | join(',') }}
storage: backup
schedule: "Sun 03:30"
mode: snapshot
prune_backups: keep-last=2
tasks:
- name: Get existing Proxmox backup jobs
ansible.builtin.command: pvesh get /cluster/backup --output-format json
register: pve_backup_jobs_existing_raw
changed_when: false
- name: Parse existing Proxmox backup jobs
ansible.builtin.set_fact:
pve_backup_jobs_existing: "{{ pve_backup_jobs_existing_raw.stdout | from_json }}"
- name: Create missing Proxmox backup jobs
ansible.builtin.command: >-
pvesh create /cluster/backup
--id {{ item.id }}
--enabled 1
--node {{ item.node }}
--vmid {{ item.vmid }}
--storage {{ item.storage }}
--schedule {{ item.schedule | quote }}
--mode {{ item.mode }}
{% if item.prune_backups is defined %}
--prune-backups {{ item.prune_backups }} --remove 1
{% else %}
--remove 0
{% endif %}
{% if item.exclude_path is defined %}
--exclude-path {{ item.exclude_path | quote }}
{% endif %}
--notes-template {{ '{{' }}guestname{{ '}}' }}
--comment {{ item.comment | quote }}
loop: "{{ pve_backup_jobs }}"
when: item.id not in (pve_backup_jobs_existing | map(attribute='id') | list)
- name: Update existing Proxmox backup jobs
ansible.builtin.command: >-
pvesh set /cluster/backup/{{ item.id }}
--enabled 1
--node {{ item.node }}
--vmid {{ item.vmid }}
--storage {{ item.storage }}
--schedule {{ item.schedule | quote }}
--mode {{ item.mode }}
{% if item.prune_backups is defined %}
--prune-backups {{ item.prune_backups }} --remove 1
{% else %}
--delete prune-backups --remove 0
{% endif %}
{% if item.exclude_path is defined %}
--exclude-path {{ item.exclude_path | quote }}
{% else %}
--delete exclude-path
{% endif %}
--notes-template {{ '{{' }}guestname{{ '}}' }}
--comment {{ item.comment | quote }}
loop: "{{ pve_backup_jobs }}"
vars:
current_job: >-
{{ pve_backup_jobs_existing | selectattr('id', 'equalto', item.id) | first }}
when:
- item.id in (pve_backup_jobs_existing | map(attribute='id') | list)
- >-
current_job.enabled | int != 1 or
current_job.node != item.node or
current_job.vmid | string != item.vmid | string or
current_job.storage != item.storage or
current_job.schedule != item.schedule or
current_job.mode != item.mode or
current_job.comment != item.comment or
current_job.remove | int != (1 if item.prune_backups is defined else 0) or
current_job['exclude-path'] | default([]) != ([item.exclude_path] if item.exclude_path is defined else []) or
(item.prune_backups is not defined and current_job['prune-backups'] is defined) or
(item.prune_backups is defined and
(current_job['prune-backups'] | default({})).get('keep-last', 0) | int !=
item.prune_backups | regex_replace('^keep-last=', '') | int)
changed_when: true
- name: Show configured Proxmox backup jobs
ansible.builtin.command: pvesh get /cluster/backup --output-format yaml
register: pve_backup_jobs_configured
changed_when: false
- name: Print configured Proxmox backup jobs
ansible.builtin.debug:
var: pve_backup_jobs_configured.stdout_lines