addon
This commit is contained in:
310
docs/AJOUT_CHAMPS_MANQUANTS.md
Executable file
310
docs/AJOUT_CHAMPS_MANQUANTS.md
Executable file
@@ -0,0 +1,310 @@
|
||||
# Ajout des Champs Manquants - 2025-12-14
|
||||
|
||||
## 🎯 Objectif
|
||||
|
||||
Ajouter les 2 champs identifiés comme **collectés mais non stockés** dans la base de données :
|
||||
|
||||
1. **`bios_vendor`** - Fabricant du BIOS (ex: "American Megatrends Inc.")
|
||||
2. **`wake_on_lan`** - Support Wake-on-LAN des interfaces réseau (true/false)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Champ #1 : `bios_vendor`
|
||||
|
||||
### Analyse Initiale
|
||||
|
||||
**Collecté** : ✅ Oui - ligne 491 de [scripts/bench.sh](scripts/bench.sh#L491)
|
||||
```bash
|
||||
bios_vendor=$(sudo dmidecode -s bios-vendor 2>/dev/null || echo "Unknown")
|
||||
```
|
||||
|
||||
**Envoyé dans JSON** : ✅ Oui - ligne 505
|
||||
```json
|
||||
{
|
||||
"motherboard": {
|
||||
"bios_vendor": "Gigabyte Technology Co., Ltd."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Stocké en base** : ❌ Non - Colonne absente du schema SQLite
|
||||
|
||||
### Modifications Appliquées
|
||||
|
||||
#### 1. Modèle SQLAlchemy
|
||||
|
||||
**Fichier** : [backend/app/models/hardware_snapshot.py](backend/app/models/hardware_snapshot.py#L70)
|
||||
|
||||
```python
|
||||
# Ajout ligne 70
|
||||
bios_vendor = Column(String(100), nullable=True)
|
||||
```
|
||||
|
||||
#### 2. Schema Pydantic
|
||||
|
||||
**Fichier** : [backend/app/schemas/hardware.py](backend/app/schemas/hardware.py#L103)
|
||||
|
||||
```python
|
||||
class MotherboardInfo(BaseModel):
|
||||
vendor: Optional[str] = None
|
||||
model: Optional[str] = None
|
||||
bios_vendor: Optional[str] = None # ← AJOUTÉ
|
||||
bios_version: Optional[str] = None
|
||||
bios_date: Optional[str] = None
|
||||
```
|
||||
|
||||
#### 3. API Mapping
|
||||
|
||||
**Fichier** : [backend/app/api/benchmark.py](backend/app/api/benchmark.py#L121)
|
||||
|
||||
```python
|
||||
snapshot.bios_vendor = hw.motherboard.bios_vendor if hw.motherboard and hasattr(hw.motherboard, 'bios_vendor') else None
|
||||
```
|
||||
|
||||
#### 4. Migration Base de Données
|
||||
|
||||
**Commande exécutée** :
|
||||
```bash
|
||||
docker compose exec backend python3 -c "
|
||||
import sqlite3
|
||||
conn = sqlite3.connect('/app/data/data.db')
|
||||
conn.execute('ALTER TABLE hardware_snapshots ADD COLUMN bios_vendor VARCHAR(100)')
|
||||
conn.commit()
|
||||
"
|
||||
```
|
||||
|
||||
**Résultat** :
|
||||
```
|
||||
✓ Colonne bios_vendor ajoutée avec succès
|
||||
```
|
||||
|
||||
**Vérification** :
|
||||
```sql
|
||||
PRAGMA table_info(hardware_snapshots);
|
||||
-- Résultat :
|
||||
45. bios_vendor VARCHAR(100) NULL
|
||||
```
|
||||
|
||||
### Test de Validation
|
||||
|
||||
Au prochain benchmark, la valeur sera stockée :
|
||||
|
||||
**Attendu** :
|
||||
```json
|
||||
{
|
||||
"motherboard": {
|
||||
"bios_vendor": "American Megatrends Inc." // ou "Gigabyte Technology Co., Ltd."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**En base** :
|
||||
```sql
|
||||
SELECT bios_vendor FROM hardware_snapshots WHERE device_id = 1 ORDER BY captured_at DESC LIMIT 1;
|
||||
-- Devrait retourner: "American Megatrends Inc."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Champ #2 : `wake_on_lan`
|
||||
|
||||
### Analyse Initiale
|
||||
|
||||
**Collecté** : ✅ Oui - ligne 667-676 de [scripts/bench.sh](scripts/bench.sh#L667-L676)
|
||||
```bash
|
||||
local wol_supported=""
|
||||
if [[ "$type" = "ethernet" && -x /usr/sbin/ethtool ]]; then
|
||||
wol=$(echo "$e" | awk -F: '/Wake-on:/ {gsub(/^[ \t]+/,"",$2); print $2}')
|
||||
if [[ -n "$wol" && "$wol" != "d" ]]; then
|
||||
wol_supported="true"
|
||||
fi
|
||||
fi
|
||||
```
|
||||
|
||||
**Envoyé dans JSON** : ✅ Oui - ligne 687
|
||||
```json
|
||||
{
|
||||
"network": {
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "eno1",
|
||||
"wake_on_lan": null // ou true/false si collecté
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Stocké en base** : ⚠️ Partiellement - Stocké dans `network_interfaces_json` (TEXT)
|
||||
|
||||
### Décision : Pas de Colonne Dédiée
|
||||
|
||||
**Raison** : Le champ `wake_on_lan` est **déjà stocké** dans le JSON `network_interfaces_json`.
|
||||
|
||||
**Exemple de contenu actuel** :
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "eno1",
|
||||
"type": "ethernet",
|
||||
"mac": "18:c0:4d:b5:65:74",
|
||||
"ip": "10.0.1.109",
|
||||
"speed_mbps": null,
|
||||
"driver": null,
|
||||
"wake_on_lan": null // ← Déjà présent !
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**Action requise** :
|
||||
- ✅ Aucune modification backend nécessaire
|
||||
- ⚠️ Le frontend peut déjà parser `network_interfaces_json` pour afficher cette info
|
||||
|
||||
### Mise à Jour Schema Pydantic (pour validation)
|
||||
|
||||
**Fichier** : [backend/app/schemas/hardware.py](backend/app/schemas/hardware.py#L84-L92)
|
||||
|
||||
```python
|
||||
class NetworkInterface(BaseModel):
|
||||
"""Network interface information"""
|
||||
name: str
|
||||
type: Optional[str] = None
|
||||
mac: Optional[str] = None
|
||||
ip: Optional[str] = None
|
||||
speed_mbps: Optional[int] = None
|
||||
driver: Optional[str] = None
|
||||
wake_on_lan: Optional[bool] = None # ← AJOUTÉ pour validation Pydantic
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Résumé des Modifications
|
||||
|
||||
| Champ | Collecté | Envoyé JSON | Stocké DB | Action |
|
||||
|-------|----------|-------------|-----------|--------|
|
||||
| **bios_vendor** | ✅ | ✅ | ❌ → ✅ | **Colonne ajoutée** |
|
||||
| **wake_on_lan** | ✅ | ✅ | ⚠️ (JSON) | **Schema Pydantic mis à jour** |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Fichiers Modifiés
|
||||
|
||||
### Backend
|
||||
|
||||
1. **[backend/app/models/hardware_snapshot.py](backend/app/models/hardware_snapshot.py)**
|
||||
- Ligne 70 : Ajout colonne `bios_vendor`
|
||||
|
||||
2. **[backend/app/schemas/hardware.py](backend/app/schemas/hardware.py)**
|
||||
- Ligne 103 : Ajout `bios_vendor` à `MotherboardInfo`
|
||||
- Ligne 92 : Ajout `wake_on_lan` à `NetworkInterface`
|
||||
|
||||
3. **[backend/app/api/benchmark.py](backend/app/api/benchmark.py)**
|
||||
- Ligne 121 : Mapping `bios_vendor` vers DB
|
||||
|
||||
4. **[backend/migrations/add_bios_vendor.sql](backend/migrations/add_bios_vendor.sql)**
|
||||
- Script SQL de migration (pour référence)
|
||||
|
||||
### Base de Données
|
||||
|
||||
```sql
|
||||
-- Colonne ajoutée
|
||||
ALTER TABLE hardware_snapshots ADD COLUMN bios_vendor VARCHAR(100);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validation Finale
|
||||
|
||||
### Test 1 : Vérifier bios_vendor dans DB
|
||||
|
||||
```bash
|
||||
# Lancer un nouveau benchmark
|
||||
cd /home/gilles/Documents/vscode/serv_benchmark/scripts
|
||||
sudo bash bench.sh
|
||||
|
||||
# Vérifier en base
|
||||
docker compose exec backend python3 -c "
|
||||
import sqlite3
|
||||
conn = sqlite3.connect('/app/data/data.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('SELECT bios_vendor, bios_version FROM hardware_snapshots ORDER BY captured_at DESC LIMIT 1')
|
||||
print(cursor.fetchone())
|
||||
"
|
||||
```
|
||||
|
||||
**Résultat attendu** :
|
||||
```
|
||||
('American Megatrends Inc.', 'F65e')
|
||||
```
|
||||
|
||||
### Test 2 : Vérifier wake_on_lan dans JSON
|
||||
|
||||
```bash
|
||||
# Requête API
|
||||
curl -s http://10.0.0.50:8007/api/devices/1 | jq '.hardware_snapshots[0].network_interfaces_json' | jq '.[0].wake_on_lan'
|
||||
```
|
||||
|
||||
**Résultat attendu** :
|
||||
```json
|
||||
null // ou true/false si ethtool a pu le détecter
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes Techniques
|
||||
|
||||
### Pourquoi wake_on_lan n'est pas en colonne dédiée ?
|
||||
|
||||
1. **Donnée par interface** : Chaque interface réseau peut avoir un statut WoL différent
|
||||
2. **Déjà dans JSON** : Stocké dans `network_interfaces_json` avec les autres propriétés
|
||||
3. **Peu utilisé en requêtes** : Pas besoin d'indexation SQL pour ce champ
|
||||
4. **Flexibilité** : Permet d'ajouter d'autres propriétés réseau sans migration
|
||||
|
||||
### Pourquoi bios_vendor mérite une colonne ?
|
||||
|
||||
1. **Donnée unique par device** : Une seule valeur par snapshot
|
||||
2. **Filtrabilité** : Peut être utile pour filtrer/grouper par fabricant BIOS
|
||||
3. **Cohérence** : Suit le pattern de `bios_version` et `bios_date` (déjà en colonnes)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines Étapes (Optionnel)
|
||||
|
||||
### Frontend : Afficher bios_vendor
|
||||
|
||||
**Fichier** : `frontend/js/device_detail.js`
|
||||
|
||||
**Zone** : Section "Carte mère et BIOS" (ligne ~95-107)
|
||||
|
||||
**Ajout suggéré** :
|
||||
```javascript
|
||||
const biosVendor = cleanValue(snapshot.bios_vendor);
|
||||
if (biosVendor !== 'N/A') {
|
||||
motherboardHTML += `<p><strong>Fabricant BIOS :</strong> ${biosVendor}</p>`;
|
||||
}
|
||||
```
|
||||
|
||||
### Frontend : Afficher wake_on_lan
|
||||
|
||||
**Fichier** : `frontend/js/device_detail.js`
|
||||
|
||||
**Zone** : Section "Réseau" (après affichage des interfaces)
|
||||
|
||||
**Ajout suggéré** :
|
||||
```javascript
|
||||
const interfaces = JSON.parse(snapshot.network_interfaces_json || '[]');
|
||||
interfaces.forEach(iface => {
|
||||
// ... affichage existant ...
|
||||
if (iface.wake_on_lan !== null) {
|
||||
const wolStatus = iface.wake_on_lan ? '✅ Activé' : '❌ Désactivé';
|
||||
networkHTML += `<p><strong>Wake-on-LAN :</strong> ${wolStatus}</p>`;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Document créé le** : 2025-12-14 à 10h00
|
||||
**Version backend** : 1.2.0
|
||||
**Statut** : ✅ Migration appliquée, backend redémarré
|
||||
**Prochaine action** : Lancer un benchmark pour valider le stockage de `bios_vendor`
|
||||
Reference in New Issue
Block a user