Добавить script/getlast.sh
This commit is contained in:
@@ -0,0 +1,122 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# zrepl_last_snapshot_age.sh
|
||||||
|
#
|
||||||
|
# Показывает, сколько минут назад был создан последний снапшот
|
||||||
|
# (по умолчанию с префиксом "zrepl_") на резервной (приёмной) стороне.
|
||||||
|
#
|
||||||
|
# Использование:
|
||||||
|
# ./zrepl_last_snapshot_age.sh <датасет> [<датасет2> ...]
|
||||||
|
# ./zrepl_last_snapshot_age.sh -r <датасет> # рекурсивно по всем дочерним
|
||||||
|
# ./zrepl_last_snapshot_age.sh -p zrepl_ -r chunk_9XG1J8T0/nomad
|
||||||
|
#
|
||||||
|
# Опции:
|
||||||
|
# -r рекурсивно проверять все дочерние датасеты
|
||||||
|
# -p PREFIX фильтровать снапшоты по префиксу имени (по умолчанию "zrepl_")
|
||||||
|
# -w MINUTES задать порог в минутах: если снапшот старше — exit code 1
|
||||||
|
# (удобно для мониторинга / cron)
|
||||||
|
# -q тихий режим: не печатать построчный вывод, только итог
|
||||||
|
#
|
||||||
|
# Коды возврата:
|
||||||
|
# 0 — всё ок (снапшот найден, и если задан -w, он не старше порога)
|
||||||
|
# 1 — снапшот найден, но старше порога -w
|
||||||
|
# 2 — снапшот не найден вообще (для датасета/выборки)
|
||||||
|
# 3 — ошибка использования / zfs недоступен
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PREFIX="zrepl_"
|
||||||
|
RECURSIVE=0
|
||||||
|
WARN_MINUTES=""
|
||||||
|
QUIET=0
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
grep '^#' "$0" | sed -e '1d' -e 's/^# \{0,1\}//'
|
||||||
|
exit 3
|
||||||
|
}
|
||||||
|
|
||||||
|
while getopts ":rp:w:qh" opt; do
|
||||||
|
case "$opt" in
|
||||||
|
r) RECURSIVE=1 ;;
|
||||||
|
p) PREFIX="$OPTARG" ;;
|
||||||
|
w) WARN_MINUTES="$OPTARG" ;;
|
||||||
|
q) QUIET=1 ;;
|
||||||
|
h) usage ;;
|
||||||
|
*) usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
if [[ $# -lt 1 ]]; then
|
||||||
|
echo "Ошибка: укажите хотя бы один датасет." >&2
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v zfs >/dev/null 2>&1; then
|
||||||
|
echo "Ошибка: команда zfs не найдена." >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
now_epoch=$(date +%s)
|
||||||
|
|
||||||
|
overall_newest_epoch=0
|
||||||
|
overall_newest_name=""
|
||||||
|
any_found=0
|
||||||
|
|
||||||
|
for dataset in "$@"; do
|
||||||
|
zfs_opts=(-H -p -o name,creation -t snapshot -s creation)
|
||||||
|
if [[ $RECURSIVE -eq 1 ]]; then
|
||||||
|
zfs_opts+=(-r)
|
||||||
|
else
|
||||||
|
zfs_opts+=(-d 1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -H без заголовков, -p значения в "машинном" виде (creation -> epoch seconds)
|
||||||
|
mapfile -t lines < <(zfs list "${zfs_opts[@]}" "$dataset" 2>/dev/null | grep "@${PREFIX}" || true)
|
||||||
|
|
||||||
|
if [[ ${#lines[@]} -eq 0 ]]; then
|
||||||
|
if [[ $QUIET -eq 0 ]]; then
|
||||||
|
echo "[$dataset] снапшотов с префиксом '${PREFIX}' не найдено"
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# последняя строка — самый свежий снапшот (сортировка -s creation)
|
||||||
|
last_line="${lines[-1]}"
|
||||||
|
snap_name="${last_line%%$'\t'*}"
|
||||||
|
snap_epoch="${last_line##*$'\t'}"
|
||||||
|
|
||||||
|
age_seconds=$(( now_epoch - snap_epoch ))
|
||||||
|
age_minutes=$(( age_seconds / 60 ))
|
||||||
|
|
||||||
|
any_found=1
|
||||||
|
if (( snap_epoch > overall_newest_epoch )); then
|
||||||
|
overall_newest_epoch=$snap_epoch
|
||||||
|
overall_newest_name=$snap_name
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $QUIET -eq 0 ]]; then
|
||||||
|
printf "[%s] последний снапшот: %s (%d мин. назад)\n" \
|
||||||
|
"$dataset" "$snap_name" "$age_minutes"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $any_found -eq 0 ]]; then
|
||||||
|
echo "Ни одного снапшота с префиксом '${PREFIX}' не найдено ни в одном из указанных датасетов." >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
overall_age_minutes=$(( (now_epoch - overall_newest_epoch) / 60 ))
|
||||||
|
|
||||||
|
echo "---"
|
||||||
|
printf "Самый свежий снапшот в выборке: %s (%d мин. назад)\n" \
|
||||||
|
"$overall_newest_name" "$overall_age_minutes"
|
||||||
|
|
||||||
|
if [[ -n "$WARN_MINUTES" ]]; then
|
||||||
|
if (( overall_age_minutes > WARN_MINUTES )); then
|
||||||
|
echo "ВНИМАНИЕ: последний снапшот старше порога ${WARN_MINUTES} мин." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user