#!/bin/bash #============================================================================ #title : TUBS #description : The Ultimate Backup Script (Linux) Version 2 #author : Janic Voser Xelon #date : 2022-04-08 #updated : 2022-04-09 #version : 2.0 #usage : chmod +x tubs.sh && ./tubs.sh #notes : #bash_version : #============================================================================ # Config ## Configfile #CONFIG_FILE=/etc/tubs/config # Any Config File CONFIG_FILE="$PWD/tubs.config" # Functions ## Colorful Information function blue(){ # The blue color is used for inforation echo -e '\e[34m'"$1"'\e[0m' } function cyan(){ # The cyan color is only used for help echo -e '\e[0;36m'"$1"'\e[0m' } function green(){ # The green color is used for successful steps echo -e '\e[32m'"$1"'\e[0m' } function magenta(){ # The magenta color is used for warnings & important Information echo -e '\e[35m'"$1"'\e[0m' } function red(){ # The red color is used for failed steps echo -e '\e[31m'"$1"'\e[0m' && exit 1 } ## Critical Error function critical_error { red "Critical error during: $1" } ## Load Config function load_config { if [ -e "$CONFIG_FILE" ] then blue "Loading Config" source "$CONFIG_FILE" || critical_error "Reading Configfile" else red "Configfile not Found" fi } ## Create destination Structure function create_dst { mkdir -p "$BACKUP_DST_FULL" || critical_error "Creating Directory BACKUP_DST_FULL" mkdir -p "$BACKUP_DST_INC" || critical_error "Creating Directory BACKUP_DST_INC" } ## Check destination function check_dst { if [ -e "$BACKUP_DST" ] then blue "Backup destinantion existing" else red "Backup destination not existing" fi mkdir -p "$BACKUP_DST_INC_PATH" || critical_error "Error while creating incremental backup-directory ($BACKUP_DST_INC_PATH)" mkdir -p "$BACKUP_DST_FULL_LOGS" || critical_error "Error while creating log directory ($BACKUP_DST_FULL_LOGS)" } ## Check sources function check_src { for src_dir in "${BACKUP_SRC_ARRAY[@]}" do if [[ "$src_dir" =~ ^*[/] ]] then critical_error "$src_dir is ending with slash please remove it" fi if ! [ -d "$src_dir" ] then critical_error "$src_dir is not a directory" fi green "Source $src_dir is valid" done } ## Check Incremental Date function check_inc { if ! [ -e "$BACKUP_LAST_FILE" ] then magenta "Missing last successfull backup file, just using the day before" LAST_BACKUP="$(date --date="yesterday" "$DATE_FORMAT")" else LAST_BACKUP="$(cat "$BACKUP_LAST_FILE")" if ! [[ $LAST_BACKUP =~ ^[0-9]{4}(-[0-9]{2}){2}_[0-9]{2}-[0-9]{2} ]] then magenta "Content of last successfull backup file was not valid" LAST_BACKUP="$(date --date="yesterday" "$DATE_FORMAT")" fi fi BACKUP_DST_INC_PATH="$BACKUP_DST_INC/$BACKUP_PREFIX$LAST_BACKUP" } ## Check Prerequirements function check_prereq { command -v rsync &> /dev/null || critical_error "Missing rsync" green "All requirements are saturated" } ## Last successful backup function last_backup { if touch "$BACKUP_LAST_FILE" &> /dev/null then echo "$BACKUP_DATE" > "$BACKUP_LAST_FILE" else critical_error "Can not write Last successful backup file" fi } ## Backup all function backup_all { blue "Starting Backup Processes" for src_dir in "${BACKUP_SRC_ARRAY[@]}" do src_dir_name="$(echo "$src_dir" | rev | cut -d / -f 1 | rev)" cat << EOF >> "$BACKUP_DST_FULL_LOGS/$src_dir_name.log" ################################################################################ #############################TUBS $BACKUP_DATE############################## ################################################################################ EOF rsync "$RSYNC_ARGS" --backup --delete --backup-dir="$BACKUP_DST_INC_PATH/" "$src_dir" "$BACKUP_DST_FULL/$src_dir_name" >> "$BACKUP_DST_FULL_LOGS/$src_dir_name.log" & done green "All backup processes started successfull" blue "Waiting for processes to finish" # wait for all pids jobs=$(jobs -p) for process in $jobs do wait "$process" || critical_error "Process: $process failed" done green "All Processes finished" } ## Pre Backup Script function pre_backup_script { if [ -e "$PRE_BACKUP_SCRIPT" ] then if [ -x "$PRE_BACKUP_SCRIPT" ] then blue "Executing Pre-Backup-Script" $PRE_BACKUP_SCRIPT green "Pre-Backup-Script finished" else magenta "Pre-Backup-Script is not executable" fi else blue "No Pre-Backup-Script found" fi } ## Post Backup Script function post_backup_script { if [ -e "$POST_BACKUP_SCRIPT" ] then if [ -x "$POST_BACKUP_SCRIPT" ] then blue "Executing Post-Backup-Script" $POST_BACKUP_SCRIPT green "Post-Backup-Script finished" else magenta "Post-Backup-Script is not executable" fi else blue "No Pre-Backup-Script found" fi } ## Generate Variables load_config # Load config first (Variables are dependent on it) BACKUP_DATE="$(date "$DATE_FORMAT")" BACKUP_DST_FULL="$BACKUP_DST/FULL" BACKUP_DST_FULL_LOGS="$BACKUP_DST_FULL/logs" BACKUP_DST_INC="$BACKUP_DST/INCREMENTAL" BACKUP_LAST_FILE="$BACKUP_DST/LAST_SUCCESSFULL_BACKUP" # Main Script ## Load config if [ -n "$1" ] then case "$1" in help) cyan "Execute this script with one of the following arguments" cyan " - help --> Display help (your reading it right now)" cyan " - init --> Initialize the backup Structure" cyan " - backup --> Do the accual backup" cyan " - restore --> Restore all the data from a certain day" ;; init) blue "Starting initialisation" create_dst blue "Initialisation was successfull" ;; backup) green "TUBS started" check_inc check_dst check_src check_prereq last_backup pre_backup_script backup_all post_backup_script green "TUBS finished" ;; restore) magenta "I am kinda sorry this is not implemented yet" exit ;; *) red "Your supplied argument was not valid use help if you don't know what you are doing" ;; esac exit else cyan "Please supply a valid argument or execute with help flag" fi