173 lines
4.3 KiB
Bash
Executable File
173 lines
4.3 KiB
Bash
Executable File
#! /bin/bash
|
|
|
|
function main() {
|
|
set -e
|
|
set -u
|
|
|
|
cd "$(dirname "${BASH_SOURCE[0]}")"
|
|
export GOPATH="$PWD/restic-go"
|
|
|
|
if [ -z "${PASSWORD:-""}" ]; then
|
|
read -sp "Password: " PASSWORD
|
|
echo ""
|
|
fi
|
|
|
|
install
|
|
|
|
configure
|
|
|
|
local action="$1"
|
|
shift
|
|
case "$action" in
|
|
clean ) clean_remote "$@" ;;
|
|
backup ) backup "$@" ;;
|
|
restore ) restore "$@" ;;
|
|
* ) RESTIC "$action" "$@" ;;
|
|
esac
|
|
}
|
|
|
|
function install() {
|
|
if ! go version; then
|
|
echo "Must install go" >&2
|
|
exit 1
|
|
fi
|
|
export GOFLAGS=""; export GO111MODULE=""; export GOPROXY=""
|
|
export GOFLAGS=""
|
|
mkdir -p "$GOPATH/bin/$(uname)"
|
|
for i in ncw/rclone restic/restic; do
|
|
local b="${i##*/}"
|
|
if [ -e "$GOPATH/bin/$(uname)/$b" ]; then
|
|
continue
|
|
fi
|
|
mkdir -p $GOPATH/src/github.com/${i%/*}
|
|
#go get -u "github.com/$i" || true
|
|
pushd "$GOPATH/src/github.com/${i%/*}"
|
|
git clone --depth 1 --branch master https://github.com/$i
|
|
cd ${i##*/}
|
|
go get ./...
|
|
case "$i" in
|
|
restic* )
|
|
go run build.go
|
|
mv "./$b" "$GOPATH/bin/$(uname)/$b"
|
|
;;
|
|
* )
|
|
go install
|
|
mv "$GOPATH/bin/$b" "$GOPATH/bin/$(uname)/$b"
|
|
;;
|
|
esac
|
|
popd
|
|
done
|
|
}
|
|
|
|
function configure() {
|
|
mkdir -p "$PWD/config"
|
|
if [ ! -e "$PWD/config/rclone" ]; then
|
|
configure_rclone
|
|
fi
|
|
if [ ! -e "$PWD/config/restic" ]; then
|
|
configure_restic
|
|
fi
|
|
}
|
|
|
|
function configure_rclone() {
|
|
RCLONE config create remote drive
|
|
#RCLONE config create remote-enc crypt \
|
|
# remote remote:cloudly/restic \
|
|
# filename_encryption obfuscate \
|
|
# directory_name_encryption true \
|
|
# password $PASSWORD \
|
|
# password2 ""
|
|
}
|
|
|
|
function configure_restic() {
|
|
RESTIC init
|
|
touch "$PWD/config/restic"
|
|
}
|
|
|
|
function backup() {
|
|
local args=()
|
|
for arg in "$@"; do
|
|
local real="$(realpath "$arg")"
|
|
if [ "$real" == "${real#$HOME}" ]; then
|
|
log "Cowardly skipping $arg ($real) for not being under \$HOME ($HOME)"
|
|
continue
|
|
fi
|
|
args+=("$real")
|
|
done
|
|
local extraTags=" "
|
|
if [ -n "${TAGS:-""}" ]; then
|
|
extraTags="--tag $TAGS"
|
|
fi
|
|
log "BACKUP ${args[@]}"
|
|
RESTIC backup \
|
|
-e "**.sw*" \
|
|
--tag "${real#$HOME/}" \
|
|
$extraTags \
|
|
"${args[@]}"
|
|
}
|
|
|
|
function restore() {
|
|
for arg in "$@"; do
|
|
if [ -e "$arg" ] || [ -d "$arg" ]; then
|
|
arg="$(realpath "$arg")"
|
|
fi
|
|
local latest="$(RESTIC snapshots --last --tag "${arg#$HOME/}" | sort -k 2 | grep '20[0-9][0-9].[0-9][0-9].[0-9][0-9]' | tail -n 1)"
|
|
local id="$(echo "$latest" | awk '{print $1}')"
|
|
local path="$(echo "$latest" | awk '{print $5}')"
|
|
local rpath="$(echo "$latest" | awk '{print $6}')"
|
|
log "RESTORE $id as $HOME/$path as $HOME/$path-restore"
|
|
rm -rf "$HOME/$path-"{dump,restore} 2> /dev/null \
|
|
|| sudo rm -rf "$HOME/$path-"{dump,restore} 2> /dev/null \
|
|
|| true
|
|
mkdir -p "$HOME/$path-dump"
|
|
RESTIC restore $id --target "$HOME/$path-dump"
|
|
mv "$HOME/$path-dump/${rpath#/}" "$HOME/$path-restore"
|
|
rm -rf "$HOME/$path-"{dump,old} \
|
|
|| sudo rm -rf "$HOME/$path-"{dump,old} \
|
|
|| true
|
|
if [ -d "$HOME/$path" ]; then
|
|
mv "$HOME/$path" "$HOME/$path-old"
|
|
fi
|
|
mv "$HOME/$path-restore" "$HOME/$path"
|
|
done
|
|
if [ -z "${DIRTY:-}" ]; then
|
|
clean_remote
|
|
fi
|
|
}
|
|
|
|
function clean_remote() {
|
|
RESTIC forget --prune --cleanup-cache --keep-last 2 --group-by host,tags "$@"
|
|
RESTIC check
|
|
}
|
|
|
|
function RCLONE() {
|
|
$GOPATH/bin/$(uname)/rclone --config=$PWD/config/rclone --ask-password=false "$@"
|
|
}
|
|
|
|
function RESTIC() {
|
|
RESTIC_PASSWORD=$PASSWORD \
|
|
$GOPATH/bin/$(uname)/restic \
|
|
-r rclone:remote:cloudly/restic-plain/backup \
|
|
-o rclone.program=$GOPATH/bin/$(uname)/rclone \
|
|
-o rclone.args="serve restic --stdio --b2-hard-delete --drive-use-trash=false --config $PWD/config/rclone --bwlimit 26M --ask-password=false" \
|
|
"$@"
|
|
|
|
#-r rclone:remote-enc:backup
|
|
}
|
|
|
|
function log() {
|
|
echo "$(date +%H:%M:%S): $@" >&2
|
|
}
|
|
|
|
function fatal() {
|
|
log "$@"
|
|
exit 1
|
|
}
|
|
|
|
if [ "$0" == "${BASH_SOURCE[0]}" ]; then
|
|
SECONDS=0
|
|
log "Start"
|
|
main "$@"
|
|
log "Stop ($?): $(python3 -c "print(int(10*$SECONDS/60)/10.0, 'minutes')")"
|
|
fi
|