#!/bin/bash

# backup.sh is a simple example of how to safely backup the internally
# consistent state of a system installed to btrfs to some other
# location.  It uses snapshots and rsync, and thus "$target" is any
# destination supported by rsync.  It is a full-system backup utility
# that assumes superuser capabilities.
#
# Please report any issues with backup.sh using 'reportbug btrfs-progs'
#
# © 2015,2026 Nicholas D Steeves
# SPDX-License-Identifier: GPL-2.0-only

fsroot="/btrfs-admin"
snapdir="$fsroot/snapshots"
#sources=(@rootfs)
#sources=(@home @)
#target="/mnt/usb-disk/laptop-LATEST-RSYNC"
#target="root@nas:/backups/laptop-LATEST-RSYNC"
# Change "zstd" to your choice of rsync-suppported compression
# algorithm, set to "" to autonegotiate, or set to "none" for no
# compression.
compression="zstd"

check_prerequisites(){
    if [[ ! -v fsroot ]] || [[ ! -v snapdir ]] || [[ ! -v sources ]] || [[ ! -v target ]] || [[ ! -v compression ]]; then
        echo -en "\n    "
        realpath "${BASH_SOURCE:-$0}"
        echo "    has incomplete configuration."
        echo -e "    Aborting now.\n"
        exit 1
    fi
    if ! findmnt --noheadings --nofsroot "$fsroot"; then
        if [ ! -t 0 ]; then
            echo "$fsroot does not exist and this is a noninteractive terminal."
            echo "Aborting now."
            exit 1
        else
            while true; do
                echo -n "Filesystem root not found at $fsroot!  Create? (yes/no): "
                read -r choice
                case "$choice" in
                    yes | y | Yes | YES )
                        break
                        ;;
                    no | n | No | NO )
                        echo "Cannot continue without fsroot.  Exiting now."
                        exit 1
                        ;;
                    * )
                        echo -e "Please answer yes or no.\n"
                        ;;
                esac
            done
            echo "Creating $fsroot mount point with safe permissions."
            install -d -m 700 "$fsroot"
            mount "$(findmnt --noheadings --nofsroot -o SOURCE /)" "-o" "subvolid=5,noatime" "$fsroot"
        fi
    fi
}

fail(){
    local exit_code="$1"
    echo "Something failed in $2()...exiting now"
    exit "$exit_code"
}

backup(){
    rsync --acls --archive --hard-links --sparse --xattrs \
          --compress-choice="$compression" --delete \
          --info=progress2 \
          ./  "$target" \
        || fail "$?" "${FUNCNAME[0]}"
}

cleanup(){
    echo "Expunging temporary snapshots created for the following: $*"
    btrfs sub del -c "$@" >/dev/null || fail "$?" "${FUNCNAME[0]}"
    sync
    rmdir "$snapdir/backup.sh-$epoch"
}

snapshot(){
    mkdir -p "$snapdir/backup.sh-$epoch" || fail "$?" "${FUNCNAME[0]}"
    cd "$_" || fail "$?" "${FUNCNAME[0]}"
    for i in "$@"; do
        echo "Creating read-only snapshot $snapdir/backup.sh-$epoch/$i"
        btrfs sub snap -r ../../"$i" . >/dev/null || fail "$?" "${FUNCNAME[0]}"
    done
}


epoch="$(date "+%s")"
check_prerequisites
snapshot "${sources[@]}"
backup
cleanup "${sources[@]}"
