#!/bin/bash # Script to create and run rsync command based on JSON configuration : <<'COMMENT' Config File Example (local backup for hs01 ========================================== { "Name" : "hs01", "Host" : "", "BackupHost" : "", "BackupRootDir" : "/backup/hs01", "Filesystems" : ["/etc", "/opt", "/archive", "/data", "/works" ], "RsyncOptions" : ["-arxv", "--delete", "--relative" ], "Exclude" : ["*var/tmp*" , "*var/lib/ntp/proc*" , "*.cache*" , "*root/.mozilla*" , "*var/cache*" , "*var/spool*" , "*/.kde4/*" , "/tmp" ], "DailySnapshots" : false, "PruneBackupDays" : 1 } COMMENT usage() { echo "Usage: ${Script} " exit 1 } # Check if jq is installed if ! command -v jq &>/dev/null; then echo "Error: jq is required for JSON processing. Install it and try again." exit 1 fi # Verify configuration verify_config() { local config_file="$1" # Check if required directories and files exist local backup_root_dir backup_root_dir=$(jq -r '.BackupRootDir' "$config_file") if [[ ! -d "$backup_root_dir" ]]; then echo "----- Error: BackupRootDir ($backup_root_dir) does not exist." mkdir -p "${backup_root_dir}" fi } # Run rsync run_rsync() { local cmdlist=("$@") echo "----- Running rsync: ${cmdlist[*]}" "${cmdlist[@]}" } # Prune old backups prune_backup_dirs() { local bkp_host="$1" local root_dir="$2" local days="$3" echo "----- Looking for files to prune..." local cmd="cd $root_dir && ls -rd 2* | awk -v days=$days '{ if (NR > days) print }'" [[ -n "$bkp_host" ]] && cmd="ssh $bkp_host \"$cmd\"" echo "----- Command: $cmd" local files files=$(eval "$cmd") if [[ -n "$files" ]]; then echo "----- Found files to prune:" echo "$files" local prune_cmd="rm -rf $(echo "$files" | xargs -I {} echo "$root_dir/{}")" [[ -n "$bkp_host" ]] && prune_cmd="ssh $bkp_host \"$prune_cmd\"" echo "----- Executing: $prune_cmd" eval "$prune_cmd" else echo "----- Nothing to prune." fi } # Generate rsync arguments get_rsync_arguments() { local config_file="$1" local dt="$2" local fs="$3" local bkp_root_dir bkp_root_dir=$(jq -r '.BackupRootDir' "$config_file") local daily_snapshots daily_snapshots=$(jq -r '.DailySnapshots' "$config_file") local rsync_options rsync_options=$(jq -r '.RsyncOptions[]' "$config_file") local exclude_list exclude_list=$(jq -r '.Exclude[]' "$config_file") local bkp_dir="$bkp_root_dir" [[ "$daily_snapshots" == "true" ]] && bkp_dir="$bkp_root_dir/$dt" local cmdlist=("rsync" $rsync_options) for excl in $exclude_list; do cmdlist+=("--exclude=$excl") done [[ "$daily_snapshots" == "true" ]] && cmdlist+=("--link-dest=$bkp_root_dir/current") local src_host src_host=$(jq -r '.Host' "$config_file") [[ -n "$src_host" ]] && src_host="$src_host:" local tgt_host tgt_host=$(jq -r '.BackupHost' "$config_file") [[ -n "$tgt_host" ]] && tgt_host="$tgt_host:" cmdlist+=("${src_host}${fs}" "${tgt_host}${bkp_dir}/") echo "${cmdlist[@]}" } # Main function main() { local config_file="$1" if [[ ! -f "$config_file" ]]; then echo "----- Error: Configuration file $config_file does not exist." exit 1 fi if ! verify_config "$config_file"; then exit 1 fi local dt dt=$(date +%Y%m%d) local filesystems filesystems=$(jq -r '.Filesystems[]' "$config_file") for fs in $filesystems; do echo "----- Processing filesystem: $fs" local cmdlist cmdlist=($(get_rsync_arguments "$config_file" "$dt" "$fs")) run_rsync "${cmdlist[@]}" done local daily_snapshots daily_snapshots=$(jq -r '.DailySnapshots' "$config_file") if [[ "$daily_snapshots" == "true" ]]; then local bkp_root_dir bkp_root_dir=$(jq -r '.BackupRootDir' "$config_file") local bkp_host bkp_host=$(jq -r '.BackupHost' "$config_file") local cmd="ln -snf $bkp_root_dir/$dt $bkp_root_dir/current" [[ -n "$bkp_host" ]] && cmd="ssh $bkp_host \"$cmd\"" echo "----- Switching current symlink: $cmd" eval "$cmd" local prune_days prune_days=$(jq -r '.PruneBackupDays' "$config_file") if [[ "$prune_days" -gt 0 ]]; then local bkp_root_dir bkp_root_dir=$(jq -r '.BackupRootDir' "$config_file") local bkp_host bkp_host=$(jq -r '.BackupHost' "$config_file") prune_backup_dirs "$bkp_host" "$bkp_root_dir" "$prune_days" fi fi } # Entry point Script=${0} Config=${1} if [[ $# -lt 1 ]]; then usage exit 1 fi main "${Config}"