Files
serv_benchmark/docs/04_bench_script_client.md
2025-12-14 10:40:54 +01:00

476 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 04 Spécification du script client de benchmark (bench.sh)
Objectif : définir précisément le comportement du script Bash exécuté sur les machines clientes pour :
- collecter les informations matérielles et système,
- exécuter les benchmarks,
- calculer les scores,
- envoyer un JSON complet au backend via HTTP.
Ce fichier sert de référence pour écrire `scripts/bench.sh` dans le dépôt.
---
## 1. Usage et interface en ligne de commande
Le script doit être exécutable en one-liner depuis une machine cliente, par exemple :
```bash
curl -s https://gitea.maison43.duckdns.org/gilles/linux-benchtools/raw/branch/main/scripts/bench.sh \
| bash -s -- \
--server https://bench.maison43/api/benchmark \
--token "XXXXXXX" \
--device "elitedesk-800g3" \
--iperf-server 10.0.0.10 \
--short
```
### 1.1. Arguments supportés
- `--server <URL>` (obligatoire)
URL de lendpoint backend `POST /api/benchmark`.
- `--token <TOKEN>` (obligatoire)
Token dauthentification à envoyer dans `Authorization: Bearer <TOKEN>`.
- `--device <NAME>` (optionnel)
Identifiant logique de la machine (`device_identifier`).
Si non fourni, utiliser `hostname` de la machine.
- `--iperf-server <HOST>` (optionnel)
Hôte/IP du serveur iperf3 utilisé pour les tests réseau.
- `--skip-cpu`, `--skip-memory`, `--skip-disk`, `--skip-network`, `--skip-gpu` (optionnels)
Permettent de désactiver certains tests.
- `--short` (optionnel)
Version “rapide” des tests (durées/tailles réduites).
- `--help`
Affiche un message daide et quitte.
### 1.2. Variables internes
- `BENCH_SCRIPT_VERSION` (string, ex: `"1.0.0"`)
Doit être mise à jour à chaque changement incompatible du script.
---
## 2. Pré-requis et compatibilité
### 2.1. OS visés (MVP)
- Debian / Ubuntu / Proxmox (base Debian).
Le script doit :
- Lire `/etc/os-release` pour détecter lOS.
- Utiliser `apt-get` pour installer les paquets manquants.
### 2.2. Outils nécessaires
Le script doit vérifier et installer si besoin :
- `curl`
- `jq` (construction JSON)
- `sysbench` (CPU + mémoire)
- `fio` (disque)
- `iperf3` (réseau, si `--iperf-server` fourni)
- `dmidecode` (RAM, carte mère, BIOS)
- `lsblk`
- `lscpu`
- `smartmontools` (optionnel pour SMART disques)
- `lm-sensors` (optionnel pour températures)
- `glmark2` (optionnel pour GPU si dispo)
---
## 3. Structure générale du script
1. Parser les arguments.
2. Vérifier `--server` et `--token` (sinon erreur + exit 1).
3. Déterminer :
- `DEVICE_IDENTIFIER` = `--device` ou `hostname`.
- `BENCH_SCRIPT_VERSION`.
4. Détecter lOS et préparer la commande dinstallation de paquets.
5. Vérifier/installer les outils nécessaires.
6. Collecter les informations hardware et OS.
7. Exécuter les benchmarks (en respectant les flags `--skip-*`).
8. Calculer les scores (CPU, mémoire, disque, réseau, GPU, global).
9. Construire le JSON.
10. Envoyer le JSON au backend.
11. Afficher un récap et le statut HTTP.
---
## 4. Collecte des informations matérielles et système
Toutes les infos doivent ensuite être assemblées dans le bloc `hardware` du JSON.
### 4.1. CPU
Commandes possibles :
- `lscpu`
- `/proc/cpuinfo`
Informations à extraire :
- `vendor` : ligne `Vendor ID` (ou `GenuineIntel`, `AuthenticAMD`, etc.).
- `model` : `Model name`.
- `microarchitecture` : optionnel (peut être déterminé via une table interne si souhaité, sinon laisser vide).
- `cores` : `Core(s) per socket` × `Socket(s)` ou `CPU(s)` minus hyperthreading.
- `threads` : `CPU(s)` (nombre logique).
- `base_freq_ghz` : depuis `lscpu` (MHz -> GHz).
- `max_freq_ghz` : `CPU max MHz` si disponible.
- `cache_l1_kb`, `cache_l2_kb`, `cache_l3_kb` : `L1d cache`, `L2 cache`, `L3 cache`.
- `flags` : liste depuis `Flags` / `Features`.
- `tdp_w` : non triviale à extraire dans un script, peut rester null.
### 4.2. RAM
Commandes :
- `free -m`
- `dmidecode --type memory` (requiert sudo)
Infos :
- `total_mb` : depuis `free -m`.
- `slots_total` : nombre dentrées `Locator` dans `dmidecode` (type DIMM).
- `slots_used` : slots où `Size` nest pas `No Module Installed`.
- `ecc` : champ `Total Width` vs `Data Width` ou `Error Correction Type`.
- `layout` : tableau dobjets avec :
- `slot` (Locator)
- `size_mb`
- `type` (DDR3/DDR4/DDR5/etc.)
- `speed_mhz`
- `vendor`
- `part_number`
### 4.3. GPU
Commandes :
- `lspci | grep -i vga`
- éventuellement `nvidia-smi` si NVIDIA.
Infos :
- `vendor` : Intel, NVIDIA, AMD…
- `model` : texte brut de `lspci`.
- `driver_version` : si récupérable (`nvidia-smi --query-gpu=driver_version`).
- `memory_dedicated_mb` : via `nvidia-smi`/outils spécifiques si possible, sinon null.
- `memory_shared_mb` : éventuellement via `lspci`/`/proc`, sinon null.
- `api_support` : optionnel (OpenGL/Vulkan), peut être laissé vide.
### 4.4. Stockage (disques et partitions)
Commandes :
- `lsblk -o NAME,SIZE,TYPE,MODEL,TRAN,MOUNTPOINT,FSTYPE`
- `smartctl -H /dev/sdX` (si présent)
- éventuellement `nvme list` / `nvme smart-log`.
Infos :
- `devices` : tableau dobjets :
- `name` (ex: `/dev/nvme0n1`)
- `type` (HDD/SSD/NVMe, déduit de `TYPE`/`TRAN`/nom).
- `interface` (SATA, PCIe 3.0 x4, USB, etc. si déductible).
- `capacity_gb` : depuis `SIZE`.
- `vendor` / `model` : `MODEL`.
- `smart_health` : `PASSED` / `FAILED` / null.
- `temperature_c` : si dispo via SMART.
- `partitions` : tableau dobjets :
- `name`
- `mount_point`
- `fs_type`
- `used_gb`
- `total_gb`
### 4.5. Réseau
Commandes :
- `ip addr`
- `ip -o link`
- `ethtool <iface>` (pour vitesse si dispo).
- pour Wi-Fi : `iw dev` / `iwconfig`.
Infos :
- `interfaces` : tableau dobjets :
- `name` (ex: `eth0`, `enp3s0`, `wlan0`)
- `type` (`ethernet`, `wifi`, `other`)
- `mac`
- `ip` (IPv4 principale si existante)
- `speed_mbps` : via `ethtool`.
- `driver` : éventuellement depuis `/sys/class/net/<iface>/device/driver`.
### 4.6. Carte mère / BIOS
Commandes :
- `dmidecode --type baseboard`
- `dmidecode --type bios`
Infos :
- `motherboard.vendor`
- `motherboard.model`
- `bios_version`
- `bios_date`
### 4.7. OS
Commandes :
- `/etc/os-release`
- `uname -r`
- `uname -m`
- `systemd-detect-virt` (si dispo).
Infos :
- `name` : ID ou PRETTY_NAME.
- `version` : VERSION ou VERSION_CODENAME.
- `kernel_version` : `uname -r`.
- `architecture` : `uname -m`.
- `virtualization_type` : sortie de `systemd-detect-virt` (kvm, qemu, none, etc.).
### 4.8. Capteurs (facultatif)
- `sensors` (lm-sensors)
- `smartctl -A` pour température disques.
Infos :
- `sensors.cpu_temp_c` (ou valeur moyenne).
- `sensors.disk_temps_c` : map `{ "/dev/nvme0n1": 42 }`.
---
## 5. Benchmarks à exécuter
Les résultats iront dans le bloc `results` du JSON.
### 5.1. CPU sysbench
Commande par défaut (mode complet) :
```bash
sysbench cpu --cpu-max-prime=20000 --threads="$(nproc)" run
```
Mode `--short` :
```bash
sysbench cpu --cpu-max-prime=10000 --threads="$(nproc)" run
```
Valeurs à extraire :
- `events_per_sec` : ligne `events per second: X`.
- `duration_s` : temps total (`total time:`).
Score CPU :
- Score simple :
- définir une valeur de référence (par ex. 5000 events/s = 50 points).
- `cpu_score = min(100, events_per_sec / ref * 50)` (ajuster plus tard).
- Pour linstant, le script peut :
- soit calculer cette note,
- soit juste envoyer les valeurs brutes et laisser le backend calculer.
### 5.2. Mémoire sysbench
Commande (complet) :
```bash
sysbench memory --memory-total-size=2G --memory-oper=write run
```
Mode `--short` :
```bash
sysbench memory --memory-total-size=512M --memory-oper=write run
```
Valeurs :
- `throughput_mib_s` : ligne `transferred (XXXX MiB/sec)`.
Score mémoire :
- Basé sur `throughput_mib_s` et une référence.
### 5.3. Disque fio
Profil simple (séquentiel read/write 1GiB) :
```bash
fio --name=bench_seq_rw \
--rw=readwrite \
--bs=1M \
--size=1G \
--numjobs=1 \
--iodepth=16 \
--filename=/tmp/fio_benchfile \
--direct=1 \
--group_reporting
```
Mode `--short` :
- Taille 256M.
Valeurs à extraire (via parsing ou `--output-format=json`) :
- `read_mb_s`
- `write_mb_s`
- éventuellement `iops_read`, `iops_write`, `latency_ms`.
Score disque :
- Moyenne pondérée de read/write vs valeurs de référence.
Après test, supprimer `/tmp/fio_benchfile`.
### 5.4. Réseau iperf3
Uniquement si `--iperf-server` fourni.
Download (client -> server, test reverse) :
```bash
iperf3 -c "$IPERF_SERVER" -R -J
```
Upload :
```bash
iperf3 -c "$IPERF_SERVER" -J
```
Utiliser le JSON (`-J`) + `jq` pour extraire :
- `upload_mbps`
- `download_mbps`
- `jitter_ms`
- `packet_loss_percent` (si UDP, option future).
Ping (latence) :
```bash
ping -c 5 "$IPERF_SERVER"
```
Extraire :
- `ping_ms` = moyenne.
Score réseau :
- Combinaison débit (min(up, down)) et latence (ping).
### 5.5. GPU glmark2 (optionnel)
Si `glmark2` disponible :
```bash
glmark2
```
Extraire :
- Score global `glmark2_score`.
Score GPU :
- Normalisation simple vs référence.
---
## 6. Construction du JSON
Le script utilise `jq` pour construire le JSON final :
Structure :
```json
{
"device_identifier": "...",
"bench_script_version": "1.0.0",
"hardware": { ... },
"results": { ... }
}
```
Principes :
- Utiliser `jq -n` et passer les valeurs via `--arg` / `--argjson`.
- Attention aux nombres vs strings (utiliser `--argjson` pour les nombres).
- Gérer proprement les valeurs nulles (par exemple si test GPU non réalisé).
Exemple (simplifié) en shell :
```bash
payload=$(jq -n --arg device_identifier "$DEVICE_IDENTIFIER" --arg bench_script_version "$BENCH_SCRIPT_VERSION" --argjson cpu "$CPU_JSON" --argjson ram "$RAM_JSON" --argjson results "$RESULTS_JSON" '{
device_identifier: $device_identifier,
bench_script_version: $bench_script_version,
hardware: {
cpu: $cpu,
ram: $ram
},
results: $results
}')
```
---
## 7. Envoi au backend
Commandes :
```bash
HTTP_RESPONSE=$(curl -s -o /tmp/bench_response.txt -w "%{http_code}" \
-X POST "$SERVER_URL" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d "$payload")
```
- Si `HTTP_RESPONSE` != `200` :
- Afficher un message derreur (console).
- Optionnel : afficher `/tmp/bench_response.txt`.
- Si succès :
- Afficher un message confirmant lID du benchmark si présent dans la réponse.
---
## 8. Gestion des erreurs à prévoir
- Absence de `--server` ou `--token` -> erreur et exit.
- Outils manquants et impossible à installer -> avertir, sauter le test concerné, transmettre `score = null`.
- Erreurs iperf3 (serveur indisponible) -> ignorer la partie réseau, `network` null.
- Temps de test trop long -> proposer un mode `--short`.
---
## 9. Journalisation locale (optionnelle)
- Possibilité de logger les infos dans `/var/log/linux_benchtools_client.log` ou `/tmp/linux_benchtools_client.log`.
- Log recommandé :
- Date/heure.
- SERVER, DEVICE_IDENTIFIER.
- Résumé des scores.
- Code HTTP de la réponse.
---
## 10. Bonnes pratiques
- Ne jamais supprimer ou modifier des fichiers système.
- Nettoyer les fichiers temporaires (fio, résultats intermédiaires).
- Garder le script idempotent : on peut le relancer sans casser la machine.
- Prévoir un délai total raisonnable pour un run complet (ex. < 510 minutes en mode complet, < 23 minutes en mode `--short`).