#!/bin/bash
################################################
### Managed by someone's ansible provisioner ###
################################################
# Part of: https://git.somenet.org/root/pub/somesible.git
# 2017-2026 by someone <someone@somenet.org>
#

umask 0077
cd /tmp
export ERRCODE=0

export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK="yes"
export BORG_RELOCATED_REPO_ACCESS_IS_OK="yes"

function backup {
    export BKPREPO=${1} # backup repo (should be: "/bkp/storage-local/$host/$path" or for ssh: "user@server:$path")
    export BKPHOST=${2} # src-host
    export BKPPATH=${3} # abs-path on src-host
    export BKPKEEP=${4} # pruning-settings
    export BORG_PASSPHRASE=${5} # borg key passphrase

    BKPPATH_ESCAPED=$(echo -n "$BKPPATH"|sed -e 's#/#-#g') # contains first "/"

    if [[ -z "$BORG_PASSPHRASE" ]]; then
        borg info "$BKPREPO" >/dev/null 2>&1 || borg init --umask 0077 -e none --make-parent-dirs "$BKPREPO"
    else
        borg info "$BKPREPO" >/dev/null 2>&1 || borg init --umask 0077 -e repokey-blake2 --make-parent-dirs "$BKPREPO"
    fi

    echo "# Merged on: $(date -Isec)" > "/bkp/local/exclude.conf.d/.merged.$BKPHOST-$BKPPATH_ESCAPED"
    for file in /bkp/local/exclude.conf.d/$BKPHOST-$BKPPATH_ESCAPED*; do
        echo -e "\n\n# $file" >> "/bkp/local/exclude.conf.d/.merged.$BKPHOST-$BKPPATH_ESCAPED"
        cat "$file" >> "/bkp/local/exclude.conf.d/.merged.$BKPHOST-$BKPPATH_ESCAPED"
    done

    borg create --umask 0077 --info --list --stats --noctime --nobirthtime --exclude-caches --exclude-from "/bkp/local/exclude.conf.d/.merged.$BKPHOST-$BKPPATH_ESCAPED" "$BKPREPO::$BKPHOST-$BKPPATH_ESCAPED--{now}" "$BKPPATH"
        exit_status=$?;
        if [ $exit_status -ne 0 ]; then
            export ERRCODE="$exit_status";
            echo "** backup.sh (backup:create): non-zero exitcode: $exit_status"
        fi

    backup_prune "$BKPREPO" "$BKPKEEP" "$BORG_PASSPHRASE"
}

function backup2 {
    export BKPREPO=${1} # backup repo (should be: "/bkp/storage-local/$host/$path" or for ssh: "user@server:$path")
    export BKPHOST=${2} # src-host
    export BKPPATH=${3} # abs-path on src-host
    export BKPKEEP=${4} # pruning-settings
    export BORG_PASSPHRASE=${5} # borg key passphrase

    BKPPATH_ESCAPED=$(echo -n "$BKPPATH"|sed -e 's#/#-#g') # contains first "/"

    if [[ -z "$BORG_PASSPHRASE" ]]; then
        borg2 repo-info --repo "$BKPREPO" >/dev/null 2>&1 || borg2 repo-create --umask 0077 -e none --repo "$BKPREPO"
    else
        borg2 repo-info --repo "$BKPREPO" >/dev/null 2>&1 || borg2 repo-create --umask 0077 -e repokey-blake2-chacha20-poly1305 --repo "$BKPREPO"
    fi

    echo "# Merged on: $(date -Isec)" > "/bkp/local/exclude.conf.d/.merged.$BKPHOST-$BKPPATH_ESCAPED"
    for file in /bkp/local/exclude.conf.d/$BKPHOST-$BKPPATH_ESCAPED*; do
        echo -e "\n\n# $file" >> "/bkp/local/exclude.conf.d/.merged.$BKPHOST-$BKPPATH_ESCAPED"
        cat "$file" >> "/bkp/local/exclude.conf.d/.merged.$BKPHOST-$BKPPATH_ESCAPED"
    done

    echo "** backup.sh(backup2:create) ********************************************************************************************************************************"
    borg2 create --umask 0077 --info --list --stats --nobirthtime --compression zstd --exclude-caches --exclude-from "/bkp/local/exclude.conf.d/.merged.$BKPHOST-$BKPPATH_ESCAPED" --repo "$BKPREPO" "$BKPHOST-$BKPPATH_ESCAPED" "$BKPPATH"
        exit_status=$?;
        if [ $exit_status -ne 0 ]; then
            export ERRCODE="$exit_status";
            echo "** backup.sh (backup2:create): non-zero exitcode: $exit_status"
        fi

    backup_prune2 "$BKPREPO" "$BKPKEEP" "$BORG_PASSPHRASE"
}

