#!/bin/bash env_dir=$1 base_dir="$(dirname "$(realpath -s "$0")")" root_dir="$base_dir/../../.." [[ -z $env_dir ]] && env_dir="/etc/zio/backup" function restic_exec() { command="$1" args="${@:2}" if [[ -z $command ]]; then say_warn "No command specified. Not running." else restic \ --password-file "$passwd_file" \ --repo "$repo" \ $command $args fi } function backup() { path="$1" args="${@:2}" if [[ ! -d $path ]]; then warn "'$path' does not exist. Not backing up." else for exclude in "${excludes[@]}" do args+=" --iexclude \"$exclude\"" done restic_exec \ backup \ --iexclude "__MACOSX" \ --iexclude ".cache" \ --iexclude ".DS_Store" \ --iexclude "cache" \ --iexclude "CachedData" \ --iexclude "CachedExtensionVSIXs" \ --iexclude "Code Cache" \ --iexclude "GPUCache" \ --iexclude "GrSharedCache" \ --iexclude "ShaderCache" \ --iexclude "system-cache" \ --iexclude "thumbs.db" \ --iexclude "tmp" \ --exclude "containers/storage/overlay" \ --exclude "containers/storage/overlay-containers" \ --exclude "containers/storage/overlay-images" \ --exclude "containers/storage/overlay-layers" \ --exclude-if-present ".nobackup" \ --host "$host" \ $args "$path" fi } function forget() { path="$1" restic_exec \ forget \ --host "$host" \ --keep-last 5 \ --path "$path" } function get_prop() { file=$1 item=$2 echo $(grep -oP '(?<=^'"$item"'=).+' $file | tr -d '"') } function say() { message=$@ echo -e "$@" } function say_die() { message=$@ say "\033[1;31mError: $message\033[0m" exit 255 } function say_do() { message=$@ say "\033[1;34m$message\033[0m" } function say_warn() { message=$@ say "\033[1;33mWarning: $message\033[0m" } function test_path() { prog=$@ if [[ ! -x "$(command -v $prog)" ]]; then say_die "'$prog' is not installed (or not in \$PATH). Aborting..." fi } host="$(hostname -s)" repo="b2:zio-euc-servers:/" passwd_file="$env_dir/passwd" pre_script_file="$env_dir/pre-script" post_script_file="$env_dir/post-script" b2_account_id="" b2_account_key="" excludes=() paths=() services=() if [[ $UID != 0 ]]; then say_die "Unauthorized (are you root?)" fi if [[ ! -d $env_dir ]]; then say_die "Config directory ($env_dir) not found." else chown root:root -R $env_dir chmod 660 -R $env_dir [[ -f "$env_dir/script-pre" ]] && pre_script="$env_dir/script-pre" [[ -f "$env_dir/script-post" ]] && post_script="$env_dir/script-post" if [[ -f "$env_dir/config" ]]; then [[ ! -z $(get_prop "$env_dir/config" B2_ACCOUNT_ID) ]] && \ b2_account_id="$(get_prop "$env_dir/config" B2_ACCOUNT_ID)" [[ ! -z $(get_prop "$env_dir/config" B2_ACCOUNT_KEY) ]] && \ b2_account_key="$(get_prop "$env_dir/config" B2_ACCOUNT_KEY)" [[ ! -z $(get_prop "$env_dir/config" EXCLUDES) ]] && \ IFS=';' read -ra excludes <<< "$(get_prop "$env_dir/config" EXCLUDES)" [[ ! -z $(get_prop "$env_dir/config" PATHS) ]] && \ IFS=';' read -ra paths <<< "$(get_prop "$env_dir/config" PATHS)" [[ ! -z $(get_prop "$env_dir/config" SERVICES) ]] && \ IFS=';' read -ra services <<< "$(get_prop "$env_dir/config" SERVICES)" fi if [[ ! -f "$env_dir/passwd" ]]; then say_die "Password file ($passwd_file) not found." fi fi [[ -z $paths ]] && say_die "No paths specified. Aborting..." if [[ -z $b2_account_id ]]; then say_die "B2_ACCOUNT_ID (in $env_dir/config) not set. Aborting..." else export B2_ACCOUNT_ID="$b2_account_id" fi if [[ -z $b2_account_key ]]; then say_die "B2_ACCOUNT_KEY (in $env_dir/config) not set. Aborting..." else export B2_ACCOUNT_KEY="$b2_account_key" fi if [[ -f $pre_script_file ]]; then say_do "Executing pre-backup script..." . $pre_script_file fi say_do "Stopping services..." for service in "${services[@]}" do systemctl stop $service done say_do "Backing up files..." for path in "${paths[@]}" do backup $path done say_do "Starting services..." for service in "${services[@]}" do systemctl start $service done if [[ -f $post_script_file ]]; then say_do "Executing post-backup script..." . $post_script_file fi say_do "Removing old backups..." for path in "${paths[@]}" do forget $path done