Browse Source
new: [rsync-backup] new state files and check capability for ``mirror-dir``
new: [rsync-backup] new state files and check capability for ``mirror-dir``
Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>backup
Valentin Lab
4 years ago
2 changed files with 229 additions and 8 deletions
@ -0,0 +1,194 @@ |
|||
#!/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 <<EOF | mail -s "[$(hostname)] mirror backup failing" "${MAIL_DESTS[@]}" |
|||
Hi, |
|||
|
|||
Some configured mirroring targets have not finished gracefully in |
|||
the last $time_spec. Please see for yourself: |
|||
|
|||
$( |
|||
for m in "${msg[@]}"; do |
|||
echo " $m" |
|||
done |
|||
) |
|||
|
|||
You might want to find these following information of some use: |
|||
|
|||
$( |
|||
|
|||
for m in "${bad_sessions[@]}"; do |
|||
if [ -e "${state_dir}"/$m-fail ]; then |
|||
echo " ${sessions[$m]}:" |
|||
tail -n 5 "${state_dir}"/$m-fail | cut -f 1,2,5- -d " " | sed -r "s/^/ /g" |
|||
echo |
|||
else |
|||
echo " ${sessions[$m]}: no fail log available" |
|||
fi |
|||
done |
|||
|
|||
) |
|||
|
|||
Hoping all this will help you sort out the issue... |
|||
|
|||
Yours sincerly, |
|||
-- |
|||
mirror-dir-check |
|||
|
|||
PS: You received this email because your email is listed in |
|||
\$MAIL_DESTS of '$CHECK_DEFAULT_SOURCE' of '$(hostname)' |
|||
(also known as $(cat /etc/mailname)). |
|||
|
|||
EOF |
|||
|
|||
fi |
Reference in new issue
xxxxxxxxxx