function backup_cmd {
    export BKPREPO=${1} # backup repo (should be: "/bkp/storage-local/$host/$path" or for ssh: "user@server:$path")
    export BKPNAME=${2} # backup name
    export BKPCMD=${3}  # command to run
    export BKPKEEP=${4} # pruning-settings
    export BORG_PASSPHRASE=${5} # borg key passphrase

    if [[ -z "$BORG_PASSPHRASE" ]]; then
        borg info "$BKPREPO" >/dev/null 2>&1 || borg init --umask 0077 -e none --make-parent-dirs "$BKPREPO"
    else
        borg info "$BKPREPO" >/dev/null 2>&1 || borg init --umask 0077 -e repokey-blake2 --make-parent-dirs "$BKPREPO"
    fi

    borg create --umask 0077 --info --stats --noctime --nobirthtime --compression zstd --files-cache disabled --content-from-command -- "$BKPREPO::$BKPNAME--{now}" $BKPCMD
        exit_status=$?;
        if [ $exit_status -ne 0 ]; then
            export ERRCODE="$exit_status";
            echo "** backup.sh (backup_cmd:create): non-zero exitcode: $exit_status"
        fi

    backup_prune "$BKPREPO" "$BKPKEEP" "$BORG_PASSPHRASE"
}

function backup_cmd2 {
    export BKPREPO=${1} # backup repo (should be: "/bkp/storage-local/$host/$path" or for ssh: "user@server:$path")
    export BKPNAME=${2} # backup name
    export BKPCMD=${3}  # command to run
    export BKPKEEP=${4} # pruning-settings
    export BORG_PASSPHRASE=${5} # borg key passphrase

    if [[ -z "$BORG_PASSPHRASE" ]]; then
        borg2 repo-info --repo "$BKPREPO" >/dev/null 2>&1 || borg2 repo-create --umask 0077 -e none --repo "$BKPREPO"
    else
        borg2 repo-info --repo "$BKPREPO" >/dev/null 2>&1 || borg2 repo-create --umask 0077 -e repokey-blake2-chacha20-poly1305 --repo "$BKPREPO"
    fi

    echo "** backup.sh(backup_cmd2:create) ********************************************************************************************************************************"
    borg2 create --umask 0077 --info --stats --nobirthtime --compression zstd --files-cache disabled --content-from-command --repo "$BKPREPO" "$BKPNAME" -- $BKPCMD
        exit_status=$?;
        if [ $exit_status -ne 0 ]; then
            export ERRCODE="$exit_status";
            echo "** backup.sh (backup_cmd2:create): non-zero exitcode: $exit_status"
        fi

    backup_prune2 "$BKPREPO" "$BKPKEEP" "$BORG_PASSPHRASE"
}

function backup_prune {
    export BKPREPO=${1} # backup repo (should be: "/bkp/storage-local/$host/$path" or for ssh: "user@server:$path")
    export BKPKEEP=${2} # pruning-settings
    export BORG_PASSPHRASE=${3} # borg key passphrase

    if [[ -z "$BKPKEEP" ]]; then
        echo "** backup.sh(backup_prune): No prune settings, skipping"
    else
        borg prune --umask 0077 --list --stats --save-space --keep-last 1 $BKPKEEP "$BKPREPO"
            exit_status=$?;
            if [ $exit_status -ne 0 ]; then
                export ERRCODE="$exit_status";
                echo "** backup.sh (backup_prune:prune): non-zero exitcode: $exit_status"
            fi
       borg compact --umask 0077 -v --cleanup-commits "$BKPREPO"
            exit_status=$?;
            if [ $exit_status -ne 0 ]; then
                export ERRCODE="$exit_status";
                echo "** backup.sh (backup_prune:compact): non-zero exitcode: $exit_status"
            fi
    fi
}

function backup_prune2 {
    export BKPREPO=${1} # backup repo (should be: "/bkp/storage-local/$host/$path" or for ssh: "user@server:$path")
    export BKPKEEP=${2} # pruning-settings
    export BORG_PASSPHRASE=${3} # borg key passphrase

    if [[ -z "$BKPKEEP" ]]; then
        echo "** backup.sh(backup_prune2): No prune settings, skipping"
    else
        echo "** backup.sh(backup_prune2:prune) ********************************************************************************************************************************"
        time borg2 prune --umask 0077 --list --keep-last 1 $BKPKEEP --repo "$BKPREPO"
            exit_status=$?;
            if [ $exit_status -ne 0 ]; then
                export ERRCODE="$exit_status";
                echo "** backup.sh (backup_prune2:prune): non-zero exitcode: $exit_status"
            fi
        echo "** backup.sh(backup_prune2:compact) ********************************************************************************************************************************"
        time borg2 compact --umask 0077 -v --stats --repo "$BKPREPO"
            exit_status=$?;
            if [ $exit_status -ne 0 ]; then
                export ERRCODE="$exit_status";
                echo "** backup.sh (backup_prune2:compact): non-zero exitcode: $exit_status"
            fi
    fi
}

# run managed
echo "** backup.sh: running /bkp/local/backup.conf.managed"
source /bkp/local/backup.conf.managed

# run local additions
if [ -e "/bkp/local/backup.conf.local" ]; then
    echo "** backup.sh: running /bkp/local/backup.conf.local"
    source /bkp/local/backup.conf.local
fi

echo "** backup.sh: DONE"

unset BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK
unset BORG_RELOCATED_REPO_ACCESS_IS_OK

exit $ERRCODE
