0a97f00356
backup role now logs into borgcontroller and creates (or looks up) a
repository with alias=inventory_hostname, registering root's pubkey and
the requested storageSize. The resulting SSH URI is injected into the
borgmatic config so each host gets a remote-managed repo without manual
config.
backup_hosts entries gain a `storage_size_gb` field (stripped before
templating) and lose the manual `repositories` entry — the role fills it.
borgcontroller_{username,password} are expected from Semaphore secrets.
Also gitignores .claude/ local state.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
91 lines
2.6 KiB
YAML
91 lines
2.6 KiB
YAML
---
|
|
- name: Login to borg controller
|
|
ansible.builtin.uri:
|
|
url: "{{ borgcontroller_url }}/api/auth/login"
|
|
method: POST
|
|
body_format: json
|
|
body:
|
|
username: "{{ borgcontroller_username }}"
|
|
password: "{{ borgcontroller_password }}"
|
|
status_code: 200
|
|
delegate_to: localhost
|
|
become: false
|
|
register: _bc_login
|
|
no_log: true
|
|
|
|
- name: Get borg server SSH endpoint
|
|
ansible.builtin.uri:
|
|
url: "{{ borgcontroller_url }}/api/config"
|
|
method: GET
|
|
headers:
|
|
Cookie: "{{ _bc_login.cookies_string }}"
|
|
delegate_to: localhost
|
|
become: false
|
|
register: _bc_config
|
|
|
|
- name: List repositories
|
|
ansible.builtin.uri:
|
|
url: "{{ borgcontroller_url }}/api/repositories"
|
|
method: GET
|
|
headers:
|
|
Cookie: "{{ _bc_login.cookies_string }}"
|
|
delegate_to: localhost
|
|
become: false
|
|
register: _bc_repos
|
|
|
|
- name: Find existing repository for this host
|
|
ansible.builtin.set_fact:
|
|
_bc_existing: >-
|
|
{{ _bc_repos.json | selectattr('alias', 'eq', inventory_hostname) | list }}
|
|
|
|
- name: Create repository if missing
|
|
ansible.builtin.uri:
|
|
url: "{{ borgcontroller_url }}/api/repositories"
|
|
method: POST
|
|
body_format: json
|
|
body:
|
|
alias: "{{ inventory_hostname }}"
|
|
sshPublicKey: "{{ root_ssh.ssh_public_key }}"
|
|
storageSize: "{{ backup_hosts[inventory_hostname].storage_size_gb | int }}"
|
|
headers:
|
|
Cookie: "{{ _bc_login.cookies_string }}"
|
|
status_code: [200, 201]
|
|
delegate_to: localhost
|
|
become: false
|
|
when: _bc_existing | length == 0
|
|
|
|
- name: Update repository SSH key if root's key changed
|
|
ansible.builtin.uri:
|
|
url: "{{ borgcontroller_url }}/api/repositories/{{ _bc_existing[0].id }}"
|
|
method: PATCH
|
|
body_format: json
|
|
body:
|
|
sshPublicKey: "{{ root_ssh.ssh_public_key }}"
|
|
headers:
|
|
Cookie: "{{ _bc_login.cookies_string }}"
|
|
status_code: 200
|
|
delegate_to: localhost
|
|
become: false
|
|
when:
|
|
- _bc_existing | length > 0
|
|
- _bc_existing[0].sshPublicKey != root_ssh.ssh_public_key
|
|
|
|
- name: Re-list repositories after possible create/update
|
|
ansible.builtin.uri:
|
|
url: "{{ borgcontroller_url }}/api/repositories"
|
|
method: GET
|
|
headers:
|
|
Cookie: "{{ _bc_login.cookies_string }}"
|
|
delegate_to: localhost
|
|
become: false
|
|
register: _bc_repos_after
|
|
|
|
- name: Resolve repository for this host
|
|
ansible.builtin.set_fact:
|
|
_bc_repo: >-
|
|
{{ (_bc_repos_after.json | selectattr('alias', 'eq', inventory_hostname) | list)[0] }}
|
|
|
|
- name: Build borg SSH URI
|
|
ansible.builtin.set_fact:
|
|
borgcontroller_repo_uri: "ssh://{{ _bc_repo.repository }}@{{ _bc_config.json.borgSshHost.split('@')[1] }}/./repos"
|