1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/restic_ynh.git synced 2024-09-03 20:16:22 +02:00

Manifest v2

This commit is contained in:
Salamandar 2024-05-25 09:34:34 +02:00
parent 075ce5d9b5
commit 099f0568b8
14 changed files with 400 additions and 597 deletions

View file

@ -20,13 +20,13 @@ CHECK_READ_DATA=${1:-0}
# Check system part conf
conf=$(sudo yunohost app setting {{ app }} conf)
if [ $conf -eq 1 ];then
sudo {{final_path}}/check_method_{{ app }} auto_conf ${CHECK_READ_DATA}
sudo {{install_dir}}/check_method_{{ app }} auto_conf ${CHECK_READ_DATA}
fi
# Check system data
data=$(sudo yunohost app setting {{ app }} data)
if [ $data -eq 1 ];then
sudo {{final_path}}/check_method_{{ app }} auto_data ${CHECK_READ_DATA}
sudo {{install_dir}}/check_method_{{ app }} auto_data ${CHECK_READ_DATA}
fi
# Check all apps independently
@ -40,7 +40,7 @@ for app in $(sudo /usr/bin/find /etc/yunohost/apps -name backup | cut -d / -f 5)
fi
done
if [ "$check_app" == "true" ];then
sudo {{final_path}}/check_method_{{ app }} auto_${app} ${CHECK_READ_DATA}
sudo {{install_dir}}/check_method_{{ app }} auto_${app} ${CHECK_READ_DATA}
fi
done
rm "$LOCK_FILE"

1
conf/sudoer Normal file
View file

@ -0,0 +1 @@
__APP__ ALL=(root) NOPASSWD: /usr/bin/yunohost*, /bin/journalctl*, /usr/bin/find /etc/yunohost/apps -name backup, __INSTALL_DIR__/check_method___APP__

View file

@ -4,7 +4,7 @@ After=network.target
[Service]
Type=oneshot
ExecStart=__FINALPATH__/check-__APP__
ExecStart=__INSTALL_DIR__/check-__APP__
ExecStartPost=/opt/yunohost/__APP__/restic_check_log___APP__ 0
User=__APP__
Group=__APP__

View file

@ -4,7 +4,7 @@ After=network.target
[Service]
Type=oneshot
ExecStart=__FINALPATH__/check-__APP__ "1"
ExecStart=__INSTALL_DIR__/check-__APP__ "1"
ExecStartPost=/opt/yunohost/__APP__/restic_check_log___APP__ 1
User=__APP__
Group=__APP__

16
doc/POST_INSTALL.md Normal file
View file

@ -0,0 +1,16 @@
You should now allow the following public key for user __SSH_USER__ on server __SERVER__:
__PUBLIC_KEY__
Do so by running those commands on __SERVER__ with user __SSH_USER__:
mkdir ~/.ssh 2>/dev/null
touch ~/.ssh/authorized_keys
chmod u=rw,go= ~/.ssh/authorized_keys
cat << EOPKEY >> ~/.ssh/authorized_keys
__PUBLIC_KEY__
EOPKEY
Also make sure __BACKUP_PATH__ exists and is writable by __SSH_USER__
If you're facing an issue or want to improve this app, please open a new issue in this project: <https://github.com/YunoHost-Apps/restic_ynh>

View file

@ -1,160 +0,0 @@
{
"name": "Restic",
"id": "restic",
"packaging_format": 1,
"description": {
"en": "Backup your server with Restic",
"fr": "Sauvegardez votre serveur avec Restic"
},
"version": "0.12.0~ynh9",
"url": "https://restic.net/",
"upstream": {
"license": "BSD-2-Clause",
"website": "https://restic.net",
"admindoc": "https://restic.readthedocs.io/en/latest/",
"code": "https://github.com/restic/restic"
},
"license": "BSD-2-Clause",
"maintainer": {
"name": "Lionel Coupouchetty-Ramouchetty",
"email": "restic-ynh@coupouchetty-ramouchetty.fr",
"url": "https://gnoobix.net"
},
"requirements": {
"yunohost": ">= 11.2"
},
"multi_instance": true,
"services": [],
"arguments": {
"install" : [
{
"name": "server",
"type": "string",
"ask": {
"en": "Indicate the server where you want put your backups",
"fr": "Indiquez le serveur où vous voulez faire vos sauvegardes"
},
"help":{
"en": "IP address or resolvable hostname of your destination server",
"fr": "Adresse IP ou nom résolvable de votre serveur de destination"
},
"example": "example.com"
},
{
"name": "port",
"type": "string",
"ask": {
"en": "sftp port of your server",
"fr": "Le port sftp de votre serveur"
},
"help":{
"en": "Listening port of your sftp or ssh server. The default value is 22",
"fr": "Le port d'écoute de votre serveur sftp ou ssh. La valeur par défaut est 22"
},
"example": "22",
"default": "22"
},
{
"name": "backup_path",
"type": "string",
"ask": {
"en": "The directory where you want your backup repositories to be created in",
"fr": "Le répertoire dans lequel les dépôts restic seront créés"
},
"help":{
"en": "A complete or relative path to an existing directory on the remote server writable by the remote backup user. Defaults to the login directory",
"fr": "Un chemin complet ou relatif vers un répertoire existant sur le serveur distant et accessible en écriture au compte utilisé pour la sauvegarde. Répertoire d'accueil par défaut"
},
"example": "./backups",
"default": "."
},
{
"name": "ssh_user",
"type": "string",
"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": "string",
"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": "allow_extra_space_use",
"type": "boolean",
"ask": {
"en": "Allow backup method to temporarily use more space?",
"fr": "Permettre à la sauvegarde de consommer temporairement de l'espace supplémentaire?"
},
"help":{
"en": "Some applications as Gitlab can't be backed up with the standard method and require extra space temporarily",
"fr": "Certaines applications comme Gitlab ne peuvent être sauvegardées avec la méthode standard et nécessitent d'utiliser plus d'espace disque temporairement"
},
"default": true
},
{
"name": "on_calendar",
"type": "string",
"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": "*-*-* 0:15:00"
},
{
"name": "check_on_calendar",
"type": "string",
"ask": {
"en": "Indicate the backup check frequency (see systemd OnCalendar format)",
"fr": "Indiquez la fréquence de vérification de la sauvegarde (voir le format OnCalendar de systemd)"
},
"example": "Tue *-*-* 00:15:00",
"default": "Sat *-*-8..31 3:15:00"
},
{
"name": "check_read_data_on_calendar",
"type": "string",
"ask": {
"en": "Indicate the complete backup check frequency (see systemd OnCalendar format)",
"fr": "Indiquez la fréquence de vérification complète de la sauvegarde (voir le format OnCalendar de systemd)"
},
"example": "Tue *-*-* 00:15:00",
"default": "Sat *-*-1..7 3:15:00"
}
]
}
}

