Created
February 6, 2026 06:43
-
-
Save gjaekel/dee5fd7648854d4d9fac19143ece0275 to your computer and use it in GitHub Desktop.
Restic Wrapper
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
| #!/bin/bash | |
| # | |
| # 20231229/gj | |
| # 20240314/gj keep policy | |
| # 20240315/gj backup ALL meta source | |
| # 20240330/gj AUTO-DRY --yes | |
| # 20241112/gj disable cache | |
| # 20241110/gj mention about dry run | |
| # 20241207/gj set TMPDIR to cache dir | |
| # 20250221/gj ensure existence of TMPDIR | |
| # 20260206/gj add filesystem layout example | |
| #======================================== | |
| # | |
| # filesystem layout example | |
| # | |
| # root@client:/import/storage/backup# tree -L 2 restic | |
| # restic | |
| # ├── bin | |
| # │ ├── _restic | |
| # │ ├── restic -> restic_0.17.3_linux_amd64 | |
| # │ ├── _restic-remote-backup | |
| # │ └── URL | |
| # ├── bar | |
| # │ ├── config | |
| # │ ├── data | |
| # │ ├── index | |
| # │ ├── keys | |
| # │ ├── locks | |
| # │ └── snapshots | |
| # ├── foo | |
| # │ ├── config | |
| # │ ├── data | |
| # │ ├── index | |
| # │ ├── keys | |
| # │ ├── locks | |
| # │ └── snapshots | |
| # ├── _restic.bar -> bin/_restic | |
| # ├── | |
| # ├── _restic.bar -> bin/_restic | |
| # └── _restic.foo -> bin/_restic | |
| # | |
| #---------------------------------------- | |
| REPOSITORY="${0##*.}"; [ -z "$REPOSITORY" ] && REPOSITORY="restic" | |
| P="$(realpath $0)" | |
| RESTIC_BASE="${P%/bin/*}"; [ ! -d "$RESTIC_BASE" ] && echo "base dir not found!" >&2 && exit -1 | |
| RESTIC_BIN="$RESTIC_BASE/bin/restic"; [ ! -x "$RESTIC_BIN" ] && echo "restic binary not found!" >&2 && exit -1 | |
| ROOT_PARTITION="$(sed 's#^/dev/\([^ ]*\) / .*#\1#p' -n /proc/mounts)" | |
| EXCLUDES=('/mnt/*' '.cache/') | |
| MOUNTPOINT="/tmp/restic" | |
| PRUNE_POLICY="--max-unused 1%" | |
| KEEP_POLICY="--keep-within-daily 7d --keep-within-weekly 1m --keep-within-monthly 1y --keep-within-yearly 1000y --prune $PRUNE_POLICY" | |
| KEEP_POLICY="--keep-within-daily 14d --keep-within-weekly 2m --keep-within-monthly 2y --keep-within-yearly 1000y --prune $PRUNE_POLICY" | |
| KEEP_POLICY="--keep-tag keep --keep-daily 14 --keep-weekly 8 --keep-monthly 24 --keep-yearly 1000 --prune $PRUNE_POLICY" | |
| RESTIC () { | |
| export TMPDIR="$HOME/.cache/restic" | |
| [ ! -d "$TMPDIR" ] && mkdir -p "$TMPDIR" && echo "TMPDIR \"$TMPDIR \" created." | |
| [ ! -d "$TMPDIR" ] && echo "FATAL: can't create TMPDIR \"$TMPDIR\"!" >&2 && exit -1 | |
| echo "running \"restic $@\" on repository \"$REPOSITORY\" ..." >&2 | |
| RESTIC_REPOSITORY=$RESTIC_BASE/$REPOSITORY \ | |
| RESTIC_PASSWORD=$(rev <<< citser) \ | |
| RESTIC_COMPRESSION=max \ | |
| RESTIC_READ_CONCURRENCY=$(nproc) \ | |
| $RESTIC_BIN $@ | |
| } | |
| PARTITION_OF() { # $1: file-or-path | |
| local PARTITION="$(findmnt -n -o SOURCE -T $1)" | |
| echo "${PARTITION#/dev/}" | |
| } | |
| CMD="$1"; shift | |
| # # auto disable cache | |
| # [ "$CMD" -a "$CMD" != "raw" ] && NOCACHE="--no-cache" && for ARG; do shift; [ "$ARG" == "--cache" ] && NOCACHE="" && continue; set -- "$@" "$ARG"; done && [ -z "$NOCACHE" ] && echo "caching enabled" | |
| # auto dry run | |
| AUTO_DRY='DRY="-n"; for ARG; do shift; [ "$ARG" == "-Y" -o "${ARG^^}" == "--YES" ] && DRY="" && continue; set -- "$@" "$ARG"; done; [ -z "$DRY" ] && echo -n "*NO* "; echo "DRY RUN!"' # cancel dry run by --yes or -Y | |
| case "$CMD" in | |
| 'raw') | |
| CMD="$1"; shift | |
| ;; | |
| 'backup') | |
| SRC="$1"; shift; [ -z "$SRC" ] && echo "no source directory given!" >&2 && exit -1 | |
| if [ "$SRC" == "ALL" ]; then | |
| case "$REPOSITORY" in | |
| 'esprimo') SRCS="/mnt/sda{4,7,8}";; | |
| 'ubuntu') SRCS='/';; | |
| *) echo "unknow repository, ALL not definied!" >&2 && exit 1 | |
| esac | |
| SRCS="$(eval echo $SRCS)" | |
| echo "ALL is \"$SRCS\"" | |
| for SRC in $SRCS; do | |
| $0 backup $SRC $@ | |
| done | |
| exit | |
| fi | |
| [ ! -d "$SRC" ] && echo "\"$SRC\" don't exists!" >&2 && exit -1 | |
| PARTITION="$(PARTITION_OF $SRC)" | |
| OPTS="-v -x --no-cache --exclude-caches ${EXCLUDES[@]/#/--exclude=}" | |
| [[ "$SRC" =~ ^/mnt/ ]] && OPTS+=" --exclude=!$SRC" | |
| OPTS+=" ${PARTITION:+--tag $PARTITION} $SRC" | |
| CMD="backup" | |
| ;; | |
| 'mount') | |
| [ ! -d "$MOUNTPOINT" ] && mkdir "$MOUNTPOINT" -p && trap "rmdir $MOUNTPOINT" EXIT | |
| OPTS="--path-template %h:%t/%T $MOUNTPOINT" | |
| ;; | |
| 'forget') | |
| eval $AUTO_DRY | |
| OPTS="$KEEP_POLICY${DRY:+ $DRY}" | |
| ;; | |
| 'prune') | |
| eval $AUTO_DRY | |
| OPTS="$PRUNE_POLICY${DRY:+ $DRY}" | |
| esac | |
| RESTIC "$CMD""${NOCACHE+ $NOCACHE}""${OPTS+ $OPTS}" "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment