#!/usr/bin/env bash if [ $# -ne 1 ] then echo "USAGE: $0 " exit 1 fi TANK="$1" IS_TANK_EXIST=$(zfs list | grep -c "tank/${TANK} ") if [ "${IS_TANK_EXIST}" -ne 1 ] then echo "${TANK} n'existe pas. Arrêt." exit 1 fi TODAY=$(date "+%Y-%m-%d") TODAY_EPOCH=$(date -d "${TODAY}" +%s) # # 1. On fait les snapshots sur le ZFS du NAS. /sbin/zfs snapshot "tank/${TANK}@${TODAY}" # 2. On envoie les snapshots sur le ZFS de backup. while true do # Au préalable, on regarde si un envoi a été interrompu. TOKEN=$(ssh perceval.adm.auro.re zfs list -o receive_resume_token "tank/${TANK}_backup" | tail -n 1) if [ "${#TOKEN}" -gt 15 ] then echo "Un envoi a été interrompu. Reprise." zfs send -t "${TOKEN}" | pv -trb | ssh perceval.adm.auro.re zfs recv -s -u "tank/${TANK}_backup" if [ $? -ne 0 ] then echo "La reprise s'est mal déroulée. Arrêt." exit 1 fi fi # On récupère les dernières snapshots envoyées sur backup. LAST_SNAPSHOT=$(ssh perceval.adm.auro.re zfs list -t snapshot \ | grep "tank/${TANK}_backup" \ | cut -d' ' -f1 | cut -d'@' -f2 \ | sort | tail -n1) LAST_SNAPSHOT_EPOCH=$(date -d "${LAST_SNAPSHOT}" "+%s") # Si la dernière backup envoyée est celle d'aujourd'hui: On sort. if [ "${LAST_SNAPSHOT_EPOCH}" -ge "${TODAY_EPOCH}" ] then echo "La backup distance ${TANK} ${LAST_SNAPSHOT} est suffisament récente. Fin." break fi # Sinon, on envoie une backup supplémentaire à partir de la dernière snapshot. NEW_SNAPSHOT=$(date -d "${LAST_SNAPSHOT} +1day" "+%Y-%m-%d") echo "Envoi de la backup ${TANK} ${NEW_SNAPSHOT}." zfs send -i "tank/${TANK}@${LAST_SNAPSHOT}" "tank/${TANK}@${NEW_SNAPSHOT}" \ | pv -trb | ssh perceval.adm.auro.re zfs recv -s -u "tank/${TANK}_backup" if [ $? -ne 0 ] then echo "L'envoi s'est mal déroulé. Arrêt." exit 1 fi done # 3. On ne garde que les 15 dernières snapshots ZFS LIMIT=$(date -d "${TODAY} -15days" "+%Y-%m-%d") LIMIT_EPOCH=$(date -d "${LIMIT}" "+%s") while true do # On vérifie qu'il existe au moins 15 backups COUNT=$(zfs list -t snapshot \ | grep -c "tank/${TANK}") if [ "${COUNT}" -le 15 ] then echo "Il y a moins de 16 backups. Fin." break fi # On récupère la plus vieille snapshot OLDEST_SNAPSHOT=$(zfs list -t snapshot \ | grep "tank/${TANK}" \ | cut -d' ' -f1 | cut -d'@' -f2 \ | sort | head -n1) OLDEST_SNAPSHOT_EPOCH=$(date -d "${OLDEST_SNAPSHOT}" "+%s") # Sanity-check: Si la plus vieille backup est celle d'il y a moins de 15 jours: On sort. if [ "${OLDEST_SNAPSHOT_EPOCH}" -ge "${LIMIT_EPOCH}" ] then echo "La backup locale ${TANK} ${OLDEST_SNAPSHOT} est suffisament récente. Fin." break fi # Sinon, on supprime la plus vieille snapshot. echo "Suppression de la backup ${TANK} ${OLDEST_SNAPSHOT}." zfs destroy "tank/${TANK}@${OLDEST_SNAPSHOT}" if [ $? -ne 0 ] then echo "La suppression s'est mal déroulée. Arrêt." exit 1 fi done