133
manifest.toml Normal file
View file

@ -0,0 +1,133 @@
#:schema https://raw.githubusercontent.com/YunoHost/apps/master/schemas/manifest.v2.schema.json
packaging_format = 2
id = "restic"
name = "Restic"
description.en = "Backup your server with Restic"
description.fr = "Sauvegardez votre serveur avec Restic"
version = "0.12.0~ynh9"
maintainers = ["Lionel Coupouchetty-Ramouchetty"]
[upstream]
license = "BSD-2-Clause"
website = "https://restic.net"
admindoc = "https://restic.readthedocs.io/en/latest/"
code = "https://github.com/restic/restic"
[integration]
yunohost = ">= 11.2"
architectures = "all"
multi_instance = true
ldap = "not_relevant"
sso = "not_relevant"
disk = "50M" # FIXME: replace with an **estimate** minimum disk requirement. e.g. 20M, 400M, 1G, ...
ram.build = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ...
ram.runtime = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ...
[install]
[install.server]
ask.en = "Indicate the server where you want put your backups"
ask.fr = "Indiquez le serveur où vous voulez faire vos sauvegardes"
help.en = "IP address or resolvable hostname of your destination server"
help.fr = "Adresse IP ou nom résolvable de votre serveur de destination"
type = "string"
example = "example.com"
[install.port]
ask.en = "sftp port of your server"
ask.fr = "Le port sftp de votre serveur"
help.en = "Listening port of your sftp or ssh server. The default value is 22"
help.fr = "Le port d'écoute de votre serveur sftp ou ssh. La valeur par défaut est 22"
type = "string"
example = "22"
default = "22"
[install.backup_path]
ask.en = "The directory where you want your backup repositories to be created in"
ask.fr = "Le répertoire dans lequel les dépôts restic seront créés"
help.en = "A complete or relative path to an existing directory on the remote server writable by the remote backup user. Defaults to the login directory"
help.fr = "Un chemin complet ou relatif vers un répertoire existant sur le serveur distant et accessible en écriture au compte utilisé pour la sauvegarde. Répertoire d'accueil par défaut"
type = "string"
example = "./backups"
default = "."
[install.ssh_user]
ask.en = "Indicate the ssh user to use to connect on this server"
ask.fr = "Indiquez l'utilisateur ssh à utiliser pour se connecter au serveur"
type = "string"
example = "john"
[install.passphrase]
ask.en = "Indicate a strong passphrase, that you will keep preciously if you want to be able to use your backups"
ask.fr = "Indiquez une phrase de passe forte que vous garderez précieusement si vous voulez être en mesure d'utiliser vos sauvegardes"
type = "password"
[install.conf]
ask.en = "Would you like to backup your YunoHost configuration ?"
ask.fr = "Souhaitez-vous effectuer des sauvegardes des configurations du système YunoHost ?"
type = "boolean"
default = true
[install.data]
ask.en = "Would you like to backup mails and user home directory ?"
ask.fr = "Souhaitez-vous effectuer des sauvegardes des mails et des répertoire des utilisateurs ?"
type = "boolean"
default = true
[install.apps]
ask.en = "Which apps would you backup (list separated by comma or 'all') ?"
ask.fr = "Souhaitez-vous effectuer des sauvegardes de vos applications ?"
type = "string"
default = "all"
[install.allow_extra_space_use]
ask.en = "Allow backup method to temporarily use more space?"
ask.fr = "Permettre à la sauvegarde de consommer temporairement de l'espace supplémentaire?"
help.en = "Some applications as Gitlab can't be backed up with the standard method and require extra space temporarily"
help.fr = "Certaines applications comme Gitlab ne peuvent être sauvegardées avec la méthode standard et nécessitent d'utiliser plus d'espace disque temporairement"
type = "boolean"
default = true
[install.on_calendar]
ask.en = "Indicate the backup frequency (see systemd OnCalendar format)"
ask.fr = "Indiquez la fréquence de la sauvegarde (voir le format OnCalendar de systemd)"
type = "string"
example = "Daily"
default = "*-*-* 0:15:00"
[install.check_on_calendar]
ask.en = "Indicate the backup check frequency (see systemd OnCalendar format)"
ask.fr = "Indiquez la fréquence de vérification de la sauvegarde (voir le format OnCalendar de systemd)"
type = "string"
example = "Tue *-*-* 00:15:00"
default = "Sat *-*-8..31 3:15:00"
[install.check_read_data_on_calendar]
ask.en = "Indicate the complete backup check frequency (see systemd OnCalendar format)"
ask.fr = "Indiquez la fréquence de vérification complète de la sauvegarde (voir le format OnCalendar de systemd)"
type = "string"
example = "Tue *-*-* 00:15:00"
default = "Sat *-*-1..7 3:15:00"
[resources]
[resources.sources.main]
amd64.url = "https://github.com/restic/restic/releases/download/v0.16.2/restic_0.16.2_linux_amd64.bz2"
amd64.sha256 = "dae5e6e39107a66dc5c8ea59f6f27b16c54bd6be31f57e3281f6d87de30e05b0"
i386.url = "https://github.com/restic/restic/releases/download/v0.16.2/restic_0.16.2_linux_386.bz2"
i386.sha256 = "692e70ade358ad4fe19f0cd5fbaf21c3830d0f23c3d4e491a043f6cbc1b5cf59"
arm64.url = "https://github.com/restic/restic/releases/download/v0.16.2/restic_0.16.2_linux_arm64.bz2"
arm64.sha256 = "efdd75eb5c12af6fec4189aa57dc777035a87dd57204daa52293901199569157"
armhf.url = "https://github.com/restic/restic/releases/download/v0.16.2/restic_0.16.2_linux_arm.bz2"
armhf.sha256 = "60376b01b334a0cee3a59016f44dde8b336de2b6aa44f1e6e403d307990c47a0"
in_subdir = false
rename = "restic"
[resources.system_user]
[resources.install_dir]
[resources.permissions]

