1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/borg_ynh.git synced 2024-09-03 18:16:05 +02:00

[enh] Backup your server with borg

This commit is contained in:
ljf 2018-06-14 02:15:06 +02:00
parent d8a10856b8
commit 91c80b11e0
12 changed files with 494 additions and 0 deletions

View file

@ -1,2 +1,5 @@
# borg_ynh
An experimental borg implementation for yunohost
## Usage

27
conf/backup-with-borg.j2 Normal file
View file

@ -0,0 +1,27 @@
#!/bin/bash
filter_hooks() {
ls /usr/share/yunohost/hooks/backup/ /etc/yunohost/hooks.d/backup/ | grep "\-$1_" | cut -d"-" -f2 | uniq
}
# Backup system part conf
conf=$(yunohost app setting {{ app }} conf)
if [ "$conf" = "true" ]
then
yunohost backup create --ignore-apps -n auto_conf --method {{ app }} --system $(filter_hooks conf)
fi
# Backup system data
data=$(yunohost app setting {{ app }} data)
if [ "$data" = "true" ]
then
yunohost backup create --ignore-apps -n auto_data --method {{ app }} --system $(filter_hooks data)
fi
# Backup all apps independently
apps=$(yunohost app setting {{ app }} apps)
for app in $(yunohost app list --installed -b | grep id: | cut -d: -f2); do
if [ "$apps" ?? "$app," ] || [ "$apps" = "all" ]; then
yunohost backup create --ignore-system -n auto_$app --method {{ app }} --apps $app
fi
done

69
conf/backup_method.j2 Normal file
View file

@ -0,0 +1,69 @@
#!/bin/bash
set -e
BORG_PASSPHRASE="{{ passphrase }}"
BORG_RSH="ssh -i /root/.ssh/id_{{ app }}_ed25519 -oStrictHostKeyChecking=accept-new "
repo=ssh://{{ ssh_user }}@{{ server }}/~/backup #$4
do_need_mount() {
true
}
do_backup() {
export BORG_PASSPHRASE
work_dir=$1
name=$2
repo=$3
size=$4
description=$5
LOGFILE=/var/log/backup_borg.log
ERRFILE=/var/log/backup_borg.err
current_date=$(date +"%d_%m_%y_%H:%M")
pushd $work_dir
set +e
borg init -e repokey $repo >> $LOGFILE 2>> $ERRFILE
set -e
borg create $repo::${name}_${current_date} ./ >> $LOGFILE 2>> $ERRFILE
popd
borg prune $repo -P ${name} --keep-daily=7 --keep-weekly=8 --keep-monthly=12 >> $LOGFILE 2>> $ERRFILE
}
do_mount() {
export BORG_PASSPHRASE
work_dir=$1
name=$2
repo=$3
size=$4
description=$5
LOGFILE=/var/log/backup_borg.log
ERRFILE=/var/log/backup_borg.err
borg mount $repo::$name $work_dir >> $LOGFILE 2>> $ERRFILE
}
work_dir=$2
name=$3
size=$5
description=$6
case "$1" in
need_mount)
do_need_mount $work_dir $name $repo $size $description
;;
backup)
do_backup $work_dir $name $repo $size $description
;;
mount)
do_mount
;;
*)
echo "hook called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0

12
conf/systemd.service Normal file
View file

@ -0,0 +1,12 @@
[Unit]
Description=Run backup __APP__
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup⁻with-__APP__
User=root
Group=root
[Install]
WantedBy=multi-user.target

8
conf/systemd.timer.j2 Normal file
View file

@ -0,0 +1,8 @@
[Unit]
Description=Run backup {{ app }} regularly
[Timer]
OnCalendar={{ on_calendar }}
[Install]
WantedBy=timers.target

86
manifest.json Normal file
View file

