X-Git-Url: https://git.llucax.com/software/bacap.git/blobdiff_plain/809d2328e236c71816c9e29c4295476f8a8126d4..caa02f4c59c79184cef7d682a1f4bd4b7b542a1e:/bacap diff --git a/bacap b/bacap index fb6cc5e..976ee08 100755 --- a/bacap +++ b/bacap @@ -12,6 +12,9 @@ DEBUG=0 # Don't actually do anything, just print the commands DRY_RUN=0 +# Force synchronization, even when the target already exist +FORCE_SYNC=0 + # Log file (if empty, print to stdout/err) LOG_FILE= @@ -19,7 +22,7 @@ LOG_FILE= CONFIG_PATH=/etc/bacap/hosts # Name of the local host (so no ssh would be used with this host) -LOCALHOST=localhost +LOCALHOST=$HOSTNAME # Where to put the backups BACKUP_PATH=/backup @@ -27,24 +30,32 @@ BACKUP_PATH=/backup # Date format used for backed up directories (passed to the date command) DATE_FMT="%Y-%m-%d" +# Ping remote hosts to check if they are up (set to 0 if your hosts don't +# reply to ICMP pings). +PING_CHECK=1 + # rsync flags to use -RSYNC_FLAGS="-aAXHx --numeric-ids --delete" +RSYNC_FLAGS="-aAHSXx --numeric-ids" # rsync flags to use when in verbose mode RSYNC_VERBOSE_FLAGS="-v --stats" # rsync remote shell to use -RSYNC_RSH="ssh -c arcfour -o Compression=no -x" +RSYNC_RSH="ssh" #_INCLUDE_END_ +SCRIPT_DIR=$(dirname `readlink -f $0`) +BACAPRC=$1 # Load configuration files -source "/etc/bacaprc" 2> /dev/null -source "/etc/bacap/bacaprc" 2> /dev/null -source `dirname \`readlink -f "$0"\``/bacaprc 2> /dev/null -test -n "$1" && source "$1" - +load_config() { + source "/etc/bacaprc" 2> /dev/null + source "/etc/bacap/bacaprc" 2> /dev/null + source "$SCRIPT_DIR/bacaprc" 2> /dev/null + test -n "$BACAPRC" && source "$BACAPRC" +} +load_config export RSYNC_RSH @@ -55,8 +66,8 @@ run= RSYNC_FLAGS="$RSYNC_FLAGS $RSYNC_VERBOSE_FLAGS" [ $DEBUG -eq 1 ] && V=-v +exec 3>&2 [ -n "$LOG_FILE" ] && - exec 3>&2 && exec 1>>"$LOG_FILE" && exec 2>>"$LOG_FILE" @@ -73,7 +84,7 @@ perror() { echo "$@" >&2 } -host_up() { +ping_host() { ping -c1 "$1" > /dev/null 2>&1 } @@ -86,42 +97,70 @@ plog "=========================================================================" ret=0 for host_path in "$CONFIG_PATH"/* do + saved_ret=$ret + # Load default config and override config if correspond + load_config + source "$host_path/bacaprc" 2>/dev/null host=`basename "$host_path"` host_backup_path="$BACKUP_PATH/$host" + mkdir -p $host_backup_path dst="$BACKUP_PATH/$host/$date" src=`cat "$host_path/paths"` [ "$host" != "$LOCALHOST" ] && src=`awk "{print \"$host:\"\\$1}" "$host_path/paths"` exclude="$host_path/excludes" + include="$host_path/includes" current_link="$host_backup_path/current" current_dir="$host_backup_path/`readlink \"$current_link\"`" - exclude_flags= + extra_flags= plog "-----------------------------------------------------------------" - plog "Backup for host $host" + plog "Backup for host $host started at `date '+%Y-%m-%d %H:%M:%S'`" plog "-----------------------------------------------------------------" - plog "Source: "$src + plog "Source: $src" plog "Destination: $dst" plog "Last: $current_dir" plog - [ -d "$dst" ] && + [ -d "$dst" ] && [ "$FORCE_SYNC" -ne 1 ] && perror "$dst already exists, skipping..." && continue - ! host_up $host && + [ "$PING_CHECK" -eq 1 ] && ! ping_host $host && perror "$host is down, skipping..." && continue [ -r "$exclude" ] && - exclude_flags=" --exclude-from=$exclude --delete-excluded" - plog "Rotating backup..." - $run cp -al $V "$current_dir" "$dst" || - ret=$(($ret+1)) + extra_flags="--exclude-from=$exclude" + [ -r "$include" ] && + extra_flags="$extra_flags --include-from=$include" plog "Running rsync..." - $run rsync $RSYNC_FLAGS $exclude_flags $src "$dst/" || - ret=$(($ret+1)) - plog "Moving current..." - $run rm $V "$current_link" || + $run rsync $RSYNC_FLAGS $extra_flags \ + --link-dest="$current_dir" $src "$dst/" + rsync_ret=$? + case $rsync_ret in + 0) + # Normal return + ;; + 24) + # Ignore error 24 from rsync ("Partial transfer due to + # vanished source files") which is somewhat expected + # since we don't do a snapshot + ;; + *) + # Any other error is important enough + ret=$(($ret+1)) + ;; + esac + + if [ $ret -eq $saved_ret ] + then + # Only move current if rsync did not fail, to avoid dangling + # symlinks + plog "Moving current..." + $run rm -f $V "$current_link" || ret=$(($ret+1)) - $run ln -s $V "$date" "$current_link" || + $run ln -s $V "$date" "$current_link" || ret=$(($ret+1)) + else + ERROR_HOSTS="$ERROR_HOSTS $host" + fi done plog "=========================================================================" @@ -130,10 +169,14 @@ plog "=========================================================================" if [ $ret -ne 0 ] then - pout 'There were some errors when running the backup.' pout - pout "Please take a look at the log: $LOG_FILE" + pout "There were some errors when running the backup on: $ERROR_HOSTS" pout + if [ -n "$LOG_FILE" ] + then + pout "Please take a look at the log: $LOG_FILE" + pout + fi fi exit $ret