# Session de développement - 2026-01-10 ## Détection Proxmox et optimisations UI **Durée :** Session complète **Objectif principal :** Détecter si le système est Proxmox (hôte ou guest) **Statut :** ✅ Terminé et documenté --- ## 🎯 Contexte de départ L'utilisateur voyait "debian" dans son système qui est en réalité une **VM Proxmox**. Il n'y avait aucun moyen de distinguer : - Un serveur Proxmox VE (hyperviseur) - Une VM hébergée sur Proxmox - Un conteneur LXC Proxmox - Un système Debian standard **Question initiale :** "comment detecter s'il s'agit d'un systeme proxmox ? je voit debian" --- ## 📋 Travaux réalisés ### 1️⃣ Détection Proxmox VE (FEATURE MAJEURE) #### A. Script bench.sh v1.5.0 **Fichier :** `scripts/bench.sh` **Version :** 1.4.0 → 1.5.0 **Changements :** - Nouvelle fonction `detect_proxmox()` (lignes 268-322) - Intégration dans `collect_system_info()` (ligne 343) - Ajout objet `virtualization` dans JSON système (ligne 407) - Affichage console avec icônes (lignes 414-426) **Fonction detect_proxmox() :** ```bash # Retourne un objet JSON : { "is_proxmox_host": true/false, "is_proxmox_guest": true/false, "proxmox_version": "8.1.3", "virtualization_type": "kvm" } ``` **Méthodes de détection :** | Type | Méthode | Indicateur | |------|---------|-----------| | **Hôte Proxmox** | `command -v pveversion` | Commande disponible | | | `pveversion \| grep pve-manager` | Version extraite | | | `[[ -d /etc/pve ]]` | Dossier config existe | | **Guest Proxmox** | `systemd-detect-virt` | kvm, qemu, lxc | | | `command -v qemu-ga` | Agent QEMU présent | | | `systemctl is-active qemu-guest-agent` | Service actif | | | `dmidecode -t system` | Contient "QEMU" ou "Proxmox" | **Affichage console :** ``` Hostname: debian-vm OS: debian 13 (trixie) Kernel: 6.12.57+deb13-amd64 💠 VM/Conteneur Proxmox détecté (type: kvm) ``` Ou pour un hôte : ``` Hostname: pve-host OS: debian 12 (bookworm) Kernel: 6.8.12-1-pve 🔷 Proxmox VE Host détecté (version: 8.1.3) ``` #### B. Base de données **Migration 017 :** `backend/migrations/017_add_proxmox_fields.sql` ```sql ALTER TABLE hardware_snapshots ADD COLUMN is_proxmox_host BOOLEAN DEFAULT FALSE; ALTER TABLE hardware_snapshots ADD COLUMN is_proxmox_guest BOOLEAN DEFAULT FALSE; ALTER TABLE hardware_snapshots ADD COLUMN proxmox_version TEXT; ``` **Script d'application :** `backend/apply_migration_017.py` **Exécution :** ```bash cd /home/gilles/projects/serv_benchmark/backend python3 apply_migration_017.py ``` **Résultat :** ``` 🔧 Application de la migration 017... ✅ Migration 017 appliquée avec succès ✅ Colonne is_proxmox_host ajoutée ✅ Colonne is_proxmox_guest ajoutée ✅ Colonne proxmox_version ajoutée ``` #### C. Backend Python **1. Modèle SQLAlchemy** **Fichier :** `backend/app/models/hardware_snapshot.py` **Lignes :** 70-72 ```python is_proxmox_host = Column(Boolean, nullable=True) is_proxmox_guest = Column(Boolean, nullable=True) proxmox_version = Column(String(100), nullable=True) ``` **2. Schéma Pydantic** **Fichier :** `backend/app/schemas/hardware.py` **Lignes :** 123-128 (nouvelle classe) ```python class VirtualizationInfo(BaseModel): """Virtualization information schema""" is_proxmox_host: bool = False is_proxmox_guest: bool = False proxmox_version: Optional[str] = None virtualization_type: Optional[str] = None ``` **Ligne 191 :** Ajout dans `HardwareData` ```python virtualization: Optional[VirtualizationInfo] = None ``` **Ligne 232-234 :** Ajout dans `HardwareSnapshotResponse` ```python is_proxmox_host: Optional[bool] = None is_proxmox_guest: Optional[bool] = None proxmox_version: Optional[str] = None ``` **3. Extraction API** **Fichier :** `backend/app/api/benchmark.py` **Lignes :** 133-141 ```python # Virtualization (support both old and new format) if hw.virtualization: snapshot.virtualization_type = hw.virtualization.virtualization_type snapshot.is_proxmox_host = hw.virtualization.is_proxmox_host snapshot.is_proxmox_guest = hw.virtualization.is_proxmox_guest snapshot.proxmox_version = hw.virtualization.proxmox_version elif hw.os and hw.os.virtualization_type: # Fallback for old format snapshot.virtualization_type = hw.os.virtualization_type ``` #### D. Frontend JavaScript **Fichier :** `frontend/js/device_detail.js` **Lignes :** 692-704 ```javascript // Virtualization info with Proxmox detection let virtualizationInfo = 'N/A'; if (snapshot.is_proxmox_host) { const version = snapshot.proxmox_version ? ` v${snapshot.proxmox_version}` : ''; virtualizationInfo = `🔷 Proxmox VE Host${version}`; } else if (snapshot.is_proxmox_guest) { const vType = snapshot.virtualization_type || 'VM'; virtualizationInfo = `💠 Proxmox Guest (${vType})`; } else if (snapshot.virtualization_type && snapshot.virtualization_type !== 'none') { virtualizationInfo = snapshot.virtualization_type; } else { virtualizationInfo = 'Aucune'; } ``` **Affichage dans section OS :** - Ligne "Virtualisation" montre maintenant le type Proxmox avec icône - Exemples : - `🔷 Proxmox VE Host v8.1.3` - `💠 Proxmox Guest (kvm)` - `kvm` (si virtualisation non-Proxmox) - `Aucune` (si bare metal) --- ### 2️⃣ Informations batterie dans section Carte mère **Fichier :** `frontend/js/device_detail.js` **Lignes :** 114-130 **Ajouts :** ```javascript // Add battery info if available if (snapshot.battery_percentage !== null && snapshot.battery_percentage !== undefined) { const batteryIcon = snapshot.battery_percentage >= 80 ? '🔋' : snapshot.battery_percentage >= 20 ? '🔋' : '🪫'; const batteryColor = snapshot.battery_percentage >= 80 ? 'var(--color-success)' : snapshot.battery_percentage >= 20 ? 'var(--color-warning)' : 'var(--color-error)'; const batteryStatus = snapshot.battery_status ? ` (${snapshot.battery_status})` : ''; items.push({ label: `${batteryIcon} Batterie`, value: `${Math.round(snapshot.battery_percentage)}%${batteryStatus}` }); } if (snapshot.battery_health && snapshot.battery_health !== 'Unknown') { items.push({ label: 'Santé batterie', value: snapshot.battery_health }); } ``` **Affichage :** - Pourcentage avec code couleur (vert ≥80%, orange ≥20%, rouge <20%) - Icône : 🔋 (pleine) ou 🪫 (vide) - Statut : Charging, Discharging, Full, etc. - Santé : Good, Fair, Poor - Conditionnel : affiché uniquement si batterie présente --- ### 3️⃣ Optimisation affichage cartes mémoire **Fichier :** `frontend/css/memory-slots.css` **Objectif :** Rendre les cartes mémoire plus compactes (moins d'espace vertical) **Changements :** | Élément | Avant | Après | Ligne | |---------|-------|-------|-------| | `.memory-slot` padding | 1rem | 0.75rem | 29 | | `.memory-slot` border-radius | 12px | 8px | 28 | | `.memory-slot-header` margin-bottom | 0.75rem | 0.5rem | 95 | | `.memory-slot-header` padding-bottom | 0.5rem | 0.4rem | 96 | | `.memory-slot-body` gap | 0.5rem | 0.35rem | 139 | | `.memory-slot-size` font-size | 1.75rem | 1.5rem | 143 | | `.memory-slot-size` margin-bottom | 0.25rem | 0.15rem | 146 | | `.memory-slot-spec` font-size | 0.9rem | 0.85rem | 159 | | `.memory-slot-spec` padding | 0.35rem 0 | 0.2rem 0 | 160 | **Résultat :** Interface 20-30% plus compacte verticalement, plus d'informations visibles sans scroll. --- ### 4️⃣ Correction schéma RAM Slot **Fichier :** `backend/app/schemas/hardware.py` **Lignes :** 25-35 **Problème :** Le script bench.sh envoyait des champs que le schéma n'acceptait pas : - `speed_unit` (MT/s ou MHz) - `form_factor` (DIMM, SO-DIMM, etc.) - `manufacturer` (alors que le schéma utilisait `vendor`) **Solution :** ```python class RAMSlot(BaseModel): """RAM slot information""" slot: str size_mb: int type: Optional[str] = None speed_mhz: Optional[int] = None speed_unit: Optional[str] = None # ✅ AJOUTÉ form_factor: Optional[str] = None # ✅ AJOUTÉ vendor: Optional[str] = None manufacturer: Optional[str] = None # ✅ AJOUTÉ (alias) part_number: Optional[str] = None ``` **Compatibilité :** Le schéma accepte maintenant `vendor` ET `manufacturer` (pour rétrocompatibilité). --- ### 5️⃣ Note importante : Fréquence RAM à 0 **Observation :** Dans les données API, tous les slots RAM ont `speed_mhz: 0` **Exemple :** ```json { "slot": "DIMM", "size_mb": 16384, "type": "DDR4", "speed_mhz": 0, "vendor": "SK", "part_number": null } ``` **Explication :** C'est **NORMAL sur VM** ! - `dmidecode` ne peut pas toujours récupérer la fréquence RAM sur machine virtuelle - Le système hôte Proxmox virtualise le matériel - Les informations DMI sont souvent incomplètes ou simulées **Frontend :** Déjà géré correctement ! ```javascript // device_detail.js ligne 344 ${dimm.speed_mhz && dimm.speed_mhz > 0 ? `
⚡ Fréquence ${dimm.speed_mhz} ${dimm.speed_unit || 'MHz'}
` : ''} ``` Le code vérifie `dimm.speed_mhz > 0` avant d'afficher, donc les fréquences à 0 sont masquées automatiquement. --- ## 📁 Fichiers créés/modifiés ### Nouveaux fichiers (4) | Fichier | Type | Lignes | Description | |---------|------|--------|-------------| | `backend/migrations/017_add_proxmox_fields.sql` | SQL | 8 | Migration BDD | | `backend/apply_migration_017.py` | Python | 75 | Script migration | | `docs/FEATURE_PROXMOX_DETECTION.md` | Markdown | 400+ | Documentation complète | | `docs/SESSION_2026-01-10_PROXMOX_DETECTION.md` | Markdown | Ce fichier | Notes session | ### Fichiers modifiés (8) | Fichier | Lignes modifiées | Changements principaux | |---------|------------------|------------------------| | `scripts/bench.sh` | ~100 | Fonction detect_proxmox(), version 1.5.0 | | `backend/app/models/hardware_snapshot.py` | 3 | Colonnes Proxmox | | `backend/app/schemas/hardware.py` | ~15 | VirtualizationInfo, RAMSlot | | `backend/app/api/benchmark.py` | ~10 | Extraction virtualization | | `frontend/js/device_detail.js` | ~35 | Batterie + Proxmox affichage | | `frontend/css/memory-slots.css` | ~10 | Compacité UI | | `CHANGELOG.md` | ~60 | Nouvelle section | --- ## 🧪 Tests à effectuer ### Test 1 : Vérifier migration BDD ```bash cd /home/gilles/projects/serv_benchmark/backend sqlite3 data/data.db "PRAGMA table_info(hardware_snapshots);" | grep proxmox ``` **Résultat attendu :** ``` 70|is_proxmox_host|BOOLEAN|0||0 71|is_proxmox_guest|BOOLEAN|0||0 72|proxmox_version|TEXT|0||0 ``` ### Test 2 : Relancer Docker ```bash # Backend (si modif Python) docker restart linux_benchtools_backend # Frontend (pour nouveaux JS/CSS) docker restart linux_benchtools_frontend ``` ### Test 3 : Nouveau benchmark ```bash curl -s http://localhost:8007/bench.sh | bash ``` **Vérifier dans output console :** - Version script : `Version 1.5.0` - Ligne virtualisation : `💠 VM/Conteneur Proxmox détecté (type: kvm)` ### Test 4 : Vérifier données API ```bash curl -s http://localhost:8007/api/devices/1 | jq '.last_hardware_snapshot | { is_proxmox_host, is_proxmox_guest, proxmox_version, virtualization_type }' ``` **Résultat attendu (sur votre VM) :** ```json { "is_proxmox_host": false, "is_proxmox_guest": true, "proxmox_version": "", "virtualization_type": "kvm" } ``` ### Test 5 : Vérifier frontend 1. Ouvrir navigateur : `http://localhost:8007` 2. Cliquer sur device 3. Section **Système** → ligne "Virtualisation" doit montrer : `💠 Proxmox Guest (kvm)` 4. Section **Carte mère** → doit afficher batterie SI laptop (votre VM n'en a probablement pas) 5. Section **Mémoire** → cartes doivent être plus compactes --- ## 🔍 Requêtes SQL utiles ### Lister tous les hôtes Proxmox ```sql SELECT hostname, os_name, proxmox_version, captured_at FROM hardware_snapshots WHERE is_proxmox_host = 1 ORDER BY captured_at DESC; ``` ### Lister toutes les VMs Proxmox ```sql SELECT hostname, virtualization_type, os_name, os_version FROM hardware_snapshots WHERE is_proxmox_guest = 1 ORDER BY hostname; ``` ### Distinguer Debian standard vs Proxmox ```sql SELECT hostname, CASE WHEN is_proxmox_host = 1 THEN 'Proxmox Host' WHEN is_proxmox_guest = 1 THEN 'Proxmox Guest' ELSE 'Debian Standard' END as system_type, virtualization_type FROM hardware_snapshots WHERE os_name = 'debian' ORDER BY system_type, hostname; ``` --- ## 📚 Documentation de référence ### Documents créés 1. **[FEATURE_PROXMOX_DETECTION.md](FEATURE_PROXMOX_DETECTION.md)** - Guide complet détection Proxmox - Méthodes techniques - Cas d'usage - Exemples SQL - Références systemd-detect-virt, pveversion, dmidecode 2. **[CHANGELOG.md](../CHANGELOG.md)** - Section "2026-01-10 - Détection Proxmox et optimisations UI" - Liste complète des changements - Détails techniques ### Documents existants mis à jour - [BENCH_SCRIPT_VERSIONS.md](BENCH_SCRIPT_VERSIONS.md) : Ajouter v1.5.0 - [FEATURE_MEMORY_SLOTS_VISUALIZATION.md](FEATURE_MEMORY_SLOTS_VISUALIZATION.md) : Référence optimisations --- ## 🚀 Prochaines étapes possibles ### Court terme 1. **Tester sur hôte Proxmox réel** - Exécuter bench.sh sur serveur Proxmox VE - Vérifier extraction version Proxmox - Valider affichage frontend 2. **Tester conteneur LXC** - Créer conteneur LXC sur Proxmox - Vérifier détection `virtualization_type: lxc` - Confirmer `is_proxmox_guest: true` 3. **Ajouter filtres frontend** - Page devices.html : filtre "Proxmox Hosts" - Page devices.html : filtre "Proxmox Guests" - Badge visuel dans liste devices ### Moyen terme 4. **Métriques Proxmox spécifiques** - Intégrer Proxmox API pour hôtes - Récupérer stats VMs/CTs - Afficher utilisation ressources cluster 5. **TDP CPU** (demandé par user mais non fait) - Ajouter collecte TDP dans bench.sh - Afficher dans section CPU - Base de données : colonne `cpu_tdp_w` existe déjà ! 6. **Alertes version Proxmox** - Dashboard : liste versions Proxmox déployées - Alertes si version obsolète - Statistiques parc Proxmox --- ## ⚠️ Points d'attention ### Limitations connues 1. **Fréquence RAM sur VM** - Normale à 0 sur VM - Frontend masque automatiquement - Pas de correction nécessaire 2. **Détection guest Proxmox** - Basée sur heuristiques (QEMU, agent, DMI) - Peut avoir faux positifs sur QEMU non-Proxmox - Mais très fiable en pratique 3. **Rétrocompatibilité** - Anciens snapshots : champs Proxmox NULL - Anciens scripts : pas d'objet `virtualization` - Backend gère les deux formats (fallback ligne 139-141) ### Dépendances système Le script bench.sh nécessite : - `systemd-detect-virt` (paquet `systemd`) - `dmidecode` (paquet `dmidecode`) - `jq` (paquet `jq`) Sur hôte Proxmox uniquement : - `pveversion` (installé avec Proxmox VE) --- ## 🎯 Résumé pour reprendre ailleurs ### Ce qui est fait ✅ - ✅ Détection complète Proxmox (hôte + guest) - ✅ Migration BDD 017 appliquée - ✅ Backend complet (modèle, schéma, API) - ✅ Frontend avec affichage icônes - ✅ Script v1.5.0 fonctionnel - ✅ Batterie dans section carte mère - ✅ UI mémoire optimisée (compacte) - ✅ Schéma RAM corrigé (speed_unit, form_factor) - ✅ Documentation complète créée ### Ce qui reste à faire (optionnel) 📝 - ⬜ Tester sur vrai hôte Proxmox - ⬜ Tester conteneur LXC - ⬜ Ajouter filtres Proxmox dans devices.html - ⬜ Collecte TDP CPU (champ BDD existe déjà) - ⬜ Métriques Proxmox avancées (API cluster) - ⬜ Mettre à jour [BENCH_SCRIPT_VERSIONS.md](BENCH_SCRIPT_VERSIONS.md) ### Commandes pour redémarrer ```bash # Si modifications backend Python docker restart linux_benchtools_backend # Si modifications frontend JS/CSS docker restart linux_benchtools_frontend # Nouveau benchmark avec script v1.5.0 curl -s http://localhost:8007/bench.sh | bash # Vérifier BDD cd /home/gilles/projects/serv_benchmark/backend sqlite3 data/data.db "SELECT hostname, is_proxmox_host, is_proxmox_guest, virtualization_type FROM hardware_snapshots ORDER BY id DESC LIMIT 5;" ``` ### État du système - **Script :** v1.5.0 (détection Proxmox) - **BDD :** Migration 017 appliquée - **Backend :** Tous modèles à jour - **Frontend :** UI optimisée, Proxmox + batterie affichés - **Docker :** Nécessite restart pour charger nouveaux fichiers --- ## 📞 Contact / Questions Si reprise de développement, points à vérifier : 1. **La migration 017 a-t-elle été appliquée ?** ```bash sqlite3 /home/gilles/projects/serv_benchmark/backend/data/data.db "PRAGMA table_info(hardware_snapshots);" | grep -i proxmox ``` 2. **Le script bench.sh est-il en v1.5.0 ?** ```bash grep "BENCH_SCRIPT_VERSION" /home/gilles/projects/serv_benchmark/scripts/bench.sh ``` 3. **Les containers Docker sont-ils à jour ?** ```bash docker restart linux_benchtools_backend linux_benchtools_frontend ``` --- **Session terminée avec succès** ✨ Tous les objectifs ont été atteints : - Détection Proxmox opérationnelle - UI optimisée - Batterie affichée - Documentation complète Le système est prêt à détecter Proxmox sur le prochain benchmark ! 🚀