@ -0,0 +1,86 @@
{
"name": "Borg",
"id": "borg",
"packaging_format": 1,
"description": {
"en": "Backup your server with borg.",
"fr": "Sauvegarder votre serveur avec borg."
},
"version": "1.0",
"url": "https://borgbackup.readthedocs.io",
"license": "BSD-3-Clause",
"maintainer": {
"name": "ljf",
"email": "ljf+borg_ynh@reflexlibre.net",
"url": "https://reflexlibre.net"
},
"requirements": {
"yunohost": ">= 2.7.2"
},
"multi_instance": true,
"services": [],
"arguments": {
"install" : [
{
"name": "server",
"ask": {
"en": "Indicate the server where you want put your backups",
"fr": "Indiquez le serveur où vous voulez faire vos sauvegardes"
},
"example": "example.com:22"
},
{
"name": "ssh_user",
"ask": {
"en": "Indicate the ssh user to use to connect on this server",
"fr": "Indiquez l'utilisateur ssh à utiliser pour se connecter au serveur"
},
"example": "john"
},
{
"name": "passphrase",
"type": "password",
"ask": {
"en": "Indicate a strong passphrase, that you will keep preciously if you want to be able to use your backups",
"fr": "Indiquez une phrase de passe forte que vous garderez précieusement si vous voulez être en mesure d'utiliser vos sauvegardes"
}
},
{
"name": "conf",
"type": "boolean",
"ask": {
"en": "Would you like to backup your YunoHost configuration ?",
"fr": "Souhaitez-vous effectuer des sauvegardes des configurations du système YunoHost ?"
},
"default": true
},
{
"name": "data",
"type": "boolean",
"ask": {
"en": "Would you like to backup mails and user home directory ?",
"fr": "Souhaitez-vous effectuer des sauvegardes des mails et des répertoire des utilisateurs ?"
},
"default": true
},
{
"name": "apps",
"type": "boolean",
"ask": {
"en": "Which apps would you backup (list separated by comma or 'all') ?",
"fr": "Souhaitez-vous effectuer des sauvegardes de vos applications ?"
},
"default": "all"
},
{
"name": "on_calendar",
"ask": {
"en": "Indicate the backup frequency (see systemd OnCalendar format)",
"fr": "Indiquez la fréquence de la sauvegarde (voir le format OnCalendar de systemd)"
},
"example": "Daily",
"default": "Daily"
}
]
}
}

60
scripts/_common.sh Normal file
View file

@ -0,0 +1,60 @@
#!/bin/bash
#=================================================
# COMMON VARIABLES
#=================================================
# App package root directory should be the parent folder
PKG_DIR=$(cd ../; pwd)
pkg_dependencies="python3-pip python3-dev libacl1-dev libssl-dev liblz4-dev"
#=================================================
# COMMON HELPERS
#=================================================
ynh_export () {
local ynh_arg=""
for var in $@;
do
ynh_arg=$(echo $var | awk '{print toupper($0)}')
if [ "$var" == "path_url" ]; then
ynh_arg="PATH"
fi
ynh_arg="YNH_APP_ARG_$ynh_arg"
export $var=${!ynh_arg}
done
}
# Save listed var in YunoHost app settings
# usage: ynh_save_args VARNAME1 [VARNAME2 [...]]
ynh_save_args () {
for var in $@;
do
local setting_var="$var"
if [ "$var" == "path_url" ]; then
setting_var="path"
fi
ynh_app_setting_set $app $setting_var ${!var}
done
}
# Render templates with Jinja2
#
# Attention : Variables should be exported before calling this helper to be
# accessible inside templates.
#
# usage: ynh_render_template some_template output_path
# | arg: some_template - Template file to be rendered
# | arg: output_path - The path where the output will be redirected to
ynh_render_template() {
local template_path=$1
local output_path=$2
# Taken from https://stackoverflow.com/a/35009576
python2.7 -c 'import os, sys, jinja2; sys.stdout.write(
jinja2.Template(sys.stdin.read()
).render(os.environ));' < $template_path > $output_path
}
ynh_configure () {
ynh_backup_if_checksum_is_different $2
ynh_configure "${PKG_DIR}/conf/$1.j2" $2
ynh_store_file_checksum $2
}

30
scripts/backup Executable file
View file

@ -0,0 +1,30 @@
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
source /usr/share/yunohost/helpers
#=================================================
# MANAGE SCRIPT FAILURE
#=================================================
# Exit if an error occurs during the execution of the script
ynh_abort_if_errors
#=================================================
# LOAD SETTINGS
#=================================================
app=$YNH_APP_INSTANCE_NAME
ynh_backup "/usr/local/bin/backup-with-$app"
ynh_backup "/etc/systemd/system/$app.service"
ynh_backup "/etc/systemd/system/$app.timer"
ynh_backup "/etc/yunohost/hooks.d/backup_method/05-$app"
ynh_backup "/root/.ssh/id_${app}_ed25519"
ynh_backup "/root/.ssh/id_${app}_ed25519.pub"

80
scripts/install Executable file
View file

