From 41df5c5033f08374161a90e4c8fb17de86400624 Mon Sep 17 00:00:00 2001 From: Eric Lay Date: Sat, 24 Jun 2023 18:30:55 -0500 Subject: [PATCH] moved backup script to service unit --- borg-backup/backup | 138 ++++++++++++++++++++++++++++++++ borg-backup/backup-headless | 116 +++++++++++++++++++++++++++ borg-backup/borg-backup.service | 7 ++ borg-backup/borg-backup.timer | 11 +++ 4 files changed, 272 insertions(+) create mode 100755 borg-backup/backup create mode 100755 borg-backup/backup-headless create mode 100644 borg-backup/borg-backup.service create mode 100644 borg-backup/borg-backup.timer diff --git a/borg-backup/backup b/borg-backup/backup new file mode 100755 index 0000000..6ebff63 --- /dev/null +++ b/borg-backup/backup @@ -0,0 +1,138 @@ +#!/bin/sh + +# Setting this, so the repo does not need to be given on the commandline: +machine="$( hostnamectl --static )" +remoteHost="reposerver" +remoteUser="" +export BORG_REPO="$remoteUser@$remoteHost:/backup/$machine" + +# See the section "Passphrase notes" for more infos. +export BORG_PASSPHRASE='' + +# Non-interactively accept relocation of a repository +export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes + +# Some helpers and error handling: +logPath="/home/ez/.cache/logs/borg" +logFile="$logPath/$( date +%Y-%m-%d-%H:%M:%S.%N )" +infoLine() { printf "%s\t%s\n" "$( date +%H:%M:%S )" "$*" | tee -a "$logFile"; } +seeLog() { printf "\n%s %s" "$*" "$logFile"; } +trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM + +# Notify user of running backup +notify() { + if [ "$(command -v sudo)" ] && [ "$(command -v notify-send)" ]; then + dialog_kind=$(echo "$1"|tr '[:upper:]' '[:lower:]') + if [ "$dialog_kind" = 'info' ]; then + dialog_kind='information' + fi + for u in $(users); do + sudo -u "$u" DISPLAY=:0 \ + DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/"$(sudo -u "$u" id -u)/bus" \ + notify-send -a 'luky-borg-backup' "$1" "$2" --icon="dialog-$dialog_kind" + done + fi +} + +# Remove logs of pruned backups +tidyLogs() { + mapfile -t removeList < <(grep -w "^Pruning archive" "$logFile" | awk '{ print $4 }' ) + for ((i=0; i<${#removeList[@]}; i++)); do + rm "$logPath/${removeList[i]}" + done +} + +# Backup the most important directories into an archive named after +# the machine this script is currently running on: +notify info "Starting backup to $BORG_REPO" +infoLine "Starting backup to $BORG_REPO" + +borg create \ + --verbose \ + --stats \ + --show-rc \ + --compression lz4 \ + --progress \ + --exclude-caches \ + --exclude 'home/*/.cache/*' \ + --exclude 'var/tmp/*' \ + --exclude '/etc/mtab' \ + --exclude '/backup/' \ + --exclude '/dev/' \ + --exclude '/lost+found/' \ + --exclude '/mnt/' \ + --exclude '/proc/' \ + --exclude '/run/' \ + --exclude '/sys/' \ + --exclude '/tmp/' \ + --exclude '/home/*/.cache/mozilla/firefox/' \ + --exclude '/home/*/.local/share/Trash/' \ + --exclude '/home/*/.thumbnails/' \ + \ + ::'{hostname}-{now:%Y-%m-%d-%H:%M:%S.%f}' \ + /boot \ + /bin \ + /efi \ + /etc \ + /home \ + /lib \ + /lib64 \ + /opt \ + /root \ + /sbin \ + /srv \ + /usr \ + /var \ + 2>> "$logFile" + +backup_exit=$? + +# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly +# archives of THIS machine. The '{hostname}-*' matching is very important to +# limit prune's operation to this machine's archives and not apply to +# other machines' archives also: +notify info "Pruning repository: $BORG_REPO" +infoLine "Pruning repository" + +borg prune \ + --list \ + --glob-archives '{hostname}-*' \ + --show-rc \ + --keep-daily 3 \ + --keep-weekly 4 \ + --keep-monthly 6 \ + --keep-yearly 1 \ + 2>> "$logFile" + +prune_exit=$? + +# actually free repo disk space by compacting segments +notify info "Compacting repository: $BORG_REPO" +infoLine "Compacting repository" + +borg compact 2>> "$logFile" + +compact_exit=$? + +# Don't forget to tidy up the log files! +tidyLogs + +# use highest exit code as global exit code +global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit )) +global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit )) + +if [ ${global_exit} -eq 0 ]; then + notify info "Backup, Prune, and Compact finished successfully to $BORG_REPO" + infoLine "Backup, Prune, and Compact finished successfully to $BORG_REPO" + seeLog "Log available:" +elif [ ${global_exit} -eq 1 ]; then + notify info "Backup, Prune, and/or Compact finished with warnings" + infoLine "Backup, Prune, and/or Compact finished with warnings" + seeLog "Check log for warnings:" +else + notify info "Backup, Prune, and/or Compact finished with errors" + infoLine "Backup, Prune, and/or Compact finished with errors" + seeLog "Check log for errors:" +fi + +exit ${global_exit} diff --git a/borg-backup/backup-headless b/borg-backup/backup-headless new file mode 100755 index 0000000..e76ae45 --- /dev/null +++ b/borg-backup/backup-headless @@ -0,0 +1,116 @@ +#!/bin/sh + +# Setting this, so the repo does not need to be given on the commandline: +machine="$( hostnamectl --static )" +#remoteHost="" +#remoteUser="" +export BORG_REPO="/backup/$machine" + +# See the section "Passphrase notes" for more infos. +export BORG_PASSPHRASE='' + +# Non-interactively accept relocation of a repository +export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes + +# some helpers and error handling: +logPath="/home/ez/.cache/logs/borg" +logFile="$logPath/$( date +%Y-%m-%d-%H:%M:%S.%N )" +infoLine() { printf "%s\t%s\n" "$( date +%H:%M:%S )" "$*" | tee -a "$logFile"; } +seeLog() { printf "\n%s %s" "$*" "$logFile"; } +trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM + +# Remove logs of pruned backups +tidyLogs() { + mapfile -t removeList < <(grep -w "^Pruning archive" "$logFile" | awk '{ print $4 }' ) + for ((i=0; i<${#removeList[@]}; i++)); do + rm "$logPath/${removeList[i]}" + done +} + +# Backup the most important directories into an archive named after +# the machine this script is currently running on: +infoLine "Starting backup to $BORG_REPO" + +borg create \ + --verbose \ + --stats \ + --show-rc \ + --compression lz4 \ + --progress \ + --exclude-caches \ + --exclude 'home/*/.cache/*' \ + --exclude 'var/tmp/*' \ + --exclude '/etc/mtab' \ + --exclude '/backup/' \ + --exclude '/dev/' \ + --exclude '/lost+found/' \ + --exclude '/mnt/' \ + --exclude '/proc/' \ + --exclude '/run/' \ + --exclude '/sys/' \ + --exclude '/tmp/' \ + --exclude '/home/*/.cache/mozilla/firefox/' \ + --exclude '/home/*/.local/share/Trash/' \ + --exclude '/home/*/.thumbnails/' \ + \ + ::'{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}' \ + /boot \ + /bin \ + /etc \ + /home \ + /lib \ + /lib64 \ + /opt \ + /root \ + /sbin \ + /srv \ + /usr \ + /var \ + 2>> "$logFile" + +backup_exit=$? + +# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly +# archives of THIS machine. The '{hostname}-*' matching is very important to +# limit prune's operation to this machine's archives and not apply to +# other machines' archives also: +infoLine "Pruning repository" + +borg prune \ + --list \ + --glob-archives '{hostname}-*' \ + --show-rc \ + --keep-daily 3 \ + --keep-weekly 4 \ + --keep-monthly 6 \ + --keep-yearly 1 \ + 2>> "$logFile" + +prune_exit=$? + +# actually free repo disk space by compacting segments +infoLine "Compacting repository" + +borg compact 2>> "$logFile" + +compact_exit=$? + +# Don't forget to tidy up the log files! +tidyLogs + +# use highest exit code as global exit code +global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit )) +global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit )) + +if [ ${global_exit} -eq 0 ]; then + infoLine "Backup, Prune, and Compact finished successfully" + seeLog "Log available:" +elif [ ${global_exit} -eq 1 ]; then + infoLine "Backup, Prune, and/or Compact finished with warnings" + seeLog "Check log for warnings:" +else + infoLine "Backup, Prune, and/or Compact finished with errors" + seeLog "Check log for errors:" +fi + +exit ${global_exit} diff --git a/borg-backup/borg-backup.service b/borg-backup/borg-backup.service new file mode 100644 index 0000000..276cbc4 --- /dev/null +++ b/borg-backup/borg-backup.service @@ -0,0 +1,7 @@ +[Unit] +Description=Borg Backup Service +After=network.target sshd.service + +[Service] +Type=oneshot +ExecStart=/home/ez/.local/bin/backup diff --git a/borg-backup/borg-backup.timer b/borg-backup/borg-backup.timer new file mode 100644 index 0000000..e423638 --- /dev/null +++ b/borg-backup/borg-backup.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Borg Backup Service Timer + +[Timer] +Unit=borg-backup.service +OnCalendar=*-*-* 4:00:00 +AccuracySec=1h +Persistent=yes + +[Install] +WantedBy=timers.target