72 lines
3.2 KiB
Text
72 lines
3.2 KiB
Text
|
|
#jinja2: comment_start_string:'{=#', comment_end_string:'#=}'
|
||
|
|
#!/bin/bash
|
||
|
|
# (Le gabarit redefinit le delimiteur de commentaire Jinja : `${#tableau[@]}` contient
|
||
|
|
# la sequence `{#`, que Jinja lirait comme un debut de commentaire. Le shell en a
|
||
|
|
# besoin ; c'est donc Jinja qui cede. Meme geste que `client_sante/setops-sante.sh.j2`
|
||
|
|
# et `serveur_nginx/sonde-edge.sh.j2`.)
|
||
|
|
# GENERE par Set-OPS (role serveur_backup_site). Ne pas editer a la main.
|
||
|
|
#
|
||
|
|
# SONDE « depot-locataires » — les depots sont-ils etanches, et reste-t-il de la place ?
|
||
|
|
#
|
||
|
|
# PAS UNE ENVELOPPE DE GREFFON. `check_disk` saurait la moitie du travail — la place —
|
||
|
|
# mais pas l'autre, qui est la seule proprement Set-OPS : « chaque locataire est-il
|
||
|
|
# toujours seul chez lui ». On garde les deux dans une sonde parce qu'elles appellent le
|
||
|
|
# MEME geste : aller voir le depot du site.
|
||
|
|
set -uo pipefail
|
||
|
|
|
||
|
|
PARENT={{ serveur_backup_site_parent }}
|
||
|
|
PLANCHER={{ serveur_backup_site_espace_minimal_go }}
|
||
|
|
comptes=({% for l in serveur_backup_site_locataires | default([]) %}'{{ l.compte }}' {% endfor %})
|
||
|
|
noms=({% for l in serveur_backup_site_locataires | default([]) %}'{{ l.nom }}' {% endfor %})
|
||
|
|
|
||
|
|
# 1. L'ETANCHEITE, LOCATAIRE PAR LOCATAIRE.
|
||
|
|
#
|
||
|
|
# ON RELIT CE QUE LE NOYAU APPLIQUE, pas ce qu'on croit avoir pose — `stat` sur le
|
||
|
|
# repertoire reel. C'est la meme lecture que l'assertion du deploiement, rejouee quand
|
||
|
|
# plus personne ne regarde.
|
||
|
|
fautifs=()
|
||
|
|
for i in "${!comptes[@]}"; do
|
||
|
|
compte=${comptes[$i]}
|
||
|
|
nom=${noms[$i]}
|
||
|
|
chemin="${PARENT}/${compte}"
|
||
|
|
|
||
|
|
if [[ ! -d "${chemin}" ]]; then
|
||
|
|
fautifs+=("${nom} : ${chemin} a disparu")
|
||
|
|
continue
|
||
|
|
fi
|
||
|
|
|
||
|
|
lu=$(stat -c '%U %a' "${chemin}" 2>/dev/null) || { fautifs+=("${nom} : ${chemin} illisible"); continue; }
|
||
|
|
proprietaire=${lu%% *}
|
||
|
|
mode=${lu##* }
|
||
|
|
|
||
|
|
[[ "${proprietaire}" == "${compte}" ]] || fautifs+=("${nom} : appartient a « ${proprietaire} », pas a « ${compte} »")
|
||
|
|
[[ "${mode}" == "700" ]] || fautifs+=("${nom} : mode ${mode} au lieu de 700")
|
||
|
|
done
|
||
|
|
|
||
|
|
if (( ${#fautifs[@]} > 0 )); then
|
||
|
|
# SEPARES PAR « ; », pas par une espace : sans separateur, deux constats se collent et
|
||
|
|
# le message rendu par Icinga devient une phrase qu'on ne peut plus decouper.
|
||
|
|
liste=$(printf '%s; ' "${fautifs[@]}"); liste=${liste%; }
|
||
|
|
echo "Isolation rompue entre locataires — ${liste}. Un locataire peut lire ou effacer les instantanes d'un autre, et aucune sauvegarde n'echouera pour le dire."
|
||
|
|
exit 2
|
||
|
|
fi
|
||
|
|
|
||
|
|
# 2. LA PLACE DEVANT LES LOCATAIRES.
|
||
|
|
#
|
||
|
|
# EN GIGAOCTETS ENTIERS, comme le plancher du deploiement : on compare deux grandeurs
|
||
|
|
# ecrites dans la meme unite, pour que le message de la sonde et celui de l'assertion
|
||
|
|
# disent exactement la meme chose.
|
||
|
|
libre=$(df -BG --output=avail "${PARENT}" 2>/dev/null | tail -1 | tr -dc '0-9')
|
||
|
|
if [[ -z "${libre}" ]]; then
|
||
|
|
echo "Impossible de mesurer la place restante sous ${PARENT} — le systeme de fichiers repond-il encore ?"
|
||
|
|
exit 2
|
||
|
|
fi
|
||
|
|
|
||
|
|
if (( libre < PLANCHER )); then
|
||
|
|
echo "Depot du site : ${libre} Go libres sous le plancher de ${PLANCHER} Go. Le prochain instantane echouera AU MILIEU, chez le locataire, et sa panne s'y lira comme une erreur reseau."
|
||
|
|
exit 2
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "Depot du site : ${#comptes[@]} locataire(s) etanche(s), ${libre} Go libres (plancher ${PLANCHER})."
|
||
|
|
exit 0
|