docs: review Monitor documentation in all seven translations

This commit is contained in:
Jonatan
2026-10-17 15:08:53 +02:00
parent ce1a3de719
commit dace78214a
209 changed files with 43788 additions and 1942 deletions
@@ -0,0 +1,396 @@
{
"meta": {
"title": "Authentification du tableau de bord Proxmox — 2FA, jetons API, profil, proxy inverse | ProxMenux Monitor",
"description": "Accès et protection de ProxMenux Monitor : premier démarrage, mot de passe avec nom et avatar, profil, TOTP 2FA, jetons API pour les scripts, HTTPS, exemples Nginx/Caddy/Traefik, journal d’audit et jail Fail2Ban facultative.",
"ogTitle": "Authentification Proxmox — 2FA, jetons API, proxy inverse",
"ogDescription": "Protégez ProxMenux Monitor avec mot de passe, TOTP 2FA, jetons API, HTTPS, exemples de proxy inverse et jail Fail2Ban facultative.",
"twitterTitle": "Authentification du tableau de bord Proxmox | ProxMenux Monitor",
"twitterDescription": "Mot de passe + TOTP 2FA, jetons API, HTTPS, Nginx/Caddy/Traefik et journal d'audit."
},
"header": {
"title": "Accès et authentification",
"description": "Accès au tableau de bord, premier démarrage et couches de protection : mot de passe et TOTP, sessions JWT, jetons API, HTTPS, proxy inverse, Secure Gateway et jail Fail2Ban facultative.",
"section": "Moniteur ProxMenux"
},
"intro": {
"title": "L’authentification est facultative",
"body": "Au premier lancement, le tableau de bord affiche la boîte de dialogue <em>« Protéger votre tableau de bord ? »</em>, avec les boutons <strong>Oui, définir un mot de passe</strong> et <strong>Non, continuer sans protection</strong>. La seconde option laisse les points d’accès de l’API ouverts sur TCP 8008 : cela peut convenir à un réseau local de laboratoire isolé, mais reste dangereux ailleurs. L’authentification à deux facteurs (2FA) <strong>ne fait pas</strong> partie de ce choix initial ; elle se configure ensuite dans <strong>l’onglet Sécurité</strong>, après la définition d’un mot de passe."
},
"reaching": {
"heading": "Atteindre le tableau de bord",
"intro": "Le ProxMenux Monitor se lie au <code>0.0.0.0:8008</code>. Il y a trois façons communes d'y parvenir:",
"outro": "L’accès direct correspond à l’unité systemd par défaut. Le proxy inverse et Secure Gateway sont décrits ci-dessous. Les IP de <code>X-Forwarded-For</code> nécessitent PROXMENUX_TRUST_PROXY=1 et un proxy que vous contrôlez. <code>X-Forwarded-Proto</code> ou <code>X-Forwarded-Host</code> seuls n’activent pas cette confiance ; le frontend construit les URL API depuis l’origine du navigateur."
},
"firstLaunch": {
"heading": "Premier démarrage",
"intro": "La première fois que vous ouvrez le tableau de bord, le frontend appelle <code>GET /api/auth/status</code>. Si la configuration auth n'a jamais été écrite (<code>configured: false</code>), une boîte de dialogue unique s'affiche intitulée <em>\"Protect Your Dashboard?\"</em> avec deux choix :",
"imageAlt": "Dialogue initial « Protéger votre tableau de bord ? », avec choix de définir un mot de passe ou de continuer sans protection",
"imageCaption": "Choix initial de protection par mot de passe ou non. Réapparaît après une installation neuve ou la désactivation de l’authentification dans les paramètres.",
"headerButton": "Bouton",
"headerWhat": "Ce qui se passe",
"headerApi": "Appel API",
"rows": [
{
"button": "Oui, configurer le mot de passe",
"what": "Ouvre un formulaire avec identifiant et mot de passe obligatoires, plus un <em>nom d’affichage</em> et une <em>image d’avatar</em> facultatifs. Active l’authentification dans <code>auth.json</code> avec <code>enabled: true</code> et renvoie un JWT pour vous connecter. Le profil facultatif est enregistré par des appels ultérieurs, décrits ci-dessous.",
"api": "POST /api/auth/setup"
},
{
"button": "Non, continuez sans protection",
"what": "Définit <code>declined: true</code> dans <code>auth.json</code>. Les points d’accès API restent ouverts jusqu’à l’activation de la protection dans les paramètres.",
"api": "POST /api/auth/skip"
}
],
"twofaCalloutTitle": "2FA est configuré plus tard, pas ici",
"twofaCalloutBody": "Le dialogue initial concerne seulement la protection par mot de passe. L’<strong>authentification à deux facteurs (TOTP)</strong> se configure ensuite dans <strong>l’onglet Sécurité</strong>, une fois connecté par mot de passe. Le guide complet suit plus bas.",
"createTitle": "Création du premier utilisateur",
"createIntro": "Cliquer sur <em>Oui, définir un mot de passe</em> ouvre un formulaire pour créer le compte et renseigner le profil facultatif. L’avatar peut ainsi apparaître dès l’enregistrement. Les champs :",
"headerField": "Champ",
"headerRequired": "Requis",
"headerNotes": "Remarques",
"fieldRows": [
{
"field": "Nom d'utilisateur",
"required": "Oui",
"notes": "Identifiant de connexion. Non modifiable depuis l’interface ; il faut éditer <code>auth.json</code> directement."
},
{
"field": "Mot de passe",
"required": "Oui",
"notes": "Au moins 10 caractères, issus d’au moins 3 des 4 catégories : minuscules, majuscules, chiffres, symboles. Les mots de passe évidents comme <code>password</code>, <code>12345678</code> et <code>proxmenux</code> sont refusés. Les mêmes règles sont imposées côté serveur : curl ne permet pas de contourner le contrôle."
},
{
"field": "Nom d'affichage",
"required": "Non",
"notes": "Nom affiché dans le menu de l’en-tête et le profil. Sans valeur, le nom d’utilisateur est repris. Modifiable ensuite via <strong>Avatar → Voir le profil</strong>."
},
{
"field": "Image Avatar",
"required": "Non",
"notes": "PNG, JPEG, WebP ou GIF jusqu'à 2 MB. Rendu comme un cercle dans l'en-tête et sur la page de profil. Lorsque vide, l'en-tête affiche la première lettre du nom d'affichage (ou nom d'utilisateur) sur un cercle coloré. Peut être téléchargé, remplacé ou supprimé plus tard de la page de profil."
}
],
"createImageAlt": "Formulaire de création du compte : identifiant et mot de passe obligatoires, nom d’affichage et avatar facultatifs",
"createImageCaption": "Formulaire du premier démarrage. Sans nom d’affichage ni avatar, le compte est créé et l’en-tête affiche une lettre dans un cercle.",
"saveCalloutTitle": "Un enregistrement, jusqu’à trois appels API",
"saveCalloutBody": "Le formulaire envoie d’abord <code>POST /api/auth/setup</code> avec identifiant et mot de passe. Le JWT reçu sert ensuite à <code>PUT /api/auth/profile</code> pour le nom et à <code>POST /api/auth/profile/avatar</code> pour l’image, si renseignés. Une erreur de profil n’annule pas le compte : vous pourrez compléter le profil plus tard.",
"avatarTitle": "Menu et page de profil Avatar",
"avatarBody1": "Une fois l’authentification configurée, l’avatar apparaît en haut à droite près du choix du thème. Son menu mène au profil et à Sécurité, avec l’action <strong>Se déconnecter</strong>. La déconnexion est aussi disponible dans Sécurité.",
"avatarBody2": "Le profil affiche l’avatar, le nom d’utilisateur en lecture seule et le nom d’affichage modifiable. Les ajouts, remplacements et suppressions d’avatar sont atomiques ; l’en-tête s’actualise automatiquement après réussite. Le formulaire initial et le profil utilisent les mêmes points d’accès décrits ci-dessous.",
"profileImageAlt": "Profil avec aperçu de l’avatar, boutons Ajouter / Remplacer / Supprimer, identifiant en lecture seule et nom d’affichage modifiable",
"profileImageCaption": "Page de profil dédiée. Le nom d’utilisateur est en lecture seule ; le nom d’affichage et l’avatar sont modifiables ici sans passer par Sécurité.",
"headerEndpoint": "Point d’accès",
"headerEpWhat": "Ce qu'il fait",
"endpointRows": [
{
"endpoint": "GET /api/auth/profile",
"what": "Renvoie le nom d’utilisateur, le nom d’affichage et l’état de l’avatar (<code>has_avatar</code>, <code>avatar_mtime</code>)."
},
{
"endpoint": "PUT /api/auth/profile",
"what": "Modifie le nom d’affichage. Corps de la requête : <code>'{' \"display_name\": \"...\" '}'</code>."
},
{
"endpoint": "GET /api/auth/profile/avatar",
"what": "Renvoie l’image d’avatar en PNG / JPEG / WebP / GIF avec le type de contenu adapté. Nécessite l’en-tête Bearer ; le frontend récupère un blob et crée une URL d’objet locale pour l’afficher."
},
{
"endpoint": "POST /api/auth/profile/avatar",
"what": "Charge un nouvel avatar (max. 2 MB). Le type de contenu doit correspondre au fichier. L'ancien avatar est remplacé atomiquement."
},
{
"endpoint": "DELETE /api/auth/profile/avatar",
"what": "Supprime l’avatar. L’en-tête affiche à nouveau une initiale dans un cercle coloré."
}
],
"reversibleTitle": "Vous pouvez activer la protection plus tard",
"reversibleBody": "Après <em>Non, continuer sans protection</em>, le dialogue ne réapparaît plus. Activez l’authentification dans <strong>l’onglet Sécurité</strong> ou modifiez <code>/root/.config/proxmenux-monitor/auth.json</code>, retirez l’indicateur <code>declined</code> et redémarrez le service."
},
"password": {
"heading": "Authentification du mot de passe",
"intro": "Une fois la protection configurée, les appels API protégés nécessitent un JWT dans <code>Authorization: Bearer &lt;token&gt;</code> :",
"items": [
"<strong>Jeton de session :</strong> valable 24 heures, émis par <code>POST /api/auth/login</code>.",
"<strong>Jeton API pour les intégrations :</strong> valable 365 jours, émis par <code>POST /api/auth/generate-api-token</code>. Voir la section suivante."
],
"loginImageAlt": "Écran de connexion affiché après la configuration de l'authentification — champs nom d'utilisateur et mot de passe",
"loginImageCaption": "Une fois l'authentification configurée, chaque visite au tableau de bord commence ici. Avec 2FA activé, l'écran demande le code à chiffres 6 dans une deuxième étape après l'acceptation du mot de passe.",
"loginFlowTitle": "Flux de connexion",
"twofaIntro": "Avec 2FA, le premier appel renvoie <code>requires_totp: true</code>. Répétez-le avec le code à six chiffres :",
"publicTitle": "Accès public et sondes protégées",
"publicIntro": "La connexion et son état sont publics. La création du compte reste possible tant qu’aucun identifiant et mot de passe ne sont enregistrés, même après un refus de protection. Les données système exigent une authentification lorsque la protection est active :",
"publicItems": [
"<code>/api/auth/login</code> et <code>/api/auth/status</code> sont publics. <code>/api/auth/setup</code> crée le premier compte et refuse d’écraser des identifiants existants.",
"<code>/api/system-info</code> est un endpoint public d’informations système légères, dont <code>health.status</code>. Il n’exige pas de jeton. /api/auth/status est également public et permet de vérifier la disponibilité."
],
"cryptoTitle": "Cryptographie et stockage",
"cryptoIntro": "ProxMenux Monitor est open source — rien de tout cela n'est secret. Documenter la pile ici explicitement est un choix délibéré: les opérateurs qui stockent des identifiants sur leur hôte méritent de savoir comment ces identifiants sont protégés avant de décider de leur faire confiance. Les algorithmes ci-dessous sont les mêmes que le code utilisé dans <code>scripts/auth_manager.py</code>; cette section est un contrat, pas une promesse de marketing.",
"headerAsset": "Élément",
"headerAlgo": "Algorithme",
"headerWhere": "Emplacement",
"cryptoRows": [
{
"asset": "Mot de passe",
"algorithm": "PBKDF2-HMAC-SHA256 avec un sel aléatoire par mot de passe et un taux d'itération élevé (base de référence de l'OWASP 2023+). Conservé comme <code>pbkdf2_sha256$&lt;iters&gt;$&lt;salt&gt;$&lt;hash&gt;</code>.",
"where": "<code>auth.json</code> → <code>password_hash</code>"
},
{
"asset": "Séance / API JWT",
"algorithm": "Signature HS256 avec un secret propre à l’installation, généré au premier démarrage (<code>secrets.token_urlsafe</code>, ≥48 octets). Les jetons contiennent <code>iss=proxmenux-monitor</code> et <code>aud=api</code> ; chaque requête vérifie la signature avec le secret actuel.",
"where": "Secret: <code>auth.json</code> → <code>jwt_secret</code>. JWT lui-même: seulement sur le client."
},
{
"asset": "Métadonnées de jeton API",
"algorithm": "Le SHA-256 du JWT est conservé avec l’empreinte <code>signed_with</code> du <code>jwt_secret</code> qui l’a signé. Cela permet d’afficher les métadonnées et de repérer les jetons affectés par un changement de secret.",
"where": "<code>auth.json</code> → <code>api_tokens[]</code>"
},
{
"asset": "Secret TOTP de 2FA",
"algorithm": "TOTP standard (RFC 6238), avec secret encodé en base32. Les huit codes de récupération sont à usage unique et conservés sous forme de hachages SHA-256.",
"where": "<code>auth.json</code> → <code>totp_secret</code> + <code>backup_codes[]</code>"
},
{
"asset": "Révocations",
"algorithm": "Lors d’une révocation, le SHA-256 du jeton rejoint une liste de refus consultée à chaque vérification. Un cache mémoire d’environ 30 s évite des lectures disque répétées.",
"where": "<code>auth.json</code> → <code>revoked_tokens[]</code>"
}
],
"authJsonTitle": "auth.json — ce qu'il contient et comment il est protégé",
"authJsonBody": "Les données d’authentification se trouvent dans <code>/root/.config/proxmenux-monitor/auth.json</code>, mode <code>0600</code>, propriétaire <code>root</code>. Le fichier contient des <em>hachages</em> PBKDF2 et des <em>secrets cryptographiques</em> (<code>jwt_secret</code>, <code>totp_secret</code>), jamais le mot de passe en clair. Chiffrez les destinations de sauvegarde ou de réplication et n’ajoutez jamais ce fichier au contrôle de version.",
"rotateTitle": "La rotation de jwt_secret invalide tous les JWT existants",
"rotateBody": "Si <code>auth.json</code> est recréé ou restauré avec un autre secret, <code>jwt_secret</code> change. Les anciens JWT de session et d’API échouent alors avec « Invalid or expired token ». L’interface affiche <strong>Invalide — régénérer</strong> pour les jetons concernés. Révoquez-les et remplacez-les aussi dans Home Assistant, les scripts et les autres clients.",
"recoverTitle": "Récupération d'un mot de passe perdu",
"recoverIntro": "Il n'y a pas de flux \"mot de passe oublié\" en ligne — par conception, puisque le tableau de bord fonctionne sur le propre hôte de l'opérateur et le chemin de récupération est l'accès shell à cet hôte. ProxMenux envoie une réinitialisation guidée dans le menu de configuration afin que vous n'ayez pas à éditer manuellement <code>auth.json</code>:",
"survivesTitle": "Ce qui survit à la réinitialisation",
"survivesBody": "La connexion interactive est effacée, mais <code>jwt_secret</code> et les <code>api_tokens</code> enregistrés sont conservés. Home Assistant et les autres scripts gardent leurs jetons. Pour repartir entièrement de zéro avec un nouveau secret, supprimez <code>auth.json</code> et redémarrez le service : tous les anciens jetons deviennent invalides.",
"physicalTitle": "Préalable d'accès physique",
"physicalBody": "Cette méthode exige un <strong>shell root sur l’hôte</strong>. Quiconque exécute <code>menu</code> en root contrôle déjà la machine ; la réinitialisation n’ajoute aucun privilège. Le mot de passe Monitor ne protège donc pas l’hôte contre une personne ayant déjà cet accès root."
},
"twofa": {
"heading": "Authentification à deux facteurs (TOTP)",
"intro": "2FA ajoute un deuxième facteur en plus de votre mot de passe : un code à chiffres 6 qui tourne chaque 30 secondes, généré sur un téléphone ou un gestionnaire de mots de passe que vous contrôlez. Même si quelqu'un obtient le mot de passe, il ne peut toujours pas se connecter sans le code de votre appareil. ProxMenux Monitor implémente le protocole standard <strong>TOTP</strong> (RFC 6238), donc toute application d'authentification fonctionne.",
"pickTitle": "Choisir une application d'authentification",
"pickIntro": "Vous pouvez utiliser une application TOTP existante. Voici des options courantes : certaines gratuites, d’autres sur abonnement. Les plateformes et les méthodes de sauvegarde diffèrent aussi.",
"headerApp": "Application",
"headerPlatforms": "Plateformes",
"headerAppNotes": "Remarques",
"apps": [
{
"name": "Google Authenticator",
"href": "https://safety.google/authentication/",
"platforms": "iOS, Android",
"notes": "La valeur par défaut pour de nombreux utilisateurs. Sauvegarde en nuage optionnelle Google-compte."
},
{
"name": "Microsoft Authenticator",
"href": "https://www.microsoft.com/en-us/security/mobile-authenticator-app",
"platforms": "iOS, Android",
"notes": "Sauvegarde via un compte Microsoft. Gère aussi les notifications push Microsoft utilisées au travail."
},
{
"name": "Authy",
"href": "https://authy.com/",
"platforms": "iOS, Android",
"notes": "Synchronisation chiffrée entre appareils. L’application de bureau n’est plus prise en charge depuis le 19 mars 2024."
},
{
"name": "Apple Passwords",
"href": "https://support.apple.com/guide/passwords/welcome/mac",
"platforms": "iOS, iPadOS, macOS, visionOS, Windows (via iCloud)",
"notes": "Intégrée aux systèmes Apple ; application Passwords distincte depuis iOS 18 / macOS Sequoia. Conserve TOTP avec le mot de passe et synchronise via le trousseau iCloud."
},
{
"name": "Bitwarden",
"href": "https://bitwarden.com/",
"platforms": "iOS, Android, bureau, navigateur",
"notes": "Code source ouvert. TOTP peut être conservé avec les mots de passe dans le coffre. C’est pratique, mais cela ne les sépare pas sur un second appareil."
},
{
"name": "1Password",
"href": "https://1password.com/",
"platforms": "iOS, Android, bureau, navigateur",
"notes": "Comme Bitwarden : TOTP intégré au coffre de mots de passe. Sur abonnement."
},
{
"name": "Aegis Authenticator",
"href": "https://getaegis.app/",
"platforms": "Android",
"notes": "Code source ouvert. Sauvegarde locale chiffrée sous votre contrôle. Aucun cloud ni compte requis."
},
{
"name": "Raivo OTP",
"href": "https://raivo-otp.com/",
"platforms": "iOS, macOS",
"notes": "Code source ouvert. Synchronisation iCloud facultative. Une option de l’écosystème Apple comparable à Aegis."
},
{
"name": "Ente Auth",
"href": "https://ente.io/auth/",
"platforms": "iOS, Android, bureau, web",
"notes": "Code source ouvert. Synchronisation cloud entre appareils avec chiffrement de bout en bout."
},
{
"name": "2FAS",
"href": "https://2fas.com/",
"platforms": "iOS, Android, extension du navigateur",
"notes": "Code source ouvert. Sauvegarde cloud chiffrée facultative ; l’extension de navigateur peut remplir les codes automatiquement."
},
{
"name": "FreeOTP+",
"href": "https://github.com/helloworld1/FreeOTPPlus",
"platforms": "Android",
"notes": "Fork libre de FreeOTP pour Android, avec importation et exportation. Aucun compte requis."
}
],
"backupTitle": "Pourquoi les sauvegardes comptent",
"backupBody": "Si vous perdez l’appareil, utilisez un code de récupération conservé ou restaurez une sauvegarde préparée auparavant. Synchronisation cloud et exports varient selon l’application : vérifiez que votre méthode restaure bien les secrets TOTP. L’accès root à l’hôte permet aussi une récupération, décrite ci-dessous. Gardez une sauvegarde distincte et sécurisée.",
"setupTitle": "Configuration étape par étape depuis le tableau de bord",
"setupImageAlt": "Écran de configuration 2FA avec code QR et codes de sauvegarde",
"setupImageCaption": "Le dialogue 2FA montre un QR code, le secret Base32 pour la saisie manuelle et huit codes de récupération à usage unique. Copiez-les avant de fermer : ils ne seront plus affichés.",
"setupSteps": [
"<strong>Installez l'application authentificateur sur votre téléphone</strong> (ou ouvrez votre gestionnaire de mots de passe). Une des applications du tableau ci-dessus. Vous n'avez besoin de le faire qu'une seule fois — la même application contiendra des codes pour chaque service que vous protégez.",
"<strong>Se connecter au tableau de bord</strong> avec votre nom d'utilisateur et votre mot de passe.",
"<strong>Ouvrez l’onglet Sécurité</strong>, puis <strong>Activer 2FA</strong>. Le dialogue montre le QR code, le secret Base32 et huit codes de récupération.",
"<strong>Ajouter l'entrée à l'application authentificateur:</strong>",
"<strong>Conservez les codes de récupération.</strong> Gardez les huit dans un gestionnaire de mots de passe, une note chiffrée ou une copie papier sécurisée. Chacun sert une fois si l’application est indisponible.",
"<strong>Confirmez avec le code actuel à six chiffres</strong> de l’application dans le champ « Code de vérification », puis validez. Le code change toutes les 30 secondes ; s’il expire pendant la saisie, utilisez le suivant.",
"<strong>Terminé.</strong> 2FA est actif. La prochaine connexion demande d’abord le mot de passe, puis le code actuel à six chiffres."
],
"setupStep4Sub": [
"<em>Méthode simple :</em> dans l’application, choisissez <em>Ajouter un compte</em> → <em>Scanner un QR code</em>, puis visez le code affiché. L’entrée reçoit un nom comme <code>ProxMenux Monitor (your-username)</code> et affiche un code à six chiffres renouvelé toutes les 30 secondes.",
"<em>Alternative manuelle</em> si le scan est impossible, notamment sur le même téléphone : <em>Ajouter un compte</em> → <em>Saisir une clé de configuration</em>. Choisissez un nom comme <em>Proxmox Monitor</em>, collez le secret Base32, laissez le <em>Type</em> sur <em>Basé sur le temps</em> et enregistrez."
],
"testTitle": "Tester avant de déconnecter",
"testBody": "Gardez la session actuelle ouverte et testez une nouvelle connexion dans une fenêtre privée <em>immédiatement</em> après la configuration. Si le code échoue, vérifiez les horloges du serveur et du téléphone avant de fermer la session fonctionnelle. Si l’accès est perdu, utilisez un code de récupération ou modifiez <code>auth.json</code> depuis le shell de l’hôte.",
"lostTitle": "Authentificateur perdu",
"lostIntro": "Trois méthodes de récupération, de la moins intrusive à la plus intrusive :",
"lostItems": [
"<strong>Utilisez un code de récupération.</strong> Saisissez un des huit codes dans le champ TOTP. Il sert une fois ; les autres restent valides. Après connexion, reconfigurez 2FA dans les paramètres pour obtenir huit nouveaux codes.",
"<strong>Restaurer l'authentificateur à partir du cloud / sauvegarde.</strong> Si votre application a une synchronisation cloud (Google, Microsoft, Authy, Apple Passwords via iCloud Keychain, Ente, 2FAS) l'installe sur un nouvel appareil, se connecte et les entrées réapparaissent. Si votre application utilise un fichier d'exportation chiffré (Aegis, Raivo, FreeOTP+), installer l'application sur le nouvel appareil et importer le fichier.",
"<strong>Désactivez 2FA depuis le shell de l'hôte.</strong> Lorsque les options précédentes ne sont pas disponibles, modifiez <code>/root/.config/proxmenux-monitor/auth.json</code> sur l'hôte Proxmox (vous avez besoin de root SSH ou d'un accès à la console), définissez <code>totp_enabled</code> sur <code>false</code>, enregistrez et redémarrez le service :"
],
"lostShellOutro": "Vous pouvez vous connecter avec le nom d'utilisateur + mot de passe seulement, puis réactiver 2FA depuis Paramètres.",
"disableTitle": "Désactiver 2FA",
"disableBody": "Ouvrez <strong>Sécurité</strong> et choisissez <strong>Désactiver 2FA</strong>. <code>POST /api/auth/totp/disable</code> exige le mot de passe actuel et un code TOTP ou de récupération valide. Le secret TOTP et les codes sont effacés. Retirez aussi l’ancienne entrée de l’application.",
"rejectedTitle": "Le code à chiffres 6 est toujours rejeté",
"rejectedIntro": "TOTP dépend du temps : les horloges du serveur et du téléphone doivent différer de moins d’environ 30 s. Deux contrôles :",
"rejectedItems": [
"<strong>Téléphone :</strong> Paramètres → Date et heure → activer la synchronisation automatique / réseau.",
"<strong>Hôte Proxmox :</strong> <code>timedatectl status</code> doit afficher « System clock synchronized: yes ». Sinon, lancez <code>timedatectl set-ntp true</code> et attendez une minute."
],
"rejectedOutro": "Une fois les horloges synchronisées, le code est accepté dans la fenêtre de 30 secondes suivante."
},
"apiTokens": {
"heading": "Jetons API de longue durée",
"intro": "Les sessions expirent après 24 heures. Pour Homepage, Home Assistant, Grafana ou Uptime Kuma, créez un <strong>jeton API</strong> valable 365 jours. Ce JWT utilise le même secret de signature ; le champ <code>token_name</code> permet de le suivre et de le révoquer individuellement.",
"imageAlt": "Panneau de jetons API montrant la liste de jetons avec nom, préfixe, date de création et expiration",
"imageCaption": "Liste des jetons dans les paramètres : nom, préfixe avec quatre derniers caractères d’identification, dates de création et d’expiration, action de révocation.",
"generateTitle": "Générer un jeton",
"generateIntro": "Dans le tableau de bord:",
"generateSteps": [
"Ouvrez <strong>Sécurité → Jetons d’accès API</strong>.",
"Tapez un nom descriptif (<em>p.ex. \"Home Assistant\"</em>).",
"Entrez de nouveau votre mot de passe. Si 2FA est activé, aussi le code à chiffres 6 actuel.",
"Cliquez sur <strong>Générer le jeton</strong>. Il s’affiche <strong>une seule fois</strong> : copiez-le immédiatement."
],
"generateCli": "Depuis la ligne de commande :",
"useTitle": "Utiliser un jeton",
"revokeTitle": "Révoquer un jeton",
"revokeBody": "Chaque ligne propose <strong>Révoquer</strong>, qui ajoute le hachage à <code>revoked_tokens</code> dans <code>auth.json</code>. Le jeton est refusé dès la requête suivante.",
"cheatTitle": "Aide-mémoire de sécurité des jetons",
"cheatItems": [
"Gardez les jetons dans le stockage de secrets de l’intégration : Homepage <code>secrets.yaml</code>, Home Assistant <code>!secret</code>, variables d’environnement. Ne les ajoutez jamais à Git.",
"Un jeton par intégration, portant son nom. Révoquez-le lors du retrait de cette intégration.",
"Rotation tous les 6–12 mois. L'expiration est une limite dure, pas une recommandation."
],
"outro": "Conseils de stockage et exemples : <apiLink>Référence API → Gestion des jetons</apiLink> et <intLink>Intégrations</intLink>."
},
"https": {
"heading": "HTTPS",
"intro": "Deux chemins vers TLS:",
"items": [
"<strong>Proxy inverse recommandé.</strong> Terminez TLS sur Nginx / Caddy / Traefik et transmettez HTTP au processus Flask sur le port 8008. Exemples ci-dessous.",
"<strong>HTTPS direct dans l’AppImage.</strong> Configurez un certificat via <code>POST /api/ssl/configure</code> (interface : <strong>Paramètres → SSL</strong>). HTTPS utilise <code>gevent.pywsgi</code> avec son gestionnaire standard ; flask-sock gère WebSocket pour WSS. Les chemins des certificats sont enregistrés dans la configuration SSL."
],
"calloutTitle": "Limites directes de HTTPS",
"calloutBody": "Monitor peut utiliser un certificat géré par Proxmox ou des fichiers personnalisés. Il n’émet pas lui-même de certificats ACME. Pour l’émission et le renouvellement automatiques, utilisez Proxmox ACME ou un proxy inverse Caddy, Traefik ou Nginx et veillez au chargement des certificats renouvelés."
},
"gateway": {
"heading": "Passerelle sécurisée (Tailscale)",
"intro": "Un proxy inverse permet l’accès distant. <strong>Secure Gateway</strong> évite d’exposer TCP 8008 : il déploie un LXC Alpine exécutant <a>Tailscale</a> comme routeur de sous-réseau. L’accès à l’IP LAN de l’hôte dépend des routes approuvées et des règles d’accès du tailnet.",
"calloutTitle": "Pourquoi c'est pratique",
"calloutBody": "Utilisez l’URL LAN <code>http://&lt;proxmox-lan-ip&gt;:8008</code> via la route approuvée. Les routeurs Tailscale utilisent SNAT par défaut : Monitor voit généralement l’IP LAN de la passerelle, et non l’IP <code>100.x.y.z</code> du client. Journaux et Fail2Ban identifient l’adresse source reçue par l’hôte.",
"deployBody": "Sur un écran, choisissez le stockage LXC, collez une clé Tailscale créée sur <a>login.tailscale.com/admin/settings/keys</a>, choisissez les sous-réseaux et déployez. Le LXC s’initialise en environ 30 secondes et rejoint le tailnet.",
"outro": "Déploiement, routes de sous-réseau, ACL Tailscale et mode Exit Node sont détaillés dans <link>Tableau de bord → Sécurité → Secure Gateway</link>, où se trouve aussi l’assistant. Cette page décrit l’accès."
},
"proxy": {
"heading": "Extraits de proxy inversés",
"intro": "Utilisez un <strong>nom d’hôte dédié</strong>, comme <code>monitor.example.com</code>, qui transmet au port 8008 de l’hôte Proxmox. Les exemples suivent ce modèle. Un sous-chemin comme <code>example.com/proxmenux-monitor/</code> exige des adaptations frontend et proxy ; retirer le préfixe ne suffit pas.",
"nginxTitle": "Nginx",
"caddyTitle": "Caddy",
"traefikTitle": "Traefik (étiquettes — Docker / Kubernetes)",
"subPathTitle": "Avancé : déploiement sous un sous-chemin",
"subPathBody": "Le frontend actuel n’a pas de base de sous-chemin configurée et construit ses appels API depuis la racine avec <code>/api/*</code>. Retirer un préfixe comme <code>example.com/proxmenux-monitor/</code> ne traite ni ces appels ni tous les fichiers frontend. Utilisez un nom d’hôte dédié. Un sous-chemin exige des changements coordonnés et des tests spécifiques."
},
"audit": {
"heading": "Registre des audits",
"intro": "Les échecs de connexion et avertissements de limitation sont écrits ligne par ligne dans <code>/var/log/proxmenux-auth.log</code>. Ce logger n’enregistre pas les connexions réussies :",
"outro": "Suivez le journal avec <code>tail -F /var/log/proxmenux-auth.log</code>. Une configuration ajoutée à <code>logrotate</code> permet sa rotation ; Monitor ne l’effectue pas lui-même."
},
"fail2ban": {
"heading": "Facultatif : jail Fail2Ban",
"calloutTitle": "Fail2Ban n'est pas livré avec le moniteur",
"calloutBody": "Fail2Ban n'est <strong>pas</strong> installé par ProxMenux Monitor lui-même. Installez-le via <link>Sécurité → Fail2Ban</link> dans le menu ProxMenux (ou avec le package Debian standard). Sans cela, le moniteur écrit toujours le journal d'audit ci-dessus ; il n'interdit tout simplement pas les récidivistes.",
"intro": "L’intégration ProxMenux fournit une jail <code>[proxmenux]</code> qui :",
"items": [
"Lit <code>/var/log/proxmenux-auth.log</code>.",
"Correspond au modèle <code>authentication failure; rhost=&lt;ip&gt;</code> avec un filtre dédié.",
"Interdit par défaut l'IP contrevenant au niveau du pare-feu du noyau.",
"Le hook Flask <code>before_request</code> compare les requêtes à la liste de blocage, mise en cache 30 s. Derrière un proxy inverse, le blocage par IP exige aussi PROXMENUX_TRUST_PROXY=1 et un proxy contrôlé qui définit des en-têtes fiables."
],
"outro": "Configuration, durée de blocage et déblocage : <link>Sécurité → Fail2Ban</link>."
},
"troubleshoot": {
"heading": "Dépannage",
"noScreenTitle": "L'écran du premier lancement n'apparaît jamais",
"noScreenBody": "L’authentification est déjà configurée (<code>configured: true</code>) ou a été ignorée. Pour recommencer :",
"noScreenOutro": "Cela efface l'état d'auth — aussi tous les secrets TOTP et les jetons API. Sauvegardez d'abord <code>auth.json</code> si vous avez des jetons que vous voulez garder.",
"tokenTitle": "HTTP 401 sur chaque demande d'un jeton API en service",
"tokenBody": "Les jetons ont expiré (limite 365 d) ou sont entrés dans la liste <code>revoked_tokens</code>. Générer un nouveau dans Paramètres et mettre à jour l'intégration. Pour vérifier :",
"tokenOutro": "Les jetons périmés ou révoqués retournent <code>'{'\"error\":\"Invalid or expired token\"'}'</code>.",
"no2faTitle": "Impossible de se connecter après avoir activé 2FA, aucun authentificateur à portée de main",
"no2faBody": "Utilisez un code de sauvegarde dans le champ TOTP. Si ceux-ci sont partis, modifiez <code>/root/.config/proxmenux-monitor/auth.json</code> à partir d'un shell hôte, définissez <code>totp_enabled</code> à <code>false</code>, redémarrez le service.",
"wsTitle": "Le proxy inverse fonctionne mais l'onglet terminal se déconnecte chaque minute",
"wsBody": "Délai d’inactivité WebSocket du proxy. Augmentez le délai de lecture (Nginx : <code>proxy_read_timeout 86400s</code> ; Traefik : <code>idleTimeout</code> du point d’entrée ou middleware). Pour Nginx, vérifiez <code>proxy_set_header Upgrade $http_upgrade</code> et <code>Connection \"upgrade\"</code>."
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Référence API → Gestion des jetons",
"href": "/docs/monitor/api",
"tail": " — créer, lister et révoquer les jetons API ; bonnes pratiques de sécurité et stockage des secrets."
},
{
"label": "Intégrations",
"href": "/docs/monitor/integrations",
"tail": " — Homepage, Home Assistant, Grafana / Prometheus, Uptime Kuma et exemples cURL."
},
{
"label": "Tableau de bord → Sécurité → Portail sécurisé",
"href": "/docs/monitor/dashboard/security",
"tail": " — déployer le LXC Tailscale pas à pas : routes de sous-réseau, ACL et mode Exit Node."
},
{
"label": "Sécurité → Fail2Ban",
"href": "/docs/security/fail2ban",
"tail": " — installer et configurer la jail facultative."
},
{
"label": "Paramètres → ProxMenux Monitor",
"href": "/docs/settings/proxmenux-monitor",
"tail": " — démarrer et arrêter le service systemd depuis la TUI ProxMenux."
}
]
}
}
@@ -0,0 +1,342 @@
{
"meta": {
"title": "Assistant IA Proxmox — OpenAI, Claude, Gemini, Groq, Ollama | ProxMenux Monitor",
"description": "L’assistant IA facultatif reformule les notifications Proxmox VE en langage clair. Six fournisseurs : OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter et Ollama. L’interface propose treize langues, trois niveaux de détail par canal, des instructions personnalisées avec une bibliothèque communautaire et un contexte incluant durée de fonctionnement, récurrence et données SMART.",
"ogTitle": "Assistant IA Proxmox — OpenAI, Claude, Gemini, Groq, Ollama",
"ogDescription": "Réécrire les notifications Proxmox VE en langage clair avec OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter ou Ollama local.",
"twitterTitle": "Assistant IA Proxmox | ProxMenux Monitor",
"twitterDescription": "Réécrire les notifications Proxmox VE en langage clair avec OpenAI, Anthropic, Gemini, Groq, OpenRouter ou Ollama local."
},
"header": {
"title": "Assistant IA",
"description": "La reformulation IA facultative transforme les modèles de notification admissibles en messages clairs : niveaux de détail par canal, treize langues dans l’interface, instructions personnalisées, bibliothèque communautaire publique et contexte enrichi. Les rapports <code>backup_complete</code> et <code>backup_fail</code> ignorent entièrement l’IA.",
"section": "Moniteur ProxMenux"
},
"intro": {
"title": "Désactivé par défaut, un seul interrupteur pour l’activer",
"body": "La reformulation IA est désactivée par défaut. Activez-la dans <em>Paramètres → Notifications → Avancé : amélioration IA</em>. Si l’enrichissement ou la reformulation échoue, le texte du modèle original est envoyé. Chaque reformulation a un délai maximal de 25 secondes ; au-delà, le modèle est utilisé sans attendre indéfiniment."
},
"howItWorks": {
"heading": "Comment ça marche",
"intro": "Les événements envoyés par Monitor suivent le même processus. La reformulation IA est une étape facultative entre le texte du modèle et l’envoi au canal. Un événement passe par quatre étapes :",
"steps": [
"<strong>Événement et modèle.</strong> Un événement provient d’un des six collecteurs. <code>notification_templates.py</code> le met en forme en texte brut structuré, qui serait envoyé sans reformulation IA.",
"<strong>Enrichissement du contexte.</strong> Le répartiteur ajoute les signaux pertinents selon l’événement : durée de fonctionnement pour les défaillances système critiques, fréquence des événements, données SMART pour les disques, correspondances dans la base des erreurs connues et lignes de journal.",
"<strong>Construction des instructions.</strong> Les instructions système combinent le modèle et les réglages du canal : langue, niveau de détail, règles emoji des <em>Messages enrichis</em> et suggestions IA si activées. En mode personnalisé, vos instructions remplacent tout le texte système. Le message utilisateur contient le texte du modèle et les blocs de contexte.",
"<strong>Appel au fournisseur.</strong> Groq, OpenAI, Anthropic, Gemini, Ollama ou OpenRouter renvoie un titre et un texte reformulés. Le répartiteur analyse la réponse, remplace ces contenus pour le canal et les transmet à son adaptateur d’envoi."
],
"notesIntro": "Trois détails à retenir avant de lire le reste de cette page:",
"notes": [
"<strong>L’IA ne crée pas d’événements.</strong> Chaque événement provient d’un signal réel : contrôle de santé, ligne de journal, webhook PVE, etc. Un modèle produit le texte avant son passage à l’IA, qui traduit et reformate sans surveiller le système.",
"<strong>L'IA fonctionne par canal.</strong> Telegram et Discord peuvent utiliser une brève réécriture tandis que l'email obtient un rapport détaillé — même événement, forme différente, tous à partir d'un seul appel de fournisseur par canal.",
"<strong>En cas d’échec, le modèle prend le relais.</strong> Si le fournisseur renvoie une erreur 5xx, dépasse le délai, produit une réponse incorrecte ou refuse la demande, le répartiteur journalise l’erreur et envoie le texte original du modèle pour ce canal."
]
},
"enabling": {
"heading": "Activer le panneau",
"intro": "La configuration IA se trouve en bas du panneau Notifications, dans l’onglet Paramètres, sous le bloc repliable <em>Avancé : amélioration IA</em>. Cliquez sur son titre pour l’ouvrir :",
"collapsedAlt": "En-tête replié des réglages IA avancés avec indicateur en chevron",
"collapsedCaption": "Replié par défaut ; un clic ouvre le panneau.",
"panelAlt": "Panneau IA ouvert avec interrupteur principal, fournisseur Google Gemini, clé API masquée, modèle gemini-2.5-flash, instructions par défaut, langue anglaise, détail par canal Telegram, Discord, Gotify et e-mail, suggestions IA et test de connexion",
"panelCaption": "Le panneau IA complet : chaque commande décrite dans cette page correspond à un des champs ci-dessus.",
"outro": "De haut en bas : interrupteur <em>Messages améliorés par IA</em>, choix du fournisseur et fenêtre d’information, clé API ou URL Ollama, liste des modèles chargée après saisie de la clé, mode <em>Par défaut</em> / <em>Personnalisé</em>, langue, détail par canal, <em>Suggestions IA</em> et bouton <em>Tester la connexion</em> qui envoie un message de test au fournisseur pour vérifier les identifiants."
},
"context": {
"heading": "Quel contexte l'IA reçoit",
"intro": "Avant que l'invite ne soit construite, le régulateur suit une routine d'enrichissement du contexte qui décide quels signaux supplémentaires sont pertinents à l'événement en question. Le but est de donner au LLM suffisamment d'informations pour produire un message utile, sans l'envahir (et votre portefeuille) avec du bruit qui ne s'applique pas. Cinq blocs contextuels peuvent être ajoutés au message utilisateur :",
"headerBlock": "Bloc",
"headerWhen": "Quand il est injecté",
"headerWhat": "Ce qu'il porte",
"rows": [
{
"block": "Durée de fonctionnement du système",
"when": "Uniquement pour les défaillances système critiques : <code>crash</code>, <code>panic</code>, <code>oom</code>, <code>kernel</code>, <code>split_brain</code>, <code>quorum_lost</code>, <code>node_offline</code>, <code>node_fail</code>, <code>system_fail</code>, <code>boot_fail</code>. Omis pour les erreurs de disque, avertissements et opérations courantes afin de limiter le texte des instructions.",
"what": "Une ligne telle que <code>System uptime: 14 days (stable system)</code>. Permet au LLM de distinguer les problèmes de démarrage des échecs de longue durée."
},
{
"block": "Fréquence des événements",
"when": "Toujours, quand le moniteur a vu la même empreinte digitale avant.",
"what": "Nombre d'occurrences, horodatage à première vue, étiquette de motif optionnelle (récurrent / unique / pic). Le LLM utilise cette expression pour dire « problème récurrent » par opposition à « première fois vu »."
},
{
"block": "Données SMART",
"when": "Seulement pour les événements liés au disque (le type d'événement contient <code>disk</code>, <code>smart</code>, <code>storage</code>, <code>io_error</code>, ou le corps mentionne <code>/dev/sd</code>, <code>ata</code>, <code>i/o error</code>).",
"what": "Sortie de <code>smartctl</code> pour l'appareil touché — santé globale (PASSED / FAILED) plus les attributs pertinents pour le mode de défaillance."
},
{
"block": "Base des erreurs connues",
"when": "Lorsque le contexte du corps ou du journal correspond à un modèle d'erreur spécifique à Proxmox envoyé avec le moniteur.",
"what": "Un bloc <code>KNOWN PROXMOX ERROR DETECTED</code> avec la cause reconnue et une solution précise. Les instructions demandent une traduction fidèle, sans reformuler la correction recommandée."
},
{
"block": "Registres",
"when": "Chaque fois que le collectionneur d'origine a capturé des lignes de journal pour l'événement (principalement l'observateur de journal et l'observateur des tâches).",
"what": "Extraits bruts de <code>journalctl</code>. L'invite indique à la LLM d'extraire les ID, les timestamps et les indices de cause racine, et d'ignorer les entrées non liées."
}
],
"afterBlocks": "Une fois ces blocs joints, le message utilisateur envoyé au LLM a cette forme :",
"calloutTitle": "Pas de télémétrie au-delà de l'événement lui-même",
"calloutBody": "Monitor envoie uniquement les informations disponibles pour l’événement courant : aucune télémétrie générale, série historique de métriques ou export d’inventaire. Les cinq blocs ci-dessus limitent ce qui quitte l’hôte lors d’une reformulation IA."
},
"tokens": {
"heading": "Jetons — ce qu'ils sont et comment ils sont consommés",
"intro1": "Les fournisseurs commerciaux facturent les <em>tokens</em>. Un token représente environ quatre caractères anglais ou trois quarts de mot. La phrase anglaise <em>\"Backup completed on storage local-bak\"</em> compte environ huit tokens. Dix lignes de journal peuvent représenter 200 à 400 tokens selon leur contenu technique.",
"intro2": "Deux choses sont facturées à chaque appel :",
"items": [
"<strong>Tokens d’entrée</strong> : instructions système et message utilisateur, avec gravité, titre, texte du modèle et contexte enrichi. Leur nombre dépend des instructions et de l’événement. Chaque canal reformulé peut consommer ses propres tokens ; les rapports de sauvegarde terminée ou échouée ignorent l’IA.",
"<strong>Tokens de sortie</strong> : la réponse du modèle. Monitor les limite avec <code>max_tokens</code>. Le plafond est une <em>limite</em>, pas une consommation fixe : pour 250 tokens produits avec un plafond de 1500, vous payez 250."
],
"capsIntro": "Ce sont les plafonds réels que le régulateur applique, pris directement à partir de <code>AI_DETAIL_TOKENS</code> dans <code>notification_templates.py</code>:",
"headerLevel": "Niveau de détail",
"headerCap": "Limite de sortie (tokens)",
"headerConsumption": "Consommation réelle typique",
"capRows": [
{
"level": "bref",
"cap": "500",
"consumption": "50-200 jetons de sortie pour les événements courts."
},
{
"level": "standard",
"cap": "1500",
"consumption": "200 à 700 tokens de sortie pour les événements habituels avec peu de contexte."
},
{
"level": "détaillé",
"cap": "3000",
"consumption": "500-2000 jetons de sortie pour les rapports de courriel complets avec les journaux et les tables SMART."
}
],
"customNote": "Le mode personnalisé fixe la sortie à 500 tokens, quel que soit le niveau de détail. Vous contrôlez les instructions ; le plafond évite les réponses trop longues.",
"sizingTitle": "Taille pratique",
"sizingBody": "Estimez la consommation : événements reformulés × canaux IA × tokens d’entrée et de sortie par appel. Exemple : 50 événements × un canal × (500 en entrée + 300 en sortie) = 40 000 tokens par jour. Les valeurs réelles dépendent du modèle, du contexte, du cache et des limites du fournisseur. <link>Détail par canal</link> explique comment utiliser <code>brief</code> pour le chat au lieu de <code>standard</code>, avec des e-mails détaillés."
},
"providers": {
"heading": "Fournisseurs d'IA",
"intro": "Six fournisseurs sont connectés au moniteur. Le menu déroulant du fournisseur dans l'interface utilisateur les montre tous; un bouton d'information à côté ouvre un modal avec une description d'une ligne pour chacun. Voici la référence complète, avec l'URL pour obtenir une clé API, la description affichée dans l'interface utilisateur et les notes pertinentes de la base de codes.",
"imageAlt": "Informations sur les fournisseurs d'IA modal énumérant les six fournisseurs supportés — Groq, OpenAI, Anthropic Claude, Google Gemini, Ollama, OpenRouter — chacun avec son icône et sa description en une seule ligne, et une note spéciale d'APIs compatibles OpenAI pour OpenAI",
"imageCaption": "La fenêtre de l’application : six fiches, une par fournisseur, avec les descriptions ci-dessous.",
"groq": {
"heading": "Groq",
"tagline": "Très rapide, généreux niveau libre (30 req/min). Idéal pour commencer.",
"items": [
"Clé API : <a>console.groq.com/keys</a>",
"Exemples de la liste de modèles fournie : <code>allam-2-7b</code>, <code>qwen/qwen3.8-27b</code>, <code>openai/gpt-oss-20b</code>, <code>groq/compound-mini</code>.",
"Recommandation fournie : <strong><code>openai/gpt-oss-20b</code></strong>. Vérifiez sa disponibilité pour votre compte avec le sélecteur du fournisseur et le test de connexion."
]
},
"openai": {
"heading": "OpenAI",
"tagline": "Norme de l'industrie. Très précis et largement utilisé.",
"items": [
"Clé API : <a>platform.openai.com/api-keys</a>",
"Exemples de la liste de modèles fournie : <code>gpt-4.1-nano</code>, <code>gpt-4.1-mini</code>, <code>gpt-4o-mini</code>, <code>gpt-4.1</code>, <code>gpt-4o</code>, <code>gpt-5-nano</code>.",
"Recommandation fournie : <strong><code>gpt-4.1-nano</code></strong>. L’adaptateur gère aussi les exigences des modèles de raisonnement ; la liste inclut gpt-5-nano, ils ne sont donc pas tous exclus."
],
"baseUrlTitle": "URL de base compatible OpenAI",
"baseUrlBody": "Le fournisseur OpenAI accepte une <em>URL de base</em> personnalisée pour les points d’accès compatibles : <strong>BytePlus / ByteDance (Kimi K2.5)</strong>, <strong>LocalAI</strong>, <strong>LM Studio</strong>, <strong>vLLM</strong>, <strong>Together AI</strong>, <strong>Fireworks AI</strong> et les services utilisant le format <code>/v1/chat/completions</code>. Saisissez l’URL dans l’onglet OpenAI près de la clé API."
},
"anthropic": {
"heading": "Anthropic (Claude)",
"tagline": "Excellent pour l'écriture et la traduction. Rapide et économique.",
"items": [
"Clé API : <a>console.anthropic.com/settings/keys</a>",
"Exemples de la liste de modèles fournie : <code>claude-haiku-4-5-20251001</code>, <code>claude-sonnet-4-6</code>, <code>claude-opus-4-6</code>.",
"Recommandation fournie : <strong><code>claude-haiku-4-5-20251001</code></strong>. Cette version précise est recommandée ; les anciens modèles Claude 3.5 ne figurent plus dans la liste fournie."
]
},
"gemini": {
"heading": "Google Gemini",
"tagline": "Niveau gratuit disponible, excellent rapport qualité/prix.",
"items": [
"Clé API : <a>aistudio.google.com/app/apikey</a>",
"Exemples de la liste de modèles fournie : <code>gemini-2.5-flash-lite</code>, <code>gemini-2.5-flash</code>, <code>gemini-3-flash-preview</code>.",
"Recommandé: <strong><code>gemini-2.5-flash-lite</code></strong> — flash et flash-lite passent le vérificateur de façon cohérente. Les variantes pro rejettent le réglage <code>thinkingBudget=0</code> du moniteur et sont surqualifiées pour cette charge de travail."
]
},
"openrouter": {
"heading": "OpenRouter",
"tagline": "Agrégateur avec accès aux modèles 100+ en utilisant une seule clé API. Flexibilité maximale.",
"items": [
"Clé API : <a>openrouter.ai/keys</a>",
"Exemples de la liste de modèles fournie : <code>meta-llama/llama-3.3-70b-instruct</code>, <code>meta-llama/llama-3.1-70b-instruct</code>, <code>meta-llama/llama-3.1-8b-instruct</code>, <code>anthropic/claude-haiku-4.5</code>, <code>google/gemini-2.5-flash-lite</code>, <code>openai/gpt-4o-mini</code>, <code>mistralai/mistral-medium-3</code>.",
"Recommandé: <strong><code>meta-llama/llama-3.3-70b-instruct</code></strong> — le même modèle que l'entrée Groq mais acheminé par OpenRouter, ce qui signifie une seule clé pour tous les modèles listés."
]
},
"ollama": {
"heading": "Ollama (local)",
"tagline": "Utilise les modèles du serveur Ollama configuré. Les modèles locaux s’exécutent sur ce serveur ; les modèles cloud transmettent les requêtes à un fournisseur externe. L’exécution locale évite les frais d’API hébergée, mais utilise votre matériel et votre électricité.",
"items": [
"Pas de clé API. Définissez le champ <em>Ollama URL</em> sur votre serveur (par défaut <code>http://localhost:11434</code> ou quel que soit l'hôte exécute votre instance Ollama).",
"Modèles: <strong>non filtré.</strong> Le moniteur lit les modèles que vous avez tirés sur le côté Ollama via <code>ollama pull &lt;model&gt;</code>. Le menu déroulant est peuplé de <code>GET /api/tags</code> sur votre serveur Ollama.",
"Installation : <a>ollama.com/download</a> — Linux, macOS et Windows. Choisissez un modèle qui tient en RAM et dont la fenêtre de contexte peut contenir les blocs de journal ajoutés par le répartiteur."
]
}
},
"models": {
"heading": "Pourquoi ces modèles spécifiques",
"intro": "Le choix des modèles commerciaux utilise le catalogue fourni <code>verified_ai_models.json</code> et les contrôles de disponibilité des adaptateurs. Ceux-ci convertissent la demande interne <code>system_prompt + user_message + max_tokens</code> vers chaque API. Le catalogue contient des modèles testés et des ajouts manuels ; il ne garantit ni l’accès actuel du compte ni le passage de chaque entrée au même vérificateur.",
"consequencesIntro": "Deux conséquences méritent d'être connues:",
"consequences": [
"<strong>La recommandation fournie</strong> est un point de départ pour les notifications. Évaluez qualité linguistique, latence et coût selon vos événements et votre compte ; ce n’est pas un classement universel.",
"<strong>Vous pouvez choisir un autre modèle de la liste</strong> selon votre quota ou vos préférences. Testez sa disponibilité : sa présence ne garantit pas l’accès actuel de votre compte."
],
"ollamaTitle": "Ollama est l'exception",
"ollamaBody": "La liste Ollama n’est pas filtrée par le catalogue commercial ; elle reflète les modèles du serveur. Pour une exécution locale, choisissez un modèle local adapté à la RAM et au contexte des journaux. Les modèles cloud restent distants, même via un serveur Ollama local."
},
"defaultPrompt": {
"heading": "Invite par défaut",
"intro": "Avec le mode prompt réglé sur <em>Default</em>, le moniteur utilise l'invite système ci-dessous. L'invite est modélisée à l'exécution : <code>'{'language'}'</code>, <code>'{'detail_level'}'</code>, <code>'{'emoji_instructions'}'</code> et <code>'{'suggestions_addon'}'</code> sont remplacés avant l'appel. Les variantes pour les canaux riches vs simples et l'ajout AI Suggestions sont affichés immédiatement après.",
"showFullSummary": "Afficher l'invite système par défaut complète",
"passagesIntro": "Deux variantes de texte sont choisies selon le réglage <em>Messages enrichis</em> de chaque canal :",
"passages": [
"<strong>Rich on</strong> → un bloc emoji est injecté listant les icônes que LLM peut utiliser, plus une règle de nom d'hôte (le LLM doit garder le préfixe du nom d'hôte à partir du titre) et une poignée d'exemples formatés (démarrage de sauvegarde, sauvegarde complète, mises à jour, démarrage de VM, dégradation de la santé). C'est ce qui produit les messages préfixés emoji sur Telegram et Discord.",
"<strong>Rich off</strong> → un bloc d'une ligne dit au LLM d'utiliser uniquement ASCII simple — pas d'emojis, pas de symboles Unicode. Utilisé pour l'email et tout canal où le formatage du bruit fait mal aux règles de boîte de réception ou de lisibilité."
],
"suggestionsPlaceholder": "L’espace réservé <code>'{'suggestions_addon'}'</code> reste vide sauf si vous activez les suggestions IA ; le bloc suivant est alors ajouté :",
"showAddonSummary": "Afficher le complément de suggestions IA"
},
"customPrompt": {
"heading": "Mode d'invite personnalisé",
"intro": "Le mode <em>Personnalisé</em> remplace tout le texte système par vos propres instructions. Elles sont enregistrées dans les paramètres SQLite et envoyées sans modification à chaque appel IA. Vous pouvez ainsi choisir un autre ton, une autre structure ou priorité.",
"imageAlt": "Mode personnalisé Prompt affichant une zone de texte avec des règles de traduction et des boutons d'importation d'exportation plus un lien d'invite communautaire",
"imageCaption": "Prompt personnalisé — grande zone de texte avec l'invite de l'utilisateur, plus <em>Export</em>, <em>Import</em> et un lien vers la galerie communautaire sur GitHub.",
"changesTitle": "Ce qui change en mode personnalisé",
"changes": [
"<strong>L'invite par défaut est entièrement remplacée.</strong> Les mappages Proxmox, les règles de gestion du contexte et les instructions emoji sont tous partis. Si vous voulez garder l'un d'eux, collez-les dans votre invite — le <code>EXAMPLE_CUSTOM_PROMPT</code> fourni ci-dessous est un point de départ.",
"<strong>Le sélecteur de langue est ignoré.</strong> Les instructions par défaut contiennent <code>'{'language'}'</code>, contrairement au texte personnalisé. Précisez la langue dans vos instructions, par exemple « Traduire en espagnol » ou « Tout écrire en français ».",
"<strong>Le mode personnalisé reste limité à 500 tokens</strong>, indépendamment du détail enregistré par canal. Le mode par défaut utilise 500 / 1500 / 3000. Modifier les instructions ne relève pas ce plafond ; demandez une réponse plus courte ou choisissez un détail par défaut adapté.",
"<strong>Les marqueurs de sortie restent obligatoires.</strong> Incluez <code>[TITLE]</code> et <code>[BODY]</code> dans le format de réponse. L’analyseur extrait leur contenu ; si un marqueur manque, il renvoie le modèle original.",
"<strong>Rich messages émoji règles ne sont pas auto-injectés.</strong> Si vous voulez emojis, dites à l'invite de les utiliser. Si vous voulez un texte clair, dites-lui de ne pas le faire. La bascule ne porte que les blocs groupés de l'invite par défaut, et non votre chaîne personnalisée."
],
"starterTitle": "Exemple initial d’instructions",
"starterIntro": "La zone de texte <em>Custom Prompt</em> est pré-remplie avec un exemple minimal que vous pouvez adapter:",
"showStarterSummary": "Afficher l’exemple initial personnalisé",
"shareTitle": "Partager des instructions avec la communauté",
"shareIntro": "Le bouton <em>Exporter</em> enregistre vos instructions dans un fichier (<code>.txt</code> / <code>.md</code>) à garder comme sauvegarde ou à partager. <em>Importer</em> recharge un fichier. Le troisième bouton ouvre la galerie communautaire publique sur GitHub :",
"shareLinkLabel": "github.com/MacRimi/ProxMenux/discussions — Partagez les instructions personnalisées pour les notifications AI",
"shareOutro": "Parcourez la discussion pour découvrir les créations des autres administrateurs : alertes très courtes, rapports techniques détaillés et variantes linguistiques. Si votre adaptation vous convient, partagez-la avec un paragraphe expliquant son objectif. Les retours sur ce qui fonctionne ou non sont également bienvenus."
},
"suggestions": {
"heading": "Suggestions d'IA (BÊTA)",
"intro": "Les suggestions IA permettent d’ajouter <strong>un</strong> conseil court et applicable à la fin du texte. Elles nécessitent le mode <em>Par défaut</em>, l’IA et les <em>Suggestions IA</em> activés. Les instructions demandent d’omettre le conseil si la cause ou la solution est incertaine.",
"formatIntro": "Lorsqu’un conseil est ajouté, il suit ce format exact :",
"rulesIntro": "Les règles ont été introduites dans l'addon (visible dans le bloc pliable sous la section invite par défaut ci-dessus) :",
"rules": [
"Le conseil est inclus <em>uniquement</em> si les journaux ou la base des erreurs connues indiquent clairement une correction précise.",
"Les instructions demandent un conseil de moins de 100 caractères ; l’analyseur ne vérifie pas cette longueur séparément.",
"Les instructions exigent une commande ou un chemin précis et demandent d’éviter les conseils généraux.",
"Si une erreur connue fournit une solution, la LLM doit utiliser cette solution, et non en inventer une nouvelle.",
"Les instructions demandent d’omettre le conseil si les données ne justifient pas une correction précise."
],
"betaTitle": "Pourquoi BETA",
"betaBody": "La qualité des conseils dépend du modèle choisi et du contexte disponible dans les journaux. Un modèle performant, comme Claude 3.5 Haiku, GPT-4.1 Mini ou Llama 3.3 70B, avec données smartctl et lignes de journal, peut fournir un conseil utile. Un petit modèle Ollama local avec un événement d’une ligne peut donner un résultat peu utile ou aucun conseil. Désactivez les suggestions si elles vous gênent, puis réactivez-les à votre convenance."
},
"detailLevel": {
"heading": "Niveau de détail par canal",
"intro": "Telegram, Discord, Gotify et e-mail ont chacun un choix de détail. Trois valeurs déterminent le plafond de tokens et les instructions du mode par défaut :",
"headerLevel": "Niveau",
"headerLabel": "Étiquette UI",
"headerCap": "Limite de production",
"headerProduce": "Ce que l'invite demande au LLM de produire",
"rows": [
{
"level": "bref",
"label": "2 à 3 lignes, uniquement l’essentiel",
"cap": "500 tokens",
"produce": "\"Ce qui s'est passé + où\". Rien d'autre."
},
{
"level": "standard",
"label": "Concise avec le contexte de base",
"cap": "1500 tokens",
"produce": "3 à 6 lignes : quoi, où, cause, appareils concernés."
},
{
"level": "détaillé",
"label": "Détails techniques complets",
"cap": "3000 tokens",
"produce": "Rapport complet : quoi, où, cause, affecté, journaux, données SMART, historique."
}
],
"defaultsIntro": "Valeurs par défaut à la première installation :",
"defaults": [
"<strong>Telegram, Discord, Gotify</strong> — <code>standard</code>.",
"<strong>Courriel</strong> — <code>detailed</code>. Le courriel est le canal où vous voulez généralement l'image complète pour l'archivage."
],
"emailTitle": "Le niveau de détail du courriel ajoute l'original",
"emailBody": "Si le formateur IA renvoie un résultat pour l’e-mail en <code>detailed</code> et que le texte original dépasse 50 caractères, il l’ajoute après 40 tirets et <code>Original message:</code>. Les détails restent disponibles pour les recherches. Si l’IA est ignorée ou échoue, le modèle original seul peut être envoyé."
},
"language": {
"heading": "Langue",
"intro": "Le sélecteur propose treize langues. Il enregistre <code>ai_language</code>, utilisé par les instructions par défaut dans <em>\"translate alerts into '{'language'}'\"</em>. La liste :",
"list": "Anglais (<code>en</code>), slovaque (<code>sk</code>), espagnol (<code>es</code>), français (<code>fr</code>), allemand (<code>de</code>), portugais (<code>pt</code>), italien (<code>it</code>), russe (<code>ru</code>), suédois (<code>sv</code>), norvégien (<code>no</code>), japonais (<code>ja</code>), chinois (<code>zh</code>), néerlandais (<code>nl</code>).",
"rulesIntro": "Deux règles importantes tirées directement de l'invite :",
"rules": [
"<strong>Traduire</strong> : libellés, descriptions, états et unités, par exemple GB → Go en français.",
"<strong>Ne pas traduire</strong>: noms d'hôte, IPs, chemins, IDs VM/CT, noms de périphérique comme <code>/dev/sdX</code>, identifiants techniques. Celles-ci restent in extenso quelle que soit la langue."
],
"customNote": "Mode d'invite personnalisé <strong> n'utilise pas</strong> le sélecteur de langue. Si vous passez à Custom et voulez un langage de sortie spécifique, déclarez-le à l'intérieur de votre invite."
},
"templates": {
"heading": "Note sur les modèles",
"body1": "L’IA reçoit le texte d’un modèle, pas les données brutes de l’événement. <code>vm_start</code>, <code>auth_fail</code> et <code>health_degraded</code> ont des modèles dans <code>notification_templates.py</code>. L’IA reformule les sorties admissibles ; <code>backup_complete</code> et <code>backup_fail</code> conservent leurs rapports déterministes sans IA.",
"body2": "Deux implications pratiques: l'IA ne voit jamais un nom d'hôte ou VMID qu'il doit inventer — ces champs sont placés par le modèle avant la réécriture. Et si l'IA est désactivé, le corps modèle est ce qui est envoyé directement. La page <link>Notifications</link> documente le pipeline d'expédition en entier et est la bonne référence pour tout ce qui arrive à un événement avant qu'il atteigne ce calque."
},
"privacy": {
"heading": "Confidentialité & flux de données",
"intro": "Avec la réécriture AI activée, le moniteur envoie le corps de notification rendu ainsi que les blocs de contexte enrichis au fournisseur configuré. Cela peut inclure des noms d'hôte, des IP, des noms d'utilisateur, des chemins de périphérique, des lignes de journal et des attributs SMART pour le périphérique touché. Si cela quitte l'hôte dépend du fournisseur que vous avez choisi:",
"headerProvider": "Fournisseur",
"headerDestination": "Destination des données",
"rows": [
{
"provider": "Ollama",
"destination": "Les modèles locaux s’exécutent sur l’hôte Ollama configuré. S’il s’agit du nœud Proxmox, leurs requêtes y restent. Les modèles cloud transmettent les requêtes hors de l’hôte, même via un serveur Ollama local."
},
{
"provider": "OpenAI",
"destination": "<code>api.openai.com</code> par défaut, ou l’URL de base personnalisée. La politique de données de l’opérateur réel du point d’accès s’applique."
},
{
"provider": "Anthropic",
"destination": "<code>api.anthropic.com</code>."
},
{
"provider": "Google Gemini",
"destination": "<code>generativelanguage.googleapis.com</code>."
},
{
"provider": "Groq",
"destination": "<code>api.groq.com</code>."
},
{
"provider": "OpenRouter",
"destination": "<code>openrouter.ai</code>, qui est transmis au fournisseur de modèles sous-jacent choisi dans le champ <code>model</code>. Deux sauts au lieu d'un."
}
],
"calloutTitle": "Si le contenu de l'événement ne peut pas quitter le réseau",
"calloutBody": "Utilisez un point d’accès hébergé localement avec un modèle local, comme Ollama ou un serveur compatible OpenAI, ou désactivez l’IA. Les modèles cloud Ollama ne traitent pas les données localement. Le répartiteur ne masque ni noms d’hôte ni IP ; il utilise le contenu réel de l’événement."
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Notifications",
"href": "/docs/monitor/notifications",
"tail": "— le pipeline d'expédition, les canaux, les toggles par événement et l'intégration PVE webhook qui entoure cette couche."
},
{
"label": "Moniteur de santé",
"href": "/docs/monitor/health-monitor",
"tail": "— le plus grand producteur d'événements l'IA finit par réécrire, avec ses propres durées de suppression par catégorie."
},
{
"label": "Architecture",
"href": "/docs/monitor/architecture",
"tail": "— où l'AI Enhancer s'inscrit dans le processus plus large de Monitor (c'est un module, pas un service séparé)."
}
],
"communityLabel": "Instructions communautaires sur GitHub",
"communityTail": "— parcourez, partagez, demandez."
}
}
@@ -0,0 +1,760 @@
{
"meta": {
"title": "API Proxmox Monitor — Référence d’intégration | ProxMenux",
"description": "Points d’accès HTTP de ProxMenux Monitor pour Home Assistant, Homepage, Grafana, Prometheus, n8n et tableaux de bord personnalisés. Consulter l’état et lancer les opérations documentées : contrôle des VM, sauvegardes, notifications et acquittement des alertes.",
"ogTitle": "API Proxmox Monitor — Référence d’intégration",
"ogDescription": "Points d’accès ProxMenux Monitor pour Home Assistant, Homepage, Grafana, Prometheus, n8n et tableaux de bord personnalisés.",
"twitterTitle": "API Proxmox Monitor | ProxMenux",
"twitterDescription": "Points d’accès pour Home Assistant, Homepage, Grafana, Prometheus, n8n et tableaux de bord personnalisés."
},
"header": {
"title": "Référence de l’API",
"description": "Points d’accès HTTP pour consulter l’état et lancer des actions documentées : capteurs Home Assistant, cartes Homepage, tableaux Grafana, collecte Prometheus, flux n8n et scripts personnalisés. Avec catégories, métriques exportées et exemples curl.",
"section": "ProxMenux Monitor"
},
"intro": {
"title": "À quoi sert cette page",
"body": "Cette page réunit les points d’accès des intégrations : lecture des données, lancement de sauvegardes, notifications personnalisées et acquittement d’alertes. L’API utilise le processus Flask du tableau de bord sur TCP <strong>8008</strong>. L’adresse d’écoute et TLS sont décrits dans <link>Accès et authentification</link>."
},
"headerEndpoint": "Point d’accès",
"headerMethod": "Méthode",
"headerUse": "Utilisation",
"auth": {
"heading": "Authentification",
"intro": "Lorsque l’authentification est active, les points d’accès protégés attendent un jeton JWT Bearer dans l’en-tête :",
"tokensIntro": "Deux façons d'obtenir le jeton :",
"items": [
"<strong>Jetons API, recommandés pour les intégrations.</strong> Valables 365 jours, créés dans <strong>Sécurité → Jetons API</strong>. Ils sont nommés et révocables individuellement. Utilisez read_only pour les données, full_admin uniquement pour les actions administratives nécessaires.",
"<strong>Connexion, JWT de 24 heures.</strong> <code>POST /api/auth/login</code> avec identifiant, mot de passe et TOTP si la 2FA l’exige. Le JWT expire après 24 heures ; les scripts doivent alors s’authentifier à nouveau."
],
"flowLink": "Connexion, mots de passe, 2FA, journal d’audit et TLS sont décrits dans <link>Accès et authentification</link>.",
"rows": [
{
"endpoint": "/api/auth/login",
"method": "POST",
"use": "Champs du corps (schéma) : <code>'{'\"username\",\"password\",\"totp_token?\"'}'</code>. Renvoie un JWT de 24 heures."
},
{
"endpoint": "/api/auth/api-tokens",
"method": "GET",
"use": "Liste des jetons API (métadonnées seulement — noms, préfixes, dates; jamais le vrai secret)."
},
{
"endpoint": "/api/auth/generate-api-token",
"method": "POST",
"use": "Crée un jeton API de 365 jours avec une session authentifiée. Champs : <code>password, token_name?, totp_token?, scope?</code>. Mot de passe et TOTP requis sont vérifiés à nouveau. scope vaut read_only par défaut ; full_admin doit être choisi explicitement. Le secret est renvoyé une seule fois."
},
{
"endpoint": "/api/auth/api-tokens/<id>",
"method": "DELETE",
"use": "Révoquer un jeton API par son identifiant."
}
]
},
"conventions": {
"heading": "Conventions",
"items": [
"La plupart utilisent JSON. Certains téléchargements renvoient du texte brut ; <code>/api/prometheus</code> utilise le format texte Prometheus 0.0.4, plutôt qu’OpenMetrics. Vérifiez le type de réponse de chaque route.",
"De nombreuses écritures renvoient <code>'{'\"success\": true, ...'}'</code>. Les erreurs varient ; un format courant est <code>'{'\"success\": false, \"error\": \"'<'reason'>'\"'}'</code>. Vérifiez le statut HTTP et les champs : certains défis d’authentification utilisent HTTP 200 avec success false.",
"Les paramètres dépendent du point d’accès. Utilisez <code>limit</code>, <code>offset</code>, <code>since</code> et les filtres de catégorie uniquement si la route les accepte.",
"Les formats temporels varient : horodatages Unix, chaînes ISO-8601 et dates systemd. Ne supposez ni une unité commune ni un fuseau explicite pour tous les champs."
]
},
"system": {
"heading": "Système & matériel",
"rows": [
{
"endpoint": "/api/system",
"method": "GET",
"use": "Valeurs actuelles de CPU, mémoire, swap, durée de fonctionnement et charge."
},
{
"endpoint": "/api/info",
"method": "GET",
"use": "Informations statiques de l’hôte : nom, noyau, version PVE, modèle CPU et distribution."
},
{
"endpoint": "/api/system-info",
"method": "GET",
"use": "Données système étendues de l’en-tête : métriques générales et heure de démarrage."
},
{
"endpoint": "/api/hardware",
"method": "GET",
"use": "Inventaire matériel détaillé : périphériques PCI, GPU et capteurs."
},
{
"endpoint": "/api/hardware/live",
"method": "GET",
"use": "Valeurs actuelles des capteurs à variation rapide."
},
{
"endpoint": "/api/temperature/history",
"method": "GET",
"use": "Séries temporelles des températures du CPU et de son boîtier."
},
{
"endpoint": "/api/gpu/<slot>/realtime",
"method": "GET",
"use": "Métriques actuelles des GPU NVIDIA, Intel et AMD par emplacement PCI."
}
]
},
"actions": {
"heading": "Actions du système",
"intro": "Ces actions asynchrones utilisent des unités systemd temporaires. Avec authentification active, leurs écritures exigent <code>full_admin</code> ; <code>read_only</code> peut consulter <code>.../status</code>. Un lancement accepté renvoie HTTP 202 et l’état ; consultez <code>.../status</code> pour la progression. Le contrôle des invités et les sauvegardes ont d’autres réponses, décrites plus bas.",
"shapeTitle": "Forme de réponse commune",
"shapeIntro": "Les actions système asynchrones partagent l’objet d’état JSON ci-dessous. Le contrôle des invités et les sauvegardes ont d’autres formats :",
"shapeCode": "{\n \"unit\": \"proxmenux-action-pve-update.service\",\n \"state\": \"idle | running | success | failed | cancelled\",\n \"started_at\": \"Sat 2026-08-01 11:01:32 CEST\",\n \"finished_at\": null,\n \"exit_code\": null,\n \"result\": null\n}",
"concurrencyTitle": "Concurrence et annulation",
"concurrencyBody": "Relancer la même action déjà active renvoie HTTP 409. L’annulation existe seulement avec une route DELETE documentée, comme pour la mise à jour PVE. L’état devient <code>cancelled</code> avec dates conservées. Les états finaux sont en mémoire du processus et peuvent disparaître au redémarrage du moniteur.",
"rows": [
{
"endpoint": "/api/system/power/reboot",
"method": "POST",
"use": "Lance le redémarrage de l’hôte Proxmox. La connexion HTTP peut se fermer quand systemd commence l’arrêt."
},
{
"endpoint": "/api/system/power/reboot/status",
"method": "GET",
"use": "État du redémarrage actuel ou précédent."
},
{
"endpoint": "/api/system/power/shutdown",
"method": "POST",
"use": "Éteint l’hôte Proxmox, par exemple en réponse au signal d’arrêt d’un onduleur."
},
{
"endpoint": "/api/system/power/shutdown/status",
"method": "GET",
"use": "État de l’arrêt actuel ou précédent."
},
{
"endpoint": "/api/system/pve-update/run",
"method": "POST",
"use": "Lance la mise à jour PVE utilisée par Mettre à jour maintenant du Health Monitor et le menu shell ; délègue à update-pve-safe.sh."
},
{
"endpoint": "/api/system/pve-update/status",
"method": "GET",
"use": "État de la mise à jour PVE actuelle ou précédente."
},
{
"endpoint": "/api/system/pve-update",
"method": "DELETE",
"use": "Annule une mise à jour PVE en cours par SIGTERM."
},
{
"endpoint": "/api/proxmenux/self-update/run",
"method": "POST",
"use": "Met à jour ProxMenux avec l’installateur du canal stable ou bêta configuré. Une unité systemd distincte permet au travail de survivre au redémarrage de proxmenux-monitor lancé par l’installateur."
},
{
"endpoint": "/api/proxmenux/self-update/status",
"method": "GET",
"use": "État de la mise à jour ProxMenux actuelle ou précédente."
},
{
"endpoint": "/api/vms/<vmid>/control",
"method": "POST",
"use": "Envoie une commande de VM ou LXC. Le champ <code>action</code> accepte <code>start</code>, <code>stop</code>, <code>shutdown</code> ou <code>reboot</code>. Une réponse réussie renvoie une tâche PVE confirmée, sans garantir sa fin. Consultez le point d’accès control-task de l’invité pour le résultat."
},
{
"endpoint": "/api/vms/<vmid>/backup",
"method": "POST",
"use": "Crée une sauvegarde vzdump de VM ou LXC. Champs facultatifs à adapter au stockage : <code>storage</code> (cible PVE), <code>mode</code> (<code>snapshot</code>, <code>suspend</code> ou <code>stop</code>), <code>compress</code> (<code>zstd</code>, <code>lzo</code>, <code>gzip</code> ou <code>none</code>), <code>protected</code> (<code>true</code> ou <code>false</code>), <code>notes</code>, <code>notification</code> (<code>auto</code>, <code>always</code>, <code>failure</code> ou <code>never</code>) et <code>pbs_change_detection</code> (<code>default</code>, <code>legacy</code> ou <code>data</code>). Renvoie l’UPID de la tâche PVE."
},
{
"endpoint": "/api/vms/<vmid>/backups",
"method": "GET",
"use": "Liste les sauvegardes précédentes d’une VM ou d’un LXC sur les stockages accessibles."
}
],
"syncVsAsyncTitle": "Deux types d’actions",
"syncVsAsyncBody": "Alimentation et mises à jour de l’hôte utilisent des unités systemd temporaires avec <code>.../status</code>. Seule la mise à jour PVE possède ici une route <code>DELETE</code> d’annulation. Le contrôle VM/LXC renvoie une tâche à suivre ; la sauvegarde un UPID de travail en arrière-plan. Acceptation ne signifie pas achèvement. Authentification et droits dépendent de la route.",
"curlTitle": "Exemple curl",
"curlBody": "Lance une mise à jour PVE et suit sa progression jusqu’à la fin, comme une automatisation Home Assistant ou un playbook Ansible.",
"curlCode": "TOKEN=<your full_admin token>\n\ncurl -sSf -X POST \\\n -H \"Authorization: Bearer $TOKEN\" \\\n https://<host>:8008/api/system/pve-update/run\n\nwhile true; do\n state=$(curl -sSf -H \"Authorization: Bearer $TOKEN\" \\\n https://<host>:8008/api/system/pve-update/status | jq -r .state)\n [ \"$state\" != \"running\" ] && break\n sleep 30\ndone\necho \"final state: $state\"",
"haTitle": "Exemple pour Home Assistant",
"haBody": "Un capteur <code>rest</code> consulte l’état et <code>rest_command</code> lance la mise à jour. Associez-les à un bouton du tableau de bord et aux automatisations voulues :",
"haCode": "# configuration.yaml\nsensor:\n - platform: rest\n resource: https://pve.local:8008/api/system/pve-update/status\n name: pve_update_state\n value_template: \"{{ value_json.state }}\"\n scan_interval: 60\n headers:\n Authorization: \"Bearer !secret proxmenux_token\"\n\nrest_command:\n pve_update:\n url: https://pve.local:8008/api/system/pve-update/run\n method: POST\n headers:\n Authorization: \"Bearer !secret proxmenux_token\"\n\n # Start VM 100 (works for LXC too — same endpoint)\n vm_100_start:\n url: https://pve.local:8008/api/vms/100/control\n method: POST\n content_type: 'application/json'\n payload: '{\"action\": \"start\"}'\n headers:\n Authorization: \"Bearer !secret proxmenux_token\"\n\n # Backup VM 100 to the 'pbs-main' storage\n vm_100_backup:\n url: https://pve.local:8008/api/vms/100/backup\n method: POST\n content_type: 'application/json'\n payload: '{\"storage\": \"pbs-main\", \"mode\": \"snapshot\", \"compress\": \"zstd\"}'\n headers:\n Authorization: \"Bearer !secret proxmenux_token\""
},
"health": {
"heading": "Moniteur de santé",
"rows": [
{
"endpoint": "/api/health",
"method": "GET",
"use": "Sonde légère renvoyant JSON avec <code>status</code>, <code>timestamp</code> et <code>version</code>. Adaptée aux contrôles par mot-clé d’Uptime Kuma ; avec authentification active, le client doit envoyer l’en-tête Bearer."
},
{
"endpoint": "/api/health/status",
"method": "GET",
"use": "État global : un niveau de gravité et un résumé."
},
{
"endpoint": "/api/health/details",
"method": "GET",
"use": "Les dix catégories avec état et données structurées de chaque contrôle."
},
{
"endpoint": "/api/health/full",
"method": "GET",
"use": "Données complètes : catégories, erreurs actives, alertes rejetées et réglages de suppression. Utilise les résultats en arrière-plan de moins de six minutes ; sinon, ou en cas d’actualisation forcée, lance un nouveau contrôle."
},
{
"endpoint": "/api/health/active-errors",
"method": "GET",
"use": "Liste active, filtrée par <code>?category=&lt;name&gt;</code>."
},
{
"endpoint": "/api/health/dismissed",
"method": "GET",
"use": "Alertes rejetées avec les heures de suppression restantes."
},
{
"endpoint": "/api/health/settings",
"method": "GET",
"use": "Durée de suppression configurée pour chaque catégorie."
},
{
"endpoint": "/api/health/remote-storages",
"method": "GET",
"use": "Inventaire des stockages à distance définis par Proxmox, avec état en ligne."
},
{
"endpoint": "/api/health/interfaces",
"method": "GET",
"use": "Interfaces réseau avec type (pont / agrégat / physique), IP et débit du lien."
},
{
"endpoint": "/api/health/acknowledge",
"method": "POST",
"use": "Corps : <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Supprime une alerte pendant la durée configurée pour sa catégorie."
},
{
"endpoint": "/api/health/cleanup-orphans",
"method": "POST",
"use": "Nettoyage manuel des erreurs de périphériques ou VM supprimés. Idempotent."
}
],
"outro": "Les formats de réponse et les catégories sont décrits dans <link>Health Monitor</link>."
},
"storage": {
"heading": "Stockage",
"rows": [
{
"endpoint": "/api/storage",
"method": "GET",
"use": "Disques visibles par l’hôte : périphériques blocs, pools ZFS et LVM."
},
{
"endpoint": "/api/storage/summary",
"method": "GET",
"use": "Résumé compact utilisé par les cartes de tableau de bord."
},
{
"endpoint": "/api/proxmox-storage",
"method": "GET",
"use": "Stockages définis par Proxmox de <code>/etc/pve/storage.cfg</code> avec état en ligne et espace libre."
},
{
"endpoint": "/api/storage/observations",
"method": "GET",
"use": "Historique persistant : avertissements SMART, erreurs d’E/S et événements ZFS. Conservé après la résolution automatique des alertes."
},
{
"endpoint": "/api/storage/smart/<disk>",
"method": "GET",
"use": "Attributs actuels SMART pour un disque."
},
{
"endpoint": "/api/storage/smart/<disk>/latest",
"method": "GET",
"use": "Le plus récent auto-test SMART pour le disque."
},
{
"endpoint": "/api/storage/smart/<disk>/history",
"method": "GET",
"use": "Liste des rapports SMART stockés pour le disque."
},
{
"endpoint": "/api/storage/smart/<disk>/history/<file>",
"method": "GET",
"use": "Lit un rapport SMART enregistré précis."
},
{
"endpoint": "/api/storage/smart/<disk>/test",
"method": "POST",
"use": "Lance un autotest SMART. Schéma du corps : <code>'{'\"type\":\"short\"|\"long\"'}'</code>."
},
{
"endpoint": "/api/storage/smart/schedules",
"method": "GET",
"use": "Énumérez les tests SMART actuellement prévus."
},
{
"endpoint": "/api/storage/smart/tools",
"method": "GET",
"use": "Vérifie si <code>smartctl</code> et les outils associés sont installés."
}
]
},
"network": {
"heading": "Réseau",
"rows": [
{
"endpoint": "/api/network",
"method": "GET",
"use": "Toutes les interfaces avec état du lien et adresses."
},
{
"endpoint": "/api/network/summary",
"method": "GET",
"use": "Vue compacte utilisée par le tableau de bord."
},
{
"endpoint": "/api/network/<iface>/metrics",
"method": "GET",
"use": "RX/TX par interface, compteurs d’erreurs et séries temporelles RRD."
},
{
"endpoint": "/api/network/latency/current",
"method": "GET",
"use": "Dernière mesure de latence vers la passerelle."
},
{
"endpoint": "/api/network/latency/history",
"method": "GET",
"use": "Série chronologique de latence de passerelle."
}
]
},
"vms": {
"heading": "Machines virtuelles et conteneurs",
"rows": [
{
"endpoint": "/api/vms",
"method": "GET",
"use": "VM et CT du nœud local avec état, vmid et nom."
},
{
"endpoint": "/api/vms/<vmid>",
"method": "GET",
"use": "Détail complet pour un invité (config, réseau, disques)."
},
{
"endpoint": "/api/vms/<vmid>/metrics",
"method": "GET",
"use": "Séries temporelles CPU, mémoire et E/S disque d’un invité (RRD)."
},
{
"endpoint": "/api/vms/<vmid>/logs",
"method": "GET",
"use": "Journaux des tâches récentes de cet invité."
},
{
"endpoint": "/api/vms/<vmid>/backups",
"method": "GET",
"use": "Sauvegardes conservées pour cet invité."
},
{
"endpoint": "/api/vms/<vmid>/control",
"method": "POST",
"use": "Choisissez une action du schéma : <code>'{'\"action\":\"start|stop|reboot|shutdown\"'}'</code>. Contrôle l’alimentation de l’invité."
},
{
"endpoint": "/api/vms/<vmid>/backup",
"method": "POST",
"use": "Lance <code>vzdump</code> pour l’invité. Le corps choisit le stockage et le mode (<code>snapshot</code> / <code>suspend</code> / <code>stop</code>)."
},
{
"endpoint": "/api/vms/<vmid>/config",
"method": "PUT",
"use": "Modifie la description (notes) d’une VM ou d’un CT. Les autres paramètres de configuration ne sont pas modifiables par ce point d’accès."
},
{
"endpoint": "/api/node/metrics",
"method": "GET",
"use": "Métriques agrégées du nœud en séries RRD."
}
]
},
"backups": {
"heading": "Sauvegardes",
"rows": [
{
"endpoint": "/api/backups",
"method": "GET",
"use": "Sauvegardes trouvées dans les stockages dir, NFS, CIFS et PBS interrogés via le nœud local. Aucun parcours exhaustif de tous les nœuds du cluster."
},
{
"endpoint": "/api/backup-storages",
"method": "GET",
"use": "Stockages marqués comme cibles de sauvegarde, avec espace libre."
}
]
},
"logs": {
"heading": "Journaux, tâches, événements",
"rows": [
{
"endpoint": "/api/logs",
"method": "GET",
"use": "Entrées de journaux filtrées. Demande: <code>?level=&service=&limit=</code>."
},
{
"endpoint": "/api/logs/download",
"method": "GET",
"use": "Exporte la plage filtrée en texte brut."
},
{
"endpoint": "/api/events",
"method": "GET",
"use": "Flux d'événements internes — le même qui alimente les notifications."
},
{
"endpoint": "/api/task-log/<upid>",
"method": "GET",
"use": "Journal complet en texte brut d’une tâche Proxmox identifiée par UPID."
}
]
},
"notifications": {
"heading": "Notifications et IA",
"intro": "L’envoi, les canaux et la reformulation par IA sont décrits dans <notifLink>Notifications</notifLink> et <aiLink>Assistant IA</aiLink>.",
"rows": [
{
"endpoint": "/api/notifications",
"method": "GET",
"use": "Notifications récentes affichées dans le tableau de bord."
},
{
"endpoint": "/api/notifications/download",
"method": "GET",
"use": "Exporte les notifications en texte."
},
{
"endpoint": "/api/notifications/status",
"method": "GET",
"use": "État de l’envoi : processus en arrière-plan actif, longueur de file et dernier envoi."
},
{
"endpoint": "/api/notifications/settings",
"method": "GET",
"use": "Lit la configuration des notifications : canaux, réglages par événement, reformulation IA et nom affiché."
},
{
"endpoint": "/api/notifications/history",
"method": "GET",
"use": "Historique d’envoi. Paramètres : <code>?limit=&offset=&severity=&channel=</code>."
},
{
"endpoint": "/api/notifications/history",
"method": "DELETE",
"use": "Vide la table de l’historique d’envoi."
},
{
"endpoint": "/api/notifications/test",
"method": "POST",
"use": "Envoie une notification de test à un canal. Corps : <code>'{'\"channel\":\"telegram\"'}'</code>."
},
{
"endpoint": "/api/notifications/send",
"method": "POST",
"use": "Émet un événement personnalisé. Corps : <code>'{'\"event_type\":\"custom\",\"severity\":\"WARNING\",\"title\":\"...\",\"body\":\"...\",\"data\":'{''}''}'</code>."
},
{
"endpoint": "/api/notifications/test-ai",
"method": "POST",
"use": "Teste la connexion au fournisseur d’IA. Champs du corps (schéma) : <code>'{'\"provider\",\"api_key\",\"model\",\"ollama_url?\"'}'</code>."
},
{
"endpoint": "/api/notifications/provider-models",
"method": "POST",
"use": "Liste des modèles disponibles pour le fournisseur d'IA sélectionné."
},
{
"endpoint": "/api/notifications/proxmox/setup-webhook",
"method": "POST",
"use": "Enregistrer le moniteur comme cible webhook dans <code>/etc/pve/notifications.cfg</code>."
},
{
"endpoint": "/api/notifications/proxmox/cleanup-webhook",
"method": "POST",
"use": "Supprimer la cible Monitor de la configuration de notification de PVE."
},
{
"endpoint": "/api/notifications/proxmox/read-cfg",
"method": "GET",
"use": "Lisez le <code>notifications.cfg</code> actuel de PVE comme PVE le voit."
}
]
},
"security": {
"heading": "Sécurité (lecture)",
"rows": [
{
"endpoint": "/api/security/firewall/status",
"method": "GET",
"use": "État du pare-feu PVE et règles actives."
},
{
"endpoint": "/api/security/fail2ban/details",
"method": "GET",
"use": "État du jail Fail2Ban ; nécessite ce composant facultatif installé."
},
{
"endpoint": "/api/security/fail2ban/activity",
"method": "GET",
"use": "Événements Fail2Ban récents : blocages, déblocages et démarrages du jail."
},
{
"endpoint": "/api/security/lynis/status",
"method": "GET",
"use": "État de Lynis : installation et date de la dernière analyse."
},
{
"endpoint": "/api/security/lynis/report",
"method": "GET",
"use": "Dernier rapport Lynis : avertissements, suggestions et indice de durcissement."
},
{
"endpoint": "/api/security/tools",
"method": "GET",
"use": "Détectez quels outils de sécurité optionnels (Fail2Ban, Lynis) sont installés."
}
]
},
"proxmenuxIntegration": {
"heading": "Intégration ProxMenux",
"rows": [
{
"endpoint": "/api/proxmenux/update-status",
"method": "GET",
"use": "Disponibilité d’une mise à jour ProxMenux Monitor, version installée et dernière version."
},
{
"endpoint": "/api/proxmenux/installed-tools",
"method": "GET",
"use": "Liste de chaque optimisation de ProxMenux après l'installation actuellement enregistrée sur l'hôte (à partir de <code>/usr/local/share/proxmenux/installed_tools.json</code>)."
},
{
"endpoint": "/api/proxmenux/tool-source/<key>",
"method": "GET",
"use": "Code de la fonction de post-installation associée, extrait des scripts actuels de l’hôte ou d’ancien code conservé. Ce n’est pas un instantané garanti du code initialement exécuté."
}
]
},
"prometheus": {
"heading": "Métriques Prometheus",
"intro": "Le point d’accès authentifié <code>GET /api/prometheus</code> renvoie le format texte Prometheus 0.0.4. Chaque métrique inclut <code>node=\"&lt;hostname&gt;\"</code> et un horodatage explicite. Collectez-les avec Prometheus ou une base temporelle compatible.",
"exportedTitle": "Mesures exportées",
"headerGroup": "Groupe",
"headerMetric": "Métrique",
"headerDesc": "Description",
"groups": [
{
"group": "Système",
"metrics": [
{
"metric": "proxmox_cpu_usage",
"desc": "Pourcentage d’utilisation CPU, de type gauge."
},
{
"metric": "proxmox_memory_total_bytes",
"desc": "Mémoire physique totale en octets."
},
{
"metric": "proxmox_memory_used_bytes",
"desc": "Mémoire utilisée en octets."
},
{
"metric": "proxmox_memory_usage_percent",
"desc": "Pourcentage d'utilisation de la mémoire."
},
{
"metric": "proxmox_load_average",
"desc": "Moyenne de la charge du système. Étiquette <code>period=\"1m\" | \"5m\" | \"15m\"</code>."
}
]
},
{
"group": "Durée de fonctionnement",
"metrics": [
{
"metric": "proxmox_uptime_seconds",
"desc": "Secondes depuis le dernier démarrage."
}
]
},
{
"group": "Matériel",
"metrics": [
{
"metric": "proxmox_cpu_temperature_celsius",
"desc": "Température du boîtier du CPU."
},
{
"metric": "proxmox_disk_temperature_celsius",
"desc": "Température par disque. Étiquette <code>disk</code>."
},
{
"metric": "proxmox_fan_speed_rpm",
"desc": "Vitesses des ventilateurs. Étiquette <code>fan</code>."
}
]
},
{
"group": "Espace disque",
"metrics": [
{
"metric": "proxmox_disk_total_bytes",
"desc": "Capacité totale de chaque entrée de disque exportée. Étiquette <code>disk</code>."
},
{
"metric": "proxmox_disk_used_bytes",
"desc": "Capacité utilisée de chaque entrée de disque exportée."
},
{
"metric": "proxmox_disk_usage_percent",
"desc": "Pourcentage utilisé de chaque entrée de disque exportée."
}
]
},
{
"group": "Réseau",
"metrics": [
{
"metric": "proxmox_network_bytes_sent_total",
"desc": "Total des octets envoyés, de type counter."
},
{
"metric": "proxmox_network_bytes_received_total",
"desc": "Total des octets reçus, de type counter."
},
{
"metric": "proxmox_interface_bytes_sent_total",
"desc": "Octets envoyés par interface. Étiquette <code>interface</code>."
},
{
"metric": "proxmox_interface_bytes_received_total",
"desc": "Octets reçus par interface."
}
]
},
{
"group": "VMs / CTs",
"metrics": [
{
"metric": "proxmox_vms_total",
"desc": "Nombre total de VM et de LXC."
},
{
"metric": "proxmox_vms_running",
"desc": "Nombre d’invités en cours d’exécution."
},
{
"metric": "proxmox_vms_stopped",
"desc": "Nombre d’invités arrêtés."
},
{
"metric": "proxmox_vm_status",
"desc": "État par VM/CT : 1 en cours d’exécution, 0 sinon. Étiquettes <code>node</code>, <code>vmid</code> et <code>name</code>."
},
{
"metric": "proxmox_vm_cpu_usage",
"desc": "Utilisation CPU par VM/CT, avec les mêmes étiquettes."
},
{
"metric": "proxmox_vm_memory_used_bytes / _max_bytes",
"desc": "Mémoire utilisée et maximum configuré par VM/CT."
}
]
},
{
"group": "GPU",
"metrics": [
{
"metric": "proxmox_gpu_temperature_celsius",
"desc": "Température GPU. Étiquettes <code>slot</code> et <code>vendor</code> ; gpu contient aussi le nom du GPU."
},
{
"metric": "proxmox_gpu_utilization_percent",
"desc": "Pourcentage d’utilisation du GPU."
},
{
"metric": "proxmox_gpu_memory_total_bytes",
"desc": "Mémoire totale du GPU."
},
{
"metric": "proxmox_gpu_power_draw_watts",
"desc": "Puissance consommée par le GPU en watts."
},
{
"metric": "proxmox_gpu_clock_speed_mhz",
"desc": "Fréquence du cœur du GPU."
},
{
"metric": "proxmox_gpu_memory_clock_mhz",
"desc": "Fréquence de la mémoire du GPU."
}
]
},
{
"group": "UPS",
"metrics": [
{
"metric": "proxmox_ups_battery_charge_percent",
"desc": "Pourcentage de charge de la batterie."
},
{
"metric": "proxmox_ups_load_percent",
"desc": "Charge courante sur l'UPS."
},
{
"metric": "proxmox_ups_runtime_seconds",
"desc": "Autonomie estimée sur batterie."
},
{
"metric": "proxmox_ups_input_voltage_volts",
"desc": "Tension d'entrée."
}
]
}
],
"scrapeTitle": "Configuration de collecte Prometheus",
"scrapeIntro": "Avec l’authentification active, ajoutez un jeton API à l’en-tête Bearer de la configuration de collecte Prometheus :",
"perHostTitle": "Collecte par hôte",
"perHostBody": "Chaque instance exporte les métriques de son hôte. Dans un cluster, configurez Prometheus pour collecter chaque nœud. L’étiquette <code>node</code> distingue les séries dans Grafana (<code>proxmox_vms_running'{'node=\"pve01\"'}'</code>)."
},
"puttingItTogether": {
"heading": "Assembler les intégrations",
"body": "Voir <link>Intégrations</link> pour relier ces points d’accès aux capteurs Home Assistant, cartes Homepage, tableaux Grafana, flux n8n et autres outils. La page fournit les configurations habituelles à copier. Cette page-ci présente le catalogue des points d’accès."
},
"whereNext": {
"heading": "Pour continuer",
"items": [
{
"label": "Accès et authentification",
"href": "/docs/monitor/access-auth",
"tail": " — création de jetons, journal d’audit, jail Fail2Ban facultatif et TLS."
},
{
"label": "Notifications",
"href": "/docs/monitor/notifications",
"tailRich": " — contenu de <code>data</code> par événement lors d’un appel à <code>/api/notifications/send</code>."
},
{
"label": "Assistant IA",
"href": "/docs/monitor/ai-assistant",
"tailRich": " — fonctionnement de <code>/api/notifications/test-ai</code> et <code>/api/notifications/provider-models</code>."
},
{
"label": "Moniteur de santé",
"href": "/docs/monitor/health-monitor",
"tailRich": " — format de réponse de <code>/api/health/*</code> et sens des dix catégories."
}
]
}
}
@@ -0,0 +1,303 @@
{
"meta": {
"title": "Architecture de ProxMenux Monitor — AppImage, Flask, SQLite, WebSocket | ProxMenux",
"description": "Construction de ProxMenux Monitor : structure AppImage, blueprints Flask, tâches en arrière-plan, données psutil, pvesh, smartctl et journalctl, stockage SQLite, terminal WebSocket, fournisseurs d’IA, canaux de notification, proxy inverse et Fail2Ban facultatif.",
"ogTitle": "Architecture ProxMenux Monitor",
"ogDescription": "Dans ProxMenux Monitor : AppImage, blueprints Flask, tâches en arrière-plan, SQLite, WebSocket, fournisseurs d’IA et canaux de notification.",
"twitterTitle": "Architecture ProxMenux Monitor",
"twitterDescription": "AppImage, Flask, SQLite, WebSocket, fournisseurs d'IA et canaux de notification — à l'intérieur du moniteur."
},
"header": {
"title": "Architecture",
"description": "Comment ProxMenux Monitor est distribué, ce que contient l’AppImage et comment les requêtes du navigateur traversent Flask jusqu’aux outils de l’hôte et au stockage SQLite.",
"section": "ProxMenux Monitor"
},
"intro": {
"title": "Un processus, de nombreuses responsabilités",
"body": "Un processus Python écoute sur TCP 8008. Il sert la version statique Next.js, expose l’API REST, gère le terminal WebSocket, exécute Health Monitor et envoie les notifications. Il ne nécessite ni serveur web distinct, ni courtier de messages, ni base externe."
},
"requestFlow": {
"heading": "Parcours d’une requête",
"intro": "Une requête de données typique suit ce parcours ; les préférences du navigateur peuvent être traitées localement :",
"diagramCaption": "Les routes protégées valident JWT si l’authentification est active. Les routes centrales et blueprints renvoient des données en cache ou fraîchement collectées. Le contrôle Fail2Ban facultatif consulte sa liste de blocage en cache. Les en-têtes IP transférés sont acceptés uniquement avec PROXMENUX_TRUST_PROXY=1 ; sinon, l’adresse du pair est utilisée. L’état persistant comprend SQLite et des fichiers JSON comme auth.json.",
"diagramArrowLabel": "HTTP / WS",
"nodes": {
"clientLabel": "Client",
"clientDetail": "Navigateur ou PWA\n+ proxy facultatif\nNginx / Caddy /\nTraefik",
"flaskLabel": "Flask :8008",
"flaskDetail": "Blueprints\nMiddleware JWT\nContrôle Fail2Ban\n(si installé)",
"hostLabel": "Outils de l’hôte",
"hostDetail": "psutil\npvesh\nsmartctl\njournalctl",
"stateLabel": "État local",
"stateDetail": "SQLite DB\n+ auth.json"
},
"threadsIntro": "Le processus exécute aussi des <strong>threads en arrière-plan</strong>. Ces exemples collectent les données, actualisent les caches et SQLite et envoient les notifications. D’autres tâches existent ; l’envoi doit être activé :",
"headerThread": "Fil",
"headerCadence": "Cadence",
"headerJob": "Tâche planifiée",
"rows": [
{
"thread": "_temperature_collector_loop",
"cadence": "60 s",
"job": "Enregistre température CPU et mesures de latence dans la base d’historique pour alimenter les graphiques même sans navigateur connecté."
},
{
"thread": "_health_collector_loop",
"cadence": "5 min",
"job": "Exécute le cycle Health Monitor des dix catégories, conserve erreurs et observations de disque, tient compte des rejets et transmet les nouveaux événements au moteur de notification."
},
{
"thread": "_vital_signs_sampler",
"cadence": "CPU 5 s ; température 15 s ; mémoire 30 s",
"job": "Échantillonne CPU, mémoire et température CPU pour les indicateurs et la détection de conditions prolongées, indépendamment du contrôle global de cinq minutes."
},
{
"thread": "notification_manager.start()",
"cadence": "événementiel",
"job": "Démarre les observateurs du journal, des tâches et des hooks (<code>JournalWatcher</code>, <code>TaskWatcher</code>, <code>ProxmoxHookWatcher</code>) et envoie aux canaux configurés, avec reformulation IA facultative."
}
]
},
"systemd": {
"heading": "Unité systemd",
"intro": "L’installateur crée l’unité <code>/etc/systemd/system/proxmenux-monitor.service</code>. Configuration par défaut :",
"items": [
"<strong><code>User=root</code></strong> : le service utilise les privilèges root pour SMART, <code>pvesh</code> et la gestion ZFS. Les processus du terminal web héritent de ces droits.",
"<strong><code>Restart=on-failure</code></strong> avec attente de dix secondes : le service redémarre automatiquement après un échec.",
"<strong><code>After=network.target</code></strong> : ordonne le démarrage après cette cible ; ne garantit ni adresse IP, ni DNS, ni connexion externe."
],
"inspectTitle": "Inspecter l’unité actuelle"
},
"appimage": {
"heading": "Contenu de l’AppImage",
"intro": "L’AppImage contient un système de fichiers monté à l’exécution. <code>AppRun</code> à sa racine prépare l’environnement et lance <code>flask_server.py</code> :",
"consequencesIntro": "Deux conséquences de cette disposition :",
"consequences": [
"<strong>Environnement Python fourni.</strong> Interpréteur et paquets sont dans l’AppImage, sans installation dans le Python système. L’application utilise toujours les interfaces du noyau et les outils externes de l’hôte.",
"<strong>Clients matériels inclus.</strong> L’AppImage fournit <code>ipmitool</code>, <code>lm-sensors</code> et <code>upsc</code>. Les mesures dépendent du matériel compatible, de l’accès aux capteurs et, pour l’onduleur, d’un serveur NUT configuré."
]
},
"flask": {
"heading": "Structure de l’application Flask",
"intro": "<code>flask_server.py</code> crée une instance <code>Flask(__name__)</code> avec CORS limité, enregistre directement neuf blueprints et initialise le terminal. Le tableau montre les modules principaux ; audit, sauvegarde VM et PBS sont aussi enregistrés. Les préchargements PVE ne tournent que sur les hôtes PVE.",
"headerBlueprint": "Blueprint / module",
"headerPrefix": "Préfixe des itinéraires",
"headerOwns": "Responsabilité",
"rows": [
{
"blueprint": "flask_server.py",
"prefix": [
"/api/system",
"/api/storage",
"/api/network",
"/api/vms",
"/api/hardware",
"/api/logs",
"/api/prometheus"
],
"owns": "Points d’accès centraux, web statique et contrôle Fail2Ban facultatif si le jail <code>proxmenux</code> existe sur l’hôte."
},
{
"blueprint": "flask_auth_routes.py",
"prefix": [
"/api/auth/*"
],
"owns": "Connexion, émission JWT, configuration et vérification TOTP, changement de mot de passe et jetons API."
},
{
"blueprint": "flask_health_routes.py",
"prefix": [
"/api/health/*"
],
"owns": "Sondes d’état, détails, erreurs actives et rejetées et réglages de suppression. Les routes protégées exigent l’authentification lorsqu’elle est active."
},
{
"blueprint": "flask_terminal_routes.py",
"prefix": [
"/api/terminal/* + WS"
],
"owns": "Alloue un PTY par session et le relie par WebSocket à <code>xterm.js</code> dans le navigateur."
},
{
"blueprint": "flask_notification_routes.py",
"prefix": [
"/api/notifications/*"
],
"owns": "Créer, consulter, modifier et supprimer les canaux ; tests, IA, historique et envois manuels."
},
{
"blueprint": "flask_security_routes.py",
"prefix": [
"/api/security/*"
],
"owns": "Échecs de connexion et, avec Fail2Ban installé, état du jail, blocages et déblocage manuel."
},
{
"blueprint": "flask_proxmenux_routes.py",
"prefix": [
"/api/proxmenux/*"
],
"owns": "Lit les optimisations ProxMenux enregistrées sur l’hôte."
},
{
"blueprint": "flask_oci_routes.py",
"prefix": [
"/api/oci/*"
],
"owns": "Fonctions de déploiement d’applications OCI et conteneurs sur Proxmox VE 9.1+."
}
],
"endpointsLink": "Les points d’accès d’intégration et leurs formats sont décrits dans <link>Référence de l’API</link>."
},
"dataSources": {
"heading": "Sources des données",
"intro": "Les données de l’hôte viennent surtout de bibliothèques standard, fichiers et commandes d’administration. Certaines données des invités dépendent aussi du QEMU Guest Agent ou de commandes dans un CT :",
"headerSource": "Source",
"headerUsedFor": "Utilisé pour",
"rows": [
{
"source": "psutil",
"usedFor": "Charge CPU, mémoire, swap, occupation des montages, compteurs réseau et processus."
},
{
"source": "pvesh / qm / pct",
"usedFor": "Informations du nœud Proxmox, inventaire et configuration VM/CT, stockage et historique des tâches."
},
{
"source": "smartctl",
"usedFor": "Attributs SATA/NVMe, état SMART, usure, durée de vie, modèle et numéro de série."
},
{
"source": "zpool / zfs",
"usedFor": "État du pool (ONLINE / DEGRADED / FAULTED / UNAVAIL), progression du scrub et utilisation des datasets."
},
{
"source": "journalctl",
"usedFor": "Journaux système, processus arrêtés par OOM, erreurs ATA/NVMe/dm, sécurité et unités de service personnalisées."
},
{
"source": "ip / iproute2",
"usedFor": "Interfaces, adresses, ponts, agrégats de liens et périphériques gérés par OVS."
},
{
"source": "nvidia-smi · intel_gpu_top",
"usedFor": "Données GPU disponibles : utilisation, VRAM, température et encodage/décodage. Les champs dépendent du fabricant, de l’outil et du pilote."
},
{
"source": "lspci · lscpu · dmidecode",
"usedFor": "Topologie PCIe, modèle et topologie CPU, carte mère et BIOS."
},
{
"source": "ipmitool · sensors",
"usedFor": "Capteurs hors bande, ventilateurs et températures de la carte mère, si le matériel le permet."
},
{
"source": "upsc (NUT)",
"usedFor": "État de batterie, charge et autonomie de l’onduleur avec un serveur NUT configuré."
}
],
"cacheTitle": "Des caches réduisent les requêtes à l’hôte",
"cacheBody": "Les résultats coûteux de <code>smartctl -a</code> et <code>pvesh get</code> sont temporairement conservés dans Flask pour réduire les appels aux disques et à l’API du cluster. La durée dépend de la source : secondes pour les métriques et minutes pour SMART."
},
"persistence": {
"heading": "Persistance",
"intro": "Plusieurs fichiers d’état ont des contenus et des besoins d’accès différents :",
"headerPath": "Path",
"headerOwner": "Propriétaire",
"headerContents": "Contenu",
"rows": [
{
"path": "/usr/local/share/proxmenux/health_monitor.db",
"owner": "root:root",
"contents": "Base SQLite. Tables : <code>errors</code>, <code>events</code>, <code>disk_registry</code>, <code>disk_observations</code>, <code>user_settings</code>, <code>notification_history</code>, <code>excluded_storages</code>, <code>excluded_interfaces</code>. Journal en mode WAL."
},
{
"path": "/usr/local/share/proxmenux/.notification_key",
"owner": "root <code>0600</code>",
"contents": "Clé maîtresse de 32 octets pour les secrets de notification ENC2. Utilise un sel aléatoire par valeur, des clés dérivées et un MAC. Les anciennes valeurs XOR sont prises en charge pour migration."
},
{
"path": "/root/.config/proxmenux-monitor/auth.json",
"owner": "root:root",
"contents": "Configuration d’accès : activation, identifiant, hachage PBKDF2-HMAC-SHA256 salé du mot de passe, secret TOTP, codes de secours, clé JWT propre à l’installation, métadonnées des jetons API et empreintes de révocation. Les anciens hachages SHA-256 migrent à la connexion réussie."
},
{
"path": "/var/log/proxmenux-auth.log",
"owner": "root:root",
"contents": "Journal d’authentification en texte brut, indépendant de Fail2Ban. Si le jail <code>[proxmenux]</code> est installé et actif, il le lit pour détecter les échecs répétés. Sans ce jail, le journal reste consultable."
}
],
"backupTitle": "Sauvegarder auth.json avant réinstallation",
"backupBody": "Remplacer l’AppImage conserve normalement <code>/root/.config/proxmenux-monitor/auth.json</code> et <code>/usr/local/share/proxmenux/health_monitor.db</code>. Gardez <code>auth.json</code> avec son jwt_secret pour préserver validité et métadonnées des jetons. La base conserve séparément état et notifications. Sauvegardez <code>.notification_key</code> avec elle pour restaurer les secrets des canaux ; la base seule ne restaure pas l’authentification API."
},
"health": {
"heading": "Cycle Health Monitor",
"intro": "Environ toutes les cinq minutes, le collecteur appelle <code>health_monitor.py</code> pour les contrôles des dix catégories du tableau de bord :",
"items": [
"Services PVE critiques (<code>pveproxy</code>, <code>pvedaemon</code>, <code>pvestatd</code>, <code>pve-cluster</code>).",
"Stockages Proxmox : <code>pvesh get /storage</code> et disponibilité de chacun.",
"Disques et systèmes de fichiers : SMART, erreurs d’E/S dans dmesg, état ZFS et capacité des montages.",
"VM et CT : échecs de démarrage, arrêts inattendus, erreurs QMP et échecs d’arrêt.",
"Réseau : état des ponts et agrégats, liens et latence vers la passerelle.",
"Mises à jour : paquets en attente et correctifs de sécurité.",
"Journaux : motifs persistants, pics et cascades dans le journal système.",
"Mémoire : interventions de l’OOM killer et pression mémoire prolongée.",
"Température : mesures CPU et disques comparées aux seuils de surveillance ; les capteurs disponibles dépendent du matériel.",
"Sécurité : échecs de connexion, blocages et état du jail Fail2Ban."
],
"afterIntro": "Les constats utilisent <code>error_key</code>, catégorie et gravité stables. Les lignes d’<code>errors</code> sont mises à jour avec <code>last_seen</code> et le compteur, sans duplication. L’envoi a aussi ses propres empreintes et temporisations.",
"cycleEnd": "Le nettoyage peut résoudre les erreurs anciennes selon la <em>durée de suppression</em> par catégorie et des règles d’état, retirer les entrées orphelines des ressources supprimées et purger <code>events</code> après 30 jours. Voir <link>Tableau de bord → Health Monitor</link> pour les catégories."
},
"notifications": {
"heading": "Moteur de notifications",
"intro": "<code>notification_manager.py</code> coordonne l’envoi : charge les canaux, gère la file et fournit une API Python pour Flask et Health Monitor ainsi qu’une entrée CLI pour les hooks <code>.sh</code> de ProxMenux.",
"items": [
"Les <strong>observateurs</strong> produisent les événements : <code>JournalWatcher</code> suit le journal, <code>TaskWatcher</code> interroge les tâches Proxmox, <code>ProxmoxHookWatcher</code> reçoit les hooks de sauvegarde, réplication et snapshots, et <code>PollingCollector</code> gère les sources lentes.",
"Les <strong>modèles</strong> transforment les événements en titre et texte. Le fournisseur d’IA configuré (OpenAI / Anthropic / Gemini / Groq / Ollama / OpenRouter) peut les reformuler en langage courant. Les deux versions sont conservées dans <code>notification_history</code>.",
"Les <strong>canaux</strong> envoient par des services dont Telegram, Discord, courriel, Gotify, Pushover et Apprise. Les implémentations de <code>notification_channels.py</code> partagent l’interface <code>create_channel()</code> / <code>send()</code>.",
"<strong>Chiffrement.</strong> Les réglages sensibles (<code>telegram.bot_token</code>, <code>discord.webhook_url</code>, <code>pushover.user_key</code>, <code>pushover.api_token</code>, <code>ai_api_key_*</code>, <code>email.password</code>) sont chiffrés avec la clé de <code>.notification_key</code> avant stockage et masqués dans l’interface."
],
"linksFooter": "Les réglages par événement, options des canaux et IA sont décrits dans <notifLink>Paramètres → Notifications</notifLink> et <aiLink>Paramètres → Assistant IA</aiLink>."
},
"websocket": {
"heading": "Terminal WebSocket",
"intro": "L’onglet <em>Terminal</em> relie un client léger <code>xterm.js</code> à un PTY du serveur via WebSocket. Deux modes existent :",
"items": [
"<strong>Mode HTTP, par défaut :</strong> le serveur Flask intégré et <code>flask-sock</code> gèrent le passage au protocole WebSocket.",
"<strong>Mode HTTPS / WSS :</strong> utilise <code>gevent.pywsgi.WSGIServer</code> avec <code>geventwebsocket.handler.WebSocketHandler</code> pour WebSocket sur TLS."
],
"outro": "Les processus du terminal héritent de <code>User=root</code>. Avec authentification active, WebSocket exige un ticket bref à usage unique obtenu par le point d’accès authentifié avec droits administratifs. Si l’authentification est désactivée ou refusée, la connexion suit ce mode sans authentification.",
"proxyNote": "Avec un proxy inverse, autorisez WebSocket et ses en-têtes <code>Upgrade</code> et <code>Connection</code>. Le terminal a besoin de ce transfert."
},
"proxy": {
"heading": "Proxy inverse et Fail2Ban",
"intro": "Le choix de l’IP client et le blocage applicatif facultatif dépendent de ces réglages et composants :",
"items": [
"<strong>Choix de l’IP client.</strong> Le contrôle <code>before_request</code> et le journal d’accès acceptent <code>X-Forwarded-For</code>, puis <code>X-Real-IP</code>, uniquement avec PROXMENUX_TRUST_PROXY=1. Sinon, ils utilisent <code>request.remote_addr</code>. Les en-têtes transférés ne sont pas acceptés automatiquement.",
"<strong>Fail2Ban applicatif facultatif.</strong> Une connexion proxy peut présenter l’IP du proxy comme pair TCP. Avec l’adresse client fiable et le jail <code>proxmenux</code> actif, Flask refuse les IP bloquées par HTTP 403. La liste est conservée 30 secondes puis actualisée lors du traitement d’une requête, sans temporisateur dédié."
],
"calloutTitle": "Fail2Ban n’est pas inclus",
"calloutBody": "Fail2Ban n’est <strong>pas</strong> inclus ni installé automatiquement. Il peut être installé depuis Sécurité du Monitor ou <link>Sécurité → Fail2Ban</link> dans ProxMenux Scripts. Sans <code>fail2ban-client</code> ou le jail <code>proxmenux</code>, ce contrôle ne bloque aucune requête. La politique d’authentification configurée reste applicable.",
"outro": "Les exemples Nginx/Caddy/Traefik et le guide du jail sont dans <accessLink>Accès et authentification</accessLink> et <fail2banLink>Sécurité → Fail2Ban</fail2banLink>."
},
"whereNext": {
"heading": "Pour continuer",
"items": [
{
"label": "Accès et authentification",
"href": "/docs/monitor/access-auth",
"tail": " — premier lancement, mot de passe et TOTP 2FA, exemples de proxy inverse et jail Fail2Ban."
},
{
"label": "Référence de l’API",
"href": "/docs/monitor/api",
"tail": " — points d’accès d’intégration, gestion des jetons et conventions d’authentification."
},
{
"label": "Paramètres → ProxMenux Monitor",
"href": "/docs/settings/proxmenux-monitor",
"tail": " — commande du service et vérification de son état dans le menu texte ProxMenux."
}
]
}
}
@@ -0,0 +1,218 @@
{
"meta": {
"title": "Évaluation et inventaire | Audit et rapports",
"description": "Évaluation d'Audit et rapports : profils des rapports, classement des résultats, risques acceptés, sources illisibles, Lynis et inventaire du nœud."
},
"header": {
"title": "Évaluation et inventaire",
"description": "L'évaluation inspecte le noeud, conserve ses constatations et répond à différentes questions selon le profil du rapport.",
"section": "Audit et rapports"
},
"sections": [
{
"id": "read-only",
"blocks": [
{
"calloutInfo": {
"title": "Une évaluation inspecte; elle ne modifie pas la configuration",
"body": "Il lit la configuration et l'état de l'hôte. Il écrit ses résultats, rapports et journaux, et les vérifications de démarrage peuvent monter des partitions système EFI pour un moment. La configuration qu'elle évalue n'est pas modifiée."
}
},
{
"p": "<strong>Lancer l'évaluation</strong> démarre une exécution avec le profil choisi dans <strong>Rapport</strong>. La vue indique la date de la dernière exécution et le temps écoulé."
}
]
},
{
"id": "profiles",
"title": "Profils des rapports",
"intro": "Chaque profil répond à une question différente. Les vérifications et les sections sont sélectionnées avant la composition du document.",
"blocks": [
{
"table": {
"headers": [
"Profil",
"Ce qu'il couvre"
],
"rows": [
[
"Audit complet",
"Toutes les vérifications et toute la structure disponible."
],
[
"Diagnostic rapide",
"Chaque vérification; le résultat s'ouvre sur les constatations critiques, les avertissements et les lectures qui n'ont pas pu être vérifiées."
],
[
"Inventaire",
"Une description du noeud, sans vérification et sans classification."
],
[
"Examen de la sécurité",
"Exposition, accès, privilèges, certificats, mises à jour, dépôts et Lynis."
],
[
"Assurance de sauvegarde",
"Couverture, âge, résultats, vérification, conservation et récupération des sauvegardes."
],
[
"Capacité et usure",
"Marge de croissance, mémoire, utilisation de l'espace et la durée de vie des disques."
]
]
}
},
{
"p": "Le contenu de chaque document est décrit dans <reportsLink>Rapports et comparaisons</reportsLink>."
}
]
},
{
"id": "results",
"title": "La classification des résultats",
"blocks": [
{
"table": {
"headers": [
"Classement",
"Signification"
],
"rows": [
[
"Critique",
"Une condition ratée qui a priorité."
],
[
"Avertissement",
"Une condition qui nécessite un examen, compte tenu de la preuve ou de la politique."
],
[
"Observation",
"Informations sur le noeud qui n'est pas déclaré comme un échec."
],
[
"Non vérifié",
"La source nécessaire à la vérification n'a pas pu être lue. Cela ne signifie pas que le problème est absent."
],
[
"Conforme",
"La condition répond au critère appliqué."
],
[
"Non applicable",
"Rien dans le cadre de la vérification ne s'applique."
],
[
"Risque accepté",
"La conclusion existe et une décision à ce sujet a été enregistrée."
],
[
"Exclu par la politique",
"La politique déclare que l'élément est exclu du compte."
]
]
}
},
{
"p": "Les résultats peuvent être filtrés par zone : Système, Stockage, Réseau, Sécurité, Sauvegarde, Invités et Matériel. Chaque constatation conserve ses preuves, avec la source à laquelle elle a été lue."
}
]
},
{
"id": "unverified",
"title": "Quand une source ne peut pas être lue",
"blocks": [
{
"table": {
"headers": [
"Cas",
"Comportement"
],
"rows": [
[
"Non vérifié",
"La vérification conserve son identité, précise dans les preuves quelle source a échoué et ne transforme pas les données manquantes en résultat conforme."
],
[
"Preuves incomplètes",
"Le rapport précise la source et l'heure de collecte pour distinguer un problème réel d'une lecture insuffisante."
],
[
"Une nouvelle exécution",
"Une fois que l'accès, le paquet ou le service est corrigé, le même profil fonctionne à nouveau et la comparaison montre si le résultat peut être vérifié."
]
]
}
}
]
},
{
"id": "lynis",
"title": "Lynis",
"blocks": [
{
"p": "La revue de sécurité utilise le rapport Lynis de l'hôte. Si Lynis n'a jamais été exécuté ou si le rapport dépasse l'ancienneté autorisée par la politique, un dialogue propose <strong>Exécuter avec Lynis</strong>, qui prend quelques minutes de plus, ou <strong>Exécuter sans Lynis</strong>, qui utilise le rapport existant."
},
{
"figure": {
"src": "/monitor/audit/lynis-dialog.png",
"alt": "Boîte de dialogue qui offre d'exécuter l'évaluation avec ou sans Lynis",
"caption": "Le dialogue Lynis avant un examen de sécurité."
}
}
]
},
{
"id": "accept",
"title": "Accepter un risque",
"blocks": [
{
"p": "<strong>Accepter le risque</strong> consigne une décision sur un constat. Le motif est obligatoire et enregistré avec l'auteur et la date."
},
{
"table": {
"headers": [
"Champ",
"Possibilités"
],
"rows": [
[
"Motifs",
"Texte libre requis."
],
[
"Cesse de s'appliquer après",
"90 jours, 180 jours, 1 année ou n'expire pas. Lorsque la période prend fin, la constatation devient active à nouveau."
],
[
"Me rappeler de la revoir",
"Un rappel qui rappelle la décision pendant qu'elle reste en vigueur."
]
]
}
},
{
"p": "Un constat accepté reste visible avec la décision ; <strong>Rendre à nouveau actif</strong> révoque cette acceptation. Accepter un risque ne le corrige pas : la comparaison le signale comme accepté, pas comme résolu."
}
]
},
{
"id": "inventory",
"title": "Inventaire",
"blocks": [
{
"list": {
"items": [
"Identité, version Proxmox VE, noyau, abonnement et cluster.",
"CPU, mémoire, carte, BIOS, contrôleurs et IOMMU.",
"Disques, SMART, heures d'alimentation et événements enregistrés.",
"Adaptateurs, bonds, bridges, latence et connexions.",
"Stockage, invités avec leurs disques et interfaces, et sauvegardes.",
"PCI passthrough et le logiciel ProxMenux gère."
]
}
}
]
}
]
}
@@ -0,0 +1,208 @@
{
"meta": {
"title": "Modifications | Audit et rapports",
"description": "Journal des modifications d'Audit et rapports : changements de ProxMenux sur l'hôte, état précédent, différences et possibilité de les annuler."
},
"header": {
"title": "Modifications",
"description": "Journal des opérations effectuées par ProxMenux sur l'hôte et, lorsque capturé, de l'état avant et après chacune.",
"section": "Audit et rapports"
},
"sections": [
{
"id": "purpose",
"blocks": [
{
"calloutInfo": {
"title": "Du script exécuté à la modification effectuée",
"body": "Une longue fonction peut ne changer que deux lignes. Le journal conserve chaque opération concrète avec le script, la fonction et la version responsables, la ressource concernée, la différence et la possibilité d'annulation."
}
},
{
"flow": {
"nodes": [
{
"label": "Script",
"detail": "fonction + version"
},
{
"label": "Capture",
"detail": "contenu avant"
},
{
"label": "Opération",
"detail": "fichier · paquet · service"
},
{
"label": "Journal",
"detail": "attribution + différence"
}
],
"caption": "La capture est réalisée lors de l'exécution de l'opération et consolidée quand Monitor lit le journal."
}
},
{
"figure": {
"src": "/monitor/audit/changes-view.png",
"alt": "Vue Modifications d'Audit et rapports avec les entrées regroupées par option de post-installation et par script",
"caption": "La vue Modifications, avec la différence d'un fichier édité par ProxMenux."
}
}
]
},
{
"id": "types",
"title": "Types d'entrées",
"intro": "Le filtre en haut sépare les entrées par type.",
"blocks": [
{
"table": {
"headers": [
"Type",
"Ce qu'il enregistre"
],
"rows": [
[
"Configuration",
"ProxMenux a écrit, modifié ou supprimé un fichier, modifié un paramètre ou modifié un service."
],
[
"Installations",
"ProxMenux a ajouté un paquet ou un composant, et les paquets qui sont réellement apparus sont enregistrés."
],
[
"Exécutions",
"ProxMenux a exécuté une commande ; les changements dépendent de la commande elle-même."
],
[
"Appliqué",
"Une fonction a été appliquée avant l'existence du journal ; l'état précédent n'a pas été capturé."
]
]
}
}
]
},
{
"id": "groups",
"title": "Organisation de la vue",
"blocks": [
{
"table": {
"headers": [
"Chapitre",
"Contenu"
],
"rows": [
[
"Optimisations post-installation",
"Regroupées selon l'option de post-installation choisie par l'utilisateur."
],
[
"Scripts ProxMenux",
"GPU, Coral, réseau, stockage, sécurité, utilitaires et les autres scripts instrumentés, y compris l'installateur ProxMenux et ProxMenux Monitor."
],
[
"Paquets et utilitaires installés",
"Logiciels installés par ProxMenux sur l'hôte."
]
]
}
},
{
"p": "Dans chaque section, <strong>Par fonction</strong> regroupe les entrées sous la fonction qui les a faites."
}
]
},
{
"id": "entry",
"title": "Ce que chaque entrée montre",
"blocks": [
{
"list": {
"items": [
"Le script, la fonction et la version responsable.",
"La date et la ressource touchée.",
"L'état connu avant et après le changement.",
"Les lignes ont été ajoutées et supprimées.",
"Les paquets qui ont été effectivement ajoutés.",
"La transition d'état d'un service.",
"<strong>Annuler cette modification</strong> : <em>Restaure exactement l'état précédent</em>, <em>Supprime le fichier (inexistant auparavant)</em>, <em>Le paquet peut être désinstallé</em>, une annulation partielle ou <em>Impossible à annuler depuis le journal</em>."
]
}
}
]
},
{
"id": "before",
"title": "Signification de l'état précédent",
"blocks": [
{
"p": "L'état précédent peut être un contenu capturé, un fichier créé pour la première fois ou un état inconnu. Les modifications antérieures au journal ne peuvent pas être reconstruites ; relancer la fonction capture d'abord l'état trouvé à ce moment."
}
]
},
{
"id": "limits",
"title": "Portée du journal",
"blocks": [
{
"list": {
"items": [
"Les modifications manuelles et celles d'autres logiciels ne sont pas enregistrées.",
"Seules les opérations qui passent par les primitives d'audit ProxMenux sont couvertes.",
"L'enregistrement ne bloque jamais l'opération qu'il décrit : si l'entrée ne peut pas être écrite, l'opération continue.",
"Les changements successifs à une ressource sont indiqués comme l'origine connue par rapport à l'état actuel."
]
}
}
]
},
{
"id": "retention",
"title": "Preuves stockées",
"blocks": [
{
"table": {
"headers": [
"Élément",
"Comportement"
],
"rows": [
[
"Entrées",
"Ils sont conservés sur l'hôte; rien n'est retiré automatiquement du journal."
],
[
"Contenu capturé",
"Un objet capturé est conservé pendant qu'une entrée y fait référence."
],
[
"Taille d'une capture",
"Contenu supérieur à 1 MiB n'est pas stocké entier; l'entrée enregistre que la capture a été sautée en raison de sa taille."
],
[
"Lecture",
"Le moniteur ne charge pas les objets stockés au-dessus de 2 MiB."
],
[
"Différence",
"Au maximum 400 lignes sont affichées ; une différence plus longue est signalée comme tronquée."
],
[
"Liste",
"L'API renvoie 200 entrées par requête par défaut, avec un maximum de 1000."
]
]
}
},
{
"calloutWarning": {
"title": "Conserver le contenu n'annule pas automatiquement la modification",
"body": "Le contenu précédent peut être consulté et restauré manuellement, mais la vue Modifications n'annule pas les opérations. Une entrée d'exécution consigne la commande sans connaître tous les effets de l'outil exécuté."
}
}
]
}
]
}
@@ -0,0 +1,136 @@
{
"meta": {
"title": "Audit et rapports | ProxMenux Monitor",
"description": "Évaluez un nœud Proxmox VE, consignez les changements de ProxMenux et déclarez les attentes concernant ses invités et son stockage, avec des rapports imprimables."
},
"header": {
"title": "Audit et rapports",
"description": "Évaluation du nœud, journal des changements de ProxMenux et déclaration des attentes, avec des documents imprimables ou enregistrables en PDF.",
"section": "ProxMenux Monitor"
},
"sections": [
{
"id": "views",
"blocks": [
{
"calloutInfo": {
"title": "Trois vues, trois questions",
"body": "Audit et rapports distingue les faits du nœud, les interventions de ProxMenux et les attentes déclarées. Une configuration qui ne peut pas être évaluée selon un objectif déclaré est décrite sans être signalée comme une défaillance."
}
},
{
"cards": {
"items": [
{
"icon": "shield",
"title": "Évaluation — Comment va le nœud?",
"body": "Exécute les vérifications du profil choisi, compose l'inventaire et classe ce qui a besoin d'attention, avec la preuve de chaque résultat."
},
{
"icon": "refresh",
"title": "Changements — Qu'a fait ProxMenux?",
"body": "Répertorie les fichiers, paquets, services et commandes modifiés par les scripts ProxMenux instrumentés, avec l'état antérieur lorsqu'il a été capturé."
},
{
"icon": "fileText",
"title": "Politique — Qu'est - ce qui est attendu?",
"body": "Déclare quels invités nécessitent une sauvegarde ou doivent démarrer avec l'hôte, quel stockage est essentiel et les seuils des vérifications."
}
]
}
},
{
"flow": {
"nodes": [
{
"label": "Évaluation",
"detail": "faits"
},
{
"label": "Politique",
"detail": "contexte"
},
{
"label": "Modifications",
"detail": "interventions"
}
],
"caption": "L'évaluation fournit les faits, la politique leur donne du contexte et le journal consigne les actions de ProxMenux."
}
},
{
"figure": {
"src": "/monitor/audit/assessment-view.png",
"alt": "Audit et rapports dans ProxMenux Monitor avec les vues Évaluation, Modifications et Politique",
"caption": "Vérification et rapport, la vue d'évaluation étant ouverte."
}
}
]
},
{
"id": "boundaries",
"title": "Trois fonctions différentes",
"blocks": [
{
"table": {
"headers": [
"Fonction",
"Ce qu'il fait"
],
"rows": [
[
"<healthLink>Surveillance de santé</healthLink>",
"Observe les métriques et les événements en continu et peut déclencher des notifications."
],
[
"Audit et rapports",
"Exécute une évaluation à la demande, documente le nœud et compare les exécutions entre elles."
],
[
"Journal des modifications",
"Consigne les opérations effectuées par ProxMenux via ses primitives d'audit."
]
]
}
}
]
},
{
"id": "pages",
"title": "Pages de cette section",
"blocks": [
{
"next": {
"items": [
{
"label": "Évaluation et inventaire",
"href": "/docs/monitor/audit-report/assessment",
"tail": "profils, résultats, risques acceptés et inventaire."
},
{
"label": "Modifications",
"href": "/docs/monitor/audit-report/changes",
"tail": "le journal de ce que ProxMenux a changé sur l'hôte."
},
{
"label": "Politique",
"href": "/docs/monitor/audit-report/policy",
"tail": "invités, stockage et seuils."
},
{
"label": "Rapports et comparaisons",
"href": "/docs/monitor/audit-report/reports",
"tail": "les six documents et l'exécution de référence."
},
{
"label": "Portée et garanties",
"href": "/docs/monitor/audit-report/scope",
"tail": "les sources, les limites et les données stockées."
}
]
}
}
]
}
]
}
@@ -0,0 +1,111 @@
{
"meta": {
"title": "Politique | Audit et rapports",
"description": "Politique du nœud dans Audit et rapports : sauvegarde, démarrage automatique et objectif de reprise de chaque invité, rôle de chaque stockage et seuils des contrôles."
},
"header": {
"title": "Politique",
"description": "La politique déclare ce qu'une inspection ne peut déduire : le rôle de chaque invité et stockage et les seuils à appliquer aux vérifications.",
"section": "Audit et rapports"
},
"sections": [
{
"id": "principle",
"blocks": [
{
"calloutInfo": {
"title": "Sans déclaration, le rapport décrit ; avec une déclaration, il évalue",
"body": "Une évaluation voit ce que l'hôte fait, pas ce qu'il est pour. Un invité sans sauvegarde dont le but n'est pas déclaré est signalé comme une observation. Si sa sauvegarde est déclarée nécessaire, la même absence est signalée comme un avertissement. Rien ne doit être déclaré."
}
},
{
"figure": {
"src": "/monitor/audit/policy-view.png",
"alt": "Vue Politique avec les invités, le stockage et les seuils du nœud",
"caption": "La vue Politique."
}
}
]
},
{
"id": "guests",
"title": "Invités",
"intro": "Chaque VM et LXC du nœud comporte trois champs. Une valeur laissée par défaut prend la valeur générale, affichée à côté.",
"blocks": [
{
"table": {
"headers": [
"Champ",
"Valeurs",
"Effet sur l'évaluation"
],
"rows": [
[
"Sauvegarde",
"Requis, Non requis, Non indiqué",
"Une sauvegarde manquante est un avertissement quand elle est requise, une observation quand elle n'est pas indiquée, et elle est laissée hors du compte quand elle n'est pas requise."
],
[
"Démarrage auto",
"Requis, Non requis, Non indiqué",
"Indique si l'invité doit démarrer avec l'hôte."
],
[
"Objectif de reprise",
"Heures",
"L'âge maximum acceptable de la dernière sauvegarde."
]
]
}
}
]
},
{
"id": "storage",
"title": "Stockage",
"blocks": [
{
"p": "Un stockage inaccessible est déclaré critique lorsqu'il est déclaré essentiel ou sert un invité en cours d'exécution, comme avertissement lorsque son rôle n'est pas indiqué, et comme observation lorsqu'il est déclaré facultatif."
}
],
"intro": "Chaque stockage du noeud est déclaré essentiel, facultatif ou non indiqué."
},
{
"id": "thresholds",
"title": "Seuils",
"intro": "Un seuil vide utilise la valeur par défaut fournie, affichée comme texte indicatif.",
"blocks": [
{
"list": {
"items": [
"Vérification de la capacité de stockage (%) et du remplissage du thin pool (%).",
"Ratios de surallocation thin et de surallocation mémoire.",
"Intervalle du scrub ZFS (jours).",
"Limite de repli pour l'ancienneté des sauvegardes (jours) et marge sur le calendrier (ratio).",
"Avis d'expiration du certificat (jours).",
"Durée de vie des disques (heures) et nouvelle fenêtre d'erreur disque (jours).",
"Ancienneté du rapport Lynis (jours) et de l'index des paquets (jours).",
"Occupation du journal par rapport à son plafond (%).",
"Vérification de l'espace (%) et des inodes (%) du système de fichiers."
]
}
}
]
},
{
"id": "save",
"title": "Comment la politique est enregistrée",
"blocks": [
{
"p": "La déclaration est validée et enregistrée de manière atomique dans <code>/usr/local/share/proxmenux/audit_policy.json</code>. Chaque enregistrement porte une révision : si une autre session a changé la déclaration, le brouillon n'est pas enregistré et la vue propose de recharger la version sauvegardée."
},
{
"calloutWarning": {
"title": "La politique n'est jamais inférée",
"body": "ProxMenux n'ajoute aucune exigence de lui-même. Un champ vide conserve la valeur par défaut ou reste non déclaré ; une déclaration partielle ne concerne que les éléments qu'elle nomme."
}
}
]
}
]
}
@@ -0,0 +1,247 @@
{
"meta": {
"title": "Rapports et comparaisons | Audit et rapports",
"description": "Les six documents d'Audit et rapports, leur impression ou enregistrement en PDF et la comparaison des exécutions avec une référence."
},
"header": {
"title": "Rapports et comparaisons",
"description": "Six documents répondant à des questions différentes et la comparaison de chaque exécution avec une référence.",
"section": "Audit et rapports"
},
"sections": [
{
"id": "intro",
"blocks": [
{
"calloutInfo": {
"title": "Six documents, pas six styles",
"body": "Le moteur sélectionne les vérifications et les sections avant de composer le document. Un diagnostic rapide n'est pas une vérification complète avec moins de pages, et un inventaire ne présente aucun résultat d'évaluation. Les échantillons ci-dessous utilisent des données fictives."
}
}
]
},
{
"id": "documents",
"title": "Les six documents",
"blocks": [
{
"downloads": {
"items": [
{
"title": "Audit complet",
"body": "Documente le nœud de bout en bout sous forme de dossier technique.",
"href": "/monitor/audit/sample-audit-full-report.pdf",
"facts": [
{
"label": "Contrôles",
"value": "Toutes les vérifications disponibles."
},
{
"label": "Contenu",
"value": "Synthèse ; identité et cluster ; matériel ; réseau et latence ; stockage ; invités ; passthrough ; applications ; constats avec preuves ; sources et portée."
}
]
},
{
"title": "Diagnostic rapide",
"body": "Montre ce qui a besoin d'attention sans l'inventaire complet.",
"href": "/monitor/audit/sample-audit-diagnostic-report.pdf",
"facts": [
{
"label": "Contrôles",
"value": "Les mêmes vérifications que la vérification complète."
},
{
"label": "Contenu",
"value": "Identité minimale; constatations critiques; avertissements; observations pertinentes; lectures non vérifiées et mesures prioritaires. Les diagrammes, les inventaires et les longues annexes sont exclus."
}
]
},
{
"title": "Inventaire",
"body": "Décrit ce qui existe sur le noeud sans l'évaluer.",
"href": "/monitor/audit/sample-audit-inventory-report.pdf",
"facts": [
{
"label": "Contrôles",
"value": "Aucune; aucune conclusion n'est classée."
},
{
"label": "Contenu",
"value": "Identité ; cluster ; CPU et mémoire ; carte mère, BIOS et contrôleurs ; réseau ; stockage ; VM et LXC ; passthrough ; applications et éléments gérés par ProxMenux."
}
]
},
{
"title": "Examen de la sécurité",
"body": "Couvre l'exposition et les contrôles sur l'accès au nœud.",
"href": "/monitor/audit/sample-audit-security-report.pdf",
"facts": [
{
"label": "Contrôles",
"value": "La zone de sécurité, plus les privilèges de conteneur, les mises à jour, les dépôts et la chaîne APT."
},
{
"label": "Contenu",
"value": "Identité et cluster ; réseau et latence ; accès ; pare-feu ; 2FA ; certificats ; privilèges ; mises à jour ; dépôts ; état et ancienneté du rapport Lynis."
}
]
},
{
"title": "Assurance de sauvegarde",
"body": "Vérifier que la protection déclarée existe et que ses sauvegardes sont utilisables.",
"href": "/monitor/audit/sample-audit-backup-report.pdf",
"facts": [
{
"label": "Contrôles",
"value": "La zone de sauvegarde, la connectivité de stockage et la livraison de notification."
},
{
"label": "Contenu",
"value": "Couverture par invité ; objectif de reprise déclaré ; ancienneté et résultat ; destination ; conservation ; vérification ; tâches échouées ; reprise et sources incomplètes."
}
]
},
{
"title": "Capacité et usure",
"body": "Mesure la marge de croissance et les signes d'épuisement ou de vieillissement.",
"href": "/monitor/audit/sample-audit-capacity-report.pdf",
"facts": [
{
"label": "Contrôles",
"value": "Les zones de stockage et de matériel, plus mémoire, échange, journal et le système de fichiers hôte."
},
{
"label": "Contenu",
"value": "Utilisation et seuils ; thin pools ; surallocation ; mémoire ; inodes ; ZFS ; températures ; heures de fonctionnement ; erreurs SMART et durée de vie NVMe/SSD."
}
]
}
]
}
},
{
"figure": {
"src": "/monitor/audit/audit-report-preview.png",
"alt": "Première page d'un rapport d'audit complet",
"caption": "Chaque document partage l'identificateur de rapport, les sections numérotées, la date, le noeud, le profil et le pied de page."
}
},
{
"p": "Selon le profil, le document contient l'identité du nœud et la date d'évaluation, une synthèse, un résumé par domaine, la structure du matériel, du réseau et du stockage, la protection des invités, les constats avec preuves, les sources illisibles ainsi que la portée et la politique appliquées."
}
]
},
{
"id": "print",
"title": "Impression ou enregistrement en format PDF",
"blocks": [
{
"steps": {
"items": [
{
"title": "Exécuter",
"body": "L'évaluation utilise le profil choisi dans <strong>Rapport</strong>."
},
{
"title": "Révision",
"body": "L'exécution terminée affiche ses constats, les sources qu'elle n'a pas pu lire et la politique appliquée."
},
{
"title": "Générer le rapport",
"body": "<strong>Générer le rapport</strong> ouvre la vue préparée comme document."
},
{
"title": "Imprimer",
"body": "<strong>Imprimer ou enregistrer en PDF</strong> ouvre le dialogue d'impression du navigateur pour choisir une imprimante ou <em>Enregistrer en PDF</em>."
}
]
}
},
{
"calloutTip": {
"title": "L'impression est un document, pas une capture d'écran",
"body": "La barre d'actions est masquée, les tableaux continuant sur la page suivante répètent leur en-tête, les blocs évitent les coupures inutiles et chaque page conserve son identification et sa numérotation."
}
}
]
},
{
"id": "compare",
"title": "Comparer avec une exécution de référence",
"intro": "<strong>Utiliser comme référence</strong> marque une exécution terminée. Les exécutions suivantes lui sont comparées et leurs constats sont regroupés ainsi :",
"blocks": [
{
"table": {
"headers": [
"Groupe",
"Signification"
],
"rows": [
[
"Nouveau",
"Signalé maintenant et pas avant."
],
[
"Aggravés",
"Toujours signalés, mais plus graves ou plus étendus que précédemment."
],
[
"Améliorés",
"Toujours signalés, mais moins graves ou moins étendus que précédemment."
],
[
"Résolue",
"Ne sont plus signalés et personne ne les a acceptés."
],
[
"Acceptés",
"N'est plus compté parce qu'un risque a été accepté, pas parce que l'hôte a changé."
],
[
"Plus évalués",
"Présents auparavant mais absents de cette exécution ; leur disparition n'a pas été vérifiée."
]
]
}
},
{
"table": {
"headers": [
"Exécution de référence",
"Comportement"
],
"rows": [
[
"Réglage",
"Toute exécution terminée peut être marquée ; aucune ne l'est automatiquement."
],
[
"Changer",
"Marquer une autre exécution déplace la référence sans supprimer l'historique."
],
[
"Comparaison",
"Sans deux exécutions sélectionnées, la comparaison utilise la référence et la dernière exécution ou celle choisie."
],
[
"Conservation des exécutions",
"Les 30 exécutions les plus récentes sont conservées ; la référence est toujours préservée."
],
[
"Sans référence",
"La vue indique qu'aucune exécution de référence n'a encore été choisie ; aucune comparaison n'est donc possible."
]
]
}
},
{
"calloutWarning": {
"title": "Un rapport décrit un moment",
"body": "Une évaluation ne certifie pas une période entière. Les anciens résultats cessent de décrire l'état actuel ; la vue indique l'ancienneté de la dernière exécution et chaque source conserve son heure de collecte."
}
}
]
}
]
}
@@ -0,0 +1,115 @@
{
"meta": {
"title": "Portée et garanties | Audit et rapports",
"description": "Origine des données d'Audit et rapports, limites de son champ de vision, garanties de conception et emplacement des données."
},
"header": {
"title": "Portée et garanties",
"description": "Origine des données d'une évaluation, éléments hors de son champ de vision et emplacement des données d'Audit et rapports.",
"section": "Audit et rapports"
},
"sections": [
{
"id": "sees",
"title": "Ce qu'il observe",
"blocks": [
{
"list": {
"items": [
"Configuration et état du nœud local.",
"La configuration déclarée des VM et des LXC.",
"L'état du stockage tel que Proxmox VE le connaît.",
"L'historique disponible des sauvegardes et des vérifications.",
"Les données SMART et les événements que le moniteur a recueillis.",
"État des services, cluster, HA et sources locales."
]
}
}
]
},
{
"id": "outside",
"title": "Ce qui est hors de sa vue",
"blocks": [
{
"list": {
"items": [
"L'intérieur des invités, au-delà de ce qu'ils déclarent à Proxmox VE.",
"Équipement réseau à l'extérieur de l'hôte.",
"Dépendances éloignées que le noeud ne peut pas observer.",
"L'état physique que le matériel ne fournit pas.",
"Le journal des modifications ne couvre pas les actions manuelles ou celles d'autres logiciels."
]
}
},
{
"calloutWarning": {
"title": "Une preuve manquante n'est pas une preuve d'absence",
"body": "Une source qui ne peut être lue donne un résultat non vérifié ou incomplet, jamais conforme. Le rapport énumère les sources qui n'étaient pas disponibles."
}
}
]
},
{
"id": "guarantees",
"title": "Garanties de conception",
"blocks": [
{
"list": {
"items": [
"Des identifiants stables pour les vérifications.",
"Historique des exécutions et des constats.",
"Une politique validée, enregistrée de manière atomique.",
"Risques acceptés avec une raison visible.",
"Attribution des modifications au script et à la fonction.",
"Capture de l'état avant et après, lorsque disponible.",
"Un résultat explicite lorsque quelque chose ne peut être mesuré ou capturé."
]
}
}
]
},
{
"id": "storage",
"title": "Où les données sont stockées",
"blocks": [
{
"table": {
"headers": [
"Données",
"Emplacement"
],
"rows": [
[
"Politique",
"<code>/usr/local/share/proxmenux/audit_policy.json</code>"
],
[
"Évaluations",
"La base de données d'audit de Monitor"
],
[
"Objets capturés",
"<code>/usr/local/share/proxmenux/changes/objects/</code>"
],
[
"Entrées en attente",
"<code>/usr/local/share/proxmenux/changes/spool/</code>"
],
[
"Journal consolidé",
"<code>/usr/local/share/proxmenux/changes.db</code>"
]
]
}
},
{
"calloutInfo": {
"title": "Un outil d'examen, pas une certification",
"body": "Audit et rapports examine, compare et documente le nœud. Ses résultats s'interprètent selon l'objectif du système, la politique déclarée et les sources disponibles."
}
}
]
}
]
}
@@ -0,0 +1,174 @@
{
"meta": {
"title": "Tableau de bord Apps : un lanceur pour tous les liens web | ProxMenux",
"description": "Utilisez le tableau de bord Apps pour ouvrir les Liens Web LXC enregistrés et les liens personnalisés, les organiser par catégorie et revenir à l'invité qui possède chaque service."
},
"header": {
"title": "Tableau de bord : onglet Apps",
"description": "Un seul lanceur pour les interfaces web du nœud, qu'elles proviennent d'une application LXC enregistrée ou d'un lien personnalisé.",
"section": "ProxMenux Monitor · Tableau de bord"
},
"intro": {
"title": "Un lanceur, pas un installateur d'applications",
"body": "L'onglet <strong>Apps</strong> n'installe pas de logiciel et ne découvre pas lui-même les services. Il regroupe les liens sauvegardés dans une grille de recherche. Les liens LXC se configurent dans l'<appTabLink>onglet App</appTabLink> de l'invité ; les liens personnalisés ajoutent services VM, proxies inverses et tableaux de bord externes."
},
"sources": {
"heading": "Ce qui apparaît dans Apps",
"intro": "Chaque URL de lancement devient sa propre carte. La source détermine où cette carte est éditée, mais pas comment elle semble pendant l'utilisation normale.",
"colSource": "Source",
"colAppears": "Ce qui apparaît",
"colManagedFrom": "Où elle est gérée",
"rows": [
{
"source": "Application de LXC enregistrée",
"appears": "Une carte pour chaque lien Web enregistré sur l'enregistrement de l'application.",
"managedFrom": "VMs & LXCs → modale LXC → App"
},
{
"source": "Lien personnalisé lié à un invité",
"appears": "URL de service associée à un VM ou LXC.",
"managedFrom": "Apps → Modifier"
},
{
"source": "Lien personnalisé sans association",
"appears": "Toute destination HTTP(S), y compris un service externe ou derrière un proxy inverse.",
"managedFrom": "Apps → Modifier"
}
],
"relationshipTitle": "Les applications et l'onglet LXC App ont des tâches différentes",
"relationshipBody": "L'<appTabLink>onglet App</appTabLink> du LXC gère l'identité, les liens web et le suivi facultatif des versions. <strong>Apps</strong> utilise ces liens pour les ouvrir rapidement. Modifier une carte LXC renvoie donc à la fiche de l'invité sans dupliquer la configuration."
},
"cards": {
"heading": "Comment utiliser une carte",
"intro": "La carte entière est la cible de lancement, tandis que ses petites commandes fournissent le contexte sans ouvrir le service.",
"items": [
"Cliquez sur la carte pour ouvrir son URL dans un nouvel onglet de navigateur.",
"Le logo utilise le logo Web Link d'abord et revient au logo de l'application le cas échéant.",
"La puce de catégorie utilise la même couleur et la même étiquette que le lien Web correspondant dans l'onglet LXC App.",
"L'étiquette de l'invité identifie la VM ou le LXC associé. Un clic ouvre sa fenêtre : les liens LXC ouvrent <strong>App</strong>, ceux des VM <strong>État</strong>.",
"Une flèche vers le haut violet signifie que l'application spécifique ou l'image Docker a une mise à jour disponible. Ce n'est pas une mise à jour générale pour tout l'invité."
]
},
"toolbar": {
"heading": "Recherche, filtre et tri",
"intro": "La barre d'outils rétrécit une grande collection d'applications sans changer les enregistrements enregistrés.",
"items": [
"La recherche correspond au nom de l'application, au nom de l'invité, au VMID et à la catégorie.",
"Le filtre de catégorie montre une catégorie à la fois ou toutes les applications.",
"Triez par <strong>Nom</strong>, <strong>ID</strong> ou <strong>Catégorie</strong>. Le tri par catégorie ajoute des titres entre les groupes de cartes.",
"L'ordre est mémorisé dans ce navigateur. Le texte de recherche et le filtre de catégorie sont réinitialisés à la prochaine visite.",
"L'onglet Apps reste disponible lorsque la grille est vide, de sorte que le premier lien personnalisé peut être ajouté sans enregistrer d'abord une application LXC."
]
},
"customLinks": {
"heading": "Ajout et édition de liens Web personnalisés",
"intro": "Utilisez un lien personnalisé lorsque le service n'est pas représenté par une application LXC enregistrée.",
"steps": [
"Appuyez sur <strong>Ajouter le lien</strong> depuis la barre d'outils ou l'état vide.",
"Saisissez un nom et une URL complète <code>http://</code> ou <code>https://</code>.",
"Ajouter un logo, choisir ou créer une catégorie et lier le lien à un VM ou LXC.",
"Enregistrez le lien. Sa carte apparaît immédiatement dans la grille.",
"Pour modifier ou supprimer un lien personnalisé, cliquez sur <strong>Modifier</strong> puis sur le crayon de sa carte."
],
"colField": "Champ",
"colRequired": "Requis",
"colPurpose": "Objet",
"fields": [
{
"field": "Nom",
"required": "Oui",
"purpose": "Titre de la carte et terme de recherche."
},
{
"field": "URL",
"required": "Oui",
"purpose": "La destination complète HTTP(S) ouverte par la carte."
},
{
"field": "URL du logo",
"required": "Non",
"purpose": "Une image à distance affichée sur la carte."
},
{
"field": "Catégorie",
"required": "Non",
"purpose": "Ajoute un badge partagé et permet le filtrage de catégorie."
},
{
"field": "Association à l'invité",
"required": "Non",
"purpose": "Associé le lien avec un VM ou LXC et permet le raccourci invité."
}
],
"editTitle": "Modifier la source de la vérité",
"editBody": "Le mode édition affiche des crayons uniquement pour les liens personnalisés. Pour une carte LXC, ouvrez l'<appTabLink>onglet App</appTabLink> de l'invité et modifiez le lien sauvegardé."
},
"categories": {
"heading": "Catégories et signaux de mise à jour",
"intro": "Les catégories organisent les liens ; les indicateurs de mise à jour décrivent le logiciel. Ces fonctions sont volontairement séparées.",
"items": [
"L'enregistrement LXC assisté par catalogue peut préremplir une catégorie, mais il reste modifiable.",
"Les noms de catégorie personnalisés peuvent être créés à partir du même sélecteur, puis réutilisés par le filtre.",
"Les couleurs de catégorie sont déterministes et s'adaptent au thème clair ou sombre. Les gammes violet et rouge sont réservées aux états de mise à jour et de danger.",
"Pour Docker, ProxMenux associe la carte à son conteneur ou son image et indique les mises à jour de cette image. Celles de Docker Engine restent dans l'<updatesLink>onglet Mises à jour</updatesLink> du LXC."
]
},
"persistence": {
"heading": "Persistance et comportement de cache",
"intro": "Le tableau de bord utilise les données déjà disponibles dans Monitor sans analyser à nouveau chaque invité.",
"items": [
"Les liens personnalisés sont enregistrés de manière atomique dans <code>/etc/proxmenux/custom_links.json</code> et chargés en mémoire au démarrage de Monitor.",
"Les liens LXC restent dans la fiche de leur application enregistrée dans Monitor ; le tableau de bord Apps ne les duplique pas dans le fichier des liens personnalisés.",
"Création, édition ou suppression d'un lien personnalisé rafraîchit immédiatement la liste in-memory.",
"La préférence de tri est locale au navigateur, sans synchronisation entre appareils ou utilisateurs.",
"La position supérieure des applications est contrôlée séparément par <settingsLink>Paramètres → Ordre de navigation</settingsLink>."
]
},
"troubleshooting": {
"heading": "Situations communes",
"colProblem": "Situation actuelle",
"colResolution": "Résolution",
"rows": [
{
"problem": "Une application LXC est enregistrée mais aucune carte n'apparaît",
"resolution": "Ouvrez son onglet App et ajoutez au moins un lien Web. Le suivi des versions ne crée pas à lui seul une carte de lanceur."
},
{
"problem": "L'URL ou le logo est faux",
"resolution": "Modifier le lien personnalisé dans les applications, ou modifier le lien Web dans l'onglet propriétaire de l'application LXC."
},
{
"problem": "Il manque un service Docker",
"resolution": "Modifiez l'application Docker enregistrée et enregistrez le port web publié du service en tant que lien Web."
},
{
"problem": "La flèche pourpre se réfère à la mauvaise mise à jour Docker",
"resolution": "Consultez le nom et la description du lien Web afin qu'ils puissent être adaptés au conteneur ou à l'image prévu."
},
{
"problem": "Les applications s'ouvrent en premier lieu au lieu de Aperçu du système",
"resolution": "Le premier élément enregistré dans Paramètres → L'ordre de navigation devient l'onglet d'atterrissage. Restaurer l'ordre par défaut ou déplacer Aperçu d'abord."
}
]
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Onglet de l'application LXC",
"href": "/docs/monitor/dashboard/vms-lxcs/app",
"tail": "— enregistrer les applications, les liens Web et le suivi facultatif des versions."
},
{
"label": "Onglet Mises à jour LXC",
"href": "/docs/monitor/dashboard/vms-lxcs/updates",
"tail": " — configurer et lancer les mises à jour des applications, de Docker Engine et des images."
},
{
"label": "Onglet Paramètres",
"href": "/docs/monitor/dashboard/settings#navigation-order",
"tail": "— modifier l'ordre de navigation et l'onglet d'atterrissage."
}
]
}
}
@@ -0,0 +1,248 @@
{
"meta": {
"title": "ProxMenux Monitor — Tableau de bord : Matériel | Documentation ProxMenux",
"description": "L'onglet Matériel inventorie la machine physique : CPU, carte mère, modules mémoire, capteurs thermiques, GPU avec surveillance par emplacement et installation du pilote en un clic, accélérateurs Coral TPU, résumé du stockage avec vitesses de liaison, listes PCI et USB, consommation, alimentations, ventilateurs et état de l'onduleur."
},
"header": {
"title": "Tableau de bord : onglet matériel",
"description": "La machine physique en un seul écran — CPU et identité carte mère, chaque module de mémoire, capteurs thermiques dans tous les sous-systèmes, GPU avec utilisation en direct et un installateur de pilote intégré, Coral TPU, chaque PCI et périphérique USB avec son pilote de noyau, l'inventaire du disque complet avec des vitesses de liaison négociées, plus la puissance, le refroidissement et l'UPS.",
"section": "ProxMenux Monitor · Tableau de bord"
},
"intro": {
"title": "Construit à partir d'outils standard",
"body": "La plupart de cet onglet est analysé à partir de <code>lscpu</code>, <code>dmidecode</code>, <code>lspci</code>, <code>lsusb</code>, <code>lsblk</code>, <code>smartctl</code>, <code>nvme</code>, <code>sensors</code>, <code>nvidia-smi</code>, <code>intel_gpu_top</code>, <code>amdgpu_top</code>, <code>ipmitool</code> et <code>upsc</code>. Les sections ne rendent que lorsque l'outil concerné renvoie des données, de sorte qu'un hôte sans UPS n'affiche pas la carte UPS et qu'un hôte sans IPMI n'affiche pas de chiffres de puissance hors bande."
},
"thresholds": {
"title": "Couleurs et seuils appliqués ici",
"intro": "Chaque indicateur et mesure de température suit la même échelle : <green/> <strong>vert</strong> sous Avertissement, <amber/> <strong>ambre</strong> entre Avertissement et Critique, <red/> <strong>rouge</strong> à partir de Critique. Valeurs recommandées fournies avec ProxMenux :",
"items": [
"<strong>Température CPU</strong> — avertissement 80 °C, critique 90 °C.",
"<strong>Température du disque</strong> — HDD 60/65 °C · SSD 70/75 °C · NVMe 80/85 °C · SAS 55/65 °C (avertissement / critique)."
],
"outro": "Les valeurs sont configurables par hôte. <link>Paramètres → Seuils du moniteur de santé</link> centralise leur réglage et explique comment les adapter."
},
"sections": {
"heading": "Sections",
"intro": "Les sections apparaissent dans cet ordre, de haut en bas. Certaines exigent le matériel ou l'outil correspondant et sont indiquées <em>(conditionnel)</em> ci-dessous.",
"systemInfoTitle": "Informations système",
"systemInfoIntro": "Deux blocs côte à côte, toujours présents:",
"systemInfoItems": [
"<strong>CPU</strong> — modèle, microarchitecture, sockets/cœurs/threads, fréquences de base et boost, capacités de virtualisation (VT-x / AMD-V) et topologie du cache.",
"<strong>Carte mère</strong> — fabricant, modèle, version et date du BIOS, UUID SMBIOS. Permet de trouver la bonne page de téléchargement du fabricant pour le firmware."
],
"memoryTitle": "Modules de mémoire",
"memoryBody": "Une ligne par emplacement occupé selon <code>dmidecode</code> : étiquette, capacité du module, type (DDR4 / DDR5 / variantes ECC), vitesse configurée et nominale, fabricant, référence et numéro de série. Les emplacements vides sont grisés pour montrer les possibilités d'extension.",
"thermalTitle": "Surveillance thermique",
"thermalIntro": "Sept blocs alimentés par <code>lm-sensors</code>, <code>sysfs</code> et des collecteurs propres à chaque outil. Les capteurs hwmon de stockage sont associés au périphérique bloc physique, avec son modèle et son chemin <code>/dev/...</code>. Un bloc est masqué si sa catégorie ne contient aucun capteur.",
"thermalItems": [
"<strong>CPU</strong> — température du boîtier du processeur et de chaque cœur.",
"<strong>GPU</strong> — capteurs de GPU dédié via <code>nvidia-smi</code> / <code>amdgpu_top</code> et d'iGPU Intel. Inclut le point chaud et la température de jonction mémoire si le pilote les fournit.",
"<strong>NVME</strong> — température composite du contrôleur associée à son espace de noms NVMe exact.",
"<strong>HDD</strong> — <code>drivetemp</code> lectures pour les dispositifs de blocs rotatifs.",
"<strong>SSD</strong> — lectures <code>drivetemp</code> pour les dispositifs de blocs SATA/SAS non rotatifs.",
"<strong>PCI</strong> — capteurs qui se présentent comme des dispositifs fixés par PCI (HBA, cartes réseau avec capteurs internes).",
"<strong>OTHER</strong> — chipset, VRM, capteurs ambiants qui ne s'adaptent pas ailleurs."
]
},
"graphics": {
"heading": "Cartes graphiques",
"intro": "Chaque contrôleur vidéo apparaît dans une carte avec fabricant, modèle, type (<em>Intégré</em> / <em>PCI</em> / BMC), adresse PCI (BDF), pilote noyau et modules. <strong>Changer de mode</strong> bascule entre partage LXC avec pilote natif et passthrough VM (<code>vfio-pci</code>). <link>Changer le mode GPU (VM ↔ LXC)</link> explique les effets sur l'hôte.",
"vfioImageAlt": "Section des cartes graphiques montrant un GPU intégré à Matrox G200EH lié à mgag200 (Ready pour LXC) et un NVIDIA Quadro P400 lié à vfio-pci (Ready pour VM passthrough)",
"vfioImageCaption": "Deux GPU détectés : la puce Matrox BMC est sur le pilote natif et prête pour LXC ; le NVIDIA Quadro P400 est lié à <code>vfio-pci</code>, prêt pour le passage VM.",
"lxcImageAlt": "Cartes graphiques : iGPU Intel UHD Graphics avec i915 et NVIDIA Quadro P1000 avec nvidia, toutes deux prêtes pour les conteneurs LXC",
"lxcImageCaption": "Même noeud après avoir retourné la carte NVIDIA au pilote natif — les deux GPU sont maintenant prêts pour les conteneurs LXC.",
"realtimeTitle": "Fenêtre de surveillance en temps réel",
"realtimeBody": "Un clic ouvre la surveillance du GPU par emplacement, avec une requête à l'outil du fabricant toutes les trois secondes. Elle affiche fabricant, type, emplacement PCI, pilote, modules noyau, utilisation des moteurs (Render/3D, Video, Blitter, VideoEnhance), fréquences graphique et mémoire, température, consommation si disponible, VRAM et processus actifs avec leur charge moteur. Données de <code>/api/gpu/&lt;slot&gt;/realtime</code>.",
"toolsIntro": "L'outil fournisseur utilisé par GPU:",
"headerVendor": "Fournisseur",
"headerTool": "Outil",
"headerProject": "Projet",
"tools": [
{
"vendor": "NVIDIA",
"tool": "nvidia-smi",
"projectLabel": "developer.nvidia.com",
"projectHref": "https://developer.nvidia.com/nvidia-system-management-interface"
},
{
"vendor": "Intel iGPU",
"tool": "intel_gpu_top (igt-gpu-tools)",
"projectLabel": "gitlab.freedesktop.org",
"projectHref": "https://gitlab.freedesktop.org/drm/igt-gpu-tools"
},
{
"vendor": "AMD",
"tool": "amdgpu_top",
"projectLabel": "github.com/Umio-Yasuno/amdgpu_top",
"projectHref": "https://github.com/Umio-Yasuno/amdgpu_top"
},
{
"vendor": "Matrox / ASPEED (BMC)",
"tool": "— (affichage uniquement)",
"projectLabel": "Détecté et étiqueté comme BMC; aucun bloc en temps réel."
}
],
"nvidiaImageAlt": "Surveillance NVIDIA Quadro P1000 : fabricant NVIDIA, pilote nvidia chargé, fréquence graphique 1.26 GHz, mémoire 2.50 GHz, température 50 °C, moteurs à 0 %, aucun processus actif, mémoire totale 4096 MiB",
"nvidiaImageCaption": "NVIDIA Quadro P1000 avec pilote propriétaire : fréquences, température, barres d'utilisation des moteurs et processus actifs.",
"intelImageAlt": "Surveillance d'une iGPU Intel UHD Graphics avec i915 : consommation 11.31 W, charge vidéo 1 % et processus ffmpeg utilisant 8 MB",
"intelImageCaption": "Intel iGPU avec <code>i915</code> actif. La table Active Processes reprend un travail ffmpeg en utilisant le moteur vidéo.",
"amdImageAlt": "Surveillance du GPU intégré AMD Lucienne avec amdgpu : moteurs à 0 % et amdgpu_top comme processus actif",
"amdImageCaption": "iGPU AMD surveillée avec <code>amdgpu_top</code>. L'outil apparaît lui-même comme processus actif car il collecte les données en direct.",
"installTitle": "Installer le pilote NVIDIA depuis la fenêtre",
"installBody": "Avec <code>nouveau</code>/<code>nvidiafb</code> sans pilote propriétaire NVIDIA, les fréquences, la consommation et la charge par processus ne sont pas disponibles. La fenêtre propose <strong>Installer les pilotes NVIDIA</strong>, qui lance le script décrit dans <link>Installer les pilotes NVIDIA (hôte)</link>.",
"noDriverAlt": "Surveillance NVIDIA Quadro P620 avec nvidiafb et nouveau chargés, avertissement Surveillance étendue indisponible et bouton bleu Installer les pilotes NVIDIA",
"noDriverCaption": "Aucun pilote propriétaire installé : la fenêtre propose un installateur en un clic.",
"promptAlt": "Confirmation d'installation du pilote NVIDIA, avec GPU détectés, conteneurs LXC utilisant le passthrough NVIDIA et boutons Oui/Annuler",
"promptCaption": "Résumé avant installation : GPU détectés, conteneurs LXC avec passthrough NVIDIA et actions prévues. Aucune modification avant confirmation.",
"successAlt": "Sortie terminale montrant le pilote NVIDIA 580.105.08 installé avec succès et nvidia-smi signalant un Quadro P620",
"successCaption": "Installation réussie — le NVIDIA <code>.run</code> construit via DKMS, le service de persistance est en place, et <code>nvidia-smi</code> rapporte le GPU.",
"warningTitle": "Choisissez une version de pilote que votre GPU prend en charge",
"warningBody": "Les nouvelles branches NVIDIA abandonnent certaines anciennes familles GPU, comme Maxwell ou Kepler. Si <code>nvidia-smi</code> affiche <em>\"No devices were found\"</em> après l'installation ou si DKMS échoue, la branche peut être incompatible. Relancez avec une branche plus ancienne, comme legacy 470.x pour Kepler. Vérifiez la compatibilité sur la <a>page officielle de recherche des pilotes</a>.",
"whereGoIntro": "Où aller d'ici :",
"whereGoItems": [
"<link1>Installer les pilotes NVIDIA (hôte)</link1> — guide complet, matrice de compatibilité du noyau, correctif NVENC facultatif et propagation aux LXC.",
"<link2>Changer le mode GPU (VM ↔ LXC)</link2> — effets de la commande <em>Changer de mode</em> de la carte.",
"<link3>Ajouter un GPU à une VM (passthrough)</link3> et <link4>Ajouter un GPU à un LXC</link4> — première affectation d'un GPU non associé."
]
},
"coral": {
"heading": "Accélérateurs Coral TPU / AI",
"subHeading": "(conditionnel)",
"intro": "Apparaît avec des appareils Google Coral ou d'autres accélérateurs IA connectés. La fenêtre affiche connexion (M.2 / mini-PCIe / USB), largeur PCIe, ID fabricant/produit, support logiciel (<code>apex</code> dans le noyau pour PCIe, <code>libedgetpu</code> en espace utilisateur pour USB), modules (<code>gasket</code> + <code>apex</code>), nœuds (<code>/dev/apex_*</code>), état du runtime Edge TPU, température en direct et seuils d'alerte du firmware.",
"imageAlt": "Coral Edge TPU détail modal : connexion PCIe / M.2, PCIe 5.0 lien GT/s x1, fournisseur 1ac1:089a, pilote noyau apex, gasket et apex modules chargés, /dev/apex_0 présents, Edge TPU Runtime non installé, température 53.5 °C avec seuils d'avertissement matériels",
"imageCaption": "M.2 Coral avec les modules du noyau hôte chargés, le nœud du périphérique activé et les avertissements de température du micrologiciel exposés. La ligne d'exécution devient verte une fois que le runtime Edge TPU correspondant est installé.",
"pathsIntro": "Deux chemins d'installation existent selon le facteur de forme :",
"pathsItems": [
"<strong>M.2 / Mini-PCIe</strong> — l'hôte a besoin des modules du noyau <code>gasket</code> + <code>apex</code> construits via DKMS afin que le noeud du périphérique <code>/dev/apex_0</code> apparaisse au démarrage.",
"<strong>USB Accélérateur</strong> — l'hôte n'a besoin que de l'espace utilisateur Edge TPU (<code>libedgetpu1-std</code>) du dépôt APT de Google."
],
"outro": "<installLink>Installer Coral TPU sur l'hôte</installLink> détecte et gère les deux variantes. Contexte et runtime officiel sur <a>coral.ai/docs</a>. Ensuite, affectez l'appareil à un conteneur avec <lxcLink>Ajouter Coral TPU à un LXC</lxcLink>."
},
"storage": {
"heading": "Résumé du stockage",
"intro": "Tous les périphériques bloc connus du noyau, regroupés par type. Chaque disque montre son nom (<code>sda</code>, <code>nvme0n1</code>, <code>zram0</code>…), type (<em>SSD</em>, <em>HDD</em>, <em>NVMe SSD</em>), modèle et lien négocié. Un clic ouvre modèle, numéro de série, capacité, interface et vitesse de liaison actuelle et maximale.",
"imageAlt": "Résumé du stockage avec onze périphériques bloc (SSD SATA, HDD SATA, SSD NVMe et zram), modèles et liens négociés ; deux NVMe en 3.0 x4 avec vitesse actuelle surlignée",
"imageCaption": "Onze appareils sur ce nœud. Les liens SATA sont affichés sous la forme <em>SATA &lt;version&gt;, &lt;Gb/s&gt; (current: ...)</em> ; les NVMe sous la forme <em>&lt;PCIe gen&gt; x&lt;width&gt;</em>.",
"nvmeBody": "Pour chaque NVMe, la ligne compare le lien négocié au maximum pris en charge. S'ils diffèrent, par exemple un SSD Gen3 x4 à <strong>3.0 x1</strong> dans un emplacement câblé sur une voie, la valeur actuelle apparaît en ambre. Utile pour diagnostiquer un disque lent ou une réaffectation des voies après une mise à jour BIOS.",
"nvmeModalAlt": "NVMe drive detail modal pour nvme0n1: NVMe type SSD, 953.9 capacité GB, vitesse de liaison actuelle 3.0 x1 mis en évidence en ambre, vitesse de liaison maximale 3.0 x4, modèle WDC CL SN720, numéro de série, interface PCIe/NVMe",
"nvmeModalCaption": "Détails NVMe avec lien réduit : le disque prend en charge x4, mais l'emplacement est câblé en x1.",
"outro": "Données SMART, autotests, historique et rapport PDF sont dans <storageLink>Tableau de bord : Stockage</storageLink>. Les mêmes données alimentent <smartLink>Santé et tests SMART des disques</smartLink>. Un test long lancé par le script écrit le JSON affiché dans <em>Stockage → Historique</em>."
},
"pci": {
"heading": "Périphériques PCI",
"intro": "Appareils PCI identifiés par leur <strong>BDF PCI</strong> (Bus:Device.Function, par exemple <code>03:00.0</code>) et classe (<em>Contrôleur de stockage</em>, <em>Contrôleur USB</em>, <em>Carte graphique</em>, <em>Contrôleur réseau</em>, <em>Contrôleur audio</em>…). Chaque carte montre fabricant, nom et <strong>pilote noyau associé</strong>, utiles pour diagnostiquer passthrough, groupes IOMMU ou mauvais pilote.",
"imageAlt": "PCI Devices section énumérant quinze périphériques regroupés par classe: contrôleurs de stockage sur ahci/nvme, contrôleurs USB, cartes graphiques (un sur vfio-pci, un sur le pilote natif), contrôleurs réseau sur igb / tg3, un contrôleur audio à côté d'un GPU passé",
"imageCaption": "Quinze appareils sur ce nœud. Notez que le GPU et sa fonction audio associée sont liés au <code>vfio-pci</code> — c'est-à-dire une carte préparée pour la transmission du VM.",
"bdfTitle": "Lecture du BDF",
"bdfBody": "<code>03:00.0</code> signifie bus PCI <code>03</code>, périphérique <code>00</code>, fonction <code>0</code>. Les GPU dédiés utilisent généralement <code>.0</code> pour le GPU et <code>.1</code> pour l'audio HDMI. Les deux fonctions sont transmises ensemble à la VM ; <link>Changer le mode GPU</link> nettoie donc aussi les associations audio orphelines en quittant le mode VM."
},
"usb": {
"heading": "Périphériques USB",
"intro": "Appareils USB avec fabricant et produit, version USB, adresse <code>bus:device</code>, ID <code>vendor:product</code> et pilote noyau. Classement par rôle : <em>Communications</em> (adaptateurs Z-Wave / Zigbee), <em>Onduleur</em>, stockage ou HID. Les appareils sont ainsi identifiables sans comparer leurs ID.",
"imageAlt": "Appareils USB : Aeotec Z-Wave Z-Stick, coordinateur Zigbee ConBee II et onduleur Ellipse ECO, avec version USB, adresse, ID vendor:product et pilote associé",
"imageCaption": "Trois appareils USB – deux radios d'automation sur <code>usbfs</code> et un UPS sur <code>usbfs</code> (NUT lui parle par libusb)."
},
"power": {
"heading": "Consommation d'énergie",
"subHeading": "(conditionnel)",
"intro": "Apparaît si l'hôte fournit des mesures de puissance. Deux sources indépendantes sont affichées lorsqu'elles sont disponibles :",
"items": [
"<strong>Consommation totale ACPI / IPMI</strong> — puissance de tout le système mesurée par un capteur de carte mère ou le BMC. Courant sur les cartes serveur.",
"<strong>Puissance du processeur</strong> — compteurs Intel RAPL ou équivalent AMD. Distingue la consommation CPU du reste sur les cartes grand public sans mesure globale."
],
"supplyImageAlt": "Consommation : 198 W au total via ACPI et deux alimentations à l'état OK, délivrant 185 W et 5 W",
"supplyImageCaption": "Carte serveur avec un capteur de puissance ACPI unique et deux PSU signalés par IPMI — le deuxième PSU est le redondant, au ralenti à 5 W.",
"cpuImageAlt": "Consommation sur une carte grand public : seulement 8.7 W de CPU via Intel RAPL",
"cpuImageCaption": "Carte grand public sans capteur global : seule la consommation CPU via RAPL est affichée."
},
"psu": {
"heading": "Alimentations",
"subHeading": "(conditionnel)",
"body": "Sur les machines serveur à double alimentation, IPMI montre présence (PSU 1 / PSU 2 / …), tension d'entrée, puissance de sortie et état OK/défaillant. À vérifier après une coupure électrique sur un nœud à alimentations redondantes."
},
"fans": {
"heading": "Ventilateurs système",
"subHeading": "(conditionnel)",
"body": "Vitesse de chaque ventilateur en tr/min avec mini-courbe si disponible. Sans mesures individuelles, une seule valeur de ventilateur du châssis est affichée."
},
"ups": {
"heading": "Statut UPS",
"subHeading": "(conditionnel)",
"body": "Apparaît avec un serveur NUT (Network UPS Tools) configuré et joignable. Affiche état (secteur / batterie / charge / batterie faible), niveau de batterie, autonomie estimée, taux de charge de l'onduleur, tension d'entrée, modèle et firmware. Les données alimentent aussi <em>Sécurité et certificats</em> du moniteur de santé : le passage sur batterie est immédiatement signalé."
},
"dataCollected": {
"heading": "Comment les données sont collectées",
"headerSection": "Section de l'onglet",
"headerEndpoint": "Point de terminaison",
"headerSource": "Source",
"rows": [
{
"section": "Inventaire statique (PCI, CPU, BIOS)",
"endpoint": "/api/hardware",
"source": "<code>lspci -vmm</code>, <code>/proc/cpuinfo</code>, <code>dmidecode</code>; mis en cache pendant toute la durée du processus."
},
{
"section": "Valeurs réelles du capteur",
"endpoint": "/api/hardware/live",
"source": "<code>sensors</code> (lm-sensors), <code>/sys/class/hwmon</code> et <code>/sys/block</code> identifient les périphériques de stockage. Les températures restent en direct ; seule la correspondance hwmon-appareil est mise en cache 60 secondes."
},
{
"section": "Historique de température CPU",
"endpoint": "/api/temperature/history",
"source": "Série temporelle enregistrée toutes les 60 secondes par le collecteur de température et stockée dans SQLite."
},
{
"section": "GPU métriques vivantes",
"endpoint": "/api/gpu/<slot>/realtime",
"source": "NVIDIA: <code>nvidia-smi --query-gpu=...</code>. Intel: <code>intel_gpu_top</code>. AMD: sysfs <code>/sys/class/drm/cardN</code>."
}
],
"codeComment1": "# Comparer l'inventaire à la vue du système d'exploitation",
"codeComment2": "# Confirmer la carte GPU que le tableau de bord voit"
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Installer les pilotes NVIDIA (host)",
"href": "/docs/hardware/nvidia-host",
"tail": " — script lancé par le bouton d'installation de la fenêtre GPU."
},
{
"label": "Changer le mode GPU (VM ↔ LXC)",
"href": "/docs/hardware/switch-gpu-mode",
"tail": " — effets sur l'hôte du changement de mode dans chaque carte GPU."
},
{
"label": "Installez Coral TPU sur l'hôte",
"href": "/docs/hardware/install-coral-tpu-host",
"tail": " — installation du module noyau et du runtime Coral."
},
{
"label": "Santé et test du disque SMART",
"href": "/docs/disk-manager/smart-disk-test",
"tail": " — script qui produit les données SMART affichées dans les détails du disque sous Stockage."
},
{
"label": "Tableau de bord : onglet de stockage",
"href": "/docs/monitor/dashboard/storage",
"tail": "— tableau complet des attributs SMART, historique d'auto-test et rapport PDF."
},
{
"label": "Moniteur de santé",
"href": "/docs/monitor/health-monitor",
"tail": " — catégorie CPU et température, qui utilise les mêmes capteurs."
},
{
"label": "Référence de l’API",
"href": "/docs/monitor/api",
"tail": " — points de terminaison matériel et GPU."
},
{
"label": "Index du tableau de bord",
"href": "/docs/monitor/dashboard",
"tail": "— les autres onglets."
}
]
}
}
@@ -0,0 +1,101 @@
{
"meta": {
"title": "ProxMenux Monitor — Tableau de bord | Documentation ProxMenux",
"description": "Le tableau de bord est l'interface principale de ProxMenux Monitor : dix onglets, dont le lanceur Apps, un en-tête global et un ordre de navigation configurable."
},
"header": {
"title": "Tableau de bord",
"description": "La vue quotidienne de ProxMenux Monitor : dix onglets, dont le lanceur Apps, un en-tête global et un ordre de navigation configurable.",
"section": "ProxMenux Monitor"
},
"oneHeader": {
"title": "Un en-tête, dix onglets",
"body": "L'en-tête (logo, nom du nœud, indicateur d'état, durée de fonctionnement, actualisation et thème) reste visible. L'onglet actif change toute la zone de contenu. La couleur de l'indicateur reflète la catégorie la plus grave du <link>moniteur d'état</link> : la même donnée est affichée sur le tableau de bord."
},
"tabs": {
"heading": "Les dix onglets",
"intro": "Chaque onglet a sa propre page dédiée. Les pages sont ajoutées progressivement à mesure que la documentation est remplie; ci-dessous est la liste complète et la responsabilité de chacun.",
"headerTab": "onglet",
"headerOwns": "Ce que cet onglet couvre",
"rows": [
{
"name": "Présentation du système",
"linksTo": "/docs/monitor/dashboard/system-overview",
"owns": "CPU / mémoire / widgets de température, nombre de VM et LXC actifs, graphiques historiques, stockage et résumés réseau. Onglet d'atterrissage par défaut jusqu'à ce que l'ordre de navigation soit personnalisé."
},
{
"name": "Applications",
"linksTo": "/docs/monitor/dashboard/apps",
"owns": "Lanceur unifié de liens web LXC enregistrés et de liens personnalisés, avec catégories, recherche, raccourcis vers les invités et indicateurs de mise à jour par application."
},
{
"name": "Stockage",
"owns": "Pools Proxmox, disques physiques, données SMART, état ZFS, usure et durée de vie, historique d'observation."
},
{
"name": "Réseau",
"owns": "Interfaces physiques, bonds, bridges et OVS, adresses IP/MAC, graphiques RX/TX et historique RRD par interface."
},
{
"name": "VM et LXC",
"owns": "Inventaire des invités, détails de configuration, métriques et journaux, actions de démarrage, arrêt, redémarrage et extinction."
},
{
"name": "Matériel",
"owns": "Modèle et topologie CPU, mise en page de mémoire, topologie PCIe, GPUs avec surveillance en temps réel per-slot."
},
{
"name": "Journaux système",
"owns": "Live <code>journalctl</code> avec filtres, historique des tâches Proxmox, journal de notification, paquets de journaux téléchargeables."
},
{
"name": "Terminal",
"owns": "Shell vers l'hôte ou toute VM/CT dans le navigateur, avec <code>xterm.js</code> via WebSockets."
},
{
"name": "Sécurité",
"owns": "Configuration auth, mot de passe / 2FA / API jetons, journal d'audit, panneau Fail2Ban optionnel, déploiement Secure Gateway."
},
{
"name": "Paramètres",
"owns": "Langue de Monitor, ordre de navigation, canaux de notification, fournisseur IA, seuils de surveillance, exclusions et inventaire des optimisations après installation."
}
]
},
"headerAnatomy": {
"heading": "Anatomie en-tête",
"items": [
"<strong>Logo + nom du produit</strong> sur la gauche. Le logo se transforme en une variante \"mise à jour disponible\" quand une nouvelle version de Monitor est détectée.",
"<strong>Identité du nœud</strong> : nom obtenu par <code>pvesh get /nodes</code>, avec <code>hostname</code> en solution de repli.",
"<strong>Indicateur d'état</strong> : Sain (vert), Avertissement (jaune), Critique (rouge). Un clic ouvre le moniteur d'état. Un badge bleu <em>info</em> apparaît si des éléments ignorés restent dans leur période de suppression.",
"<strong>Durée de fonctionnement</strong> : temps d'activité de l'hôte dans un format lisible.",
"<strong>Bouton Actualiser</strong> : relance les appels API des données en direct sans recharger toute la page.",
"<strong>Sélecteur de thème</strong> : clair, sombre ou système. Enregistré dans <code>localStorage</code>."
]
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "onglet Apps",
"href": "/docs/monitor/dashboard/apps",
"tail": " — lanceur unifié de liens web et relation avec les applications LXC enregistrées."
},
{
"label": "Onglet Aperçu du système",
"href": "/docs/monitor/dashboard/system-overview",
"tail": "— l'onglet d'atterrissage, entièrement documenté."
},
{
"label": "Moniteur de santé",
"href": "/docs/monitor/health-monitor",
"tail": " — fenêtre de l'indicateur d'état, avec le détail des dix catégories."
},
{
"label": "Architecture",
"href": "/docs/monitor/architecture",
"tail": "— comment le tableau de bord parle au moteur de Flask."
}
]
}
}
@@ -0,0 +1,251 @@
{
"meta": {
"title": "ProxMenux Monitor — Tableau de bord : onglet Réseau | Documentation ProxMenux",
"description": "L’onglet Réseau répertorie les interfaces de l’hôte : cartes physiques, ponts, agrégats, VLAN et interfaces virtuelles VM/LXC. Le détail affiche IP, MAC, état, membres de l’agrégat, trafic depuis le démarrage et historique RRD."
},
"header": {
"title": "Tableau de bord : onglet réseau",
"description": "Les interfaces signalées par le noyau — cartes physiques, ponts, agrégats, VLAN et ports virtuels VM/LXC — sont regroupées en trois cartes. Cliquez sur une ligne pour voir les adresses, compteurs de trafic et données historiques RRD.",
"section": "ProxMenux Monitor · Tableau de bord"
},
"intro": {
"title": "Données actuelles et historiques",
"body": "L’état actuel provient de <code>psutil.net_if_stats()</code> et d’<code>ip</code>, l’historique de bande passante du stockage RRD Proxmox via <code>/api/network/&lt;interface&gt;/metrics</code>. Les compteurs sont actualisés environ toutes les 5 secondes et les données RRD du graphique sont chargées à la demande."
},
"topRow": {
"heading": "Rangée supérieure : quatre cartes statistiques",
"headerCard": "Carte",
"headerWhat": "Ce qu'il montre",
"rows": [
{
"card": "Trafic réseau",
"what": "Taux agrégé RX / TX sur toutes les interfaces, formaté dans la bonne unité (bps / Kbps / Mbps / Gbps)."
},
{
"card": "Interfaces actives",
"what": "Deux compteurs : <em>Physical X / Y</em> et <em>Bridges X / Y</em>, actifs par rapport au total. Un premier point à vérifier en cas de panne."
},
{
"card": "État du réseau",
"what": "État rapide : Sain / Avertissement / Critique selon la liaison, l’accessibilité de la passerelle et l’intégrité du pont. Reprend la catégorie <em>Interfaces réseau</em> de Health Monitor."
},
{
"card": "Latence du réseau",
"what": "Temps aller-retour vers la passerelle avec un petit graphique. Un clic ouvre le <strong>dialogue Latence réseau</strong> décrit plus bas : historique et test ping à la demande vers la passerelle, Cloudflare ou Google, avec rapport PDF téléchargeable."
}
]
},
"flow": {
"heading": "Diagramme de flux réseau",
"intro": "Entre la rangée supérieure et les trois cartes, <strong>Network Flow</strong> affiche la topologie en direct. Les chemins des paquets relient les cartes physiques, les ponts au centre, puis les VM et conteneurs. Les impulsions animées représentent le trafic rx/tx actuel sur chaque liaison.",
"imageAlt": "Schéma de flux réseau — NIC à gauche, hôte et ponts au milieu, VM et LXC à droite, avec impulsions animées sur chaque connexion",
"imageCaption": "Flux réseau — nœuds codés en couleurs plus comètes animées dont la direction et l'épaisseur reflètent le trafic en direct.",
"elementsTitle": "Ce que montre le diagramme",
"elementsIntro": "Chaque nœud représente une entrée du même inventaire que les cartes ci-dessous. La disposition en topologie rend leurs relations immédiatement visibles :",
"elements": [
"<strong>Cartes réseau</strong> (orange) — interfaces physiques avec liaison active ; les inactives sont estompées.",
"<strong>Hôte</strong> (orange) — l’hôte Proxmox entre les cartes réseau et les ponts. Un point fixe non cliquable.",
"<strong>Ponts</strong> (cyan) — ponts Linux et OVS avec au moins une machine invitée active. Les ponts inutilisés sont masqués pour centrer le diagramme sur le trafic réel.",
"<strong>LXC</strong> (cyan) — conteneurs en cours d’exécution reliés à un pont.",
"<strong>VM</strong> (violet) — machines virtuelles en cours d’exécution reliées à un pont.",
"Les VM et conteneurs arrêtés sont masqués."
],
"pulsesTitle": "Ce que l'animation encode",
"pulsesBody": "Les comètes animées qui voyagent sur chaque bord représentent un trafic en direct :",
"pulses": [
"<strong>Direction</strong> — vers la carte réseau signifie <em>tx</em> de la machine invitée ; vers la machine, <em>rx</em>.",
"L’<strong>épaisseur du trait</strong> augmente avec le débit rx+tx de la machine invitée. Une ligne animée faible reste visible sans trafic ; elle s’épaissit lorsque le trafic augmente.",
"<strong>Lueur de la tête de comète</strong> — teinte chaude vers 1 MB/s, intense à partir de 30 MB/s. Permet de repérer la machine invitée qui utilise le plus une carte réseau.",
"<strong>Clic</strong> — tous les nœuds sauf l’hôte ouvrent le dialogue de détail d’interface décrit plus bas. Cliquer sur l’hôte n’a aucun effet ; aucun dialogue ne lui est associé ici."
],
"useTitle": "Quand c'est utile",
"useBody": "Les cartes montrent <em>ce qui</em> existe ; le diagramme montre <em>les connexions</em> et le trafic. Il permet de repérer des machines sur un même pont, deux machines très actives partageant une carte réseau — un possible goulot d’étranglement — ou une VM saturant une liaison alors que les autres restent peu actives."
},
"groups": {
"heading": "Trois groupes d'interface",
"intro": "Trois cartes regroupent les interfaces par rôle. Chaque en-tête indique le nombre d’interfaces actives. Une étiquette colorée identifie le <strong>type</strong> de chaque interface :",
"badges": [
"Bleu <strong>Physical</strong> — réel NIC.",
"Vert <strong>Bridge</strong> — Pont Linux ou pont OVS (<code>vmbr*</code>).",
"Violet <strong>Bond</strong> — agrégat bond / LACP / active-backup.",
"Cyan <strong>VLAN</strong> — sous-interface VLAN (<code>vmbr0.10</code>, <code>eno1.42</code>, …)."
],
"clickable": "<strong>Chaque ligne est cliquable</strong> : interfaces physiques, virtuelles, ponts et agrégats. Le détail décrit plus bas affiche informations de base, IP, compteurs et historique RX/TX du stockage RRD Proxmox.",
"physicalTitle": "Interfaces physiques",
"physicalBody": "Interfaces physiques reconnues par le noyau : <code>eno1</code>, <code>enp4s0</code>, <code>eth0</code>, <code>wlp3s0</code>, etc. Chaque appareil a une ligne avec l’étiquette bleue <strong>Physical</strong> et l’état de liaison. Les <em>membres d’un agrégat</em> apparaissent aussi avec une référence à leur bond.",
"bridgeTitle": "Interfaces de pont",
"bridgeBody": "Ponts Linux (<code>vmbr0</code>, <code>vmbr1</code>, …) et OVS gérés par Proxmox. Chaque ligne affiche l’étiquette verte <strong>Bridge</strong>, l’interface physique si le pont n’a qu’un port et son état. Les agrégats portent l’étiquette violette <strong>Bond</strong>, les sous-interfaces VLAN l’étiquette cyan <strong>VLAN</strong>.",
"vmTitle": "Interfaces VM / LXC",
"vmBody": "Interfaces <code>tap*</code> et <code>veth*</code> créées au démarrage des machines invitées, une par carte virtuelle. L’en-tête affiche <em>X / Y Active</em> et les lignes renvoient à leur VM/CT dans l’onglet VMs et LXCs. Après un arrêt, les entrées inactives disparaissent au cycle d’actualisation suivant."
},
"drillIn": {
"heading": "Détail par interface",
"intro": "Un clic sur une ligne ouvre un dialogue avec cinq blocs :",
"headerBlock": "Bloc",
"headerContents": "Contenu",
"rows": [
{
"block": "Informations de base",
"contents": "Nom, type (physique / pont / bond / VLAN / vm), adresse MAC, état (actif / inactif), MTU et interface physique sous-jacente pour les types virtuels."
},
{
"block": "Membres du bond",
"contents": "Pour les bonds uniquement : chaque carte membre avec son état actif ou défaillant, le mode (active-backup / 802.3ad / balance-alb / …) et l’interface principale si elle est définie."
},
{
"block": "Adresses IP",
"contents": "Chaque adresse IPv4 / IPv6 avec la longueur du préfixe. Les adresses link-local configurées automatiquement sont listées mais grisées."
},
{
"block": "Graphique historique",
"contents": "Bande passante RX/TX sur la période choisie (1 heure / 24 heures / 7 jours / 30 jours / 1 an), obtenue via <code>/api/network/&lt;interface&gt;/metrics</code> (RRD Proxmox)."
},
{
"block": "Trafic depuis le dernier démarrage",
"contents": "Total des octets et paquets RX/TX depuis le dernier démarrage de l’hôte, avec compteurs d’erreurs et de paquets abandonnés."
}
],
"inactiveTitle": "Le détail des interfaces inactives reste accessible",
"inactiveBody": "Si l’interface est <em>inactive</em>, le dialogue affiche un avis « Interface inactive » sans compteurs actuels. La configuration — adresses et membres du bond — et l’historique restent visibles pour déterminer la cause et le moment de la panne."
},
"latency": {
"heading": "Dialogue Latence réseau",
"intro": "Cliquez sur <em>Latence réseau</em> dans la rangée supérieure pour ouvrir son dialogue : historique, test à la demande, trois cibles et rapport PDF téléchargeable.",
"targetsTitle": "Cibles",
"targetsIntro": "La liste en haut sélectionne la cible du ping :",
"targets": [
"<strong>Passerelle</strong> — votre routeur LAN. Teste uniquement le trajet local pour examiner les problèmes de commutateur ou de câblage sans inclure le WAN.",
"<strong>Cloudflare (1.1.1.1)</strong> — résolveur DNS public sur un réseau anycast. Teste le trajet WAN.",
"<strong>Google (8.8.8.8)</strong> — cible publique alternative pour vérifier les résultats ou en cas de problèmes régionaux de Cloudflare."
],
"mode1Title": "Mode 1 — Vue historique",
"mode1Alt": "Dialogue de latence en mode historique, cible Passerelle, période d’une heure et mesures précédentes tracées",
"mode1Caption": "Historique de la passerelle sur la dernière heure. Le collecteur de température et de latence enregistre les mesures en base toutes les 60 secondes.",
"mode1Body1": "Mode initial du dialogue. Une seconde liste choisit la période (<em>1 heure / 6 heures / 24 heures / 3 jours / 7 jours</em>). Au-dessus figurent Actuel / Minimum / Moyenne / Maximum et un état Excellent / Bon / Moyen / Mauvais selon les seuils ci-dessous.",
"mode1Body2": "Source : les mesures utilisées par Health Monitor pour détecter les ralentissements persistants. Le thread <code>_temperature_collector_loop</code> mesure la passerelle toutes les 60 secondes et conserve l’historique localement dans SQLite.",
"mode2Title": "Mode 2 — Essai en temps réel",
"mode2Alt": "Dialogue de latence exécutant un ping en temps réel vers Cloudflare, progression à 50 % et nouvelles mesures sur le graphique",
"mode2Caption": "Test de deux minutes vers Cloudflare avec une mesure toutes les cinq secondes, tracée dès son arrivée. <em>Arrêter</em> termine le test plus tôt ; <em>Tester à nouveau</em> ajoute des mesures aux mêmes données.",
"mode2Intro": "Changer la cible en Cloudflare ou Google commence un test de ping sur demande. Comportement:",
"mode2Items": [
"<strong>Durée</strong> — deux minutes par test avec barre de progression et secondes restantes.",
"<strong>Fréquence</strong> — une mesure toutes les cinq secondes, 24 par test.",
"<strong>Méthode</strong> — ICMP Echo Request (<code>ping</code>), trois pings consécutifs par mesure avec latence moyenne.",
"<strong>Stop</strong> – termine immédiatement le test ; des données partielles sont conservées.",
"<strong>Tester à nouveau</strong> — ajoute des mesures aux données existantes pour constituer un historique plus long sur plusieurs tests.",
"<strong>Indicateur d’état actuel</strong> — réévalué après chaque mesure selon les mêmes seuils Excellent / Bon / Moyen / Mauvais."
],
"thresholdsTitle": "Seuils de performance",
"headerStatus": "État",
"headerRange": "Intervalle",
"headerImpact": "Impact pratique",
"thresholdRows": [
{
"status": "Excellent",
"range": "< 50 ms",
"impact": "Optimisé pour les applications en temps réel, les jeux et les appels vidéo."
},
{
"status": "Bon",
"range": "50 – 100 ms",
"impact": "Acceptable pour la plupart des applications avec un impact minimal."
},
{
"status": "Moyen",
"range": "100 – 200 ms",
"impact": "Un retard notable. Peut affecter les applications VoIP et interactives."
},
{
"status": "Mauvais",
"range": "> 200 ms",
"impact": "Latence importante. Enquête recommandée."
}
],
"reportTitle": "Rapport de latence réseau (PDF)",
"reportIntro": "Les deux modes ont un bouton <strong>Rapport</strong> près du sélecteur de cible. Il génère un PDF des mesures que vous pouvez joindre à une demande d’assistance auprès de votre FAI.",
"reportPreviewAlt": "Première page PDF du rapport de latence : synthèse, jauge, statistiques, graphique et guide des seuils",
"reportPreviewCaption": "La première page contient la synthèse, la jauge, les statistiques principales, l’évolution de la latence et le guide des seuils. À partir de la page 2 figurent le tableau des mesures et la méthodologie.",
"downloadLabel": "Télécharger un exemple de rapport de latence (PDF)",
"sectionsIntro": "Le rapport comporte six sections :",
"sections": [
"<strong>Synthèse</strong> — jauge de 0 à plus de 300 ms avec zones verte, jaune et rouge ; état Excellent / Bon / Moyen / Mauvais ; cible, mode, nombre de mesures et résumé des pertes de paquets.",
"<strong>Statistiques de latence</strong> — quatre indicateurs : actuel, minimum, moyenne et maximum ; plus le nombre de mesures, la perte moyenne de paquets et la période du test.",
"<strong>Graphique de latence</strong> — graphique en aires des mesures du test, avec repères minimum, moyenne et maximum sur l’axe vertical.",
"<strong>Seuils de performance</strong> — la même échelle à quatre niveaux, avec un point coloré par niveau.",
"<strong>Résultats détaillés</strong> — tableau numéroté avec horodatage, latence, perte de paquets et état de chaque mesure. Permet de repérer les pics brefs masqués par les moyennes.",
"<strong>Méthodologie</strong> — ICMP Echo Request, trois pings consécutifs par mesure, nom et IP de la cible et évaluation finale issue de l’état."
],
"useCaseTitle": "Cas d’utilisation : assistance de votre FAI",
"useCaseBody": "Lancez deux minutes de test Cloudflare lorsque la connexion ralentit, prolongez avec <em>Tester à nouveau</em>, puis choisissez <em>Rapport</em>. Le PDF contient toutes les mesures et la méthodologie. Vous pouvez le joindre à une demande d’assistance avec les heures de l’incident ; le FAI décide des justificatifs nécessaires."
},
"excluding": {
"heading": "Exclure des interfaces de la surveillance",
"body1": "Vous pouvez exclure des interfaces de la surveillance : ponts volontairement désactivés, interfaces de test ou cartes retirées encore configurées. Le réglage est conservé dans <code>excluded_interfaces</code> : Health Monitor ne génère ni avertissements ni notifications et ne les inclut pas dans l’état global.",
"body2": "Dans le menu contextuel, choisissez <em>Exclure de la surveillance</em>. L’interface reste visible avec une étiquette violette <strong>exclue</strong>. Le même menu permet de réactiver la surveillance."
},
"dataCollected": {
"heading": "Comment les données sont collectées",
"headerSection": "Section de l'onglet",
"headerEndpoint": "Point de terminaison",
"headerSource": "Source",
"rows": [
{
"section": "Inventaire des interfaces",
"endpoint": "/api/network",
"source": "<code>ip -j addr</code> + <code>ip -j link</code> et inspection des bonds et ponts."
},
{
"section": "Cartes sommaires",
"endpoint": "/api/network/summary",
"source": "Synthèse de l’inventaire et nombre d’interfaces actives et inactives."
},
{
"section": "Historique RX/TX par interface",
"endpoint": "/api/network/<iface>/metrics",
"source": "Les compteurs actuels utilisent <code>/proc/net/dev</code> ; l’historique vient de RRD Proxmox via pvesh. Les interfaces VM/LXC utilisent les données de la machine invitée ; les interfaces physiques et ponts, celles du nœud."
},
{
"section": "Latence: actuelle",
"endpoint": "/api/network/latency/current",
"source": "Courte série de <code>ping</code> vers la passerelle ou la cible configurée."
},
{
"section": "Latence : historique",
"endpoint": "/api/network/latency/history",
"source": "Mesures enregistrées environ toutes les 60 secondes par le collecteur de température et de latence en arrière-plan."
}
],
"codeComment1": "# Vérifier l’état des interfaces affiché dans le tableau de bord",
"codeComment2": "# Vérifier une mesure actuelle de latence de bout en bout"
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Moniteur de santé",
"href": "/docs/monitor/health-monitor",
"tail": " — catégorie Réseau et seuils de l’historique de latence."
},
{
"label": "Référence de l’API",
"href": "/docs/monitor/api",
"tail": " — points de terminaison réseau et latence."
},
{
"label": "Intégrations",
"href": "/docs/monitor/integrations",
"tail": " — la collecte Prometheus expose les mêmes métriques réseau."
},
{
"label": "Indice du tableau de bord",
"href": "/docs/monitor/dashboard",
"tail": "— les autres onglets."
},
{
"label": "ProxMenux → Réseau",
"href": "/docs/network",
"tail": "— le côté actions: analyse de pont, noms d'interface persistants, sauvegarde & redémarrage, iperf3."
}
]
}
}
@@ -0,0 +1,246 @@
{
"meta": {
"title": "ProxMenux Monitor — Tableau de bord : onglet Sécurité | Documentation ProxMenux",
"description": "L’onglet Sécurité regroupe les protections en deux colonnes : ProxMenux Monitor (authentification, SSL/HTTPS, jetons d’API, Secure Gateway) et Proxmox VE (pare-feu, Fail2Ban, audit Lynis). Découvrez l’assistant Secure Gateway, l’audit Lynis et l’installation et le réglage des règles Fail2Ban."
},
"header": {
"title": "Tableau de bord : onglet Sécurité",
"description": "Les contrôles de sécurité sont répartis en deux blocs : la configuration de Monitor (authentification, SSL, jetons, Secure Gateway) et celle de l’hôte Proxmox surveillé (pare-feu, Fail2Ban, Lynis).",
"section": "ProxMenux Monitor · Tableau de bord"
},
"intro": {
"title": "Deux périmètres, un onglet",
"body": "L’onglet Sécurité comporte deux sections : <strong>ProxMenux Monitor</strong> (paramètres du tableau de bord) et <strong>Proxmox VE</strong> (paramètres de l’hôte). Les cartes Fail2Ban et Lynis proposent d’installer ces outils s’ils sont absents, puis affichent leurs commandes une fois installés."
},
"monitor": {
"heading": "ProxMenux Monitor",
"intro": "Quatre cartes permettent de gérer l’accès au tableau de bord et l’authentification."
},
"auth": {
"heading": "Authentification",
"imageAlt": "Carte d’authentification avec l’état Activée, les boutons Déconnexion et Modifier le mot de passe, des informations sur l’authentification à deux facteurs et des boutons pour l’activer ou désactiver l’authentification",
"imageCaption": "Carte avec l’authentification activée : indicateur d’état, Modifier le mot de passe, Activer la 2FA et l’action destructive Désactiver l’authentification.",
"intro": "Cette carte gère la connexion au tableau de bord. Le premier lancement, la politique de mots de passe, la configuration TOTP et la récupération après perte de l’authentificateur sont décrits dans <link>Accès et authentification</link>. Cette carte permet de gérer ces paramètres au quotidien :",
"items": [
"<strong>État de l’authentification</strong> — indicateur <em>Activée</em> / <em>Désactivée</em> / <em>Refusée</em>.",
"<strong>Modifier le mot de passe</strong> — mot de passe actuel + nouveau mot de passe + confirmation.",
"<strong>Activer / Désactiver l’authentification à deux facteurs</strong> — ouvre le dialogue de configuration avec code QR à l’activation et demande le mot de passe actuel à la désactivation.",
"<strong>Désactiver l’authentification</strong> — action destructive qui réaffiche le dialogue initial <em>Protéger votre tableau de bord ?</em> lors de la prochaine visite."
]
},
"ssl": {
"heading": "SSL/HTTPS",
"imageAlt": "Carte SSL/HTTPS avec l’état HTTP sans SSL, le certificat Proxmox détecté avec son sujet, son émetteur et son expiration, et les options pour utiliser ce certificat ou un certificat personnalisé",
"imageCaption": "Carte SSL/HTTPS avec HTTPS désactivé. Monitor détecte le certificat installé sur l’hôte Proxmox et permet de l’utiliser en un clic. L’option <em>Utiliser un certificat personnalisé</em> permet de choisir vos propres fichiers stockés ailleurs.",
"intro": "Permet d’accéder au tableau de bord par HTTPS sans proxy inverse. La carte détecte le certificat utilisé par Proxmox dans <code>/etc/pve/local/</code> et affiche son sujet, son émetteur et sa date d’expiration pour vérification avant activation. Deux méthodes sont proposées :",
"items": [
"<strong>Utiliser le certificat Proxmox</strong> — Monitor réutilise le certificat de l’hôte en un clic. Adapté si PVE et le tableau de bord utilisent déjà le même nom DNS.",
"<strong>Utiliser un certificat personnalisé</strong> — collez les chemins absolus du certificat <code>.pem</code> et de la clé privée <code>.key</code>. Ils sont validés avant le redémarrage du service. Si le chargement échoue, le tableau de bord repasse automatiquement en HTTP et reste accessible."
],
"enabledAlt": "Carte SSL/HTTPS avec HTTPS activé, certificat actif avec les chemins pve-ssl.pem et pve-ssl.key et bouton Désactiver HTTPS",
"enabledCaption": "HTTPS actif — la carte affiche le certificat utilisé, ses chemins et l’action <em>Désactiver HTTPS</em>, qui rétablit HTTP sur le même port.",
"acmeTitle": "ACME / Let's Encrypt via Proxmox",
"acmeBody": "Si Let’s Encrypt est déjà configuré sur votre nœud Proxmox dans <em>Datacenter → Certificats → ACME</em>, le tableau de bord réutilise le certificat présenté aux navigateurs lorsque vous cliquez sur <em>Utiliser le certificat Proxmox</em>. Aucune configuration ACME distincte n’est nécessaire pour Monitor.",
"walkthroughLink": "Consultez <link>HTTPS pour ProxMenux Monitor</link> pour découvrir la détection du certificat ACME, les données écrites sur disque et l’utilisation d’une paire <code>.pem</code> / <code>.key</code> personnalisée."
},
"apiTokens": {
"heading": "Jetons d’accès à l’API",
"emptyAlt": "Carte de jetons d’accès à l’API vide, avec des informations sur les jetons et le bouton Générer un nouveau jeton d’API",
"emptyCaption": "Carte des jetons après une nouvelle installation. L’encadré <em>À propos des jetons d’API</em> résume leur durée de validité, leur utilisation et leur insertion dans les en-têtes <code>Authorization: Bearer</code>.",
"intro": "Jetons valables un an pour les intégrations automatisées : widgets Homepage, capteurs REST Home Assistant, collecteurs Grafana, flux n8n et scripts personnalisés. La carte passe par trois états : vide → formulaire → jeton généré.",
"generateBody": "<strong>Générer un jeton.</strong> Cliquez sur <em>Générer un nouveau jeton d’API</em>. Saisissez un <em>nom de jeton</em> descriptif pour l’identifier ensuite et votre <em>mot de passe</em> comme confirmation supplémentaire. Si la 2FA est activée, le code TOTP actuel est également demandé.",
"generateAlt": "Formulaire de génération d’un jeton d’API avec les champs Nom du jeton et Mot de passe et les boutons Générer et Annuler",
"generateCaption": "Formulaire de génération d’un jeton d’API : saisissez un nom et confirmez avec votre mot de passe et le code TOTP si la 2FA est activée.",
"saveBody": "<strong>Enregistrez immédiatement le jeton.</strong> Sa valeur complète s’affiche <strong>une seule fois</strong> après sa création. La carte le signale par un avis orange et un bouton de copie. Vous ne pourrez pas la récupérer ensuite : seul le préfixe restera visible dans la liste des jetons actifs.",
"generatedAlt": "Jeton d’API généré avec valeur masquée, bouton de copie, instructions pour l’en-tête Authorization: Bearer et liste des jetons actifs avec leur préfixe",
"generatedCaption": "Jeton généré : la valeur s’affiche une seule fois, avec un bouton de copie et l’extrait exact <code>Authorization: Bearer</code>. La liste des jetons actifs conserve le nom, le préfixe et la date de création pour permettre leur révocation individuelle.",
"outro": "Chaque jeton actif possède un bouton <em>Révoquer</em>. La révocation l’invalide immédiatement et interrompt les intégrations qui l’utilisent. Des exemples pour Homepage, Home Assistant, n8n et Prometheus figurent dans <link>Intégrations</link>."
},
"gateway": {
"heading": "Secure Gateway",
"cardAlt": "Carte Secure Gateway avant tout déploiement, avec le bouton Déployer Secure Gateway",
"cardCaption": "Carte Secure Gateway sur une nouvelle installation : un bouton lance l’assistant.",
"intro": "Accédez au tableau de bord, à l’interface web Proxmox et aux machines invitées depuis votre réseau <a>Tailscale</a>, sans exposer de port sur Internet. Monitor déploie sur l’hôte un conteneur LXC Alpine exécutant <code>tailscaled</code> comme routeur de sous-réseau. Après approbation dans la console Tailscale, vos appareils distants peuvent joindre l’adresse IP LAN de l’hôte depuis n’importe où.",
"wizardTitle": "Assistant étape par étape",
"wizardIntro": "Avant de cliquer sur <em>Deploy Secure Gateway</em>, générez une clé d’authentification dans la console Tailscale. L’assistant la demandera à l’étape 2.",
"step0Title": "0. Générer la clé d’authentification Tailscale",
"step0Body": "Connectez-vous à <a>login.tailscale.com/admin/settings/keys</a> et cliquez sur <em>Generate auth key…</em>. Choisissez une clé <em>préauthentifiée</em> pour éviter une connexion interactive depuis la passerelle. Copiez la valeur : elle ne s’affiche qu’une seule fois.",
"step0Alt": "Page Settings → Keys de la console Tailscale, avec le bouton Generate auth key mis en évidence",
"step0Caption": "Console d'administration Tailscale — <em>Paramètres → Clés → Générer la clé auth...</em>. Utilisez un compte Tailscale gratuit si vous n'en avez pas encore (lien à l'intérieur de l'assistant).",
"step1Title": "1. Ouvrez l'assistant",
"step1Body": "Revenez à l’onglet Sécurité et cliquez sur <em>Deploy Secure Gateway</em>. La première étape présente les fonctions et les prérequis.",
"step1Alt": "Introduction de l’assistant Secure Gateway : accès VPN sans redirection de ports et avec chiffrement de bout en bout",
"step1Caption": "Étape 1 — aperçu de ce que fournit la passerelle sécurisée et un rappel que vous aurez besoin d'un compte Tailscale gratuit.",
"step2Title": "2. Authentification Tailscale",
"step2Body": "Collez la clé d’authentification de l’étape 0 et choisissez un nom d’hôte. La passerelle apparaîtra sous ce nom dans la console Tailscale, généralement <code>proxmox-gateway</code> ou le nom de votre nœud.",
"step2Alt": "Étape de l’assistant Secure Gateway demandant la clé d’authentification Tailscale et le nom d’hôte de l’appareil, avec un lien pour générer la clé",
"step2Caption": "Étape 2 : collez la clé préauthentifiée et choisissez le nom d’hôte. Si vous avez sauté l’étape 0, le lien sous le champ ouvre la page Tailscale correspondante.",
"step3Title": "3. Portée de l'accès",
"step3Intro": "Choisissez les ressources accessibles depuis votre réseau Tailscale via la passerelle :",
"step3Items": [
"<strong>Proxmox Only</strong> — seulement l'interface utilisateur Proxmox et le moniteur. La plus petite surface d'attaque.",
"<strong>Réseau local complet</strong> — tout le sous-réseau LAN (détecté automatiquement depuis l'interface principale de l'hôte). Permet d'atteindre le NAS, les imprimantes, les VM et tout autre périphérique LAN.",
"<strong>Sous-réseaux personnalisés</strong> — indiquez les CIDR souhaités. Pour les configurations à plusieurs VLAN où seuls certains segments doivent être accessibles."
],
"step3Alt": "Étape Périmètre d’accès de l’assistant Secure Gateway avec les options Proxmox uniquement, Réseau local complet et Sous-réseaux personnalisés",
"step3Caption": "Étape 3 : choisissez le périmètre d’accès. <em>Réseau local complet</em> renseigne automatiquement le sous-réseau LAN détecté.",
"step4Title": "4. Options avancées (facultatif)",
"step4Intro": "Deux options, toutes deux <strong>désactivées par défaut</strong> :",
"step4Items": [
"<strong>Exit Node</strong> — une fois activé et sélectionné sur un appareil distant, tout le trafic Internet de cet appareil passe par la connexion WAN de l’hôte Proxmox. En voyage, le trafic de votre téléphone utilise ainsi votre connexion domestique.",
"<strong>Accepter les routes</strong> — permet à cette passerelle de joindre les réseaux annoncés par les <em>autres</em> routeurs de sous-réseau Tailscale, pour les installations multisites."
],
"step4Alt": "Étape Options avancées de Secure Gateway avec les cases Exit Node et Accept Routes",
"step4Caption": "Étape 4 : Exit Node et Accept Routes. Laissez ces deux options désactivées si vous souhaitez simplement accéder au tableau de bord depuis votre téléphone ou ordinateur portable.",
"step5Title": "5. Vérifier et déployer",
"step5Body": "Résumé final avant le déploiement. L’assistant rappelle l’étape manuelle à effectuer ensuite dans la console Tailscale : <strong>approuver la route de sous-réseau</strong>.",
"step5Alt": "Étape Vérifier et déployer de Secure Gateway avec le résumé du nom d’hôte, du mode d’accès, des réseaux, d’Exit Node et d’Accept Routes et le bouton Déployer la passerelle",
"step5Caption": "Étape 5 — examiner la configuration et le déploiement. L'avis bleu au bas annonce l'approbation de route en attente.",
"approvalTitle": "Une dernière étape manuelle dans Tailscale admin",
"approvalBody": "Après le déploiement, ouvrez <a>login.tailscale.com/admin/machines</a> et approuvez la route de sous-réseau annoncée par la passerelle. Sans cette approbation, les appareils distants du réseau Tailscale ne peuvent pas joindre les IP LAN via la passerelle. Tailscale signale les routes en attente en jaune sur la ligne de l’appareil : cliquez sur <em>Edit route settings</em> et cochez la route."
},
"pve": {
"heading": "Proxmox VE",
"intro": "Les protections de l’hôte : pare-feu, prévention des intrusions et audit de sécurité. Les cartes Fail2Ban et Lynis proposent leur installation si nécessaire, puis affichent leurs commandes de gestion."
},
"firewall": {
"heading": "Proxmox Firewall",
"imageAlt": "Carte du pare-feu Proxmox avec états du cluster et de l’hôte, règles d’accès rapide pour Monitor et l’interface web Proxmox, compteurs, liste des règles et bouton Ajouter une règle",
"imageCaption": "Carte du pare-feu Proxmox : interrupteurs pour le cluster et l’hôte, ports courants dans <em>Règles d’accès rapide</em>, compteurs dans <em>Aperçu des règles</em> et liste complète avec <em>+ Ajouter une règle</em>.",
"intro": "La carte gère la configuration du pare-feu Proxmox VE. Le moteur classique utilise <code>iptables</code>, l’alternative utilise <code>nftables</code>. Elle ne gère pas les règles créées hors de Proxmox. Trois blocs :",
"items": [
"<strong>Pare-feu du cluster + pare-feu de l’hôte</strong> — interrupteurs globaux. Le pare-feu du cluster doit être actif pour que les règles de l’hôte s’appliquent. La carte indique cette dépendance près du réglage.",
"<strong>Règles d’accès rapide</strong> — lignes prédéfinies pour <code>8008/TCP</code> (Monitor) et <code>8006/TCP</code> (interface web Proxmox), avec l’état autorisé, bloqué ou non protégé. L’interface Proxmox est autorisée par une macro de pare-feu <em>intégrée</em> qui ne peut pas être supprimée par erreur.",
"<strong>Aperçu des règles</strong> — compteurs du total des règles, des règles accept, des règles drop/reject et des ports distincts protégés. Les valeurs proviennent de <code>/etc/pve/firewall/cluster.fw</code> et <code>/etc/pve/nodes/&lt;node&gt;/host.fw</code>.",
"<strong>Règles du pare-feu</strong> — liste avec action, protocole, port, source et niveau. <em>+ Ajouter une règle</em> ouvre l’éditeur dans la carte ; la corbeille supprime la règle. Les modifications sont enregistrées dans les fichiers Proxmox et apparaissent aussi dans son interface (Datacenter / Node → Firewall)."
]
},
"fail2ban": {
"heading": "Fail2Ban",
"subHeading": "(selon l’état)",
"whatIs": "<strong>De quoi s’agit-il ?</strong> Fail2Ban est un service libre qui détecte les échecs de connexion répétés dans les journaux et bloque l’IP au niveau du pare-feu. Il protège SSH et les formulaires web contre les attaques par force brute continues. ProxMenux configure trois jails : SSH, connexion web Proxmox (port 8006) et connexion ProxMenux Monitor (port 8008).",
"notBundled": "Fail2Ban <strong>n’est pas fourni</strong>. La carte détecte sa présence et s’adapte : s’il manque, elle propose de l’installer en un clic. Une fois installé, elle affiche l’état des jails et les IP bloquées, et permet de régler le nombre de tentatives et la durée de blocage pour chaque jail.",
"notInstalledAlt": "Carte Fail2Ban non installé avec la protection prévue pour SSH, l’interface web Proxmox et Monitor via nftables et le bouton Installer et configurer Fail2Ban",
"notInstalledCaption": "La carte Fail2Ban avant l'installation — la boîte bleue prévisualise ce que l'installation va configurer.",
"clickBody": "Cliquez sur <em>Installer et configurer Fail2Ban</em> pour ouvrir un dialogue de confirmation répertoriant toutes les modifications du script sur l’hôte :",
"confirmAlt": "Confirmation Fail2Ban avec mode SSH agressif, protection Proxmox sur le port 8006 et Monitor sur le port 8008, détection de nftables, réglage des journaux journald et renforcement de SSH MaxAuthTries",
"confirmCaption": "Confirmation d’installation : liste des jails, réglage de la journalisation journald pour lire les événements SSH et renforcement supplémentaire de SSH (<code>MaxAuthTries=3</code>).",
"confirmIntro": "Après confirmation, un panneau affiche l’installation en direct : apt, configuration des jails et tests. Le mécanisme est le même que celui de l’installateur CLI ProxMenux.",
"progressAlt": "Panneau avec journal d’installation Fail2Ban : paquet, journald MaxLevelStore pour l’authentification, jails, détection de nftables, renforcement MaxAuthTries, test fail2ban-client et message de fin",
"progressCaption": "Installation en cours : chaque étape est consignée dans le panneau. Le message Connection closed en bas marque la fin de la transmission.",
"afterInstall": "Après l’installation, la carte affiche l’état en direct : jails configurés, IP bloquées et blocages récents. Les onglets séparent <em>Jails et IP bloquées</em> de l’<em>Activité récente</em>, les N dernières entrées du journal Fail2Ban.",
"activeAlt": "Carte Fail2Ban active avec trois jails (proxmenux, proxmox, sshd), compteurs des IP bloquées, du total des blocages et des tentatives échouées et lignes avec tentatives, durée de blocage, période et roue dentée",
"activeCaption": "Fail2Ban actif : les trois jails par défaut (<code>proxmenux</code>, <code>proxmox</code>, <code>sshd</code>) avec leurs réglages de tentatives, durée de blocage et période de détection.",
"tuneBody": "<strong>Régler les règles du jail.</strong> Cliquez sur sa roue dentée pour modifier <em>Max Retries</em>, <em>Ban Time</em> et <em>Find Time</em>, la période glissante de comptage des tentatives. Un blocage permanent dure jusqu’à sa levée manuelle. Le formulaire explique les valeurs courantes.",
"configAlt": "Formulaire du jail sshd avec Max Retries, Ban Time en secondes, option Permanent Ban, Find Time, aide sur les valeurs courantes et bouton Enregistrer la configuration",
"configCaption": "Modification du jail sshd : réduisez <em>Max Retries</em> si vous utilisez SSH uniquement depuis votre sous-réseau, ou augmentez <em>Ban Time</em> pour un tableau de bord exposé sur Internet.",
"outro": "Le guide <em>Installation, configuration et désinstallation</em> couvre aussi l’installation manuelle, la modification de SSH MaxAuthTries et le journal <code>proxmenux-auth.log</code>. Consultez <link>ProxMenux → Sécurité → Fail2Ban</link>.",
"calloutTitle": "Sans Fail2Ban, ce mécanisme ne bloque pas les IP",
"calloutBody": "ProxMenux Monitor vérifie les IP bloquées par Fail2Ban au <em>niveau applicatif</em> avant de traiter les requêtes Flask. Il interroge fail2ban-client et conserve le résultat en cache pendant 30 secondes ; il ne lit pas de table SQL de blocages. Sans Fail2Ban, les échecs sont consignés dans <code>proxmenux-auth.log</code>, mais ce mécanisme ne bloque pas les IP."
},
"lynis": {
"heading": "Audit de sécurité Lynis",
"subHeading": "(selon l’état)",
"whatIs": "<strong>De quoi s’agit-il ?</strong> Lynis est un outil libre d’audit de sécurité qui effectue environ 280 tests sur l’hôte : permissions, durcissement du noyau, SSH, vulnérabilités des paquets, politique cryptographique, tâches planifiées, identification des services, etc. Il produit un indice de durcissement de 0 à 100, des avertissements et des suggestions. C’est une référence courante pour évaluer les serveurs Debian.",
"whyUseful": "<strong>Pourquoi est-ce utile ?</strong> Évaluer la sécurité en lisant chaque fichier de configuration est difficile. Lynis repère les oublis courants : protections du noyau absentes, chiffrements SSH faibles, journaux non persistants ou <code>NOPASSWD</code> dans sudoers pour les comptes par défaut. Une nouvelle analyse après les réglages ProxMenux permet de comparer l’amélioration par un score.",
"notInstalledAlt": "Carte Lynis non installé avec bouton Installer Lynis et fonctions : indice de durcissement, détection des vulnérabilités, conformité et sources GitHub",
"notInstalledCaption": "Carte Lynis avant l'installation — la boîte bleue résume ce que l'outil fait.",
"notBundled": "Lynis <strong>n’est pas fourni</strong> non plus. ProxMenux l’installe directement depuis les sources officielles GitHub plutôt que depuis le paquet Debian.",
"confirmAlt": "Dialogue de confirmation Lynis présentant ses fonctions : indice de durcissement, détection des vulnérabilités, analyse de configuration, conformité et sources du dépôt officiel GitHub",
"confirmCaption": "Confirmation d’installation indiquant explicitement la source GitHub.",
"progressAlt": "Panneau d’installation Lynis en direct, avec installation de la dernière version, confirmation de la version 3.1.6 et message de fin",
"progressCaption": "Installation en cours : le panneau affiche le journal en direct, comme pour Fail2Ban.",
"afterInstall": "Après l’installation, la carte affiche la version et un historique d’audit vide. Cliquez sur <em>Lancer l’audit de sécurité</em> pour démarrer la première analyse.",
"installedAlt": "Carte Lynis après installation avec version 3.1.6, date de dernière analyse, indice de durcissement 0, avertissements 0, suggestions 0, rapport vide et bouton Lancer l’audit de sécurité",
"installedCaption": "Lynis est installé, sans audit pour le moment. Les indicateurs affichent initialement zéro.",
"runningAlt": "Carte Lynis pendant l’audit avec message d’analyse en cours, durée estimée de 2 à 5 minutes et bouton Audit en cours désactivé",
"runningCaption": "Audit en cours : le bouton affiche un indicateur de chargement et la carte précise que l’analyse peut durer de 2 à 5 minutes.",
"finishedBody": "À la fin, la carte affiche les résultats : indice de durcissement, avertissements, suggestions et liste des <em>Rapports d’audit</em> avec les analyses précédentes.",
"resultsAlt": "Carte Lynis avec indice 71, détail Lynis 66 et PVE 71, 3 avertissements, 40 suggestions, score adapté à Proxmox de 71 sur 100 dans la catégorie Bon, rapports téléchargeables en PDF et bouton Lancer l’audit de sécurité",
"resultsCaption": "Exemple de résultats : indice de durcissement <strong>71/100 (Bon)</strong>. La carte affiche le score brut Lynis (66) et le score adapté à Proxmox (71). L’ajustement dépend du score brut et de la proportion des constats considérés comme normaux sur Proxmox VE ; il n’ajoute pas systématiquement 11 points.",
"scoreTitle": "Score brut Lynis vs Score ajusté Proxmox",
"scoreIntro": "Les règles Lynis visent les systèmes Debian généralistes. Proxmox s’en écarte parfois pour des raisons légitimes, par exemple des services de cluster exécutés en root ou des réglages spécifiques de <code>journald</code>. La carte affiche les deux scores pour permettre de :",
"scoreItems": [
"Suivre le <em>score brut Lynis</em>, comme le ferait un auditeur externe.",
"Suivre le score <em>adapté à Proxmox</em>, une référence plus pertinente pour comparer les nœuds d’un même cluster."
],
"reportBody": "<strong>Rapport complet.</strong> Le bouton <em>PDF</em> de chaque audit télécharge un rapport de plusieurs pages : synthèse, informations système, état de sécurité, avertissements expliqués, suggestions classées par impact et inventaire des paquets. Vous pouvez le joindre à une revue de sécurité.",
"reportAlt": "Première page d’exemple du rapport PDF Lynis avec synthèse, indice 71 sur 100, nombre d’avertissements et de suggestions, nom d’hôte, noyau, version Lynis, date et aperçu de la sécurité",
"reportCaption": "Première page du rapport : synthèse, informations système et état de sécurité. La suite contient les avertissements détaillés, les suggestions et la liste des paquets installés. Un <a>exemple PDF</a> est joint pour référence.",
"runPeriodically": "Exécutez l'audit périodiquement (après les mises à niveau majeures de Proxmox, après avoir appliqué des modifications post-installation, avant d'ouvrir un chemin d'accès à distance) et gardez les rapports — la tendance compte plus que n'importe quel numéro.",
"outro": "Le guide d’<em>installation, configuration et désinstallation</em> et l’analyse d’un exemple de rapport figurent dans <link>ProxMenux → Sécurité → Lynis</link>."
},
"dataCollected": {
"heading": "Comment les données sont collectées",
"headerCard": "Carte",
"headerEndpoint": "Point de terminaison",
"headerSource": "Source",
"rows": [
{
"card": "Authentification, 2FA, changement de mot de passe",
"endpoint": "/api/auth/*",
"source": "Configuration locale d’authentification dans ~/.config/proxmenux-monitor/auth.json ; JWT émis par Monitor."
},
{
"card": "SSL/HTTPS",
"endpoint": "/api/auth/ssl/*",
"source": "<code>openssl x509</code> sur <code>/etc/pve/local/pve-ssl.pem</code> + <code>/etc/proxmenux/ssl_config.json</code>."
},
{
"card": "Lister, créer et révoquer les jetons d’API",
"endpoint": "/api/auth/api-tokens",
"source": "Les rangées de jetons sont conservées localement; rien ne quitte l'hôte."
},
{
"card": "Portail sécurisé (déploiement + statut)",
"endpoint": "/api/oci/*",
"source": "Crée un conteneur LXC Alpine avec <code>tailscaled</code> via <code>pct create</code> / <code>pct exec</code>."
},
{
"card": "Statut et règles du pare-feu",
"endpoint": "/api/security/firewall/*",
"source": "<code>pve-firewall</code> + <code>/etc/pve/firewall/&lt;cluster|host&gt;.fw</code>."
},
{
"card": "Fail2Ban (état disponible après installation)",
"endpoint": "/api/security/fail2ban/*",
"source": "<code>fail2ban-client status</code>, <code>/var/log/fail2ban.log</code>, <code>/etc/fail2ban/jail.local</code>."
},
{
"card": "Audit Lynis (uniquement lorsqu'il est installé)",
"endpoint": "/api/security/lynis/*",
"source": "Exécute <code>lynis audit system</code> en arrière-plan; rapport analysé à partir de <code>/var/log/lynis-report.dat</code>."
}
]
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Accès et authentification",
"href": "/docs/monitor/access-auth",
"tail": " — configuration initiale complète, choix d’application 2FA, récupération après perte de l’authentificateur et exemples de proxy inverse."
},
{
"label": "Intégrations",
"href": "/docs/monitor/integrations",
"tail": " — exemples de jetons d’API avec Homepage, Home Assistant, Prometheus et n8n, et configuration complète de Secure Gateway."
},
{
"label": "Référence de l’API",
"href": "/docs/monitor/api",
"tailRich": " — tous les points de terminaison <code>/api/auth</code>, <code>/api/security</code> et <code>/api/oci</code> avec méthode, corps de requête et exemples curl."
},
{
"label": "ProxMenux → Sécurité → Fail2Ban",
"href": "/docs/security/fail2ban",
"tail": " — guide d’installation, jails configurés et installation manuelle."
},
{
"label": "ProxMenux → Sécurité → Lynis",
"href": "/docs/security/lynis",
"tail": " — exemple de rapport, interprétation du score et fréquence des audits."
}
]
}
}
@@ -0,0 +1,367 @@
{
"meta": {
"title": "ProxMenux Monitor — Tableau de bord : onglet Paramètres | Documentation ProxMenux",
"description": "L’onglet Paramètres gère la langue, l’ordre de navigation, les préférences du tableau de bord, les seuils et exclusions de surveillance, les notifications, l’IA et l’inventaire des optimisations après installation."
},
"header": {
"title": "Tableau de bord : onglet Paramètres",
"description": "Langue de Monitor, ordre de navigation, préférences du tableau de bord, exclusions de surveillance, notifications, configuration de l’IA et inventaire actuel des optimisations ProxMenux.",
"section": "ProxMenux Monitor · Tableau de bord"
},
"intro": {
"title": "Où chaque paramètre est conservé",
"body": "Paramètres regroupe l’affichage du tableau de bord, la surveillance Health Monitor, l’envoi des alertes et les changements déjà appliqués par ProxMenux à l’hôte. Les cartes renvoient à leur documentation détaillée ; cet onglet en est le point d’accès."
},
"interfaceLanguage": {
"heading": "Langue d'interface",
"intro": "Choisissez la langue de l’<strong>interface web du moniteur</strong>. Elle change immédiatement, sans redémarrer le service ni modifier la langue des menus shell de ProxMenux.",
"items": [
"ProxMenux Monitor offre actuellement anglais, allemand, espagnol, français, italien, portugais, slovaque et suédois.",
"À la première visite, la langue du navigateur est utilisée si elle est prise en charge ; sinon, l’anglais.",
"Changer le choix actualise la langue de la page et la synchronise avec les autres onglets du même profil de navigateur.",
"Si une traduction manque, seul ce texte apparaît en anglais plutôt qu’une clé ou un espace réservé incorrect."
],
"scopeTitle": "Préférence locale du navigateur",
"scopeBody": "Le choix est enregistré dans <code>localStorage</code> sous <code>proxmenux-ui-language</code>. Il concerne ce profil de navigateur et cet appareil, pas tout le nœud. Chaque administrateur peut choisir sa langue."
},
"navigationOrder": {
"heading": "Ordre de navigation",
"intro": "Réorganisez les sept entrées principales : <strong>Aperçu, Apps, VM et LXC, Nœud, Sauvegarde, Terminal et Administration</strong>. Cliquez sur <strong>Modifier</strong>, déplacez les lignes et enregistrez.",
"items": [
"Avec la souris, le déplacement commence à l’appui. Sur écran tactile, un appui de 250 ms le distingue du défilement.",
"Les groupes <strong>Nœud</strong> et <strong>Administration</strong> se déplacent en bloc ; leurs pages internes gardent l’ordre prévu.",
"Le menu mobile suit le même ordre enregistré.",
"<strong>Rétablir les valeurs par défaut</strong> réinitialise l’ordre en cours d’édition. Enregistrez pour appliquer le changement.",
"Les nouvelles entrées principales des versions futures sont ajoutées à la fin de l’ordre personnalisé, en conservant votre organisation."
],
"landingTitle": "La première entrée devient l’onglet initial",
"landingBody": "Monitor ouvre la première entrée enregistrée. Pour <strong>Nœud</strong>, il ouvre Stockage ; pour <strong>Administration</strong>, Journaux système. L’ordre est conservé dans ce navigateur sous <code>proxmenux-nav-order</code> ; chaque appareil peut avoir sa propre organisation."
},
"networkUnits": {
"heading": "Unités réseau",
"imageAlt": "Carte Unités réseau avec le sélecteur d’affichage sur Octets",
"imageCaption": "Choisissez les bits ou les octets par seconde pour toutes les vitesses réseau du tableau de bord.",
"body": "Affiche le débit en <strong>bits par seconde</strong> (Mbps/Gbps) ou <strong>octets par seconde</strong> (MB/s/GB/s). Les bits sont utilisés par défaut comme dans les spécifications réseau ; les transferts de fichiers utilisent souvent les octets. Graphiques, étiquettes et infobulles changent immédiatement sans rechargement."
},
"health": {
"heading": "Moniteur de santé",
"intro": "La carte règle la <strong>durée de suppression</strong> : le délai avant qu’une alerte rejetée puisse être signalée à nouveau. Chaque catégorie — CPU, mémoire, stockage, disques, réseau, VM, services PVE, journaux, mises à jour et sécurité — a sa liste :",
"items": [
"<strong>24 h</strong> — Par défaut pour la plupart des catégories transitoires.",
"<strong>72 h</strong> — pour ne plus recevoir ces événements pendant quelques jours.",
"<strong>168 h</strong> (1 semaine) et <strong>720 h</strong> (1 mois) — contrôles périodiques.",
"<strong>8760 h</strong> (1 an) — une longue période sans ces alertes.",
"<strong>-1</strong> — silence permanent jusqu’à réactivation manuelle.",
"<strong>Heures personnalisées</strong> — un nombre entier pour une durée intermédiaire."
],
"imageAlt": "Paramètres, carte Health Monitor avec durée par catégorie et suppressions actives",
"imageCaption": "Les listes définissent la durée des futurs rejets. La section inférieure montre les alertes supprimées et permet leur réactivation.",
"editTitle": "Mode modification",
"editBody": "La carte est initialement en lecture seule. <strong>Modifier</strong> en haut à droite active les listes et boutons de réactivation. <strong>Enregistrer</strong> applique ensemble les durées et réactivations en attente ; <strong>Annuler</strong> les abandonne. Enregistrer n’est actif qu’en présence de changements.",
"activeTitle": "Suppressions actives",
"activeIntro": "Sous les durées, <strong>Suppressions actives</strong> liste les alertes supprimées temporairement —24 h, 7 jours ou autre période— et <em>définitivement</em>. Chaque ligne affiche :",
"activeItems": [
"Un badge coloré : <strong>Permanent</strong> en ambre ou un décompte, comme <strong>24 h restantes</strong> / <strong>7 jours restants</strong>, en bleu.",
"L’identifiant d’alerte sous une forme lisible (par ex. <code>pve_storage_full_PBS-Cloud</code> → <em>Stockage PVE plein : PBS-Cloud</em>).",
"Catégorie, gravité et date à laquelle l’alerte a été rejetée.",
"Un bouton <strong>Réactiver</strong>, disponible en modification, prépare la levée de suppression lors de l’enregistrement."
],
"activeReenableTitle": "Comment réactiver une alerte",
"activeReenableBody": "<strong>Réactiver</strong> colore la ligne en vert et barre son identifiant, sans appliquer encore le changement. Un nouveau clic permet d’<strong>Annuler</strong>. <strong>Enregistrer</strong> envoie en parallèle <code>POST /api/health/un-acknowledge</code> pour chaque réactivation et retire les lignes. Si le problème persiste et la catégorie permet un nouvel avis, l’alerte revient parmi les actives au prochain contrôle.",
"activePermanentNote": "Les rejets définitifs —via <em>Définitivement</em> ou la durée par défaut <code>-1</code>— <strong>ne sont annulés qu’ici</strong>. Le dialogue général ne propose pas ce bouton ; cette section réunit registre et réactivation.",
"activeAutoRefreshTitle": "Actualisation automatique",
"activeAutoRefreshBody": "La liste s’actualise après rejet ou réactivation d’une alerte dans Health Monitor, au retour sur l’onglet et lors d’un changement de visibilité. Aucun rechargement n’est nécessaire.",
"calloutTitle": "Détails dans la page Health Monitor",
"calloutBody": "L’escalade, la résolution automatique quand un appareil disparaît et la différence entre rejeter et résoudre figurent dans <link>Health Monitor → Rejet des alertes et durée de suppression</link>. Cette carte propose les listes et suppressions actives."
},
"thresholds": {
"heading": "Seuils du Health Monitor",
"intro": "La carte précédente définit <em>la durée de silence après un rejet</em> ; celle-ci règle <strong>la valeur qui déclenche une alerte</strong>. La plupart des contrôles ont des valeurs <strong>Avertissement</strong> et <strong>Critique</strong> réglables. Le tableau explique les exceptions, dont la règle combinée du swap et le détecteur RAM actuel.",
"whatForTitle": "À quoi cela sert",
"whatForIntro": "Les valeurs par défaut sont un point de départ ; chaque environnement a ses propres conditions :",
"whatForItems": [
"Un homelab avec un seul SSD peut avertir plus tôt, à 75/90 % par exemple, pour garder de la place aux instantanés.",
"Les seuils mémoire doivent refléter les mesures et la charge de l’hôte. La redondance Ceph ne justifie pas à elle seule des alertes moins strictes ; un ARC ZFS élevé n’équivaut pas à une mémoire de travail non récupérable.",
"Choisissez les seuils de température selon les spécifications du disque et ses conditions réelles. Le refroidissement passif ou forcé ne définit pas seul une limite sûre universellement plus basse ou haute.",
"Un hôte très virtualisé peut avoir des pics CPU pendant les compilations sans alerter à chaque pic de 80 %, mais doit signaler une saturation durable."
],
"whatForOutro": "Les modifications prises en charge s’appliquent <strong>à l’analyse suivante</strong>. Le Health Monitor lit <code>/usr/local/share/proxmenux/health_thresholds.json</code> à chaque cycle sans redémarrage. Certains indicateurs, comme la température des disques, utilisent ces valeurs ; des barres de capacité gardent leurs propres limites. La ligne RAM décrit une exception actuelle.",
"coloursTitle": "Couleurs des états Avertissement et Critique",
"coloursIntro": "Les widgets utilisant Avertissement/Critique suivent les trois états ci-dessous. D’autres indicateurs, comme les barres de capacité PVE, ont leurs propres limites ; leur couleur seule n’indique pas une alerte Health Monitor.",
"headerColour": "Couleur",
"headerRange": "Intervalle",
"headerMeaning": "Signification",
"colourRows": [
{
"colour": "Vert",
"range": "valeur < Avertissement",
"meaning": "Plage normale. Aucune alerte n’est générée."
},
{
"colour": "Ambre",
"range": "Avertissement ≤ valeur < critique",
"meaning": "État d’avertissement. Health Monitor génère un événement WARNING ; les notifications respectent les filtres et heures silencieuses."
},
{
"colour": "Rouge",
"range": "Valeur ≥ critique",
"meaning": "État critique. Health Monitor génère un événement CRITICAL qui ignore les heures silencieuses. Les réglages de catégorie et d’événement du canal s’appliquent toujours ; la livraison dépend aussi de sa disponibilité."
}
],
"sectionsTitle": "Sections et valeurs par défaut recommandées",
"sectionsIntro": "Ce sont les valeurs initiales de ProxMenux jusqu’à modification. Les sections suivent <em>charge de calcul</em>, <em>température</em> et <em>capacité de stockage</em>, de la charge actuelle à l’espace occupé.",
"headerSection": "Chapitre",
"headerWarning": "Avertissement",
"headerCritical": "Critique",
"headerGates": "Contrôle concerné",
"thresholdRows": [
{
"section": "Utilisation du processeur",
"warning": "85 %",
"critical": "95 %",
"gates": "Alerte de charge prolongée lorsque la moyenne CPU dépasse le seuil sur la période de contrôle."
},
{
"section": "Mémoire",
"warning": "85 %",
"critical": "95 %",
"gates": "Pression RAM de l’hôte. Le réglage affiche Critique à 95 %, mais le détecteur actuel utilise une règle fixe de 90 % soutenus ; ce réglage ne modifie pas actuellement cette branche d’exécution."
},
{
"section": "Swap (seuil critique uniquement)",
"warning": "—",
"critical": "80 %",
"gates": "Le CRITICAL de swap exige plus de 80 % de swap et moins de 15 % de RAM disponible sur plusieurs mesures. Le swap occupé seul ne déclenche pas cette règle."
},
{
"section": "Température du processeur",
"warning": "80 °C",
"critical": "90 °C",
"gates": "Température du boîtier CPU ou des cœurs fournie par <code>lm-sensors</code>."
},
{
"section": "Température du disque — HDD",
"warning": "60 °C",
"critical": "65 °C",
"gates": "Température HDD. Valeurs initiales : avertissement à 60 °C, critique à 65 °C. Ce sont des réglages de surveillance, pas une limite universelle du fabricant ; consultez le modèle précis."
},
{
"section": "Température du disque — SSD",
"warning": "70 °C",
"critical": "75 °C",
"gates": "SSD SATA de 2,5 pouces ou M.2. Cette classe utilise 70/75 °C par défaut ; les limites réelles dépendent du modèle."
},
{
"section": "Température du disque — NVMe",
"warning": "80 °C",
"critical": "85 °C",
"gates": "Température NVMe. Cette classe utilise 80/85 °C par défaut. La température de limitation du contrôleur dépend du modèle et n’est pas toujours 85 °C."
},
{
"section": "Température du disque — SAS",
"warning": "55 °C",
"critical": "65 °C",
"gates": "Température SAS. Cette classe utilise avertissement à 55 °C et critique à 65 °C. Ce sont des <em>valeurs de surveillance</em>, pas la preuve d’un défaut de refroidissement à 55 °C ni une limite universelle."
},
{
"section": "Espace disque — hôte",
"warning": "85 %",
"critical": "95 %",
"gates": "Capacité de <code>/</code> et de chaque point de montage de l’hôte (<code>/var/lib/vz</code>, <code>/mnt/*</code>…)."
},
{
"section": "Espace disque — rootfs LXC",
"warning": "85 %",
"critical": "95 %",
"gates": "Disque racine par conteneur, évalué par rapport à la taille rootfs de PVE."
},
{
"section": "Points de montage LXC",
"warning": "85 %",
"critical": "95 %",
"gates": "Capacité des montages dans les CT actifs : mp0, mp1, NFS et montages liés. Exclut rootfs."
},
{
"section": "Stockage PVE",
"warning": "85 %",
"critical": "95 %",
"gates": "Stockages gérés par PVE : LVM, LVM-thin, ZFS-pool, RBD/Ceph et PBS. Tous ne sont pas des stockages en blocs."
},
{
"section": "Pool ZFS",
"warning": "85 %",
"critical": "95 %",
"gates": "Pools ZFS de l’hôte, indépendamment de leur enregistrement dans PVE."
}
],
"defaultsTitle": "Valeurs par défaut, modifications et réinitialisation",
"defaultsBody": "Chaque section part des valeurs par défaut ; seules les modifications souhaitées sont conservées. La carte montre la valeur <em>effective</em> : votre modification ou la valeur initiale. <strong>Réinitialiser</strong> supprime toutes les modifications de toutes les sections.",
"validationTitle": "Validation",
"validationBody": "L’enregistrement vérifie les plages autorisées et refuse Critique sous Avertissement. L’interface affiche les erreurs et le serveur valide les requêtes API avant sauvegarde."
},
"lxcDetection": {
"heading": "Détection de mise à jour LXC",
"imageAlt": "Carte de détection des mises à jour LXC avec interrupteur pour les paquets en attente des conteneurs Debian, Ubuntu et Alpine actifs",
"imageCaption": "Interrupteur de l’analyse périodique par <code>apt list --upgradable</code> / <code>apk list -u</code> dans les CT actifs. Activé par défaut. Le réglage associé dans Notifications → Services apparaît lorsque la détection est active.",
"intro": "L’interrupteur entre Seuils et Notifications contrôle l’analyse LXC. Activé, il interroge les gestionnaires de paquets des CT actifs ; Matériel affiche les résultats et alimente <code>lxc_updates_available</code>. Désactivé, il arrête ses appels <code>pct exec</code> et supprime les entrées LXC de <code>managed_installs.json</code> ; <code>/api/managed-installs</code> cesse d’afficher cet état sans attendre 24 h.",
"whatRunsTitle": "Ce que l’analyse exécute",
"whatRunsIntro": "Pour chaque CT à l’état <code>running</code> avec un gestionnaire de paquets pris en charge :",
"whatRunsItems": [
"<strong>Fraîcheur des métadonnées.</strong> Si le cache apt/apk dépasse <strong>24 heures</strong>, une actualisation est tentée avec <code>apt-get update -qq</code> sur Debian/Ubuntu ou <code>apk update</code> sur Alpine, limitée à 60 s. En cas d’échec, la liste utilise le cache disponible et peut être périmée.",
"<strong>Liste.</strong> Exécute <code>apt list --upgradable</code> / <code>apk list -u</code> et extrait le nombre de paquets et quelques noms.",
"<strong>Éviter les doublons par CT.</strong> Une empreinte du total, des mises à jour de sécurité et des noms triés évite les avis quotidiens identiques. Un changement significatif déclenche un nouvel avis."
],
"selfUpdateTitle": "Les CT actualisés hors apt peuvent afficher 0",
"selfUpdateBody": "La détection ne couvre que le gestionnaire de paquets du CT. Les logiciels actualisés hors apt, comme un travail <code>plexupdate</code> configuré ou les images obtenues par <code>docker pull</code>, n’entrent pas dans le compte. Zéro mise à jour apt ne prouve pas que toutes les applications sont à jour. Les paquets du système de base restent détectés.",
"refreshTitle": "Pourquoi actualiser les métadonnées après 24 h",
"refreshBody": "Un CT ancien peut avoir des métadonnées apt périmées si personne ne lance <code>apt update</code>. <code>apt list --upgradable</code> peut alors manquer des mises à jour. ProxMenux tente une actualisation après 24 heures et l’omet si le cache est plus récent.",
"toggleTitle": "Interrupteur de notification lié à la détection",
"toggleBody": "L’interrupteur <code>lxc_updates_available</code> par canal dans <strong>Notifications → Services</strong> n’apparaît que si la détection est active. La désactiver masque la ligne pour tous les canaux. Le choix reste dans la base et retrouve sa valeur à la réactivation.",
"purgeTitle": "Ce qui est supprimé à la désactivation",
"purgeBody": "La désactivation retire aussitôt les entrées <code>type=lxc</code> de <code>/usr/local/share/proxmenux/managed_installs.json</code>. Les compteurs de mises à jour LXC de Matériel disparaissent à l’actualisation suivante. La réactivation remplit le registre au prochain cycle, ou plus tôt par actualisation manuelle de l’API."
},
"storageExclusions": {
"heading": "Exclusions de stockage distant",
"imageAlt": "Carte d’exclusion des stockages distants PBS-Cloud, PBS et PBS2 avec réglages État et Alertes par ligne",
"imageCaption": "Réglages <em>État</em> et <em>Alertes</em> par stockage. Tous deux désactivés, le stockage ne contribue plus au Health Monitor et n’envoie plus de notifications. Il reste visible dans Stockage avec la mention exclu.",
"intro": "Vous pouvez exclure les stockages gérés par Proxmox (NFS / CIFS / PBS / Ceph / iSCSI / etc.) au moyen de deux réglages indépendants :",
"items": [
"<strong>État</strong> — désactiver ce réglage retire le stockage de la catégorie Stockage du Health Monitor. Utile pour les volumes d’archives généralement hors ligne ou les cibles de sauvegarde distantes allumées uniquement aux heures prévues.",
"<strong>Alertes</strong> — désactiver ce réglage empêche les notifications de ce stockage sur les canaux configurés, même si les contrôles d’état restent actifs. Utile pour consulter son état sans recevoir de notifications."
],
"outro": "Les stockages exclus restent dans l’<link>onglet Stockage</link> avec le badge violet <em>exclu</em>, pour conserver un inventaire visible. L’état est enregistré dans la table SQLite <code>excluded_storages</code>."
},
"interfaceExclusions": {
"heading": "Exclusions d'interface réseau",
"imageAlt": "Carte d’exclusion des interfaces vmbr0, vmbr1, vmbr2, bond0 et eno1 avec réglages État et Alertes par interface",
"imageCaption": "Comme pour le stockage, chaque interface possède <em>État</em> et <em>Alertes</em>. Chaque ligne montre le nom, le type (pont / agrégat / physique), l’IP et le débit du lien.",
"intro": "Le même principe s’applique aux interfaces : exclure chacune des contrôles d’état, des notifications ou des deux. Exemples courants :",
"items": [
"Un pont de réserve volontairement désactivé.",
"Une carte réseau retirée physiquement mais encore référencée dans <code>/etc/network/interfaces</code>.",
"Une sous-interface VLAN utilisée uniquement pendant la maintenance.",
"Un pont de gestion dont les changements répétés d’état du lien sont connus pendant la maintenance."
],
"outro": "L’état est enregistré dans la table SQLite <code>excluded_interfaces</code>. Le badge violet <em>exclue</em> de l’<link>onglet Réseau</link> garde les interfaces exclues visibles."
},
"notifications": {
"heading": "Notifications et IA",
"body1": "Cette section active les notifications de ProxMenux Monitor et la reformulation par IA. <em>Activer les notifications</em> démarre l’envoi en arrière-plan, enregistre une cible webhook Proxmox VE pour intégrer ses événements et ouvre le formulaire des canaux : Telegram, Discord, courriel, Gotify et autres. La reformulation par IA figure dans une section avancée repliable du même panneau.",
"body2": "Des pages dédiées expliquent les options : canaux, événements, messages enrichis, nom affiché, envoi avec dédoublonnage, temporisation, regroupement et heures silencieuses, webhook PVE, fournisseurs d’IA et modes d’instructions :",
"items": [
"<notifLink>Notifications</notifLink> : configuration des canaux (Telegram, Discord, Gotify, courriel et mots de passe d’application Gmail / Microsoft, ntfy, Slack, Teams et webhook générique), catégories d’événements, messages enrichis, nom affiché, envoi, webhook PVE, historique et API.",
"<aiLink>Assistant IA</aiLink> : fournisseurs (OpenAI, Anthropic, Gemini, Groq, OpenRouter, Ollama), modèles, instructions par défaut ou personnalisées, langue de sortie, niveau de détail par canal et suggestions d’IA."
]
},
"optimizations": {
"heading": "Optimisations ProxMenux",
"intro": "Inventaire des optimisations après installation enregistrées par ProxMenux sur l’hôte. Les options de <autoLink>Post-installation automatisée</autoLink> et <customLink>Post-installation personnalisable</customLink> enregistrent leur application dans <code>/usr/local/share/proxmenux/installed_tools.json</code>. Le moniteur lit ce registre. Une entrée ne vérifie pas à nouveau que tous les réglages sont restés identiques.",
"imageAlt": "Carte des optimisations ProxMenux avec 14 entrées : point coloré, nom et version. Elle comprend APT IPv4 Force, Bashrc Customization, Fastfetch, Log2ram SSD Protection, Memory Settings Optimization, Setting persistent network interfaces, System Limits Increase, APT Language Skip, Entropy Generation haveged avec Legacy, Kernel Panic Configuration, Logrotate Optimization, Network Optimizations, Subscription Banner Removal et VFIO IOMMU Passthrough.",
"imageCaption": "Chaque optimisation affiche nom, version et point coloré. Le compteur orange <em>14 actives</em> figure en haut à droite. Les outils dont le code source est disponible sont cliquables.",
"dotsTitle": "Ce que signifient les points",
"dotsItems": [
"<green/> <strong>Point vert</strong> : optimisation enregistrée sans mention Legacy ni mise à jour indiquée. Cliquez sur la ligne si le code source est disponible.",
"<amber/> <strong>Point ambre et badge <em>legacy</em></strong> : optimisation enregistrée dont le script a été renommé ou remplacé. Le code conservé s’ouvre en mode Legacy avec des touches ambre. Cela ne vérifie pas à nouveau la configuration actuelle de l’hôte."
],
"clickTitle": "Ouvrir le code source",
"clickBody": "Cliquer affiche la fonction bash associée et le nom du script (<code>auto_post_install.sh</code> ou <code>customizable_post_install.sh</code>). Les outils actuels sont extraits des fichiers de l’hôte ; les anciens peuvent utiliser du code conservé. Coloration syntaxique et copie facilitent l’examen. Ce n’est pas un instantané garanti du code exécuté à l’installation.",
"detailAlt": "Fenêtre de code d’APT IPv4 Force montrant la fonction bash force_apt_ipv4 de customizable_post_install.sh version 1.0. Le code coloré configure /etc/apt/apt.conf.d/99-force-ipv4 avec Acquire ForceIPv4 true, enregistre l’outil et affiche un message traduit de fin de configuration APT IPv4.",
"detailCaption": "Code d’<em>APT IPv4 Force</em> : fonction <code>force_apt_ipv4()</code> de <code>customizable_post_install.sh v1.0</code>, avec coloration syntaxique et copie en un clic.",
"whyTitle": "Pourquoi cela est important",
"whyBody": "ProxMenux peut modifier les paramètres du noyau, dépôts, réseau, rotation des journaux et passthrough GPU. Consultez les optimisations enregistrées avant des changements manuels, surtout si un autre administrateur a installé l’hôte. La carte montre le registre et le code disponible ; elle n’audite pas tous les réglages actuels et ne garde pas un historique exact d’exécution.",
"updatesTitle": "Bannière des mises à jour disponibles",
"updatesBody": "Si la version sur disque d’une optimisation est plus récente que celle enregistrée sur l’hôte, une bannière affiche le nombre et <strong>Appliquer</strong>. <strong>Appliquer</strong> ouvre le choix des optimisations, comme <em>Appliquer les mises à jour disponibles</em> du menu de post-installation. Choisissez les mises à jour ; ProxMenux relance leurs fonctions et actualise le registre. La bannière disparaît quand tout est à jour.",
"updatesAlt": "Carte des optimisations ProxMenux avec bannière de mises à jour disponibles, nombre en attente et bouton Appliquer ouvrant le sélecteur",
"updatesCaption": "La bannière apparaît si au moins une optimisation possède une version plus récente sur disque. Voir <link>Appliquer les mises à jour disponibles</link> pour la procédure et son équivalent Path-A dans le menu du shell.",
"revertTitle": "Annuler une optimisation",
"revertBody": "Pour annuler une optimisation, utilisez l’option correspondante de <link>Désinstaller les optimisations</link> dans ProxMenux Scripts. La désinstallation retire son entrée d’<code>installed_tools.json</code> ; elle disparaît de la carte à l’actualisation suivante."
},
"dataCollected": {
"heading": "Comment les données sont collectées",
"headerCard": "Carte",
"headerEndpoint": "Point d’accès",
"headerSource": "Source",
"rows": [
{
"card": "Langue d'interface",
"endpoint": "localStorage",
"source": "Préférence <code>proxmenux-ui-language</code> du navigateur ; sans choix enregistré, sa langue sert de valeur initiale."
},
{
"card": "Ordre de navigation",
"endpoint": "localStorage",
"source": "Préférence <code>proxmenux-nav-order</code> du navigateur ; elle détermine aussi l’onglet initial."
},
{
"card": "Unités réseau",
"endpoint": "/api/settings",
"source": "Enregistré dans la table SQLite des paramètres du tableau de bord."
},
{
"card": "Durées du Health Monitor",
"endpoint": "/api/health/settings",
"source": "Durée de suppression par catégorie dans la base du Health Monitor."
},
{
"card": "Exclusions de stockage / interface",
"endpoint": "/api/storage/exclusions, /api/network/exclusions",
"source": "Tables SQLite <code>excluded_storages</code> et <code>excluded_interfaces</code>."
},
{
"card": "Panneau Notifications et IA",
"endpoint": "/api/notifications/*",
"source": "Voir <notifLink>Notifications</notifLink> et <aiLink>Assistant IA</aiLink>."
},
{
"card": "Liste des optimisations ProxMenux",
"endpoint": "/api/proxmenux/installed-tools",
"source": "Lit <code>/usr/local/share/proxmenux/installed_tools.json</code>, écrit par les appels à <code>register_tool</code> des scripts de post-installation."
},
{
"card": "Fenêtre du code d’une optimisation",
"endpoint": "/api/proxmenux/tool-source",
"source": "Extrait la fonction bash associée d’<code>auto_post_install.sh</code> ou de <code>customizable_post_install.sh</code> sur l’hôte ; les anciens outils peuvent utiliser du code conservé."
}
]
},
"whereNext": {
"heading": "Pour continuer",
"items": [
{
"label": "onglet Apps",
"href": "/docs/monitor/dashboard/apps",
"tail": " — le lanceur dont la position se règle avec l’ordre de navigation."
},
{
"label": "Notifications",
"href": "/docs/monitor/notifications",
"tail": " — canaux, réglages par événement, options propres aux canaux, historique et envoi de test."
},
{
"label": "Assistant IA",
"href": "/docs/monitor/ai-assistant",
"tail": " — fournisseurs, modèles, modes d’instructions, langues et détail par canal."
},
{
"label": "Health Monitor → Rejeter les alertes et durée de suppression",
"href": "/docs/monitor/health-monitor#dismissing-alerts-and-the-suppression-duration",
"tail": " — le fonctionnement des listes de durée par catégorie."
},
{
"label": "ProxMenux Scripts → Post-installation automatisée",
"href": "/docs/post-install/automated",
"tailRich": " et <customLink>Post-installation personnalisable</customLink> — les scripts qui enregistrent les optimisations dans la liste ci-dessus."
},
{
"label": "Désinstaller les optimisations",
"href": "/docs/post-install/uninstall",
"tail": " — comment annuler une optimisation enregistrée ci-dessus."
},
{
"label": "Indice du tableau de bord",
"href": "/docs/monitor/dashboard",
"tail": " — retour à la présentation des onglets."
}
]
}
}
@@ -0,0 +1,268 @@
{
"meta": {
"title": "ProxMenux Monitor — Tableau de bord : onglet Stockage | Documentation ProxMenux",
"description": "L’onglet Stockage réunit quatre vues : stockages Proxmox avec leur état, pools ZFS, disques internes avec SMART et disques USB externes. Le détail de chaque disque affiche les attributs SMART, l’usure, la durée de vie et l’historique permanent des observations."
},
"header": {
"title": "Tableau de bord : onglet Stockage",
"description": "Le stockage de l’hôte sur un écran : NFS / CIFS / LVM / ZFS / dir Proxmox, état des pools ZFS, disques internes SATA/NVMe avec SMART et disques USB externes. Cliquez sur un disque pour voir ses attributs SMART et son historique d’observations.",
"section": "ProxMenux Monitor · Tableau de bord"
},
"intro": {
"title": "Soutenu par trois sources",
"body": "Les stockages Proxmox viennent de <code>pvesm status</code>, ZFS de <code>zpool status</code>, les disques de <code>lsblk</code> + <code>smartctl</code> et les champs NVMe de <code>nvme</code>. L’onglet s’actualise environ toutes les 60 secondes ; ouvrir le détail demande une lecture SMART."
},
"thresholds": {
"title": "Couleurs et seuils appliqués ici",
"intro": "Health Monitor classe l’état en <green/> <strong>vert</strong> sous Avertissement, <amber/> <strong>orange</strong> entre Avertissement et Critique et <red/> <strong>rouge</strong> à partir de Critique. Ses valeurs par défaut suivent. Les barres du tableau de bord peuvent utiliser d’autres limites visuelles décrites plus bas.",
"items": [
"<strong>Capacité</strong> (disques de l’hôte, stockages PVE, pools ZFS, montages LXC) — avertissement 85 %, critique 95 %.",
"<strong>Température du disque</strong> — HDD 60/65 °C · SSD 70/75 °C · NVMe 80/85 °C · SAS 55/65 °C (avertissement / critique)."
],
"outro": "Chaque valeur est configurable par hôte. <link>Paramètres → Seuils de Health Monitor</link> présente les valeurs de référence et leur réglage."
},
"topRow": {
"heading": "Rangée supérieure : aperçu du stockage",
"intro": "À l’ouverture, quatre cartes résument capacité totale, utilisation locale, utilisation distante et inventaire des disques physiques. Elles donnent une réponse rapide ; les cartes inférieures présentent les détails.",
"imageAlt": "Onglet Stockage avec quatre cartes : stockage total, utilisation locale, utilisation distante et disques physiques",
"imageCaption": "Rangée supérieure : capacité totale et nombre de disques, octets utilisés localement et à distance, répartition des disques physiques par type et état.",
"headerCard": "Carte",
"headerWhat": "Ce qu'il montre",
"totalLabel": "Stockage total",
"totalWhat": "Capacité brute totale de tous les disques physiques. Le pied indique le nombre de disques détectés.",
"localLabel": "Utilisation locale",
"localWhat": "Octets utilisés sur les stockages locaux : LVM / LVM-thin / ZFS / dir sur les disques de l’hôte. La valeur principale affiche les octets utilisés et le pied <em>X.XX % de Y TB</em> indique aussi le taux de remplissage.",
"remoteLabel": "Utilisation distante",
"remoteWhat": "Même format que l’utilisation locale pour les stockages distants NFS / CIFS / PBS / Ceph / iSCSI. Ils sont comptés séparément, car les pannes locales et distantes ont une portée différente et ces ressources se dimensionnent et se surveillent différemment.",
"disksLabel": "Disques physiques",
"disksIntro": "Deux lignes de ventilation pour l'inventaire :",
"disksItems": [
"<strong>Par type</strong> — nombre de NVMe en violet, de SSD et HDD en bleu. Les types détectés sont affichés ; un hôte tout NVMe ne montre que ce nombre.",
"<strong>Par état</strong> — nombre de disques <em>normaux</em> en vert, en <em>avertissement</em> en jaune et <em>critiques</em> en rouge. Sans problème, seul « X normaux » apparaît ; les autres états s’affichent en cas d’incident."
]
},
"pveStorage": {
"heading": "Carte de stockage Proxmox",
"intro": "Une ligne par stockage de <code>/etc/pve/storage.cfg</code> avec type (<code>nfs</code> / <code>cifs</code> / <code>zfspool</code> / <code>lvm</code> / <code>lvmthin</code> / <code>dir</code> / <code>pbs</code>), nom, état actif/erreur/non surveillé, taux d’utilisation et barre colorée :",
"items": [
"<strong>Jusqu’à 75 %</strong> — barre et valeur bleues.",
"<strong>Plus de 75 % jusqu’à 90 %</strong> — barre et valeur jaunes. Ces limites visuelles sont distinctes des seuils de Health Monitor.",
"<strong>> 90 %</strong> — barre et valeur rouges. Cette limite visuelle est distincte de l’escalade de Health Monitor.",
"<strong>Erreur</strong> — contour rouge de la ligne si le stockage est configuré mais inaccessible, par exemple serveur NFS arrêté ou identifiants CIFS expirés.",
"<strong>Exclu</strong> — contour violet et étiquette « non surveillé ». Stockages exclus par l’utilisateur, comme les volumes d’archive volontairement déconnectés."
],
"calloutTitle": "Exclure un stockage de la surveillance",
"calloutBody": "Le menu de chaque stockage permet de le marquer <em>exclu de la surveillance</em>. Le réglage est conservé dans <code>excluded_storages</code> et appliqué par le tableau de bord et Health Monitor : aucune notification ni influence sur l’état global."
},
"zfs": {
"heading": "Carte Pools ZFS",
"intro": "Visible uniquement si ZFS est installé et qu’un pool existe. Chaque ligne montre un pool avec état, taille, espace alloué et libre et icône d’état :",
"items": [
"<strong>ONLINE</strong> — vert. Tout est sain.",
"<strong>DEGRADED</strong> — jaune. Le pool fournit les données, mais au moins un appareil est indisponible ; son remplacement doit être traité.",
"<strong>FAULTED</strong> / <strong>UNAVAIL</strong> / <strong>SUSPENDED</strong> — rouge. Le pool ne fournit plus de données et nécessite une intervention immédiate."
],
"outro": "L’état ZFS et SMART de chaque disque alimente la catégorie <em>Disques et E/S</em> de <link>Health Monitor</link>."
},
"physical": {
"heading": "Disques physiques et statut SMART",
"intro": "Disques internes (SATA / NVMe). Chaque rangée condense les champs les plus utiles en un coup d'oeil:",
"items": [
"<strong>Chemin du périphérique</strong> — <code>/dev/sda</code>, <code>/dev/nvme0n1</code>.",
"<strong>Étiquette de type</strong> — SATA / NVMe et icône associée.",
"<strong>Étiquette système</strong> — marque orange pour les disques identifiés comme hébergeant le système. La détection utilise les montages <code>/</code> et <code>/boot</code> et applique l’étiquette <em>System</em>. Son absence ne prouve pas qu’un disque peut être effacé ou réutilisé sans risque.",
"<strong>Modèle</strong> — fabricant et modèle de <code>smartctl -i</code>.",
"<strong>Capacité</strong> — exprimée en unités lisibles.",
"<strong>Température</strong> — valeur actuelle en °C, colorée selon le type de disque ; les seuils NVMe sont plus élevés que SATA.",
"<strong>État SMART</strong> — réussi / échoué / inconnu.",
"<strong>Étiquette d’observations</strong> — si l’historique permanent <code>disk_observations</code> contient des entrées du disque, une étiquette bleue en indique le nombre, par exemple <em>3 obs.</em>. Cliquez sur le disque pour les consulter.",
"<strong>Étiquette d’état</strong> — Sain / Avertissement / Critique selon SMART et les observations récentes."
],
"clickHint": "Un clic sur la ligne ouvre le détail du disque décrit plus bas.",
"warningTitle": "Prudence avec les disques marqués System",
"warningBody": "Les disques marqués en orange <strong>System</strong> hébergent le système actif. L’étiquette aide à les identifier ; <link>ProxMenux → Gestionnaire de disques → Formater / Effacer</link> refuse les actions destructrices sur eux. Pour réutiliser un disque de démarrage, utilisez un environnement de secours externe au Proxmox en cours d’exécution."
},
"external": {
"heading": "Stockage externe (USB)",
"body": "Les disques USB ont une carte distincte, visible lorsqu’un disque est présent. Elle affiche les mêmes champs que les disques internes et une étiquette orange <strong>USB</strong>. Comme ces disques servent souvent aux sauvegardes ou transferts occasionnels, les observations sont conservées, mais les erreurs d’E/S d’un disque USB débranché ne sont pas escaladées."
},
"drillIn": {
"heading": "Dialogue de détail du disque",
"intro": "Cliquez sur un disque pour ouvrir quatre onglets : <strong>Aperçu</strong> · <strong>SMART</strong> · <strong>Historique</strong> · <strong>Planification</strong>. L’en-tête affiche chemin, modèle, capacité et, si nécessaire, l’étiquette orange <em>System</em>.",
"overviewTitle": "Onglet 1 — Aperçu",
"overviewImageAlt": "Détail du disque, onglet Aperçu avec état, indicateur circulaire d’usure et de durée de vie et principaux attributs SMART",
"overviewImageCaption": "Aperçu : identification, état, durée de vie restante avec usure actuelle et données écrites, et principaux attributs SMART.",
"overviewIntro": "Onglet initial pour consulter l’état du disque sans lancer de test. Trois blocs :",
"overviewItems": [
"<strong>Identification</strong> — modèle, numéro de série, capacité et état Sain / Avertissement / Critique.",
"<strong>Usure et durée de vie</strong> — anneau de durée restante (97 %, 50 %, …) avec l’attribut source (<em>Media Wearout Indicator</em>, <em>Percentage Used</em>, …), barre du pourcentage consommé, projection <em>Durée estimée</em> en années et total des données écrites. NVMe affiche aussi <em>Available Spare</em>.",
"<strong>Attributs SMART</strong> : les principales valeurs sont affichées sur deux colonnes : température, heures de fonctionnement avec une durée lisible comme <em>3 ans et 116 jours</em>, vitesse de rotation ou <em>SSD</em>, cycles de mise sous tension, état SMART, secteurs réalloués, secteurs en attente et erreurs CRC. Le tableau complet des attributs se trouve dans l’onglet SMART."
],
"smartTitle": "Onglet 2 — SMART",
"smartImageAlt": "Détail du disque, onglet SMART avec tests court et étendu, dernier résultat et tableau complet des attributs",
"smartImageCaption": "Onglet SMART : lancez un test court ou étendu, consultez le dernier résultat et tous les attributs, puis ouvrez le rapport complet pour l’imprimer ou l’enregistrer en PDF.",
"smartIntro": "Actions disponibles en trois sections :",
"smartItems": [
"<strong>Lancer un test SMART</strong> — deux boutons. <em>Test court (~2 min)</em> attend le résultat et l’affiche dans le dialogue. <em>Test étendu (arrière-plan)</em> peut durer des heures sur les grands disques, continue sur le serveur et notifie à la fin.",
"<strong>Dernier test</strong> — type, état (<em>réussi</em> / <em>échoué</em>) et date du dernier test.",
"<strong>Attributs SMART</strong> — tableau complet avec ID, nom, valeur, pire valeur et état correct, avertissement ou critique. SATA/SAS affiche la liste numérotée. NVMe utilise <code>nvme smart-log</code> : température, réserve disponible, pourcentage utilisé, unités lues/écrites, lectures/écritures hôte, temps d’occupation du contrôleur, cycles d’alimentation, arrêts non sûrs, erreurs du support, entrées du journal d’erreurs et temps de température composite en avertissement/critique."
],
"pdfTitle": "Afficher le rapport SMART complet (PDF)",
"pdfIntro": "En bas de SMART, <strong>Afficher le rapport SMART complet</strong> ouvre un rapport imprimable. Le dialogue d’impression du navigateur permet de l’enregistrer en PDF pour l’archiver ou le partager avec le support lors d’un RMA.",
"pdfPreviewAlt": "Première page du rapport SMART avec synthèse, indicateur PASSED et informations sur le disque",
"pdfPreviewCaption": "Première page : synthèse, indicateur PASSED et informations complètes du disque. L’exemple PDF contient l’usure SSD, tous les attributs SMART et l’historique des tests.",
"pdfDownloadLabel": "Télécharger un exemple de rapport SMART (PDF)",
"pdfSectionsIntro": "Le rapport comporte six sections principales :",
"pdfSections": [
"<strong>Synthèse</strong> — état PASSED/FAILED, évaluation claire du disque — sain, usé ou défaillant — et quatre données : date du rapport, dernier type de test, résultat et attributs vérifiés.",
"<strong>Informations sur le disque</strong> — modèle, série, capacité, type HDD/SSD/NVMe, famille, format, interface (SATA 3.3 · 6.0 Gb/s, …), TRIM, température et seuil optimal, heures de fonctionnement, cycles d’alimentation, SMART, secteurs en attente/réalloués et erreurs CRC.",
"<strong>Usure et durée de vie SSD</strong> (SSD/NVMe uniquement) — durée restante, attribut source, usure actuelle, données écrites et heures de fonctionnement.",
"<strong>Attributs SMART complets</strong> — ID, nom, valeur, pire valeur, seuil, valeur brute et état de chaque attribut. Les principaux — Reallocated Sector Ct, Power On Hours, Reported Uncorrect, UDMA CRC Error Count, Media Wearout Indicator, … — ont une brève explication sous leur ligne.",
"<strong>Dernier autotest et historique complet</strong> — dernier test avec type, résultat, message final et heures de fonctionnement à ce moment, puis tableau numéroté de tous les tests conservés.",
"<strong>Recommandations</strong> — actions selon le résultat. Pour les disques sains : <em>disque sain / tests périodiques / stratégie de sauvegarde</em>. Des conseils de remplacement apparaissent si les attributs sortent des limites."
],
"pdfOutro": "Le navigateur construit le rapport imprimable ; Imprimer et Enregistrer en PDF ouvrent le dialogue d’impression. Choisissez un nom comme <code>SMART-&lt;short-id&gt;.pdf</code>. Conservez des copies datées pour comparer les changements ou les partager avec le support.",
"historyTitle": "Onglet 3 — Historique",
"historyImageAlt": "Détail du disque, onglet Historique avec les tests SMART précédents et actions de téléchargement et suppression",
"historyImageCaption": "Historique SMART du disque. Chaque ligne affiche type, date, ancienneté, repère du dernier test et actions de téléchargement de la sortie <code>smartctl</code> et suppression.",
"historyIntro": "Tests courts et étendus terminés et conservés pour le disque. Chaque entrée contient la sortie originale <code>smartctl</code> et les champs interprétés par Monitor pour le tableau de bord. Actions par ligne :",
"historyItems": [
"<strong>Télécharger</strong> — enregistre l’instantané JSON contenant les données <code>smartctl -a</code> utilisées par le rapport. Utile si le support demande les champs de diagnostic originaux.",
"<strong>Supprimer</strong> — retire manuellement un test de l’historique. La conservation de Planification (<em>5 / 10 / 20 derniers</em>) supprime automatiquement les plus anciens."
],
"scheduleTitle": "Onglet 4 — Planification",
"scheduleImageAlt": "Détail du disque, onglet Planification avec interrupteur des tests SMART automatiques, liste des horaires et bouton Ajouter une planification",
"scheduleImageCaption": "Planification : choisissez type, fréquence et conservation ; Monitor configure <code>cron</code> pour exécuter les tests automatiquement.",
"scheduleIntro": "Tests SMART automatiques via cron, sans terminal. Trois zones :",
"scheduleItems": [
"<strong>Tests SMART automatiques</strong> — interrupteur commun à toutes les planifications du disque. Il permet de les suspendre pendant la maintenance sans effacer leur configuration.",
"<strong>Planifications configurées</strong> — une ligne par horaire avec type (<em>court</em> / <em>long</em>), expression cron lisible (<em>« Le 1er du mois à 03:00 »</em>, <em>« Chaque dimanche à 02:00 »</em>), disques concernés et conservation.",
"<strong>Ajouter / Modifier une planification</strong> — type (<em>court ~2 min</em> / <em>long 1–4 h</em>), fréquence (<em>quotidienne / hebdomadaire / mensuelle</em>), jour du mois ou de la semaine, heure et résultats conservés (<em>5 / 10 / 20 derniers</em>)."
],
"scheduleOutro": "La planification crée une entrée cron sur l’hôte qui appelle Monitor. Les résultats vont dans l’historique SMART de l’onglet 3 et la conservation supprime automatiquement les plus anciens après un nouveau test.",
"tempTitle": "Dialogue d’historique de température",
"tempIntro": "Monitor relève régulièrement les disques équipés d’un capteur de température et conserve un historique local. La valeur actuelle figure dans Aperçu ; un clic ouvre le détail de l’historique de température.",
"tempImageAlt": "Historique de température avec chemin et modèle, périodes de 1 heure, 24 heures, 7 ou 30 jours, indicateurs Actuel/Minimum/Moyenne/Maximum et courbe colorée selon les seuils du type de disque",
"tempImageCaption": "Le détail de température s’ouvre depuis Aperçu si le capteur renvoie une valeur non nulle. Le graphique utilise les seuils HDD / SSD / NVMe / SAS.",
"tempShowsTitle": "Contenu du dialogue",
"tempShowsItems": [
"<strong>Sélecteur de période</strong> : <em>1 heure</em>, <em>24 heures</em> par défaut, <em>7 jours</em> ou <em>30 jours</em>. Chaque requête adapte la résolution pour garder le graphique lisible.",
"<strong>Quatre indicateurs</strong> : <em>Actuel</em>, <em>Minimum</em>, <em>Moyenne</em> et <em>Maximum</em> sur la période. <em>Actuel</em> utilise les seuils du stockage et des notifications pour distinguer une température normale, élevée ou très élevée.",
"<strong>Courbe</strong> de température dans le temps, avec ligne et zone ombrée colorées selon le type de disque :"
],
"tempDiskTypes": [
"HDD — seuils de température généralement plus bas.",
"SSD — seuils modérés.",
"NVMe — seuils plus élevés (NVMe est plus chaud par conception).",
"SAS — avertissement à 55 °C et critique à 65 °C ; le seuil d’avertissement diffère du HDD."
],
"tempConfigurable": "Les quatre types se configurent dans <em>Paramètres → Seuils de Health Monitor</em>.",
"tempWhyTitle": "Pourquoi l’historique est utile",
"tempWhyItems": [
"<strong>Détecter les tendances.</strong> Une lecture isolée ne révèle pas qu’un disque chauffe progressivement depuis des semaines, par exemple à cause de la ventilation, de la poussière ou d’une source de chaleur proche. Les vues sur 7 et 30 jours montrent l’évolution.",
"<strong>Relier les pics.</strong> Si une sauvegarde ou reconstruction a brièvement dépassé le seuil, les vues sur 1 et 24 heures montrent si le pic est isolé ou récurrent.",
"<strong>Régler les seuils.</strong> Avant une modification dans <em>Paramètres → Seuils de Health Monitor</em>, consultez le graphique de 30 jours pour connaître la plage réelle du disque."
],
"obsTitle": "Historique des observations dans les onglets",
"obsIntro": "Les défauts peuvent apparaître progressivement. Un disque peut indiquer SMART <strong>PASSED</strong> tout en signalant des erreurs de lecture dans dmesg, des coupures SATA ou des secteurs en attente intermittents. ProxMenux conserve ces <em>signaux</em> et les affiche dans le dialogue avec l’état SMART actuel.",
"obsImageAlt": "Aperçu d’un disque avec SMART réussi, zéro secteur réalloué/en attente et erreur CRC, mais une observation d’erreur E/S avec message original du noyau, explication ATA, première et dernière date et compteur",
"obsImageCaption": "Un disque qui <strong>réussit SMART</strong> peut avoir des observations antérieures. La carte ajoute l’historique des signaux à l’état actuel.",
"obsWhatTitle": "Qu’est-ce qu’une observation ?",
"obsWhatIntro": "ProxMenux enregistre comme <strong>observation</strong> les événements disque du journal du noyau, de dmesg ou de SMART trop détaillés pour justifier seuls une notification. Chaque ligne affiche :",
"obsWhatItems": [
"<strong>Type</strong> — erreur E/S, SMART, système de fichiers, pool ZFS ou connexion.",
"<strong>Message original du noyau</strong> tel qu’affiché dans dmesg, à copier dans un moteur de recherche ou une demande de support.",
"<strong>Brève explication</strong> des codes ATA connus : <code>IDNF</code>, adresse de secteur introuvable, secteur ou câble potentiellement défectueux ; <code>UNC</code>, erreur de lecture irrécupérable, secteur défectueux ; et autres codes standard.",
"<strong>Première et dernière date</strong> et <strong>nombre d’occurrences</strong>, regroupés par signature d’erreur."
],
"obsWhyTitle": "Pourquoi ProxMenux les conserve et les affiche",
"obsWhyItems": [
"<strong>Les défauts peuvent évoluer.</strong> Des erreurs de bus ATA, secteurs UNC ou erreurs du support peuvent précéder un état SMART <em>FAILED</em>. Le tampon dmesg ne les conserve pas après redémarrage ; l’historique des observations, oui.",
"<strong>SMART n’exclut pas tous les défauts.</strong> Un disque peut avoir des attributs verts et rencontrer des problèmes. Les observations conservent des symptômes supplémentaires : ICRC, IDNF, réinitialisations SATA ou baisses de vitesse.",
"<strong>Distingue l’actuel du récent.</strong> Health Monitor résout automatiquement les erreurs transitoires qui ne se reproduisent plus. L’historique permet de voir plusieurs jours après, par exemple, trois erreurs E/S survenues une nuit.",
"<strong>Alimente les notifications par niveaux.</strong> disk_io utilise la fréquence des observations pour choisir silence, WARNING ou CRITICAL sur une fenêtre glissante de 24 heures introduite en 1.2.1.2."
],
"obsDedupTitle": "Regroupement des doublons et nouveaux avis",
"obsDedupBody1": "Les observations sont regroupées par <strong>signature</strong>, empreinte stable du type d’erreur, de l’appareil et des champs clés du message. Les répétitions augmentent <code>occurrence_count</code> sur la ligne existante. Une <strong>signature différente</strong> crée une autre observation et un nouvel événement pour les notifications.",
"obsDedupBody2": "Pour éviter les cascades, la première combinaison disque, signature et gravité avertit l’opérateur. La même combinaison attend 24 heures avant un nouvel avis, même si le compteur augmente. Le passage de WARNING à CRITICAL interrompt ce délai et signale l’aggravation.",
"obsDismissTitle": "Historique permanent et erreurs actives",
"obsDismissBody1": "Les observations ne peuvent être rejetées, masquées ni supprimées. Chaque signature a une carte ; une répétition augmente le compteur et actualise la dernière date. L’historique suit le numéro de série : un autre disque commence vide même sur le même port, et un renommage par le noyau conserve l’historique.",
"obsDismissBody2": "Résoudre ou rejeter une erreur active dans Health Monitor ne modifie pas ses observations. Elles subsistent après résolution automatique, pour qu’un avertissement transitoire de la semaine passée reste visible. Consultez <link>Health Monitor</link> pour gérer les erreurs actives."
},
"dataCollected": {
"heading": "Comment les données sont collectées",
"headerSection": "Section de l'onglet",
"headerEndpoint": "Point de terminaison",
"headerSource": "Source",
"rows": [
{
"section": "Cartes de synthèse supérieures",
"endpoint": "/api/storage/summary",
"source": "Agrégé de <code>lsblk</code>, <code>zpool list</code>, <code>vgs</code> / <code>lvs</code>."
},
{
"section": "Inventaire par disque",
"endpoint": "/api/storage",
"source": "<code>lsblk -O</code> + <code>smartctl -i</code> par appareil, avec cache d’identité vidé lors des branchements à chaud."
},
{
"section": "Stockages Proxmox",
"endpoint": "/api/proxmox-storage",
"source": "<code>pvesh get /nodes/&lt;node&gt;/storage</code> avec l'état actif/en ligne de chacun."
},
{
"section": "Valeurs SMART actuelles",
"endpoint": "/api/storage/smart/<disk>",
"source": "<code>smartctl -A &lt;dev&gt;</code> est une requête possible ; le point de détail utilise aussi le JSON SMART complet et les données propres à NVMe."
},
{
"section": "Historique des autotests SMART",
"endpoint": "/api/storage/smart/<disk>/history",
"source": "Conservé sous <code>/usr/local/share/proxmenux/smart/&lt;disk&gt;/</code> en instantanés JSON."
},
{
"section": "Observations permanentes",
"endpoint": "/api/storage/observations",
"source": "Table SQLite actualisée par Health Monitor à chaque cycle et conservée après résolution des erreurs actives."
}
],
"outro": "Vérifier la chaîne de collecte sur l'hôte:",
"codeComment1": "# Récupérer l’état actuel depuis un script",
"codeComment2": "# Comparer les données du tableau de bord à celles du système d’exploitation"
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Moniteur de santé",
"href": "/docs/monitor/health-monitor",
"tail": " — catégorie Disques et E/S et règles de suppression."
},
{
"label": "Référence de l’API",
"href": "/docs/monitor/api",
"tail": " — points de terminaison du stockage et de SMART."
},
{
"label": "Notifications",
"href": "/docs/monitor/notifications",
"tailRich": " — actions déclenchées par <code>disk_io_error</code>, <code>storage_unavailable</code> et <code>smart_test_failed</code>."
},
{
"label": "Indice du tableau de bord",
"href": "/docs/monitor/dashboard",
"tail": "— les autres onglets."
},
{
"label": "ProxMenux → Gestionnaire de disques",
"href": "/docs/disk-manager",
"tail": " — actions TUI : formater, effacer, tester SMART et importer des disques dans des VM ou conteneurs."
},
{
"label": "ProxMenux → État et tests SMART du disque",
"href": "/docs/disk-manager/smart-disk-test",
"tail": " — équivalent CLI : planifier les tests SMART, exporter le JSON affiché et consulter les types de tests et leur interprétation."
}
]
}
}
@@ -0,0 +1,120 @@
{
"meta": {
"title": "ProxMenux Monitor — Tableau de bord : Journaux système | Documentation ProxMenux",
"description": "L'onglet Logs système regroupe trois sources en un seul écran : journalctl en direct avec filtres et téléchargement, l'historique des tâches Proxmox (UPIDs), et le journal de notification — tous consultables, filtrés par gravité / plage de temps, et téléchargeables sous forme de paquets de texte."
},
"header": {
"title": "Tableau de bord : Journaux système",
"description": "Trois sous-onglets sur un même écran : journal système (journalctl avec filtres), historique des tâches Proxmox et journal des notifications. Tous permettent de rechercher, filtrer et télécharger les données sous forme de fichiers texte.",
"section": "ProxMenux Monitor · Tableau de bord"
},
"readOnly": {
"title": "En lecture seule par conception",
"body": "Cet onglet ne modifie aucun fichier journal. Les filtres sont conservés dans l'URL ou l'état de l'interface ; les téléchargements sont préparés sur le serveur. Le tableau de bord ne supprime jamais les entrées. Pour leur entretien, utilisez <code>journalctl --vacuum-time=&lt;N&gt;</code> ou <code>logrotate</code> sur l'hôte."
},
"topRow": {
"heading": "Ligne supérieure : quatre compteurs",
"items": [
"<strong>Total des entrées</strong> — nombre de lignes dans la période du filtre actif.",
"<strong>Erreurs</strong> — nombre de lignes de gravité ≤ 3 (<code>err</code> / <code>crit</code> / <code>alert</code> / <code>emerg</code>).",
"<strong>Avertissements</strong> — nombre de lignes de gravité 4 (<code>warning</code>).",
"<strong>Sauvegardes</strong> — nombre de tâches vzdump / PBS dans la même période."
]
},
"subtabs": {
"heading": "Trois sous-onglets",
"logsTitle": "Journaux",
"logsIntro": "Le journal système, obtenu sur le serveur avec <code>journalctl</code>. Filtres disponibles dans la barre d'outils :",
"logsFilters": [
"<strong>Gravité</strong> — emerg / alert / crit / err / warning / notice / info / debug, ou toute combinaison.",
"<strong>Délais</strong> — dernier 5 min/ 15 min/ 1 h/ 6 h/ 24 h/ 7 d/sur mesure.",
"<strong>Recherche libre</strong> — sous-chaîne ou expression régulière (<code>journalctl --grep</code>).",
"<strong>Filtre par unité</strong> — limite les résultats à une unité systemd donnée (<code>pveproxy.service</code>, <code>nginx.service</code>, …)."
],
"logsRowsAfter": "Chaque ligne affiche l'horodatage, le badge de gravité, l'unité source et le message. Les longs messages s'effondrent avec un \"show more\" bascule. L'action <strong>Download</strong> regroupe le filtre actuel dans un seul fichier <code>.txt</code> via <code>GET /api/logs/download</code> — utile quand vous voulez partager une tranche de journal avec quelqu'un.",
"logDetailsModalTitle": "Fenêtre Détails du journal",
"logDetailsBody": "Un clic sur une ligne ouvre la fenêtre <strong>Détails du journal</strong>, avec tous les champs structurés capturés par journald pour cette entrée, comme avec <code>journalctl --output=verbose</code> sur l'hôte.",
"logDetailsImageAlt": "Fenêtre Détails du journal — une entrée développée avec niveau, service, horodatage, source, unité systemd, identifiant du processus, nom d'hôte et message complet",
"logDetailsImageCaption": "Détails du journal — tous les champs structurés de cette entrée journald, avec le message complet non tronqué en bas. Utile pour les journaux de cron et de services lorsque la commande exécutée compte.",
"fieldsIntro": "Champs indiqués :",
"fields": [
"<strong>Niveau</strong> — badge de gravité de couleur (INFO / AVERTISSEMENT / ERREUR / CRITIQUE).",
"<strong>Service</strong> — nom abrégé de l'unité / processus qui a émis l'entrée.",
"<strong>Timestamp</strong> — date et heure complètes de la ligne de journal.",
"<strong>Source</strong> — origine de l'entrée (journal, noyau, audit, ...).",
"<strong>Systemd Unit</strong> — l'unité réelle <code>.service</code> / <code>.timer</code> / <code>.socket</code> si l'entrée était associée à une.",
"<strong>Process ID</strong> — PID du processus émetteur.",
"<strong>Hostname</strong> — utile lorsque les revues sont transmises à travers les nœuds de cluster.",
"<strong>Message</strong> — message complet non tronqué dans un bloc à chasse fixe, prêt à copier."
],
"maxLevelStoreTitle": "Journald MaxLevelStore",
"maxLevelStoreBody": "Sur une nouvelle installation Proxmox, journald utilise par défaut <code>MaxLevelStore=warning</code>, ce qui écarte les messages info. Monitor le détecte au démarrage et ajoute un fichier de configuration complémentaire (<code>/etc/systemd/journald.conf.d/proxmenux-loglevel.conf</code>) avec le seuil <code>info</code>, pour conserver les messages informatifs et plus graves. Cela ne comprend pas debug.",
"backupsTitle": "Sauvegardes",
"backupsBody": "Historique des tâches Proxmox limité aux sauvegardes. Une ligne par tâche (<code>vzdump</code>, transferts PBS, récupération de mémoire inutilisée, vérification), avec état (OK / WARNINGS / ERROR), invité concerné, stockage source, durée et UPID. Cliquez sur une ligne pour charger le journal complet via <code>GET /api/task-log/&lt;upid&gt;</code> : les mêmes données que dans <em>Datacenter → Tâches</em>, limitées aux sauvegardes.",
"notificationsTitle": "Notifications",
"notificationsBody1": "Toutes les notifications envoyées par Monitor : Telegram, Discord, e-mail, Gotify, ntfy, Slack, Teams et webhook. Chaque ligne indique l'horodatage, le canal, le type d'événement, la gravité, le titre et le corps générés et, si l'IA est activée, un bouton pour comparer sa reformulation à l'original.",
"notificationsBody2": "Cet onglet permet de vérifier la bonne livraison par un canal et de comparer la reformulation de l'IA au texte du modèle. Les canaux se configurent sur la page détaillée <link>Notifications</link>."
},
"dataCollected": {
"heading": "Comment les données sont collectées",
"headerSubtab": "Sous-onglet",
"headerEndpoint": "Point de terminaison",
"headerSource": "Source",
"rows": [
{
"subtab": "Journaux (filtre en direct)",
"endpoint": "/api/logs",
"source": "<code>journalctl --output json --since &lt;range&gt;</code> avec filtres de gravité, unité et recherche appliqués sur le serveur."
},
{
"subtab": "Télécharger",
"endpoint": "/api/logs/download",
"source": "Même requête, renvoyée en texte brut pour grep / less."
},
{
"subtab": "Sauvegardes",
"endpoint": "/api/backups",
"source": "Historique des tâches PVE filtré sur <code>vzdump</code>, les transferts PBS, la récupération de mémoire inutilisée et la vérification."
},
{
"subtab": "Détails d'une tâche de sauvegarde",
"endpoint": "/api/task-log/&lt;upid&gt;",
"source": "Journal complet des tâches en texte clair lu à partir de <code>/var/log/pve/tasks/&lt;index&gt;/&lt;upid&gt;</code>."
},
{
"subtab": "Historique des notifications",
"endpoint": "/api/notifications/history",
"source": "Table SQLite <code>notification_history</code> alimentée par la boucle d'envoi."
}
],
"apiIntro": "Le filtre en direct et les téléchargements sont aussi accessibles via l'API :",
"codeComment1": "# Erreurs et événements plus graves de la dernière heure avec un mot-clé",
"codeComment2": "# Télécharger le journal complet des dernières 6 heures en texte simple",
"codeComment3": "# Rechercher la sortie complète d'une tâche spécifique par UPID"
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Moniteur de santé",
"href": "/docs/monitor/health-monitor",
"tail": " — la catégorie Journaux système, qui détecte les événements persistants, les pics et les cascades."
},
{
"label": "Notifications",
"href": "/docs/monitor/notifications",
"tail": " — la surveillance du journal lit la même source et transforme les correspondances en notifications."
},
{
"label": "Référence de l’API",
"href": "/docs/monitor/api",
"tail": " — les points de terminaison logs et task-log et leurs paramètres de requête."
},
{
"label": "Index du tableau de bord",
"href": "/docs/monitor/dashboard",
"tail": "— les autres onglets."
}
]
}
}
@@ -0,0 +1,177 @@
{
"meta": {
"title": "ProxMenux Monitor — Tableau de bord : Aperçu du système | Documentation ProxMenux",
"description": "Onglet initial par défaut de ProxMenux Monitor : quatre cartes (CPU, mémoire, VM et LXC actifs, température) avec actualisation en direct et mini-courbe de tendance, graphique historique et résumés du stockage et du réseau liés à leurs onglets détaillés."
},
"header": {
"title": "Tableau de bord : onglet Aperçu du système",
"description": "L'onglet ouvert par défaut : quatre cartes de mesures en direct en haut, un graphique historique au centre et des résumés du stockage et du réseau en bas, issus des mêmes API que les onglets détaillés.",
"section": "ProxMenux Monitor · Tableau de bord"
},
"readOnly": {
"title": "Un instantané en lecture seule",
"body": "Tous les panneaux de cet onglet sont informatifs. Les actions se trouvent dans les onglets liés : Stockage pour les disques, VMs et LXCs pour démarrer ou arrêter les invités, Sécurité pour l'authentification."
},
"captureAlt": "Onglet Aperçu du système — quatre cartes métriques (CPU, Mémoire, VMs actifs, Température), diagramme des nœuds, et cartes de synthèse de stockage / réseau",
"captureCaption": "Aperçu du système, l'onglet initial par défaut. Les quatre cartes sont actualisées en direct, le graphique montre l'historique et les deux cartes du bas résument le stockage et le réseau.",
"topRow": {
"heading": "Ligne supérieure : cartes de mesures en direct",
"intro": "Quatre cartes en grille 2×2 sur mobile et sur une ligne sur ordinateur. Chacune est actualisée via <code>/api/system</code> toutes les quelques secondes.",
"headerCard": "Carte",
"headerWhat": "Ce qu'il montre",
"headerSource": "Source",
"rows": [
{
"card": "Utilisation du processeur",
"what": "Pourcentage actuel avec une barre de progression. Mise à jour ~1 s via l'échantillonneur de signes vitaux.",
"source": "psutil.cpu_percent()"
},
{
"card": "Utilisation de la mémoire",
"what": "Go utilisés, pourcentage et total en Go. La barre représente le pourcentage.",
"source": "psutil.virtual_memory()"
},
{
"card": "VM active et LXC",
"what": "Nombre d'invités en cours d'exécution, répartition En cours / Arrêtés et total des VM et LXC en bas.",
"source": "/api/vms (consolidé)"
},
{
"card": "Température",
"what": "Température CPU en °C avec état (basse / modérée / élevée) et mini-courbe des 5 dernières minutes en arrière-plan. Affiche <em>N/A</em> sans capteur. Cliquez pour ouvrir les détails.",
"source": "sensors / coretemp"
}
],
"thresholdsTitle": "Couleurs et seuils appliqués ici",
"thresholdsIntro": "Anneaux, barres et mini-courbes suivent la même échelle : <green/> <strong>vert</strong> sous le seuil Avertissement, <amber/> <strong>ambre</strong> entre Avertissement et Critique, <red/> <strong>rouge</strong> à partir de Critique. Valeurs recommandées fournies avec ProxMenux :",
"thresholdsItems": [
"<strong>Utilisation CPU</strong> — avertissement 85 %, critique 95 %.",
"<strong>Mémoire</strong> — avertissement 85 %, critique 95 %. Le swap déclenche aussi le niveau Critique à 5 % d'utilisation ; un hôte Proxmox sain devrait rarement y recourir.",
"<strong>Température CPU</strong> — avertissement 80 °C, critique 90 °C."
],
"thresholdsOutro": "Les valeurs sont configurables par hôte. <link>Paramètres → Seuils du moniteur de santé</link> centralise leur réglage et explique comment les adapter.",
"sparklineTitle": "La mini-courbe montre la tendance",
"sparklineBody": "La carte de température trace les 5 dernières minutes sous la valeur, avec les couleurs Avertissement/Critique définies ci-dessus. Elle permet de voir rapidement si la température de l'hôte augmente sans ouvrir les détails."
},
"processes": {
"heading": "Processus les plus consommateurs de CPU et de mémoire",
"intro": "Les cartes CPU et Mémoire ouvrent une liste triable des 25 processus les plus consommateurs : par utilisation CPU depuis la carte CPU, ou par mémoire résidente depuis la carte Mémoire.",
"listTitle": "La boîte de dialogue liste",
"listItems": [
"<strong>Actualisation automatique</strong> — la liste se met à jour toutes les 5 secondes tant que la fenêtre est ouverte ; les requêtes cessent à sa fermeture.",
"<strong>Filtre</strong> — la recherche limite la liste par commande, utilisateur ou PID.",
"<strong>Barre en ligne</strong> — la colonne métrique primaire dessine une petite barre à l'échelle de la valeur la plus élevée de la liste filtrée, de sorte que le classement reste visible même si aucun processus n'est proche de 100 %.",
"<strong>Disposition mobile</strong> — sous 640 px, les colonnes PID et Utilisateur sont masquées pour garder Commande, CPU % et Mémoire sans défilement horizontal."
],
"captureListAlt": "Fenêtre des processus par mémoire — tableau trié par RSS avec PID, utilisateur, commande, CPU % et mémoire",
"captureListCaption": "La carte mémoire ouvre la liste triée par RSS (accent indigo). La carte CPU ouvre la même liste triée par l'utilisation de CPU (accent bleu).",
"detailTitle": "Détails par processus",
"detailIntro": "Cliquez sur une ligne pour ouvrir une seconde fenêtre avec les données en direct du processus, réparties en quatre sections :",
"detailItems": [
"<strong>Aperçu</strong> — état, processus parent, nombre de threads, descripteurs de fichiers ouverts, utilisateur et groupe.",
"<strong>Ressources</strong> — CPU %, mémoire %, mémoire résidente (RSS), taille virtuelle, swap et totaux des E/S en lecture et écriture.",
"<strong>Commande</strong> — nom court, ligne de commande complète, chemin de l'exécutable et répertoire de travail.",
"<strong>Durée</strong> — horodatage de démarrage et temps d'exécution écoulé."
],
"detailRefresh": "Les détails sont actualisés toutes les 3 secondes. Quand le processus se termine, les requêtes cessent et un bandeau ambre <em>Ce processus est terminé</em> apparaît. Le dernier état capturé reste visible, atténué, pour consulter ce qui se passait juste avant la fin.",
"captureDetailAlt": "Fenêtre de détails d'un processus — Aperçu, Ressources, Commande et Durée pour un PID",
"captureDetailCaption": "Boîte de dialogue de détails par processus ouverte à partir d'une ligne de liste. La couleur de l'accent correspond à la carte qui l'a ouverte (bleu pour CPU, indigo pour Mémoire)."
},
"middle": {
"heading": "Centre : graphiques des métriques du nœud",
"body1": "Sous les cartes, <code>NodeMetricsCharts</code> affiche les historiques CPU, mémoire et E/S disque du stockage RRD de Proxmox via <code>/api/node/metrics</code>. Le sélecteur propose <em>1 heure / 24 heures / 7 jours / 30 jours / 1 an</em>. La résolution diminue pour les grandes périodes afin de conserver un affichage fluide.",
"body2": "Les mêmes graphiques que l'interface web Proxmox pour un nœud, intégrés au thème sombre de Monitor et alignés avec les autres panneaux."
},
"bottom": {
"heading": "Ligne inférieure : Sommaires de stockage et de réseau",
"storageTitle": "Carte d'aperçu du stockage",
"storageIntro": "Une vue condensée de l'état de stockage de l'hôte, divisée en trois blocs:",
"storageItems": [
"<strong>Capacité totale du nœud</strong> — somme des stockages VM/LXC et du stockage local du système, avec une barre dégradée représentant l'espace utilisé et libre.",
"<strong>Capacité totale / Disques physiques</strong> — capacité brute et nombre de disques physiques détectés.",
"<strong>Stockage VM/LXC</strong> — espace utilisé, libre et pourcentage des stockages des invités, avec un compteur s'il y en a plusieurs.",
"<strong>Stockage local (système)</strong> — montage racine ou système de l'hôte, séparé du pool des invités."
],
"storageDrillIn": "Les détails se trouvent dans l'<link>onglet Stockage</link> : SMART par disque, pools ZFS, historique des observations, etc.",
"networkTitle": "Carte d'aperçu du réseau",
"networkBody1": "La ligne supérieure montre le nombre d'interfaces actives (physiques + ponts combinés). En dessous, deux rangées de badges colorés pour les interfaces qui sont <code>up</code> — NIC physiques en bleu, ponts en couleur secondaire. Un sélecteur de temps en haut à droite (1 heure / 24 heures / 7 jours / 30 jours / 1 année) contrôle une petite carte de trafic RX / TX.",
"networkBody2": "Les détails par interface (IP/MAC, graphique RRD, membres du pont, mode bond, etc.) sont dans l'<link>onglet Réseau</link>."
},
"refresh": {
"heading": "Modèle d'actualisation",
"intro": "Chaque panneau gère son état de chargement (<code>loadingStates.cpu</code>, <code>loadingStates.storage</code>, …) pour éviter qu'une source lente bloque les autres. Un espace réservé animé apparaît pendant le chargement. Les échecs sont gérés sans bloquer la vue : sans capteur de température, la carte affiche <em>N/A</em> plutôt qu'une erreur.",
"items": [
"<strong>Cartes supérieures</strong> — actualisation toutes les 5 s environ. CPU et température reçoivent aussi des données chaque seconde depuis l'échantillonneur de signes vitaux.",
"<strong>Graphique des métriques du nœud</strong> — chargement à l'ouverture et au changement de période ou de langue. Un nouvel essai, si nécessaire, a lieu après 60 s.",
"<strong>Carte de stockage</strong> — rafraîchir chaque 60 s. Les données SMART sont mises en cache plus longtemps (l'onglet Stockage déclenche une nouvelle lecture sur demande).",
"<strong>Carte réseau</strong> — résumé toutes les 59 s et graphique du trafic toutes les 60 s pour la période sélectionnée.",
"<strong>Actualisation manuelle</strong> — le bouton Actualiser de l'en-tête recharge immédiatement tous les panneaux."
]
},
"dataCollected": {
"heading": "Comment les données sont collectées",
"headerCard": "Carte",
"headerEndpoint": "Point de terminaison",
"headerSource": "Source",
"rows": [
{
"card": "Indicateur d'état de l'en-tête",
"endpoint": "/api/health",
"source": "L'état global mis en cache produit par le Health Monitor chaque cycle."
},
{
"card": "CPU / RAM / Swap / Durée de fonctionnement",
"endpoint": "/api/system",
"source": "<code>/proc/stat</code>, <code>/proc/meminfo</code>, <code>/proc/uptime</code> avec prélèvement à courte fenêtre CPU."
},
{
"card": "Informations sur l'hôte (kernel, BIOS, distro)",
"endpoint": "/api/info",
"source": "<code>uname -a</code>, <code>dmidecode</code>, version PVE. Mis en cache par processus."
},
{
"card": "Stockage / réseau / cartes VMs",
"endpoint": "/api/storage/summary, /api/network/summary, /api/vms",
"source": "Consultez les onglets détaillés. Les cartes d'en-tête montrent une vue compacte provenant des mêmes points de terminaison."
},
{
"card": "Fréquence d'actualisation",
"endpoint": "—",
"source": "Données système toutes les 5 s ; stockage, VM et résumé réseau toutes les 59 s. Le bouton Actualiser de l'en-tête recharge immédiatement tous les panneaux."
}
],
"codeComment1": "# Appel alimentant l'indicateur d'état de l'en-tête",
"codeComment2": "# public, sans jeton",
"codeComment3": "# instantané authentifié utilisé par les cartes"
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Moniteur de santé",
"href": "/docs/monitor/health-monitor",
"tail": " — la fenêtre de l'indicateur d'état de l'en-tête : dix catégories, masquage et suppression des alertes."
},
{
"label": "Référence de l’API",
"href": "/docs/monitor/api",
"tail": " — points de terminaison system, info et health."
},
{
"label": "Notifications",
"href": "/docs/monitor/notifications",
"tail": "— comment les mêmes statuts se transforment en Telegram / Discord / Messages électroniques."
},
{
"label": "Index du tableau de bord",
"href": "/docs/monitor/dashboard",
"tail": " — les autres onglets du tableau de bord en un coup d'œil."
},
{
"label": "Architecture",
"href": "/docs/monitor/architecture",
"tail": " — les threads en arrière-plan et les API qui alimentent cette vue."
}
]
}
}
@@ -0,0 +1,174 @@
{
"meta": {
"title": "ProxMenux Monitor — Tableau de bord : Terminal | Documentation ProxMenux",
"description": "Shell de l'hôte Proxmox dans le navigateur : jusqu'à 4 terminaux en grille, boutons de clavier pour mobiles (ESC, TAB, flèches, combinaisons Ctrl), aide-mémoire intégré avec cheat.sh et protection JWT."
},
"header": {
"title": "Tableau de bord : onglet terminal",
"description": "Une véritable session shell sur l'hôte Proxmox depuis le navigateur : jusqu'à quatre terminaux simultanés, boutons de clavier pour mobiles et aide-mémoire des commandes, avec le même thème que le reste du tableau de bord.",
"section": "ProxMenux Monitor · Tableau de bord"
},
"intro": {
"title": "Un vrai PTY dans le navigateur",
"body": "Le terminal crée un PTY sur le serveur via <code>flask_terminal_routes</code>, le relie par WebSocket à <code>xterm.js</code> dans le navigateur et fonctionne en tant que <code>root</code>, utilisateur de l'unité systemd. Comme avec <code>ssh root@&lt;host&gt;</code>, vous pouvez utiliser <code>vim</code>, <code>tmux</code>, les outils ncurses et les CLI Proxmox (<code>qm</code>, <code>pct</code>, <code>pvesh</code>, <code>pvecm</code>). Chaque PTY exporte <code>PROXMENUX_TERMINAL=monitor</code>. Tous ses processus enfants <code>bash</code>, dont un lancement ultérieur de <code>menu</code>, héritent de cette variable pour reconnaître le terminal de Monitor."
},
"singleAlt": "Onglet Terminal de ProxMenux Monitor — une session affichant le résumé système de Fastfetch à la connexion",
"singleCaption": "Un terminal hôte ouvert : la barre indique le nombre (<em>1 / 4 terminaux</em>), <em>+ Nouveau</em>, <em>Rechercher</em>, <em>Effacer</em> et <em>Fermer</em>. Les boutons de clavier pour mobiles apparaissent en dessous sur les appareils tactiles.",
"target": {
"heading": "Cible de connexion",
"body1": "L'onglet Terminal ouvre un shell sur l'hôte <strong>Proxmox lui-même</strong> — la même connexion que vous pourriez obtenir sur SSH. Chaque onglet ouvre un tout nouveau terminal hôte.",
"body2": "Pour atteindre un conteneur <strong>LXC</strong> du navigateur, utilisez le bouton dédié <em>Console</em> sur chaque carte CT en cours d'exécution dans l'onglet <link>VMs & LXCs</link>. Il ouvre un modal qui exécute <code>pct enter &lt;vmid&gt;</code> et réutilise la même barre d'outils mobile décrite ci-dessous."
},
"menuGuard": {
"heading": "Protection de la mise à jour de menu dans ce terminal",
"body1": "Après confirmation, <code>menu</code> remplace sa propre arborescence de scripts et se recharge. Cela fonctionne via SSH ou la console Proxmox, mais fermerait le PTY du shell dans le navigateur et interromprait le WebSocket. Pour l'éviter, <code>check_updates_stable</code>, <code>check_updates_beta</code> et <code>apply_release_channel</code> lisent <code>PROXMENUX_TERMINAL</code> pour détecter le contexte Monitor.",
"body2": "Le dialogue oui/non est alors remplacé par un message avec la commande officielle de l'installateur : <code>bash -c \"$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)\"</code> pour stable et l'URL équivalente de <code>install_proxmenux_beta.sh</code> pour bêta. La mise à jour doit être exécutée via SSH ou la console de l'hôte Proxmox ; le terminal du navigateur sert à lire et confirmer le message."
},
"fourTerminals": {
"heading": "Jusqu'à quatre terminaux à la fois",
"intro": "L'onglet vous permet d'ouvrir jusqu'à quatre terminaux hôtes simultanément. Chacun obtient son propre PTY et son propre WebSocket — ce sont des sessions totalement indépendantes. Deux mises en page changent avec les icônes à côté du bouton \"Nouveau\" :",
"items": [
"<strong>Vue par onglets</strong> — un terminal visible, les autres sous forme d'onglets nommés en haut (<em>Terminal 1</em>, <em>Terminal 2</em>…). Pratique pour une tâche, les autres restant en arrière-plan.",
"<strong>Vue en grille</strong> — tous les terminaux ouverts dans une grille 2×2. Vous pouvez surveiller <code>htop</code> dans l'un, <code>iftop</code> dans un autre et modifier des fichiers dans un troisième sans changer d'onglet."
],
"outro": "La barre indique le nombre de terminaux (<em>1/4 terminaux</em>, <em>4/4 terminaux</em>). <strong>+ Nouveau</strong> ouvre un onglet ; le petit <code>×</code> de son en-tête le ferme. Le grand bouton rouge <strong>Fermer</strong> en haut ferme tous les terminaux."
},
"gridAlt": "Onglet Terminal de ProxMenux Monitor — quatre terminaux en grille avec ls, configuration réseau, iftop et menu principal ProxMenux côte à côte",
"gridCaption": "Vue en grille (4 / 4 terminaux) — quatre PTY indépendants en parallèle : liste de répertoire, <code>/etc/network/interfaces</code>, <code>iftop</code> et menu principal ProxMenux. Le sélecteur de disposition de la barre permet de passer entre grille et onglets.",
"keyboard": {
"heading": "Boutons de clavier pour mobiles",
"intro": "Les claviers de téléphone et de tablette n'offrent souvent pas ESC, TAB, les flèches ou les combinaisons de touches de modification. Elles sont nécessaires pour utiliser <code>vim</code>, <code>nano</code>, <code>htop</code> ou les menus TUI. Terminal affiche donc une rangée de boutons tactiles en dessous sur les petits écrans ou les appareils tactiles :",
"headerButton": "Bouton",
"headerSends": "Envoie",
"headerUse": "Utilisation typique",
"rows": [
{
"button": "ESC",
"sends": "\\x1b",
"use": "Quitter le mode insert en <code>vim</code>, annuler une boîte de dialogue TUI, laisser une recherche."
},
{
"button": "TAB",
"sends": "\\t",
"use": "Complétion des chemins et navigation entre les champs dans dialog/whiptail."
},
{
"button": "↑ ↓ ← →",
"sends": "\\x1bO[ABCD]",
"use": "Historique Shell, mouvement de curseur, navigation de menu."
},
{
"button": "↵ Entrée",
"sends": "\\r",
"use": "Confirmer. Certains claviers remplacent Entrée par Aller/Terminé ; ce bouton évite l'ambiguïté."
},
{
"button": "Ctrl ▾",
"sends": "Liste déroulante",
"useRich": true
}
],
"ctrlIntro": "Trois séquences de contrôle :",
"ctrlItems": [
"<code>Ctrl+C</code> — annuler / interrompre la commande en cours d'exécution (<code>\\x03</code>).",
"<code>Ctrl+X</code> — quitter <code>nano</code> (<code>\\x18</code>).",
"<code>Ctrl+R</code> — recherche à rebours dans l'historique bash (<code>\\x12</code>)."
],
"modalTitle": "Même barre d'outils dans la fenêtre de console LXC",
"modalBody": "La console ouverte depuis <link>VMs et LXCs → Console</link> affiche les mêmes boutons de clavier sous la fenêtre. À la connexion, elle saisit automatiquement <code>pct enter &lt;vmid&gt;</code> pour entrer directement dans le conteneur."
},
"lxcAlt": "Fenêtre de console LXC de ProxMenux Monitor — Terminal: ubuntu (ID: 103), avec la même barre mobile (ESC, TAB, flèches, Entrée, Ctrl) en dessous",
"lxcCaption": "Console LXC ouverte depuis <em>VMs et LXCs → Console</em>. L'en-tête indique le conteneur cible (<em>Terminal: ubuntu (ID: 103)</em>) et la même barre tactile apparaît sous le terminal.",
"search": {
"heading": "Rechercher des commandes — aide-mémoire intégré",
"intro": "Le bouton bleu <strong>Rechercher</strong> ouvre une recherche approximative de commandes. Saisissez quelques lettres d'une commande Linux ou Proxmox (<code>ls</code>, <code>tar</code>, <code>qm</code>, <code>pct</code>, <code>zpool</code>, <code>systemctl</code>…) pour afficher des exemples avec <em>Envoyer au terminal actif</em> en un geste. Vous pouvez ainsi retrouver une option sans changer d'onglet.",
"modalAlt": "Fenêtre Rechercher des commandes de ProxMenux Monitor — recherche approximative de commandes Linux et Proxmox avec cheat.sh et plusieurs exemples de ls",
"modalCaption": "Recherche de <code>ls</code> — chaque résultat affiche la commande, sa description et une petite flèche pour l'envoyer au terminal actif. La source des données est indiquée en bas à droite (<em>Fourni par cheat.sh</em>).",
"aboutLabel": "À propos de cheat.sh:",
"aboutBody": "est un aide-mémoire libre maintenu par la communauté, regroupant de courts exemples pratiques pour des centaines de commandes Linux, outils d'administration et langages de programmation. Prévu pour être consulté avec <code>curl cheat.sh/&lt;command&gt;</code>, il est aussi accessible dans le navigateur. ProxMenux Monitor transmet les requêtes par un proxy côté serveur pour garder la même origine que le tableau de bord.",
"headerSource": "Source",
"headerWhen": "Quand il est utilisé",
"headerWhat": "Ce que vous voyez",
"onlineLabel": "(en ligne)",
"onlineWhen": "Lorsque l'hôte a accès à Internet et que le proxy cheat.sh répond.",
"onlineWhat": "Plusieurs exemples pratiques par commande, avec leur description au-dessus. Le point d'état de l'en-tête est <green>vert</green>.",
"fallbackLabel": "Solution de repli locale",
"fallbackWhen": "Lorsque cheat.sh est inaccessible (hôte hors ligne, pare-feu restrictif, panne de cheat.sh).",
"fallbackWhat": "Une liste intégrée de commandes Linux et Proxmox courantes. Le catalogue est plus petit, mais toujours disponible. Le point d'état est <red>rouge</red>.",
"sendingNote": "<strong>Fonctionnement de l'envoi</strong> : la flèche près du résultat transmet le texte au terminal actif (onglet sélectionné ou dernier terminal cliqué en grille). La fenêtre se ferme automatiquement pour vous permettre d'appuyer sur Entrée."
},
"auth": {
"heading": "Authentification",
"items": [
"Le navigateur demande d'abord un ticket à usage unique via <code>POST /api/terminal/ticket</code>, avec le JWT dans l'en-tête <code>Authorization</code>. Ce ticket est ensuite transmis à l'ouverture du WebSocket et expire après 5 secondes. Si l'authentification est activée et le ticket absent ou invalide, la connexion est fermée avant la création d'un PTY.",
"Si Monitor est derrière un proxy inverse, celui-ci doit transmettre les demandes de mise à niveau WebSocket. Exemples Nginx / Caddy / Traefik sur la page <link>Accès et authentification</link>."
]
},
"clipboard": {
"heading": "Presse-papiers, historique d'affichage et redimensionnement",
"items": [
"<strong>Copier et coller</strong> — utilise le presse-papiers du navigateur. Sélectionnez le texte avec la souris ou le pavé tactile et utilisez le raccourci système (<code>Cmd+C</code> sur macOS, <code>Ctrl+Shift+C</code> sur Linux/Windows). Les bureaux Linux permettent aussi de coller avec le clic central.",
"<strong>Historique d'affichage</strong> — défilement à la molette ou à deux doigts. xterm.js garde les quelques milliers de dernières lignes en mémoire.",
"<strong>Redimensionnement</strong> — le terminal ajuste la taille de la fenêtre PTY quand vous redimensionnez le panneau, pour afficher correctement <code>htop</code> et <code>vim</code>.",
"<strong>Reconnexion au retour sur l'onglet</strong> — changer d'application sur téléphone ou tablette, notamment iPad, peut couper le WebSocket. Terminal détecte le changement de visibilité et se reconnecte au retour, avec un délai de 15 secondes pour les connexions VPN lentes."
]
},
"disconnect": {
"heading": "Causes de déconnexion",
"intro": "Les raisons les plus courantes pour lesquelles une session se termine et ce qu'il faut faire pour chacune :",
"headerCause": "Cause",
"headerFix": "Solution",
"rows": [
{
"cause": "JWT de session expiré lors de l'ouverture ou de la reconnexion (durée de 24 h).",
"fix": "Rafraîchir la page et vous connecter à nouveau. Le terminal n'est pas conçu pour les sessions sans surveillance, donc la durée de vie du JWT correspond à la connexion régulière du tableau de bord."
},
{
"cause": "Délai d'inactivité du proxy inverse.",
"fix": "Augmentez <code>proxy_read_timeout</code> dans Nginx ou son équivalent dans Caddy / Traefik (exemples dans Accès et authentification)."
},
{
"cause": "Téléphone ou tablette en veille.",
"fix": "Au réveil de l'appareil, l'onglet se reconnecte automatiquement (délai de 15 s pour les connexions VPN). Sinon, rechargez-le."
},
{
"cause": "Le service redémarre sur l'hôte.",
"fix": "Tout redémarrage de <code>proxmenux-monitor.service</code> ferme tous les PTY. Ouvrez de nouveaux terminaux une fois le tableau de bord rechargé."
}
]
},
"warning": {
"title": "Le terminal est un shell root sur l'hôte",
"body": "Le terminal hérite de l'utilisateur de l'unité systemd (<code>root</code>) et dispose de tous les privilèges sur l'hôte Proxmox. Configurez utilisateur, mot de passe et 2FA dans <authLink>Accès et authentification</authLink> avant d'autoriser les accès hors du réseau local. Si l'authentification est désactivée, toute personne atteignant le port 8008 peut ouvrir un shell root sans confirmation ni identifiants SSH. Pour les accès externes, utilisez <gatewayLink>Secure Gateway</gatewayLink> (Tailscale) ou un proxy inverse HTTPS au lieu de publier ce port sur Internet."
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Accès et authentification",
"href": "/docs/monitor/access-auth",
"tail": " — exemples de proxy inverse avec les lignes de mise à niveau WebSocket nécessaires au terminal."
},
{
"label": "Architecture",
"href": "/docs/monitor/architecture",
"tail": " — transport WebSocket (HTTP via flask-sock et HTTPS / WSS via gevent)."
},
{
"label": "Référence de l’API",
"href": "/docs/monitor/api",
"tail": " — points de terminaison WebSocket /ws/terminal et /ws/script/<sid>, avec le reste de l'API."
},
{
"label": "Intégrations → Portail sécurisé",
"href": "/docs/monitor/integrations",
"tail": "— lorsque vous voulez un accès terminal de l'extérieur du LAN sans exposer le port 8008."
},
{
"label": "Index du tableau de bord",
"href": "/docs/monitor/dashboard",
"tail": "— les autres onglets."
}
]
}
}
@@ -0,0 +1,245 @@
{
"meta": {
"title": "Onglet App LXC : détection, liens et suivi de version | ProxMenux",
"description": "Découvrez et enregistrez les applications LXC, créez des liens web et en option suivez les versions installées et disponibles."
},
"header": {
"title": "Onglet de l'application LXC : découverte, liens et suivi des versions",
"description": "Donnez à chaque application LXC une identité persistante, un accès web et une preuve de version optionnelle sans couplage de l'enregistrement aux mises à jour."
},
"intro": {
"p1": "L'onglet <strong>App</strong> enregistre les applications du LXC. Une fiche peut contenir simplement un nom et un lien web, ou aussi un détecteur de version installée et une source amont.",
"p2": "La procédure qui modifie le logiciel se configure séparément dans l'<link>onglet Mises à jour</link>. Enregistrer une application ne lance jamais d'installateur ni de programme de mise à jour.",
"callout": "L'enregistrement, le suivi et la mise à jour des versions sont trois capacités indépendantes. Chacun peut être utilisé sans exiger les deux autres.",
"dashboardTitle": "De l'inscription au lanceur Apps",
"dashboard": "Chaque lien web enregistré ici apparaît aussi dans l'<appsLink>onglet Apps</appsLink> principal. Cette page du LXC reste la référence pour le nom, le logo, les liens et le suivi de version."
},
"overview": {
"heading": "Ce que peut fournir une fiche d'application",
"lead": "Un seul enregistrement enregistré peut inclure:",
"items": [
"Un nom d'affichage et un logo adapté au thème.",
"Un ou plusieurs liens Web cliquables construits à partir de l'adresse LXC, le schéma et le port sauvegardé.",
"Un détecteur optionnel pour la version actuellement installée dans le LXC.",
"Une source optionnelle GitHub, HTTP JSON ou Docker Hub pour la dernière version disponible.",
"Notifications de nouvelles versions et inclusion dans le compteur de mises à jour, par application.",
"Une section correspondante de l'onglet Mises à jour, même lorsque le suivi des versions est désactivé."
]
},
"discovery": {
"heading": "Découverte en cache et recherche d'applications",
"lead": "Les suggestions sont incluses dans le cache de la fenêtre de chaque LXC. L'analyse de démarrage les prépare en arrière-plan pour afficher immédiatement les résultats à l'ouverture d'App.",
"items": [
"L'ouverture de l'onglet Application <strong>ne démarre pas</strong> une nouvelle analyse du catalogue et n'interroge pas de manière répétée le LXC.",
"<strong>Rechercher des applications</strong> lance une nouvelle détection pour ce LXC. Utilisez cette action après avoir installé un logiciel alors que ProxMenux fonctionne déjà.",
"La liste précédente reste visible pendant l'analyse. Les nouvelles correspondances sont ajoutées à la fin.",
"Si aucune nouvelle correspondance n'est trouvée, le résultat est indiqué à côté des actions et <strong>Enregistrer l'application</strong> reste disponible pour l'entrée manuelle.",
"Enregistrer, supprimer ou restaurer une application met à jour le même cache immédiatement. Commencer ou restaurer un LXC rafraîchit seulement cet invité à travers son cycle de vie existant."
],
"callout": "Une suggestion n'est pas une fiche enregistrée. Elle reste en lecture seule jusqu'au clic sur <strong>Enregistrer</strong> et à la sauvegarde du formulaire."
},
"registration": {
"heading": "Enregistrement d'une application",
"lead": "Une suggestion détectée et un enregistrement manuel utilisent le même éditeur:",
"steps": [
"Cliquez sur <strong>Enregistrer</strong> pour une suggestion, ou sur <strong>Enregistrer une application</strong> pour choisir dans le catalogue ou saisir un nom personnalisé.",
"Consultez le nom et le logo proposés par le catalogue.",
"Ajouter les liens web requis. Les ports d'écoute détectés sont proposés comme raccourcis, mais aucun n'est enregistré automatiquement.",
"Laissez <strong>Suivre la version amont</strong> désactivé pour une fiche avec seulement des liens, ou activez-le et vérifiez le détecteur de version installée et la source amont.",
"Si le suivi est activé, utilisez <strong>Tester le détecteur</strong>, puis enregistrez la fiche.",
"Cliquez sur <strong>Terminé</strong> après modification. App et Mises à jour utilisent la même fiche actualisée en cache."
]
},
"catalog": {
"heading": "Inscription assistée par catalogue",
"lead": "Le catalogue fournit des données par défaut, mais l'enregistrement enregistré reste modifiable.",
"items": [
"Les résultats de recherche peuvent préremplir le nom canonique, le logo et les ports web communs.",
"Les détecteurs connus utilisent les vrais noms de paquets, exécutables, fichiers, distributions Python, étiquettes OCI ou commandes, plutôt qu'une hypothèse universelle comme <code>/root/.app</code>.",
"Les corrections vérifiées dans les installations réelles sont prioritaires lorsque le chemin diffère des métadonnées de l'installateur.",
"Les marqueurs Proxmox VE Helper-Scripts tels que <code>/root/.slug</code> restent un signal de compatibilité pour les nouvelles installations d'aide, pas le seul détecteur.",
"Chaque valeur proposée peut être modifiée avant d'enregistrer pour couvrir les installateurs officiels et les installations manuelles."
]
},
"docker": {
"heading": "Comment les Docker LXC sont représentés",
"lead": "Si Docker est la plateforme principale d'un LXC, <strong>Docker</strong> est l'application enregistrée au niveau LXC.",
"items": [
"Une charge de travail conteneurisée telle que Portainer, Frigate ou Vaultwarden n'est pas suggérée en tant qu'application native indépendante LXC.",
"Les services Docker en cours d'exécution avec des ports TCP publiés sont proposés comme liens web facultatifs dans l'éditeur Docker.",
"Chaque lien suggéré indique le service, le port hôte et le port conteneur. Seuls les liens qui fournissent une interface Web doivent être enregistrés.",
"Le logo général Docker est utilisé si le lien n'a pas de logo spécifique. Un logo configuré pour le lien le remplace.",
"Après l'enregistrement de Docker, Docker Engine et les mises à jour d'images sont affichées ensemble dans sa section sur l'onglet Mises à jour."
],
"callout": "Cette structure empêche une charge de travail Docker de ressembler à un logiciel installé directement dans le LXC tout en préservant des liens rapides avec ses interfaces."
},
"webLinks": {
"heading": "Liens et logos Web",
"lead": "Les liens Web fonctionnent avec ou sans suivi des versions.",
"items": [
"Chaque lien stocke un schéma, un port, une description optionnelle et une URL de logo optionnelle.",
"L'URL affichée utilise l'adresse courante déjà détectée pour le LXC; l'adresse n'est pas dupliquée dans chaque enregistrement d'application.",
"Un lien sans son propre logo revient au logo du niveau de l'application.",
"Plusieurs liens peuvent représenter une interface d'administration, une API, une interface secondaire ou un autre point de terminaison de l'application.",
"Une application enregistrée avec seulement des liens apparaît aussi dans Mises à jour, où un programme personnalisé peut être configuré plus tard."
]
},
"tracking": {
"heading": "Suivi optionnel de la version",
"lead": "Le suivi combine un détecteur de version installé avec une source en amont optionnelle. Les deux côtés sont vérifiés indépendamment.",
"colMethod": "Méthode de détection de la version installée",
"colUse": "Utilisation",
"detectorRows": [
{
"method": "dpkg / apk",
"use": "Lis la version de paquets installée à partir de métadonnées de paquets Debian, Ubuntu ou Alpine."
},
{
"method": "binary",
"use": "Exécute un chemin binaire absolu ou un nom de commande avec des arguments de version."
},
{
"method": "file + regex",
"use": "Lit un fichier réel et extrait la version avec un groupe de capture."
},
{
"method": "docker label / docker exec",
"use": "Lit une étiquette de version OCI ou exécute une commande de version dans un conteneur Docker."
},
{
"method": "python distribution",
"use": "Utilise importlib.metadata via l'interpréteur Python sélectionné."
},
{
"method": "command",
"use": "Exécute une commande avancée de style argv sans shell et extrait la version de sa sortie."
},
{
"method": "manual",
"use": "Stocke une version entrée manuellement; elle doit être modifiée après la mise à jour de l'application."
},
{
"method": "OCI image",
"use": "Pour les conteneurs installés par OCI manager Apps. Lit les versions de l'application et de l'image dans la fiche d'installation et compare le digest installé à celui publié par le registre. Aucune configuration nécessaire."
}
],
"sourcesHeading": "Sources de la version disponible",
"sources": [
"<strong>GitHub dépôt</strong> : dernière version ou étiquette d'un dépôt public <code>owner/name</code>.",
"<strong>HTTP JSON</strong> : point de terminaison public et chemin à points comme <code>data.version</code> ou <code>releases[0].tag_name</code>.",
"<strong>Docker Hub</strong>: étiquettes en version filtrées par une expression régulière. Un aperçu en direct montre de vraies balises correspondantes avant que l'enregistrement soit enregistré.",
"Les tags mobiles comme <code>latest</code>, <code>stable</code> ou <code>lts</code> ne contiennent pas de version. Suivez ces images par digest dans les mises à jour d'images Docker."
],
"regexHeading": "Écrire l'expression de capture",
"regexLead": "L'expression régulière doit renvoyer la version dans son <strong>premier groupe de capture</strong>.",
"regexRules": [
"Correspondez au texte émis par la source binaire, le fichier, la commande ou la balise sélectionnée; ne devinez pas un chemin générique.",
"Échappez les points littéraux avec <code>\\.</code> pour éviter de reconnaître des caractères arbitraires.",
"Acceptez un <code>v</code> initial seulement si la source peut en contenir un.",
"Inclure des suffixes tels que des révisions préalables ou des révisions distro seulement lorsqu'elles sont significatives pour la comparaison.",
"Utilisez <strong>Tester le détecteur</strong> avant de sauvegarder et vérifiez la version installée affichée dans le LXC."
],
"regexExampleLead": "Capture sémantique commune:",
"regexExample": "v?(\\d+\\.\\d+\\.\\d+)",
"regexCallout": "Une correspondance régex réussie n'est pas la preuve que le chemin du détecteur est correct. Le chemin ou le paquet doit également exister dans l'installation réelle enregistrée."
},
"updater": {
"heading": "Le suivi et la mise à jour des versions sont indépendants",
"lead": "L'<link>onglet Mises à jour</link> crée une section dès qu'une fiche d'application est enregistrée.",
"items": [
"Un enregistrement link-only montre que le suivi des versions n'est pas configuré, mais peut toujours recevoir une commande de mise à jour personnalisée.",
"Une application avec suivi mais sans méthode exécutable affiche un message neutre demandant une commande personnalisée.",
"Une application avec un wrapper Proxmox VE Helper-Scripts vérifié peut utiliser ce programme intégré même si sa fiche a commencé par un simple lien web.",
"Ajouter ou modifier un programme de mise à jour ne change ni le détecteur ni la source amont enregistrés dans App."
]
},
"states": {
"heading": "États de version sur la carte App",
"colState": "État",
"colDisplay": "Affichage",
"colMeaning": "Signification",
"rows": [
{
"state": "Mise à jour disponible",
"display": "Version disponible en violet avec une icône vers le haut",
"meaning": "Les versions installées et amont diffèrent."
},
{
"state": "À jour",
"display": "Versions installée et disponible sans alerte violette",
"meaning": "La dernière vérification n'a trouvé aucune version en amont plus récente."
},
{
"state": "Suivi en attente",
"display": "Vérification en cours ou en attente",
"meaning": "L'enregistrement est configuré mais n'a pas encore effectué les deux vérifications."
},
{
"state": "Suivi désactivé",
"display": "Liens Web seulement; aucun bloc de comparaison de version",
"meaning": "La fiche reste valide et peut toujours avoir un programme de mise à jour."
},
{
"state": "Erreur de vérification",
"display": "Explication en ambre dans la carte",
"meaning": "L'état précédent reste visible tandis que l'erreur du détecteur ou de la source amont est signalée."
}
]
},
"management": {
"heading": "Gestion des applications sauvegardées et suggérées",
"lead": "Les actions en bas de l'onglet ont des rôles distincts :",
"items": [
"<strong>Trouver des applications</strong> rafraîchit la découverte pour ce LXC seulement.",
"<strong>Inscrivez une autre application</strong> ouvre le catalogue et l'éditeur manuel sans rescanner le LXC.",
"<strong>Modifier</strong> révèle les actions Supprimer, Vérifier, notifications et Modifier les champs sur chaque carte.",
"<strong>Masquer</strong> retire une suggestion indésirable. Les détections masquées se restaurent dans la vue d'enregistrement.",
"<strong>Vérifier</strong> actualise les données de version de la fiche sélectionnée sans rechercher de nouvelles applications."
]
},
"troubleshooting": {
"heading": "Situations communes",
"colProblem": "Situation actuelle",
"colResolution": "Résolution",
"rows": [
{
"problem": "Le logiciel a été installé après le démarrage de ProxMenux",
"resolution": "Appuyez sur Trouver des applications. L'analyse explicite met à jour les suggestions mises en cache pour ce LXC."
},
{
"problem": "Aucune application n'a été détectée",
"resolution": "Enregistrez-le manuellement. Un nom et un lien Web suffisent; un suivi peut être ajouté plus tard."
},
{
"problem": "Le détecteur suggéré retourne la mauvaise version",
"resolution": "Ouvrez Modifier les champs, choisissez le vrai paquet, exécutable ou chemin de fichier et testez avant de sauvegarder."
},
{
"problem": "Une charge de travail Docker n'est pas offerte en tant qu'application LXC",
"resolution": "Enregistrez Docker et ajoutez l'interface publiée de la charge de travail comme lien web Docker. Les mises à jour d'image restent dans la section Docker."
},
{
"problem": "Une application enregistrée n'a pas de bouton de mise à jour",
"resolution": "Ouvrez Mises à jour et configurez la méthode. Le seul suivi de version ne définit pas comment installer une mise à jour."
}
]
},
"figures": {
"catalog": {
"alt": "Catalogue d'enregistrement d'applications avec résultats de recherche, logos, ports et champs détecteurs",
"caption": "Les métadonnées de catalogue accélèrent l'enregistrement tandis que chaque valeur proposée reste modifiable."
},
"webLinks": {
"alt": "Carte d'application LXC sauvegardée contenant un lien Web cliquable",
"caption": "Une fiche avec seulement des liens est valide : le suivi peut rester désactivé et un programme de mise à jour peut être ajouté séparément."
},
"tracking": {
"alt": "Détecteur de version installé en option et champs sources en amont",
"caption": "La détection de la version installée et la source en amont sont configurées et testées séparément."
},
"card": {
"alt": "Carte d'application sauvegardée avec versions installées et disponibles plus un lien web",
"caption": "La carte combine l'identité, les preuves de version et l'accès web sans exécuter des actions de mise à jour de cet onglet."
}
}
}
@@ -0,0 +1,203 @@
{
"meta": {
"title": "Mises à jour LXC : système, applications et Docker | ProxMenux",
"description": "Configurer et lancer les mises à jour du système d'exploitation, des applications, de Docker Engine et des images Docker dans un LXC."
},
"header": {
"title": "Mises à jour de LXC: OS, applications et Docker",
"description": "Examiner chaque cible de mise à jour en un seul endroit, l'exécuter de façon indépendante ou combiner des cibles sélectionnées dans une action en vrac contrôlée."
},
"intro": {
"p1": "L'onglet <strong>Mises à jour</strong> sépare la détection des versions de leur installation. Enregistrement et suivi facultatif se trouvent dans l'<link>onglet App</link> ; les méthodes exécutables se gèrent ici.",
"p2": "Une application enregistrée apparaît dans Mises à jour même avec un seul lien web. Le suivi de version est facultatif ; son programme de mise à jour peut être configuré séparément.",
"callout": "L'enregistrement ne choisit aucun programme de mise à jour. Si un programme Helper-Scripts correspondant est détecté, choisissez et enregistrez <strong>Helper-Scripts</strong> ou <strong>Commande personnalisée</strong>. La détection ne garantit pas la compatibilité. Le choix appartient à chaque application, même dans un LXC partagé."
},
"overview": {
"heading": "Que contient l'onglet",
"lead": "Chaque cible disponible a sa propre section et action:",
"items": [
"<strong>Paquets du système</strong> pour les conteneurs Debian, Ubuntu et Alpine.",
"Une section par <strong>application enregistrée</strong>, y compris les fiches avec seulement un lien.",
"Une section <strong>Docker</strong> lorsque le Docker est enregistré, avec Docker Engine et des images marquées regroupées.",
"Une section <strong>Mise à jour groupée</strong> configurable, suivie des options de sauvegarde, redémarrage et programmation."
]
},
"mechanisms": {
"heading": "Comment une méthode de mise à jour est sélectionnée",
"lead": "Le chemin intégré Proxmox VE Helper-Scripts suit le mécanisme officiel <helper>update-apps</helper>. D'autres types d'installation utilisent le paquet correspondant, Docker ou chemin personnalisé.",
"officialReference": "Référence officielle : la <helper>documentation update-apps de Proxmox VE Helper-Scripts</helper> décrit les modes interactif et sans surveillance, sauvegardes, simulations, ressources temporaires de compilation, journaux et codes de sortie.",
"colSource": "Source",
"colAction": "Action affichée",
"colNotes": "Ce qui est exécuté",
"rows": [
{
"source": "Paquets APT ou APK",
"action": "Appliquer les mises à jour du système d'exploitation",
"notes": "Mettre à jour les paquets de conteneurs. Les applications enregistrées installées sous forme de paquets dpkg ou apk sont couvertes par ce même passe."
},
{
"source": "Proxmox VE Helper-Scripts",
"action": "Appliquer la mise à jour",
"notes": "Après sélection explicite de Helper-Scripts, lance le script officiel identifié par le wrapper /usr/bin/update validé. Un marqueur ou une correspondance du catalogue ne suffit jamais à autoriser l'exécution."
},
{
"source": "Commande personnalisée",
"action": "Exécuter le programme de mise à jour",
"notes": "Exécute la commande enregistrée dans le LXC et remplace tout programme intégré de mise à jour de cette fiche."
},
{
"source": "Docker Engine",
"action": "Mettre à jour Docker Engine",
"notes": "Met à jour uniquement les paquets Docker installés et leurs dépendances nécessaires. Les autres paquets système et les conteneurs restent inchangés."
},
{
"source": "Image Docker",
"action": "Mettre à jour l’image",
"notes": "Télécharge l'image sélectionnée et recrée son groupe de services Compose ou son conteneur autonome protégé."
}
],
"callout": "Une commande personnalisée <strong>remplace</strong> Helper-Scripts pour cette application. Les exécutions manuelles, groupées et programmées respectent le choix enregistré. Les commandes existantes et les anciennes sélections explicitement enregistrées dans les plans groupés ou les programmations actives sont conservées ; une nouvelle application n'est jamais ajoutée par une ancienne programmation."
},
"docker": {
"heading": "Docker Engine et images Docker",
"lead": "Après enregistrement de Docker dans App, Docker Engine et l'inventaire des images apparaissent dans la même section <strong>Docker</strong>.",
"items": [
"Le suivi de la version Docker Engine est séparé du compteur de paquets OS et a son propre bouton de mise à jour.",
"Les images locales taggées sont comparées à leur registre par digest immuable. <strong>Vérifier maintenant</strong> rafraîchit cet inventaire sans tirer des images ou redémarrer des conteneurs.",
"Les services Compose sont mis à jour depuis leur projet déclaré. Les images du même groupe sont traitées ensemble pour éviter de recréer le projet plusieurs fois.",
"Un conteneur autonome est recréé à partir de sa configuration actuelle. Le processus protégé garde les données de retour arrière et restaure le conteneur précédent si la recréation échoue.",
"Chaque image est sélectionnable séparément pour les mises à jour manuelles, groupées et programmées, sauf les dépendances Compose déclarées qui doivent suivre leur service principal."
],
"callout": "Les conteneurs fonctionnant à l'intérieur de Docker ne sont pas présentés comme des applications indépendantes LXC. Leurs ports web publiés peuvent être enregistrés sous forme de liens sous l'enregistrement Docker, tandis que les mises à jour d'images restent dans la section Docker."
},
"actions": {
"heading": "Actions individuelles et couleurs de statut",
"lead": "Chaque section reste actionnable indépendamment, qu'une mise à jour en vrac soit configurée ou non.",
"items": [
"<strong>Configurer</strong> ouvre le choix du programme si aucune méthode n'est définie ; <strong>Modifier</strong> change un choix enregistré. Les boutons d'information expliquent les options, donnent la documentation officielle et un exemple de script personnalisé. Choisir une option ne l'exécute pas.",
"Sans suivi de version mais avec un programme de mise à jour, l'action neutre <strong>Exécuter le programme de mise à jour</strong> apparaît. ProxMenux n'affirme pas qu'une mise à jour est en attente.",
"Sans programme Helper-Scripts disponible, configurez une commande personnalisée. Désactiver une méthode n'en choisit pas une autre ; les sélections des plans groupés et programmations restent enregistrées et les cibles indisponibles sont signalées.",
"L'action <strong>Mise à jour de l'image</strong> s'applique uniquement à l'unité Docker sélectionnée; elle ne met pas à jour Docker Engine ou des images non liées."
],
"statusColState": "État connu",
"statusColAppearance": "Apparence",
"statusColMeaning": "Signification",
"statusRows": [
{
"state": "Mise à jour vérifiée disponible",
"appearance": "Texte pourpre, icône vers le haut et action pourpre",
"meaning": "Les versions installées et disponibles ou les empreintes digest des images diffèrent."
},
{
"state": "À jour, vérifié",
"appearance": "Coche verte et action À jour en vert",
"meaning": "La dernière vérification effectuée confirme que la cible est à jour."
},
{
"state": "Version inconnue",
"appearance": "Texte neutre et action neutre",
"meaning": "Un programme de mise à jour peut être lancé, mais les données de version manquent pour déterminer si la cible est à jour ou si une mise à jour est disponible."
}
]
},
"custom": {
"heading": "Commandes de mise à jour personnalisées",
"lead": "Utilisez une commande personnalisée si l'installation ne dispose pas de programme intégré vérifié ou si la procédure normale doit être remplacée.",
"items": [
"Ouvrez <strong>Configurer</strong> si le champ est vide, ou <strong>Modifier</strong> si une méthode existe.",
"Pour une application intégrée ou Docker Engine, l'éditeur affiche la commande actuelle. Enregistrer un autre contenu en fait le remplacement explicite pour cette fiche.",
"Testez d'abord la procédure complète dans le terminal LXC. Il doit être non interactif, utiliser le répertoire de travail correct et retourner un statut de sortie non zéro en cas d'échec.",
"N'incluez pas <code>pct exec</code> ; ProxMenux entre déjà dans le conteneur et exécute la commande en tant que root."
],
"exampleLead": "Exemple de procédure complète dans le conteneur:",
"example": "cd /opt/my-app && ./update.sh",
"callout": "Une commande comme <code>myapp --version</code> lit seulement la version ; ce n'est pas un programme de mise à jour. Les commandes sont exécutées avec les droits administrateur : examinez leur contenu comme une commande shell root."
},
"bulk": {
"heading": "Mise à jour groupée",
"lead": "La mise à jour en vrac crée une action réutilisable pour un ensemble exact de cibles dans le LXC. Il est placé après les différentes sections de l'application et Docker et avant <strong>Options</strong>.",
"items": [
"Les paquets système sont obligatoires. Sélectionnez au moins une application, Docker Engine ou une unité image Docker supplémentaire.",
"Applications et unités Docker se choisissent séparément. Le service principal Compose affiche les dépendances mises à jour avec lui.",
"Les cibles indisponibles ou supprimées sont marquées comme étant indisponibles et doivent être supprimées avant que la configuration puisse être enregistrée.",
"<strong>Appliquer les mises à jour</strong> est violet si une cible a une mise à jour vérifiée, vert si toutes sont vérifiées à jour et neutre si le résultat est inconnu.",
"L'élimination de la configuration en vrac ne supprime pas les méthodes de mise à jour individuelles ou les paramètres de mise à jour programmés."
],
"callout": "La mise à jour en vrac ne remplace pas les boutons individuels. Il s'agit d'un raccourci optionnel pour une sélection qui doit fonctionner ensemble."
},
"options": {
"heading": "Options de sauvegarde et de redémarrage",
"lead": "Les mêmes options s'appliquent aux opérations manuelles, en vrac et programmées:",
"items": [
"<strong>Snapshot avant d'appliquer</strong> crée une sauvegarde vzdump sur le stockage sélectionné. Si la sauvegarde requise échoue, la mise à jour ne démarre pas.",
"<strong>Redémarrer après avoir appliqué</strong> redémarre le LXC seulement après un succès.",
"Les sélections sont stockées par LXC et restent indépendantes de la liste cible."
]
},
"scheduled": {
"heading": "Mises à jour programmées",
"lead": "Les mises à jour prévues utilisent les mêmes cibles exécutables et les mêmes options de sécurité que les actions manuelles.",
"items": [
"Choisissez une fréquence prédéfinie ou une expression cron, puis les cibles exactes : paquets système, applications, Docker Engine, unités Docker autonomes ou groupes de services Compose.",
"Le délai après publication ne concerne que les applications sélectionnées avec suivi de version. Sans suivi, leur programme de mise à jour est lancé à chaque échéance.",
"L'état de la dernière exécution distingue succès, achèvement partiel, échec, blocage de sécurité et absence de mise à jour en attente. Après la première exécution programmée, <strong>Mises à jour → Mises à jour programmées → Afficher le journal</strong> ouvre toute la sortie du programme de mise à jour et des scripts secondaires appelés.",
"Après chaque exécution, ProxMenux vérifie le marqueur standard de redémarrage de Debian. Lorsqu'un redémarrage est nécessaire, l'onglet Mises à jour et la notification d'achèvement le disent; l'avertissement est effacé lorsque LXC démarre ou redémarre.",
"Sur l'hôte Proxmox, les journaux programmés sont stockés dans <code>/usr/local/share/proxmenux/logs/lxc-updates/</code> en utilisant le nom <code>&lt;VMID&gt;-scheduled-&lt;run-id&gt;.log</code>. Les dix derniers journaux sont conservés par LXC et les anciens fichiers sont supprimés automatiquement.",
"Cet historique concerne les mises à jour programmées. Une mise à jour manuelle affiche sa sortie en direct dans la fenêtre d'exécution de Monitor et ne crée aucun journal programmé dans ce répertoire.",
"Les calendriers d'hôtes externes détectés à partir de Proxmox VE Helper-Scripts sont indiqués séparément, de sorte que l'automatisation du chevauchement est visible."
],
"callout": "Testez chaque méthode manuellement avant d'activer une programmation. Les commandes programmées ne peuvent pas répondre aux questions interactives."
},
"completion": {
"heading": "Ce qui se passe après une mise à jour",
"lead": "La simple fin de la commande du terminal ne suffit pas à considérer la mise à jour terminée.",
"items": [
"La même exécution enregistre son résultat final et rafraîchit l'état du paquet OS, les versions app enregistrées et l'inventaire Docker selon le cas.",
"Les exécutions programmées conservent la sortie du terminal et signalent si un redémarrage reste nécessaire pour terminer l'application des changements de paquets.",
"Le cache LXC est remplacé par l'état vérifié après mise à jour, de sorte que les badges et les boutons ne conservent pas le résultat précédent.",
"Si un LXC arrêté ou restauré démarre, le cycle de vie existant rafraîchit à nouveau ce LXC. L'inventaire de Docker attend que le démon soit prêt au lieu de mettre en cache un résultat de démarrage vide comme final.",
"Les notifications activées sont émises après finalisation du résultat, y compris les échecs partiels et les résultats groupés des images Docker."
]
},
"troubleshooting": {
"heading": "Situations communes",
"colProblem": "Situation actuelle",
"colResolution": "Résolution",
"rows": [
{
"problem": "Aucune méthode de mise à jour n'a été identifiée",
"resolution": "Ouvrez Configurer, ajoutez la procédure non interactive officielle et testez-la manuellement avant de la programmer."
},
{
"problem": "Une identité Proxmox VE Helper-Scripts est affichée mais aucune action n'existe",
"resolution": "Le LXC possède d'anciennes données d'identification, mais aucun wrapper /usr/bin/update vérifié. Ajoutez une méthode personnalisée après avoir confirmé la bonne procédure."
},
{
"problem": "Les images Docker sont temporairement vides après le démarrage ou la restauration",
"resolution": "Attendez que Docker soit prêt ou cliquez sur Vérifier maintenant. L'inventaire réessaie au démarrage et ne considère pas un résultat vide transitoire comme définitif."
},
{
"problem": "Une cible de mise à jour groupée enregistrée n'est plus disponible",
"resolution": "Modifiez la configuration groupée, retirez la cible obsolète et choisissez son remplacement actuel s'il existe."
},
{
"problem": "Une commande personnalisée échoue",
"resolution": "Exécutez-la dans le terminal LXC et vérifiez chemin, dépendances, options non interactives et code de sortie."
},
{
"problem": "Une mise à jour programmée indique qu'un redémarrage est nécessaire",
"resolution": "Ouvrez Afficher le journal pour consulter l'exécution terminée, puis redémarrez ce LXC. ProxMenux efface l'avertissement lorsque l'événement de cycle de vie détecte son redémarrage."
}
]
},
"figures": {
"osPending": {
"alt": "Section des paquets système d'exploitation avec comptes de mise à jour en attente et de sécurité",
"caption": "La section système d'exploitation maintient les mises à jour du paquet indépendamment des actions d'application et Docker."
},
"options": {
"alt": "Options de mise à jour LXC avec sauvegarde avant mise à jour et redémarrage après",
"caption": "Les préférences de sauvegarde et de redémarrage s'appliquent aux exécutions manuelles, en vrac et programmées."
}
}
}
@@ -0,0 +1,244 @@
{
"meta": {
"title": "ProxMenux Monitor — Tableau de bord : VM et LXC | Documentation ProxMenux",
"description": "Inventaire des invités avec CPU, mémoire et disque en direct. Les détails montrent configuration, ressources, sauvegardes, résultats récents du journal Proxmox, notes et Démarrer / Éteindre / Redémarrer / Forcer l'arrêt."
},
"header": {
"title": "Tableau de bord : VM et LXC",
"description": "Inventaire complet du nœud : quatre mesures en haut, une liste triable des VM et LXC et les détails par invité avec configuration, ressources, sauvegardes, journaux et commandes Démarrer / Éteindre / Redémarrer / Forcer l'arrêt.",
"section": "ProxMenux Monitor · Tableau de bord"
},
"intro": {
"title": "Commandes des systèmes invités",
"body": "Cet onglet contrôle le cycle de vie des invités. Les actions passent par <code>POST /api/vms/&lt;vmid&gt;/control</code> avec confirmation explicite et actualisent la ligne de l'invité. L'arrêt forcé nécessite le bouton dédié Forcer l'arrêt."
},
"topRow": {
"heading": "Ligne supérieure : quatre cartes statistiques",
"intro": "Quatre cartes résument l'état des invités : nombres, utilisation CPU, mémoire allouée par rapport à la capacité de l'hôte et espace disque alloué.",
"imageAlt": "Onglet VMs & LXCs — rangée supérieure de quatre cartes statistiques: Total VMs & LXCs, Total CPU, Mémoire totale, Disque total",
"imageCaption": "Ligne supérieure : totaux et états En cours / Arrêtés, utilisation CPU, mémoire utilisée / allouée aux invités actifs / allouée au total avec indicateur Dans les limites, et espace disque alloué.",
"headerCard": "Carte",
"headerWhat": "Ce qu'il montre",
"totalLabel": "Nombre total de VM et LXC",
"totalWhat": "Nombre total avec deux badges — <em>X Running</em> (vert) et <em>Y stoppé</em> (rouge, seulement lorsque > 0). Le numéro que vous regardez quand quelque chose n'est pas revenu après un redémarrage.",
"cpuLabel": "CPU total",
"cpuWhat": "Utilisation CPU totale en direct des invités, en pourcentage du CPU physique de l'hôte, avec la mention <em>« Utilisation CPU allouée »</em>.",
"memoryLabel": "Mémoire totale",
"memoryIntro": "Trois lectures empilées verticalement:",
"memoryItems": [
"<strong>Utilisée actuellement</strong> — valeur principale, par exemple <em>15.4 GB</em>, et <em>X.X % de Y GB</em> par rapport à la RAM de l'hôte. La barre bleue montre le pourcentage.",
"<strong>Allouée aux actifs</strong> + <strong>Allouée totale</strong> — somme de <code>maxmem</code> des invités <em>en cours</em> et de <em>tous</em> les invités, arrêtés compris. La première compte maintenant, la seconde si vous les démarrez tous.",
"<strong>Dans les limites</strong>, en vert, devient <em>Surallocation</em> si le total alloué dépasse la RAM de l'hôte. Une surallocation maîtrisée peut fonctionner avec KSM ; l'indicateur avertit lorsque la marge diminue."
],
"diskLabel": "Disque total",
"diskWhat": "Somme de l'espace disque alloué à tous les invités, dans l'unité appropriée (GB / TB), avec la ligne de pied de page <em>\"Espace disque alloué\"</em>."
},
"inventory": {
"heading": "Liste des machines virtuelles et conteneurs",
"intro": "Une rangée par invité. La liste est une source unique de <code>/api/vms</code>, qui consolide <code>qm list</code> + <code>pct list</code> + <code>pvesh /cluster/resources</code> sur l'hôte.",
"imageAlt": "Liste des machines et conteneurs virtuels — une ligne par invité avec statut, type badge, nom, ID et inline CPU / mémoire / pourcentages de disque",
"imageCaption": "La disposition mobile optimisée de l'inventaire — les mêmes données que celles que montre la vue de bureau, replacées dans une seule colonne avec les pourcentages et les indicateurs d'état restent compacts.",
"rowsIntro": "Chaque ligne montre :",
"rows": [
"<strong>Icône d'état</strong> — triangle vert pour En cours ou carré rouge pour Arrêté. Le reste de la ligne est atténué pour les invités arrêtés.",
"<strong>Type</strong> — <em>LXC</em> en cyan pour les conteneurs, <em>VM</em> en violet pour les machines virtuelles.",
"<strong>Nom</strong> — nom d'hôte ou nom affiché de l'invité.",
"<strong>VMID</strong> — l'ID numérique Proxmox sous le nom.",
"<strong>Mesures en ligne</strong> — trois pourcentages avec leur icône (CPU %, Mémoire %, Disque %). Chaque icône devient orange lorsque la métrique traverse un seuil d'attention (par exemple, mémoire au-dessus de 90 %), de sorte qu'un scan rapide vous indique quel invité est sous pression sans l'ouvrir."
],
"clickHint": "Cliquez sur une ligne, que l'invité fonctionne ou soit arrêté, pour ouvrir ses détails.",
"mobileTitle": "Liste conçue pour les mobiles",
"mobileBody": "Sur mobile et dans les fenêtres étroites, type, nom, ID et trois pourcentages sont empilés en une colonne, comme sur la capture. Les vues larges répartissent les données horizontalement. Toute la ligne est cliquable pour ouvrir les détails."
},
"drillIn": {
"heading": "Fenêtre de détails de l'invité",
"intro": "La fenêtre de détail affiche le nom de l’invité, son VMID, son type, son état et sa durée de fonctionnement. Sa navigation s’adapte à l’invité : <strong>État</strong>, <strong>Application</strong> et <strong>Mises à jour</strong> pour la gestion des applications LXC, <strong>Montages</strong> lorsqu’un LXC possède des points de montage, <strong>Journaux</strong> pour les conteneurs installés par OCI manager Apps, ainsi que <strong>Sauvegardes</strong> et <strong>Pare-feu</strong>. La barre d’actions fixe conserve les commandes de démarrage et d’arrêt et le terminal LXC dans chaque onglet.",
"statusTitle": "Onglet 1 — État",
"statusImageAlt": "Détails de l'invité — État avec CPU, mémoire et disque en direct, E/S disque et réseau, logo système et Ressources / Adresses IP",
"statusImageCaption": "État : CPU, mémoire et disque avec barres en haut ; totaux d'E/S (disque lu/écrit, réseau reçu/envoyé) ; puis Ressources avec Notes, + Info et liste des adresses IP.",
"statusIntro": "Onglet initial pour vérifier le comportement de l'invité. Trois blocs :",
"liveTitle": "1. Ligne de mesures en direct",
"liveItems": [
"<strong>Utilisation CPU (X cœurs)</strong> — pourcentage avec barre. Le nombre de cœurs configurés dans l'en-tête précise ce que représente 100 %.",
"<strong>Mémoire</strong> — <em>utilisée / maximale</em> en Go avec barre.",
"<strong>Disque</strong> — <em>utilisé / maximal</em> pour l'image disque principale, au même format."
],
"ioTitle": "2. Total des E/S + logo OS",
"ioItems": [
"<strong>E/S disque</strong> — totaux des lectures (↓) et écritures (↑) depuis le démarrage. Permet de repérer une hausse soudaine des E/S par rapport au comportement habituel.",
"<strong>E/S réseau</strong> — réception (↓) et envoi (↑) cumulés, selon le même principe.",
"<strong>Logo du système</strong> — icône Debian / Ubuntu / Alpine / Windows / etc. selon le système détecté. Repère visuel pour identifier les fenêtres ouvertes."
],
"resourcesTitle": "3. Bloc ressources",
"resourcesIntro": "Configuration selon Proxmox : cœurs CPU, mémoire (<code>maxmem</code> configuré) et swap. Deux sections dépliables dans l'en-tête :",
"resourcesItems": [
"<strong>Notes</strong> — description modifiable de l'invité. Enregistrer appelle <code>PUT /api/vms/&lt;vmid&gt;/config</code> et écrit dans <code>/etc/pve/qemu-server/&lt;vmid&gt;.conf</code> ou <code>/etc/pve/lxc/&lt;vmid&gt;.conf</code>.",
"<strong>+ Info</strong> — champs supplémentaires trop verbeux pour la vue par défaut: mode bios, type de machine, état de l'agent, entrées passthrough hostpci, points de montage (CT), ordre de démarrage."
],
"ipsTitle": "4. Adresses IP",
"ipsBody": "Chaque adresse IPv4 ou IPv6 de l'invité apparaît dans une étiquette verte. La liste est vide si l'invité est arrêté ou si une VM n'a pas l'agent QEMU ; les LXC communiquent directement leurs adresses.",
"appTitle": "Onglet 2 — App (LXC seulement)",
"appIntro": "Enregistre les applications LXC, les liens web et compare facultativement les versions. Les suggestions viennent du cache de démarrage ; <strong>Rechercher des applications</strong> relance la détection de ce LXC après une nouvelle installation.",
"appLinkLead": "Voir le",
"appLinkLabel": "page d'application dédiée",
"appLinkTail": "pour la découverte en cache, l'enregistrement assisté par catalogue, les liens web Docker et les détecteurs de versions.",
"updatesTitle": "Onglet 3 — Mises à jour (LXC seulement)",
"updatesIntro": "Sépare <strong>paquets système</strong>, applications, <strong>Docker Engine</strong> et images Docker. Chaque cible peut être exécutée seule ou choisie précisément pour une action groupée ou programmée.",
"updatesLinkLead": "Voir le",
"updatesLinkLabel": "page dédiée aux mises à jour",
"updatesLinkTail": "pour les programmes de mise à jour intégrés et personnalisés, la recréation Docker, la sélection groupée, les options de sécurité et la programmation.",
"mountsTitle": "Onglet 4 — Montages (LXC, si présents)",
"mountsImageAlt": "Détails LXC, Montages : volumes PVE, bind mounts de l'hôte ou du stockage PVE et NFS/CIFS montés dans le CT. Chaque carte indique type, capacité, octets utilisés/totaux, options et état : vert sain, ambre lecture seule/divergent, rouge inaccessible.",
"mountsImageCaption": "Montages apparaît seulement pour les LXC avec au moins un point de montage ou montage distant ajouté dans le CT. Sans montage, l'onglet est absent.",
"mountsIntro": "Proxmox montre les montages configurés en <code>mpX</code>, mais pas ceux ajoutés ensuite dans le CT via <code>mount.cifs</code>, NFS avec <code>autofs</code>, etc. Cet onglet réunit <strong>les deux vues</strong> : montages configurés <strong>et</strong> détectés dans le conteneur, avec état par montage et capacité quand le serveur peut la déterminer.",
"mountTypesTitle": "Types de montage détectés",
"mountTypesItems": [
"<strong>Volume PVE</strong> — stockage géré par Proxmox, comme un sous-volume ZFS, un répertoire ou un Ceph RBD. La capacité vient des statistiques PVE et correspond à Proxmox.",
"<strong>Bind du stockage PVE</strong> — entrée <code>mpX</code> pointant vers un chemin d'un stockage connu de PVE.",
"<strong>Bind de l'hôte</strong> — entrée <code>mpX</code> vers un chemin de l'hôte (<code>/mnt/something</code>). La capacité vient de <code>df</code> sur ce chemin.",
"<strong>Montage ajouté dans le CT</strong> — existe <em>uniquement</em> dans son espace de noms, par exemple un partage NFS monté par le CT. La capacité est lue via <code>pct exec &lt;vmid&gt; df</code> ; depuis l'hôte, <code>/proc/&lt;pid&gt;/root</code> ne fournit pas les vraies statistiques du montage distant."
],
"mountStateTitle": "Point par carte et avertissements",
"mountStateItems": [
"<green/> <strong>Vert</strong> — montage sain et accessible.",
"<amber/> <strong>Ambre</strong> — configuré mais non monté, lecture seule ou <em>bind zombie</em>. Dans ce dernier cas, la source a disparu de l'hôte mais le CT la voit toujours montée, par exemple après débranchement USB ou <code>umount</code> sur l'hôte.",
"<red/> <strong>Rouge</strong> — inaccessible : la sonde ne peut pas atteindre le montage, par exemple un partage NFS dont le serveur est arrêté."
],
"mountsCalloutTitle": "Informations supplémentaires par rapport à Proxmox",
"mountsCalloutBody": "Vue des chemins lus ou écrits par le conteneur et de leur capacité. Les partages NFS/CIFS montés dans le CT, invisibles dans Proxmox, utilisent ici la même présentation et les mêmes sondes. Les montages inaccessibles et binds zombies sont signalés avant de causer des problèmes de sauvegarde.",
"logsTitle": "Onglet 5 — Journaux (conteneurs OCI uniquement)",
"logsBody": "Uniquement pour les conteneurs OCI manager Apps. Console du processus principal de l'image dans <code>/var/log/proxmenux/oci/VMID.console.log</code> : 100, 500 ou 1000 dernières lignes, suivi en direct pendant le fonctionnement, filtre et téléchargement. Le fichier est relu à l'ouverture, même si le conteneur est arrêté. Détails : <ociLink>Conteneurs OCI dans ProxMenux Monitor</ociLink>.",
"backupsTitle": "Onglet 6 — Sauvegardes",
"backupsImageAlt": "Per-invité fore-in modal — onglet Sauvegardes avec la liste de sauvegardes disponibles, balise de destination, tailles et le bouton Créer sauvegarde",
"backupsImageCaption": "Toutes les sauvegardes de l'invité sur les stockages Proxmox configurés, de la plus récente à la plus ancienne. L'en-tête indique leur nombre.",
"backupsIntro": "Liste les sauvegardes de l'invité sur les stockages Proxmox, de la plus récente à la plus ancienne. Le compteur du titre permet de voir si des copies existent. Chaque ligne affiche :",
"backupsItems": [
"<strong>Horodatage</strong> — date et heure de l'exécution.",
"<strong>Destination</strong> — stockage (PBS-Cloud, PBS-Local, NFS-Backup, …), coloré selon son état.",
"<strong>Taille</strong> — taille finale sur disque de la sauvegarde."
],
"backupsOutro": "<strong>+ Créer une sauvegarde</strong> lance une sauvegarde sur le stockage marqué « Backup target » dans Proxmox. La restauration se fait dans l'interface web Proxmox ; Monitor montre les sauvegardes récentes de l'invité et permet d'en créer.",
"firewallTitle": "Onglet 7 — Pare-feu",
"firewallIntro": "Lit le journal du pare-feu Proxmox de l'invité directement sur l'hôte, sans service ni requêtes périodiques supplémentaires. L'onglet est toujours présent ; son contenu dépend de l'activation du pare-feu et de la journalisation effective d'une règle.",
"firewallItems": [
"<strong>Firewall désactivé</strong> — un avertissement orange indique où l’activer dans Proxmox (<em>&lt;Container|VM&gt; → Firewall → Options</em>) et rappelle qu’au moins une règle doit utiliser <code>log: info</code> ou un niveau supérieur pour afficher les paquets.",
"<strong>Pare-feu actif, aucun événement</strong> — rappel de la journalisation requise dans la vue vide, utile juste après activation.",
"<strong>Événements présents</strong> — panneau défilant à chasse fixe avec entrées brutes par action : <green>ACCEPT</green> vert, <orange>REJECT</orange> orange, <red>DROP</red> rouge. Le compteur de l'en-tête indique les lignes chargées."
],
"firewallRefresh": "<em>Actualiser</em> charge les dernières lignes à la demande. Sans actualisation automatique, la liste reste un instantané de l'ouverture ou du dernier clic. Source : <code>/var/log/pve-firewall.log</code>, filtré par VMID via <code>GET /api/vms/&lt;vmid&gt;/firewall/log</code>.",
"firewallCalloutTitle": "Pourquoi l'avoir ici quand l'UI Proxmox le montre déjà ?",
"firewallCalloutBody": "Évite de passer dans Proxmox et conserve la vue du même VMID : démarrer l'invité, vérifier montages et événements du pare-feu, puis l'arrêter depuis le panneau. Les règles sont modifiées dans Proxmox ; Monitor ne les change pas.",
"actionBarTitle": "Barre d'action inférieure",
"actionBarIntro": "Toujours visible au pied du modal quel que soit l'onglet actif:",
"consoleItem": "<strong>Console</strong>, pour les LXC actifs, ouvre <code>pct enter &lt;vmid&gt;</code> dans le conteneur. Elle utilise xterm.js et WebSocket comme l'<link>onglet Terminal</link>, avec la <strong>barre mobile</strong> : ESC, TAB, flèches, Entrée et Ctrl+C / Ctrl+X / Ctrl+R. Elle fonctionne sur téléphone ou tablette. Pour les VM, utilisez la console Proxmox noVNC.",
"lifecycleIntro": "Quatre boutons en grille 2×2 envoient <code>POST /api/vms/&lt;vmid&gt;/control</code> avec l'<code>action</code> correspondante. Leur disponibilité dépend de l'état de l'invité.",
"headerButton": "Bouton",
"headerEnabled": "Activé lorsque",
"headerAction": "Action envoyée à l'hôte",
"lifecycleRows": [
{
"button": "Démarrer",
"color": "green",
"enabled": "L'invité est arrêté.",
"action": "qm start / pct start"
},
{
"button": "Éteindre",
"color": "blue",
"enabled": "L'invité est en cours d'exécution.",
"action": "qm shutdown / pct shutdown — arrêt propre, ACPI"
},
{
"button": "Redémarrer",
"color": "blue",
"enabled": "L'invité est en cours d'exécution.",
"action": "qm reboot / pct reboot — redémarrage propre"
},
{
"button": "Forcer l'arrêt",
"color": "red",
"enabled": "L'invité est en cours d'exécution.",
"action": "qm stop / pct stop — arrêt forcé"
}
],
"forceStopTitle": "Forcer l'arrêt coupe immédiatement l'exécution",
"forceStopBody": "<strong>Forcer l'arrêt</strong> ignore la séquence d'arrêt, comme couper le courant. Utilisez <strong>Éteindre</strong> tant que l'invité répond. Forcez seulement si l'arrêt est bloqué et si vous acceptez le risque de perte de données. Le bouton rouge et son libellé limitent les clics accidentels."
},
"dataCollected": {
"heading": "Comment les données sont collectées",
"headerSection": "Section de l'onglet",
"headerEndpoint": "Point de terminaison",
"headerSource": "Source",
"rows": [
{
"section": "Liste des inventaires",
"endpoint": "/api/vms",
"source": "<code>pvesh get /cluster/resources --type vm</code> pour VM et CT."
},
{
"section": "Panneau de détails (config, réseau, disques)",
"endpoint": "/api/vms/<vmid>",
"source": "<code>qm config &lt;id&gt;</code> pour VMs / <code>pct config &lt;id&gt;</code> pour CTs."
},
{
"section": "Tableau des paramètres par invité",
"endpoint": "/api/vms/<vmid>/metrics",
"source": "Les données PVE RRD (<code>pvesh get /nodes/&lt;node&gt;/qemu/&lt;id&gt;/rrddata</code>) sont condensées à une forme facile à tracer."
},
{
"section": "Résultats récents du journal Proxmox",
"endpoint": "/api/vms/<vmid>/logs",
"source": "<code>pvesh get /nodes/&lt;node&gt;/&lt;qemu|lxc&gt;/&lt;vmid&gt;/log --start 0 --limit 1000</code>. Un échec renvoie une liste vide ; ces données ne constituent pas les journaux système complets de l'invité."
},
{
"section": "Sauvegardes disponibles pour les invités",
"endpoint": "/api/vms/<vmid>/backups",
"source": "<code>pvesm list &lt;storage&gt;</code> filtré par VMID."
},
{
"section": "Journal du pare-feu par invité (onglet Pare-feu)",
"endpoint": "/api/vms/<vmid>/firewall/log",
"source": "<code>/var/log/pve-firewall.log</code> filtré par VMID."
},
{
"section": "Commandes d'alimentation (Démarrer / Arrêt forcé / Redémarrer / Éteindre)",
"endpoint": "/api/vms/<vmid>/control",
"source": "Équivalents <code>qm start|stop|reboot|shutdown</code> ou <code>pct</code>."
}
],
"codeComment1": "# Comparer les données du tableau de bord à PVE",
"codeComment2": "# Examiner la configuration de l'invité telle que la fenêtre la voit",
"codeComment3": "# VM",
"codeComment4": "# CT"
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Moniteur de santé",
"href": "/docs/monitor/health-monitor",
"tailRich": " — catégorie VM et conteneurs : échecs de démarrage, délais QMP dépassés et échecs d'arrêt CT."
},
{
"label": "Notifications",
"href": "/docs/monitor/notifications",
"tailRich": "— ce que déclenchent les événements <code>vm_*</code>, <code>ct_*</code>, <code>migration_*</code> et <code>backup_*</code> en aval."
},
{
"label": "Référence de l’API",
"href": "/docs/monitor/api",
"tailRich": " — points de terminaison des VM et des sauvegardes."
},
{
"label": "Index du tableau de bord",
"href": "/docs/monitor/dashboard",
"tailRich": "— les autres onglets."
},
{
"label": "ProxMenux → Créer VM",
"href": "/docs/create-vm",
"tailRich": " — création de systèmes : modèles NAS (Synology et autres), VM Linux/Windows et valeurs adaptées à Proxmox."
}
]
}
}
@@ -0,0 +1,372 @@
{
"meta": {
"title": "Surveillance de Proxmox — CPU, mémoire, stockage, SMART, ZFS, journaux | ProxMenux",
"description": "Surveillance proactive de Proxmox VE : dix catégories toutes les cinq minutes (CPU et température, mémoire et swap, stockage, disques/SMART, réseau, VM, services, journaux, mises à jour et sécurité), quatre niveaux de gravité, périodes de mise en sourdine par catégorie, nettoyage des erreurs résolues, historique permanent des disques et notifications Telegram, Discord, Gotify ou e-mail.",
"ogTitle": "Surveillance de Proxmox — CPU, mémoire, stockage, SMART, ZFS, journaux",
"ogDescription": "Surveillance proactive de Proxmox VE dans dix catégories, avec niveaux de gravité, périodes de mise en sourdine et notifications par événement.",
"twitterTitle": "Surveillance de Proxmox | ProxMenux",
"twitterDescription": "Surveillance proactive de Proxmox VE dans dix catégories, avec niveaux de gravité et notifications."
},
"header": {
"title": "Moniteur de santé",
"description": "Ce contrôle continu examine dix catégories de l’hôte par cycles de cinq minutes, recueille les mesures entre les cycles, déduplique les constats en événements structurés et alimente le tableau de bord, les notifications et la reformulation IA facultative depuis une source commune.",
"section": "Moniteur ProxMenux"
},
"intro": {
"title": "Un scanner, trois consommateurs",
"body": "Un thread en arrière-plan exécute le cycle complet toutes les cinq minutes et enregistre chaque constat dans SQLite sous un <code>error_key</code> stable. Cela permet <strong>(1)</strong> au tableau de bord d’afficher l’état actuel, <strong>(2)</strong> au système de notifications de diffuser les nouveaux événements et <strong>(3)</strong> à l’assistant IA facultatif de reformuler les alertes clairement. Une seule configuration alimente tous ces composants."
},
"howItWorks": {
"heading": "Comment ça marche",
"intro": "La surveillance utilise deux threads parallèles. Un <strong>collecteur de mesures</strong> léger remplit les historiques du CPU, de la mémoire et des températures. Le <strong>cycle de contrôle complet</strong> lit ces données, évalue les conditions prolongées et exécute les autres vérifications environ toutes les cinq minutes, puis enregistre les constats dans SQLite pour le tableau de bord et les notifications.",
"scannerTitle": "De l'échantillon à la découverte stockée",
"scannerCaption": "Le collecteur remplit les historiques entre les cycles : CPU toutes les 5 s, mémoire toutes les 30 s et température toutes les 15 s. Il n’évalue pas les alertes lui-même. Le cycle complet analyse les historiques et vérifie SMART, ZFS, les journaux et les services avant d’enregistrer les constats dans SQLite.",
"scannerArrowLabel": "étape",
"scannerNodes": {
"samplerLabel": "Collecteur de mesures",
"samplerDetail": "Utilisation CPU 5 s\nMémoire 30 s\nTempérature 15 s\n→ historiques",
"cycleLabel": "Cycle complet de santé",
"cycleDetail": "Toutes les 5 min\nLit les historiques\n+ contrôles directs\n(SMART, ZFS,\nservices, journaux…)",
"checksLabel": "Contrôles par catégorie",
"checksDetail": "Dix catégories\n(CPU, mémoire,\nstockage, disques,\nréseau, VM,\nles services, les registres,\nmises à jour, sécurité)",
"sqliteLabel": "SQLite",
"sqliteDetail": "table errors\n(actives +\nmasquées)\n+ disk_observations\n(historique permanent\npar disque)"
},
"notifTitle": "Du constat enregistré à l’utilisateur",
"notifCaption": "Circuit des notifications. La même table des erreurs alimente aussi le tableau de bord (listes des alertes actives et masquées) et le nettoyage de fin de cycle qui résout automatiquement les anciennes entrées. Ces deux fonctions utilisent directement les données, sans passer par le répartiteur.",
"notifArrowLabel": "événement",
"notifNodes": {
"errorsLabel": "tableau des erreurs",
"errorsDetail": "Lignes actives +\nmasquées\nidentifiées par\nerror_key",
"dispatcherLabel": "Expéditeur de notification",
"dispatcherDetail": "Nouveaux événements\nou gravité accrue\nSelon les réglages\n+ délai minimal",
"templatesLabel": "Modèles + réécriture de l'IA",
"templatesDetail": "Modèle\npar événement\n→ reformulation IA\nfacultative en\nlangage clair",
"channelsLabel": "Canaux",
"channelsDetail": "Telegram\nDiscord\nGotify\nE-mail (SMTP)"
}
},
"categories": {
"heading": "Les dix catégories",
"imageAlt": "Vision Health Monitor montrant les dix catégories avec leurs statuts actuels (CPU, Mémoire, Stockage, Disques, Réseau, VMs, Services, Logs, Mises à jour, Sécurité)",
"imageCaption": "Le point de vue de Health Monitor — les dix catégories avec leur statut actuel. Les catégories d'un hôte sain sont toutes OK; les avertissements et les événements critiques apparaissent en ligne avec les lignes qui les ont produits.",
"intro": "Chaque cycle exécute dix contrôles indépendants. Chacun renvoie l’un des quatre états (<strong>OK</strong>, <strong>INFO</strong>, <strong>WARNING</strong>, <strong>CRITICAL</strong>) et des données structurées : noms de périphériques, extraits de journaux et seuils exacts. Ces données apparaissent dans le tableau de bord et les notifications.",
"headerCategory": "Catégorie",
"headerChecks": "Sous-contrôles",
"headerEvents": "Événements typiques",
"rows": [
{
"category": "CPU et température",
"checks": "Utilisation CPU avec hystérésis, température du capteur",
"events": "Utilisation CPU élevée et prolongée ; avertissements de température fondés sur les mesures des capteurs."
},
{
"category": "Mémoire et swap",
"checks": "Utilisation RAM, utilisation swap",
"events": "Pression mémoire prolongée ; activité de l’OOM-killer ; espace swap épuisé."
},
{
"category": "Stockage",
"checks": "Stockages Proxmox, système de fichiers racine",
"events": "Seuils d’occupation dépassés sur la racine ou un autre système de fichiers surveillé (85% avertissement / 95% critique par défaut) ; export NFS indisponible ; échec d’authentification CIFS ; pool LVM-thin plein."
},
{
"category": "Disques & SMART",
"checks": "SMART, erreurs dmesg E/S, pools ZFS, LVM, erreurs du système de fichiers",
"events": "Échec du contrôle SMART ; secteurs réalloués ou en attente ; erreurs d’E/S ATA ; pool ZFS DEGRADED / FAULTED ; remontage ext4 en lecture seule."
},
{
"category": "Réseau",
"checks": "Connectivité, état de liaison, latence de passerelle",
"events": "Bridge ou agrégat réseau hors service ; passerelle injoignable ; pics de latence persistants."
},
{
"category": "Machines virtuelles et conteneurs",
"checks": "Communication QMP, démarrage VM, démarrage conteneur",
"events": "Échec du démarrage d’une VM ou de l’arrêt d’un CT ; délai du socket QMP dépassé ; configuration ou disque manquants après un clonage."
},
{
"category": "Services PVE",
"checks": "<code>pveproxy</code>, <code>pvedaemon</code>, <code>pvestatd</code>, <code>pve-cluster</code>, mode grappe",
"events": "Le service s'est écrasé; le quorum du groupe a été perdu; <code>pmxcfs</code> bloqué."
},
{
"category": "Journaux système",
"checks": "Erreurs persistantes, pics d'erreur, cascades d'erreurs, messages critiques du noyau",
"events": "Erreurs identiques répétées; éclatement soudain d'avertissements (modèle de cascade); <code>BUG:</code> / <code>OOPS:</code> / <code>oom-killer</code> en dmesg."
},
{
"category": "Mises à jour du système",
"checks": "Mises à jour en attente, mises à jour de sécurité, version noyau / PVE, âge du système",
"events": "Mises à jour de sécurité ou du noyau utilisé en attente ; système non mis à jour depuis longtemps. Le bouton <em>Mettre à jour maintenant</em> apparaît dans l’aperçu lorsque des mises à jour sont disponibles. Il lance la procédure complète ProxMenux ; sa fermeture actualise l’état avec <code>?refresh=1</code> sans attendre le cycle suivant."
},
{
"category": "Sécurité et certificats",
"checks": "Tentatives de connexion, certificats proches de l’expiration, état des jails Fail2Ban si installé",
"events": "Répété SSH / défaillances d'auth web; certificat PVE < 30 jours à compter de la date d'expiration; interdictions actives de Fail2Ban."
}
]
},
"severity": {
"heading": "Modèle de gravité",
"headerStatus": "État",
"headerColour": "Couleur",
"headerMeaning": "Signification",
"headerNotification": "Notification",
"rows": [
{
"status": "OK",
"colour": "Vert",
"meaning": "En bonne santé. Aucune constatation dans cette catégorie.",
"notification": "Silencieux."
},
{
"status": "INFO",
"colour": "Bleu",
"meaning": "État transitoire ou déjà résolu à signaler une fois. Sert aussi aux catégories qui ne contiennent <em>que</em> des alertes masquées.",
"notification": "Facultatif. Chaque type d’événement peut être activé ou désactivé par canal."
},
{
"status": "WARNING",
"colour": "Jaune",
"meaning": "L'attention est nécessaire mais l'hôte est toujours fonctionnel. La cause est non-triviale — lire les détails.",
"notification": "Envoyée si ce type d’événement est activé pour le canal."
},
{
"status": "CRITICAL",
"colour": "Rouge",
"meaning": "Fonctionnalité cassée ou perte de données possible. Mesures à prendre.",
"notification": "Envoyée si le type d’événement est activé pour le canal. Une alerte de température CPU CRITICAL se déclenche à nouveau même après avoir été masquée."
}
],
"infoNote": "Une catégorie <strong>OK</strong> contenant encore des alertes masquées pendant leur période de mise en sourdine s’affiche en <strong>INFO</strong>. Cela rappelle que des alertes sont masquées.",
"unknownTitle": "UNKNOWN lorsqu’un contrôle ne peut pas aboutir",
"unknownBody": "Un contrôle indisponible renvoie <code>UNKNOWN</code> ; après trois cycles consécutifs, un constat persistant est enregistré. Le tableau de bord l’affiche en jaune. L’état global limite <code>UNKNOWN</code> à <strong>WARNING</strong> : ce seul problème ne rend pas l’hôte critique."
},
"dashboardView": {
"heading": "La vue du tableau de bord",
"intro": "La surveillance se trouve dans l’onglet <strong>Aperçu</strong>. L’indicateur d’état de l’en-tête (Sain / Avertissement / Critique) ouvre une fenêtre avec deux listes :",
"items": [
"<strong>Actives</strong> — catégories avec un constat non résolu. Chaque ligne se déplie pour afficher les contrôles concernés, le texte brut <code>reason</code>, l’identifiant du périphérique ou de la VM et, si disponible, un lien vers Stockage, Réseau, VM, Journaux ou Matériel.",
"<strong>Masquées</strong> — alertes acquittées par l’utilisateur dont la période de mise en sourdine n’est pas terminée. Chaque ligne affiche le temps restant et la durée choisie. À l’expiration, elle quitte cette liste ; si la cause persiste et que la catégorie le permet, elle revient parmi les alertes <em>Actives</em>."
],
"pillTitle": "L’indicateur reflète la catégorie la plus grave",
"pillBody": "La couleur de l’en-tête reflète la gravité maximale : CRITICAL → rouge, sinon WARNING → jaune, sinon INFO → bleu, sinon vert. Le point de la favicon et le badge PWA suivent la même logique.",
"updateNowTitle": "Bouton Mettre à jour maintenant dans l’en-tête de l’aperçu",
"updateNowBody1": "Si <em>Mises à jour système</em> signale des mises à jour en attente, <strong>Mettre à jour maintenant</strong> apparaît près de l’indicateur. La fenêtre lance la procédure de <em>ProxMenux → Settings post-install Proxmox → Proxmox System Update</em> : nettoyage des dépôts, <code>apt full-upgrade</code> via <code>update-pve-safe.sh</code>, reconstruction DKMS des pilotes gérés lors d’un nouveau noyau, autoremove/autoclean et proposition de redémarrage si nécessaire. La progression s’affiche en direct.",
"updateNowBody2": "À la fin, fermer la fenêtre appelle <code>GET /api/health/details?refresh=1</code> et invalide le cache du point d’accès. Les mises à jour en attente et la gravité sont recalculées depuis le nouvel état des paquets ; le badge disparaît sans attendre le prochain cycle. Le bouton est masqué si l’hôte est déjà à jour."
},
"dismiss": {
"heading": "Masquer les alertes et choisir la durée de mise en sourdine",
"intro": "Certains événements persistent, comme <em>Mises à jour système : mises à jour disponibles</em> tant que l’hôte n’est pas mis à jour. Une notification toutes les cinq minutes serait inutile. Le bouton <em>Mettre à jour maintenant</em> de l’aperçu permet de résoudre ce cas directement. Pour les autres cas ou les mises à jour reportées, deux mécanismes liés permettent de masquer les alertes :",
"step1": "<strong>Masquer un événement</strong> dans la fenêtre. Le menu propose <strong>24 heures</strong>, <strong>7 jours</strong> ou <strong>Définitivement</strong>, indépendamment de la catégorie. Le choix envoie <code>POST /api/health/acknowledge</code> avec <code>error_key</code> et <code>suppression_hours</code> (<code>-1</code> pour une durée permanente). L’événement passe dans la liste masquée avec l’horodatage <code>acknowledged_at</code>.",
"dropdownImageAlt": "Menu pour masquer une alerte : 24 heures, 7 jours ou définitivement",
"dropdownImageCaption": "La durée choisie ne concerne que cette alerte ; sans choix individuel, la valeur de la catégorie s’applique. Les alertes masquées définitivement portent un badge ambre <em>Permanent</em> et ne se déclenchent normalement plus. La température CPU critique constitue l’exception décrite plus bas.",
"step2": "<strong>Durée de mise en sourdine par catégorie</strong>. Dans Paramètres → Surveillance, ou via <code>POST /api/health/settings</code>, chacune des dix catégories possède une durée par défaut utilisée en l’absence de choix individuel :",
"imageAlt": "Durées de mise en sourdine par catégorie dans Paramètres → Surveillance",
"imageCaption": "Un menu par catégorie. Choisissez une durée longue pour les événements répétitifs, comme les mises à jour en attente, et courte pour ceux à réévaluer rapidement. Les mises en sourdine actives figurent dessous.",
"outro": "Pendant la mise en sourdine, le contrôle continue et met à jour <code>last_seen</code>, sans nouvelle notification. À l’expiration, le cycle suivant réévalue la cause : l’alerte peut se déclencher de nouveau ou disparaître si le problème est résolu.",
"activeSuppressionsTitle": "Consulter et annuler les mises en sourdine actives",
"activeSuppressionsBody": "Les alertes masquées, temporaires ou permanentes, figurent dans <strong>Paramètres → Surveillance → Mises en sourdine actives</strong>. Chaque ligne montre identifiant, catégorie, gravité, date et temps restant. <strong>Réactiver</strong> retire l’acquittement pour le prochain contrôle. Les acquittements permanents s’annulent ici ; les temporaires peuvent aussi être interrompus. Activez <em>Modifier</em>, sélectionnez les lignes à réactiver (bordure verte et texte barré), puis enregistrez. Annuler vide la sélection.",
"autoTitle": "Mise en sourdine automatique après changement de durée",
"autoBody": "Choisir une durée autre que les 24 h par défaut a un second effet : <strong>les futurs constats de la catégorie sont enregistrés comme déjà acquittés</strong>. Une semaine choisie pour les disques vaut donc aussi pour les nouveaux constats, sans les masquer un par un. Ils arrivent directement dans la liste masquée avec cette durée. Les catégories laissées à 24 h gardent le fonctionnement habituel : les nouveaux constats restent actifs jusqu’à votre intervention.",
"tempTitle": "Exception pour la température CPU CRITICAL",
"tempBody": "La couche de persistance prévoit une exception pour <strong>Température CPU CRITICAL</strong> : un tel enregistrement ignore l’acquittement antérieur et la mise en sourdine automatique. Cela ne signifie pas que tout contrôle de température émet un constat critique dès qu’un seuil configuré est dépassé.",
"nonDismissableTitle": "Quels constats peut-on masquer ?",
"nonDismissableBody": "La fenêtre propose Masquer uniquement si le contrôle renvoie explicitement dismissable = true. Une valeur fausse ou absente cache le bouton. La gravité seule ne détermine pas ce droit : plusieurs contrôles critiques autorisent l’acquittement. Les exemples décrivent les données actuelles ; masquer une alerte ne répare pas sa cause.",
"headerFinding": "Constatation",
"headerWhy": "Comportement de la mise en sourdine",
"rows": [
{
"finding": "Température CPU : avertissement / critique",
"why": "L’avertissement issu des mesures de température autorise explicitement la mise en sourdine. Une règle distincte ignore l’acquittement si un enregistrement de température CPU arrive avec la gravité CRITICAL."
},
{
"finding": "Espace critique du système de fichiers racine",
"why": "Les contrôles d’espace autorisent explicitement l’acquittement, même à un niveau critique. Cela ne libère pas d’espace et ne supprime pas le risque d’échec des écritures."
},
{
"finding": "ZFS pool DEGRADED / FAULTED",
"why": "Les contrôles de capacité des pools ZFS autorisent l’acquittement. Les autres constats suivent leur propre indicateur. Acquitter ne répare pas un pool dégradé ou défaillant."
},
{
"finding": "Erreurs d'entrée/sortie du disque avec SMART FAILED",
"why": "Les constats de disque enregistrés depuis le journal peuvent autoriser l’acquittement. SMART FAILED exige toujours une investigation ; le bouton dépend de l’indicateur du contrôle, pas du seul texte de l’alerte."
},
{
"finding": "Interface réseau DOWN",
"why": "Les contrôles persistants d’interface DOWN autorisent l’acquittement. Cela ne rétablit ni bridge, ni agrégat, ni liaison physique, ni accès distant."
},
{
"finding": "E/S sur disques sains (INFO)",
"why": "Les événements ATA ou dmesg transitoires avec un SMART sain peuvent être informatifs et se résoudre seuls. Les lignes informatives n’offrent pas forcément Masquer ; le contrôle détermine quand l’état est résolu."
}
],
"principle": "Utilisez le bouton proposé pour le constat réel, sans déduire sa disponibilité de la catégorie ou de la gravité. L’acquittement contrôle l’affichage et les notifications. Les contrôles de retour à la normale et l’historique du disque restent distincts."
},
"autoresolve": {
"heading": "Auto-résolution et nettoyage",
"intro": "De nombreuses alertes disparaissent lorsque leur cause cesse : une VM redémarre correctement, un disque a été retiré ou la température redevient normale. Le nettoyage à la fin de chaque cycle de cinq minutes applique ces règles :",
"headerTrigger": "Déclencheur",
"headerAction": "Action",
"rows": [
{
"trigger": "Utilisation CPU ou température revenue à la normale.",
"action": "Marqué résolu. Ça sort de la liste Active."
},
{
"trigger": "Pression de mémoire en dessous du seuil d'avertissement après une alerte OOM / mémoire.",
"action": "Marqué résolu."
},
{
"trigger": "VM / CT référencé par l'erreur n'existe plus (<code>qm status</code> / <code>pct status</code> non-zéro).",
"action": "Marqué résolu comme ressource supprimée."
},
{
"trigger": "Le disque référencé par l'erreur n'est plus présent dans <code>/dev/</code>.",
"action": "Marqué résolu comme dispositif enlevé. L'historique d'observation permanente est conservé (voir section suivante)."
},
{
"trigger": "Constats issus du journal système (catégorie <code>logs</code>, entrées SMART, erreurs ATA ou E/S) lorsque leur période de mise en sourdine expire.",
"action": "Ils sont retirés. Chaque analyse examine les nouvelles entrées du journal à partir de ce point ; une ancienne ligne n’est pas réémise."
},
{
"trigger": "Erreurs résolues depuis plus de sept jours.",
"action": "Supprimées de la base pour limiter la taille de la table. L’historique des notifications est indépendant et conservé plus longtemps."
}
],
"permanentTitle": "Masquer définitivement ne signifie pas résoudre",
"permanentBody": "Une durée de catégorie de <code>-1</code> (<em>permanente</em>) masque les futures alertes des éléments acquittés, sans ignorer le contrôle de résolution automatique. Si la cause disparaît, par exemple après suppression de la ressource ou retour sous le seuil, l’élément est toujours nettoyé automatiquement."
},
"observations": {
"heading": "Observations des disques — l’historique permanent",
"intro": "Les événements de disque méritent d’être conservés. Un avertissement SMART sur <code>/dev/sdh</code> à 02 h 14 reste utile après la fin de la rafale d’E/S et la résolution automatique : le disque a désormais des antécédents. La surveillance conserve donc une table <strong>permanente</strong> distincte : <code>disk_observations</code>.",
"headerProperty": "Propriété",
"headerErrors": "Table <code>errors</code> (Actives)",
"headerObs": "Table <code>disk_observations</code>",
"rows": [
{
"property": "Objet",
"errors": "Alimente la vue de santé <em>actuelle</em> et l’envoi des notifications.",
"obs": "Une piste d'audit permanente par disque."
},
{
"property": "Résoudre automatiquement",
"errors": "Oui : les lignes sont retirées lorsque la cause disparaît.",
"obs": "Non — les entrées persistent à jamais à moins que l'utilisateur les rejette explicitement."
},
{
"property": "Clé de déduplication",
"errors": "<code>error_key</code> (p. ex. <code>smart_sdh</code>).",
"obs": "<code>(disk_registry_id, error_type, error_signature)</code> avec signatures stables dépouillées de données volatiles."
},
{
"property": "Emplacement d’affichage",
"errors": "Fenêtre de surveillance (listes Actives / Masquées).",
"obs": "Fiche du disque dans l’onglet <strong>Stockage</strong>, avec un badge « X obs. » par disque."
},
{
"property": "Ce qu'il enregistre",
"errors": "Ce qui est en train d'échouer.",
"obs": "Avertissements SMART (secteurs, température, CRC, autotests échoués), erreurs d’E/S (ATA / NVMe / dm), erreurs du système de fichiers et événements de pools ZFS."
}
],
"outro": "Une alerte peut disparaître du tableau de bord tout en restant dans l’historique du disque. Ouvrez le disque dans Stockage : sa fiche affiche le nombre d’observations en attente, leurs horodatages, leur gravité et le message brut original. Ces informations aident à décider d’un remplacement.",
"renameTitle": "Les changements de nom des périphériques sont fusionnés automatiquement",
"renameBody": "Les disques peuvent d’abord apparaître sous un nom provisoire comme <code>ata8</code> ou <code>nvme0n1p3</code>. Les observations sont regroupées par numéro de série connu : si un événement est d’abord lié à <code>ata8</code> puis le même disque identifié comme <code>sdh</code>, ses anciennes observations sont rattachées à <code>sdh</code> au cycle suivant, sans fragmenter l’historique."
},
"notification": {
"heading": "Du constat à la notification",
"intro": "Chaque erreur active peut aussi déclencher une notification. Voici le parcours :",
"items": [
"Le scanner enregistre le résultat avec la catégorie + gravité + détails structurés.",
"Si le type d’événement est <strong>activé</strong> dans les notifications globales et que le canal n’a pas masqué cette catégorie, un événement est mis en file.",
"Le moteur de modèles produit un titre et un corps à partir des données structurées. Si la reformulation IA est activée, cette paire est transmise au fournisseur configuré pour une version en langage clair.",
"Le canal l’envoie sous forme de message Telegram, d’encart Discord, de notification push Gotify ou d’e-mail. Le résultat est enregistré dans <code>notification_history</code>.",
"Masquer une alerte démarre sa période de mise en sourdine. Les nouvelles détections du même <code>error_key</code> ne produisent normalement aucune notification et ne sont pas automatiquement mises en attente pour la fin de cette période. La température CPU critique reste une exception."
],
"outro": "La configuration des canaux — jeton du bot Telegram, URL des webhooks, clés IA, réglages par événement et par canal — est décrite dans <notifLink>Notifications</notifLink> et <aiLink>Assistant IA</aiLink>."
},
"rest": {
"heading": "Points d’accès REST",
"intro": "Les actions de la fenêtre sont accessibles par API pour scripts, tableaux de bord ou bots. Si l’authentification du Monitor est activée, un jeton Bearer valide issu de la connexion ou de l’écran des jetons API est requis. Les modifications, comme acquitter, enregistrer ou nettoyer les erreurs orphelines, exigent full_admin ; read_only reçoit 403. Si l’authentification est désactivée ou refusée, ces contrôles autorisent l’accès sans jeton.",
"headerEndpoint": "Point d’accès",
"headerMethod": "Méthode",
"headerUse": "Utilisation",
"rows": [
{
"endpoint": "/api/health",
"method": "GET",
"use": "Contrôle léger renvoyant du JSON avec <code>status</code>, <code>timestamp</code> et <code>version</code>. Convient aux contrôles de mots-clés Uptime Kuma ; si l’authentification du Monitor est activée, le client doit envoyer un en-tête Bearer."
},
{
"endpoint": "/api/health/status",
"method": "GET",
"use": "État global : un niveau de gravité et un texte de synthèse. Authentification requise."
},
{
"endpoint": "/api/health/details",
"method": "GET",
"use": "Les dix catégories avec leur état et les données structurées à l’origine de chacune."
},
{
"endpoint": "/api/health/full",
"method": "GET",
"use": "État complet : catégories, erreurs actives, alertes masquées et réglages de mise en sourdine. Une seule requête alimente la fenêtre ; un cache d’arrière-plan de six minutes accélère la réponse."
},
{
"endpoint": "/api/health/active-errors",
"method": "GET",
"use": "Juste la liste active. Filtré par <code>?category=&lt;name&gt;</code>."
},
{
"endpoint": "/api/health/dismissed",
"method": "GET",
"use": "Uniquement les alertes masquées, avec les heures restantes."
},
{
"endpoint": "/api/health/acknowledge",
"method": "POST",
"use": "Corps: <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Rejeter une alerte avec la fenêtre configurée de la catégorie."
},
{
"endpoint": "/api/health/settings",
"method": "GET / POST",
"use": "Lire ou enregistrer la durée de mise en sourdine par catégorie."
},
{
"endpoint": "/api/health/cleanup-orphans",
"method": "POST",
"use": "Nettoyage manuel des erreurs liées à un périphérique ou une VM supprimé. Idempotent."
}
],
"codeComment1": "# Obtenir l’état actuel pour un script",
"codeComment2": "# Rejeter une erreur spécifique",
"codeComment3": "# Définissez la suppression de la catégorie des disques à une semaine"
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Tableau de bord",
"href": "/docs/monitor/dashboard",
"tail": " — point d’ouverture de la fenêtre de surveillance dans l’interface."
},
{
"label": "Notifications",
"href": "/docs/monitor/notifications",
"tail": " — canaux, réglages par événement, reformulation IA et historique."
},
{
"label": "Assistant IA",
"href": "/docs/monitor/ai-assistant",
"tail": " — fournisseur (OpenAI / Anthropic / Gemini / Groq / Ollama / OpenRouter), mode des instructions, niveau de détail par canal et langue."
},
{
"label": "Architecture",
"href": "/docs/monitor/architecture",
"tailRich": " — schéma SQLite (<code>errors</code>, <code>disk_observations</code>, <code>events</code>) et cadence des threads d’arrière-plan."
}
]
}
}
+151
View File
@@ -0,0 +1,151 @@
{
"meta": {
"title": "ProxMenux Monitor — Tableau de bord web auto-hébergé pour Proxmox VE | ProxMenux",
"description": "ProxMenux Monitor est un tableau de bord web auto-hébergé pour Proxmox VE : mesures de l'hôte en temps réel, stockage et données SMART, réseau, VM et conteneurs, matériel, journaux, terminal web intégré, surveillance proactive de santé, notifications Telegram / Discord / e-mail, assistant IA facultatif, API REST et intégrations avec Homepage et Home Assistant.",
"ogTitle": "ProxMenux Monitor — Tableau de bord web auto-hébergé pour Proxmox VE",
"ogDescription": "Tableau de bord en temps réel Proxmox VE: métrique de l'hôte, stockage SMART, réseau, VM et conteneurs, matériel, journaux, terminal web, moniteur de santé, notifications, assistant AI, REST API.",
"twitterTitle": "ProxMenux Monitor | ProxMenux",
"twitterDescription": "Tableau de bord Proxmox VE auto-hébergé avec surveillance de santé, notifications, assistant IA et API REST."
},
"header": {
"title": "ProxMenux Monitor",
"description": "Un tableau de bord web auto-hébergé pour Proxmox VE, distribué sous forme d'AppImage. Il s'exécute sur l'hôte comme un service systemd unique, écoute sur le port TCP 8008 et fournit l'API et l'interface utilisateur depuis un seul processus.",
"section": "ProxMenux Monitor"
},
"atGlance": {
"title": "En un coup d'oeil",
"body": "Une seule AppImage sur l'hôte Proxmox → un serveur Flask (port 8008) collecte les données en temps réel avec <code>psutil</code>, <code>pvesh</code>, <code>smartctl</code> et <code>journalctl</code> → le tableau de bord Next.js est fourni par le même processus. Authentification facultative (mot de passe + 2FA), assistant IA facultatif, notifications facultatives et API REST pour les intégrations."
},
"hero": {
"alt": "Tableau de bord ProxMenux Monitor — aperçu système avec widgets CPU, mémoire, température et durée de fonctionnement",
"caption": "Écran d'atterrissage par défaut — mesures au niveau de l'hôte et état de santé en un coup d'oeil."
},
"coverage": {
"heading": "Ce que couvre le tableau de bord",
"intro": "Huit sections principales, chacune alimentée par ses propres points d'accès API :",
"tableSection": "Chapitre",
"tableWhat": "Ce qu'il montre",
"sections": [
{
"name": "Moniteur de santé",
"description": "Alertes actives et masquées concernant le CPU, la mémoire, le stockage, les disques, le réseau, les services, les journaux, les VM, les mises à jour et la sécurité. Alimente le moteur de notification."
},
{
"name": "Stockage",
"description": "Pools de stockage Proxmox, disques physiques (SATA / NVMe / USB), attributs SMART, état des pools ZFS, usure et durée de vie, activité d'entrée/sortie."
},
{
"name": "Réseau",
"description": "Toutes les interfaces (physiques, liaisons, ponts, OVS), IP/MAC/état, graphiques RX/TX en temps réel, données RRD historiques par interface."
},
{
"name": "Machines virtuelles et conteneurs",
"description": "Inventaire VM/LXC avec état, ressources et durée de fonctionnement. Le détail affiche configuration, mesures historiques, téléchargement de journaux Proxmox et actions démarrer/arrêter/redémarrer/éteindre. Les journaux dépendent du point d’accès Proxmox ; ce n’est pas une archive complète du système invité."
},
{
"name": "Matériel",
"description": "Modèle et topologie du CPU, répartition de la mémoire, périphériques PCIe, liste des GPU avec leur pilote et surveillance en temps réel par emplacement (NVIDIA / Intel iGPU)."
},
{
"name": "Journaux et événements",
"description": "Live <code>journalctl</code> avec des filtres de gravité / intervalle de temps / mots clés, historique des tâches Proxmox, journal de notification, paquets de journaux téléchargeables."
},
{
"name": "Terminal",
"description": "Shell de l’hôte et consoles VM/CT compatibles dans le navigateur via <code>xterm.js</code> et WebSockets. Le mode d’authentification configuré s’applique : désactivé ou refusé, il permet aux clients ayant accès au réseau d’ouvrir une session sans connexion. Cela n’implique pas un audit de chaque commande."
},
{
"name": "Sécurité",
"description": "Échecs d’authentification, état des jails Fail2Ban, blocages récents et intégration avec la jail <code>[proxmenux]</code> de l’hôte."
}
],
"footer": "Chaque section a une page de documentation dédiée sous <link>Tableau de bord</link> dans la barre latérale."
},
"howItRuns": {
"heading": "Comment ça marche",
"intro": "ProxMenux Monitor est distribué sous forme d’AppImage autonome. Une seule unité systemd (<code>proxmenux-monitor.service</code>) lance un processus Flask qui :",
"bullets": [
"Écoute sur <strong>TCP 8008</strong> sur l’hôte (HTTP).",
"Fournit les fichiers statiques du tableau de bord Next.js sous <code>/</code> et l'API sous <code>/api/*</code>, depuis le même processus.",
"Tire des données en direct avec des outils d'hôte standard: <code>psutil</code>, <code>pvesh</code>, <code>smartctl</code>, <code>journalctl</code>, <code>zpool</code>, <code>ip</code>, <code>nvidia-smi</code>, etc.",
"Conserve son état dans une base SQLite locale (<code>/usr/local/share/proxmenux/health_monitor.db</code>) : alertes masquées, observations des disques, configuration des notifications et de l'IA. L'état de l'authentification est stocké séparément dans <code>/root/.config/proxmenux-monitor/auth.json</code>."
],
"footer": "Le flux de requête complet, la mise en page du fichier et l'intégration systemd sont décrits dans <link>Architecture</link>."
},
"noAgent": {
"title": "Aucun agent sur les invités",
"body": "Le Monitor lit toutes les données depuis l’hôte. Aucun agent n’est nécessaire dans les VM ou les CT : les données proviennent de l’API Proxmox et des informations que le noyau de l’hôte fournit sur les systèmes invités en cours d’exécution."
},
"access": {
"heading": "Accès au tableau de bord",
"intro": "Deux modèles d'accès sont pris en charge et l'application détecte celui qui est utilisé:",
"codeComment1": "# 1) Accès direct sur l'hôte",
"codeComment2": "# 2) Par proxy inverse (Nginx / Caddy / Traefik)",
"afterCode": "Le proxy inverse doit définir <code>X-Forwarded-For</code>, <code>X-Forwarded-Proto</code> et <code>X-Forwarded-Host</code> correctement et transmettre les connexions WebSocket. Sur les ports standard, le navigateur utilise son origine courante. Le backend ne fait confiance aux IP transmises qu’avec PROXMENUX_TRUST_PROXY=1 explicite ; limitez alors l’accès direct au backend.",
"footer": "La configuration du premier lancement, le mot de passe + TOTP 2FA et les extraits de proxy inverse sont couverts par <link>Accès & Authentification</link>."
},
"mobile": {
"heading": "Utilisation mobile et installation d'écran d'accueil",
"intro": "Le tableau de bord s'adapte à la taille de l'écran et est proposé comme une application web progressive. Le fichier <code>public/manifest.json</code> fourni indique <code>display: standalone</code> ainsi qu'un nom d'application, une icône et une couleur de thème. Ajouter l'URL à l'écran d'accueil crée donc un lanceur autonome, sans barre d'adresse du navigateur, avec un écran de démarrage personnalisé et un thème sombre assorti au tableau de bord.",
"phoneAlt": "ProxMenux Monitor fonctionnant sur un téléphone — vue du tableau de bord principal",
"phoneCaption": "Tableau de bord principal sur un téléphone : la disposition se réorganise pour les petits écrans.",
"addHeading": "Ajouter à l'écran d'accueil",
"iosLabel": "iOS Safari:",
"iosBody": "bouton de partage → <em>Ajouter à l'écran d'accueil</em>. L'icône provient de <code>/apple-touch-icon.png</code> expédié dans le AppImage.",
"androidLabel": "Android Chrome / Edge:",
"androidBody": "menu à trois points → <em>Installer l'application</em> (ou <em>Ajouter à l'écran d'accueil</em> sur les anciennes versions).",
"afterInstall": "Une fois installé, l'ouverture de l'icône lance le tableau de bord en mode autonome avec sa propre entrée de commutateur de tâches.",
"onlineOnlyTitle": "Connexion requise",
"onlineOnlyBody": "La PWA peut être installée, mais elle <strong>ne fonctionne pas</strong> hors ligne : elle ne possède pas de service worker. Le raccourci se comporte comme une application native, mais l’appareil doit toujours pouvoir joindre l’hôte sur TCP 8008, par le réseau local, un VPN ou HTTPS via un proxy inverse, pour charger le tableau de bord."
},
"health": {
"heading": "Surveillance de la santé et notifications",
"alt": "Écran de moniteur de santé montrant les catégories 10 suivies (CPU, mémoire, stockage, disques, réseau, services, journaux, VM, mises à jour, sécurité) avec état actuel",
"caption": "Vision du moniteur de la santé — les catégories 10 suivies, avec leur statut actuel. Des alertes actives et rejetées apparaissent ici lorsque le système en soulève.",
"body1": "Dans le tableau de bord, le <strong>moniteur de santé</strong> fonctionne en continu en arrière-plan et produit un flux structuré d'événements : température élevée du CPU, avertissements SMART des disques, dégradation des pools ZFS, processus arrêtés par manque de mémoire, défaillances VM/CT, incidents de sécurité, etc. Chaque événement possède une catégorie, un niveau de gravité (INFO / WARNING / CRITICAL) et une <code>error_key</code> stable pour regrouper les doublons sans saturer l'écran.",
"feedsIntro": "Les événements alimentent trois choses en même temps :",
"feedsHealth": "La <strong>vue du moniteur de santé</strong> dans le tableau de bord (listes des alertes actives et masquées).",
"feedsChannels": "Le <strong>moteur de notifications</strong> — Telegram, Discord, e-mail, Gotify, Pushover et Apprise (multicanal). Chaque canal se configure séparément et les catégories d’événements peuvent être mises en sourdine.",
"feedsAI": "L’<strong>assistant IA</strong> facultatif explique les événements en langage clair via le fournisseur choisi (OpenAI, Anthropic, Gemini, Groq, Ollama ou OpenRouter) et propose la suite si cette option est activée dans les réglages IA.",
"suppressionTitle": "Masquer une alerte plutôt que tout mettre en sourdine",
"suppressionBody": "Chaque catégorie possède sa propre <em>durée de suppression des notifications</em> : après avoir masqué une alerte, vous ne recevez plus de notification pour cette même alerte pendant cette période (24 heures par défaut, réglable par catégorie jusqu'à une suppression permanente). Une aggravation réelle, par exemple le franchissement du seuil critique de température du CPU, déclenche toujours une nouvelle alerte, indépendamment de cette suppression."
},
"api": {
"heading": "REST API et intégrations",
"intro": "Les points d’accès REST exposent les mesures en JSON par HTTP/HTTPS pour Homepage, Home Assistant, Uptime Kuma et les scripts. Grafana peut utiliser l’exporteur texte Prometheus séparé sur <code>/api/prometheus</code>. Les requêtes peuvent être faites avec <code>curl</code>.",
"tokens": "Les jetons API à longue durée de vie (365 jours) sont générés à partir de <strong>Paramètres → API Tokens</strong> ou via <code>POST /api/auth/generate-api-token</code>.",
"bearer": "Envoyez les jetons via <code>Authorization: Bearer …</code>. Le point public <code>/api/health</code> convient aux sondes de disponibilité sans identifiants. Sous <code>/api/auth/*</code>, certaines routes de configuration/connexion/état sont publiques, mais celles de gestion du compte et des jetons sont protégées.",
"catalog": "Le catalogue complet des points d'accès, les conseils de rotation des jetons et les bonnes pratiques de sécurité se trouvent dans la <linkApi>référence API</linkApi>. Des exemples pour Homepage, Home Assistant, Grafana et Uptime Kuma, ainsi qu'un modèle générique cURL, sont proposés dans les <linkIntegrations>intégrations</linkIntegrations>."
},
"serviceControl": {
"heading": "Contrôle des services",
"intro": "Au jour le jour, le moniteur est géré exactement comme tout autre service systemd. Il est également exposé comme deux entrées à l'intérieur du ProxMenux TUI sous <em>Paramètres</em>:",
"codeComment": "# Contrôle manuel",
"footer": "Voir <link>Paramètres → ProxMenux Monitor</link> pour activer/désactiver le service dans le menu et vérifier son état."
},
"nextSteps": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Architecture",
"description": "— serveur Flask, unité systemd, schéma SQLite, fournisseurs d'IA et canaux de notification."
},
{
"label": "Accès et authentification",
"description": "— premier lancement, mot de passe, TOTP 2FA, configuration du proxy inverse et intégration Fail2Ban."
},
{
"label": "Tableau de bord",
"description": "— toutes les sections de l'interface utilisateur, avec une page pour chacune."
},
{
"label": "Référence de l’API",
"description": "— chaque point d'accès, structure des requêtes et réponses, gestion des jetons."
},
{
"label": "Intégrations",
"description": "— Homepage, Home Assistant, Grafana / Prometheus, Uptime Kuma et modèle générique cURL."
}
]
}
}
@@ -0,0 +1,255 @@
{
"meta": {
"title": "Intégrations Proxmox — Homepage, Home Assistant, Grafana, Prometheus | ProxMenux Monitor",
"description": "Exemples à copier pour relier ProxMenux Monitor à Homepage, Home Assistant, Grafana via Prometheus et Uptime Kuma, avec configuration attendue, points d’accès API et en-tête d’authentification.",
"ogTitle": "Intégrations Proxmox — Homepage, Home Assistant, Grafana, Prometheus",
"ogDescription": "Guide pour relier ProxMenux Monitor à Homepage, Home Assistant, Grafana, Prometheus et Uptime Kuma.",
"twitterTitle": "Intégrations Proxmox | ProxMenux Monitor",
"twitterDescription": "Recettes pour Homepage, Home Assistant, Grafana, Prometheus et Uptime Kuma."
},
"header": {
"title": "Intégrations",
"description": "Exemples à copier pour les outils de votre homelab : Homepage, Home Assistant, Grafana via Prometheus et Uptime Kuma. Chaque exemple montre la configuration attendue, le point d’accès du Monitor utilisé et l’en-tête d’authentification nécessaire.",
"section": "Moniteur ProxMenux"
},
"intro": {
"title": "Ce que vous pouvez construire à partir de cette page",
"body": "Copiez chaque exemple dans l’outil choisi. Les points d’accès figurent dans la <link>Référence de l’API</link> ; cette page explique leur utilisation dans Homepage, Home Assistant et Grafana. Les captures montrent le résultat des configurations."
},
"auth": {
"heading": "Authentification: la seule chose dont chaque recette ait besoin",
"intro": "La plupart de ces points d’accès exigent une authentification. Deux méthodes sont proposées.",
"optAtitle": "Option A — Jeton API (recommandé pour les intégrations)",
"optAbody1": "Ouvrez <strong>Paramètres → Sécurité → Jetons API</strong>. Choisissez <em>Générer un jeton</em>, nommez-le par exemple <em>homepage</em>, <em>home-assistant</em> ou <em>prometheus</em>, puis copiez-le : il n’est affiché <em>qu’une fois</em>. Sa durée par défaut est d’un an et il peut être révoqué individuellement. Utilisez-le pour les clients autres que le navigateur.",
"optAbody2": "À partir de ce moment, chaque demande est juste:",
"optBtitle": "Option B — flux de connexion (nom d'utilisateur + mot de passe)",
"optBbody": "Utile pour les scripts qui authentifient en tant qu'utilisateur humain. Le jeton retourné est de courte durée; la plupart des intégrations devraient préférer l'option A.",
"outro": "Le champ TOTP n’est requis que si la double authentification est activée. Le renouvellement et la révocation des jetons, les règles de mot de passe et le journal d’audit figurent dans <link>Accès et authentification</link>.",
"httpsTitle": "Utiliser HTTPS au lieu de HTTP",
"httpsIntro": "Chaque recette ci-dessous utilise <code>http://</code> dans les URLs pour garder les exemples courts. Si vous avez activé TLS sur le moniteur (<strong>Paramètres → Sécurité → SSL/HTTPS</strong>), échangez <code>http://</code> contre <code>https://</code> dans chaque URL — c'est le seul changement. Deux notes spécifiques à certains outils:",
"httpsItems": [
"<strong>Certificats autosignés.</strong> L’intégration Home Assistant <code>rest:</code> vérifie TLS par défaut. Pour le certificat autosigné du Monitor, ajoutez <code>verify_ssl: false</code> à chaque bloc REST près de <code>scan_interval:</code>, ou ajoutez son AC au magasin de certificats approuvés. Même principe pour les autres outils qui vérifient les certificats.",
"<strong>Prometheus</strong> dispose déjà de <code>scheme: https</code> dans l’exemple ci-dessous. Activez ou conservez <code>https</code> si TLS est activé sur le Monitor."
]
},
"homepage": {
"heading": "Homepage",
"headingHref": "https://gethomepage.dev",
"intro": "Homepage est un tableau de bord d’applications personnalisable. ProxMenux Monitor s’y connecte avec le widget intégré <code>customapi</code> : ajoutez un service à <code>services.yaml</code>, redémarrez Homepage et la carte affiche les valeurs en direct.",
"iconCalloutTitle": "Le logo officiel ProxMenux est sur dashboardicons.com",
"iconCalloutBody": "Les exemples utilisent <code>icon: proxmenux.png</code>. Homepage recherche les noms simples dans <a1>dashboardicons.com</a1>, une bibliothèque d’icônes pour tableaux de bord auto-hébergés. L’entrée ProxMenux est à <a2>dashboardicons.com/icons/external/proxmenux</a2> et se charge au premier affichage. Même principe pour des milliers d’outils comme Telegram, Discord, Grafana ou Tailscale : indiquez <code>icon: &lt;name&gt;.png</code> dans le service.",
"imageAlt": "Tableau de bord Homepage avec trois cartes ProxMenux Monitor (EDGE, VOID, DREAM) montrant durée de fonctionnement, CPU, RAM et température de chaque hôte",
"imageCaption": "Trois instances ProxMenux Monitor sous forme de cartes Homepage : durée de fonctionnement, CPU, RAM et température CPU lues sur <code>/api/system</code> de chaque hôte toutes les 10 s.",
"basicTitle": "Widget de base — pas d'authentification",
"basicIntro": "Utilisez ceci lorsque ProxMenux Monitor est sur un réseau de confiance et que vous n'avez pas encore activé l'authentification du côté Monitor. L'entrée la plus simple possible <code>services.yaml</code>:",
"authedTitle": "Widget authentifié",
"authedIntro": "Générez un jeton API dans <strong>Paramètres → Sécurité → API Jetons</strong> sur le moniteur, copiez-le et collez-le dans l'en-tête <code>Authorization</code> ci-dessous — remplacez le jeton d'exemple affiché après <code>Bearer</code> par celui que vous venez de copier:",
"authedOutro": "Redémarrez Homepage pour afficher les valeurs actualisées. Réutilisez le même jeton pour les widgets qui interrogent la même instance du Monitor.",
"multiTitle": "Configuration multi-widget — système, stockage, réseau",
"multiIntro": "Pour plus de détails, créez trois cartes utilisant des points d’accès distincts : système, stockage et réseau. Elles utilisent le même jeton pour cette instance du Monitor.",
"multiCalloutTitle": "Plusieurs hôtes Proxmox",
"multiCalloutBody": "Répétez le bloc pour chaque hôte afin d’obtenir les cartes illustrées. Chaque entrée utilise <code>http://&lt;host&gt;:8008</code> de son instance. Générez et stockez un jeton par hôte : chaque installation possède sa clé de signature, donc un jeton ne fonctionne pas automatiquement ailleurs."
},
"homeAssistant": {
"heading": "Home Assistant",
"headingHref": "https://www.home-assistant.io",
"intro": "Ces exemples utilisent l’intégration native <code>rest</code> de Home Assistant, sans composant HACS spécifique. Elle lit les points d’accès de la <link>Référence de l’API</link> et crée des capteurs et attributs pour les automatisations. La configuration fournit environ 25 capteurs pour les ressources, la santé, les VM/CT, le stockage, le réseau et les mises à jour. Ajoutez-la à <code>configuration.yaml</code> et rechargez ou redémarrez HA.",
"imageAlt": "Tableau de bord Home Assistant avec état de santé, jauges CPU/RAM/température, nombre de VM, occupation du stockage et compteur d’erreurs actives",
"imageCaption": "ProxMenux Monitor en tant qu'intégration de première classe Home Assistant — capteurs construits à partir de la recette YAML ci-dessous.",
"step1Title": "1 · Enregistrer le jeton API",
"step1Body": "Placez le jeton dans <code>secrets.yaml</code> pour le séparer de la configuration principale. Regroupez le préfixe Bearer et le jeton dans une valeur utilisable comme en-tête. Le fichier n’est pas chiffré et doit rester privé. Son emplacement dépend de l’installation, généralement <code>/config/secrets.yaml</code> sous HA OS ou Container.",
"step2Title": "2 · Ajouter la configuration REST",
"step2Body": "Six blocs REST couvrent les principales fonctions. Leur <code>scan_interval</code> suit la fréquence des changements : ressources toutes les 30 s, santé toutes les 60 s, inventaires toutes les 5 à 10 min. Collez dans <code>configuration.yaml</code> :",
"step3Title": "3 · Ajouter des capteurs binaires et des modèles auxiliaires",
"step3Body": "Deux capteurs binaires et deux capteurs de modèle complètent l’intégration. Ils simplifient les automatisations et les cartes conditionnelles Lovelace sans répéter des expressions Jinja partout.",
"step4Title": "4 · Recharger et vérifier",
"step4Body": "Vérifiez d’abord la syntaxe dans <em>Outils de développement → YAML → Vérifier la configuration</em>. Rechargez ensuite <em>Toute la configuration YAML</em> ou redémarrez HA. Filtrez <em>Paramètres → Appareils et services → Entités</em> par <em>proxmenux</em>. Les quelque 25 entités devraient recevoir leurs valeurs pendant un intervalle de collecte.",
"replaceTitle": "Remplacer une version antérieure de cette recette?",
"replaceBody": "Après une ancienne version, le registre peut conserver des identifiants obsolètes et les cartes signaler <em>Entité introuvable</em>. Retirez les anciens blocs <code>rest:</code> et <code>template:</code> de <code>configuration.yaml</code>, puis rechargez. Dans <em>Paramètres → Appareils et services → Entités</em>, filtrez par <em>proxmenux</em> et supprimez les anciennes entrées restaurées ou indisponibles. Ajoutez le YAML actuel et rechargez pour enregistrer les nouvelles.",
"step5Title": "5 · Tableau de bord Lovelace",
"step5Body": "Le YAML crée une carte <strong>vertical-stack</strong> regroupant logo, indicateurs, système, VM, stockage, réseau et carte conditionnelle des problèmes. Ouvrez le tableau de bord, sélectionnez le crayon, <em>Ajouter une carte</em>, puis <em>Manuel</em> en bas et collez :",
"viewTipTitle": "Vous voulez une vue complète du tableau de bord au lieu d'une seule carte ?",
"viewTipBody": "Ouvrez le menu à trois points → <em>Éditeur de configuration brute</em> et ajoutez une vue avec cet en-tête au-dessus de la liste <code>cards:</code> :",
"viewTipOutro": "Cela vous donne un onglet / vue dédié dans votre tableau de bord avec sa propre icône et son propre titre, au lieu d'une carte longue sur une vue existante.",
"altViewTitle": "Alternative — une vue de tableau de bord dédiée",
"altViewIntro": "Pour créer un onglet dans un tableau de bord existant, ajoutez une vue avec le YAML ci-dessous. Une vue est un onglet du tableau de bord et ne crée pas d’entrée dans la barre latérale. Étapes :",
"altViewSteps": [
"Ouvrez le tableau de bord où vous voulez le nouvel onglet.",
"Cliquez sur le crayon (modifier le tableau de bord) en haut à droite.",
"Cliquez sur l'onglet <em>+</em> à la fin des onglets existants pour créer une nouvelle vue.",
"Dans la fenêtre, passez en haut à droite à <em>Éditeur de code</em> pour basculer entre l’éditeur visuel et YAML.",
"Collez le YAML ci-dessous.",
"Enregistrez. La vue <em>ProxMenux Monitor</em> apparaît comme onglet dans le tableau de bord avec ses cartes."
],
"twoEditorsTitle": "Deux éditeurs YAML dans HA — choisissez le bon",
"twoEditorsIntro": "Home Assistant a deux éditeurs YAML qui ressemblent mais qui s'attendent à des formats différents:",
"twoEditorsItems": [
"<strong>Éditeur d’une vue</strong> — accessible par <em>+</em> ou <em>Modifier la vue → Éditeur de code</em>. Attend une seule vue avec <code>title:</code>, <code>path:</code> et <code>cards:</code> au premier niveau, sans tiret initial.",
"<strong>Éditeur brut du tableau de bord complet</strong> — accessible par le menu à trois points. Attend toute la liste <code>views:</code>, chaque vue étant un élément commençant par <code>-</code>."
],
"twoEditorsOutro": "Un format inadapté peut produire une <em>Vue sans nom</em> et <code>cards: []</code>. Le YAML ci-dessous est destiné à l’éditeur d’une seule vue ; copiez-le tel quel.",
"viewImageAlt": "Vue Home Assistant dédiée à ProxMenux Monitor : en-tête picture-entity, indicateurs glance et cartes système, VM, stockage et réseau sur plusieurs colonnes",
"viewImageCaption": "La vue <em>ProxMenux Monitor</em> sur grand écran. La disposition Masonry répartit les cartes en colonnes ; le résultat dépend du type de vue configuré.",
"twoColTipTitle": "Vous voulez une mise en page fixe à deux colonnes au lieu de la mise en page automatique ?",
"twoColTipBody": "Regroupez deux cartes, par exemple <em>Système</em> + <em>VM</em> ou <em>Stockage</em> + <em>Réseau</em>, dans un <code>horizontal-stack</code> pour les afficher côte à côte quelle que soit la largeur :",
"twoColTipOutro": "Sur mobile, la ligne reste comprimée. La disposition automatique HA sans horizontal-stack s’adapte mieux aux écrans étroits.",
"step6Title": "6 · Automatisations",
"step6Body": "Trois automatismes couvrant les scénarios réactifs les plus courants – remplacer <code>notify.mobile_app_&lt;your_phone&gt;</code> par le service d'avis que vous utilisez :",
"logoTitle": "À propos du logo ProxMenux",
"logoBody": "La carte picture-entity charge le logo officiel depuis <a1>dashboardicons.com</a1>, une bibliothèque gratuite pour tableaux de bord auto-hébergés. L’entrée est à <a2>dashboardicons.com/icons/external/proxmenux</a2>. Home Assistant récupère le SVG en HTTPS au premier affichage et le met en cache.",
"logoBrokenTitle": "Si la carte logo affiche une image cassée",
"logoBrokenIntro": "Certaines installations, réseaux filtrés ou extensions de blocage empêchent l’accès à jsdelivr.net lors de l’affichage. Utilisez alors une copie locale :",
"logoBrokenSteps": [
"Téléchargez le SVG depuis <a>cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/proxmenux.svg</a>.",
"Enregistrez-le sur <code>/config/www/icons/proxmenux.svg</code> sur votre hôte HA.",
"Dans le Lovelace YAML, remplacer l'URL <code>image:</code> par <code>/local/icons/proxmenux.svg</code>. Enregistrer et recharger — l'image rend à partir du fichier local, pas besoin d'Internet."
],
"scanTipTitle": "Règle pratique pour scan_interval",
"scanTipBody": "Commencez par interroger <code>/api/system</code> toutes les 30 s. <code>/api/health/full</code> lit généralement un résultat valable jusqu’à six minutes ; l’interroger toutes les 60 s ne contourne pas ce cache. Essayez cinq minutes pour <code>/api/storage/summary</code> et une heure pour <code>/api/proxmenux/update-status</code>. Adaptez à votre matériel et au nombre d’hôtes."
},
"grafana": {
"heading": "Prometheus + Grafana",
"promHref": "https://prometheus.io",
"grafanaHref": "https://grafana.com",
"intro": "ProxMenux Monitor expose <code>GET /api/prometheus</code> au format texte Prometheus 0.0.4. Un jeton Bearer est requis si l’authentification est activée. Configurez Prometheus pour collecter les métriques, puis Grafana pour visualiser la base de séries temporelles.",
"imageAlt": "Tableau de bord Grafana avec métriques ProxMenux : jauge CPU, historique mémoire, nombre de VM actives et débit réseau",
"imageCaption": "Un tableau de bord Grafana à partir des métriques ProxMenux collectées par Prometheus : CPU, mémoire, VM actives et débit réseau. Le catalogue complet est dans <link>Référence de l’API → Métriques Prometheus</link>.",
"step1Title": "1 · Ajouter la tâche de collecte à Prometheus",
"step1Body": "Transmettez le jeton API par le bloc natif <code>authorization</code> de Prometheus, qui permet aussi de charger les identifiants depuis un fichier.",
"step1After": "Rechargez Prometheus avec <code>kill -HUP &lt;PID&gt;</code> (remplacez PID par son identifiant de processus), <code>systemctl reload prometheus</code> si le service le permet, ou <code>docker compose restart prometheus</code> en conteneur. Dans <em>Status → Targets</em>, proxmenux devrait passer à UP en un intervalle. Le label <code>node=\"&lt;hostname&gt;\"</code> distingue les hôtes.",
"tokenTipTitle": "Conserver le jeton dans un fichier séparé",
"tokenTipBody": "En production, séparez le jeton de la configuration. Avec <code>credentials_file: /etc/prometheus/secrets/proxmenux.token</code>, Prometheus le lit dans un fichier doté des permissions 0600.",
"step2Title": "2 · Vérifier la collecte avec quelques requêtes",
"step2Body": "Avant Grafana, vérifiez que Prometheus possède les données. Ouvrez <code>http://&lt;prometheus-host&gt;:9090</code>, choisissez <em>Query</em> et lancez l’une de ces requêtes. Des valeurs récentes de l’hôte Proxmox doivent apparaître :",
"headerQuery": "Requête",
"headerConfirms": "Ce qu'il confirme",
"verifyRows": [
{
"query": "up{job=\"proxmenux\"}",
"confirms": "Renvoie <code>1</code> si Prometheus collecte correctement le Monitor, sinon <code>0</code>. Le contrôle initial le plus rapide."
},
{
"query": "proxmox_cpu_usage",
"confirms": "Utilisation actuelle de CPU % de l'hôte Proxmox. Doit changer si vous rafraîchissez la requête quelques secondes d'intervalle."
},
{
"query": "proxmox_vms_running",
"confirms": "Nombre de machines invitées en cours d’exécution. Comparez avec l’interface Proxmox."
},
{
"query": "proxmox_uptime_seconds / 86400",
"confirms": "Durée de fonctionnement de l’hôte en jours. Elle doit correspondre à <code>uptime</code> dans le terminal Proxmox."
}
],
"calloutTitle": "Un 401 en ouvrant directement l’URL du point d’accès peut être normal",
"calloutBody": "Avec l’authentification activée, le lien dans <em>Status → Targets</em> ouvre <code>/api/prometheus</code> dans le navigateur sans l’en-tête Bearer de Prometheus. La réponse peut contenir <code>'{'\"error\":\"Authentication required\"'}'</code>. Vérifiez le véritable <em>State: UP</em> de la cible pour confirmer la collecte par Prometheus.",
"step3Title": "3 · Ajouter Prometheus comme source de données Grafana",
"step3Body": "Dans Grafana, ouvrez <em>Connections → Data sources → Add new → Prometheus</em>. Indiquez l’URL, par exemple <code>http://prometheus.lan:9090</code>, enregistrez et testez. Si Prometheus exige une authentification, configurez-la séparément ici. Le jeton du Monitor appartient à la tâche de collecte Prometheus.",
"step4Title": "4 · Construire des panneaux avec ces requêtes PromQL",
"step4Body": "Une sélection de départ pour les mesures habituellement suivies sur un hôte Proxmox :",
"headerPanel": "Idée de panneau",
"headerPromql": "Requête PromQL",
"panelRows": [
{
"panel": "Jauge d’utilisation CPU par hôte",
"promql": "proxmox_cpu_usage"
},
{
"panel": "Mesure d'utilisation de la mémoire par hôte",
"promql": "proxmox_memory_usage_percent"
},
{
"panel": "Mémoire utilisée et totale (séries temporelles)",
"promql": "proxmox_memory_used_bytes / 1024 / 1024 / 1024"
},
{
"panel": "VM/CT en cours d’exécution par hôte",
"promql": "proxmox_vms_running"
},
{
"panel": "Température du processeur",
"promql": "proxmox_cpu_temperature_celsius"
},
{
"panel": "Débit réseau RX (octets/s)",
"promql": "rate(proxmox_interface_bytes_received_total[5m])"
},
{
"panel": "Débit réseau TX (octets/s)",
"promql": "rate(proxmox_interface_bytes_sent_total[5m])"
},
{
"panel": "Moyenne de charge (1 m)",
"promql": "proxmox_load_average{period=\"1m\"}"
},
{
"panel": "Espace disque utilisé % par point de montage",
"promql": "proxmox_disk_usage_percent"
},
{
"panel": "Charge de batterie UPS",
"promql": "proxmox_ups_battery_charge_percent"
},
{
"panel": "Température GPU par emplacement",
"promql": "proxmox_gpu_temperature_celsius"
}
],
"outro": "Ajoutez chaque requête comme panneau Grafana, avec <em>Stat</em> pour les valeurs et <em>Time series</em> pour les tendances, puis groupez les panneaux par catégorie. Utilisez <code>node</code> comme variable du tableau de bord (<em>Settings → Variables → New → Query → label_values(proxmox_cpu_usage, node)</em>) pour filtrer par hôte."
},
"uptimeKuma": {
"heading": "Uptime Kuma et autres vérificateurs de statut",
"href": "https://github.com/louislam/uptime-kuma",
"intro": "Pour un contrôle par mot-clé, utilisez <code>GET /api/system-info</code>. Cette route n’exige pas de jeton et renvoie nom d’hôte, durée de fonctionnement et santé : <code>healthy</code>, <code>warning</code> ou <code>critical</code>. Elle est publique, contrairement aux points d’accès détaillés protégés.",
"kumaTitle": "Uptime Kuma — moniteur de mots clés HTTP",
"kumaSteps": [
"Dans Uptime Kuma, cliquez sur <em>+ Ajouter un nouveau moniteur</em>.",
"Type de moniteur: <em>HTTP(s) - Mot-clé</em>.",
"Nom descriptif : <em>ProxMenux Monitor — pve01</em>.",
"URL: <code>http://pve01.lan:8008/api/system-info</code>.",
"Mot-clé : <code>healthy</code> (la valeur de <code>health.status</code> lorsque l'hôte est OK).",
"Intervalle de vérification : 60 secondes suffisent.",
"Enregistrez. La route system-info ne nécessite pas d’en-tête Bearer."
],
"healthchecksTitle": "healthchecks.io / pings de tâches cron",
"healthchecksBody": "Une tâche cron peut interroger <code>/api/system-info</code> et tester <code>.health.status == \"healthy\"</code>. Uniquement après réussite, elle envoie un ping de succès à son URL Healthchecks.io unique. Le service reçoit les pings des tâches ; il n’interroge pas le Monitor. Un HTTP 2xx seul ne prouve pas la bonne santé de l’hôte.",
"richTitle": "Besoin de données de santé plus riches",
"richBody": "Pour l’état complet — dix catégories, erreurs actives et alertes masquées — utilisez <code>GET /api/health/full</code>. Une réponse contient les données de la fenêtre du tableau de bord. Un jeton Bearer est requis si l’authentification est activée."
},
"workflows": {
"heading": "n8n, Zapier et scripts personnalisés",
"intro": "Les workflows et scripts peuvent <em>envoyer</em> des notifications par POST vers <code>/api/notifications/send</code>, par exemple après un échec CI ou une tâche trop longue. Cet envoi direct contourne la file et le délai entre empreintes d’événements. Il conserve le format par canal, l’IA facultative et la livraison. Gérez les doublons dans l’appelant.",
"n8nBody": "Dans n8n, utilisez un nœud <em>HTTP Request</em> avec POST, l’URL ci-dessus et le même JSON que curl. Choisissez les identifiants génériques Header Auth : nom <em>Authorization</em> et valeur <code>Bearer YOUR_API_TOKEN</code>, en remplaçant le marqueur. Reliez un planning, webhook ou autre nœud pour déclencher la requête.",
"severityBody": "La gravité utilise <code>INFO</code>, <code>WARNING</code> ou <code>CRITICAL</code> en majuscules. L’objet <code>data</code> apporte du contexte. L’IA reçoit le titre et le message rendus avec les enrichissements pris en charge ; tous les champs ne sont pas garantis dans ses instructions ou sa sortie. Voir <link>Notifications → Catalogue des événements</link>."
},
"pveWebhook": {
"heading": "Webhook natif Proxmox VE (entrant)",
"intro1": "Le système de notifications date de PVE 8.1 ; les cibles webhook natives exigent Proxmox VE 8.3 ou plus. <em>Activer les notifications</em> dans Paramètres tente d’enregistrer le Monitor comme cible. Les avis PVE qui y sont acheminés, comme les rapports de sauvegarde ou réplication, rejoignent son circuit d’envoi. La configuration doit être disponible et accessible en écriture.",
"intro2": "Le fonctionnement, le modèle envoyé par PVE, les entrées dans <code>/etc/pve/notifications.cfg</code> et le comportement en cluster figurent dans <link>Notifications → Intégration du webhook PVE</link>."
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Référence de l’API",
"href": "/docs/monitor/api",
"tail": " — points d’accès avec méthode, chemin et catalogue complet des métriques Prometheus."
},
{
"label": "Notifications",
"href": "/docs/monitor/notifications",
"tail": " — sources d’événements, canaux, circuit d’envoi et intégration du webhook PVE."
},
{
"label": "Assistant IA",
"href": "/docs/monitor/ai-assistant",
"tail": " — reformulation facultative des modèles en langage clair avant l’envoi vers Telegram, Discord, e-mail ou Gotify."
},
{
"label": "Accès et authentification",
"href": "/docs/monitor/access-auth",
"tail": " — création et révocation des jetons API de ces exemples, journal d’audit et configuration TLS."
}
]
}
}
@@ -0,0 +1,535 @@
{
"meta": {
"title": "Notifications Proxmox — Telegram, Discord, courrier électronique, Gotify, Pushover, Apprise | ProxMenux Monitor",
"description": "Envoyez les notifications Proxmox VE vers Telegram, Discord, e-mail, Gotify, Pushover et environ 80 services via Apprise. Les événements du Health Monitor, des journaux et du webhook PVE deviennent des messages avec déduplication, délai de répétition, regroupement, IA facultative et historique.",
"ogTitle": "Notifications Proxmox — Telegram, Discord, courriel, Gotify, Pushover, Apprise",
"ogDescription": "Alertes Proxmox vers Telegram, Discord, e-mail, Gotify, Pushover et environ 80 services via Apprise, avec déduplication, délais de répétition, regroupement et IA facultative.",
"twitterTitle": "Notifications Proxmox | ProxMenux Monitor",
"twitterDescription": "Envoyer des alertes Proxmox VE à Telegram, Discord, Courriel, Gotify, Pushover et ~80 services supplémentaires via Apprise."
},
"header": {
"title": "Notifications",
"description": "Distribue les événements du Monitor vers Telegram, Discord, e-mail, Gotify, Pushover et environ 80 services via Apprise. Déduplication, délais de répétition, regroupement, filtres par événement/canal, IA facultative et historique consultable.",
"section": "Moniteur ProxMenux"
},
"intro": {
"title": "D'où viennent les messages",
"body": "Les notifications distribuent les événements des sources du Monitor : <link>Health Monitor</link>, surveillance du journal et des tâches, webhook PVE, interrogations périodiques et appels internes des scripts ProxMenux. Tous suivent le même traitement avant livraison au téléphone ou par e-mail."
},
"howItWorks": {
"heading": "Comment ça marche",
"intro": "Les collecteurs produisent des événements structurés. Le traitement décide de leur envoi et de leur présentation, l’IA peut les réécrire, puis ils sont distribués aux canaux configurés.",
"arrowLabel": "événement",
"caption": "Vue générale. Les tentatives d’envoi réussies, regroupées ou échouées sont enregistrées dans SQLite. Les événements supprimés par le délai de répétition ne sont pas enregistrés.",
"nodes": {
"sourcesLabel": "Sources",
"sourcesDetail": "Health Monitor\nSurveillance du journal\nSurveillance des tâches\nWebhook PVE\nInterrogations périodiques\nSources internes",
"dispatchLabel": "Traitement de l’envoi",
"dispatchDetail": "Regroupement des rafales\nVérification empreinte / délai\nLimites par groupe\nContrôles par canal",
"aiLabel": "Réécriture par IA (facultatif)",
"aiDetail": "OpenAI / Anthropic\nGemini / Groq\nOpenRouter / Ollama\n(désactivé par défaut)",
"channelsLabel": "Canaux",
"channelsDetail": "Telegram\nDiscord\nCourriel (SMTP)\nGotify\nPushover\nApprise (~80 services)"
}
},
"enabling": {
"heading": "Activer le panneau",
"intro": "Après installation, la carte affiche <em>Désactivé</em> et <em>Activer les notifications</em>. Avant ce clic, rien n’est envoyé et la configuration PVE n’est pas modifiée.",
"disabledAlt": "Carte initiale avec statut Désactivé et bouton Activer les notifications",
"disabledCaption": "Le premier état — un clic pour activer.",
"stepsIntro": "Le bouton effectue trois actions successives :",
"steps": [
"Passe à l’état <em>Actif</em> et affiche le formulaire des canaux.",
"Enregistre une cible webhook dans <code>/etc/pve/notifications.cfg</code>. Sans HTTPS, elle utilise <code>POST http://127.0.0.1:8008/api/notifications/webhook</code> ; avec HTTPS, le récepteur HTTP local du port 8009. Les notifications PVE entrent dans le traitement du Monitor. Voir <pvelink>Intégration webhook PVE</pvelink>.",
"Lance le thread d’envoi en arrière-plan, qui consulte la file et traite chaque événement."
],
"activeAlt": "Carte active avec onglets des canaux, nom d’affichage et options avancées d’IA repliables",
"activeCaption": "État actif : canaux Telegram / Gotify / Discord / e-mail / Pushover / Apprise, nom d’affichage, catégories par canal et section <em>Avancé : amélioration par IA</em>."
},
"sources": {
"heading": "Sources des événements",
"intro": "Six types de sources alimentent le moteur : collecteurs en arrière-plan, récepteur webhook et sources internes. Ils produisent des objets structurés <code>NotificationEvent</code>.",
"headerCollector": "Collecteur",
"headerWatches": "Surveille",
"headerEvents": "Événements typiques",
"rows": [
{
"collector": "Moniteur de santé",
"watches": "Dix catégories, toutes les 5 minutes",
"events": "<code>new_error</code>, <code>error_resolved</code>, <code>error_escalated</code>, <code>health_degraded</code>, <code>health_persistent</code>."
},
{
"collector": "Surveillance du journal système",
"watches": "<code>journalctl --follow</code> avec motifs pour les échecs SSH/web, blocages Fail2Ban si la jail est installée, erreurs d’E/S du noyau, OOM et événements smartd.",
"events": "<code>auth_fail</code>, <code>ip_block</code>, <code>oom_kill</code>, <code>disk_io_error</code>, <code>service_fail</code>."
},
{
"collector": "Surveillance des tâches",
"watches": "Consulte <code>/var/log/pve/tasks/index</code> pour trouver les nouveaux UPID et suivre leurs fichiers journaux.",
"events": "<code>backup_start</code>, <code>backup_complete</code>, <code>backup_warning</code>, <code>backup_fail</code>, <code>migration_*</code>, <code>snapshot_complete</code>."
},
{
"collector": "Récepteur webhook Proxmox",
"watches": "Reçoit <code>POST /api/notifications/webhook</code>. Les versions PVE compatibles avec les cibles webhook peuvent y transmettre leurs notifications après configuration ; voir <pvelink>ci-dessous</pvelink>.",
"events": "Tout ce que PVE émet — y compris les événements que le moniteur manquerait autrement (HA, réplication, vzdump de l'interface graphique)."
},
{
"collector": "Collecteur par interrogation périodique",
"watches": "Compare régulièrement les nœuds du cluster, l’expiration des certificats, le passthrough GPU et les mises à jour PVE/ProxMenux.",
"events": "<code>node_disconnect</code>, <code>node_reconnect</code>, <code>pve_update</code>, <code>proxmenux_update</code>, <code>gpu_mode_switch</code>, <code>pci_passthrough_conflict</code>."
},
{
"collector": "Sources internes au processus",
"watches": "Appels directs des scripts ProxMenux et du Monitor (<code>notification_manager.emit_event(...)</code>).",
"events": "<code>system_startup</code>, <code>system_shutdown</code>, <code>system_reboot</code>, <code>ai_model_migrated</code>, événements de test personnalisés."
}
],
"after1": "Chaque événement porte un <code>event_type</code> stable (le catalogue est ci-dessous), un <code>severity</code> (<code>INFO</code>, <code>WARNING</code>, <code>CRITICAL</code>), un <code>category</code> (utilisé pour l'enrichissement émoji et les filtres par groupe) et une charge utile <code>data</code> avec tout ce dont le modèle a besoin (<code>vmid</code>, <code>device</code>, <code>source_ip</code>, <code>reason</code>...).",
"after2": "Chaque <code>event_type</code> utilise un modèle de <code>notification_templates.py</code> pour produire le texte. Ce texte suit le traitement d’envoi et peut être réécrit par l’IA. La page <ailink>Assistant IA</ailink> décrit cette interaction."
},
"channels": {
"heading": "Configurer les canaux",
"intro": "Six canaux : Telegram, Discord, Gotify, e-mail SMTP, Pushover et Apprise. Les cinq premiers ont leurs champs dédiés. Apprise ajoute environ 80 services via une URL, notamment ntfy, Matrix, Slack, Teams, Pushbullet, AWS SNS et Mattermost. Configuration ci-dessous.",
"credsTitle": "Stockage des identifiants",
"credsBody": "Les jetons, les clés, les URL webhook et les mots de passe SMTP sont stockés localement dans la base de données SQLite de Monitor sous <code>/usr/local/share/proxmenux/</code>. Les valeurs sensibles sont protégées et masquées dans l'interface. Ils ne quittent jamais l'hôte que pour atteindre leurs services respectifs. Une sauvegarde de ce répertoire suffit pour récupérer les canaux configurés."
},
"telegram": {
"heading": "Telegram",
"intro": "Il faut un <strong>jeton de bot</strong>, réutilisable entre conversations, et un <strong>ID de conversation</strong> pour la destination privée, le groupe ou le sujet de supergroupe. Le guide intégré détaille la configuration ; les deux formes d’ID sont expliquées ici.",
"guideAlt": "Guide Telegram en quatre sections : BotFather, jeton, ID de conversation, groupes et canaux",
"guideCaption": "Le lien <em>+ guide de configuration</em> ouvre quatre étapes pour créer le bot et configurer le canal en environ deux minutes.",
"step1Title": "1 · Créer un robot avec BotFather",
"step1Items": [
"Ouvrez Telegram et contactez <a>@BotFather</a> avec la coche bleue de vérification ; attention aux copies.",
"Envoyer <code>/newbot</code>.",
"Choisissez un nom d'affichage (p. ex. <em>ProxMenux Lab</em>). Il peut être changé plus tard.",
"Choisissez un nom d'utilisateur se terminant par <code>bot</code> (p. ex. <em>proxmenux_lab_bot</em>). Il doit être unique à travers Telegram.",
"BotFather fournit un jeton tel que <code>123456789:ABCdef…</code>. Il s’agit du jeton de bot : protégez-le comme un mot de passe."
],
"step2Title": "2 · Obtenir l'identifiant de discussion",
"step2Intro": "L’ID indique <em>où</em> le bot publie. Sa forme dépend de la destination.",
"privateLabel": "Chat privé (vous recevez les alertes pour votre propre compte):",
"privateItems": [
"Démarrez une conversation avec votre nouveau robot et envoyez tout message (par exemple : <code>/start</code>).",
"Ouvrez une conversation avec <a1>@userinfobot</a1> (ou <a2>@myidbot</a2>) et envoyez <code>/start</code>. Il répond avec votre ID d'utilisateur numérique — c'est-à-dire l'ID de chat. C'est un nombre positif."
],
"privateAlt": "Formulaire de canal Telegram rempli de jeton Bot (masqué), code de discussion positif pour un chat privé et un champ d'identification du sujet en option vide",
"privateCaption": "Chat privé avec le bot — Chat ID est un nombre positif (votre identifiant utilisateur personnel).",
"groupLabel": "Groupe ou supergroupe avec des sujets:",
"groupItems": [
"Ajouter le bot au groupe en tant que membre (et le rendre administrateur si le groupe l'exige pour poster).",
"Envoyez tout message dans le groupe.",
"Ouvrez <code>https://api.telegram.org/bot&lt;YOUR_TOKEN&gt;/getUpdates</code> dans un navigateur. Recherchez le <code>chat.id</code> dans la réponse JSON — pour les groupes, c'est un nombre négatif, pour les supergroupes, il commence par <code>-100</code>.",
"Pour un supergroupe avec <em>Sujets</em>, relevez le <code>message_thread_id</code> voulu et placez-le dans le champ facultatif <em>ID du sujet</em>."
],
"groupAlt": "Formulaire Telegram avec jeton masqué, ID négatif commençant par -100 pour un supergroupe et ID de sujet 3",
"groupCaption": "Supergroupe — Chat ID commence par <code>-100…</code> et l'option <em>Topic ID</em> cible un thread spécifique.",
"step3Title": "3 · Enregistrer et tester",
"step3Body": "Collez jeton et ID, enregistrez, puis <em>Envoyer un test</em>. Le message devrait arriver en une seconde. Sinon, l’Historique indique la cause : jeton invalide, bot absent du groupe ou bloqué par l’utilisateur."
},
"discord": {
"heading": "Discord",
"intro": "Discord reçoit les messages via une <em>URL de webhook</em> associée au canal. Monitor a besoin de cette URL.",
"items": [
"Dans Discord, ouvrez <em>Paramètres du serveur → Intégrations → Webhooks</em>.",
"Choisissez <em>Nouveau webhook</em>, nommez-le par exemple <em>ProxMenux</em> et choisissez le canal. L’avatar est facultatif.",
"Choisissez <em>Copier l’URL du webhook</em>. Format : <code>https://discord.com/api/webhooks/&lt;id&gt;/&lt;token&gt;</code>.",
"Coller dans le champ URL Webhook de l'onglet Discord dans le panneau Notifications et enregistrer."
],
"imageAlt": "Formulaire de canal Discord avec champ URL Webhook commençant par https://discord.com/api/webhooks/",
"imageCaption": "Discord : collez l’URL obtenue dans <em>Paramètres du serveur → Intégrations → Webhooks</em>."
},
"gotify": {
"heading": "Gotify",
"intro": "Gotify est un serveur de notifications auto-hébergé. Il faut son URL de base et un <em>jeton d’application</em> créé dans son administration.",
"items": [
"Si nécessaire, installez Gotify selon le <a>guide officiel d’installation</a>.",
"Connectez-vous comme administrateur et ouvrez <em>Applications</em> → <em>Créer une application</em>. Nommez-la par exemple <em>ProxMenux</em> et copiez le jeton.",
"Dans Gotify, définissez <em>URL du serveur</em>, par exemple <code>https://gotify.example.com</code>, et collez le jeton.",
"Enregistrez et choisissez <em>Envoyer un test</em>."
],
"imageAlt": "Formulaire Gotify avec URL https://gotify.example.com et champ de jeton avec exemple A_valid_gotify_token",
"imageCaption": "Gotify — URL du serveur de votre instance auto-installée plus le token App de l'interface utilisateur d'administration Gotify."
},
"email": {
"heading": "E-mail (SMTP)",
"intro": "L’e-mail nécessite serveur SMTP, port, mode TLS, identifiant et mot de passe facultatifs, adresse d’envoi et au moins un destinataire.",
"imageAlt": "Formulaire SMTP : serveur, port, TLS, identifiant, mot de passe, expéditeur, destinataires séparés par des virgules et préfixe d’objet",
"imageCaption": "SMTP : serveur, port, TLS, identifiant et mot de passe facultatifs, expéditeur, destinataires et préfixe d’objet pour le filtrage.",
"appNote": "Monitor utilise SMTP avec mot de passe. Gmail peut demander un <strong>mot de passe d’application</strong>. Chez Microsoft, cela dépend du service et des règles du tenant ; un tel mot de passe ne contourne pas l’interdiction de l’authentification de base. Vérifiez la compatibilité du service.",
"gmailTitle": "Mot de passe de l'application Gmail",
"gmailIntro": "Gmail exige la <strong>validation en deux étapes</strong> pour créer un mot de passe d’application. Sinon, <em>Mots de passe d’application</em> n’est pas disponible.",
"gmailItems": [
"Ouvrez <a>myaccount.google.com/security</a> et activez la <em>validation en deux étapes</em>.",
"Allez sur <a>myaccount.google.com/apppasswords</a>.",
"Saisissez un nom comme <em>ProxMenux</em> et choisissez <em>Créer</em>. Copiez le mot de passe de 16 caractères.",
"Renseignez <em>Serveur</em> <code>smtp.gmail.com</code>, <em>Port</em> <code>587</code>, <em>Mode TLS</em> <code>STARTTLS</code>, <em>Identifiant</em> votre adresse Gmail et <em>Mot de passe</em> celui d’application de 16 caractères."
],
"outlookTitle": "Mot de passe de l'application Microsoft / Outlook",
"outlookIntro": "Les mots de passe d’application Microsoft exigent la <strong>vérification en deux étapes</strong>, sans garantir la compatibilité SMTP. Si le service ou tenant exige OAuth2, le client SMTP du Monitor ne peut pas s’authentifier. Utilisez un relais adapté à cette authentification.",
"outlookItems": [
"Ouvrez <a>account.microsoft.com/security</a> et activez la vérification en deux étapes.",
"Si votre compte propose <em>Options de sécurité avancées</em> → <em>Mots de passe d’application</em>, choisissez <em>Créer un mot de passe d’application</em>. Cela ne garantit pas l’acceptation de SMTP avec mot de passe.",
"Si Microsoft crée ce mot de passe, copiez-le et vérifiez son acceptation par le service SMTP.",
"Uniquement si SMTP avec mot de passe est autorisé, utilisez les paramètres approuvés : <em>Serveur</em> <code>smtp.office365.com</code> pour Exchange Online, <em>Port</em> <code>587</code>, <em>Mode TLS</em> <code>STARTTLS</code>, <em>Identifiant</em> votre adresse et <em>Mot de passe</em> la valeur autorisée. Outlook.com personnel a d’autres paramètres et exigences."
],
"relayTitle": "Relais SMTP auto-hébergé",
"relayBody": "Dirigez Monitor vers un relais SMTP contrôlé, par exemple Postfix. Le relais gère l’authentification du fournisseur. Configurez authentification et TLS selon le relais ; son caractère local ne désactive pas le chiffrement."
},
"pushover": {
"heading": "Pushover",
"intro": "Pushover est un service de push mobile avec des applications officielles pour iOS, Android et les navigateurs de bureau. Le canal ProxMenux dédié parle directement au <a>Pushover API</a>, donc aucune URL Apprise n'est requise.",
"stepsTitle": "Configuration",
"steps": [
"Créer un compte <a>Pushover</a>, installer l'application officielle sur les appareils qui devraient recevoir des alertes et se connecter.",
"Copiez la <em>clé utilisateur</em> du tableau de bord Pushover. Une clé de groupe permet de servir plusieurs personnes ou appareils.",
"Ouvrez <a>Créer une application/un jeton API</a>, créez <em>ProxMenux</em> et copiez son jeton API de 30 caractères.",
"Dans <em>Paramètres → Notifications → Pushover</em>, collez la clé utilisateur ou de groupe et le jeton de l'application API. Les champs périphériques et sonores sont optionnels.",
"Enregistrer les paramètres et appuyez sur <em>Envoyer test</em>. L'application Pushover devrait recevoir le message immédiatement."
],
"priorityTitle": "Correspondance des priorités",
"priorityBody": "Les messages ordinaires utilisent la priorité 0. Avec <strong>Priorité haute pour les alertes critiques</strong>, les événements CRITICAL utilisent la priorité 1 et contournent les heures de silence Pushover. La priorité d’urgence 2 avec répétition et accusé de réception n’est pas utilisée.",
"secretTitle": "Protéger les deux valeurs",
"secretBody": "Clé utilisateur ou groupe et jeton API autorisent l’envoi. Monitor les protège et les masque dans l’interface. Ne publiez aucune des deux valeurs dans les captures ou journaux de support."
},
"apprise": {
"heading": "Apprise (hub générique pour les services ~80)",
"intro": "Apprise gère environ 80 services via des URL : ntfy, Matrix, Slack, Microsoft Teams, Mattermost, Pushbullet, AWS SNS, Pushsafer, Rocket.Chat, Signal API et d’autres, sans intégration dédiée dans Monitor. Pushover est aussi possible ; son propre onglet reste plus simple pour une destination unique.",
"listIntro": "La liste complète des services pris en charge et le format exact d'URL pour chacun d'eux sont disponibles dans la documentation officielle Apprise:",
"listItems": [
"<a>Documentation des services Apprise</a> — index complet.",
"<a>Principes des URL</a> — structure des URL Apprise."
],
"stepsTitle": "Étapes",
"steps": [
"Choisissez le service cible dans le wiki <a>Apprise</a> et copiez le modèle d'URL. Chaque page de service affiche le schéma exact à utiliser (<code>ntfy://</code>, <code>matrix://</code>, <code>pover://</code>, <code>slack://</code>...) plus les jetons, canaux ou noms d'hôte requis.",
"Remplacez les paramètres par vos identifiants. Exemples : ntfy.sh <code>ntfy://ntfy.sh/my-topic</code>, Pushover <code>pover://user@token</code>, Matrix <code>matrix://user:pass@host:port/#room</code>.",
"Coller l'URL finale dans le champ <em>Apprise URL</em> dans l'onglet Apprise du panneau Notifications et enregistrer.",
"Appuyez sur <em>Envoyer Test</em> pour vérifier que l'URL est accessible et que les identifiants sont acceptés."
],
"deliveredTitle": "Ce qui est livré",
"deliveredBody": "Apprise reçoit titre, texte et gravité, adaptée aux possibilités du service (icône, priorité, couleur). Le formatage et l’IA s’exécutent avant l’envoi, comme pour Telegram ou l’e-mail.",
"fanoutTitle": "Une URL par canal Apprise",
"fanoutBody": "Un champ URL par canal Apprise. Pour plusieurs services, tels ntfy.sh et Matrix, hébergez un <a>serveur API Apprise</a> avec configuration étiquetée. Il distribue l’appel du Monitor aux URL de l’étiquette."
},
"rich": {
"heading": "Messages riches, catégories et filtrage par canal",
"intro": "Trois contrôles par canal : <em>Messages enrichis</em>, onze <em>Catégories de notification</em> repliables avec interrupteurs d’événements, puis <em>Envoyer un test</em>.",
"imageAlt": "Catégories avec Messages enrichis en haut, sections VM/CT, sauvegardes, ressources, stockage, réseau, sécurité, cluster, services, santé et mises à jour, compteurs et bouton de test",
"imageCaption": "La flèche indique <em>Messages enrichis</em>. Dessous : onze catégories et leurs événements. <em>Envoyer un test</em> est en bas.",
"richTitle": "Messages enrichis",
"richIntro": "Avec <em>Messages enrichis</em>, chaque événement reçoit un emoji de catégorie et le format natif du canal, tel HTML Telegram ou carte Discord colorée. Sans cela, le même contenu part en texte simple :",
"plainHeader": "Texte simple — format enrichi désactivé",
"richHeader": "Texte enrichi — format activé",
"richOutro": "Réglage indépendant par canal : e-mail simple, Telegram et Discord enrichis, par exemple. Les canaux sans ce format, comme l’e-mail simple ou Gotify, reçoivent du texte.",
"togglesTitle": "Catégories par événement",
"togglesIntro": "Chaque canal contrôle séparément ses catégories et événements. Une catégorie désactivée supprime ses événements pour ce canal. Les réglages individuels s’appliquent aux catégories actives ; aucun interrupteur global d’événement n’existe dans le répartiteur.",
"togglesItems": [
"<strong>Contrôle de catégorie par canal.</strong> Désactiver VM/CT supprime <code>vm_start</code> et ses équivalents. Stockage : <code>&lt;channel&gt;.events.&lt;group&gt;</code>.",
"<strong>Contrôle d’événement par canal.</strong> Dans une catégorie active, choisissez par exemple <em>envoyer <code>backup_complete</code> à Discord, pas à Telegram</em>. Stockage : <code>&lt;channel&gt;.event.&lt;event_type&gt;</code>."
],
"togglesOutro": "Chaque catégorie affiche <em>activés</em> / <em>total</em> et un interrupteur pour tout le groupe, tel les sauvegardes <code>info</code> ou mises à jour, sans l’ouvrir."
},
"quiet": {
"heading": "Heures de silence",
"intro": "Pendant ce créneau propre au canal, seuls les événements <strong>CRITICAL</strong> passent. INFO, WARNING et actions sont conservés sur disque puis livrés dans un résumé à la fin.",
"imageAlt": "Réglages du canal : heures de silence 22:00–07:00 et aperçu du prochain changement, puis résumé quotidien à 09:00 avec note indiquant que ce résumé ne retarde ni CRITICAL ni WARNING",
"imageCaption": "Deux réglages indépendants par canal : heures de silence en haut, résumé quotidien dessous.",
"purposeTitle": "C'est pour quoi ?",
"purposeItems": [
"<strong>Pas d’avis de mise à jour à 03:00.</strong> Sauvegardes, mises à jour, optimisations et autres INFO ne font pas sonner le téléphone la nuit.",
"<strong>Les événements critiques restent immédiats.</strong> Seuls ceux classés CRITICAL contournent le silence. Le nom ne fixe pas la gravité : la surveillance du journal émet les blocages Fail2Ban et les arrêts/redémarrages de l’hôte en INFO, donc ils peuvent attendre.",
"<strong>Conserver les avis différés.</strong> Ils restent dans un tampon SQLite jusqu’à la fin du créneau."
],
"howTitle": "Comment ça marche",
"howItems": [
"<strong>Réglage par canal.</strong> Telegram peut rester silencieux de 22:00 à 07:00 tandis que l’e-mail reçoit tout, jour et nuit.",
"<strong>Début et fin</strong> dans le fuseau local : début inclus, fin exclue. Le créneau peut traverser minuit, par exemple 22:00–07:00.",
"<strong>Aperçu immédiat.</strong> Sous les champs apparaissent l’état actif et l’heure du prochain changement.",
"<strong>Pendant le créneau :</strong> CRITICAL suit l’envoi normal ; INFO et WARNING sont stockés dans la table SQLite <code>quiet_pending</code>.",
"<strong>À la fin :</strong> un résumé chronologique est envoyé, une ligne par événement. Le tampon n’est vidé qu’après confirmation de livraison, afin de résister aux pannes temporaires Telegram ou SMTP.",
"<strong>Résiste aux redémarrages.</strong> Le tampon reste sur disque. Le cycle suivant détecte les lignes en attente et envoie au besoin un résumé de récupération."
],
"criticalTitle": "Ce qui compte comme CRITIQUE",
"criticalBody": "Le producteur fixe la gravité à la création. Un événement de disque, arrêt ou sécurité n’est pas automatiquement CRITICAL. La surveillance du journal émet ip_block, system_shutdown et system_reboot en INFO. Le <link>Catalogue des événements</link> énumère les types ; consultez le producteur et l’événement reçu pour sa gravité réelle."
},
"digest": {
"heading": "Résumé quotidien des événements INFO",
"intro1": "Le résumé quotidien est <strong>facultatif</strong> : il rassemble les INFO admissibles, comme les mises à jour, à 09:00 ou à l’heure choisie. Résultats de sauvegarde/réplication et actions directes sont exclus. Les heures de silence diffèrent : elles retardent les messages non critiques durant un créneau.",
"intro2": "Le réglage est sous les heures de silence, dans la même carte ; voir <link>Heures de silence</link>. Chacun s’active séparément.",
"purposeTitle": "C'est pour quoi ?",
"purposeItems": [
"<strong>Un bilan matinal.</strong> Un résumé à 09:00 rassemble les informations de 20 messages de la veille, sans lire 20 bulles Telegram.",
"<strong>Distinguer activité et urgence.</strong> INFO décrit les faits ; CRITICAL et WARNING appellent une action. Les INFO admissibles sont regroupés, les autres gardent leur livraison directe."
],
"howTitle": "Comment ça marche",
"howItems": [
"<strong>Activation par canal.</strong> Désactivé par défaut. Activez-le seulement là où vous voulez un résumé ; les autres canaux restent en direct.",
"<strong>Heure de livraison</strong> locale, 09:00 par défaut. L’envoi se déclenche à environ 60 s près.",
"<strong>Inclus :</strong> événements génériques admissibles de niveau <strong>INFO</strong>, comme <em>mise à jour d’application disponible</em>, <em>mise à jour Tailscale disponible</em>, <em>mise à jour d’optimisation ProxMenux disponible</em>, <em>mises à jour de sécurité APT en attente</em> et <em>avis de limitation d’envoi</em>. Résultats de sauvegarde et actions exemptées restent en direct.",
"<strong>Ce qui n'est jamais retardé:</strong>",
"<strong>Persistance.</strong> Les événements restent dans SQLite, table <code>digest_pending</code>, jusqu’à l’heure prévue, même après redémarrage.",
"<strong>Sans événement, sans résumé.</strong> Aucun résumé vide n’est envoyé si aucun INFO n’attend."
],
"neverDelayedSub": [
"Les événements <strong>CRITICAL</strong> passent toujours immédiatement.",
"Les événements <strong>WARNING</strong> passent toujours immédiatement.",
"Les actions et échecs VM/CT, débuts et résultats de sauvegarde, résultats de réplication et arrêts/redémarrages de l’hôte contournent le résumé même en INFO. Le silence peut encore retarder les événements non critiques."
],
"comboTitle": "Combiner les heures tranquilles et le digest quotidien",
"comboBody": "Un canal peut activer <em>les deux</em> : silence 22:00–07:00 et résumé à 09:00. Les événements non critiques du créneau arrivent au résumé de07:00 ; les INFO admissibles hors créneau vont au résumé quotidien. CRITICAL contourne les deux ; WARNING contourne le quotidien mais attend pendant le silence. Choisissez un <em>créneau silencieux</em>, un <em>résumé à heure fixe</em>, ou les deux."
},
"displayName": {
"heading": "Nom d’affichage",
"intro": "Chaque avis porte un <em>nom d’affichage</em> identifiant l’hôte, tel <code>🏠 home-lab</code> au bas de l’exemple et dans le préfixe d’objet.",
"imageAlt": "Champ Nom d’affichage avec exemple amd ; un champ vide utilise le nom d’hôte système",
"imageCaption": "Laissez le nom vide pour utiliser celui du système ou saisissez un nom personnalisé.",
"outro": "Si le champ est vide, le moniteur revient au nom d'hôte du système. La redéfinition est surtout utile lorsque vous exécutez plusieurs hôtes ProxMenux qui envoient à la même discussion ou boîte de réception Telegram, une étiquette plus conviviale (<em>home-lab</em>, <em>office-pve</em>) est plus facile à lire que <code>pve01.lan</code> ou <code>pmx-prod-01</code>."
},
"dispatch": {
"heading": "Traitement de l’envoi",
"intro": "Trois mécanismes liés sont décrits ci-dessous. L’ordre réel est regroupement, réservation/vérification du délai, limite par groupe, rendu puis contrôles de livraison par canal :",
"headerStage": "Étape",
"headerWhat": "Ce qu'il fait",
"headerTunable": "Réglable ?",
"rows": [
{
"stage": "Déduplication par empreinte",
"what": "Une empreinte est calculée pour chaque événement (<code>event_type + key fields from data</code>). Les empreintes identiques sur un intervalle court sont considérées comme des doublons.",
"tunable": "Non — logique du répartiteur interne."
},
{
"stage": "Délai de répétition",
"what": "Après livraison réussie, les répétitions sont supprimées ; l’état est dans <code>notification_last_sent</code>. Base pour <code>CRITICAL</code>, <code>WARNING</code>, <code>INFO</code>, <code>resources</code> et <code>updates</code> : 86400 s. Exceptions : 5 s pour actions VM/CT et arrêt/redémarrage, 10 s pour résultats sauvegarde/réplication, 1800–3600 s pour plusieurs états de santé. Les réglages explicites d’événement/groupe prévalent.",
"tunable": "Oui : des valeurs explicites par événement ou groupe remplacent les valeurs du répartiteur."
},
{
"stage": "Regroupement des rafales",
"what": "Une rafale d’événements semblables, comme des tentatives SSH, devient un message <code>burst_*</code> avec compteur et échantillon.",
"tunable": "Non — la fenêtre et le seuil sont codés en dur par type d'événement."
}
],
"calloutTitle": "Envoi dans un thread en arrière-plan",
"calloutBody": "La requête HTTP se termine à la mise en file ; le thread attend les réponses Telegram, SMTP ou webhook et inscrit les résultats dans l’historique."
},
"aiRewrite": {
"heading": "Réécriture optionnelle de l'IA",
"body1": "Les événements admissibles peuvent être réécrits par un LLM. backup_complete et backup_fail sont exclus. L’IA est désactivée par défaut et s’exécute dans le thread d’envoi. En cas d’erreur ou délai dépassé, le texte du modèle est utilisé.",
"body2": "OpenAI, Anthropic, Google Gemini, Groq, OpenRouter et Ollama local sont disponibles. Par canal : détail (<code>brief</code>, <code>standard</code>, <code>detailed</code>), langue, mode d’instructions (<code>default</code> ou <code>custom</code>) et instructions propres. Guide et exemples : <link>Assistant IA</link>.",
"privacyTitle": "Note de confidentialité",
"privacyBody": "La requête IA peut inclure titre, gravité, texte, instructions système/personnelles et contexte : noms d’hôte, IP, utilisateurs, erreurs et journaux. Elle part vers le serveur choisi. Ollama reste local seulement avec serveur et modèle locaux ; serveur distant ou modèle cloud transmettent les données hors de l’hôte. Désactivez l’IA ou utilisez serveur et modèle locaux contrôlés si le contenu doit rester dans le réseau."
},
"pveWebhook": {
"heading": "Intégration PVE webhook",
"intro1": "Proxmox utilise des <em>cibles de notification</em> sendmail, Gotify, SMTP et, sur les versions compatibles, webhook. Monitor enregistre une cible <code>webhook</code>. Les avis PVE, tels HA, réplication et sauvegardes de l’interface, rejoignent le même traitement.",
"intro2": "La cible est visible à partir du GUI Proxmox à <em>Datacenter → Notifications → Objectifs de notification</em> :",
"imageAlt": "Proxmox VE Modifier la boîte de dialogue Webhook montrant la cible de proxmenux-webhook créée automatiquement avec la méthode POST, URL http://127.0.0.1:8008/api/notifications/webhook et un modèle de corps JSON utilisant le titre d'échappement, message d'échappement, gravité d'échappement, horodatage d'échappement et champs json",
"imageCaption": "La cible webhook côté PVE comme Proxmox la voit (l'interface graphique se trouve dans le local configuré de l'hôte — espagnol dans cet exemple). Les mêmes champs s'appliquent dans n'importe quelle langue.",
"registeredIntro": "Ce qui est enregistré:",
"registeredItems": [
"<strong>Méthode et URL.</strong> <code>POST http://127.0.0.1:8008/api/notifications/webhook</code> sans HTTPS Monitor ; avec HTTPS, récepteur HTTP local séparé sur 8009. Les deux restent sur l’hôte.",
"<strong>Modèle du corps.</strong> JSON avec aides Handlebars natives de PVE, stocké en base64 dans la configuration. Une fois décodé :",
"<strong>Matcher.</strong> Un bloc d'accompagnement <code>matcher: proxmenux-matcher</code> avec <code>mode all</code> afin que chaque notification PVE atteigne la cible.",
"<strong>Configuration privée.</strong> La configuration écrit <code>webhook: proxmenux-webhook</code> dans <code>/etc/pve/priv/notifications.cfg</code> avec le secret partagé en base64. La cible publique le référence pour envoyer X-Webhook-Secret. Le bloc n’est pas vide."
],
"securityTitle": "Comment le récepteur est sécurisé",
"securityIntro": "Le récepteur webhook de <code>POST /api/notifications/webhook</code> applique différentes couches de sécurité selon l'origine de la demande:",
"securityItems": [
"<strong>Sources locales (<code>127.0.0.1</code> / <code>::1</code>).</strong> Limitation du nombre de requêtes, sans contrôles distants du secret, de l’heure et des répétitions. Les adresses des interfaces de l’hôte sont aussi locales. La cible PVE automatique utilise loopback.",
"<strong>Appels distants.</strong> En plus des limites, contrôles du secret <code>X-Webhook-Secret</code>, de l’heure dans <code>X-ProxMenux-Timestamp</code> ou le JSON, des répétitions et d’une liste IP facultative. Le secret est dans SQLite et copié en base64 dans <code>/etc/pve/priv/notifications.cfg</code> pour l’en-tête PVE."
],
"practiceTitle": "En pratique",
"practiceBody": "PVE utilise <code>http://127.0.0.1:8008</code> sans HTTPS, sinon HTTP 8009. Les intégrations externes sur <code>https://&lt;monitor-host&gt;:&lt;port&gt;/api/notifications/webhook</code> doivent fournir <code>X-Webhook-Secret</code> et une heure actuelle, puis passer les contrôles de répétition et IP. Le secret seul ne suffit pas.",
"actionsIntro": "Le moniteur gère cette cible par trois actions sur l'onglet Paramètres :",
"actionsItems": [
"<strong>Configurer</strong> crée l’entrée dans <code>/etc/pve/notifications.cfg</code>. Seules les modifications sont écrites ; les trois sauvegardes récentes restent dans <code>/usr/local/share/proxmenux/backups/pve-notifications/</code>. Aucune écriture sans montage de <code>/etc/pve</code> ; la cible est inscrite au retour de <code>pve-cluster</code>.",
"<strong>Nettoyer</strong> retire l’entrée en gardant la sauvegarde précédente.",
"<strong>Lire la configuration</strong> affiche cibles et règles de correspondance pour vérifier les routes PVE."
],
"clusterTitle": "Nœuds du cluster",
"clusterBody": "<code>/etc/pve/</code>, URL et secret sont partagés dans le cluster. Chaque nœud appelle son <em>propre</em> récepteur : <code>127.0.0.1:8008</code> sans HTTPS, sinon HTTP 8009. Exécutez Monitor sur les nœuds concernés et assurez la cohérence de la cible avec chaque récepteur."
},
"catalogue": {
"heading": "Catalogue des événements",
"intro": "Environ 70 types sont regroupés en onze catégories repliables. Chaque événement possède un interrupteur et est activé par défaut, sauf indication contraire.",
"headerGroup": "Groupe",
"headerEvents": "Événements",
"rows": [
{
"group": "VM/CT",
"events": "<code>vm_start</code>, <code>vm_start_warning</code>, <code>vm_stop</code>, <code>vm_shutdown</code>, <code>vm_fail</code>, <code>vm_restart</code>, plus les équivalents <code>ct_*</code>, <code>migration_start</code>, <code>migration_complete</code>, <code>migration_warning</code>, <code>migration_fail</code>, <code>replication_complete</code>, <code>replication_fail</code>."
},
{
"group": "Sauvegardes",
"events": "<code>backup_start</code>, <code>backup_complete</code>, <code>backup_warning</code>, <code>backup_fail</code>, <code>snapshot_complete</code>, <code>snapshot_fail</code>."
},
{
"group": "Ressources",
"events": "<code>cpu_high</code>, <code>ram_high</code>, <code>temp_high</code>, <code>load_high</code>."
},
{
"group": "Stockage",
"events": "<code>disk_space_low</code>, <code>disk_io_error</code>, <code>storage_unavailable</code>, <code>smart_test_complete</code>, <code>smart_test_failed</code>."
},
{
"group": "Réseau",
"events": "<code>network_down</code>, <code>network_latency</code>."
},
{
"group": "Sécurité",
"events": "<code>auth_fail</code>, <code>ip_block</code>, <code>firewall_issue</code>, <code>user_permission_change</code>."
},
{
"group": "Cluster",
"events": "<code>split_brain</code>, <code>node_disconnect</code>, <code>node_reconnect</code>."
},
{
"group": "Services",
"events": "<code>system_startup</code>, <code>system_shutdown</code>, <code>system_reboot</code>, <code>system_problem</code>, <code>service_fail</code>, <code>oom_kill</code>, <code>system_mail</code>."
},
{
"group": "Moniteur de santé",
"events": "<code>new_error</code>, <code>error_resolved</code>, <code>error_escalated</code>, <code>health_degraded</code>, <code>health_persistent</code>, <code>health_issue_new</code>, <code>health_issue_resolved</code>."
},
{
"group": "Mises à jour",
"events": "<code>update_summary</code>, <code>update_available</code>, <code>pve_update</code>, <code>update_complete</code>, <code>proxmenux_update</code>."
},
{
"group": "Matériel / GPU",
"events": "<code>gpu_mode_switch</code>, <code>gpu_passthrough_blocked</code>, <code>pci_passthrough_conflict</code>, <code>ai_model_migrated</code>."
}
],
"burstNote": "Les types <code>burst_*</code> (<code>burst_auth_fail</code>, <code>burst_ip_block</code>, <code>burst_disk_io</code>, etc.) remplacent les rafales par un résumé. Sans interrupteur propre, ils héritent du réglage de l’événement source.",
"backupResults": {
"heading": "Résultats de sauvegarde",
"intro": "Le rapport du travail de sauvegarde fixe résultat, titre, icône avec <em>Messages enrichis</em> et ligne d’état de l’e-mail.",
"headerIcon": "Icon",
"headerResult": "Résultat",
"headerWhen": "Quand",
"rows": [
{
"icon": "💾✅",
"result": "Sauvegarde terminée",
"when": "Tous les invités ont terminé, sans avertissement dans le rapport."
},
{
"icon": "💾⚠️",
"result": "Sauvegarde terminée avec des avertissements",
"when": "Tous les invités ont terminé, avec au moins un avertissement."
},
{
"icon": "💾❌",
"result": "Erreur de sauvegarde signalée",
"when": "Un invité a échoué, ou le travail s'est arrêté avec une erreur."
},
{
"icon": "💾❔",
"result": "Résultat de sauvegarde non confirmé",
"when": "Le rapport est incomplet ou n'indique pas de résultat pour chaque invité."
}
],
"items": [
"<strong>Le titre identifie le travail.</strong> Il indique le stockage et, pour un invité unique, son type, nom et ID. En cas d’échec, l’invité concerné est nommé.",
"<strong>Le texte détaille chaque invité</strong> : résultat, taille, durée et archive, puis totaux du travail.",
"<strong>Les mises en garde et les erreurs sont listées une fois.</strong> Les lignes répétées sont montrées une seule fois avec la cause principale d'abord; après huit lignes, le reste est compté dans une ligne de fermeture et reste dans le journal des tâches Proxmox.",
"<strong>Un travail qui échoue avant son premier invité</strong> montre la cause donnée par Proxmox, par exemple un stockage qui n'existe pas.",
"<strong>Les résumés gardent le résultat.</strong> Une sauvegarde dans le résumé du silence garde son icône. Les résultats de sauvegarde contournent le résumé quotidien."
]
}
},
"history": {
"heading": "Historique",
"body1": "Chaque <em>tentative d’envoi</em> réelle est dans <code>notification_history</code> : date <code>sent_at</code>, canal, événement, gravité, titre, texte, <code>success</code> et, en cas d’échec, <code>error_message</code>. Les rafales ont un type <code>burst_*</code>. Les événements supprimés par le délai ne sont pas enregistrés.",
"body2": "Paramètres → Notifications contient <em>Historique des notifications</em>, fermé par défaut, avec les 20 dernières entrées : résultat, canal, date, erreur et état de chaque résumé quotidien. La page ne propose pas la suppression ; Audit & Report lit les mêmes livraisons.",
"body3": "Les mêmes données sont exposées aux paramètres de requête <code>GET /api/notifications/history</code> avec les paramètres de requête <code>limit</code>, <code>offset</code>, <code>severity</code> et <code>channel</code>, et peuvent être effacées avec <code>DELETE /api/notifications/history</code>."
},
"api": {
"heading": "Points d’accès API",
"headerEndpoint": "Point d’accès",
"headerMethod": "Méthode",
"headerUse": "Utiliser",
"rows": [
{
"endpoint": "/api/notifications/settings",
"method": "GET / POST",
"use": "Lit ou écrit la configuration : canaux, événements, IA et nom d’affichage."
},
{
"endpoint": "/api/notifications/test",
"method": "POST",
"use": "Envoyer une notification de test à un canal : <code>'{'\"channel\":\"telegram\"'}'</code>."
},
{
"endpoint": "/api/notifications/test-ai",
"method": "POST",
"use": "Produit et réécrit un événement de test sans l’envoyer."
},
{
"endpoint": "/api/notifications/provider-models",
"method": "POST",
"use": "Liste des modèles disponibles pour le fournisseur d'IA sélectionné."
},
{
"endpoint": "/api/notifications/send",
"method": "POST",
"use": "Émettre un événement de l'extérieur (intégrations personnalisées)."
},
{
"endpoint": "/api/notifications/history",
"method": "GET / DELETE",
"use": "Consulte l’historique avec filtres ou le supprime."
},
{
"endpoint": "/api/notifications/webhook",
"method": "POST",
"use": "Reçoit les avis Proxmox. Les sources locales évitent les contrôles distants mais gardent la limitation. Les requêtes distantes passent <code>X-Webhook-Secret</code>, l’heure dans <code>X-ProxMenux-Timestamp</code> ou JSON, les contrôles de répétition et la liste IP configurée."
},
{
"endpoint": "/api/notifications/proxmox/setup-webhook",
"method": "POST",
"use": "Enregistrer le moniteur comme cible dans <code>/etc/pve/notifications.cfg</code>."
},
{
"endpoint": "/api/notifications/proxmox/cleanup-webhook",
"method": "POST",
"use": "Supprimer la cible Monitor de la configuration de notification de PVE."
},
{
"endpoint": "/api/notifications/proxmox/read-cfg",
"method": "GET",
"use": "Affiche la configuration actuelle de la notification PVE comme PVE la voit."
}
]
},
"whereNext": {
"heading": "Où aller ensuite",
"items": [
{
"label": "Assistant AI",
"href": "/docs/monitor/ai-assistant",
"tail": " — fournisseurs, modèles, modes d’instructions, langues et détail par canal."
},
{
"label": "Moniteur de santé",
"href": "/docs/monitor/health-monitor",
"tail": "— le plus grand producteur d'événements, avec ses propres durées de suppression par catégorie."
},
{
"label": "Architecture",
"href": "/docs/monitor/architecture",
"tailRich": " — rôle des tables SQLite <code>notification_last_sent</code>, <code>notification_history</code> et du thread d’envoi dans Monitor."
},
{
"label": "Accès et authentification",
"href": "/docs/monitor/access-auth",
"tailRich": " — création des jetons API pour les scripts appelant <code>/api/notifications/send</code>."
},
{
"label": "Tableau de bord → Logs système",
"href": "/docs/monitor/dashboard/system-logs",
"tail": " — vue directe du journal système exploité par la surveillance des événements."
}
]
}
}