Compare commits

..

No commits in common. "b509ca1dffff1330ef619f43c3fcc4501f5e9057" and "0cb692783104055478fcaf969e81c2d92c2eb159" have entirely different histories.

7 changed files with 27 additions and 55 deletions

View File

@ -1,5 +1,8 @@
Sets up backups to Cloudflare R2
# Instalation
In requirements.yml:
@ -11,38 +14,8 @@ roles:
name: setup-backups
```
# Setup
Create a Cloudflare R2 account and create an admin token.
Create a file under `templates/backup-scripts/<hostname>.sh.j2` that
is a shell script that prepares the data for backup - leave empty if
not necessary.
Then in your playbook run:
```yml
- name: "Setup backups"
hosts: ansible1
roles:
- setup-backups
vars:
backup_bucket_prefix: "backup"
extra_backup_paths: # most sealcode-roles automatically register their backup dirs in the /backup-dirs txt file, but we can add anything not covered by that here
- /var/homebox/data
cloudflare_r2_access_key: "cloudflare R2 Access key (for S3-type API)"
cloudflare_r2_secret_key: "cloudflare R2 secret key (for S3-type API)"
cloudflare_r2_endpoint: https://some_endpoint.r2.cloudflarestorage.com
BACKUP_PASSWORD: password
```
If you are implementing a role that has to register a directory for
automatic backups, add a task in your role's `tasks/backup.yml`:
```yml
- ansible.builtin.lineinfile:
path: "/backup-dirs"
line: "{{juice_sqlite_path}}"
```

View File

@ -1,2 +1 @@
backup_bucket_prefix: backup
extra_backup_paths: []

View File

@ -1,15 +0,0 @@
## The playbook first runs the 'backup.yml' from each role
- name: create the /backup-dirs file
file:
path: "/backup-dirs"
state: "touch"
mode: "0400"
changed_when: "true" # we always want ti give roles a chance to register dirs
- name: Ensure file contains lines from array
lineinfile:
path: /backup-dirs
line: "{{ item }}"
create: yes
state: present
loop: "{{ extra_backup_paths }}"

View File

@ -1,6 +1,14 @@
- debug:
var: group_names
- set_fact:
all_backup_paths: "{{ all_backup_paths | default([]) + (lookup('file', 'inventory/group_vars/' + item + '.yml') | from_yaml | dict2items | selectattr('key', 'equalto', 'backup_paths') | map(attribute='value') | list | first | default([])) }}"
loop: "{{ group_names }}"
when: all_backup_paths is not defined
- debug:
var: all_backup_paths
- name: make sure restic is installed
apt: state=latest pkg=restic
@ -13,7 +21,7 @@
content: "{{ BACKUP_PASSWORD }}"
mode: "0400"
- name: Install rclone
- name: Install boto3 and botocore using apt
become: yes
apt:
name:

View File

@ -1,10 +1,13 @@
#!/bin/bash
# returns code 0 if backup is necessary, 1 otherwise
while IFS= read -r file; do
if [ ! -e "$file" ]; then
exit 0
fi
done </backup-dirs
eval "$DIRS_TO_BACKUP_STR"
for file in "${DIRS_TO_BACKUP[@]}"; do
if [ ! -e "$file" ]; then
exit 0
fi
done
exit 1

View File

@ -7,7 +7,9 @@ $RESTIC --password-file=$PWD_FILE unlock
date
echo "Sending the backup to the destination..."
cat /backup-dirs | xargs -d '\n' $RESTIC --password-file=$PWD_FILE backup
eval "$DIRS_TO_BACKUP_STR" # turn the string into an array
$RESTIC --password-file=$PWD_FILE backup "${DIRS_TO_BACKUP[@]}"
date
echo "Pruning the backup on the destination..."

View File

@ -1,3 +1,5 @@
declare -a DIRS_TO_BACKUP=({% for item in all_backup_paths %}"{{ item }}"{% if not loop.last %} {% endif %}{% endfor %})
export DIRS_TO_BACKUP_STR=$(declare -p DIRS_TO_BACKUP)
export RESTIC_REPOSITORY="rclone:cloudflare-r2:{{ backup_bucket_prefix }}-{{ inventory_hostname }}"
export PWD_FILE=/backup-pwd
export RESTIC=/usr/bin/restic