@ -0,0 +1,80 @@
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
source _common.sh
source /usr/share/yunohost/helpers
#=================================================
# MANAGE SCRIPT FAILURE
#=================================================
# Exit if an error occurs during the execution of the script
ynh_abort_if_errors
#=================================================
# RETRIEVE ARGUMENTS FROM THE MANIFEST
#=================================================
export app=$YNH_APP_INSTANCE_NAME
# Retrieve arguments
ynh_export server ssh_user passphrase on_calendar conf data apps
#=================================================
# STORE SETTINGS FROM MANIFEST
#=================================================
ynh_save_args server ssh_user passphrase on_calendar conf data apps
#=================================================
# STORE SETTINGS FROM MANIFEST
#=================================================
ynh_install_app_dependencies $pkg_dependencies
pip3 install setuptools --upgrade
pip3 install borgbackup
#=================================================
# ACTIVATE BACKUP METHODS
#=================================================
mkdir -p /etc/yunohost/hooks.d/backup_method
mkdir -p /usr/share/yunohost/backup_method
#=================================================
# SETUP THE BACKUP METHOD
#=================================================
ynh_configure backup_method "/etc/yunohost/hooks.d/backup_method/05-$app"
#=================================================
# CONFIGURE CRON
#=================================================
ynh_configure backup-with-borg "/usr/local/bin/backup-with-$app"
chmod u+x "/usr/local/bin/backup-with-$app"
ynh_add_systemd_config
ynh_configure systemd.timer "/etc/systemd/system/$app.timer"
#=================================================
# GENERATE SSH KEY
#=================================================
private_key="/root/.ssh/id_${app}_ed25519"
test -f $private_key || ssh-keygen -q -t ed25519 -N "" -f $private_key
#=================================================
# SEND A README FOR THE ADMIN
#=================================================
ynh_print_OFF
message="You should now install the \"Borg Server\" app on $server and fill questions like this:
User: ${ssh_suser}
Public key: $(cat ${private_key}.pub)
Or if you want to use cli:
yunohost app install https://github.com/YunoHost-Apps/borg_server_ynh -a \"ssh_user=$(ssh_user)&public_key=$(cat ${private_key}.pub)\"
If you facing an issue or want to improve this app, please open a new issue in this project: https://github.com/YunoHost-Apps/borg_ynh"
ynh_send_readme_to_admin "$message" "root"
ynh_print_ON

29
scripts/remove Executable file
View file

@ -0,0 +1,29 @@
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
source _common.sh
source /usr/share/yunohost/helpers
#=================================================
# LOAD SETTINGS
#=================================================
app=$YNH_APP_INSTANCE_NAME
#=================================================
# REMOVE DEPENDENCIES
#=================================================
ynh_remove_app_dependencies
#=================================================
# REMOVE FILES
#=================================================
ynh_remove_systemd_config
ynh_secure_remove "/etc/systemd/system/$app.timer"
ynh_secure_remove "/usr/local/bin/backup-with-$app"
ynh_secure_remove "/etc/yunohost/hooks.d/backup_method/05-$app"

60
scripts/restore Executable file
View file

@ -0,0 +1,60 @@
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
if [ ! -e _common.sh ]; then
# Get the _common.sh file if it's not in the current directory
cp ../settings/scripts/_common.sh ./_common.sh
chmod a+rx _common.sh
fi
source _common.sh
source /usr/share/yunohost/helpers
#=================================================
# MANAGE SCRIPT FAILURE
#=================================================
# Exit if an error occurs during the execution of the script
ynh_abort_if_errors
#=================================================
# LOAD SETTINGS
#=================================================
app=$YNH_APP_INSTANCE_NAME
server=$(ynh_app_setting_get $app server)
ssh_user=$(ynh_app_setting_get $app ssh_user)
#=================================================
# STORE SETTINGS FROM MANIFEST
#=================================================
ynh_install_app_dependencies $pkg_dependencies
pip3 install setuptools --upgrade
pip3 install borgbackup
#=================================================
# ACTIVATE BACKUP METHODS
#=================================================
mkdir -p /etc/yunohost/hooks.d/backup_method
mkdir -p /usr/share/yunohost/backup_method
#=================================================
# RESTORE FILES
#=================================================
ynh_restore
#=================================================
# ADVERTISE SERVICE IN ADMIN PANEL
#=================================================
yunohost service add $app
#=================================================
# RESTORE SYSTEMD
#=================================================
systemctl enable $app.service

30
scripts/upgrade Executable file
View file

@ -0,0 +1,30 @@
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
source _common.sh
source /usr/share/yunohost/helpers
#=================================================
# LOAD SETTINGS
#=================================================
app=$YNH_APP_INSTANCE_NAME
#=================================================
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
#=================================================
# Backup the current version of the app
ynh_backup_before_upgrade
ynh_clean_setup () {
# restore it if the upgrade fails
ynh_restore_upgradebackup
}
# Exit if an error occurs during the execution of the script
ynh_abort_if_errors