From b3e2183c1ca79036675b855af021b95181c866f1 Mon Sep 17 00:00:00 2001
From: Arthur BOUDREAULT <arthur@lydra.fr>
Date: Thu, 16 Jun 2022 14:55:58 +0200
Subject: [PATCH] feat: add external backup on borg

---
 roles/ynh_backup/defaults/main.yml    | 11 +++-
 roles/ynh_backup/requirements.yml     |  5 ++
 roles/ynh_backup/tasks/backup.yml     |  2 +-
 roles/ynh_backup/tasks/borgbackup.yml | 82 +++++++++++++++++++++++++++
 roles/ynh_backup/tasks/main.yml       |  7 +++
 5 files changed, 105 insertions(+), 2 deletions(-)
 create mode 100644 roles/ynh_backup/requirements.yml
 create mode 100644 roles/ynh_backup/tasks/borgbackup.yml

diff --git a/roles/ynh_backup/defaults/main.yml b/roles/ynh_backup/defaults/main.yml
index 27500a4..99c2dc4 100644
--- a/roles/ynh_backup/defaults/main.yml
+++ b/roles/ynh_backup/defaults/main.yml
@@ -18,7 +18,7 @@
 #                                                                             #
 #-----------------------------------------------------------------------------#
 
-# Variables for backup
+# Variables for local YunoHost backups
 ynh_backup:
   scheduled: False
   # directory: "/data/backup"
@@ -28,3 +28,12 @@ ynh_backup:
   # scheduled_month: "*"
   # system: True
   # apps: True
+
+# Variables for YunoHost BorgBackup
+ynh_borg_backup_scheduled: False
+borg_source_directories:
+  - "/data/yunohost"
+borg_repository: "/data/backup/live"
+borg_init_command: "borgmatic init -c /etc/borgmatic/{{ borgmatic_config_name }} -e repokey --syslog-verbosity 1"
+borg_archive_name_format: "'{hostname}-yunohost-live-data-{now:%Y-%m-%d-%H%M%S}'"
+ynh_borg_backup_remote_repo: False
diff --git a/roles/ynh_backup/requirements.yml b/roles/ynh_backup/requirements.yml
new file mode 100644
index 0000000..3575211
--- /dev/null
+++ b/roles/ynh_backup/requirements.yml
@@ -0,0 +1,5 @@
+---
+# from Ansible Galaxy
+roles:
+  - name: m3nu.ansible_role_borgbackup
+    version: v0.9.0
diff --git a/roles/ynh_backup/tasks/backup.yml b/roles/ynh_backup/tasks/backup.yml
index 1a5b2bb..c235c3c 100644
--- a/roles/ynh_backup/tasks/backup.yml
+++ b/roles/ynh_backup/tasks/backup.yml
@@ -18,7 +18,7 @@
 #                                                                             #
 #-----------------------------------------------------------------------------#
 
-- name: Create backup folder
+- name: Create backup folder if doesn't already exist
   ansible.builtin.file:
     path: "{{ ynh_backup.directory | default('/home/yunohost.backup/archives') }}"
     state: directory
diff --git a/roles/ynh_backup/tasks/borgbackup.yml b/roles/ynh_backup/tasks/borgbackup.yml
new file mode 100644
index 0000000..3d87cda
--- /dev/null
+++ b/roles/ynh_backup/tasks/borgbackup.yml
@@ -0,0 +1,82 @@
+---
+#-----------------------------------------------------------------------------#
+# ansible-yunohost allows to deploy Yunohost using Ansible                    #
+# Copyright 2021-present Lydra https://www.lydra.fr/                          #
+#                                                                             #
+# this program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# this program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program. If not, see <http://www.gnu.org/licenses/>.        #
+#                                                                             #
+#-----------------------------------------------------------------------------#
+- name: Download BorgBackup role on localhost
+  ansible.builtin.command: ansible-galaxy install m3nu.ansible_role_borgbackup,v0.9.0 -p ~/.ansible/roles
+  delegate_to: localhost
+  become: False
+
+- name: run BorgBackup role
+  ansible.builtin.import_role:
+    name: m3nu.ansible_role_borgbackup
+
+- name: Create backup folder for BorgBackup repository
+  ansible.builtin.file:
+    path: "{{ borg_repository }}"
+    state: directory
+    mode: '0750'
+
+- name: Configure host for Borg Remote repository
+  block:
+    - name: deploy ssh public key for BorgBackup
+      ansible.builtin.copy:
+        src: "{{ borg_ssh_keys_src }}.pub"
+        dest: "{{ borg_ssh_keys_dest }}.pub"
+        owner: "root"
+        group: "root"
+        mode: 0600
+
+    - name: deploy ssh private key for BorgBackup
+      ansible.builtin.copy:
+        src: "{{ borg_ssh_keys_src }}"
+        dest: "{{ borg_ssh_keys_dest }}"
+        owner: "root"
+        group: "root"
+        mode: 0600
+  when: ynh_borg_backup_remote_repo
+
+- name: change SSH command in "/etc/borgmatic/{{ borgmatic_config_name }}"
+  ansible.builtin.lineinfile:
+    path: "/etc/borgmatic/{{ borgmatic_config_name }}"
+    regexp: "# ssh_command: ssh -i ~/.ssh/id_ed25519"
+    line: "{{ ynh_ssh_borg_command }}"
+    state: present
+  when: ynh_ssh_borg_command is defined
+
+
+- name: change archive name in "/etc/borgmatic/{{ borgmatic_config_name }}"
+  ansible.builtin.lineinfile:
+    path: "/etc/borgmatic/{{ borgmatic_config_name }}"
+    regexp: "archive_name_format:"
+    line: "    archive_name_format: {{ borg_archive_name_format }}"
+    state: present
+
+- name: Create borg launch script in /usr/local/bin
+  ansible.builtin.copy:
+    content: |
+      #!/bin/bash
+      . /opt/borgmatic/bin/activate
+      borg "$@"
+    dest: /usr/local/bin/borg
+    owner: root
+    group: root
+    mode: "0755"
+
+- name: Initialize a new Borg repository
+  ansible.builtin.command: "{{ borg_init_command }}"
diff --git a/roles/ynh_backup/tasks/main.yml b/roles/ynh_backup/tasks/main.yml
index 3b41dc2..86cbde3 100644
--- a/roles/ynh_backup/tasks/main.yml
+++ b/roles/ynh_backup/tasks/main.yml
@@ -23,3 +23,10 @@
   when: ynh_backup.scheduled
   tags:
     - backup
+
+- name: Use Borg Backup with YunoHost
+  ansible.builtin.include_tasks: borgbackup.yml
+  when: ynh_borg_backup_scheduled
+  tags:
+    - backup
+    - borg
-- 
GitLab