From 004919824c477823a103203cfc6ca3b41f17753b Mon Sep 17 00:00:00 2001 From: "Andreas B. Mundt" Date: Sun, 19 Jan 2020 18:51:58 +0100 Subject: [PATCH] Implement borg backup role. --- README | 17 ++++++++++++ cloudbox.yml | 9 +++++-- roles/backup/defaults/main.yml | 8 ++++++ roles/backup/files/backup.service | 6 +++++ roles/backup/files/backup.timer | 10 +++++++ roles/backup/handlers/main.yml | 6 +++++ roles/backup/tasks/main.yml | 32 +++++++++++++++++++++++ roles/backup/templates/backup | 43 +++++++++++++++++++++++++++++++ 8 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 roles/backup/defaults/main.yml create mode 100644 roles/backup/files/backup.service create mode 100644 roles/backup/files/backup.timer create mode 100644 roles/backup/handlers/main.yml create mode 100644 roles/backup/tasks/main.yml create mode 100755 roles/backup/templates/backup diff --git a/README b/README index f6f1dbb..52a83b0 100644 --- a/README +++ b/README @@ -88,3 +88,20 @@ Kiosk • run ansible: ssh-copy-id ansible@1.2.3.4 ansible-playbook kiosk.yml -v --become --ask-become-pass -u ansible -i 1.2.3.4, + +Cloudbox +~~~~~~~~ + • Debian installation: + - user 'ansible' in sudo group + + • check/customize cloudbox.yml + + • download latest nextcloud-*.*.*.tar.bz2 archive and place it as nextcloud.tar.bz2 + in your debian-lan-ansible directory + + • run ansible: + ssh-copy-id ansible@1.2.3.4 + ansible-playbook cloudbox.yml -v --become --ask-become-pass -u ansible -i 1.2.3.4, + + • use 'nc-admin' with password in '/root/nc-admin.pwd' to log into nextcloud. + diff --git a/cloudbox.yml b/cloudbox.yml index 1462cf3..ae46714 100644 --- a/cloudbox.yml +++ b/cloudbox.yml @@ -2,9 +2,9 @@ # This playbook deploys the cloudbox on a minimal installation. - name: apply configuration to the cloudbox - hosts: cloudboxes + hosts: all remote_user: ansible - become: yes + become: Yes vars: if_lan: "enp1s0" ipaddr: "192.168.2.50/24" @@ -12,6 +12,10 @@ DNS: "192.168.2.1" ddns_domain: "something.ddnss.de" ddns_updkey: "138638.some.key.here.635620" + backup_opts: "--exclude-caches -e '*/updater-*/' -e '*/preview/*' -e '*/files_trashbin/*'" + backup_dirs: + - "{{ nc_dir }}" + - "{{ data_dir }}" ansible_python_interpreter: "/usr/bin/python3" roles: @@ -19,3 +23,4 @@ # - ddns-update # - low-power - nextcloud + - backup diff --git a/roles/backup/defaults/main.yml b/roles/backup/defaults/main.yml new file mode 100644 index 0000000..fd66655 --- /dev/null +++ b/roles/backup/defaults/main.yml @@ -0,0 +1,8 @@ +borg_pwd: "{{ lookup('password', '/tmp/borg.pwd length=24') }}" +borg_pwd_file: "/root/borg.pwd" +borg_key_backup: "/root/borg-key.backup" + +## alternative: "ssh://user@host:port/path/to/repo" +backup_repo: "/var/backups/mnt/backup/borg" + +backup_opts: "--exclude-caches" diff --git a/roles/backup/files/backup.service b/roles/backup/files/backup.service new file mode 100644 index 0000000..6f653c2 --- /dev/null +++ b/roles/backup/files/backup.service @@ -0,0 +1,6 @@ +[Unit] +Description=Run backup script + +[Service] +Type=simple +ExecStart=/usr/local/bin/backup diff --git a/roles/backup/files/backup.timer b/roles/backup/files/backup.timer new file mode 100644 index 0000000..866729d --- /dev/null +++ b/roles/backup/files/backup.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Run backup script daily + +[Timer] +OnCalendar=*-*-* 4:00:00 +Persistent=true +AccuracySec=15min + +[Install] +WantedBy=timers.target diff --git a/roles/backup/handlers/main.yml b/roles/backup/handlers/main.yml new file mode 100644 index 0000000..43950ec --- /dev/null +++ b/roles/backup/handlers/main.yml @@ -0,0 +1,6 @@ +- name: enable backup.service and .timer + systemd: + name: backup.timer + state: started + enabled: True + listen: "enable backup.timer" diff --git a/roles/backup/tasks/main.yml b/roles/backup/tasks/main.yml new file mode 100644 index 0000000..5cbd241 --- /dev/null +++ b/roles/backup/tasks/main.yml @@ -0,0 +1,32 @@ +- name: install borg + apt: + name: borgbackup + state: latest + +- name: check if borg password is available + stat: path="{{ borg_pwd_file }}" + register: borg + +- name: dump borg password + shell: echo -n "{{ borg_pwd }}" > "{{ borg_pwd_file }}" ; chmod 0600 "{{ borg_pwd_file }}" + no_log: True + when: not borg.stat.exists + +- name: provide backup script + template: + src: "backup" + dest: "/usr/local/bin/backup" + mode: "0750" + +- name: provide backup.service and .timer + copy: + src: "{{ item }}" + dest: "/etc/systemd/system/{{ item }}" + with_items: + - backup.service + - backup.timer + notify: "enable backup.timer" + +- name: run first backup + command: /usr/local/bin/backup + when: not borg.stat.exists diff --git a/roles/backup/templates/backup b/roles/backup/templates/backup new file mode 100755 index 0000000..9c03514 --- /dev/null +++ b/roles/backup/templates/backup @@ -0,0 +1,43 @@ +#!/bin/bash +set -eu + +REPOSITORY="{{ backup_repo }}" +BACKUP=({{ backup_dirs|join(' ') }}) +EXTRAOPTIONS=({{ backup_opts }}) +export BORG_PASSCOMMAND="cat {{ borg_pwd_file }}" +MOUNTED="" + +MNT="$(echo "$REPOSITORY" | sed "s|\(^.*/mnt\).*|\1|")" +if grep -q "$MNT" /etc/fstab ; then + [ -d "$REPOSITORY" ] || mount -v "$MNT" && MOUNTED="TRUE" +fi + +if [ ! -d "$REPOSITORY" ] ; then + mkdir -vp --mode=0750 "$REPOSITORY" + borg init --encryption=repokey "$REPOSITORY" + borg key export "$REPOSITORY" "{{ borg_key_backup }}" +fi + +if [ -e "{{ nc_dir }}/config/config.php" ] ; then + NCDB="{{ data_dir }}/nextcloud-database.dump" + sudo -u www-data /usr/bin/php {{ nc_dir }}/occ maintenance:mode --on + PW="$(grep dbpassword {{ nc_dir }}/config/config.php | \ + sed -e "s/\W*'dbpassword' => '//" -e "s/',$//")" + + echo -n "Dumping data base into '$NCDB' … " + mysqldump --single-transaction -h localhost -u nextcloud -p"$PW" nextcloud > "$NCDB" + chmod 600 "$NCDB" + echo "done." +fi + +ARCHIVE="$(date +%Y-%m-%d-%H:%M)" +echo "Backup ${BACKUP[@]} to $REPOSITORY." +borg create -v "${EXTRAOPTIONS[@]}" "$REPOSITORY::$ARCHIVE" "${BACKUP[@]}" + +if [ -e "{{ nc_dir }}/config/config.php" ] ; then + sudo -u www-data /usr/bin/php {{ nc_dir }}/occ maintenance:mode --off +fi + +if [ "$MOUNTED" = "TRUE" ] ; then + umount -v "$MNT" +fi