initial version
This commit is contained in:
parent
81a1820c39
commit
2c69041cf4
6 changed files with 154 additions and 0 deletions
25
README.md
Normal file
25
README.md
Normal 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
7
b0rged.service
Normal 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
83
b0rged.sh
Executable 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
12
b0rged.timer
Normal 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
16
env.example
Normal 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
11
patterns.system
Normal file
|
@ -0,0 +1,11 @@
|
|||
R /etc
|
||||
R /root
|
||||
- **/log/
|
||||
- **/logs/
|
||||
- **/cache/
|
||||
- **/.cache/
|
||||
- **/node_modules/
|
||||
- **/vendor/
|
||||
- **/typo3temp/
|
||||
- **/composer-cache/
|
||||
- **/.git/
|
Loading…
Reference in a new issue