diff --git a/check_process b/check_process index c4d634d..5fa3e9b 100644 --- a/check_process +++ b/check_process @@ -1,7 +1,6 @@ ;; Test complet ; Manifest - server="domain.tld:22" - ssh_user="sam" + repository="ssh://sam@domain.tld:22/~/backup" passphrase="APassphrase" conf=1 data=1 @@ -15,10 +14,15 @@ setup_private=0 setup_public=0 upgrade=1 + upgrade=1 from_commit=c1524dd8e37cc671c01f5b5363901dd6a01e6fc1 backup_restore=1 multi_instance=1 port_already_use=0 change_url=0 ;;; Options Email=ljf+borg_ynh@reflexlibre.net -Notification=down +Notificatio +;;; Upgrade options + ; commit=c1524dd8e37cc671c01f5b5363901dd6a01e6fc1 + name=Merge pull request #63 from YunoHost-Apps/testing + manifest_arg=server=domain.tld:22&ssh_user=package_checker&passphrase=APassphrase&conf=1&data=1&apps=all&on_calendar=Daily diff --git a/conf/backup-with-borg b/conf/backup-with-borg new file mode 100644 index 0000000..f153033 --- /dev/null +++ b/conf/backup-with-borg @@ -0,0 +1,81 @@ +#!/bin/bash + +# We don't stop the script on errors cause we want to backup all data we could backuped +#set -eu + +borg_id=$1 +errors="" +current_date=$(date +"%y%m%d_%H%M") +log_file="/var/log/${borg_id}/${current_date}.log" +err_file="/var/log/${borg_id}/${current_date}.err" +mkdir -p "/var/log/${borg_id}" +if [ -z "$borg_id" ] +then + echo "This script expects a borg app id as first argument" >&2 + exit 1 +fi + +filter_hooks() { + sudo ls /usr/share/yunohost/hooks/backup/ /etc/yunohost/hooks.d/backup/ | grep "\-$1_" | cut -d"-" -f2 | uniq 2>> $err_file +} + +fail_if_partially_failed() { + grep Skipped|Error +} + +# Backup system part conf +conf=$(sudo yunohost app setting ${borg_id} conf) +if [[ "$conf" = "1" ]] +then + if ! sudo yunohost backup create -n auto_conf --method ${borg_id}_app --system $(filter_hooks conf) 2>> $err_file >> $log_file ; then + errors+="\nThe backup miserably failed to backup system configurations." + fi +fi + +# Backup system data +data=$(sudo yunohost app setting ${borg_id} data) +if [[ "$data" = "1" ]] +then + if ! sudo yunohost backup create -n auto_data --method ${borg_id}_app --system $(filter_hooks data) 2>> $err_file >> $log_file ; then + errors+="\nThe backup miserably failed to backup system data." + fi +fi + +# Backup all apps independently +apps=$(sudo yunohost app setting ${borg_id} apps | tr -d ' ') +for application in $(sudo ls /etc/yunohost/apps/); do + + if ( [[ "$apps" =~ ^exclude: ]] && grep -wq "$application" <<< "$apps" ) || + ( [[ "$apps" != "all" ]] && [[ ! "$apps" =~ ^exclude: ]] && ! grep -wq "$application" <<< "$apps" ); + then + continue + fi + + if sudo test ! -f /etc/yunohost/apps/$application/scripts/backup ; then + errors+="\nWarning: The application $application has no backup script. This app won't be backuped." + continue + fi + + if ! sudo yunohost backup create -n auto_$application --method ${borg_id}_app --apps $application 2>> $err_file >> $log_file ; then + errors+="\nThe backup miserably failed to backup $application application." + fi +done + +#========================================================= +# SEND MAIL TO NOTIFY SUCCED OR FAILED OPERATIONS +#========================================================= + +partial_errors="$(cat $log_file | grep -E "Error|Skipped")" +if [ ! -z "$partial_errors" ]; then + errors+="\nSome backup partially failed:\n$partial_errors" +fi + +# Send mail on backup (partially) failed +domain=$(hostname) +if [ ! -z "$errors" ]; then + cat <(echo -e "$errors\n\n\n") "$log_file" "$err_file" | mail -s "[borg] Backup failed from $domain onto $repo" root + exit 1 +else + cat $log_file | mail -s "[borg] Backup succeed from $domain onto $repo" root + exit 0 +fi diff --git a/conf/backup-with-borg.j2 b/conf/backup-with-borg.j2 deleted file mode 100644 index 68df3b1..0000000 --- a/conf/backup-with-borg.j2 +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -# Adapt this script to different API 2.x vs 3.x -if yunohost -v | grep "version: 2." > /dev/null; then - ignore_apps="--ignore-apps" - ignore_system="--ignore-system" -else - ignore_apps="" - ignore_system="" -fi - -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 -eq 1 ] -then - yunohost backup create $ignore_apps -n auto_conf --method {{ app }}_app --system $(filter_hooks conf) -fi - -# Backup system data -data=$(yunohost app setting {{ app }} data) -if [ $data -eq 1 ] -then - yunohost backup create $ignore_apps -n auto_data --method {{ app }}_app --system $(filter_hooks data) -fi - -# Backup all apps independently -apps=$(yunohost app setting {{ app }} apps) -for app in $(ls /etc/yunohost/apps/*/scripts/backup | cut -d / -f 5); do - backup_app=false - if [[ "$apps" = "all" ]]; then - backup_app=true - else - for selected_app in $(echo $apps | tr "," " ");do - if [[ "$selected_app" == "$app" ]]; then - backup_app=true - break - fi - done - fi - if [ "$backup_app" == "true" ];then - yunohost backup create $ignore_system -n auto_$app --method {{ app }}_app --apps $app - fi -done diff --git a/conf/backup_method b/conf/backup_method new file mode 100644 index 0000000..0b3c1ed --- /dev/null +++ b/conf/backup_method @@ -0,0 +1,90 @@ +#!/bin/bash + +set -e +app="${0#"./05-"}" +app="${app%"_app"}" + +BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" +repo="$(yunohost app setting $app repository)" #$4 +if ssh-keygen -F "__SERVER__" >/dev/null ; then + BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " +else + BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=no " +fi + +do_need_mount() { + true +} + +LOGFILE=/var/log/backup_borg.err +log_with_timestamp() { + sed -e "s/^/[$(date +"%Y-%m-%d_%H:%M:%S")] /" >> $LOGFILE +} + +do_backup() { + + export BORG_PASSPHRASE + export BORG_RSH + work_dir="$1" + name="$2" + repo="$3" + size="$4" + description="$5" + current_date=$(date +"%d_%m_%y_%H:%M") + pushd "$work_dir" + set +e + if borg init -e repokey "$repo" ; then + #human_size=`echo $size | awk '{ suffix=" KMGT"; for(i=1; $1>1024 && i < length(suffix); i++) $1/=1024; print int($1) substr(suffix, i, 1), $3; }'` + # Speed in Kbps + #speed=1000 + #evaluated_time=$(($size / ($speed * 1000 / 8) / 3600)) + echo "Hello, + +Your first backup on $repo is starting. + +This is an automated message from your beloved YunoHost server." | /usr/bin/mail.mailutils -a "Content-Type: text/plain; charset=UTF-8" -s "[YNH] First backup is starting" "root" + fi + set -e + + borg create "$repo::${name}_${current_date}" ./ 2>&1 >/dev/null | log_with_timestamp + popd + + # About thi _20 it's a crazy fix to avoid pruning wordpress__2 + # if you prune wordpress + borg prune "$repo" -P ${name}_20 --keep-hourly 2 --keep-daily=7 --keep-weekly=8 --keep-monthly=12 2>&1 >/dev/null | log_with_timestamp +} + +do_mount() { + export BORG_PASSPHRASE + export BORG_RSH + work_dir="$1" + name="$2" + repo="$3" + size="$4" + description="$5" + borg mount "$repo::$name" "$work_dir" 2>&1 >/dev/null | log_with_timestamp +} + +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 diff --git a/conf/backup_method.j2 b/conf/backup_method.j2 deleted file mode 100644 index 35ed6a1..0000000 --- a/conf/backup_method.j2 +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash - -set -e - -BORG_PASSPHRASE="{{ passphrase }}" -if ssh-keygen -F "{{ server }}" >/dev/null ; then - BORG_RSH="ssh -i /root/.ssh/id_{{ app }}_ed25519 -oStrictHostKeyChecking=yes " -else - BORG_RSH="ssh -i /root/.ssh/id_{{ app }}_ed25519 -oStrictHostKeyChecking=no " -fi -repo=ssh://{{ ssh_user }}@{{ server }}/~/backup #$4 - -do_need_mount() { - true -} - -LOGFILE=/var/log/backup_borg.err -log_with_timestamp() { - sed -e "s/^/[$(date +"%Y-%m-%d_%H:%M:%S")] /" >> $LOGFILE -} - -do_backup() { - - export BORG_PASSPHRASE - export BORG_RSH - work_dir=$1 - name=$2 - repo=$3 - size=$4 - description=$5 - current_date=$(date +"%d_%m_%y_%H:%M") - pushd $work_dir - set +e - if borg init -e repokey $repo ; then - #human_size=`echo $size | awk '{ suffix=" KMGT"; for(i=1; $1>1024 && i < length(suffix); i++) $1/=1024; print int($1) substr(suffix, i, 1), $3; }'` - # Speed in Kbps - #speed=1000 - #evaluated_time=$(($size / ($speed * 1000 / 8) / 3600)) - echo "Hello, - -Your first backup on $repo is starting. - -This is an automated message from your beloved YunoHost server." | /usr/bin/mail.mailutils -a "Content-Type: text/plain; charset=UTF-8" -s "[YNH] First backup is starting" "root" - fi - set -e - - borg create $repo::${name}_${current_date} ./ 2>&1 >/dev/null | log_with_timestamp - popd - - borg prune $repo -P ${name} --keep-hourly 2 --keep-daily=7 --keep-weekly=8 --keep-monthly=12 2>&1 >/dev/null | log_with_timestamp -} - -do_mount() { - export BORG_PASSPHRASE - export BORG_RSH - work_dir=$1 - name=$2 - repo=$3 - size=$4 - description=$5 - borg mount $repo::$name $work_dir 2>&1 >/dev/null | log_with_timestamp -} - -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 diff --git a/conf/sudoer b/conf/sudoer new file mode 100644 index 0000000..6a11357 --- /dev/null +++ b/conf/sudoer @@ -0,0 +1 @@ +__APP__ ALL=(root) NOPASSWD: /usr/local/bin/backup-with-__APP__, /usr/local/bin/borg, /usr/bin/yunohost backup create *, /usr/bin/yunohost app setting *, /bin/ls, /usr/bin/test diff --git a/conf/systemd.service b/conf/systemd.service index e0d648d..b2d0080 100644 --- a/conf/systemd.service +++ b/conf/systemd.service @@ -4,9 +4,9 @@ After=network.target [Service] Type=oneshot -ExecStart=/usr/local/bin/backup-with-__APP__ -User=root -Group=root +ExecStart=/usr/bin/sudo /usr/local/bin/backup-with-__APP__ __APP__ +User=__APP__ +Group=__APP__ #[Install] #WantedBy=multi-user.target diff --git a/conf/systemd.timer b/conf/systemd.timer new file mode 100644 index 0000000..6434e4e --- /dev/null +++ b/conf/systemd.timer @@ -0,0 +1,8 @@ +[Unit] +Description=Run backup __APP__ regularly + +[Timer] +OnCalendar=__ON_CALENDAR__ + +[Install] +WantedBy=timers.target diff --git a/conf/systemd.timer.j2 b/conf/systemd.timer.j2 deleted file mode 100644 index f21a951..0000000 --- a/conf/systemd.timer.j2 +++ /dev/null @@ -1,8 +0,0 @@ -[Unit] -Description=Run backup {{ app }} regularly - -[Timer] -OnCalendar={{ on_calendar }} - -[Install] -WantedBy=timers.target diff --git a/manifest.json b/manifest.json index a51509e..5744207 100644 --- a/manifest.json +++ b/manifest.json @@ -6,7 +6,7 @@ "en": "Backup your server on a host server using Borg.", "fr": "Sauvegardez votre serveur sur un serveur distant avec Borg." }, - "version": "1.1.15~ynh1", + "version": "1.1.16~ynh16", "url": "https://borgbackup.readthedocs.io", "license": "BSD-3-Clause", "maintainer": { @@ -22,30 +22,16 @@ "arguments": { "install" : [ { - "name": "server", + "name": "repository", "type": "string", "ask": { - "en": "What is the domain name of the host server where backups will be sent?", - "fr": "Quel est le nom de domaine du serveur distant sur lequel seront envoyés les sauvegardes ?" + "en": "In which borg repository location do you want to backup your files ?", + "fr": "Dans quel repo borg souhaitez-vous sauvegarder vos fichiers ?" }, "help":{ - "en": "If this host server does use a custom SSH port (different from 22), you can specify it with DOMAIN:PORT", - "fr": "Si le serveur distant utilise un port particulier pour SSH (différent de 22), vous pouvez le spécifier avec DOMAIN:PORT" + "en": "Specify a remote repository using this format: ssh://USER@DOMAIN.TLD:PORT/~/backup . 'USER' is *not* meant to be an existing user on the guest server. Instead, it will be created *on the host server* during the installation of the Borg Server App. It's also possible to use a local repository using a syntax such as /mount/my_external_harddrive/backups" }, - "example": "host.serverb:22" - }, - { - "name": "ssh_user", - "type": "string", - "ask": { - "en": "Which SSH username should be used to connect to the host server?", - "fr": "Quel utilisateur faut-il utiliser pour se connecter au serveur distant ?" - }, - "help":{ - "en": "It is not meant to be an existing user on this guest server. Instead, it will be created *on the host server* during the installation of the Borg Server App.", - "fr": "Cet utilisateur n'est pas censé exister sur ce serveur. Il sera créé *sur le serveur distant* lors de l'installation de l'App Borg Server sur celui-ci." - }, - "example": "borgservera" + "example": "ssh://john@serverb.tld:22/~/backup" }, { "name": "passphrase", @@ -81,9 +67,13 @@ "name": "apps", "type": "string", "ask": { - "en": "Which apps should Borg backup (list separated by comma or 'all')?", - "fr": "Quelles applications doivent être sauvegardées par Borg (liste séparée par virgule ou 'all' ?" + "en": "Which apps should Borg backup ?", + "fr": "Quelles applications doivent être sauvegardées par Borg ?" }, + "help":{ + "en": "App list separated by comma. You can write 'all' to select all apps, even those installed after this borg app. You can also select all apps but some apps by writing 'exclude:' following by an app list separated by comma.", + "fr": "Liste d'applications séparées par des virgules. Vous pouvez écrire 'all' pour sélectionner toutes les apps, même celles installées après cette application borg. Vous pouvez aussi sélectionner toutes les apps sauf certaines en écrivant 'exclude:' suivi d'une liste d'applications séparées par des virgules." + }, "default": "all" }, { diff --git a/scripts/_common.sh b/scripts/_common.sh index 6bb0320..90945f3 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -5,18 +5,25 @@ #================================================= # App package root directory should be the parent folder PKG_DIR=$(cd ../; pwd) +BORG_VERSION=1.1.16 -pkg_dependencies="python3-pip python3-dev libacl1-dev libssl-dev liblz4-dev python3-jinja2 python3-setuptools python-virtualenv virtualenv" +pkg_dependencies="python3-pip python3-dev libacl1-dev libssl-dev liblz4-dev python3-jinja2 python3-setuptools python3-venv python-virtualenv virtualenv libfuse-dev pkg-config" # Install borg with pip if borg is not here install_borg_with_pip () { + if [ -d /opt/borg-env ]; then + /opt/borg-env/bin/python /opt/borg-env/bin/pip list | grep "Version: $BORG_VERSION" || ynh_secure_remove /opt/borg-env + fi if [ ! -d /opt/borg-env ]; then - virtualenv --python=python3 /opt/borg-env - /opt/borg-env/bin/python /opt/borg-env/bin/pip install borgbackup==1.1.15 + python3 -m venv /opt/borg-env + /opt/borg-env/bin/python /opt/borg-env/bin/pip install wheel + /opt/borg-env/bin/python /opt/borg-env/bin/pip install borgbackup[fuse]==$BORG_VERSION echo "#!/bin/bash /opt/borg-env/bin/python /opt/borg-env/bin/borg \"\$@\"" > /usr/local/bin/borg - chmod u+x /usr/local/bin/borg + touch "/opt/borg-env/$(ynh_get_debian_release)" fi + # We need this to be executable by other borg apps + chmod a+x /usr/local/bin/borg } #================================================= @@ -43,19 +50,20 @@ ynh_save_args () { if [ "$var" == "path_url" ]; then setting_var="path" fi - ynh_app_setting_set $app $setting_var ${!var} + ynh_app_setting_set $app $setting_var "${!var}" done } +# Need also the helper https://github.com/YunoHost-Apps/Experimental_helpers/blob/master/ynh_handle_getopts_args/ynh_handle_getopts_args - -ynh_configure () { - ynh_backup_if_checksum_is_different $2 - ynh_render_template "${PKG_DIR}/conf/$1.j2" "$2" - ynh_store_file_checksum $2 -} - - +# Send an email to inform the administrator +# +# usage: ynh_send_readme_to_admin app_message [recipients] +# | arg: -m --app_message= - The message to send to the administrator. +# | arg: -r, --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" # Send an email to inform the administrator # @@ -113,36 +121,3 @@ $(yunohost tools diagnosis | grep -B 100 "services:" | sed '/services:/d')" # Send the email to the recipients echo "$mail_message" | $mail_bin -a "Content-Type: text/plain; charset=UTF-8" -s "$mail_subject" "$recipients" } - - - -ynh_debian_release () { - lsb_release --codename --short -} - -is_buster () { - if [ "$(ynh_debian_release)" == "buster" ] - then - return 0 - else - return 1 - fi -} - -is_stretch () { - if [ "$(ynh_debian_release)" == "stretch" ] - then - return 0 - else - return 1 - fi -} - -is_jessie () { - if [ "$(ynh_debian_release)" == "jessie" ] - then - return 0 - else - return 1 - fi -} diff --git a/scripts/backup b/scripts/backup index 9a0f189..61e6920 100755 --- a/scripts/backup +++ b/scripts/backup @@ -28,6 +28,7 @@ app=$YNH_APP_INSTANCE_NAME ynh_print_info --message="Declaring files to be backed up..." ynh_backup "/usr/local/bin/backup-with-$app" +ynh_backup "/etc/sudoers.d/$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}_app" diff --git a/scripts/install b/scripts/install index 9a73927..72ad751 100755 --- a/scripts/install +++ b/scripts/install @@ -23,13 +23,20 @@ ynh_abort_if_errors export app=$YNH_APP_INSTANCE_NAME # Retrieve arguments -ynh_export server ssh_user passphrase on_calendar conf data apps +ynh_export repository passphrase on_calendar conf data apps #================================================= # STORE SETTINGS FROM MANIFEST #================================================= - -ynh_save_args server ssh_user passphrase on_calendar conf data apps +server="" +if [[ $repository == *"@"* ]]; then + server=$(echo "$repository" | cut -d"@" -f2 | cut -d"/" -f1) + if [[ $server == *":"* ]]; then + server="[$(echo "$server" | cut -d":" -f1)]:$(echo "$server" | cut -d":" -f2)" + fi + ssh_user=$(echo "$repository" | cut -d"@" -f1 | cut -d"/" -f2) +fi +ynh_save_args repository server passphrase on_calendar conf data apps #================================================= # INSTALL DEPENDENCIES @@ -39,60 +46,62 @@ ynh_script_progression --message="Installing dependencies..." ynh_install_app_dependencies $pkg_dependencies install_borg_with_pip +#================================================= +# CREATE DEDICATED USER +#================================================= +ynh_script_progression --message="Configuring system user..." --weight=1 + +# Create a system user +ynh_system_user_create --username=$app + +#================================================= +# SPECIFIC SETUP #================================================= # ACTIVATE BACKUP METHODS #================================================= +mkdir -p /etc/yunohost/hooks.d/backup mkdir -p /etc/yunohost/hooks.d/backup_method mkdir -p /usr/share/yunohost/backup_method +mkdir -p /var/log/${app} +chown -R $app:$app /var/log/${app} +chmod u+w /var/log/${app} #================================================= # SETUP THE BACKUP METHOD #================================================= -ynh_configure backup_method "/etc/yunohost/hooks.d/backup_method/05-${app}_app" +ynh_add_config --template="backup_method" --destination="/etc/yunohost/hooks.d/backup_method/05-${app}_app" +chmod go=--- "/etc/yunohost/hooks.d/backup_method/05-${app}_app" -#================================================= -# CONFIGURE CRON -#================================================= -ynh_configure backup-with-borg "/usr/local/bin/backup-with-$app" +ynh_add_config --template="backup-with-borg" --destination="/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" -systemctl enable $app.timer --quiet -systemctl start $app.timer -#yunohost service add $app.timer -#yunohost service enable $app.timer -#yunohost service start $app.timer +chown $app:$app "/usr/local/bin/backup-with-$app" -#================================================= -# ADVERTISE SERVICE IN ADMIN PANEL -#================================================= -ynh_script_progression --message="Integrating service in YunoHost..." +ynh_add_config --template="sudoer" --destination="/etc/sudoers.d/$app" -yunohost service add $app --description="Deduplicating backup program" +if [ ! -z "$server" ]; then + #================================================= + # GENERATE SSH KEY + #================================================= -#================================================= -# GENERATE SSH KEY -#================================================= + private_key="/root/.ssh/id_${app}_ed25519" + test -f $private_key || ssh-keygen -q -t ed25519 -N "" -f $private_key -private_key="/root/.ssh/id_${app}_ed25519" -test -f $private_key || ssh-keygen -q -t ed25519 -N "" -f $private_key + #================================================= + # Display key + #================================================= -#================================================= -# Display key -#================================================= + echo "You should now install the \"Borg Server\" app on $server and with the following credentials: + User: ${ssh_user} + Public key: $(cat ${private_key}.pub)" -echo "You should now install the \"Borg Server\" app on $server and fill questions like this: -User: ${ssh_user} -Public key: $(cat ${private_key}.pub)" + #================================================= + # SEND A README FOR THE ADMIN + #================================================= -#================================================= -# 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: + ynh_print_OFF + message="You should now install the \"Borg Server\" app on $server and with the following credentials: User: ${ssh_user} Public key: $(cat ${private_key}.pub) @@ -102,8 +111,32 @@ yunohost app install https://github.com/YunoHost-Apps/borgserver_ynh -a \"ssh_us 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 + ynh_send_readme_to_admin "$message" + ynh_print_ON +fi + +#================================================= +# SETUP SYSTEMD +#================================================= +ynh_script_progression --message="Configuring a systemd service..." --weight=1 + +# Create a dedicated systemd config +ynh_add_systemd_config + +#================================================= +# CONFIGURE SYSTEMD TIMER +#================================================= +ynh_add_config --template="systemd.timer" --destination="/etc/systemd/system/$app.timer" +systemctl enable $app.timer --quiet +systemctl start $app.timer + +#================================================= +# INTEGRATE SERVICE IN YUNOHOST +#================================================= +ynh_script_progression --message="Integrating service in YunoHost..." --weight=1 + +yunohost service add $app --description="Deduplicating backup program" + #================================================= # END OF SCRIPT diff --git a/scripts/remove b/scripts/remove index b57c396..e3da1d5 100755 --- a/scripts/remove +++ b/scripts/remove @@ -43,6 +43,12 @@ 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}_app" +# Remove borg if we are removing the last borg app on the system +if [ "$(yunohost app list | grep "id: borg" | wc -l)" == "1" ] ; then + ynh_secure_remove "/opt/borg-env" + ynh_secure_remove "/usr/local/bin/borg" +fi + #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/restore b/scripts/restore index bc7c282..6a70a59 100755 --- a/scripts/restore +++ b/scripts/restore @@ -23,9 +23,6 @@ ynh_script_progression --message="Loading installation settings..." app=$YNH_APP_INSTANCE_NAME -server=$(ynh_app_setting_get $app server) -ssh_user=$(ynh_app_setting_get $app ssh_user) - #================================================= # INSTALL DEPENDENCIES #================================================= @@ -34,35 +31,52 @@ ynh_script_progression --message="Reinstalling dependencies..." ynh_install_app_dependencies $pkg_dependencies install_borg_with_pip +#================================================= +# CREATE DEDICATED USER +#================================================= +ynh_script_progression --message="Configuring system user..." --weight=1 + +# Create a system user +ynh_system_user_create --username=$app + #================================================= # ACTIVATE BACKUP METHODS #================================================= mkdir -p /etc/yunohost/hooks.d/backup_method mkdir -p /usr/share/yunohost/backup_method +mkdir -p /etc/yunohost/hooks.d/backup +mkdir -p /var/log/${app} +chown -R $app:$app /var/log/${app} +chmod u+w /var/log/${app} #================================================= # RESTORE FILES #================================================= ynh_restore +chmod go=--- "/etc/yunohost/hooks.d/backup_method/05-${app}_app" +chmod u+x "/usr/local/bin/backup-with-$app" +chown $app:$app "/usr/local/bin/backup-with-$app" #================================================= # ADVERTISE SERVICE IN ADMIN PANEL #================================================= -yunohost service add $app systemctl enable $app.timer --quiet systemctl start $app.timer -#yunohost service add $app.timer -#yunohost service enable $app.timer -#yunohost service start $app.timer #================================================= # RESTORE SYSTEMD #================================================= - systemctl enable $app.service --quiet +#================================================= +# INTEGRATE SERVICE IN YUNOHOST +#================================================= +ynh_script_progression --message="Integrating service in YunoHost..." --weight=1 + +yunohost service add $app --description="Deduplicating backup program" + #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index 79ee142..8e0c8a1 100755 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -15,21 +15,14 @@ source /usr/share/yunohost/helpers export app=$YNH_APP_INSTANCE_NAME -export server=$(ynh_app_setting_get $app server) -export ssh_user=$(ynh_app_setting_get $app ssh_user) -export passphrase=$(ynh_app_setting_get $app passphrase) -export on_calendar=$(ynh_app_setting_get $app 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 server=$(ynh_app_setting_get $app server) -export ssh_user=$(ynh_app_setting_get $app ssh_user) -export passphrase=$(ynh_app_setting_get $app passphrase) -export on_calendar=$(ynh_app_setting_get $app 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 repository="$(ynh_app_setting_get $app repository)" +export server="$(ynh_app_setting_get $app server)" +export ssh_user="$(ynh_app_setting_get $app ssh_user)" +export passphrase="$(ynh_app_setting_get $app passphrase)" +export on_calendar="$(ynh_app_setting_get $app 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)" #================================================= # CHECK IF AN UPGRADE IS NEEDED @@ -51,6 +44,21 @@ ynh_clean_setup () { # Exit if an error occurs during the execution of the script ynh_abort_if_errors +#================================================= +# ENSURE DOWNWARD COMPATIBILITY +#================================================= +ynh_script_progression --message="Ensuring downward compatibility..." --weight=1 + +if [ -z "$repository" ]; then + repository="ssh://$ssh_user@$server/~/backup" + server=$(echo "$repository" | cut -d"@" -f2 | cut -d"/" -f1) + if [[ $server == *":"* ]]; then + server="[$(echo "$server" | cut -d":" -f1)]:$(echo "$server" | cut -d":" -f2)" + fi + ynh_app_setting_set $app repository "$repository" + ynh_app_setting_set $app server "$server" + ynh_app_setting_delete $app ssh_user +fi if grep "borg.timer" /etc/yunohost/services.yml > /dev/null ; then yunohost service remove $app.timer @@ -59,34 +67,80 @@ if grep "borg.timer" /etc/yunohost/services.yml > /dev/null ; then fi # Replace backports with pip -if is_buster; then - if [ ! -f /opt/borg-env/buster ] ; then - rm -f /etc/apt/sources.list.d/$app-stretch-backports.list +[ ! -e " /etc/apt/sources.list.d/$app-stretch-backports.list" ] || rm -f /etc/apt/sources.list.d/$app-stretch-backports.list + +# Reinstall borg if debian change of major version +if [ ! -f "/opt/borg-env/$(ynh_get_debian_release)" ] ; then ynh_secure_remove /opt/borg-env - install_borg_with_pip - touch /opt/borg-env/buster - fi fi +#================================================= +# UPGRADE DEPENDENCIES +#================================================= +ynh_script_progression --message="Upgrading dependencies..." --weight=1 + +ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# CREATE DEDICATED USER +#================================================= +ynh_script_progression --message="Configuring system user..." --weight=1 + +# Create a system user +ynh_system_user_create --username=$app + + +#================================================= +# SPECIFIC UPGRADE +#================================================= +# Upgrade borgbackup +#================================================= +ynh_script_progression --message="Upgrading borgbackup..." --weight=1 + +install_borg_with_pip + #================================================= # SETUP THE BACKUP METHOD #================================================= -ynh_configure backup_method "/etc/yunohost/hooks.d/backup_method/05-${app}_app" +ynh_script_progression --message="Setting up backup method..." --weight=1 +ynh_add_config --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 --template="backup-with-borg" --destination="/usr/local/bin/backup-with-$app" +chmod u+x "/usr/local/bin/backup-with-$app" +chown $app:$app "/usr/local/bin/backup-with-$app" + +ynh_add_config --template="sudoer" --destination="/etc/sudoers.d/$app" #================================================= -# CONFIGURE CRON +# SETUP SYSTEMD #================================================= -ynh_configure backup-with-borg "/usr/local/bin/backup-with-$app" -chmod u+x "/usr/local/bin/backup-with-$app" +ynh_script_progression --message="Upgrading systemd configuration..." --weight=1 + +# Create a dedicated systemd config ynh_add_systemd_config -ynh_configure systemd.timer "/etc/systemd/system/$app.timer" + +#================================================= +# CONFIGURE SYSTEMD TIMER +#================================================= +ynh_add_config --template="systemd.timer" --destination="/etc/systemd/system/$app.timer" systemctl enable $app.timer --quiet systemctl start $app.timer +mkdir -p /etc/yunohost/hooks.d/backup +mkdir -p /var/log/${app} +chown -R $app:$app /var/log/${app} +chmod u+w /var/log/${app} + #================================================= -# ADVERTISE SERVICE IN ADMIN PANEL +# GENERIC FINALIZATION #================================================= +#================================================= +# INTEGRATE SERVICE IN YUNOHOST +#================================================= +ynh_script_progression --message="Integrating service in YunoHost..." --weight=1 + yunohost service add $app --description="Deduplicating backup program" #=================================================