Last active
August 25, 2023 03:44
-
-
Save brycied00d/689f9abd08678b7463b36ad899aabaad to your computer and use it in GitHub Desktop.
backup-restic.sh - My generap-purpose script to backup a system, balancing simplicity with configurability.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is an example file, with example values. | |
#export RESTIC_PASSWORD=apassword | |
#export RESTIC_REPOSITORY=b2:bucket:path | |
#export B2_ACCOUNT_ID=12345 | |
#export B2_ACCOUNT_KEY=abcdefg | |
#restic_backup /etc | |
#restic_backup /root | |
#restic_backup /var | |
#restic_backup /usr/local | |
#restic_backup /home | |
#restic_backup --exclude /srv/Apt/acng/ /srv | |
#cd /tmp ; sudo -u postgres /usr/bin/pg_dumpall | restic_backup --stdin --stdin-filename postgres.sql | |
## Example of using LVM snapshots to backup point-in-time. This may be merged into backup-restic.sh | |
#snap_and_mount() { | |
# if [ -z "$1" ] ; then return 1 ; fi | |
# vg="$1" | |
# if [ -z "$2" ] ; then return 1 ; fi | |
# lv="$2" | |
# size=${3:-200G} | |
# /sbin/lvcreate --snapshot "$vg"/"$lv" --size $size --name backupsnapb2 --addtag temporary ; ret=$? | |
# #echo "lvcreate $ret" | |
# if [ $ret -eq 0 ] ; then | |
# mkdir -p /mnt/VG-"$vg"_LV-"$lv" | |
# mount -o ro /dev/"$vg"/backupsnapb2 /mnt/VG-"$vg"_LV-"$lv" ; ret=$? | |
# #echo "mount $ret" | |
# fi | |
# # Returns the last exit value, either lvcreate or mount, which should be 0 if success | |
# return $ret | |
#} | |
#umount_and_unsnap() { | |
# if [ -z "$1" ] ; then return 1 ; fi | |
# vg="$1" | |
# umount /dev/"$vg"/backupsnapb2 ; ret=$? | |
# #echo "Umount $ret" | |
# if [ $ret -eq 0 ] ; then | |
# /sbin/lvremove --force /dev/"$vg"/backupsnapb2 ; ret=$? | |
# #echo "lvremove $ret" | |
# fi | |
# # Returns the last exit value, either lvcreate or mount, which should be 0 if success | |
# return $ret | |
#} | |
## N=boot | |
#restic_backup /boot | |
#V=nextcloud-vg | |
#N=root | |
#if snap_and_mount $V $N 8G ; then | |
# restic_backup /mnt/VG-"$V"_LV-"$N"/etc | |
# restic_backup /mnt/VG-"$V"_LV-"$N"/home | |
# umount_and_unsnap $V | |
#fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# backup-restic | |
# | |
# Simple, basic script for performing backups using restic, and maintaining | |
# restic repositories. | |
# Configuration, including RESTIC_* and backend variables, and backup tasks go | |
# into /etc/backup-restic.conf which is a regular shell script that is sourced. | |
# | |
# Help: backup-restic.sh [configuration] [<help|install <version>|init|newkey|backup|$othercommands>] | |
# configuration -- Optional path to a configuration file. Defaults to /etc/backup-restic.conf | |
# install <version> -- install the specified version of restic to /usr/local/bin/restic | |
# init -- Initialise a new repository (RESTIC_REPOSITORY in the configuration) | |
# newkey -- Add a new key to the RESTIC_REPOSITORY | |
# backup -- Backup the given path. This is an alias to the restic_backup directive. | |
# $othercommands -- Any other restic commands, and their arguments, to be executed within the configured Restic parameters. | |
# No Arguments -- Perform the default backup operation. | |
# | |
# Installation: Install this script into /usr/local/bin/backup-restic.sh, then | |
# write the configuration file with commands and restic_backup. | |
# Cron: /usr/bin/ionice -c 2 -n 4 /usr/bin/nice /usr/local/bin/backup-restic.sh /etc/backup-restic_b2.conf | /usr/bin/logger -t backup-restic_b2 | |
# | |
# PS: Yes, it does require bash (or ksh) for `[[` | |
# | |
# Author: Bryce Chidester <[email protected]> | |
# Copyright: BSD 2-clause | |
# | |
# Changelog: | |
# 4: Work-around for https://github.com/restic/restic/issues/1807 by not | |
# passing --one-file-system if the backup command contains --stdin | |
# 3: Support for specifying/installing restic beta snapshots. Improved error | |
# handling and resiliency, will now exit if there are any syntax errors. | |
# Note: This may cause problems when restic reports an error (such as a file | |
# having changed on-disk during backup). This will be addressed in the future. | |
# Added support for PRUNE_OPTS? | |
# 2: Added some "help" functionality | |
# 1: Initial "release" | |
export SCRIPT_VERSION=4 | |
UPSTREAM_VERSION=$(curl -sSL -A "$(basename $0)/$SCRIPT_VERSION ($(hostname))" https://brycesawesomeapp.com/backup-restic.sh | perl -n -e'/export SCRIPT_VERSION=(\d+)/ && print $1') | |
if [ "$UPSTREAM_VERSION" -gt "$SCRIPT_VERSION" ]; then | |
echo "Warning: There is an updated script available. Upgrade with:" | |
echo "curl --output $0 https://brycesawesomeapp.com/backup-restic.sh ; chmod +x $0" | |
sleep 5 | |
# Don't exit, just warn. | |
fi | |
set -e # All errors (non-zero return) are fatal errors. | |
set -f # No globbing | |
set -C # No clobber | |
export CONFIG_FILE=/etc/backup-restic.conf | |
if [ -f "$1" ]; then | |
echo "Found configuration file: $1" | |
export CONFIG_FILE="$1" | |
shift | |
fi | |
if [ ! -f "$CONFIG_FILE" ]; then | |
echo "Unable to open the configuration file ($CONFIG_FILE). Exiting." | |
exit 1 | |
fi | |
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin | |
export SCRIPT_NAME=$(basename $0) | |
export SCRIPT_BASENAME=$(basename $0 .sh) | |
export CONFIG_NAME=$(basename $CONFIG_FILE) | |
export CONFIG_BASENAME=$(basename $CONFIG_FILE .conf) | |
function restic_backup { # Alias | |
# Only runs once everything is ready and configured. | |
[ "x$CONFIGURED" = "x1" ] || return 0 | |
ex= | |
if ! [[ $@ == *'--stdin'* ]]; then | |
ex=--one-file-system | |
fi | |
restic backup \ | |
--tag "SCR:$SCRIPT_NAME" \ | |
--tag "VER:$SCRIPT_VERSION" \ | |
--tag "CFG:$CONFIG_NAME" \ | |
$ex \ | |
$@ | |
} | |
# Read the configuration (embedded calls to restic_backup will fail until CONFIGURED=1) | |
export CONFIGURED=0 | |
. $CONFIG_FILE | |
if [[ "$1" = *help* ]]; then | |
head -n22 $0 | |
exit 0 | |
elif [ "x$1" = "xinstall" -a -n "$2" ]; then | |
GOOS=$(uname -s) | |
if [ "$GOOS" = "Linux" ]; then GOOS=linux | |
elif [ "$GOOS" = "OpenBSD" ]; then GOOS=openbsd | |
fi | |
GOARCH=$(uname -m) | |
if [ "$GOARCH" = "x86_64" ]; then GOARCH=amd64 | |
elif [[ "$GOARCH" = i*86 ]]; then GOARCH=386 | |
fi | |
if [[ "$2" = *.*.*-* ]]; then | |
echo "Downloading and installing restic SNAPSHOT v$2 for $GOOS/$GOARCH" | |
if ! curl -sSL --output /usr/local/bin/restic https://beta.restic.net/v$2/restic_v${2}_${GOOS}_${GOARCH} ; then | |
echo "Error downloading restic." | |
exit 1 | |
fi | |
else | |
echo "Downloading and installing restic v$2 for $GOOS/$GOARCH" | |
# Note: curl exits non-zero if bzcat fails because curl "Failed writing body" | |
if ! curl -sSL https://github.com/restic/restic/releases/download/v$2/restic_${2}_${GOOS}_${GOARCH}.bz2 | bzcat > /usr/local/bin/restic ; then | |
echo "Error downloading restic." | |
exit 1 | |
fi | |
fi | |
chmod +x /usr/local/bin/restic | |
exit 0 | |
elif [ "x$1" = "xinstall" ]; then | |
echo "A version to install must be specified." | |
exit 1 | |
elif [ "x$1" = "xnewkey" ]; then | |
echo -n "Enter current password: " | |
read -s RESTIC_PASSWORD | |
echo | |
restic key add | |
echo Be sure to update RESTIC_PASSWORD | |
exit 0 | |
elif [ "x$1" = "xinit" ]; then | |
restic init -o b2.connections=10 | |
exit 0 | |
elif [ -n "$1" ]; then | |
if [ "$1" = "backup" ]; then | |
shift | |
export CONFIGURED=1 | |
restic_backup $@ | |
else | |
restic $@ | |
fi | |
exit 0 | |
fi | |
# TODO: Change lock path on OpenBSD | |
if ! mkdir /var/lock/$SCRIPT_BASENAME ; then echo Lock file exists. Another backup process is already running. ; exit 1 ; fi | |
trap "rmdir /var/lock/$SCRIPT_BASENAME" EXIT INT TERM ERR | |
# No point scooping up anything temporary | |
which apt-get 2>/dev/null >/dev/null && apt-get clean | |
# This time, it's okay to run | |
export CONFIGURED=1 | |
. $CONFIG_FILE | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment