support append_only mode
This commit is contained in:
parent
fadd36625d
commit
dc72e03bb3
@ -2,6 +2,7 @@
|
||||
This role installs Borg backup on backupservers and clients. The role contains a wrapper-script 'borg-backup' to ease the usage on the client. Supported options include borg-backup info | init | list | backup | mount. Automysqlbackup will run as pre-backup command if it's installed.
|
||||
The role supports both self hosted and rsync.net as Borg server.
|
||||
|
||||
It's possible to configure append-only repositories to secure the backups against deletion from the client.
|
||||
|
||||
## Required variables
|
||||
Define a group backupservers in your inventory with one or multiple hosts.
|
||||
@ -9,6 +10,9 @@ Define a group backupservers in your inventory with one or multiple hosts.
|
||||
infra:
|
||||
[backupservers]
|
||||
backup1.fiaas.co
|
||||
|
||||
[borgbackup_management]
|
||||
supersecurehost
|
||||
```
|
||||
|
||||
group\_vars/all.yml:
|
||||
@ -37,6 +41,8 @@ host\_vars\client1:
|
||||
borgbackup_passphrase: Ahl9EiNohr5koosh1Wohs3Shoo3ooZ6p
|
||||
```
|
||||
|
||||
Set borgbackup\_appendonly: True in host or group vars if you want append-only repositories. In that case it's possible to define a hostname in borgbackup\_management\_station where a borg prune script will be configured.
|
||||
|
||||
*Make sure to check the configured defaults for this role, which contains the list of default locations being backed up in backup_include.* Override this in your inventory where required.
|
||||
|
||||
## Usage
|
||||
|
@ -22,4 +22,7 @@ borgbackup_retention:
|
||||
monthly: 6
|
||||
yearly: 1
|
||||
|
||||
borgbackup_appendonly: False
|
||||
borgbackup_management_station: ''
|
||||
borgbackup_management_user: ''
|
||||
borgbackup_management_sshkey: ''
|
||||
|
@ -25,7 +25,7 @@
|
||||
authorized_key:
|
||||
user: "{{ item.user }}"
|
||||
key: "{{ sshkey.stdout }}"
|
||||
key_options: 'command="cd {{ item.home }}{{ item.pool }}/{{ inventory_hostname }};borg serve --restrict-to-path {{ item.home }}/{{ item.pool }}/{{ inventory_hostname }}",no-port-forwarding,no-X11-forwarding,no-pty,no-agent-forwarding,no-user-rc'
|
||||
key_options: 'command="cd {{ item.home }}{{ item.pool }}/{{ inventory_hostname }};borg serve {% if borgbackup_appendonly %}--append-only {% endif %}--restrict-to-path {{ item.home }}/{{ item.pool }}/{{ inventory_hostname }}",no-port-forwarding,no-X11-forwarding,no-pty,no-agent-forwarding,no-user-rc'
|
||||
delegate_to: "{{ item.fqdn }}"
|
||||
when: item.type == 'normal'
|
||||
with_items: "{{ backupservers }}"
|
||||
@ -43,7 +43,7 @@
|
||||
authorized_key:
|
||||
user: "{{ ansible_user_id }}"
|
||||
key: "{{ sshkey.stdout }}"
|
||||
key_options: 'command="cd {{ item.home }}{{ item.pool }}/{{ inventory_hostname }};borg serve --restrict-to-path {{ item.home }}/{{ item.pool }}/{{ inventory_hostname }}",no-port-forwarding,no-X11-forwarding,no-pty,no-agent-forwarding,no-user-rc'
|
||||
key_options: 'command="cd {{ item.home }}{{ item.pool }}/{{ inventory_hostname }};borg serve {% if borgbackup_appendonly %}--append-only {% endif %}--restrict-to-path {{ item.home }}/{{ item.pool }}/{{ inventory_hostname }}",no-port-forwarding,no-X11-forwarding,no-pty,no-agent-forwarding,no-user-rc'
|
||||
path: "/tmp/rsync.net-{{ item.fqdn }}-authkeys"
|
||||
manage_dir: no
|
||||
delegate_to: localhost
|
||||
|
@ -1,5 +1,4 @@
|
||||
---
|
||||
|
||||
- include: install.yml
|
||||
when: >
|
||||
borgbackup_required == True or
|
||||
@ -12,3 +11,8 @@
|
||||
when: >
|
||||
borgbackup_required == True and
|
||||
inventory_hostname not in groups.backupservers
|
||||
|
||||
- include: management.yml
|
||||
when: >
|
||||
inventory_hostname in groups.borgbackup_management and
|
||||
inventory_hostname not in groups.backupservers
|
||||
|
55
tasks/management.yml
Normal file
55
tasks/management.yml
Normal file
@ -0,0 +1,55 @@
|
||||
---
|
||||
- name: management | put management station prune script
|
||||
template:
|
||||
src: prune.sh.j2
|
||||
dest: "~{{ borgbackup_management_user }}/prune.sh"
|
||||
owner: "{{ borgbackup_management_user }}"
|
||||
group: "{{ borgbackup_management_user }}"
|
||||
mode: 0700
|
||||
|
||||
- name: management | put management sshpubkey on the normal backupserver
|
||||
authorized_key:
|
||||
user: "{{ item.user }}"
|
||||
key: "{{ borgbackup_management_sshkey }}"
|
||||
delegate_to: "{{ item.fqdn }}"
|
||||
when: item.type == 'normal'
|
||||
with_items: "{{ backupservers }}"
|
||||
|
||||
|
||||
# rsync.net has no python, so we can only use raw to manage ssh keys - workaround with local tmp file
|
||||
- name: management | get rsync.net authorized_keys file
|
||||
raw: scp {{ item.user }}@{{ item.fqdn }}:.ssh/authorized_keys /tmp/rsync.net-{{ item.fqdn }}-authkeys
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
when: item.type == 'rsync.net'
|
||||
with_items: "{{ backupservers }}"
|
||||
changed_when: false
|
||||
|
||||
- name: management | modify local rsync.net authorized_keys
|
||||
authorized_key:
|
||||
user: "{{ ansible_user_id }}"
|
||||
key: "{{ borgbackup_management_sshkey }}"
|
||||
path: "/tmp/rsync.net-{{ item.fqdn }}-authkeys"
|
||||
manage_dir: no
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
when: item.type == 'rsync.net'
|
||||
with_items: "{{ backupservers }}"
|
||||
register: authkeys
|
||||
|
||||
- name: management | upload local authorized_keys to rsync.net
|
||||
raw: scp /tmp/rsync.net-{{ item.fqdn }}-authkeys {{ item.user }}@{{ item.fqdn }}:.ssh/authorized_keys
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
when: item.type == 'rsync.net' and authkeys.changed
|
||||
with_items: "{{ backupservers }}"
|
||||
|
||||
- name: management | remove tmp authorized_keys files
|
||||
file:
|
||||
path: /tmp/rsync.net-{{ item.fqdn }}-authkeys
|
||||
state: absent
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
with_items: "{{ backupservers }}"
|
||||
when: authkeys.changed
|
||||
changed_when: false
|
@ -69,10 +69,11 @@ if [ "$1" = "backup" ]
|
||||
/usr/local/bin/borg create --compression zlib,6 --stats $REPOSITORY::$date {{ b.options }} {% for dir in borgbackup_include %}{{ dir }} {% endfor %}{% if automysql.stat.isdir is defined and automysql.stat.isdir == True %}/var/lib/automysqlbackup{% endif %}
|
||||
|
||||
if [ "$?" -eq "0" ]; then printf "Backup succeeded on $date\n" >> /var/log/borg-backup.log; fi
|
||||
|
||||
# Use the `prune` subcommand to maintain 7 daily, 4 weekly
|
||||
# and 6 monthly archives.
|
||||
|
||||
{% if not borgbackup_appendonly %}
|
||||
# prune old backups
|
||||
/usr/local/bin/borg prune -v $REPOSITORY {{ b.options }} -H {{ borgbackup_retention.hourly }} -d {{ borgbackup_retention.daily }} -w {{ borgbackup_retention.weekly }} -m {{ borgbackup_retention.monthly }} -y {{ borgbackup_retention.yearly }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
fi
|
||||
|
||||
|
19
templates/prune.sh.j2
Normal file
19
templates/prune.sh.j2
Normal file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script is intended to run on a trusted management station to purge borg repo's in
|
||||
# append-only mode.
|
||||
# Don't put it on the backup server, it contains all borg secrets!
|
||||
|
||||
{% for h in groups['all'] %}
|
||||
{% if hostvars[h].borgbackup_required is defined and hostvars[h].borgbackup_required %}
|
||||
# Host: {{ h }}
|
||||
{% for b in hostvars[h].backupservers %}
|
||||
{% if hostvars[h].borgbackup_managementstation is defined and inventory_hostname == hostvars[h].borgbackup_managementstation %}
|
||||
export BORG_PASSPHRASE={{ hostvars[h].borgbackup_passphrase }}
|
||||
REPOSITORY={{ b.user }}@{{ b.fqdn }}:{{ b.home }}{{ b.pool }}/{{ h }}
|
||||
/usr/local/bin/borg prune -v $REPOSITORY {{ b.options }} -H {{ hostvars[h].borgbackup_retention.hourly }} -d {{ hostvars[h].borgbackup_retention.daily }} -w {{ hostvars[h].borgbackup_retention.weekly }} -m {{ hostvars[h].borgbackup_retention.monthly }} -y {{ hostvars[h].borgbackup_retention.yearly }}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
Loading…
Reference in New Issue
Block a user