#!/bin/bash #:- . /etc/shlib #:- include common include parse include process depends shyaml lock [ "$UID" != "0" ] && echo "You must be root." && exit 1 CHECK_DEFAULT_SOURCE=/etc/default/alerting [ -f "$CHECK_DEFAULT_SOURCE" ] && . "$CHECK_DEFAULT_SOURCE" if [ "${#MAIL_DESTS[@]}" == 0 ]; then echo "You must set at least one recipient destination for mails." >&2 echo " You can do that in '$CHECK_DEFAULT_SOURCE', using the variable" >&2 echo " '\$MAIL_DESTS'. Note this is a bash array variable." >&2 exit 1 fi usage="usage: $exname -d DEST1 [-d DEST2 [...]] [DIR1 [DIR2 ...]] Checks that mirror-dir did it's job. Will send an email if not. Options: DIR1 ... DIRn Local directories that should be mirrored on destination(s). examples: /etc /home /var/backups If no directories are provided, the config file root entries will be used all as destination to copy. -d DESTn Can be repeated. Specifies host destination towards which files will be send. Note that you can specify port number after a colon and a bandwidth limit for rsync after a '/'. examples: -d liszt.musicalta:10022 -d 10.8.0.19/200 -n TIME_SPEC Give a full english time spec about how old the last full run of rsync should be at most. Defaults to '12 hours'. examples: -n '12 hours' " dests=() source_dirs=() time_spec='12 hours' while [ "$#" != 0 ]; do case "$1" in "-d") dests+=("$2") shift ;; "-n") time_spec="$2" shift ;; *) source_dirs+=("$1") ;; esac shift done config_file="/etc/mirror-dir/config.yml" if [ "${#source_dirs[@]}" == 0 ]; then if [ -e "$config_file" ]; then source_dirs=($(eval echo $(shyaml get-values default.sources < "$config_file"))) fi >&2 if [ "${#source_dirs[@]}" == 0 ]; then err "You must specify at least one source directory to mirror" \ "on command line (or in a config file)." print_usage exit 1 fi fi if [ "${#dests[@]}" == 0 ]; then err "You must specify at least a destination." print_usage exit 1 fi state_dir=/var/run/mirror-dir get_ids() { local session_id id_done declare -A id_done for file in "$state_dir"/*{-fail,-success}; do session_id=${file%-*} [ "${id_done["$session_id"]}" ] && continue id_done["$session_id"]=1 echo "${session_id##*/}" done } dir_max_len=0 for d in "${source_dirs[@]}"; do [ "$dir_max_len" -lt "${#d}" ] && dir_max_len="${#d}" done declare -A sessions=() bad_sessions=() for dest in "${dests[@]}"; do if [[ "$dest" == *"/"* ]]; then current_rsync_options+=("--bwlimit" "${dest##*/}") dest="${dest%/*}" fi msg=() for d in "${source_dirs[@]}"; do session_id="$(echo "$dest$d" | md5_compat)" session_id="${session_id:1:8}" sessions["$session_id"]="$dest $d" f=$(find "$state_dir" \ -maxdepth 1 -newermt "-$time_spec" \ -type f -name "${session_id}-success") if [ -z "$f" ]; then if [ -e "$state_dir/${session_id}-success" ]; then msg+=("$(printf "%s %-${dir_max_len}s last full sync %s" \ "$dest" \ "$d" \ "$(stat -c %y "$state_dir/${session_id}-success" | sed -r 's/\.[0-9]{9,9} / /g')")") else msg+=("$(printf "%s %-${dir_max_len}s never finished yet" \ "$dest" \ "$d")") fi bad_sessions+=("$session_id") fi done done if [ "${#msg[@]}" != 0 ]; then cat <