initial version

This commit is contained in:
cg 2024-12-03 13:47:27 +00:00
parent 81a1820c39
commit 2c69041cf4
6 changed files with 154 additions and 0 deletions

25
README.md Normal file
View file

@ -0,0 +1,25 @@
# b0rged
simple wrapper for borg-backup, aimed at backing up to hetzner storage boxes
# install
clone this repo somewhere to your machine - I use *~root/b0rged*
set up your storage box, according to the comments in *b0rged-init.sh*.
set up your .env file, copy *env.example* and adapt.
run *b0rged-init.sh*. if you want to, you could delete the script afterwards.
add your backup patterns. you could edit *patterns.system* or add as many *patterns.foo* files as you want.
run *b0rged.sh* manually, once. check that everything works.
copy the system and timer file to `~/.config/systemd/user`. you might need to adapt *ExecStart* in *b0rged.service*.
enable and start the timer. you might need to use `sudo machinectl shell root@` instead of `sudo -i` to get a root shell that works with systemd. then run `systemctl --user enable --now b0rged.timer`.
check that your timer is set up. it should look something like this:
systemctl --user list-timers --all
NEXT LEFT LAST PASSED UNIT ACTIVATES
Tue 2024-12-03 19:01:57 UTC 5h 21min left n/a n/a b0rged.timer b0rged.service

7
b0rged.service Normal file
View file

@ -0,0 +1,7 @@
[Unit]
Description=b0rged backup
#OnFailure=status_email_user@%n.service
# error reporting - see https://wiki.archlinux.org/title/Systemd/Timers#MAILTO to set up.
[Service]
ExecStart=/root/b0rged/b0rged.sh

83
b0rged.sh Executable file
View file

@ -0,0 +1,83 @@
#!/usr/bin/env bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
set -o allexport
eval $(cat ${DIR}'/.env' | sed -e '/^#/d;/^\s*$/d' -e 's/\(\w*\)[ \t]*=[ \t]*\(.*\)/\1=\2/' -e "s/=['\"]\(.*\)['\"]/=\1/g" -e "s/'/'\\\''/g" -e "s/=\(.*\)/='\1'/g")
set +o allexport
info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; }
trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM
if [ -z ${BORG_REPO+x} ]; then info "BORG_REPO must be set, check your .env"; exit 1; fi
if [ -z ${BORG_PASSPHRASE+x} ]; then info "BORG_PASSPHRASE must be set, check your .env"; exit 1; fi
node_metrics_enabled=${NODE_METRICS_ENABLED:-1}
node_metrics_path=${NODE_METRICS_PATH:-/usr/local/lib/prom}
start=$(date +%s)
exec {lock_fd}>/var/lock/borg-backup.lock || exit 1
flock -n "$lock_fd" || { echo "ERROR: flock() failed." >&2; exit 1; }
patternfile=$(mktemp)
cat patterns.* > $patternfile
if [ ${DOCKER_VOLUMES_ENABLED} -eq 1 ]; then
info "Collecting docker volumes..."
: ${DOCKER_COMMAND:=/usr/bin/docker}
volumes=$(${DOCKER_COMMAND} volume ls -f label=org.zknt.backup -f driver=local --format "{{.Name}}")
dockerpatterns=$(mktemp)
for volume in ${volumes}; do
mountpoint=$(${DOCKER_COMMAND} volume inspect ${volume} --format "{{.Mountpoint}}")
echo "R $(dirname ${mountpoint})" >> $dockerpatterns
done
cat $dockerpatterns >> $patternfile
rm $dockerpatterns
fi
info "Starting borg..."
borg create \
--warning \
--filter AME \
--list \
--stats \
--show-rc \
--compression lz4 \
--exclude-caches \
--exclude '/home/*/.cache/*' \
--exclude '/var/tmp/*' \
::'{hostname}-{now}' \
--patterns-from $patternfile
backup_exit=$?
rm $patternfile
borg prune \
--list \
--prefix '{hostname}-' \
--show-rc \
--keep-daily ${BORG_PRUNE_KEEP_DAILY:-14} \
--keep-weekly ${BORG_PRUNE_KEEP_WEEKLY:-4} \
--keep-monthly ${BORG_PRUNE_KEEP_MONTHLY:-6}
prune_exit=$?
global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
if [ ${global_exit} -eq 0 ]; then
info "Backup, Prune, and Compact finished successfully"
elif [ ${global_exit} -eq 1 ]; then
info "Backup, Prune, and/or Compact finished with warnings"
else
info "Backup, Prune, and/or Compact finished with errors"
fi
end=$(date +%s)
if [ ${node_metrics_enabled} -eq 1 ]; then
echo "borg_last_run ${end}" > ${node_metrics_path}/borg_backup.prom.$$
echo "borg_last_duration $(($end - $start))" >> ${node_metrics_path}/borg_backup.prom.$$
mv ${node_metrics_path}/borg_backup.prom{.$$,}
fi
flock -u "$lock_fd"

12
b0rged.timer Normal file
View file

@ -0,0 +1,12 @@
[Unit]
Description=b0rged timer
[Timer]
OnCalendar=*-*-* 1,7,13,19:00:00
RandomizedDelaySec=30m
AccuracySec=1s
Persistent=true
Unit=b0rged.service
[Install]
WantedBy=timers.target

16
env.example Normal file
View file

@ -0,0 +1,16 @@
BORG_REPO=ssh://u335394-sub5@u335394.your-storagebox.de:23/./borg
BORG_PASSPHRASE=abcd1234
BORG_PRUNE_KEEP_DAILY=14
BORG_PRUNE_KEEP_WEEKLY=4
BORG_PRUNE_KEEP_MONTHLY=6
# Wether to write metrics to a textfile for node-exporter to pick up.
NODE_METRICS_ENABLED=0
# Path to write metrics to. See --collector.textfile.directory in node-exporter
NODE_METRICS_PATH=/usr/local/lib/prom
# collect docker volumes
# checks for given label on volumes
DOCKER_VOLUMES_ENABLED=0
DOCKER_VOLUMES_LABEL=borg.backup

11
patterns.system Normal file
View file

@ -0,0 +1,11 @@
R /etc
R /root
- **/log/
- **/logs/
- **/cache/
- **/.cache/
- **/node_modules/
- **/vendor/
- **/typo3temp/
- **/composer-cache/
- **/.git/