150 lines
6.7 KiB
Markdown
150 lines
6.7 KiB
Markdown
# `swap_cleaner.sh` — Purge automatique du swap avec notification Discord
|
||
|
||
🧹 **Objectif**
|
||
Sur un hôte **Proxmox VE (PVE)**, ce script surveille l’utilisation du **swap** et, si elle reste **au-dessus d’un seuil** pendant une durée continue définie, il déclenche une purge douce du swap (`swapoff -a && swapon -a`).
|
||
À chaque action (ou erreur), une **notification Discord** est envoyée (message + **pièce jointe** du log).
|
||
|
||
---
|
||
|
||
## 🧩 Fonctionnement (résumé)
|
||
1. À **chaque exécution** (idéalement via `cron`), le script lit le **% de swap utilisé** (`free -m`).
|
||
2. S’il est **≥ THRESHOLD** (par défaut **90%**), un **compteur** s’incrémente dans `STATE_FILE` (`/var/tmp/swap_usage_count.txt`).
|
||
3. Si ce compteur atteint `DURATION_MIN / CHECK_EVERY_MIN` (ex.: **120 min / 10 min = 12** exécutions consécutives), le script :
|
||
- journalise l’action dans `LOG` (`/var/log/swap_cleaner.log`),
|
||
- exécute `swapoff -a && swapon -a`,
|
||
- envoie une **notification Discord** avec le **log joint**,
|
||
- réinitialise le compteur.
|
||
4. Si l’usage repasse **sous** le seuil, le **compteur est remis à 0**.
|
||
|
||
Le script s’exécute **en instance unique** grâce à un **lock** (`/var/tmp/.swap_cleaner.lock`) pour éviter les chevauchements via `cron`.
|
||
|
||
---
|
||
|
||
## ✅ Prérequis
|
||
- Hôte **PVE** (ou Linux avec `swapoff` / `swapon` disponibles).
|
||
- **Root** requis (ne pas utiliser `sudo` dans PVE, exécuter en root directement).
|
||
- Paquet **`jq`** (installé automatiquement si absent).
|
||
- Accès **HTTP sortant** vers l’URL **Discord Webhook**.
|
||
|
||
---
|
||
|
||
## 🔧 Variables (override possibles via l’environnement)
|
||
| Variable | Par défaut | Description |
|
||
|---------------------|------------|-------------|
|
||
| `WEBHOOK` | *(exemple dans le script)* | URL du **Discord Webhook** recevant la notification. |
|
||
| `THRESHOLD` | `90` | Seuil de **% de swap utilisé** déclenchant le comptage. |
|
||
| `CHECK_EVERY_MIN` | `10` | Fréquence (en minutes) d’exécution par `cron`. |
|
||
| `DURATION_MIN` | `120` | Durée **continue** (en minutes) au-delà du seuil avant action. |
|
||
| `STATE_FILE` | `/var/tmp/swap_usage_count.txt` | Compteur persistant entre exécutions. |
|
||
| `LOG` | `/var/log/swap_cleaner.log` | Journal d’exécution (+ joint à Discord). |
|
||
|
||
**Calcul interne :** nombre d’exécutions consécutives requises = `ceil(DURATION_MIN / CHECK_EVERY_MIN)`.
|
||
|
||
---
|
||
|
||
## 📦 Installation
|
||
1. **Copier** le script dans votre répertoire de scripts (recommandé : `/home/scripts`) :
|
||
```bash
|
||
install -m 0755 swap_cleaner.sh /home/scripts/swap_cleaner.sh
|
||
```
|
||
2. **Vérifier** le shebang et les permissions :
|
||
```bash
|
||
head -n 1 /home/scripts/swap_cleaner.sh
|
||
ls -l /home/scripts/swap_cleaner.sh
|
||
```
|
||
3. **Créer** les emplacements nécessaires (log + state seront créés au premier run) :
|
||
```bash
|
||
mkdir -p /var/tmp
|
||
touch /var/log/swap_cleaner.log
|
||
```
|
||
|
||
> 💡 Conformément à votre organisation, `/home/scripts` est le dossier de référence pour vos scripts.
|
||
|
||
---
|
||
|
||
## ⏱️ Planification (cron)
|
||
Exécution **toutes les 10 minutes** (cohérente avec la valeur par défaut `CHECK_EVERY_MIN=10`).
|
||
Ouvrir le **crontab root** :
|
||
```bash
|
||
crontab -e
|
||
```
|
||
Ajouter la ligne suivante :
|
||
```cron
|
||
*/10 * * * * CHECK_EVERY_MIN=10 DURATION_MIN=120 THRESHOLD=90 WEBHOOK="https://discord.com/api/webhooks/XXX/YYY" /home/scripts/swap_cleaner.sh
|
||
```
|
||
- **Adapter** `WEBHOOK`, `THRESHOLD`, `CHECK_EVERY_MIN`, `DURATION_MIN` si nécessaire.
|
||
- **Important :** le script doit être lancé **en root** (crontab root).
|
||
|
||
### Exemples d’override
|
||
- Exécuter **toutes les 5 minutes** avec seuil **80%** et durée **1h** :
|
||
```cron
|
||
*/5 * * * * CHECK_EVERY_MIN=5 DURATION_MIN=60 THRESHOLD=80 WEBHOOK="https://discord.com/api/webhooks/XXX/YYY" /home/scripts/swap_cleaner.sh
|
||
```
|
||
- Exécuter **toutes les 15 minutes** avec durée **2h30** :
|
||
```cron
|
||
*/15 * * * * CHECK_EVERY_MIN=15 DURATION_MIN=150 WEBHOOK="https://discord.com/api/webhooks/XXX/YYY" /home/scripts/swap_cleaner.sh
|
||
```
|
||
|
||
---
|
||
|
||
## 🧪 Tests rapides (safe)
|
||
1. **Test lecture & log** (sans forcer purge) :
|
||
```bash
|
||
THRESHOLD=0 CHECK_EVERY_MIN=10 DURATION_MIN=9999 /home/scripts/swap_cleaner.sh && tail -n 5 /var/log/swap_cleaner.log
|
||
```
|
||
- Force `USAGE ≥ THRESHOLD` mais **n’atteint pas** la durée → **aucune purge**.
|
||
2. **Test action contrôlée** (⚠️ purge volontaire) :
|
||
```bash
|
||
THRESHOLD=0 CHECK_EVERY_MIN=1 DURATION_MIN=1 /home/scripts/swap_cleaner.sh
|
||
```
|
||
- Déclenche `swapoff -a && swapon -a` **une fois** et envoie la **notif Discord**.
|
||
|
||
---
|
||
|
||
## 🔔 Notifications Discord
|
||
- Le message est formaté **multiligne** et limité **< 2000 caractères** (troncature gérée).
|
||
- Le **fichier log** `/var/log/swap_cleaner.log` est **joint** systématiquement aux actions/erreurs.
|
||
- Le message inclut **Avant/Après** (`free -h`) pour la lisibilité.
|
||
|
||
> ✅ Respecte vos exigences **Discord** : `jq -Rs` pour payload JSON et **pièce jointe** via `curl -F`.
|
||
|
||
---
|
||
|
||
## 🛡️ Sécurité & impacts
|
||
- L’action `swapoff -a && swapon -a` peut **déplacer de la mémoire** et provoquer une **latence** temporaire selon la charge.
|
||
- Assurez-vous d’avoir **suffisamment de RAM** pour absorber le contenu du swap.
|
||
- Évitez d’exécuter en même temps que des opérations lourdes (ex.: backup/restores massifs).
|
||
- Le script **échoue en silence** côté cron si le réseau vers Discord est indisponible (les logs locaux restent disponibles).
|
||
|
||
---
|
||
|
||
## 🧰 Dépannage
|
||
- **Aucune notif Discord ?**
|
||
- Vérifiez la **valeur `WEBHOOK`** et la **connectivité** (pare-feu, DNS).
|
||
- Consultez `/var/log/swap_cleaner.log` et rejouez le test d’action contrôlée.
|
||
- **Pas d’action malgré un swap élevé ?**
|
||
- Confirmez la **fréquence cron** réelle et le **calcul `ceil(DURATION_MIN / CHECK_EVERY_MIN)`**.
|
||
- Examinez `STATE_FILE` (compteur) et supprimez-le si besoin : `rm -f /var/tmp/swap_usage_count.txt`.
|
||
- **Chevauchements cron** :
|
||
- Le lock file (`/var/tmp/.swap_cleaner.lock`) empêche les runs concurrents.
|
||
- Vérifiez l’absence d’exécutions trop longues (IO/charge).
|
||
|
||
---
|
||
|
||
## 🗑️ Désinstallation
|
||
```bash
|
||
crontab -e # retirer la ligne cron
|
||
rm -f /home/scripts/swap_cleaner.sh /var/log/swap_cleaner.log /var/tmp/swap_usage_count.txt /var/tmp/.swap_cleaner.lock
|
||
```
|
||
|
||
---
|
||
|
||
## ✍️ Note
|
||
- Le script est conçu pour être **idempotent**, robuste (`set -euo pipefail`) et **VSN** (bonnes pratiques, `jq` requis, envoi Discord avec pièce jointe, limite 2000 caractères).
|
||
- Adaptez `THRESHOLD`, `CHECK_EVERY_MIN`, `DURATION_MIN` en fonction de votre profil d’utilisation mémoire réelle.
|
||
|
||
---
|
||
|
||
## 📄 Licence
|
||
Utilisation interne. Adapter si nécessaire à votre politique de sécurité.
|