130 lines
4.1 KiB
Nix
130 lines
4.1 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
cfg = config.numbus-server.services.disk-space-checker;
|
|
|
|
disk_space_notifier = pkgs.writeScript "disk-space-notifier.sh" ''
|
|
#!${pkgs.bash}/bin/bash
|
|
|
|
ALERT_FILE="/var/lib/numbus-server/disk_alert.env"
|
|
if [ ! -f "$ALERT_FILE" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
source "$ALERT_FILE"
|
|
rm "$ALERT_FILE"
|
|
|
|
# Update the timestamp for this specific path to prevent spamming
|
|
SAFE_PATH=$(echo "$DISK_ALERT_PATH" | tr '/' '_')
|
|
date +%s > "/var/lib/numbus-server/last_alert_$SAFE_PATH.ts"
|
|
|
|
ADMIN_EMAIL="${config.numbus-server.mail.adminAddress}"
|
|
USER_EMAIL="${config.numbus-server.mail.userAddress}"
|
|
OWNER_NAME="${config.numbus-server.owner}"
|
|
|
|
SUBJECT="Numbus Server Alert: Low Disk Space Detected"
|
|
|
|
TECH_BODY="
|
|
Disk Space Alert:
|
|
Server owner: $OWNER_NAME
|
|
|
|
The following mount point has exceeded the safety threshold:
|
|
Mount: $DISK_ALERT_PATH
|
|
Usage: $DISK_ALERT_USAGE%
|
|
|
|
Full partition details:
|
|
$(df -h "$DISK_ALERT_PATH")
|
|
|
|
Action required: Please investigate and clear space or expand the storage capacity.
|
|
"
|
|
|
|
FRIENDLY_BODY="Cher/Chère $OWNER_NAME,
|
|
|
|
L'espace de stockage de votre serveur Numbus est presque saturé.
|
|
Disque concerné : $DISK_ALERT_PATH ($DISK_ALERT_USAGE% utilisé)
|
|
|
|
Votre administrateur a été notifié avec les détails techniques.
|
|
Nous vous conseillons d'éviter d'ajouter des fichiers volumineux pour garantir le bon fonctionnement de vos services.
|
|
Contactez votre administrateur afin d'évoquer les possibilités d'expansion du stockage.
|
|
"
|
|
|
|
printf "Subject: [ADMIN] %s\n\n%s" "$SUBJECT" "$TECH_BODY" | /run/wrappers/bin/sendmail -t "$ADMIN_EMAIL"
|
|
printf "Subject: [Alerte] Espace disque presque saturé sur votre serveur Numbus\n\n%s\n\nMerci de votre confiance,\nL'équipe de support,\nNumbus-Server." "$FRIENDLY_BODY" | /run/wrappers/bin/sendmail -t "$USER_EMAIL"
|
|
'';
|
|
|
|
disk_space_checker = pkgs.writeScript "disk-space-checker.sh" ''
|
|
#!${pkgs.bash}/bin/bash
|
|
|
|
# Safety threshold in percentage
|
|
THRESHOLD=90
|
|
# Paths to monitor (Root and MergerFS data pool)
|
|
PATHS=("/" "/mnt/data")
|
|
ALERT_FILE="/var/lib/numbus-server/disk_alert.env"
|
|
|
|
for path in "''${PATHS[@]}"; do
|
|
# Skip if path does not exist (e.g. if mergerfs is not mounted yet)
|
|
if [ ! -d "$path" ]; then
|
|
continue
|
|
fi
|
|
|
|
# Anti-spam logic: Check if we alerted on this path recently (7 days = 604800 seconds)
|
|
SAFE_PATH=$(echo "$path" | tr '/' '_')
|
|
TS_FILE="/var/lib/numbus-server/last_alert_$SAFE_PATH.ts"
|
|
NOW=$(date +%s)
|
|
|
|
if [ -f "$TS_FILE" ]; then
|
|
LAST_SENT=$(cat "$TS_FILE")
|
|
DIFF=$((NOW - LAST_SENT))
|
|
if [ "$DIFF" -lt 604800 ]; then
|
|
echo "Alert for $path was sent recently. Skipping notification to avoid spam."
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
# Extract usage percentage using df
|
|
USAGE=$(df -h "$path" | awk 'NR==2 {print $5}' | sed 's/%//')
|
|
|
|
if [ "$USAGE" -ge "$THRESHOLD" ]; then
|
|
echo "DISK_ALERT_PATH=$path" > "$ALERT_FILE"
|
|
echo "DISK_ALERT_USAGE=$USAGE" >> "$ALERT_FILE"
|
|
|
|
echo "Threshold exceeded for $path ($USAGE%). Triggering notification."
|
|
|
|
# Trigger the notification service
|
|
/run/current-system/sw/bin/systemctl start disk-space-notifier.service
|
|
|
|
# We exit after the first alert to avoid multiple overlapping emails in one run
|
|
exit 0
|
|
fi
|
|
done
|
|
'';
|
|
in
|
|
|
|
{
|
|
config = mkIf cfg.enable {
|
|
systemd.services.disk-space-notifier = {
|
|
description = "Email notification for low disk space";
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
ExecStart = "${disk_space_notifier}";
|
|
};
|
|
};
|
|
systemd.services.disk-space-checker = {
|
|
description = "Check for low disk space";
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
ExecStart = "${disk_space_checker}";
|
|
};
|
|
};
|
|
systemd.timers.disk-space-checker = {
|
|
description = "Run disk space check every day";
|
|
timerConfig = {
|
|
OnCalendar = "daily";
|
|
Persistent = true;
|
|
};
|
|
wantedBy = [ "timers.target" ];
|
|
};
|
|
};
|
|
} |