View file

@ -3,132 +3,88 @@
#=================================================
# COMMON VARIABLES
#=================================================
# App package root directory should be the parent folder
PKG_DIR=$(cd ../; pwd)
RESTIC_VERSION="0.16.2"
systemd_services_suffixes=( "" "_check" "_check_read_data" )
# Install restic if restic is not here
install_restic () {
architecture=$(uname -m)
arch=''
case $architecture in
i386|i686)
arch="386"
;;
x86_64)
arch=amd64
;;
armv*)
arch=arm
;;
aarch64)
arch=arm64
;;
*)
echo
ynh_die --message="Unsupported architecture \"$architecture\""
;;
esac
wget https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/restic_${RESTIC_VERSION}_linux_${arch}.bz2 -O /tmp/restic.bz2 2>&1 >/dev/null
wget https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/SHA256SUMS -O /tmp/restic-sha256sums 2>&1 >/dev/null
expected_sum=$(grep restic_${RESTIC_VERSION}_linux_${arch}.bz2 /tmp/restic-sha256sums | awk '{print $1}')
sum=$(sha256sum /tmp/restic.bz2 | awk '{print $1}')
if [ "$sum" == "$expected_sum" ];then
pkill restic || true
bunzip2 /tmp/restic.bz2 -f -c > /usr/local/bin/${app}
chmod +x /usr/local/bin/${app}
else
ynh_die --message="\nDownloaded file does not match expected sha256 sum, aborting"
fi
ynh_setup_source --source_id=main --dest_dir="$install_dir"
chmod +x "$install_dir/restic"
}
_gen_and_save_public_key() {
public_key=""
if [[ -n "$server" ]]; then
private_key="/root/.ssh/id_${app}_ed25519"
if [ ! -f "$private_key" ]; then
ssh-keygen -q -t ed25519 -N "" -f "$private_key"
fi
public_key=$(cat "$private_key.pub")
fi
ynh_app_setting_set --app="$app" --key=public_key --value="$public_key"
}
_set_ssh_config() {
if grep -q "$app" "/root/.ssh/config" 2>/dev/null; then
return 0
fi
cat << EOCONF >> /root/.ssh/config
# begin $app ssh config
Host ${server}
Hostname ${server}
Port ${port}
User ${ssh_user}
IdentityFile ${private_key}
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
# end $app ssh config
EOCONF
}
#=================================================
# 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
}
ynh_configure () {
ynh_backup_if_checksum_is_different $2
ynh_render_template "${PKG_DIR}/conf/$1.j2" "$2"
ynh_store_file_checksum $2
}
_ynh_add_config_j2() {
# Declare an array to define the options of this helper.
local legacy_args=tdv
local -A args_array=([t]=template= [d]=destination=)
local template
local destination
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
local template_path
# Send an email to inform the administrator
#
# usage: ynh_send_readme_to_admin app_message [recipients]
# | arg: app_message - The message to send to the administrator.
# | arg: recipients - The recipients of this email. Use spaces to separate multiples recipients. - default: root
# example: "root admin@domain"
# If you give the name of a YunoHost user, ynh_send_readme_to_admin will find its email adress for you
# example: "root admin@domain user1 user2"
ynh_send_readme_to_admin() {
local app_message="${1:-...No specific information...}"
local recipients="${2:-root}"
# Retrieve the email of users
find_mails () {
local list_mails="$1"
local mail
local recipients=" "
# Read each mail in argument
for mail in $list_mails
do
# Keep root or a real email address as it is
if [ "$mail" = "root" ] || echo "$mail" | grep --quiet "@"
then
recipients="$recipients $mail"
if [ -f "$YNH_APP_BASEDIR/conf/$template" ]; then
template_path="$YNH_APP_BASEDIR/conf/$template"
elif [ -f "$template" ]; then
template_path=$template
else
# But replace an user name without a domain after by its email
if mail=$(ynh_user_get_info "$mail" "mail" 2> /dev/null)
then
recipients="$recipients $mail"
fi
fi
done
echo "$recipients"
}
recipients=$(find_mails "$recipients")
local mail_subject="☁️🆈🅽🅷☁️: \`$app\` was just installed!"
local mail_message="This is an automated message from your beloved YunoHost server.
Specific information for the application $app.
$app_message
---
Automatic diagnosis data from YunoHost
$(yunohost tools diagnosis | grep -B 100 "services:" | sed '/services:/d')"
# Define binary to use for mail command
if [ -e /usr/bin/bsd-mailx ]
then
local mail_bin=/usr/bin/bsd-mailx
else
local mail_bin=/usr/bin/mail.mailutils
ynh_die --message="The provided template $template doesn't exist"
fi
# Send the email to the recipients
echo "$mail_message" | $mail_bin -a "Content-Type: text/plain; charset=UTF-8" -s "$mail_subject" "$recipients"
ynh_backup_if_checksum_is_different --file="$destination"
# Make sure to set the permissions before we copy the file
# This is to cover a case where an attacker could have
# created a file beforehand to have control over it
# (cp won't overwrite ownership / modes by default...)
touch $destination
chown root:root $destination
chmod 640 $destination
cp -f "$template_path" "$destination"
_ynh_apply_default_permissions $destination
ynh_replace_vars --file="$destination"
ynh_store_file_checksum --file="$destination"
}

View file

@ -1,7 +1,5 @@
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
@ -10,45 +8,33 @@
source ../settings/scripts/_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
#=================================================
ynh_print_info --message="Loading installation settings..."
export app=$YNH_APP_INSTANCE_NAME
export final_path="/opt/yunohost/${app}"
#=================================================
# DECLARE DATA AND CONF FILES TO BACKUP
#=================================================
ynh_print_info --message="Declaring files to be backed up..."
#=================================================
# BACKUP VARIOUS FILES
# BACKUP THE APP MAIN DIR
#=================================================
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/systemd/system/${app}_check.service"
ynh_backup "/etc/systemd/system/${app}_check.timer"
ynh_backup "/etc/systemd/system/${app}_check_read_data.service"
ynh_backup "/etc/systemd/system/${app}_check_read_data.timer"
ynh_backup "/etc/yunohost/hooks.d/backup_method/05-${app}_app"
ynh_backup "${final_path}/check_method_${app}"
ynh_backup "${final_path}/restic_log_${app}"
ssh_dir="/root/.ssh"
ynh_backup "${ssh_dir}/id_${app}_ed25519"
ynh_backup "${ssh_dir}/id_${app}_ed25519.pub"
ynh_backup "${ssh_dir}/config"
ynh_backup --src_path="$install_dir"
#=================================================
# SYSTEM CONFIGURATION
#=================================================
for suffix in "${systemd_services_suffixes[@]}"; do
ynh_backup --src_path="/etc/systemd/system/$app$suffix.timer"
ynh_backup --src_path="/etc/systemd/system/$app$suffix.service"
done
ynh_backup --src_path="/etc/yunohost/hooks.d/backup_method/05-${app}_app"
ynh_backup --src_path="/etc/sudoers.d/$app"
ynh_backup --src_path="/root/.ssh/id_${app}_ed25519"
ynh_backup --src_path="/root/.ssh/id_${app}_ed25519.pub"
# FIXME: uh do we really want to backup it all?
ynh_backup --src_path="/root/.ssh/config"
#=================================================
# END OF SCRIPT

View file

@ -1,7 +1,5 @@
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
@ -9,188 +7,84 @@
source _common.sh
source /usr/share/yunohost/helpers
#=================================================
# MANAGE SCRIPT FAILURE
#=================================================
ynh_clean_setup () {
ynh_clean_check_starting
}
# 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
export final_path="/opt/yunohost/${app}"
# Retrieve arguments
ynh_export server port ssh_user backup_path passphrase on_calendar check_on_calendar check_read_data_on_calendar conf data apps allow_extra_space_use
#=================================================
# STORE SETTINGS FROM MANIFEST
#=================================================
ynh_script_progression --message="Storing installation settings..."
ynh_save_args server port ssh_user backup_path passphrase on_calendar check_on_calendar check_read_data_on_calendar conf data apps allow_extra_space_use
# passwords aren't saved by default
ynh_app_setting_set --app=$app --key=passphrase --value="$passphrase"
#=================================================
# INSTALL RESTIC
#=================================================
ynh_script_progression --message="Installing restic binary" --weight=7
ynh_script_progression --message="Installing Restic..." --weight=7
install_restic
#=================================================
# CREATE APP USER
#=================================================
ynh_script_progression --message="Creating user ${app}"
_gen_and_save_public_key
useradd -m ${app}
ynh_script_progression --message="Configure ${app} user sudoer rights"
cat > /tmp/${app}_sudoer << EOSUDOER
${app} ALL = (root) NOPASSWD: /usr/bin/yunohost*, /bin/journalctl*, /usr/bin/find /etc/yunohost/apps -name backup, ${final_path}/check_method_${app}
EOSUDOER
visudo -cf /tmp/${app}_sudoer && mv /tmp/${app}_sudoer /etc/sudoers.d/${app}
#=================================================
# ACTIVATE BACKUP METHODS
#=================================================
ynh_script_progression --message="Activating backup methods"
mkdir -p /etc/yunohost/hooks.d/backup_method
mkdir -p /usr/share/yunohost/backup_method
_set_ssh_config
#=================================================
# SETUP THE BACKUP METHOD
#=================================================
ynh_script_progression --message="Setting up backup methods"
ynh_script_progression --message="Setting up backup method..." --weight=1
ynh_configure backup_method "/etc/yunohost/hooks.d/backup_method/05-${app}_app"
ynh_configure check_method "${final_path}/check_method_${app}"
mkdir -p /etc/yunohost/hooks.d/backup
mkdir -p /etc/yunohost/hooks.d/backup_method
mkdir -p /usr/share/yunohost/backup_method
## Backup method
_ynh_add_config_j2 --template="backup_method" --destination="/etc/yunohost/hooks.d/backup_method/05-${app}_app"
chmod go=--- "/etc/yunohost/hooks.d/backup_method/05-${app}_app"
_ynh_add_config_j2 --template="backup-with-restic" --destination="$install_dir/backup-with-${app}"
chmod u+x "$install_dir/backup-with-restic"
## Check method
_ynh_add_config_j2 --template="check_method" --destination="$install_dir/check_method_${app}"
_ynh_add_config_j2 --template="check-restic" --destination="$install_dir/check-${app}"
chmod u+x "$install_dir/check-$app"
## Backup log script
_ynh_add_config_j2 --template="restic_log" --destination="${install_dir}/restic_log_${app}"
chmod u+x "$install_dir/restic_log_${app}"
# Check log script
_ynh_add_config_j2 --template="restic_check_log" --destination="${install_dir}/restic_check_log_${app}"
chmod u+x "$install_dir/restic_check_log_${app}"
chown -R "$app:$app" "$install_dir"
#=================================================
# SETUP LOG SCRIPTS
# SYSTEM CONFIGURATION
#=================================================
ynh_script_progression --message="Setting up backup log script"
ynh_script_progression --message="Adding system configurations related to $app..." --weight=1
ynh_configure restic_log "${final_path}/restic_log_${app}"
chmod +x "${final_path}/restic_log_${app}"
chown ${app}: "${final_path}/restic_log_${app}"
# Systemd services and timers
for suffix in "${systemd_services_suffixes[@]}"; do
ynh_add_systemd_config --service="$app$suffix" --template="systemd$suffix.service"
_ynh_add_config_j2 --template="systemd$suffix.timer" --destination="/etc/systemd/system/$app$suffix.timer"
systemctl disable --quiet "${app}$suffix.service"
systemctl enable --quiet "${app}$suffix.time"
systemctl start --quiet "${app}$suffix.time"
ynh_script_progression --message="Setting up check log script"
ynh_configure restic_check_log "${final_path}/restic_check_log_${app}"
chmod +x "${final_path}/restic_check_log_${app}"
chown ${app}: "${final_path}/restic_check_log_${app}"
yunohost service add "$app$suffix" --description="Restic backup program ($app$suffix)" \
--test_status="systemctl show $app$suffix.service -p ActiveState --value | grep -v failed"
done
#=================================================
# CONFIGURE CRON
#=================================================
ynh_script_progression --message="Configuring cron" --weight=5
ynh_add_config --template="sudoer" --destination="/etc/sudoers.d/$app"
chown root:root "/etc/sudoers.d/$app"
ynh_configure backup-with-restic "/usr/local/bin/backup-with-${app}"
ynh_configure check-restic "${final_path}/check-${app}"
chmod +x "/usr/local/bin/backup-with-${app}"
chown ${app}: "/usr/local/bin/backup-with-${app}"
chmod +x "${final_path}/check-${app}"
chmod +x "${final_path}/check_method_${app}"
ynh_add_systemd_config --service=${app} --template=systemd.service
ynh_add_systemd_config --service=${app}_check --template=systemd_check.service
ynh_add_systemd_config --service=${app}_check_read_data --template=systemd_check_read_data.service
ynh_configure systemd.timer "/etc/systemd/system/${app}.timer"
ynh_configure systemd_check.timer "/etc/systemd/system/${app}_check.timer"
ynh_configure systemd_check_read_data.timer "/etc/systemd/system/${app}_check_read_data.timer"
systemctl disable --quiet ${app}.service
systemctl disable --quiet ${app}_check.service
systemctl disable --quiet ${app}_check_read_data.service
systemctl enable --quiet ${app}.timer
systemctl enable --quiet ${app}_check.timer
systemctl enable --quiet ${app}_check_read_data.timer
systemctl start ${app}.timer
systemctl start ${app}_check.timer
systemctl start ${app}_check_read_data.timer
ynh_use_logrotate --logfile="/var/log/restic_backup_${app}.log"
ynh_use_logrotate --logfile="/var/log/restic_backup_${app}.err"
ynh_use_logrotate --logfile="/var/log/restic_check_${app}.log"
ynh_use_logrotate --logfile="/var/log/restic_check_${app}.err"
#=================================================
# SET PERMISSIONS ON FINAL PATH
#=================================================
ynh_script_progression --message="Set permissions on ${final_path}"
chown -R ${app}: ${final_path}
#=================================================
# SETUP LOGROTATE
#=================================================
ynh_script_progression --message="Configuring logrotate"
ynh_use_logrotate --logfile=/var/log/restic_backup_${app}.log
ynh_use_logrotate --logfile=/var/log/restic_backup_${app}.err
ynh_use_logrotate --logfile=/var/log/restic_check_${app}.log
ynh_use_logrotate --logfile=/var/log/restic_check_${app}.err
#=================================================
# GENERATE SSH KEY
#=================================================
ynh_script_progression --message="Generating private key"
ssh_dir="/root/.ssh"
if [ ! -d "${ssh_dir}" ];then
mkdir -p "${ssh_dir}"
fi
private_key="${ssh_dir}/id_${app}_ed25519"
test -f $private_key || ssh-keygen -q -t ed25519 -N "" -f $private_key
#=================================================
# GENERATE SSH CONFIG
#=================================================
ynh_script_progression --message="Generating ssh config for ${app} server ${server}"
grep -q "${app}" ${ssh_dir}/config 2>/dev/null || cat << EOCONF >> ${ssh_dir}/config
# begin $app ssh config
Host ${server}
Hostname ${server}
Port ${port}
User ${ssh_user}
IdentityFile ${private_key}
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
# end $app ssh config
EOCONF
#=================================================
# Display key
#=================================================
ynh_script_progression --message="You should now allow the following public key for user ${ssh_user} on server ${server}:
$(cat ${private_key}.pub)"
#=================================================
# SEND A README FOR THE ADMIN
#=================================================
ynh_script_progression --message="Sending post-installation instructions to admin" --last
message="You should now allow the following public key for user ${ssh_user} on server ${server}:
$(cat ${private_key}.pub)
Do so by running those commands on ${server} with user ${ssh_user}:
mkdir ~/.ssh 2>/dev/null
touch ~/.ssh/authorized_keys
chmod u=rw,go= ~/.ssh/authorized_keys
cat << EOPKEY >> ~/.ssh/authorized_keys
$(cat ${private_key}.pub)
EOPKEY
$(if [ "$backup_path" != "./" ];then echo "Also make sure ${backup_path} exists and is writable by ${ssh_user}";fi)
If you're facing an issue or want to improve this app, please open a new issue in this project: https://github.com/YunoHost-Apps/restic_ynh"
ynh_send_readme_to_admin "$message" "root"
#=================================================
# END OF SCRIPT
#=================================================
ynh_script_progression --message="Installation of $app completed"
ynh_script_progression --message="Installation of $app completed" --last

View file

@ -1,7 +1,5 @@
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
@ -9,71 +7,37 @@
source _common.sh
source /usr/share/yunohost/helpers
#=================================================
# LOAD SETTINGS
#=================================================
ynh_script_progression --message="Loading installation settings..."
app=$YNH_APP_INSTANCE_NAME
export final_path="/opt/yunohost/${app}"
#=================================================
# REMOVE LOGROTATE CONFIGURATION
# REMOVE SYSTEM CONFIGURATIONS
#=================================================
ynh_script_progression --message="Removing logrotate configuration..."
ynh_script_progression --message="Removing system configurations related to $app..." --weight=1
# Systemd services and timers
for suffix in "${systemd_services_suffixes[@]}"; do
if ynh_exec_warn_less yunohost service status "$app_suffix" >/dev/null; then
yunohost service remove "$app_suffix"
fi
systemctl stop "$app$suffix.timer"
systemctl --quiet disable "$app$suffix.timer"
ynh_remove_systemd_config --service="$app$suffix"
ynh_secure_remove "/etc/systemd/system/$app$suffix.timer"
done
# Remove the app-specific logrotate config
ynh_remove_logrotate
#=================================================
# REMOVE DEPENDENCIES
#=================================================
ynh_script_progression --message="Removing dependencies..." --weight=4
# Remove sudoers
rm "/etc/sudoers.d/$app"
# Remove metapackage and its dependencies
ynh_remove_app_dependencies
#=================================================
# SPECIFIC REMOVE
#=================================================
# REMOVE VARIOUS FILES
#=================================================
ynh_script_progression --message="Removing various files..." --weight=2
systemctl stop ${app}.timer
systemctl --quiet disable ${app}.timer
ynh_remove_systemd_config --service=${app}
ynh_remove_systemd_config --service=${app}_check
ynh_remove_systemd_config --service=${app}_check_read_data
ynh_secure_remove "/etc/systemd/system/${app}.timer"
ynh_secure_remove "/etc/systemd/system/${app}_check.timer"
ynh_secure_remove "/etc/systemd/system/${app}_check_read_data.timer"
ynh_secure_remove "/usr/local/bin/backup-with-${app}"
ynh_secure_remove "/etc/yunohost/hooks.d/backup_method/05-${app}_app"
ynh_secure_remove "${final_path}/check_method_${app}"
ynh_secure_remove "${final_path}/check-${app}"
ynh_secure_remove "${final_path}/restic_log_${app}"
ynh_secure_remove "${final_path}/restic_check_log_${app}"
ynh_secure_remove "${final_path}"
#=================================================
# REMOVE SSH CONFIG
#=================================================
ynh_script_progression --message="Removing ssh config"
ssh_dir="/root/.ssh"
sed -e "/begin ${app}/,/end ${app}/{/.*/d}" ${ssh_dir}/config -i || true
#=================================================
# GENERIC FINALIZATION
#=================================================
# REMOVE DEDICATED USER
#=================================================
ynh_script_progression --message="Removing sudoers rights for user ${app}"
rm /etc/sudoers.d/${app}
ynh_script_progression --message="Removing ${app} user" --last
userdel ${app}
sed -e "/begin ${app}/,/end ${app}/{/.*/d}" /root/.ssh/config -i || true
#=================================================
# END OF SCRIPT

View file

@ -1,7 +1,5 @@
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
@ -11,53 +9,47 @@ source ../settings/scripts/_common.sh
source /usr/share/yunohost/helpers
#=================================================
# MANAGE SCRIPT FAILURE
# RESTORE THE APP MAIN DIR
#=================================================
ynh_script_progression --message="Restoring the app main directory..." --weight=1
ynh_clean_setup () {
ynh_clean_check_starting
}
# Exit if an error occurs during the execution of the script
ynh_abort_if_errors
ynh_restore_file --origin_path="$install_dir"
#=================================================
# LOAD SETTINGS
#=================================================
ynh_script_progression --message="Loading installation settings..."
export app=$YNH_APP_INSTANCE_NAME
export server=$(ynh_app_setting_get --app=$app --key=server)
export final_path="/opt/yunohost/${app}"
#=================================================
# INSTALL RESTIC
#=================================================
install_restic
chown -R "$app:$app" "$install_dir"
#=================================================
# ACTIVATE BACKUP METHODS
#=================================================
ynh_script_progression --message="Setting up backup method..." --weight=1
mkdir -p /etc/yunohost/hooks.d/backup
mkdir -p /etc/yunohost/hooks.d/backup_method
mkdir -p /usr/share/yunohost/backup_method
#=================================================
# RESTORE FILES
#=================================================
ynh_restore
ynh_restore_file --origin_path="/etc/yunohost/hooks.d/backup_method/05-${app}_app"
chmod go=--- "/etc/yunohost/hooks.d/backup_method/05-${app}_app"
#=================================================
# ENABLE TIMER
# RESTORE SYSTEM CONFIGURATIONS
#=================================================
ynh_script_progression --message="Restoring system configurations related to $app..." --weight=1
systemctl enable --quiet ${app}.timer
systemctl enable --quiet ${app}_check.timer
systemctl enable --quiet ${app}_check_read_data.timer
systemctl start ${app}.timer
systemctl start ${app}_check.timer
systemctl start ${app}_check_read_data.timer
ynh_restore_file --origin_path="/etc/sudoers.d/$app"
chown root:root "/etc/sudoers.d/$app"
ynh_restore --origin_path="/root/.ssh/id_${app}_ed25519"
ynh_restore --origin_path="/root/.ssh/id_${app}_ed25519.pub"
# FIXME: restore the .ssh/config instead?
_set_ssh_config
for suffix in "${systemd_services_suffixes[@]}"; do
ynh_restore_file --origin_path="/etc/systemd/system/$app$suffix.timer"
ynh_restore_file --origin_path="/etc/systemd/system/$app$suffix.service"
systemctl enable "$app$suffix.timer"
systemctl start "$app$suffix.timer"
done
#=================================================
# END OF SCRIPT

View file

@ -1,7 +1,5 @@
#!/bin/bash
#=================================================
# GENERIC START
#=================================================
# IMPORT GENERIC HELPERS
#=================================================
@ -10,46 +8,31 @@ source _common.sh
source /usr/share/yunohost/helpers
#=================================================
# LOAD SETTINGS
# STOP SYSTEMD SERVICE
#=================================================
ynh_script_progression --message="Loading installation settings..."
export app=$YNH_APP_INSTANCE_NAME
export final_path="/opt/yunohost/${app}"
export server=$(ynh_app_setting_get $app server)
export port=$(ynh_app_setting_get $app port)
export ssh_user=$(ynh_app_setting_get $app ssh_user)
export backup_path=$(ynh_app_setting_get $app backup_path)
export passphrase=$(ynh_app_setting_get $app passphrase)
export on_calendar=$(ynh_app_setting_get $app on_calendar)
export check_on_calendar=$(ynh_app_setting_get $app check_on_calendar)
export check_read_data_on_calendar=$(ynh_app_setting_get $app check_read_data_on_calendar)
export conf=$(ynh_app_setting_get $app conf)
export data=$(ynh_app_setting_get $app data)
export apps=$(ynh_app_setting_get $app apps)
export allow_extra_space_use=$(ynh_app_setting_get $app allow_extra_space_use)
ynh_script_progression --message="Stopping $app's systemd service..." --weight=1
#=================================================
# CHECK VERSION
# ENSURE DOWNWARD COMPATIBILITY
#=================================================
#ynh_script_progression --message="Ensuring downward compatibility..." --weight=1
upgrade_type=$(ynh_check_app_version_changed)
#=================================================
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
#=================================================
ynh_script_progression --message="Backing up the app before upgrading (may take a while)..."
#REMOVEME? ynh_script_progression --message="Backing up the app before upgrading (may take a while)..."
# Backup the current version of the app
ynh_backup_before_upgrade
ynh_clean_setup () {
#REMOVEME? ynh_backup_before_upgrade
#REMOVEME? ynh_clean_setup () {
ynh_clean_check_starting
# Restore it if the upgrade fails
ynh_restore_upgradebackup
#REMOVEME? ynh_restore_upgradebackup
}
# Exit if an error occurs during the execution of the script
ynh_abort_if_errors
#REMOVEME? ynh_abort_if_errors
if grep "${app}.timer" /etc/yunohost/services.yml > /dev/null ; then
@ -73,7 +56,7 @@ ynh_script_progression --message="Creating user ${app}"
id ${app} 2>/dev/null || useradd -m ${app}
ynh_script_progression --message="Configure ${app} user sudoer rights"
cat > /tmp/${app}_sudoer << EOSUDOER
${app} ALL = (root) NOPASSWD: /usr/bin/yunohost*, /bin/journalctl*, /usr/bin/find /etc/yunohost/apps -name backup, ${final_path}/check_method_${app}
${app} ALL = (root) NOPASSWD: /usr/bin/yunohost*, /bin/journalctl*, /usr/bin/find /etc/yunohost/apps -name backup, ${install_dir}/check_method_${app}
EOSUDOER
visudo -cf /tmp/${app}_sudoer && mv /tmp/${app}_sudoer /etc/sudoers.d/${app}
ynh_script_progression --message="Move ssh keys from root to ${app} user's home"
@ -116,21 +99,21 @@ mkdir -p /usr/share/yunohost/backup_method
ynh_script_progression --message="Setting up backup methods"
ynh_configure backup_method "/etc/yunohost/hooks.d/backup_method/05-${app}_app"
ynh_configure check_method "${final_path}/check_method_${app}"
ynh_configure check_method "${install_dir}/check_method_${app}"
#=================================================
# SETUP LOG SCRIPTS
#=================================================
ynh_script_progression --message="Setting up backup log script"
ynh_configure restic_log "${final_path}/restic_log_${app}"
chmod +x "${final_path}/restic_log_${app}"
chown ${app}: "${final_path}/restic_log_${app}"
ynh_configure restic_log "${install_dir}/restic_log_${app}"
chmod +x "${install_dir}/restic_log_${app}"
chown ${app}: "${install_dir}/restic_log_${app}"
ynh_script_progression --message="Setting up check log script"
ynh_configure restic_check_log "${final_path}/restic_check_log_${app}"
chmod +x "${final_path}/restic_check_log_${app}"
chown ${app}: "${final_path}/restic_check_log_${app}"
ynh_configure restic_check_log "${install_dir}/restic_check_log_${app}"
chmod +x "${install_dir}/restic_check_log_${app}"
chown ${app}: "${install_dir}/restic_check_log_${app}"
#=================================================
# CONFIGURE CRON
@ -138,11 +121,11 @@ chown ${app}: "${final_path}/restic_check_log_${app}"
ynh_script_progression --message="Configuring cron" --weight=5
ynh_configure backup-with-restic "/usr/local/bin/backup-with-${app}"
ynh_configure check-restic "${final_path}/check-${app}"
ynh_configure check-restic "${install_dir}/check-${app}"
chmod +x "/usr/local/bin/backup-with-${app}"
chown ${app}: "/usr/local/bin/backup-with-${app}"
chmod +x "${final_path}/check-${app}"
chmod +x "${final_path}/check_method_${app}"
chmod +x "${install_dir}/check-${app}"
chmod +x "${install_dir}/check_method_${app}"
ynh_add_systemd_config --service=${app} --template=systemd.service
ynh_add_systemd_config --service=${app}_check --template=systemd_check.service
ynh_add_systemd_config --service=${app}_check_read_data --template=systemd_check_read_data.service

38
tests.toml Normal file
View file

@ -0,0 +1,38 @@
#:schema https://raw.githubusercontent.com/YunoHost/apps/master/schemas/tests.v1.schema.json
test_format = 1.0
[default]
args.repository = "ssh://sam@domain.tld:22/~/backup"
args.passphrase = "A_Passphrase"
args.conf = 1
args.data = 1
args.apps = "all"
args.on_calendar = "Daily"
args.mailalert = "errors_only"
# -------------------------------
# Commits to test upgrade from
# -------------------------------
[default.test_upgrade_from.d1cd666ee27f5cfb8e40c6f44a09370381b41b35]
name = "Older ynh 11 version"
args.server = "domain.tld:22"
args.ssh_user = "package_checker"
args.passphrase = "A_Passphrase"
args.conf = 1
args.data = 1
args.apps = "all"
args.on_calendar = "Daily"
args.mailalert = "never"
[local_directory]
args.repository = "/mnt/backup"
args.passphrase = "A_Passphrase"
args.conf = 1
args.data = 1
args.apps = "all"
args.on_calendar = "Daily"
args.mailalert = "errors_only"