aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--defaults/main.yml3
-rw-r--r--files/borg.fact18
-rw-r--r--tasks/client.yml89
-rw-r--r--tasks/common.yml25
-rw-r--r--tasks/main.yml10
-rw-r--r--tasks/server.yml26
-rw-r--r--templates/backup.sh.j211
-rw-r--r--vars/Alpine.yml4
-rw-r--r--vars/Gentoo.yml4
-rw-r--r--vars/OpenBSD.yml4
-rw-r--r--vars/RedHat.yml4
11 files changed, 198 insertions, 0 deletions
diff --git a/defaults/main.yml b/defaults/main.yml
new file mode 100644
index 0000000..c798f67
--- /dev/null
+++ b/defaults/main.yml
@@ -0,0 +1,3 @@
+---
+borg_prune_arguments: '--keep-within 30d'
+...
diff --git a/files/borg.fact b/files/borg.fact
new file mode 100644
index 0000000..555143d
--- /dev/null
+++ b/files/borg.fact
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+echo '{'
+if [ -e '/root/.ssh/borg.pub' ]; then
+ pubkey=`cat /root/.ssh/borg.pub | tr -d "\n"`
+ echo -ne ' "pubkey": "'$pubkey'"'
+ pubkey_prefix=",\n"
+fi
+if [ -e '/srv/borg/repos/' ]; then
+ echo -ne "${pubkey_prefix:-}"' "repos": {'"\n"
+ for repo in `ls /srv/borg/repos/`; do
+ id=`awk '/^id =/ {print $3}' /srv/borg/repos/${repo}/config`
+ echo -ne ${repo_prefix:-}' "'$repo'": "'$id'"'
+ repo_prefix=",\n"
+ done
+ echo -ne "\n }"
+fi
+echo -ne "\n}"
diff --git a/tasks/client.yml b/tasks/client.yml
new file mode 100644
index 0000000..b4c4b22
--- /dev/null
+++ b/tasks/client.yml
@@ -0,0 +1,89 @@
+---
+- name: generate borg ssh key on client
+ openssh_keypair:
+ owner: root
+ mode: 0400
+ path: /root/.ssh/borg
+ type: ed25519
+ register: borg_ssh_key
+
+- name: reload ansible_local
+ setup: filter=ansible_local
+ when: borg_ssh_key.changed
+
+- name: Enforce borg authorized key on server
+ authorized_key:
+ user: borg
+ key: "{{ ansible_local.borg.pubkey }}"
+ key_options: 'command="cd /srv/borg/repos/{{ ansible_hostname }}; borg serve --restrict-to-path /srv/borg/repos/{{ ansible_hostname }}",restrict'
+ delegate_to: "{{ borg_server }}"
+
+- name: create borg client repo directory on server
+ file:
+ path: "/srv/borg/repos/{{ ansible_hostname }}"
+ state: directory
+ owner: borg
+ mode: 0700
+ delegate_to: "{{ borg_server }}"
+
+- name: create borg client repo on server
+ command: "borg init --encryption=none /srv/borg/repos/{{ ansible_hostname }}"
+ become: yes
+ become_method: su
+ become_user: borg
+ delegate_to: "{{ borg_server }}"
+ args:
+ creates: "/srv/borg/repos/{{ ansible_hostname }}/config"
+
+- name: reload ansible_local
+ setup: filter=ansible_local
+ delegate_to: "{{ borg_server }}"
+ delegate_facts: True
+ when: hostvars[borg_server]['ansible_local']['borg']['repos'][ansible_hostname] is not defined
+
+- name: make the server known to the client
+ lineinfile:
+ line: "{{ borg_server }} ecdsa-sha2-nistp256 {{ hostvars[borg_server]['ansible_ssh_host_key_ecdsa_public'] }}"
+ path: /root/.ssh/known_hosts
+ create: yes
+
+- name: make the repo directory on the client
+ file:
+ state: directory
+ path: "/root/.config/borg/security/{{ hostvars[borg_server]['ansible_local']['borg']['repos'][ansible_hostname] }}"
+ owner: root
+ mode: 0700
+
+- name: make the repo known to the client
+ copy:
+ dest: "/root/.config/borg/security/{{ hostvars[borg_server]['ansible_local']['borg']['repos'][ansible_hostname] }}/key-type"
+ content: "2"
+ owner: root
+ mode: 0600
+
+- name: deploy borg backup script
+ template:
+ dest: /usr/local/bin/adyxax_backup.sh
+ src: backup.sh.j2
+ owner: root
+ mode: 0500
+
+- name: activate borg cron on alpine
+ lineinfile:
+ line: '0 23 * * * /usr/local/bin/adyxax_backup.sh'
+ path: /etc/crontabs/root
+ when: ansible_os_family == 'Alpine'
+
+- name: activate borg cron on gentoo or redhat
+ file:
+ state: link
+ src: /usr/local/bin/adyxax_backup.sh
+ dest: /etc/cron.daily/backup
+ when: ansible_os_family == 'Gentoo' or ansible_os_family == 'RedHat'
+
+- name: activate borg cron on openbsd
+ lineinfile:
+ line: '0 23 * * * /usr/local/bin/adyxax_backup.sh'
+ path: /var/cron/tabs/root
+ when: ansible_os_family == 'OpenBSD'
+...
diff --git a/tasks/common.yml b/tasks/common.yml
new file mode 100644
index 0000000..057cd25
--- /dev/null
+++ b/tasks/common.yml
@@ -0,0 +1,25 @@
+---
+- name: set distro-specific server variables
+ include_vars: '{{ ansible_os_family }}.yml'
+
+- name: Check if borg is supported on distro
+ fail:
+ msg: "borg tasks are not supported on this operating system yet."
+ when: borg_packages is not defined
+
+- name: Ensure borg is installed
+ package:
+ name: "{{ borg_packages }}"
+
+- name: Push borg gathering fact on client
+ copy:
+ src: borg.fact
+ dest: /etc/ansible/facts.d/
+ mode: 0500
+ owner: root
+ register: borg_gathering_fact
+
+- name: reload ansible_local
+ setup: filter=ansible_local
+ when: borg_gathering_fact.changed
+...
diff --git a/tasks/main.yml b/tasks/main.yml
new file mode 100644
index 0000000..e49b440
--- /dev/null
+++ b/tasks/main.yml
@@ -0,0 +1,10 @@
+---
+- import_tasks: common.yml
+ when: (is_borg_server|default(false)) or borg_server is defined
+
+- import_tasks: server.yml
+ when: (is_borg_server|default(false))
+
+- import_tasks: client.yml
+ when: borg_server is defined
+...
diff --git a/tasks/server.yml b/tasks/server.yml
new file mode 100644
index 0000000..bd40dab
--- /dev/null
+++ b/tasks/server.yml
@@ -0,0 +1,26 @@
+---
+- name: Create borg group on server
+ group:
+ name: borg
+ system: yes
+
+- name: Create borg user on server
+ user:
+ name: borg
+ shell: /bin/sh
+ home: /srv/borg
+ createhome: yes
+ system: yes
+ password_lock: yes
+
+- name: Ensure borg directories exist on server
+ file:
+ state: directory
+ path: "{{ item }}"
+ owner: borg
+ mode: 0700
+ loop:
+ - /srv/borg
+ - /srv/borg/.ssh
+ - /srv/borg/repos
+...
diff --git a/templates/backup.sh.j2 b/templates/backup.sh.j2
new file mode 100644
index 0000000..a029080
--- /dev/null
+++ b/templates/backup.sh.j2
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+{% for job in borg_jobs %}
+{% if job.command_to_pipe is defined %}
+{{ job.command_to_pipe }} | BORG_RSH="ssh -i /root/.ssh/borg" borg create borg@{{ borg_server }}:/srv/borg/repos/{{ ansible_hostname }}::{{ job.name }}-{now} {{ job.path | default('-') }}
+{% else %}
+BORG_RSH="ssh -i /root/.ssh/borg" borg create borg@{{ borg_server }}:/srv/borg/repos/{{ ansible_hostname }}::{{ job.name }}-{now} {{ job.path }}
+{% endif %}
+{% endfor %}
+
+BORG_RSH="ssh -i /root/.ssh/borg" borg prune borg@{{ borg_server }}:/srv/borg/repos/{{ ansible_hostname }} {{ borg_prune_arguments }}
diff --git a/vars/Alpine.yml b/vars/Alpine.yml
new file mode 100644
index 0000000..ff545b1
--- /dev/null
+++ b/vars/Alpine.yml
@@ -0,0 +1,4 @@
+---
+borg_packages:
+ - 'borgbackup'
+...
diff --git a/vars/Gentoo.yml b/vars/Gentoo.yml
new file mode 100644
index 0000000..a9eb31c
--- /dev/null
+++ b/vars/Gentoo.yml
@@ -0,0 +1,4 @@
+---
+borg_packages:
+ - 'app-backup/borgbackup'
+...
diff --git a/vars/OpenBSD.yml b/vars/OpenBSD.yml
new file mode 100644
index 0000000..ff545b1
--- /dev/null
+++ b/vars/OpenBSD.yml
@@ -0,0 +1,4 @@
+---
+borg_packages:
+ - 'borgbackup'
+...
diff --git a/vars/RedHat.yml b/vars/RedHat.yml
new file mode 100644
index 0000000..83a9fbe
--- /dev/null
+++ b/vars/RedHat.yml
@@ -0,0 +1,4 @@
+---
+borg_packages:
+ - borgbackup
+...