Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f3647fb0c | ||
|
|
dd073dfc73 | ||
|
|
b23d552f0b |
11
CHANGELOG.md
11
CHANGELOG.md
@@ -6,11 +6,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [4.0.0] - 2022-02-01
|
||||
### Fixed
|
||||
- Use arrays to build up command lines. When fixing `shellcheck(1)` errors, quotes would disable expansion on e.g. $RESTIC_BACKUP_PATHS
|
||||
- **BREAKING CHANGE** `RESTIC_BACKUP_PATHS` is now a string with `:` separated values
|
||||
|
||||
## [3.0.1] - 2022-02-01
|
||||
### Fixed
|
||||
- Environment variable assertion should allow empty values e.g. `RESTIC_BACKUP_EXTRA_ARGS`
|
||||
|
||||
## [3.0.0] - 2022-02-01
|
||||
### Added
|
||||
- Allow extra arguments to restic-backup with `$RESTIC_BACKUP_EXTRA_ARGS`.
|
||||
- Add `$RESTIC_VERBOSITY_LEVEL` for debugging.
|
||||
- Assertion on all needed envionment variables in the backup and check scripts.
|
||||
- Assertion on all needed environment variables in the backup and check scripts.
|
||||
- Added linter (`shellcheck(1)`) that is run on push and PRs.
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -20,7 +20,8 @@ export B2_ACCOUNT_KEY="<b2-application-key>" # TODO fill with your applicationKe
|
||||
# How many network connections to set up to B2. Default is 5.
|
||||
export B2_CONNECTIONS=10
|
||||
|
||||
# Extra args to restic-backup. This is empty here and profiles can override this after sourcing this file.
|
||||
# Optional extra space-separated args to restic-backup.
|
||||
# This is empty here and profiles can override this after sourcing this file.
|
||||
export RESTIC_BACKUP_EXTRA_ARGS=
|
||||
|
||||
# Verbosity level from 0-3. 0 means no --verbose.
|
||||
|
||||
@@ -15,10 +15,11 @@ source /etc/restic/_global.env
|
||||
|
||||
export RESTIC_REPOSITORY="b2:<b2-repo-name>" # TODO fill with your repo name
|
||||
|
||||
# What to backup (paths our mountpoints) e.g. "/ /boot /home /mnt/media".
|
||||
# What to backup. Colon-separated paths e.g. to different mountpoints "/home:/mnt/usb_disk".
|
||||
# To backup only your home directory, set "/home/your-user"
|
||||
export RESTIC_BACKUP_PATHS="" # TODO fill conveniently with one or multiple paths
|
||||
|
||||
|
||||
# Example below of how to dynamically add a path that is mounted e.g. external USB disk.
|
||||
# restic does not fail if a specified path is not mounted, but it's nicer to only add if they are available.
|
||||
#test -d /mnt/media && RESTIC_BACKUP_PATHS+=" /mnt/media"
|
||||
@@ -33,8 +34,8 @@ export RESTIC_RETENTION_WEEKS=16
|
||||
export RESTIC_RETENTION_MONTHS=18
|
||||
export RESTIC_RETENTION_YEARS=3
|
||||
|
||||
# Optional extra arguments to restic-backup.
|
||||
# Optional extra space-separated arguments to restic-backup.
|
||||
# Example: Add two additional exclude files to the global one in RESTIC_PASSWORD_FILE.
|
||||
#RESTIC_BACKUP_EXTRA_ARGS="--exclude-file /path/to/extra/exclude/file/a /path/to/extra/exclude/file/b"
|
||||
#RESTIC_BACKUP_EXTRA_ARGS="--exclude-file /path/to/extra/exclude/file/a --exclude-file /path/to/extra/exclude/file/b"
|
||||
# Example: exclude all directories that have a .git/ directory inside it.
|
||||
#RESTIC_BACKUP_EXTRA_ARGS="--exclude-if-present .git"
|
||||
|
||||
@@ -11,14 +11,24 @@
|
||||
# Exit on error, unset var, pipe failure
|
||||
set -euo pipefail
|
||||
|
||||
# Clean up lock if we are killed.
|
||||
# If killed by systemd, like $(systemctl stop restic), then it kills the whole cgroup and all it's subprocesses.
|
||||
# However if we kill this script ourselves, we need this trap that kills all subprocesses manually.
|
||||
exit_hook() {
|
||||
echo "In exit_hook(), being killed" >&2
|
||||
jobs -p | xargs kill
|
||||
restic unlock
|
||||
}
|
||||
trap exit_hook INT TERM
|
||||
|
||||
|
||||
# Assert that all needed environment variables are set.
|
||||
# TODO in future if this grows, move this to a restic_lib.sh
|
||||
assert_envvars() {
|
||||
local varnames=("$@")
|
||||
for varname in "${varnames[@]}"; do
|
||||
# Check if variable is set, then if it is not empty (need to do both as of `set -u`).
|
||||
if [ -z ${!varname+x} ] || [ -z "${!varname}" ] ; then
|
||||
printf "%s must be set with a value for this script to work.\n\nDid you forget to source a /etc/restic/*.env profile in the current shell before executing this script?\n" "$varname" >&2
|
||||
if [ -z ${!varname+x} ]; then
|
||||
printf "%s must be set for this script to work.\n\nDid you forget to source a /etc/restic/*.env profile in the current shell before executing this script?\n" "$varname" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
@@ -30,25 +40,20 @@ assert_envvars \
|
||||
RESTIC_RETENTION_DAYS RESTIC_RETENTION_MONTHS RESTIC_RETENTION_WEEKS RESTIC_RETENTION_YEARS
|
||||
|
||||
|
||||
# Clean up lock if we are killed.
|
||||
# If killed by systemd, like $(systemctl stop restic), then it kills the whole cgroup and all it's subprocesses.
|
||||
# However if we kill this script ourselves, we need this trap that kills all subprocesses manually.
|
||||
exit_hook() {
|
||||
echo "In exit_hook(), being killed" >&2
|
||||
jobs -p | xargs kill
|
||||
restic unlock
|
||||
}
|
||||
trap exit_hook INT TERM
|
||||
# Convert to arrays, as arrays should be used to build command lines. See https://github.com/koalaman/shellcheck/wiki/SC2086
|
||||
IFS=':' read -ra backup_paths <<< "$RESTIC_BACKUP_PATHS"
|
||||
IFS=' ' read -ra extra_args <<< "$RESTIC_BACKUP_EXTRA_ARGS"
|
||||
|
||||
|
||||
# Set up exclude files: global + path-specific ones
|
||||
# NOTE that restic will fail the backup if not all listed --exclude-files exist. Thus we should only list them if they are really all available.
|
||||
## Global backup configuration.
|
||||
exclusion_args="--exclude-file ${RESTIC_BACKUP_EXCLUDE_FILE}"
|
||||
## Self-contained backup files per backup path. E.g. having an USB disk at /mnt/media in RESTIC_BACKUP_PATHS,
|
||||
# a file /mnt/media/.backup_exclude.txt will automatically be detected and used:
|
||||
for backup_path in "${RESTIC_BACKUP_PATHS[@]}"; do
|
||||
exclusion_args=(--exclude-file "$RESTIC_BACKUP_EXCLUDE_FILE")
|
||||
## Self-contained backup exclusion files per backup path. E.g. having an USB disk at /mnt/media in RESTIC_BACKUP_PATHS,
|
||||
# then a file /mnt/media/.backup_exclude.txt will automatically be detected and used:
|
||||
for backup_path in "${backup_paths[@]}"; do
|
||||
if [ -f "$backup_path/.backup_exclude.txt" ]; then
|
||||
exclusion_args+=" --exclude-file $backup_path/.backup_exclude.txt"
|
||||
exclusion_args=("${exclusion_args[@]}" --exclude-file "$backup_path/.backup_exclude.txt")
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -70,9 +75,9 @@ restic backup \
|
||||
--one-file-system \
|
||||
--tag "$RESTIC_BACKUP_TAG" \
|
||||
--option b2.connections="$B2_CONNECTIONS" \
|
||||
"$exclusion_args" \
|
||||
"$RESTIC_BACKUP_EXTRA_ARGS" \
|
||||
"$RESTIC_BACKUP_PATHS" &
|
||||
"${exclusion_args[@]}" \
|
||||
"${extra_args[@]}" \
|
||||
"${backup_paths[@]}" &
|
||||
wait $!
|
||||
|
||||
# Dereference and delete/prune old backups.
|
||||
|
||||
@@ -5,21 +5,6 @@
|
||||
# Exit on error, unset var, pipe failure
|
||||
set -euo pipefail
|
||||
|
||||
# Assert that all needed environment variables are set.
|
||||
assert_envvars() {
|
||||
local varnames=("$@")
|
||||
for varname in "${varnames[@]}"; do
|
||||
# Check if variable is set, then if it is not empty (need to do both as of `set -u`).
|
||||
if [ -z ${!varname+x} ] || [ -z "${!varname}" ] ; then
|
||||
printf "%s must be set with a value for this script to work.\n\nDid you forget to source a /etc/restic/*.env profile in the current shell before executing this script?\n" "$varname" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
assert_envvars \
|
||||
B2_ACCOUNT_ID B2_ACCOUNT_KEY B2_CONNECTIONS \
|
||||
RESTIC_PASSWORD_FILE RESTIC_REPOSITORY RESTIC_VERBOSITY_LEVEL
|
||||
|
||||
# Clean up lock if we are killed.
|
||||
# If killed by systemd, like $(systemctl stop restic), then it kills the whole cgroup and all it's subprocesses.
|
||||
# However if we kill this script ourselves, we need this trap that kills all subprocesses manually.
|
||||
@@ -30,6 +15,21 @@ exit_hook() {
|
||||
}
|
||||
trap exit_hook INT TERM
|
||||
|
||||
# Assert that all needed environment variables are set.
|
||||
assert_envvars() {
|
||||
local varnames=("$@")
|
||||
for varname in "${varnames[@]}"; do
|
||||
if [ -z ${!varname+x} ]; then
|
||||
printf "%s must be set for this script to work.\n\nDid you forget to source a /etc/restic/*.env profile in the current shell before executing this script?\n" "$varname" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
assert_envvars \
|
||||
B2_ACCOUNT_ID B2_ACCOUNT_KEY B2_CONNECTIONS \
|
||||
RESTIC_PASSWORD_FILE RESTIC_REPOSITORY RESTIC_VERBOSITY_LEVEL
|
||||
|
||||
|
||||
# Remove locks from other stale processes to keep the automated backup running.
|
||||
# NOTE nope, don't unlock like restic_backup.sh. restic_backup.sh should take precedence over this script.
|
||||
#restic unlock &
|
||||
|
||||
Reference in New Issue
Block a user