Merge remote-tracking branch 'origin/develop' into HEAD

This commit is contained in:
MacRimi
2026-10-18 18:20:11 +02:00
209 changed files with 43773 additions and 1937 deletions
@@ -110,7 +110,7 @@ class LynisThresholdContracts(unittest.TestCase):
_, module = extract_function(APP / 'scripts/health_monitor.py', '_check_memory_comprehensive', owner='HealthMonitor')
# The method is bound to an inert class, not the production constructor.
self_obj = SimpleNamespace(state_history=defaultdict(list), MEMORY_DURATION=300, SWAP_CRITICAL_DURATION=300,
MEMORY_WARNING=80, SWAP_HIGH_PERCENT=80, AVAILABLE_MIN_PERCENT=20)
MEMORY_WARNING=80, MEMORY_CRITICAL=90, SWAP_HIGH_PERCENT=80, AVAILABLE_MIN_PERCENT=20)
memory = SimpleNamespace(percent=50, available=10, total=100)
swap = SimpleNamespace(percent=90, used=90, total=100)
namespace = {'Dict': dict, 'Any': object, 'psutil': SimpleNamespace(virtual_memory=lambda: memory, swap_memory=lambda: swap),
@@ -643,11 +643,11 @@ labels:
{t.rich("audit.intro", { code })}
</p>
<CopyableCode
code={`# Failed login from 192.0.2.10 (real IP recovered from X-Forwarded-For)
2026-04-24 14:32:11 WARNING proxmenux.auth: authentication failure; rhost=192.0.2.10 user=admin
code={`# Failed login from 192.0.2.10 (forwarded IP only with PROXMENUX_TRUST_PROXY=1)
2026-04-24 14:32:11,000 proxmenux-auth: authentication failure; rhost=192.0.2.10 user=admin
# Successful login
2026-04-24 14:32:18 INFO proxmenux.auth: authentication success; rhost=192.0.2.10 user=admin`}
# Login rate limit reached
2026-04-24 14:32:18,000 proxmenux-auth: login rate limit exceeded; rhost=192.0.2.10 retry_after=240s`}
className="my-4"
/>
<p className="mb-6 text-gray-800 leading-relaxed">
@@ -580,7 +580,7 @@ template:
- binary_sensor:
- name: "ProxMenux Healthy"
default_entity_id: binary_sensor.proxmenux_is_healthy
device_class: problem
device_class: connectivity
delay_off: 30
state: "{{ states('sensor.proxmenux_health') == 'OK' }}"
- name: "ProxMenux Critical"
@@ -1070,8 +1070,8 @@ scrape_configs:
<h2 id="uptime-kuma" className="text-2xl font-semibold mt-10 mb-4 text-gray-900">
<a href={t("uptimeKuma.href")} target="_blank" rel="noopener noreferrer" className="text-blue-600 hover:underline inline-flex items-center gap-1">
Uptime Kuma<ExternalLink className="w-5 h-5" />
</a>{" "}and other status checkers
{t("uptimeKuma.heading")}<ExternalLink className="w-5 h-5" />
</a>
</h2>
<p className="mb-4 text-gray-800 leading-relaxed">
@@ -1087,12 +1087,12 @@ scrape_configs:
</ol>
<CopyableCode
code={`# Verify the response shape — no token required
curl http://pve01.lan:8008/api/system-info | jq
code={`# Verify the public system-info response shape
curl -fsS http://pve01.lan:8008/api/system-info | jq
# → { "hostname": "...", "uptime": "...", "health": { "status": "healthy", ... }, ... }
# A failing scriptable check (non-zero when the Monitor isn't reporting healthy)
curl -s http://pve01.lan:8008/api/system-info | jq -e '.health.status == "healthy"'`}
curl -fsS http://pve01.lan:8008/api/system-info | jq -e '.health.status == "healthy"'`}
className="my-4"
/>
@@ -1121,7 +1121,7 @@ curl -X POST http://proxmox.example.tld:8008/api/notifications/send \\
"event_type":"system_problem",
"severity":"WARNING",
"title":"Nightly rsync took 4h27m",
"body":"The nightly-rsync job exceeded the 2h alert threshold. Check the source storage.",
"message":"The nightly-rsync job exceeded the 2h alert threshold. Check the source storage.",
"data":{
"service_name":"nightly-rsync",
"hostname":"backup-host"
@@ -0,0 +1,396 @@
{
"meta": {
"title": "Proxmox-Dashboard-Authentifizierung — 2FA, API-Tokens, Benutzerprofil, Reverse-Proxy | ProxMenux Monitor",
"description": "Zugriff und Schutz für ProxMenux Monitor: Ersteinrichtung, Passwort mit Anzeigename und Avatar, Profilseite, TOTP-2FA, langlebige API-Tokens, HTTPS, Beispiele für Nginx/Caddy/Traefik, Audit-Protokoll und optionale Fail2Ban-Jail.",
"ogTitle": "Proxmox-Dashboard-Authentifizierung — 2FA, API-Tokens, Reverse-Proxy",
"ogDescription": "ProxMenux Monitor mit Passwort, TOTP-2FA, langlebigen API-Tokens, HTTPS, Reverse-Proxy-Beispielen und optionaler Fail2Ban-Jail schützen.",
"twitterTitle": "Proxmox Dashboard-Authentifizierung | ProxMenux Monitor",
"twitterDescription": "Passwort + TOTP 2FA, API Token, HTTPS, Nginx/Caddy/Traefik Snippets und Audit Log."
},
"header": {
"title": "Zugriff und Authentifizierung",
"description": "Dashboard-Zugriff, Ersteinrichtung und Schutzschichten: Passwort und TOTP, JWT-Sitzungen, langlebige API-Tokens, HTTPS, Reverse-Proxys, Secure Gateway und optionale Fail2Ban-Jail.",
"section": "ProxMenux-Monitor"
},
"intro": {
"title": "Authentifizierung ist optional",
"body": "Beim ersten Start zeigt das Dashboard den Dialog <em>„Dashboard schützen?“</em> mit den Schaltflächen <strong>Ja, Passwort einrichten</strong> und <strong>Nein, ohne Schutz fortfahren</strong>. Bei der zweiten Option bleiben die API-Endpunkte über TCP 8008 offen. Das kann für ein isoliertes Labor-LAN ausreichen, ist in anderen Umgebungen jedoch gefährlich. Die Zwei-Faktor-Authentifizierung (2FA) ist <strong>nicht</strong> Teil dieser ersten Auswahl; sie wird nach dem Einrichten eines Passworts unter <strong>Sicherheit</strong> konfiguriert."
},
"reaching": {
"heading": "Dashboard öffnen",
"intro": "ProxMenux Monitor lauscht auf <code>0.0.0.0:8008</code>. Drei übliche Zugriffswege:",
"outro": "Direktzugriff entspricht der Standard-systemd-Unit. Reverse-Proxy und Secure Gateway werden unten beschrieben. Das Vertrauen in Client-IPs aus <code>X-Forwarded-For</code> erfordert PROXMENUX_TRUST_PROXY=1 und einen von Ihnen kontrollierten Proxy. <code>X-Forwarded-Proto</code> oder <code>X-Forwarded-Host</code> allein aktivieren das Proxy-Vertrauen nicht. Auf den Ports 80/443 verwendet das Frontend relative <code>/api/*</code>-URLs; auf jedem anderen Port ruft es Port 8008 unter demselben Hostnamen auf."
},
"firstLaunch": {
"heading": "Ablauf beim ersten Start",
"intro": "Beim ersten Öffnen ruft das Frontend <code>GET /api/auth/status</code> auf. Wurde die Authentifizierung noch nie eingerichtet (<code>configured: false</code>), erscheint <em>„Dashboard schützen?“</em> mit zwei Optionen:",
"imageAlt": "Ersteinrichtungsdialog „Dashboard schützen?“ mit „Ja, Passwort einrichten“ und „Nein, ohne Schutz fortfahren“",
"imageCaption": "Authentifizierung beim ersten Start: Passwortschutz einrichten oder überspringen. Erscheint nach einer Neuinstallation oder nach „Authentifizierung deaktivieren“ in den Einstellungen erneut.",
"headerButton": "Schaltfläche",
"headerWhat": "Was passiert",
"headerApi": "API-Aufruf",
"rows": [
{
"button": "Ja, Passwort einrichten",
"what": "Öffnet ein Formular mit verpflichtendem Benutzernamen und Passwort sowie optionalem <em>Anzeigenamen</em> und <em>Avatarbild</em>. Aktiviert die Authentifizierung in <code>auth.json</code> mit <code>enabled: true</code> und gibt ein JWT zur Anmeldung zurück. Optionale Profilfelder werden durch weitere Aufrufe gespeichert, wie unten beschrieben.",
"api": "POST /api/auth/setup"
},
{
"button": "Nein, fahren Sie ohne Schutz fort",
"what": "Markiert <code>declined: true</code> in <code>auth.json</code>. Jeder API-Endpunkt ist öffentlich zugänglich, bis Sie Ihre Meinung über Einstellungen ändern.",
"api": "POST /api/auth/skip"
}
],
"twofaCalloutTitle": "2FA wird später konfiguriert, nicht hier",
"twofaCalloutBody": "Der erste Dialog entscheidet nur über den Passwortschutz. <strong>Zwei-Faktor-Authentifizierung (TOTP)</strong> richten Sie danach unter <strong>Sicherheit</strong> ein, sobald Sie mit Passwort angemeldet sind. Die vollständige Anleitung folgt weiter unten.",
"createTitle": "Erstellen des ersten Benutzers",
"createIntro": "Mit <em>Ja, Passwort einrichten</em> öffnen Sie ein Formular für Konto und optionales Profil. So erscheint der Avatar direkt nach dem Speichern im Kopfbereich. Die Felder:",
"headerField": "Feld",
"headerRequired": "Erforderlich",
"headerNotes": "Notizen",
"fieldRows": [
{
"field": "Benutzername",
"required": "Ja",
"notes": "Kennung zur Anmeldung. Später nicht über die Oberfläche änderbar; dafür muss <code>auth.json</code> direkt bearbeitet werden."
},
{
"field": "Passwort",
"required": "Ja",
"notes": "Mindestens 10 Zeichen aus mindestens 3 von 4 Kategorien: Kleinbuchstaben, Großbuchstaben, Ziffern und Symbole. Offensichtliche Passwörter wie <code>password</code>, <code>12345678</code> oder <code>proxmenux</code> werden abgelehnt. Dieselben Regeln gelten serverseitig und lassen sich nicht per curl umgehen."
},
{
"field": "Anzeigename",
"required": "Nein",
"notes": "Name im Menü des Kopfbereichs und auf der Profilseite. Ohne Angabe wird der Benutzername verwendet. Später über <strong>Avatar → Profil ansehen</strong> änderbar."
},
{
"field": "Avatarbild",
"required": "Nein",
"notes": "PNG, JPEG, WebP oder GIF bis 2 MB. Erscheint als Kreis im Kopfbereich und im Profil. Ohne Bild wird der erste Buchstabe des Anzeigenamens oder Benutzernamens auf farbigem Hintergrund gezeigt. Im Profil können Sie das Bild später hochladen, ersetzen oder entfernen."
}
],
"createImageAlt": "Formular mit verpflichtendem Benutzernamen und Passwort sowie optionalem Anzeigenamen und Avatar-Upload",
"createImageCaption": "Formular zur Ersteinrichtung. Anzeigename und Avatar sind optional. Ohne Angaben wird das Konto angelegt und im Kopfbereich ein Kreis mit einem Buchstaben angezeigt.",
"saveCalloutTitle": "Einmal speichern, bis zu drei API-Aufrufe",
"saveCalloutBody": "Zuerst sendet das Formular <code>POST /api/auth/setup</code> mit Benutzername und Passwort. Mit dem neuen JWT folgen gegebenenfalls <code>PUT /api/auth/profile</code> für den Anzeigenamen und <code>POST /api/auth/profile/avatar</code> für das Bild. Fehler beim Profil verhindern die Kontoerstellung nicht; das Profil lässt sich später ergänzen.",
"avatarTitle": "Avatar-Menü und Profilseite",
"avatarBody1": "Nach der Einrichtung erscheint oben rechts neben dem Designschalter ein Avatar. Sein Menü führt zum Profil und zur Sicherheit und bietet <strong>Abmelden</strong>. Eine Abmeldung ist auch unter Sicherheit möglich.",
"avatarBody2": "Die Profilseite zeigt eine Avatarvorschau, den schreibgeschützten Benutzernamen und den bearbeitbaren Anzeigenamen. Avatar-Uploads, Ersetzungen und Löschungen erfolgen atomar; der Avatar im Kopfbereich aktualisiert sich nach Erfolg ohne Neuladen. Ersteinrichtung und Profilseite verwenden die nachfolgend beschriebenen Endpunkte.",
"profileImageAlt": "Profilseite mit Avatarvorschau, Schaltflächen zum Hochladen, Ersetzen und Entfernen, schreibgeschütztem Benutzernamen und bearbeitbarem Anzeigenamen",
"profileImageCaption": "Die dedizierte Profilseite. Benutzername ist schreibgeschützt; Anzeigename und Avatar können von hier aus bearbeitet werden, ohne die Registerkarte Sicherheit zu berühren.",
"headerEndpoint": "Endpunkt",
"headerEpWhat": "Was es tut",
"endpointRows": [
{
"endpoint": "GET /api/auth/profile",
"what": "Gibt den aktuellen Benutzernamen, den Anzeigenamen und ob ein Avatar gesetzt ist (<code>has_avatar</code>, <code>avatar_mtime</code>) zurück."
},
{
"endpoint": "PUT /api/auth/profile",
"what": "Aktualisiert den Anzeigenamen. Anfrageinhalt: <code>'{' \"display_name\": \"...\" '}'</code>."
},
{
"endpoint": "GET /api/auth/profile/avatar",
"what": "Gibt das Avatarbild als PNG / JPEG / WebP / GIF mit passendem Inhaltstyp zurück. Benötigt den Bearer-Header; das Frontend lädt einen Blob und erzeugt daraus eine lokale Objekt-URL."
},
{
"endpoint": "POST /api/auth/profile/avatar",
"what": "Ladet einen neuen Avatar hoch (max 2 MB). Der Inhaltstyp muss der Datei entsprechen. Der alte Avatar wird atomar ersetzt."
},
{
"endpoint": "DELETE /api/auth/profile/avatar",
"what": "Entfernt den Avatar. Im Kopfbereich erscheint wieder eine Initiale in einem farbigen Kreis."
}
],
"reversibleTitle": "Der Verzicht auf Schutz lässt sich später ändern",
"reversibleBody": "Nach <em>Nein, ohne Schutz fortfahren</em> erscheint der Dialog nicht erneut. Aktivieren Sie die Authentifizierung unter <strong>Sicherheit</strong> oder bearbeiten Sie <code>/root/.config/proxmenux-monitor/auth.json</code>, entfernen Sie das Flag <code>declined</code> und starten Sie den Dienst neu."
},
"password": {
"heading": "Passwort-Authentifizierung",
"intro": "Nach der Einrichtung benötigen geschützte API-Aufrufe ein JWT in <code>Authorization: Bearer &lt;token&gt;</code>:",
"items": [
"<strong>Sitzungstoken zur Anmeldung:</strong> 24 Stunden gültig. Ausgestellt über <code>POST /api/auth/login</code>.",
"<strong>API-Token für Integrationen:</strong> 365 Tage gültig. Ausgestellt über <code>POST /api/auth/generate-api-token</code>. Weitere Informationen im nächsten Abschnitt."
],
"loginImageAlt": "Anmeldebildschirm nach der Konfiguration der Authentifizierung angezeigt - Benutzername und Passwortfelder",
"loginImageCaption": "Sobald die Authentifizierung konfiguriert ist, beginnt hier jeder Besuch des Dashboards. Wenn 2FA aktiviert ist, fragt der Bildschirm in einem zweiten Schritt nach dem akzeptierten Passwort nach dem 6-stelligen Code.",
"loginFlowTitle": "Loginfluss",
"twofaIntro": "Mit 2FA antwortet derselbe Aufruf zunächst mit <code>requires_totp: true</code>. Senden Sie ihn erneut mit dem sechsstelligen Code:",
"publicTitle": "Öffentliche Endpunkte (ohne Token)",
"publicIntro": "Anmeldung, Authentifizierungsstatus, Ersteinrichtung und der leichte Endpunkt <code>/api/system-info</code> sind öffentlich:",
"publicItems": [
"<code>/api/auth/login</code> und <code>/api/auth/status</code> sind öffentlich. <code>/api/auth/setup</code> erstellt das erste Konto und lehnt das Überschreiben vorhandener Zugangsdaten ab.",
"<code>/api/system-info</code> ist ein öffentlicher Endpunkt für grundlegende Systemdaten einschließlich <code>health.status</code>. Er verlangt kein Token. Auch /api/auth/status ist öffentlich und eignet sich für eine Erreichbarkeitsprüfung."
],
"cryptoTitle": "Kryptographie und Speicherung",
"cryptoIntro": "ProxMenux Monitor ist Open Source – nichts davon ist geheim. Die Dokumentation des Stacks hier ist eine bewusste Entscheidung: Betreiber, die Anmeldeinformationen auf ihrem Host speichern, verdienen es zu wissen, wie diese Anmeldeinformationen geschützt sind, bevor sie sich entscheiden, ihnen zu vertrauen. Die folgenden Algorithmen sind die gleichen, die der Code in <code>scripts/auth_manager.py</code> verwendet; dieser Abschnitt ist ein Vertrag, kein Marketingversprechen.",
"headerAsset": "Datenelement",
"headerAlgo": "Algorithmus",
"headerWhere": "Speicherort",
"cryptoRows": [
{
"asset": "Passwort",
"algorithm": "PBKDF2-HMAC-SHA256 mit einem Zufallssalz pro Passwort und einer hohen Iterationszahl (OWASP 2023+ Baseline). Speichert als <code>pbkdf2_sha256$&lt;iters&gt;$&lt;salt&gt;$&lt;hash&gt;</code>.",
"where": "<code>auth.json</code> → <code>password_hash</code>"
},
{
"asset": "Sitzung / API JWT",
"algorithm": "HS256 mit einem pro Installation beim ersten Start erzeugten Geheimnis (<code>secrets.token_urlsafe</code>, ≥48 Byte). Tokens enthalten die Angaben <code>iss=proxmenux-monitor</code> und <code>aud=api</code>; die Signatur wird bei jeder Anfrage mit dem aktuellen Geheimnis geprüft.",
"where": "Geheimnis: <code>auth.json</code> → <code>jwt_secret</code>. JWT selbst: nur auf dem Client."
},
{
"asset": "API Token Metadaten",
"algorithm": "Der SHA-256-Hash des JWT wird mit dem Fingerabdruck <code>signed_with</code> des verwendeten <code>jwt_secret</code> gespeichert. Damit lassen sich Token-Metadaten anzeigen und Tokens nach einem Wechsel des Signaturgeheimnisses erkennen.",
"where": "<code>auth.json</code> → <code>api_tokens[]</code>"
},
{
"asset": "2FA-TOTP-Geheimnis",
"algorithm": "Standard-TOTP (RFC 6238) mit Base32-kodiertem Geheimnis. Die acht Backup-Codes sind einmalig und werden als SHA-256-Hashes gespeichert.",
"where": "<code>auth.json</code> → <code>totp_secret</code> + <code>backup_codes[]</code>"
},
{
"asset": "Widerrufe",
"algorithm": "Bei Widerruf eines Tokens oder einer Sitzung wird dessen SHA-256-Hash in eine Sperrliste aufgenommen, die bei jeder Prüfung berücksichtigt wird. Eine etwa 30 Sekunden gültige Speicherkopie vermeidet häufige Datenträgerzugriffe.",
"where": "<code>auth.json</code> → <code>revoked_tokens[]</code>"
}
],
"authJsonTitle": "auth.json - was es enthält und wie es geschützt ist",
"authJsonBody": "Die Authentifizierungsdaten liegen in <code>/root/.config/proxmenux-monitor/auth.json</code>, mit Modus <code>0600</code> und Eigentümer <code>root</code>. Die Datei enthält <em>Hashes</em> (PBKDF2) und <em>geheimes Schlüsselmaterial</em> (<code>jwt_secret</code>, <code>totp_secret</code>), niemals das Klartextpasswort. Sichern oder replizieren Sie den Host nur auf ein verschlüsseltes Ziel und nehmen Sie diese Datei niemals in die Versionsverwaltung auf.",
"rotateTitle": "Ein Wechsel von jwt_secret macht bestehende JWTs ungültig",
"rotateBody": "Wird <code>auth.json</code> neu erstellt oder mit einem anderen Geheimnis wiederhergestellt, ändert sich <code>jwt_secret</code>. Bisherige Sitzungs- und API-Tokens scheitern dann mit „Invalid or expired token“. Die Oberfläche kennzeichnet betroffene Tokens mit <strong>Ungültig — neu erstellen</strong>. Widerrufen und ersetzen Sie sie auch in Home Assistant, Skripten und anderen Clients.",
"recoverTitle": "Wiederherstellen eines verlorenen Passworts",
"recoverIntro": "Es gibt keinen Online-Fluss für \"Passwort vergessen\" - von Grund auf, da das Dashboard auf dem eigenen Host des Betreibers läuft und der Wiederherstellungspfad Shell-Zugriff auf diesen Host ist. ProxMenux liefert einen geführten Reset im Konfigurationsmenü, sodass Sie <code>auth.json</code> nicht von Hand bearbeiten müssen:",
"survivesTitle": "Was den Reset überlebt",
"survivesBody": "Die interaktive Anmeldung wird gelöscht, <code>jwt_secret</code> und registrierte <code>api_tokens</code> bleiben erhalten. Home Assistant und andere Integrationen können ihre Tokens weiterverwenden. Für einen vollständigen Neustart samt neuem Signaturgeheimnis <code>auth.json</code> manuell löschen und den Dienst neu starten. Dann sind alle alten Tokens ungültig.",
"physicalTitle": "Voraussetzung für den physischen Zugang",
"physicalBody": "Erfordert eine <strong>Root-Shell auf dem Host</strong>. Wer <code>menu</code> als root ausführen kann, besitzt bereits vollständige Kontrolle; die Passwortzurücksetzung erweitert seine Rechte nicht. Ein Monitor-Passwort schützt den Host daher nicht vor Personen mit unberechtigtem Root-Zugang."
},
"twofa": {
"heading": "Zwei-Faktor-Authentifizierung (TOTP)",
"intro": "2FA fügt Ihrem Passwort einen zweiten Faktor hinzu: einen 6-stelligen Code, der alle 30 Sekunden rotiert und auf einem von Ihnen kontrollierten Telefon- oder Passwortmanager generiert wird. Selbst wenn jemand das Passwort erhält, kann er sich immer noch nicht ohne den Code von Ihrem Gerät anmelden. ProxMenux Monitor implementiert das Standard-Protokoll <strong>TOTP</strong> (RFC 6238), so dass jede Authentifizierungs-App funktioniert.",
"pickTitle": "Wählen Sie eine Authenticator App",
"pickIntro": "Eine vorhandene TOTP-App können Sie weiterverwenden. Die Tabelle nennt übliche Optionen: einige kostenlos, andere mit Abonnement. Plattformen und Sicherungsverfahren unterscheiden sich ebenfalls.",
"headerApp": "App",
"headerPlatforms": "Plattformen",
"headerAppNotes": "Notizen",
"apps": [
{
"name": "Google Authenticator",
"href": "https://safety.google/authentication/",
"platforms": "iOS, Android",
"notes": "Der Standard für viele Benutzer. Optionales Google-Konto Cloud-Backup."
},
{
"name": "Microsoft Authenticator",
"href": "https://www.microsoft.com/en-us/security/mobile-authenticator-app",
"platforms": "iOS, Android",
"notes": "Microsoft-Account Backup. Behandelt auch MS-Push-Benachrichtigungen, wenn Sie sie bei der Arbeit verwenden."
},
{
"name": "Authy",
"href": "https://authy.com/",
"platforms": "iOS, Android",
"notes": "Verschlüsselte Synchronisierung zwischen Geräten. Die Desktop-App wird seit dem 19. März 2024 nicht mehr unterstützt."
},
{
"name": "Apple Passwords",
"href": "https://support.apple.com/guide/passwords/welcome/mac",
"platforms": "iOS, iPadOS, macOS, visionOS, Windows (über iCloud)",
"notes": "In Apple-Betriebssystemen enthalten; eigenständige Passwords-App seit iOS 18 / macOS Sequoia. Speichert TOTP neben dem Passwort und synchronisiert über den iCloud-Schlüsselbund."
},
{
"name": "Bitwarden",
"href": "https://bitwarden.com/",
"platforms": "iOS, Android, Desktop, Browser",
"notes": "Open Source. TOTP kann im Passworttresor neben Passwörtern gespeichert werden. Das ist praktisch, bietet aber keine Trennung auf ein zweites Gerät."
},
{
"name": "1Password",
"href": "https://1password.com/",
"platforms": "iOS, Android, Desktop, Browser",
"notes": "Wie Bitwarden: TOTP im Passworttresor. Kostenpflichtiges Abonnement."
},
{
"name": "Aegis Authenticator",
"href": "https://getaegis.app/",
"platforms": "Android",
"notes": "Open Source. Verschlüsselte Backup-Datei auf dem Gerät, die Sie kontrollieren. Keine Cloud, kein Account erforderlich."
},
{
"name": "Raivo OTP",
"href": "https://raivo-otp.com/",
"platforms": "iOS, macOS",
"notes": "Open Source. Optionale iCloud Sync. Das Apple-Ökosystem Pendant zu Aegis."
},
{
"name": "Ente Auth",
"href": "https://ente.io/auth/",
"platforms": "iOS, Android, Desktop, Web",
"notes": "Open Source. Ende-zu-Ende verschlüsselte Cloud-Synchronisierung über Geräte hinweg."
},
{
"name": "2FAS",
"href": "https://2fas.com/",
"platforms": "iOS, Android, Browsererweiterung",
"notes": "Open Source. Optionales verschlüsseltes Cloud-Backup; Browsererweiterung kann automatisch Codes ausfüllen."
},
{
"name": "FreeOTP+",
"href": "https://github.com/helloworld1/FreeOTPPlus",
"platforms": "Android",
"notes": "Open-Source-Abspaltung von FreeOTP für Android mit Import und Export. Kein Konto erforderlich."
}
],
"backupTitle": "Warum Sicherungen wichtig sind",
"backupBody": "Bei Verlust des Authenticator-Geräts einen gesicherten Backup-Code verwenden oder die App aus einer zuvor eingerichteten Sicherung wiederherstellen. Cloud-Synchronisierung und lokale Exporte unterscheiden sich je nach App; prüfen Sie, ob die gewählte Methode die TOTP-Geheimnisse tatsächlich wiederherstellt. Mit Root-Zugang zum Host ist die unten beschriebene Wiederherstellung ebenfalls möglich. Bewahren Sie eine separate, sichere Kopie auf.",
"setupTitle": "Schritt-für-Schritt-Setup aus dem Dashboard",
"setupImageAlt": "Einrichtungsbildschirm 2FA mit QR-Code und Backup-Codes",
"setupImageCaption": "Der 2FA-Einrichtungsdialog zeigt QR-Code, Base32-Geheimnis zur manuellen Eingabe und nach der Überprüfung acht einmalige Backup-Codes. Die Codes vor dem Schließen des Dialogs kopieren; sie werden nicht erneut angezeigt.",
"setupSteps": [
"<strong>Installieren Sie die Authenticator-App auf Ihrem Telefon</strong> (oder öffnen Sie Ihren Passwort-Manager). Eine der Apps aus der Tabelle oben. Sie müssen dies nur einmal tun - die gleiche app enthält codes für jeden dienst, den sie schützen.",
"<strong>Am Dashboard anmelden</strong> mit Benutzername und Passwort.",
"<strong>Registerkarte Sicherheit öffnen</strong> in der Seitenleiste des Dashboards, dann auf <strong>2FA aktivieren</strong> und <strong>Einrichtung starten</strong> klicken. Der Dialog zeigt QR-Code und manuellen Schlüssel; die acht Backup-Codes erscheinen, nachdem der Code überprüft wurde.",
"<strong>Fügen Sie den Eintrag zur Authenticator-App hinzu:</strong>",
"<strong>Bestätigen Sie, indem Sie den aktuellen 6-stelligen Code</strong> aus der App in das Feld \"Verifizierungscode\" des Setup-Dialogs eingeben und senden. Codes aktualisieren alle 30 Sekunden, wenn es also abläuft, während Sie tippen, geben Sie einfach den nächsten ein.",
"<strong>Backup-Codes sichern.</strong> Nach der Überprüfung alle acht sicher in einem Passwortmanager, einer verschlüsselten Notiz oder einem sicheren Ausdruck aufbewahren. Jeder funktioniert einmal, wenn der Authenticator nicht verfügbar ist.",
"<strong>Fertig.</strong> 2FA ist aktiv. Bei der nächsten Anmeldung wird zuerst das Passwort und danach der aktuelle sechsstellige Code abgefragt."
],
"setupStep4Sub": [
"<em>Einfaches Verfahren:</em> In der App <em>Konto hinzufügen</em> → <em>QR-Code scannen</em> wählen und die Kamera auf den QR-Code richten. Die App benennt den Eintrag automatisch, etwa <code>ProxMenux Monitor (your-username)</code>, und zeigt alle 30 Sekunden einen neuen sechsstelligen Code.",
"<em>Manuelle Alternative</em>, falls Scannen nicht möglich ist, etwa auf demselben Telefon: <em>Konto hinzufügen</em> → <em>Einrichtungsschlüssel eingeben</em>. Einen Namen wie <em>Proxmox Monitor</em> wählen, Base32-Geheimnis einfügen, <em>Typ</em> auf <em>Zeitbasiert</em> belassen und speichern."
],
"testTitle": "Test vor dem Abmelden",
"testBody": "Die bestehende Sitzung geöffnet lassen und <em>sofort</em> nach der Einrichtung in einem privaten Fenster eine neue Anmeldung testen. Bei abgelehntem Code zuerst Server- und Telefonuhr prüfen, bevor Sie sich aus der funktionierenden Sitzung abmelden. Bei bereits verlorenem Zugang einen Backup-Code verwenden oder <code>auth.json</code> in der Host-Shell bearbeiten.",
"lostTitle": "Verlorener Authentifikator",
"lostIntro": "Drei Wiederherstellungswege, von geringem bis stärkerem Eingriff:",
"lostItems": [
"<strong>Backup-Code verwenden.</strong> Einen der acht gesicherten Codes im TOTP-Feld eingeben. Er funktioniert einmal; unbenutzte Codes bleiben gültig. Nach der Anmeldung Sicherheit öffnen, zuerst <strong>2FA deaktivieren</strong> und danach <strong>2FA aktivieren</strong> wählen, um acht neue Codes zu erhalten.",
"<strong>Authenticator aus Cloud oder Sicherung wiederherstellen.</strong> Bei eingerichteter Cloud-Synchronisierung die App auf dem neuen Gerät installieren und anmelden, etwa Google, Microsoft, Authy, Apple Passwords über iCloud-Schlüsselbund, Ente oder 2FAS. Bei einer Exportdatei, etwa aus Aegis, Raivo oder FreeOTP+, die App installieren und die Datei importieren.",
"<strong>Deaktivieren Sie 2FA von der Host-Shell.</strong> Wenn die vorherigen Optionen nicht verfügbar sind, bearbeiten Sie <code>/root/.config/proxmenux-monitor/auth.json</code> auf dem Proxmox-Host (Sie benötigen SSH oder Konsolenzugriff), setzen Sie <code>totp_enabled</code> auf <code>false</code>, speichern und starten Sie den Dienst neu:"
],
"lostShellOutro": "Sie können sich nur mit Benutzername + Passwort anmelden und dann 2FA aus Einstellungen wieder aktivieren.",
"disableTitle": "Deaktivieren Sie 2FA",
"disableBody": "<strong>Sicherheit</strong> öffnen und <strong>2FA deaktivieren</strong> wählen. <code>POST /api/auth/totp/disable</code> benötigt das aktuelle Passwort und einen gültigen TOTP- oder Backup-Code. Dabei werden TOTP-Geheimnis und Backup-Codes gelöscht. Den alten Eintrag auch in der Authenticator-App entfernen.",
"rejectedTitle": "Der 6-stellige Code wird immer abgelehnt",
"rejectedIntro": "TOTP ist zeitbasiert. Server- und Telefonuhr dürfen nur etwa 30 Sekunden voneinander abweichen. Zwei Prüfungen:",
"rejectedItems": [
"<strong>Telefon:</strong> Einstellungen → Datum und Uhrzeit → automatische / Netzwerksynchronisierung aktivieren.",
"<strong>Proxmox-Host:</strong> <code>timedatectl status</code> sollte „System clock synchronized: yes“ anzeigen. Andernfalls <code>timedatectl set-ntp true</code> ausführen und eine Minute warten."
],
"rejectedOutro": "Sobald beide Uhren übereinstimmen, wird der Code innerhalb des nächsten 30-Sekundenfensters akzeptiert."
},
"apiTokens": {
"heading": "API-Token (langlebig)",
"intro": "Browsersitzungen laufen nach 24 Stunden ab. Für Homepage-Widgets, Home Assistant, Grafana oder Uptime Kuma erstellen Sie ein separates <strong>API-Token</strong> mit 365 Tagen Laufzeit. Es verwendet dasselbe Signaturgeheimnis; die Angabe <code>token_name</code> erlaubt die Zuordnung und den einzelnen Widerruf.",
"imageAlt": "API-Token-Panel zeigt die Token-Liste mit Name, Präfix, erstelltem Datum und Ablauf",
"imageCaption": "Die API-Tokenliste unter Einstellungen — Name, Präfix (die letzten 4-Zeichen werden zur Identifizierung angezeigt), erstellt und Ablaufdatum, Widerrufsaktion.",
"generateTitle": "Generieren Sie ein Token",
"generateIntro": "Aus dem Dashboard:",
"generateSteps": [
"Unter <strong>Sicherheit → API-Zugriffstokens</strong> öffnen.",
"Beschreibenden Namen angeben, <em>z. B. „Home Assistant“</em>.",
"Geben Sie Ihr Passwort erneut ein. Wenn 2FA eingeschaltet ist, auch der aktuelle 6-stellige Code.",
"<strong>Token erstellen</strong> wählen. Es erscheint <strong>nur einmal</strong>; sofort kopieren."
],
"generateCli": "Aus der Kommandozeile:",
"useTitle": "Verwenden Sie ein Token",
"revokeTitle": "Einen Token widerrufen",
"revokeBody": "Jede Zeile bietet <strong>Widerrufen</strong>. Dadurch wird der Token-Hash unter <code>revoked_tokens</code> in <code>auth.json</code> gespeichert. Ab der nächsten Anfrage wird das Token abgelehnt.",
"cheatTitle": "Kurzübersicht zur Token-Sicherheit",
"cheatItems": [
"Tokens im Geheimnisspeicher der Integration ablegen: Homepage <code>secrets.yaml</code>, Home Assistant <code>!secret</code> oder Umgebungsvariablen. Niemals in Git aufnehmen.",
"Ein nach der jeweiligen Integration benanntes Token verwenden. Beim Entfernen der Integration dieses Token einzeln widerrufen.",
"Rotieren Sie alle 6–12 Monate. Der Ablauf ist eine harte Grenze, keine Empfehlung."
],
"outro": "Hinweise zur sicheren Speicherung und Integrationsbeispiele: <apiLink>API-Referenz → Token-Verwaltung</apiLink> und <intLink>Integrationen</intLink>."
},
"https": {
"heading": "HTTPS",
"intro": "Zwei Wege zu TLS:",
"items": [
"<strong>Reverse-Proxy (empfohlen).</strong> Beenden Sie TLS auf Nginx / Caddy / Traefik und leiten Sie HTTP auf Port 8008 zum Flask-Prozess weiter. Snippets unten.",
"<strong>Direktes HTTPS in der AppImage.</strong> Zertifikat über <code>POST /api/ssl/configure</code> einrichten (Oberfläche: <strong>Einstellungen → SSL</strong>). HTTPS verwendet <code>gevent.pywsgi</code> mit dem Standardhandler; flask-sock übernimmt WebSocket-Verbindungen für WSS. Zertifikatspfade stehen in der SSL-Konfiguration."
],
"calloutTitle": "Direkte HTTPS-Beschränkungen",
"calloutBody": "Der Monitor kann ein von Proxmox verwaltetes Zertifikat oder eigene Zertifikatsdateien verwenden. Er stellt selbst keine ACME-Zertifikate aus. Für automatische Ausstellung und Erneuerung Proxmox ACME oder einen Reverse-Proxy wie Caddy, Traefik oder Nginx verwenden; erneuerte Zertifikate müssen geladen werden."
},
"gateway": {
"heading": "Sicheres Gateway (Tailscale)",
"intro": "Ein Reverse-Proxy ermöglicht Fernzugriff. <strong>Secure Gateway</strong> bietet Zugriff ohne Veröffentlichung von TCP 8008: Ein Alpine-LXC führt <a>Tailscale</a> als Subnetz-Router aus. Die LAN-IP des Hosts ist über genehmigte Subnetzrouten und Tailnet-Zugriffsregeln erreichbar.",
"calloutTitle": "Warum dies bequem ist",
"calloutBody": "Die LAN-URL <code>http://&lt;proxmox-lan-ip&gt;:8008</code> über die genehmigte Route verwenden. Tailscale-Subnetz-Router nutzen standardmäßig SNAT. Der Monitor sieht daher üblicherweise die LAN-IP des Gateways statt der Clientadresse <code>100.x.y.z</code>. Protokoll und Fail2Ban erkennen die tatsächlich am Host ankommende Quelladresse.",
"deployBody": "Auf einer Seite LXC-Speicher wählen, einen unter <a>login.tailscale.com/admin/settings/keys</a> erzeugten Tailscale-Schlüssel einfügen, Subnetze wählen und bereitstellen. Der LXC wird in etwa 30 Sekunden eingerichtet und im Tailnet registriert.",
"outro": "Bereitstellung, Subnetzrouten, Tailscale-ACLs und Exit-Node-Modus stehen unter <link>Dashboard → Sicherheit → Secure Gateway</link>. Dort befindet sich auch der Assistent. Diese Seite beschreibt den Zugriff."
},
"proxy": {
"heading": "Konfigurationsbeispiele für Reverse-Proxys",
"intro": "Einen <strong>eigenen Hostnamen</strong> wie <code>monitor.example.com</code> auf Port 8008 des Proxmox-Hosts weiterleiten. Die Beispiele nutzen dieses Schema. Ein Unterpfad wie <code>example.com/proxmenux-monitor/</code> braucht weitere Frontend- und Proxy-Anpassungen; Entfernen des Präfixes allein reicht nicht.",
"nginxTitle": "Nginx",
"caddyTitle": "Caddy",
"traefikTitle": "Traefik (Labels — Docker / Kubernetes)",
"subPathTitle": "Erweitert: Bereitstellung unter einem Unterpfad",
"subPathBody": "Das aktuelle Frontend hat keine konfigurierte Unterpfad-Basis und erstellt API-Aufrufe mit rootrelativen <code>/api/*</code>-URLs. Ein Präfix wie <code>example.com/proxmenux-monitor/</code> zu entfernen reicht weder für diese API-Aufrufe noch für alle Frontend-Dateien aus. Verwenden Sie einen eigenen Hostnamen. Ein Unterpfad erfordert abgestimmte Frontend-/Proxy-Anpassungen und eigene Tests."
},
"audit": {
"heading": "Prüfprotokoll",
"intro": "Fehlgeschlagene Anmeldungen und Warnungen des Anmeldelimits werden zeilenweise in <code>/var/log/proxmenux-auth.log</code> geschrieben. Erfolgreiche Anmeldungen protokolliert dieser Logger nicht:",
"outro": "Mit <code>tail -F /var/log/proxmenux-auth.log</code> verfolgen. Eine zusätzliche Konfiguration für <code>logrotate</code> ermöglicht die Rotation; der Monitor führt sie nicht selbst durch."
},
"fail2ban": {
"heading": "Optional: Fail2Ban-Jail",
"calloutTitle": "Fail2Ban ist nicht mit dem Monitor gebündelt",
"calloutBody": "Fail2Ban wird <strong>nicht</strong> von ProxMenux Monitor selbst installiert. Installieren Sie es über <link>Sicherheit → Fail2Ban</link> im Menü ProxMenux (oder mit dem Standard-Debian-Paket). Ohne sie schreibt der Monitor immer noch das obige Überwachungsprotokoll – Wiederholungstäter werden einfach nicht automatisch gesperrt.",
"intro": "Wenn Fail2Ban installiert ist, liefert die ProxMenux-Integration einen <code>[proxmenux]</code> jail mit, der:",
"items": [
"Liest <code>/var/log/proxmenux-auth.log</code>.",
"Erkennt das Muster <code>authentication failure; rhost=&lt;ip&gt;</code> mit einem eigenen Filter.",
"Sperrt die beanstandete IP standardmäßig auf Kernel-Firewall-Ebene.",
"Der Flask-Hook <code>before_request</code> prüft Anfragen anhand der für 30 Sekunden zwischengespeicherten Sperrliste. Hinter einem Reverse-Proxy sind PROXMENUX_TRUST_PROXY=1 und ein kontrollierter Proxy mit vertrauenswürdigen Weiterleitungsheadern erforderlich."
],
"outro": "Konfiguration, Sperrdauer und Entsperren: <link>Sicherheit → Fail2Ban</link>."
},
"troubleshoot": {
"heading": "Fehlerbehebung",
"noScreenTitle": "Der erste Launch-Bildschirm erscheint nie",
"noScreenBody": "Die Authentifizierung ist bereits eingerichtet (<code>configured: true</code>) oder wurde übersprungen. Für eine neue Einrichtung:",
"noScreenOutro": "Löscht den Authentifizierungszustand einschließlich TOTP-Geheimnissen und API-Tokens. Zuerst <code>auth.json</code> sichern, falls Sie Tokens behalten möchten.",
"tokenTitle": "HTTP 401 bei jeder Anfrage von einem funktionierenden API-Token",
"tokenBody": "Token abgelaufen (365 Tage) oder in <code>revoked_tokens</code> eingetragen. Neues Token in den Einstellungen erstellen und die Integration aktualisieren. Prüfen mit:",
"tokenOutro": "Abgelaufene oder widerrufene Token geben <code>'{'\"error\":\"Invalid or expired token\"'}'</code> zurück.",
"no2faTitle": "Kann sich nicht anmelden, nachdem 2FA aktiviert wurde, kein Authentifikator zur Hand",
"no2faBody": "Verwenden Sie einen Backup-Code im TOTP-Feld. Wenn diese nicht mehr vorhanden sind, bearbeiten Sie <code>/root/.config/proxmenux-monitor/auth.json</code> von einer Host-Shell, setzen <code>totp_enabled</code> auf <code>false</code>, starten Sie den Dienst neu.",
"wsTitle": "Reverse Proxy funktioniert, aber der Terminal-Tab trennt sich jede Minute",
"wsBody": "Möglicher Grund ist das WebSocket-Leerlaufzeitlimit des Proxys. Lesezeitlimit erhöhen (Nginx: <code>proxy_read_timeout 86400s</code>; Traefik: <code>idleTimeout</code> im Einstiegspunkt oder der Middleware). In Nginx <code>proxy_set_header Upgrade $http_upgrade</code> und <code>Connection \"upgrade\"</code> prüfen."
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "API-Referenz → Token-Verwaltung",
"href": "/docs/monitor/api",
"tail": " — API-Tokens erstellen, auflisten und widerrufen; sichere Speicherung und Sicherheitsregeln."
},
{
"label": "Integrationen",
"href": "/docs/monitor/integrations",
"tail": " — Homepage, Home Assistant, Grafana / Prometheus, Uptime Kuma und allgemeine cURL-Beispiele."
},
{
"label": "Übersicht → Sicherheit → Sicheres Gateway",
"href": "/docs/monitor/dashboard/security",
"tail": " — Tailscale-Gateway-LXC schrittweise bereitstellen: Subnetzrouten, ACLs und Exit-Node-Modus."
},
{
"label": "Sicherheit: Fail2Ban",
"href": "/docs/security/fail2ban",
"tail": " — optionale Jail installieren und konfigurieren."
},
{
"label": "Einstellungen → ProxMenux Monitor",
"href": "/docs/settings/proxmenux-monitor",
"tail": " — systemd-Dienst über die ProxMenux-TUI starten und stoppen."
}
]
}
}
@@ -0,0 +1,342 @@
{
"meta": {
"title": "Proxmox-KI-Assistent — OpenAI, Claude, Gemini, Groq, Ollama | ProxMenux Monitor",
"description": "Der optionale KI-Assistent formuliert Proxmox-VE-Benachrichtigungen verständlich um. Sechs Anbieter: OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter und Ollama. Die Oberfläche bietet dreizehn Sprachen, drei Detailstufen pro Kanal, eigene Prompts mit Community-Bibliothek sowie Ereigniskontext mit Laufzeit, Wiederholungen und SMART-Daten.",
"ogTitle": "Proxmox-KI-Assistent — OpenAI, Claude, Gemini, Groq, Ollama",
"ogDescription": "Beschreiben Sie Proxmox VE-Benachrichtigungen in einfacher Sprache mit OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter oder lokalem Ollama.",
"twitterTitle": "Proxmox-KI-Assistent | ProxMenux Monitor",
"twitterDescription": "Beschreiben Sie Proxmox VE-Benachrichtigungen in einfacher Sprache mit OpenAI, Anthropic, Gemini, Groq, OpenRouter oder lokalem Ollama."
},
"header": {
"title": "KI-Assistent",
"description": "Die optionale KI formuliert geeignete Benachrichtigungsvorlagen verständlich um: mit Detailstufen pro Kanal, dreizehn Oberflächensprachen, eigenen Prompts, öffentlicher Community-Bibliothek und zusätzlichem Kontext. Die Backup-Berichte <code>backup_complete</code> und <code>backup_fail</code> umgehen die KI vollständig.",
"section": "ProxMenux-Monitor"
},
"intro": {
"title": "Standardmäßig aus, mit einem Schalter aktivieren",
"body": "Die KI-Umschreibung ist standardmäßig aus. Aktivieren Sie sie unter <em>Einstellungen → Benachrichtigungen → Erweitert: KI-Verbesserung</em>. Schlagen Kontextanreicherung oder Umschreibung fehl, sendet der Dispatcher die ursprüngliche Vorlage. Umschreibungen in der Versandwarteschlange für Ereignisse haben ein Zeitlimit von 25 Sekunden; wird es erreicht, wird die Vorlage gesendet, statt weiter zu warten."
},
"howItWorks": {
"heading": "Wie es funktioniert",
"intro": "Die versendeten Monitor-Ereignisse durchlaufen denselben Ablauf. Die KI-Umschreibung ist ein optionaler Schritt zwischen Vorlagentext und Kanalversand. Ein Ereignis durchläuft vier Schritte:",
"steps": [
"<strong>Ereignis und Vorlage.</strong> Ein Ereignis kommt von einem der sechs Datensammler. <code>notification_templates.py</code> formatiert es als strukturierten Klartext. Diesen Text würde der Kanal ohne KI-Umschreibung senden.",
"<strong>Kontext-Anreicherung.</strong> Der Dispatcher inspiziert das Ereignis und fügt die relevanten zusätzlichen Signale bedingt an: System-Uptime (nur für kritische Systemausfälle), Ereignis-Frequenz, SMART-Daten (nur für Festplatten-Ereignisse), Bekannte Fehler-Datenbankübereinstimmungen und Journal-Logleitungen.",
"<strong>Prompt-Erstellung.</strong> Der Systemprompt setzt sich aus Vorlage und Kanaleinstellungen zusammen: Zielsprache, Detailstufe, Emoji-Regeln aus <em>Formatierte Nachrichten</em> und optionalen KI-Vorschlägen. Ein eigener Prompt ersetzt den Systemprompt vollständig. Die Benutzernachricht enthält Vorlagentext und ergänzte Kontextblöcke.",
"<strong>Anbieteraufruf.</strong> Groq, OpenAI, Anthropic, Gemini, Ollama oder OpenRouter liefert umformulierten Titel und Nachrichtentext. Der Dispatcher verarbeitet die Antwort, ersetzt diese Inhalte für den Kanal und übergibt sie an dessen Versandadapter."
],
"notesIntro": "Drei Details, an denen es sich zu halten lohnt, bevor Sie den Rest dieser Seite lesen:",
"notes": [
"<strong>Die KI erzeugt keine Ereignisse.</strong> Jedes Ereignis stammt aus einem echten Signal wie Zustandsprüfung, Journalzeile oder PVE-Webhook. Vor der KI-Verarbeitung wird es als Vorlagentext formatiert. Die KI übersetzt und formatiert, sie überwacht das System nicht.",
"<strong>Die AI läuft per-channel.</strong> Telegram und Discord können eine kurze Umschreibung verwenden, während E-Mail einen detaillierten Bericht erhält - dasselbe Ereignis, unterschiedliche Form, alles von einem Anbieteranruf pro Kanal.",
"<strong>Fehler führen zur Vorlage zurück.</strong> Bei HTTP-5xx-Fehlern, Zeitüberschreitung, ungültiger Ausgabe oder abgelehnter Anfrage protokolliert der Dispatcher den Fehler und sendet den ursprünglichen Vorlagentext für den Kanal. Ein KI-Fehler verhindert die Benachrichtigung nicht."
]
},
"enabling": {
"heading": "Panel aktivieren",
"intro": "Die AI-Konfiguration befindet sich am unteren Rand des Benachrichtigungsfeldes innerhalb der Registerkarte Einstellungen als zusammenklappbarer <em>Advanced: AI Enhancement</em>-Block. Klicken Sie auf den Header, um zu erweitern:",
"collapsedAlt": "Eingeklappter Bereich für erweiterte KI-Einstellungen mit Pfeilsymbol",
"collapsedCaption": "Standardmäßig eingeklappt; ein Klick öffnet das Panel.",
"panelAlt": "Geöffnetes KI-Panel mit Hauptschalter, Anbieter Google Gemini, verdecktem API-Schlüssel, Modell gemini-2.5-flash, Standardprompt, Sprache Englisch, Detailstufe für Telegram, Discord, Gotify und E-Mail, KI-Vorschlägen und Verbindungstest",
"panelCaption": "Das vollständige AI Enhancement-Panel - jedes auf dieser Seite dokumentierte Steuerelement wird einem der oben genannten Felder zugeordnet.",
"outro": "Von oben nach unten zeigt das Panel: den <em>AI-Enhanced Messages</em> Master-Toggle, den Provider-Selektor mit einem Informationsmodal daneben, den API-Schlüsseleingang (oder die Ollama-URL für den lokalen Modus), den Modell-Dropdown (vom Provider nach Eingabe des Schlüssels geladen), den prompten Modus (<em>Default</em> / <em>Custom</em>), die Ausgabesprache, die Pro-Kanal-Detailebene, die <em>AI Suggestions</em> Opt-in und eine <em>Test Connection</em>-Taste, die eine Probenachricht an den Provider sendet, um die Anmeldeinformationen zu validieren."
},
"context": {
"heading": "Welchen Kontext die KI erhält",
"intro": "Bevor die Eingabeaufforderung erstellt wird, führt der Dispatcher eine Kontextanreicherungsroutine durch, die entscheidet, welche zusätzlichen Signale für das jeweilige Ereignis relevant sind. Ziel ist es, dem LLM genügend Informationen zu geben, um eine nützliche Nachricht zu erstellen, ohne sie (und Ihren Geldbeutel) mit Lärm zu überschwemmen, der nicht zutrifft. Fünf Kontextblöcke können der Benutzernachricht hinzugefügt werden:",
"headerBlock": "Block",
"headerWhen": "Wenn es injiziert wird",
"headerWhat": "Was es trägt",
"rows": [
{
"block": "Systemlaufzeit",
"when": "Nur bei kritischen Systemfehlern: <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>. Bei Laufwerksfehlern, Warnungen und Routinevorgängen wird dieser Kontext für einen knappen Prompt ausgelassen.",
"what": "Eine Linie wie <code>System uptime: 14 days (stable system)</code>. LLM unterscheidet Startprobleme von lang andauernden Fehlern."
},
{
"block": "Ereignishäufigkeit",
"when": "Immer, wenn der Monitor den gleichen Fingerabdruck schon einmal gesehen hat.",
"what": "Häufigkeit, erstgesehener Zeitstempel, optionale Musterbezeichnung (wiederkehrend / einmalig / Spike). Das LLM verwendet dies, um \"wiederkehrendes Problem\" vs \"erstes Mal gesehen\" zu formulieren."
},
{
"block": "SMART-Daten",
"when": "Nur für plattenbezogene Ereignisse (der Ereignistyp enthält <code>disk</code>, <code>smart</code>, <code>storage</code>, <code>io_error</code> oder der Körper erwähnt <code>/dev/sd</code>, <code>ata</code>, <code>i/o error</code>).",
"what": "Ausgabe von <code>smartctl</code> für das betroffene Gerät — Gesamtzustand (PASSED / FAILED) zuzüglich der relevanten Attribute für den Fehlermodus."
},
{
"block": "Bekannte Fehler DB",
"when": "Wenn der Body- oder Journalkontext mit einem Proxmox-spezifischen Fehlermuster übereinstimmt, das mit dem Monitor ausgeliefert wird.",
"what": "Ein <code>KNOWN PROXMOX ERROR DETECTED</code> Block mit der passenden Ursache und einer konkreten Lösung. Die Aufforderung weist das LLM an, dieses wörtlich zu übersetzen - keine Paraphrasierung des empfohlenen Fixes."
},
{
"block": "Journalprotokolle",
"when": "Wenn der ursprüngliche Datensammler Journalzeilen zum Ereignis erfasst hat, vor allem die Journal- und Aufgabenüberwachung.",
"what": "Rohe <code>journalctl</code>-Auszüge. Die Aufforderung sagt dem LLM, IDs, Zeitstempel und Root-Cause-Hinweise zu extrahieren und nicht verwandte Einträge zu ignorieren."
}
],
"afterBlocks": "Sobald diese Blöcke verbunden sind, hat die an den LLM gesendete Benutzernachricht diese Form:",
"calloutTitle": "Keine Telemetrie über das Ereignis selbst hinaus",
"calloutBody": "Der Monitor sendet nur das, was er für das aktuelle Ereignis zur Hand hat - keine systemweite Telemetrie, keine historischen metrischen Serien, keine Inventar-Dumps. Die fünf Blöcke oben sind die obere Grenze dessen, was den Host bei einer einzelnen KI-Umschreibung verlässt."
},
"tokens": {
"heading": "Tokens - was sie sind und wie sie konsumiert werden",
"intro1": "Kommerzielle Anbieter rechnen nach <em>Token</em> ab. Ein Token entspricht grob vier englischen Zeichen oder drei Vierteln eines Wortes. Der englische Satz <em>\"Backup completed on storage local-bak\"</em> hat ungefähr acht Token. Zehn Journalzeilen können je nach technischem Inhalt 200–400 Token umfassen.",
"intro2": "Zwei Dinge werden bei jedem Anruf in Rechnung gestellt:",
"items": [
"<strong>Eingabe-Token</strong> umfassen Systemprompt und Benutzernachricht: Schweregrad, Titel, Vorlagentext und Kontext. Die Anzahl hängt vom tatsächlichen Prompt und Ereignis ab. Jeder umgeschriebene Kanal kann eigene Eingabe-Token verbrauchen; Backup-Abschluss- und Fehlerberichte umgehen die KI.",
"<strong>Ausgabe-Token</strong> sind die Modellantwort. Monitor begrenzt sie mit <code>max_tokens</code>. Die Grenze ist ein <em>Höchstwert</em>, kein fester Verbrauch: Erzeugt das Modell 250 Token bei einem Limit von 1500, werden 250 berechnet."
],
"capsIntro": "Dies sind die tatsächlichen Obergrenzen, die der Dispatcher anwendet, direkt aus <code>AI_DETAIL_TOKENS</code> in <code>notification_templates.py</code> entnommen:",
"headerLevel": "Detailebene",
"headerCap": "Ausgabegrenze (Token)",
"headerConsumption": "Typischer realer Verbrauch",
"capRows": [
{
"level": "kurz",
"cap": "500",
"consumption": "50–200 Ausgabe-Token für kurze Ereignisse."
},
{
"level": "Standard",
"cap": "1500",
"consumption": "200–700 Ausgabe-Token für typische Ereignisse mit wenig Kontext."
},
{
"level": "ausführlich",
"cap": "3000",
"consumption": "500–2000 Ausgabe-Token für vollständige E-Mail-Berichte mit Protokollen und SMART-Tabellen."
}
],
"customNote": "Der benutzerdefinierte Eingabeaufforderungsmodus verwendet eine feste Obergrenze von 500-Ausgabetoken unabhängig von der Detailstufe - die benutzerdefinierte Eingabeaufforderung ist in Ihrer Kontrolle und die Obergrenze schützt vor außer Kontrolle geratenen Antworten.",
"sizingTitle": "Praktische Dimensionierung",
"sizingBody": "Schätzen Sie den Verbrauch als umgeschriebene Ereignisse × KI-Kanäle × Eingabe- und Ausgabe-Token je Aufruf. Beispiel: 50 Ereignisse × ein Kanal × (2.000 Eingabe + 300 Ausgabe) ergeben etwa 115.000 Token täglich, da allein der Standard-Systemprompt rund 1.500 Token umfasst. Tatsächlicher Verbrauch und Kosten hängen von Modell, Kontext, Cache und Anbieterlimits ab. Der Abschnitt <link>Detailstufe pro Kanal</link> erklärt <code>brief</code> für Chats statt <code>standard</code>, bei weiterhin ausführlichen E-Mail-Berichten."
},
"providers": {
"heading": "KI-Anbieter",
"intro": "Sechs Anbieter sind mit dem Monitor verbunden. Die Anbieter-Dropdown in der Benutzeroberfläche zeigt sie alle; ein Informationsbutton daneben öffnet ein Modal mit einer einzeiligen Beschreibung für jeden. Unten finden Sie die vollständige Referenz mit der URL zum Erhalten eines API-Schlüssels, der Beschreibung in der Benutzeroberfläche und den entsprechenden Notizen aus der Codebasis.",
"imageAlt": "AI Providers Informationen modal Auflistung der sechs unterstützten Anbieter - Groq, OpenAI, Anthropic Claude, Google Gemini, Ollama, OpenRouter - jeder mit seinem Symbol und einzeilige Beschreibung und eine spezielle OpenAI-Kompatible APIs Hinweis für OpenAI",
"imageCaption": "Informationsfenster mit sechs Karten, einer je Anbieter, und den unten beschriebenen Angaben.",
"groq": {
"heading": "Groq",
"tagline": "Sehr schnelle, großzügige freie Stufe (30 req/min). Ideal zum Starten.",
"items": [
"API-Schlüssel: <a>console.groq.com/keys</a>",
"Beispiele aus der mitgelieferten Modellliste: <code>allam-2-7b</code>, <code>qwen/qwen3.8-27b</code>, <code>openai/gpt-oss-20b</code>, <code>groq/compound-mini</code>.",
"Mitgelieferte Empfehlung: <strong><code>openai/gpt-oss-20b</code></strong>. Prüfen Sie die Verfügbarkeit für Ihr Konto über die Anbieterauswahl und den Verbindungstest."
]
},
"openai": {
"heading": "OpenAI",
"tagline": "Industriestandard. Sehr genau und weit verbreitet.",
"items": [
"API-Schlüssel: <a>platform.openai.com/api-keys</a>",
"Beispiele aus der mitgelieferten Modellliste: <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>.",
"Mitgelieferte Empfehlung: <strong><code>gpt-4.1-nano</code></strong>. Der Adapter unterstützt auch besondere Anforderungen von Reasoning-Modellen; die Liste enthält gpt-5-nano. Diese Modelle sind daher nicht pauschal ausgeschlossen."
],
"baseUrlTitle": "OpenAI-kompatible Basis URL",
"baseUrlBody": "Der OpenAI-Anbieter akzeptiert eine eigene <em>Basis-URL</em> für OpenAI-kompatible Endpunkte, etwa <strong>BytePlus / ByteDance (Kimi K2.5)</strong>, <strong>LocalAI</strong>, <strong>LM Studio</strong>, <strong>vLLM</strong>, <strong>Together AI</strong> und <strong>Fireworks AI</strong>, die das Format <code>/v1/chat/completions</code> unterstützen. Tragen Sie die URL im OpenAI-Bereich neben dem API-Schlüssel ein."
},
"anthropic": {
"heading": "Anthropic (Claude)",
"tagline": "Hervorragend zum Schreiben und Übersetzen. Schnell und wirtschaftlich.",
"items": [
"API-Schlüssel: <a>console.anthropic.com/settings/keys</a>",
"Beispiele aus der mitgelieferten Modellliste: <code>claude-haiku-4-5-20251001</code>, <code>claude-sonnet-4-6</code>, <code>claude-opus-4-6</code>.",
"Mitgelieferte Empfehlung: <strong><code>claude-haiku-4-5-20251001</code></strong>, ein fest angehefteter Snapshot statt eines wechselnden Alias."
]
},
"gemini": {
"heading": "Google Gemini",
"tagline": "Kostenloses Kontingent verfügbar, gutes Verhältnis von Qualität und Preis.",
"items": [
"API-Schlüssel: <a>aistudio.google.com/app/apikey</a>",
"Beispiele aus der mitgelieferten Modellliste: <code>gemini-2.5-flash-lite</code>, <code>gemini-2.5-flash</code>, <code>gemini-3-flash-preview</code>.",
"Empfohlen: <strong><code>gemini-2.5-flash-lite</code></strong> - Flash und Flash-Lite passieren den Verifier konsequent. Die Pro-Varianten lehnen die <code>thinkingBudget=0</code>-Einstellung ab, die der Monitor verwendet, und sind für diese Workload übertrieben."
]
},
"openrouter": {
"heading": "OpenRouter",
"tagline": "Aggregator mit Zugriff auf 100+ Modelle mit einem einzigen API-Schlüssel. Maximale Flexibilität.",
"items": [
"API-Schlüssel: <a>openrouter.ai/keys</a>",
"Beispiele aus der mitgelieferten Modellliste: <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>.",
"Empfohlen: <strong><code>meta-llama/llama-3.3-70b-instruct</code></strong> - dasselbe Modell wie der Groq-Eintrag, aber über OpenRouter geroutet, was einen einzigen Schlüssel für alle aufgeführten Modelle bedeutet."
]
},
"ollama": {
"heading": "Ollama (lokal)",
"tagline": "Nutzt die Modelle Ihres konfigurierten Ollama-Servers. Lokale Modelle laufen dort; Ollama-Cloud-Modelle leiten Anfragen an einen Cloud-Anbieter weiter. Lokale Ausführung vermeidet gehostete API-Gebühren, verbraucht aber eigene Hardware und Strom.",
"items": [
"Kein API-Schlüssel. Setzen Sie das <em>Ollama URL</em>-Feld auf Ihren Server (Standard <code>http://localhost:11434</code> oder welcher Host Ihre Ollama-Instanz ausführt).",
"Modelle: <strong>nicht gefiltert.</strong> Der Monitor liest die Modelle, die Sie auf der Ollama-Seite über <code>ollama pull &lt;model&gt;</code> gezogen haben. Der Dropdown wird von <code>GET /api/tags</code> auf Ihrem Ollama-Server ausgefüllt.",
"Installieren: <a>ollama.com/download</a> – läuft unter Linux, macOS, Windows. Für beste Ergebnisse wählen Sie ein Modell, das in RAM mit einem ausreichend großen Kontextfenster für die Journalblöcke passt, die der Dispatcher injiziert."
]
}
},
"models": {
"heading": "Warum diese spezifischen Modelle",
"intro": "Die Modellauswahl nutzt den mitgelieferten Katalog <code>verified_ai_models.json</code> und Verfügbarkeitsprüfungen der Anbieteradapter. Diese setzen die interne Anfrage <code>system_prompt + user_message + max_tokens</code> in das jeweilige API-Format um. Der Katalog enthält getestete und manuell ergänzte Einträge; er garantiert weder aktuellen Kontozugriff noch denselben Verifikationstest für jedes Modell.",
"consequencesIntro": "Zwei Konsequenzen, die es wert sind, beachtet zu werden:",
"consequences": [
"<strong>Die mitgelieferte Empfehlung</strong> ist ein Ausgangspunkt für Benachrichtigungen. Bewerten Sie Sprachqualität, Latenz und Kosten mit Ihren Ereignissen und Ihrem Konto; sie ist keine allgemeine Modellrangliste.",
"<strong>Sie können ein anderes aufgeführtes Modell wählen</strong>, passend zu Kontingent und Vorlieben. Prüfen Sie die Verfügbarkeit mit dem Verbindungstest; ein Listeneintrag garantiert keinen aktuellen Kontozugriff."
],
"ollamaTitle": "Ollama ist die Ausnahme",
"ollamaBody": "Die Ollama-Auswahl wird nicht vom kommerziellen Katalog gefiltert; sie zeigt die Modelle des Ollama-Servers. Wählen Sie für lokale Ausführung ein lokales Modell mit ausreichend RAM und Kontext für Journalblöcke. Cloud-Modelle bleiben auch über einen lokalen Ollama-Server remote."
},
"defaultPrompt": {
"heading": "Standard-Eingabeaufforderung",
"intro": "Im Modus <em>Standard</em> nutzt Monitor den unten gezeigten Systemprompt. Vor dem Aufruf werden die Platzhalter ersetzt: <code>'{'language'}'</code>, <code>'{'detail_level'}'</code>, <code>'{'emoji_instructions'}'</code>, <code>'{'suggestions_addon'}'</code>. Danach folgen Varianten für formatierte und einfache Kanäle sowie der Zusatz für KI-Vorschläge.",
"showFullSummary": "Vollständige Standardsystemaufforderung anzeigen",
"passagesIntro": "Zwei Textvarianten werden entsprechend dem Schalter <em>Formatierte Nachrichten</em> des jeweiligen Kanals eingesetzt:",
"passages": [
"<strong>Rich on</strong> → ein Emoji-Block wird eingeschleust, der die Symbole auflistet, die der LLM verwenden kann, sowie eine Hostnamenregel (der LLM muss das Hostnamenpräfix aus dem Titel wörtlich beibehalten) und eine Handvoll formatierter Beispiele (Backup-Start, Backup vollständig, Updates, VM Start, Gesundheit beeinträchtigt). Dies erzeugt die emoji-präfixierten Nachrichten auf Telegram und Discord.",
"<strong>Rich off</strong> → Ein einzeiliger Block weist den LLM an, nur einfache ASCII zu verwenden - keine Emojis, keine Unicode-Symbole. Wird für E-Mails und jeden Kanal verwendet, bei dem Formatierungsgeräusche die Posteingangsregeln oder die Lesbarkeit verletzen."
],
"suggestionsPlaceholder": "Und der <code>'{'suggestions_addon'}'</code> Platzhalter ist leer, es sei denn, Sie aktivieren AI Suggestions (nächster Abschnitt), in welchem Fall dieser Block injiziert wird:",
"showAddonSummary": "AI Suggestions Addon anzeigen"
},
"customPrompt": {
"heading": "Benutzerdefinierter Eingabeaufforderungsmodus",
"intro": "Der Modus <em>Benutzerdefiniert</em> ersetzt den gesamten Standard-Systemprompt durch Ihren eigenen Text. Er wird in den SQLite-Einstellungen gespeichert und bei jedem KI-Aufruf unverändert gesendet. So können Sie Ton, Aufbau und Schwerpunkt frei festlegen.",
"imageAlt": "Eigener Prompt mit Textfeld für Übersetzungsregeln, Export- und Import-Schaltflächen sowie Link zu Community-Prompts",
"imageCaption": "Benutzerdefinierte Eingabeaufforderung — großer Textbereich mit der Eingabeaufforderung des Benutzers sowie <em>Export</em>, <em>Import</em> und ein Link zur Community-Galerie auf GitHub.",
"changesTitle": "Was sich ändert, wenn Custom eingeschaltet ist",
"changes": [
"<strong>Die Standardaufforderung wird vollständig ersetzt.</strong> Die Proxmox-Mappings, die Kontext-Handling-Regeln und die Emoji-Anweisungen sind alle verschwunden. Wenn Sie eine davon behalten möchten, fügen Sie sie in Ihre Eingabeaufforderung ein - die unten gezeigte gebündelte <code>EXAMPLE_CUSTOM_PROMPT</code> ist ein Ausgangspunkt.",
"<strong>Die Sprachauswahl wird ignoriert.</strong> Die Standard-Eingabeaufforderung hat einen <code>'{'language'}'</code>-Platzhalter; die benutzerdefinierte Eingabeaufforderung nicht. Wenn Sie eine Ausgabe in einer bestimmten Sprache wünschen, deklarieren Sie sie in Ihrer Eingabeaufforderung (\"Ins Spanische übersetzen\", \"Alles auf Französisch ausgeben\").",
"<strong>Der eigene Prompt hat ein festes Limit von 500 Token</strong>, unabhängig von der gespeicherten Detailstufe. Der Standardmodus nutzt 500 / 1500 / 3000. Prompt-Änderungen erhöhen das Limit nicht; fordern Sie kürzere Antworten an oder wählen Sie eine passende Standardstufe.",
"<strong>Die Ausgabemarker bleiben erforderlich.</strong> Geben Sie <code>[TITLE]</code> und <code>[BODY]</code> im Antwortformat vor. Der Parser liest deren Inhalt; fehlt ein Marker, wird die ursprüngliche Vorlage verwendet.",
"<strong>Emoji-Regeln formatierter Nachrichten werden nicht automatisch ergänzt.</strong> Fordern Sie Emojis im eigenen Prompt ausdrücklich an oder untersagen Sie sie für Klartext. Der Schalter steuert nur die Standardblöcke, nicht Ihren eigenen Text."
],
"starterTitle": "Startaufforderung",
"starterIntro": "Der Textbereich <em>Benutzerdefinierte Eingabeaufforderung</em> wird mit einem minimalen Beispiel ausgeliefert, das Sie anpassen können:",
"showStarterSummary": "Benutzerdefinierten Beispielprompt anzeigen",
"shareTitle": "Aufforderungen mit der Community teilen",
"shareIntro": "Die Schaltfläche <em>Export</em> schreibt Ihre aktuelle benutzerdefinierte Eingabeaufforderung in eine Datei (<code>.txt</code> / <code>.md</code>), die Sie als Backup oder Hand an eine andere Person speichern können. <em>Import</em> zieht einen zurück. Der dritte Button neben ihnen verlinkt zu einer öffentlichen Community-Galerie auf GitHub:",
"shareLinkLabel": "github.com/MacRimi/ProxMenux/discussions — Eigene Prompts für KI-Benachrichtigungen teilen",
"shareOutro": "Durchsuchen sie die diskussion, um zu sehen, was andere betreiber erstellt haben - knappe pager-alarme, ausführliche technische berichte, sprachspezifische varianten. Wenn Sie Ihre optimieren und das Ergebnis mögen, posten Sie es dort: Selbst eine Beschreibung mit einem Absatz, für die Ihre Eingabeaufforderung optimiert wird, hilft den Menschen, einen guten Ausgangspunkt zu finden. Feedback darüber, was funktioniert und was nicht, ist ebenso willkommen."
},
"suggestions": {
"heading": "KI-Vorschläge (BETA)",
"intro": "KI-Vorschläge sind ein optionaler Zusatz für <strong>einen</strong> kurzen, umsetzbaren Tipp am Ende der Nachricht. Dafür müssen Modus <em>Standard</em>, der KI-Hauptschalter und <em>KI-Vorschläge</em> aktiv sein. Der Prompt verlangt, den Tipp bei unklarer Ursache oder Lösung auszulassen.",
"formatIntro": "Wenn ein Tipp hinzugefügt wird, folgt er genau diesem Format:",
"rulesIntro": "Die Regeln im Addon (sichtbar im zusammenklappbaren Block unter der Standard-Eingabeaufforderung oben):",
"rules": [
"Der Tipp ist <em>nur</em> enthalten, wenn der Journalkontext oder die Datenbank mit bekannten Fehlern eindeutig auf einen bestimmten Fix hinweist.",
"Der Prompt verlangt einen Tipp unter 100 Zeichen; der Parser prüft diese Länge nicht unabhängig.",
"Der Prompt verlangt einen konkreten Befehl oder Pfad und weist das Modell an, allgemeine Ratschläge zu vermeiden.",
"Wenn ein bekannter Fehler eine Lösung bietet, muss der LLM diese Lösung verwenden und keine neue erfinden.",
"Der Prompt weist das Modell an, den Tipp wegzulassen, wenn die Eingabe keine konkrete Lösung belegt."
],
"betaTitle": "Warum Beta",
"betaBody": "Die Tip-Qualität hängt von zwei Dingen ab, die außerhalb von ProxMenux liegen: das ausgewählte Modell und wie reich der Journal-Kontext für die Veranstaltung war. Mit einem starken Modell (Claude 3.5 Haiku, GPT-4.1 Mini, Llama 3.3 70B) und einem Festplattenfehler, der mit smartctl + Zeitschriftenzeilen geliefert wird, ist der Tipp durchweg nützlich. Mit einem winzigen lokalen Ollama-Modell und einem einzeiligen Ereignis kann die Spitze flach fallen oder ganz übersprungen werden. Deaktivieren Sie den Schalter, wenn Sie die Tipps laut finden, und aktivieren Sie ihn wieder, wenn Sie ihn zurückhaben möchten."
},
"detailLevel": {
"heading": "Detailebene pro Kanal",
"intro": "Telegram, Discord, Gotify und E-Mail haben jeweils eine eigene Auswahl der Detailstufe. Drei Werte steuern im Standardprompt sowohl das Ausgabe-Token-Limit als auch die Detailvorgaben:",
"headerLevel": "Ebene",
"headerLabel": "UI-Kennzeichnung",
"headerCap": "Ausgabegrenze",
"headerProduce": "Was der Prompt vom LLM verlangt",
"rows": [
{
"level": "kurz",
"label": "2–3 Zeilen, nur das Wesentliche",
"cap": "500-Token",
"produce": "\"Was passiert ist + wo\". Nichts anderes."
},
{
"level": "Standard",
"label": "Knapp mit grundlegendem Kontext",
"cap": "1500-Token",
"produce": "3–6 Zeilen: was, wo, Ursache, betroffene Geräte."
},
{
"level": "ausführlich",
"label": "Vollständige technische Angaben",
"cap": "3000-Token",
"produce": "Vollständiger Bericht: was, wo, Ursache, Betroffene, Protokolle, SMART-Daten und Verlauf."
}
],
"defaultsIntro": "Standardwerte bei der ersten Installation:",
"defaults": [
"<strong>Telegram, Discord, Gotify</strong> — <code>standard</code>.",
"<strong>Email</strong> — <code>detailed</code>. E-Mail ist der Kanal, in dem Sie normalerweise das vollständige Bild für die Archivierung wünschen."
],
"emailTitle": "E-Mail-Detailebene fügt das Original hinzu",
"emailBody": "Liefert der KI-Formatter ein Ergebnis für E-Mail mit <code>detailed</code> und hat der Ursprungstext mehr als 50 Zeichen, hängt er ihn nach 40 Bindestrichen und <code>Original message:</code> an. Das bewahrt Details für spätere Suchen. Bei KI-Umgehung oder Fehlern kann nur die ursprüngliche Vorlage versendet werden."
},
"language": {
"heading": "Sprache",
"intro": "Die Oberflächenauswahl bietet dreizehn Sprachen. Sie speichert <code>ai_language</code>, das der Standardprompt in <em>\"translate alerts into '{'language'}'\"</em> verwendet. Die Liste:",
"list": "Englisch (<code>en</code>), Slowakisch (<code>sk</code>), Spanisch (<code>es</code>), Französisch (<code>fr</code>), Deutsch (<code>de</code>), Portugiesisch (<code>pt</code>), Italienisch (<code>it</code>), Russisch (<code>ru</code>), Schwedisch (<code>sv</code>), Norwegisch (<code>no</code>), Japanisch (<code>ja</code>), Chinesisch (<code>zh</code>), Niederländisch (<code>nl</code>).",
"rulesIntro": "Zwei wichtige Regeln direkt aus der Aufforderung:",
"rules": [
"<strong>Übersetzen</strong>: Beschriftungen, Beschreibungen, Statuswörter und Einheiten, etwa GB → Go auf Französisch.",
"<strong>Nicht übersetzen</strong>: Hostnamen, IPs, Pfade, VM/CT IDs, Gerätenamen wie <code>/dev/sdX</code>, technische Identifikatoren. Diese bleiben wortwörtlich unabhängig von der Sprache."
],
"customNote": "Der eigene Prompt <strong>verwendet die Sprachauswahl nicht</strong>. Geben Sie die gewünschte Ausgabesprache direkt im Prompt an."
},
"templates": {
"heading": "Ein Hinweis auf Vorlagen",
"body1": "Die KI erhält formatierten Vorlagentext statt roher Ereignisdaten. Typen wie <code>vm_start</code>, <code>auth_fail</code> und <code>health_degraded</code> haben Vorlagen in <code>notification_templates.py</code>. Die KI formuliert geeignete Texte um; <code>backup_complete</code> und <code>backup_fail</code> behalten deterministische Berichte und umgehen die KI.",
"body2": "Zwei praktische Implikationen: Die KI sieht nie einen Hostnamen oder VMID, den sie erfinden muss - diese Felder werden von der Vorlage vor dem Umschreiben platziert. Und wenn AI deaktiviert ist, wird der vorgefertigte Körper direkt versandt. Die <link>Notifications</link>-Seite dokumentiert die Versandpipeline vollständig und ist der richtige Querverweis für alles, was mit einem Ereignis passiert, bevor es diese Ebene erreicht."
},
"privacy": {
"heading": "Datenschutz & Datenfluss",
"intro": "Bei aktivierter KI-Umschreibung sendet Monitor den Vorlagentext samt Kontextblöcken an den Anbieter. Dazu können Hostnamen, IP-Adressen, Benutzernamen, Gerätepfade, Journalzeilen und SMART-Attribute des betroffenen Geräts gehören. Ob diese Daten den Host verlassen, hängt vom Anbieter ab:",
"headerProvider": "Anbieter",
"headerDestination": "Datenziel",
"rows": [
{
"provider": "Ollama",
"destination": "Lokale Modelle laufen auf dem konfigurierten Ollama-Host. Ist dies der Proxmox-Knoten selbst, bleiben ihre Anfragen dort. Ollama-Cloud-Modelle senden Anfragen nach außen, auch über einen lokalen Ollama-Server."
},
{
"provider": "OpenAI",
"destination": "Standardmäßig <code>api.openai.com</code> oder die konfigurierte eigene Basis-URL. Es gelten die Datenverarbeitungsregeln des tatsächlichen Endpunktbetreibers."
},
{
"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> leitet an den im Feld <code>model</code> gewählten Modellanbieter weiter. Zwei Verarbeitungsstationen statt einer."
}
],
"calloutTitle": "Wenn Ereignisinhalte das Netzwerk nicht verlassen können",
"calloutBody": "Nutzen Sie einen lokal gehosteten Endpunkt mit lokalem Modell, etwa Ollama oder einen OpenAI-kompatiblen Server, oder deaktivieren Sie die KI. Ollama-Cloud-Modelle verarbeiten Daten nicht lokal. Der Dispatcher anonymisiert keine Hostnamen oder IP-Adressen; er nutzt den tatsächlichen Ereignisinhalt."
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "Benachrichtigungen",
"href": "/docs/monitor/notifications",
"tail": "— die Versandpipeline, Kanäle, Per-Event-Toggles und die PVE webhook-Integration, die diese Schicht umgibt."
},
{
"label": "Gesundheitsmonitor",
"href": "/docs/monitor/health-monitor",
"tail": "— der größte Einzelproduzent von Ereignissen, den die KI am Ende umschreibt, mit eigenen Unterdrückungsdauern pro Kategorie."
},
{
"label": "Architektur",
"href": "/docs/monitor/architecture",
"tail": "- wo der AI Enhancer in den breiteren Monitor-Prozess passt (es ist ein Modul, kein separater Dienst)."
}
],
"communityLabel": "Community prompts auf GitHub",
"communityTail": "- durchsuchen, teilen, fragen."
}
}
@@ -0,0 +1,760 @@
{
"meta": {
"title": "Proxmox-Monitor-API — Integrationsreferenz | ProxMenux",
"description": "HTTP-Endpunkte von ProxMenux Monitor für Home Assistant, Homepage, Grafana, Prometheus, n8n und eigene Dashboards. Zustand abfragen und dokumentierte Änderungen anstoßen: VM-Steuerung, Sicherungen, Benachrichtigungen und Warnungsbestätigung.",
"ogTitle": "Proxmox-Monitor-API — Integrationsreferenz",
"ogDescription": "ProxMenux-Monitor-Endpunkte für Home Assistant, Homepage, Grafana, Prometheus, n8n und eigene Dashboards.",
"twitterTitle": "Proxmox-Monitor-API | ProxMenux",
"twitterDescription": "Endpunkte für Home Assistant, Homepage, Grafana, Prometheus, n8n und eigene Dashboards."
},
"header": {
"title": "API-Referenz",
"description": "HTTP-Endpunkte zum Lesen des Zustands und Aufrufen dokumentierter Aktionen: Home-Assistant-Sensoren, Homepage-Karten, Grafana-Dashboards, Prometheus-Erfassung, n8n-Abläufe und eigene Skripte. Mit Kategorien, exportierten Metriken und curl-Beispielen.",
"section": "ProxMenux Monitor"
},
"intro": {
"title": "Wofür diese Seite ist",
"body": "Diese Seite enthält Endpunkte für externe Integrationen: Datenabruf und Aktionen wie Sicherungen, eigene Meldungen und Warnungsbestätigung. Die API läuft im Flask-Prozess des Dashboards auf TCP <strong>8008</strong>. Bindeadresse und TLS beschreibt <link>Zugriff und Authentifizierung</link>."
},
"headerEndpoint": "Endpunkt",
"headerMethod": "Methode",
"headerUse": "Verwendung",
"auth": {
"heading": "Authentifizierung",
"intro": "Bei aktiver Authentifizierung erwarten geschützte Endpunkte ein JWT-Bearer-Token im Anfrageheader:",
"tokensIntro": "Zwei Möglichkeiten, das Token zu erhalten:",
"items": [
"<strong>API-Token, für Integrationen empfohlen.</strong> Sie gelten 365 Tage und entstehen unter <strong>Sicherheit → API-Token</strong>. Sie haben Namen und sind einzeln widerrufbar. read_only dient dem Datenabruf; full_admin wählen Sie nur für benötigte Verwaltungsaktionen.",
"<strong>Anmeldung, JWT für 24 Stunden.</strong> <code>POST /api/auth/login</code> mit Benutzername, Passwort und TOTP, falls 2FA dies verlangt. Das JWT läuft nach 24 Stunden ab; Skripte müssen sich danach erneut anmelden."
],
"flowLink": "Anmeldung, Passwörter, 2FA, Auditprotokoll und TLS erklärt <link>Zugriff und Authentifizierung</link>.",
"rows": [
{
"endpoint": "/api/auth/login",
"method": "POST",
"use": "Anfragefelder (Schema): <code>'{'\"username\",\"password\",\"totp_token?\"'}'</code>. Liefert ein JWT für 24 Stunden."
},
{
"endpoint": "/api/auth/api-tokens",
"method": "GET",
"use": "Listen Sie API-Token auf (nur Metadaten - Namen, Präfixe, Daten; niemals das eigentliche Geheimnis)."
},
{
"endpoint": "/api/auth/generate-api-token",
"method": "POST",
"use": "Erstellt mit einer angemeldeten Sitzung ein API-Token für 365 Tage. Felder: <code>password, token_name?, totp_token?, scope?</code>. Passwort und erforderliches TOTP werden erneut geprüft. scope ist standardmäßig read_only; full_admin muss ausdrücklich gewählt werden. Der geheime Wert erscheint nur einmal."
},
{
"endpoint": "/api/auth/api-tokens/<id>",
"method": "DELETE",
"use": "Widerruf eines bestimmten API-Tokens durch seine ID."
}
]
},
"conventions": {
"heading": "Konventionen",
"items": [
"Die meisten Endpunkte verwenden JSON. Downloads können Klartext liefern; <code>/api/prometheus</code> liefert das Prometheus-Textformat 0.0.4 statt OpenMetrics. Prüfen Sie den Antworttyp der jeweiligen Route.",
"Viele Schreiboperationen liefern <code>'{'\"success\": true, ...'}'</code>. Fehlerformate variieren; häufig ist <code>'{'\"success\": false, \"error\": \"'<'reason'>'\"'}'</code>. Prüfen Sie HTTP-Status und Felder: manche Authentifizierungsanforderungen liefern HTTP 200 mit success false.",
"Abfrageparameter hängen vom Endpunkt ab. Verwenden Sie <code>limit</code>, <code>offset</code>, <code>since</code> und Kategoriefilter nur, wenn die Route sie unterstützt.",
"Zeitformate variieren: Unix-Zeitstempel, ISO-8601-Zeichenfolgen und systemd-Datumsformate kommen vor. Nicht jedes Feld hat dieselbe Einheit oder eine ausdrückliche Zeitzone."
]
},
"system": {
"heading": "System und Hardware",
"rows": [
{
"endpoint": "/api/system",
"method": "GET",
"use": "Aktuelle Werte für CPU, RAM, Swap, Betriebszeit und Last."
},
{
"endpoint": "/api/info",
"method": "GET",
"use": "Statische Host-Infos: Hostname, Kernel, PVE-Version, CPU-Modell, Distribution."
},
{
"endpoint": "/api/system-info",
"method": "GET",
"use": "Erweiterte Systemdaten der Dashboard-Kopfzeile: Gesamtmetriken und Startzeitpunkt."
},
{
"endpoint": "/api/hardware",
"method": "GET",
"use": "Detaillierter Hardwarebestand: PCI-Geräte, GPUs und Sensorzuordnung."
},
{
"endpoint": "/api/hardware/live",
"method": "GET",
"use": "Aktuelle Werte schnell veränderlicher Sensoren."
},
{
"endpoint": "/api/temperature/history",
"method": "GET",
"use": "Zeitreihen der CPU- und Package-Temperaturen."
},
{
"endpoint": "/api/gpu/<slot>/realtime",
"method": "GET",
"use": "Aktuelle GPU-Metriken von NVIDIA, Intel und AMD je PCI-Slot."
}
]
},
"actions": {
"heading": "Systemaktionen",
"intro": "Diese asynchronen Systemaktionen laufen in temporären systemd-Units. Bei aktiver Authentifizierung verlangen ihre Schreibzugriffe <code>full_admin</code>; <code>read_only</code> darf <code>.../status</code> abfragen. Angenommene Starts liefern HTTP 202 mit Zustand; <code>.../status</code> zeigt den Fortschritt. Gaststeuerung und Sicherungen haben andere Antworten, siehe unten.",
"shapeTitle": "Gemeinsames Antwortformat",
"shapeIntro": "Asynchrone Systemaktionen teilen das folgende JSON-Zustandsobjekt. Gaststeuerung und Sicherungen antworten in anderen Formaten:",
"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": "Parallele Ausführung und Abbruch",
"concurrencyBody": "Ein zweiter Start derselben laufenden Aktion liefert HTTP 409. Abbruch gibt es nur mit dokumentierter DELETE-Route, etwa beim PVE-Update. Der Zustand wird <code>cancelled</code>, Zeitstempel bleiben erhalten. Endzustände liegen im Prozessspeicher und können beim Monitor-Neustart verloren gehen.",
"rows": [
{
"endpoint": "/api/system/power/reboot",
"method": "POST",
"use": "Startet den Neustart des Proxmox-Hosts. Die HTTP-Verbindung kann beim Beginn der Abschaltung durch systemd abbrechen."
},
{
"endpoint": "/api/system/power/reboot/status",
"method": "GET",
"use": "Zustand des aktuellen oder letzten Neustarts."
},
{
"endpoint": "/api/system/power/shutdown",
"method": "POST",
"use": "Schaltet den Proxmox-Host aus, etwa als Reaktion auf ein USV-Abschaltsignal."
},
{
"endpoint": "/api/system/power/shutdown/status",
"method": "GET",
"use": "Zustand der aktuellen oder letzten Abschaltung."
},
{
"endpoint": "/api/system/pve-update/run",
"method": "POST",
"use": "Startet denselben PVE-Updateablauf wie Jetzt aktualisieren im Health Monitor und das Shell-Menü; delegiert an update-pve-safe.sh."
},
{
"endpoint": "/api/system/pve-update/status",
"method": "GET",
"use": "Zustand des aktuellen oder letzten PVE-Updates."
},
{
"endpoint": "/api/system/pve-update",
"method": "DELETE",
"use": "Bricht ein laufendes PVE-Update mit SIGTERM ab."
},
{
"endpoint": "/api/proxmenux/self-update/run",
"method": "POST",
"use": "Aktualisiert ProxMenux mit dem Installer des eingestellten Stable- oder Beta-Kanals. Eine eigene systemd-Unit lässt den Auftrag den vom Installer ausgelösten proxmenux-monitor-Neustart überstehen."
},
{
"endpoint": "/api/proxmenux/self-update/status",
"method": "GET",
"use": "Zustand der aktuellen oder letzten ProxMenux-Selbstaktualisierung."
},
{
"endpoint": "/api/vms/<vmid>/control",
"method": "POST",
"use": "Übermittelt die Steuerung einer VM oder eines LXC. <code>action</code> erlaubt <code>start</code>, <code>stop</code>, <code>shutdown</code> oder <code>reboot</code>. Eine erfolgreiche Antwort enthält einen bestätigten PVE-Task und bedeutet nicht dessen Abschluss. Fragen Sie den control-task-Endpunkt des Gastes für das Ergebnis ab."
},
{
"endpoint": "/api/vms/<vmid>/backup",
"method": "POST",
"use": "Erstellt eine vzdump-Sicherung einer VM oder eines LXC. Felder im Body, alle optional, sofern die Vorgaben zum Speicheraufbau passen: <code>storage</code> (ein PVE-Speicher), <code>mode</code> (<code>snapshot</code>, <code>suspend</code> oder <code>stop</code>), <code>compress</code> (<code>zstd</code>, <code>lzo</code>, <code>gzip</code> oder <code>none</code>), <code>protected</code> (<code>true</code> oder <code>false</code>), <code>notes</code> und <code>pbs_change_detection</code> (<code>default</code>, <code>legacy</code> oder <code>data</code>). Liefert die UPID des PVE-Tasks."
},
{
"endpoint": "/api/vms/<vmid>/backups",
"method": "GET",
"use": "Listet bisherige Sicherungen einer VM oder eines LXC auf allen erreichbaren Speichern auf."
}
],
"syncVsAsyncTitle": "Zwei Arten von Aktionen",
"syncVsAsyncBody": "Host-Stromsteuerung und Updates laufen in temporären systemd-Units mit <code>.../status</code>. Nur das PVE-Update hat hier eine <code>DELETE</code>-Abbruchroute. VM/LXC-Steuerung liefert einen abzufragenden Task, Sicherung eine UPID für einen Hintergrundauftrag. Annahme bedeutet nicht Abschluss. Authentifizierung und Rechte hängen von der Route ab.",
"curlTitle": "curl-Beispiel",
"curlBody": "Startet ein PVE-Update und fragt bis zum Abschluss ab, wie eine Home-Assistant-Automation oder ein Ansible-Playbook.",
"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": "Home-Assistant-Beispiel",
"haBody": "Ein <code>rest</code>-Sensor fragt den Zustand ab; <code>rest_command</code> startet das Update. Binden Sie beide in Dashboard-Schaltflächen und Automationen ein:",
"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": "Gesundheitsmonitor",
"rows": [
{
"endpoint": "/api/health",
"method": "GET",
"use": "Kleine Zustandsprüfung mit JSON-Feldern <code>status</code>, <code>timestamp</code> und <code>version</code>. Für Uptime-Kuma-Schlüsselwortprüfungen geeignet; bei aktiver Authentifizierung muss der Client den Bearer-Header senden."
},
{
"endpoint": "/api/health/status",
"method": "GET",
"use": "Gesamtzustand: ein Schweregrad und eine Zusammenfassung."
},
{
"endpoint": "/api/health/details",
"method": "GET",
"use": "Alle zehn Kategorien mit Zustand und strukturierten Daten der jeweiligen Prüfung."
},
{
"endpoint": "/api/health/full",
"method": "GET",
"use": "Vollständige Daten: Kategorien, aktive Fehler, unterdrückte Warnungen und Einstellungen. Hintergrunddaten werden genutzt, wenn sie jünger als sechs Minuten sind; sonst oder bei erzwungener Aktualisierung läuft eine neue Prüfung."
},
{
"endpoint": "/api/health/active-errors",
"method": "GET",
"use": "Aktive Liste, filterbar durch <code>?category=&lt;name&gt;</code>."
},
{
"endpoint": "/api/health/dismissed",
"method": "GET",
"use": "Unterdrückte Warnungen mit verbleibenden Stunden."
},
{
"endpoint": "/api/health/settings",
"method": "GET",
"use": "Eingestellte Unterdrückungsdauer je Kategorie."
},
{
"endpoint": "/api/health/remote-storages",
"method": "GET",
"use": "Inventar von Proxmox-definierten Fernspeichern mit Online-Status."
},
{
"endpoint": "/api/health/interfaces",
"method": "GET",
"use": "Netzwerkschnittstellen mit Typ (Bridge / Bond / physisch), IP und Verbindungsgeschwindigkeit."
},
{
"endpoint": "/api/health/acknowledge",
"method": "POST",
"use": "Anfrageinhalt: <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Unterdrückt eine Warnung für die eingestellte Dauer ihrer Kategorie."
},
{
"endpoint": "/api/health/cleanup-orphans",
"method": "POST",
"use": "Manuelle Bereinigung von Fehlern, deren zugrunde liegendes Gerät oder VM verschwunden ist. Idempotent."
}
],
"outro": "Antwortformate und Kategorien erklärt <link>Health Monitor</link>."
},
"storage": {
"heading": "Speicher",
"rows": [
{
"endpoint": "/api/storage",
"method": "GET",
"use": "Für den Host sichtbare Datenträger: Blockgeräte, ZFS-Pools und LVM."
},
{
"endpoint": "/api/storage/summary",
"method": "GET",
"use": "Kompakte Zusammenfassung, die von Dashboardkarten verwendet wird."
},
{
"endpoint": "/api/proxmox-storage",
"method": "GET",
"use": "Proxmox-definierte Speicher von <code>/etc/pve/storage.cfg</code> mit Online-Zustand und freiem Speicherplatz."
},
{
"endpoint": "/api/storage/observations",
"method": "GET",
"use": "Dauerhaft gespeicherte Beobachtungen: SMART-Warnungen, E/A-Fehler und ZFS-Ereignisse. Bleiben nach automatischer Fehlerauflösung erhalten."
},
{
"endpoint": "/api/storage/smart/<disk>",
"method": "GET",
"use": "Aktuelle SMART Attribute für eine Festplatte."
},
{
"endpoint": "/api/storage/smart/<disk>/latest",
"method": "GET",
"use": "Aktueller SMART Selbsttest für die Festplatte."
},
{
"endpoint": "/api/storage/smart/<disk>/history",
"method": "GET",
"use": "Liste der gespeicherten SMART-Berichte für die Festplatte."
},
{
"endpoint": "/api/storage/smart/<disk>/history/<file>",
"method": "GET",
"use": "Lesen Sie einen spezifischen gespeicherten SMART-Bericht."
},
{
"endpoint": "/api/storage/smart/<disk>/test",
"method": "POST",
"use": "Startet einen SMART-Selbsttest. Anfrageschema: <code>'{'\"test_type\":\"short\"|\"long\"'}'</code>."
},
{
"endpoint": "/api/storage/smart/schedules",
"method": "GET",
"use": "Listen Sie die derzeit geplanten SMART-Tests auf."
},
{
"endpoint": "/api/storage/smart/tools",
"method": "GET",
"use": "Prüft, ob <code>smartctl</code> und zugehörige Werkzeuge installiert sind."
}
]
},
"network": {
"heading": "Netzwerk",
"rows": [
{
"endpoint": "/api/network",
"method": "GET",
"use": "Alle Schnittstellen mit Linkzustand und Adressen."
},
{
"endpoint": "/api/network/summary",
"method": "GET",
"use": "Kompakte Ansicht, die vom Dashboard verwendet wird."
},
{
"endpoint": "/api/network/<iface>/metrics",
"method": "GET",
"use": "RX/TX je Schnittstelle, Fehlerzähler und RRD-Zeitreihen."
},
{
"endpoint": "/api/network/latency/current",
"method": "GET",
"use": "Letzte Latenzmessung zum Gateway."
},
{
"endpoint": "/api/network/latency/history",
"method": "GET",
"use": "Zeitreihe der Gateway-Latenz."
}
]
},
"vms": {
"heading": "VMs und Container",
"rows": [
{
"endpoint": "/api/vms",
"method": "GET",
"use": "VMs und CTs des lokalen Knotens mit Zustand, vmid und Name."
},
{
"endpoint": "/api/vms/<vmid>",
"method": "GET",
"use": "Vollständige Details für einen Gast (Konfiguration, Netzwerk, Festplatten)."
},
{
"endpoint": "/api/vms/<vmid>/metrics",
"method": "GET",
"use": "CPU / Speicher / Festplatte I/O Zeitreihe für einen Gast (RRD)."
},
{
"endpoint": "/api/vms/<vmid>/logs",
"method": "GET",
"use": "Aktuelle Task-Protokolle dieses Gastes."
},
{
"endpoint": "/api/vms/<vmid>/backups",
"method": "GET",
"use": "Für diesen Gast gespeicherte Sicherungen."
},
{
"endpoint": "/api/vms/<vmid>/control",
"method": "POST",
"use": "Wählen Sie eine Aktion aus dem Schema: <code>'{'\"action\":\"start|stop|reboot|shutdown\"'}'</code>. Steuert den Betriebszustand des Gastes."
},
{
"endpoint": "/api/vms/<vmid>/backup",
"method": "POST",
"use": "Startet <code>vzdump</code> für den Gast. Die Anfrage legt Speicher und Modus fest (<code>snapshot</code> / <code>suspend</code> / <code>stop</code>)."
},
{
"endpoint": "/api/vms/<vmid>/config",
"method": "PUT",
"use": "Aktualisieren Sie das Beschreibungsfeld (Notizen) eines VM / CT. Andere Konfigurationsschlüssel sind von diesem Endpunkt aus nicht veränderbar."
},
{
"endpoint": "/api/node/metrics",
"method": "GET",
"use": "Zusammengefasste Knotenmetriken als RRD-Zeitreihen."
}
]
},
"backups": {
"heading": "Sicherungen",
"rows": [
{
"endpoint": "/api/backups",
"method": "GET",
"use": "Sicherungen auf dir-, NFS-, CIFS- und PBS-Speichern, die über den lokalen Knoten abgefragt werden. Keine vollständige Prüfung aller Clusterknoten."
},
{
"endpoint": "/api/backup-storages",
"method": "GET",
"use": "Als Sicherungsziele gekennzeichnete Speicher mit freiem Platz."
}
]
},
"logs": {
"heading": "Protokolle, Aufgaben, Ereignisse",
"rows": [
{
"endpoint": "/api/logs",
"method": "GET",
"use": "Gefilterte Journaleinträge. Anfrage: <code>?level=&service=&limit=</code>."
},
{
"endpoint": "/api/logs/download",
"method": "GET",
"use": "Exportiert den gefilterten Bereich als Klartext."
},
{
"endpoint": "/api/events",
"method": "GET",
"use": "Interner Ereignisstrom - derselbe, der Benachrichtigungen füttert."
},
{
"endpoint": "/api/task-log/<upid>",
"method": "GET",
"use": "Vollständiges Klartextprotokoll eines Proxmox-Tasks anhand seiner UPID."
}
]
},
"notifications": {
"heading": "Benachrichtigungen und KI",
"intro": "Versand, Kanaleinrichtung und KI-Umformulierung erklären <notifLink>Benachrichtigungen</notifLink> und <aiLink>KI-Assistent</aiLink>.",
"rows": [
{
"endpoint": "/api/notifications",
"method": "GET",
"use": "Im Dashboard angezeigte aktuelle Benachrichtigungen."
},
{
"endpoint": "/api/notifications/download",
"method": "GET",
"use": "Exportiert Benachrichtigungen als Text."
},
{
"endpoint": "/api/notifications/status",
"method": "GET",
"use": "Versandzustand: aktiver Hintergrundprozess, Warteschlangenlänge und letzter Versand."
},
{
"endpoint": "/api/notifications/settings",
"method": "GET",
"use": "Liest die Benachrichtigungseinstellungen: Kanäle, Ereignisschalter, KI-Umformulierung und Anzeigename."
},
{
"endpoint": "/api/notifications/history",
"method": "GET",
"use": "Versandverlauf. Parameter: <code>?limit=&offset=&severity=&channel=</code>."
},
{
"endpoint": "/api/notifications/history",
"method": "DELETE",
"use": "Leert die Tabelle des Versandverlaufs."
},
{
"endpoint": "/api/notifications/test",
"method": "POST",
"use": "Sendet eine Testnachricht an einen Kanal. Anfrageinhalt: <code>'{'\"channel\":\"telegram\"'}'</code>."
},
{
"endpoint": "/api/notifications/send",
"method": "POST",
"use": "Erzeugt ein eigenes Ereignis. Anfrageinhalt: <code>'{'\"event_type\":\"custom\",\"severity\":\"WARNING\",\"title\":\"...\",\"body\":\"...\",\"data\":'{''}''}'</code>."
},
{
"endpoint": "/api/notifications/test-ai",
"method": "POST",
"use": "Prüft die Verbindung zum KI-Anbieter. Anfragefelder (Schema): <code>'{'\"provider\",\"api_key\",\"model\",\"ollama_url?\"'}'</code>."
},
{
"endpoint": "/api/notifications/provider-models",
"method": "POST",
"use": "Listen Sie verfügbare Modelle für den ausgewählten AI-Anbieter auf."
},
{
"endpoint": "/api/notifications/proxmox/setup-webhook",
"method": "POST",
"use": "Registrieren Sie den Monitor als webhook-Ziel in <code>/etc/pve/notifications.cfg</code>."
},
{
"endpoint": "/api/notifications/proxmox/cleanup-webhook",
"method": "POST",
"use": "Entfernen Sie das Monitor-Ziel aus der Benachrichtigungskonfiguration von PVE."
},
{
"endpoint": "/api/notifications/proxmox/read-cfg",
"method": "GET",
"use": "Lesen Sie den aktuellen <code>notifications.cfg</code> von PVE, wie PVE ihn sieht."
}
]
},
"security": {
"heading": "Sicherheit (lesen)",
"rows": [
{
"endpoint": "/api/security/firewall/status",
"method": "GET",
"use": "PVE Firewall Status und aktive Regeln."
},
{
"endpoint": "/api/security/fail2ban/details",
"method": "GET",
"use": "Zustand des Fail2Ban-Jails; setzt diese optionale Installation voraus."
},
{
"endpoint": "/api/security/fail2ban/activity",
"method": "GET",
"use": "Aktuelle Fail2Ban-Ereignisse: Sperren, Entsperren und Jail-Starts."
},
{
"endpoint": "/api/security/lynis/status",
"method": "GET",
"use": "Lynis-Zustand: Installation und Zeitpunkt der letzten Prüfung."
},
{
"endpoint": "/api/security/lynis/report",
"method": "GET",
"use": "Letzter Lynis-Auditbericht: Warnungen, Vorschläge und Hardening-Index."
},
{
"endpoint": "/api/security/tools",
"method": "GET",
"use": "Erkennen Sie, welche optionalen Sicherheitstools (Fail2Ban, Lynis) installiert sind."
}
]
},
"proxmenuxIntegration": {
"heading": "ProxMenux Integration",
"rows": [
{
"endpoint": "/api/proxmenux/update-status",
"method": "GET",
"use": "Verfügbarkeit eines ProxMenux-Monitor-Updates sowie installierte und neueste Version."
},
{
"endpoint": "/api/proxmenux/installed-tools",
"method": "GET",
"use": "Liste jeder ProxMenux-Postinstallationsoptimierung, die derzeit auf dem Host registriert ist (ab <code>/usr/local/share/proxmenux/installed_tools.json</code>)."
},
{
"endpoint": "/api/proxmenux/tool-source/<key>",
"method": "GET",
"use": "Quellcode der zugeordneten Nachinstallationsfunktion aus aktuellen Host-Skripten oder erhaltenem älterem Code. Kein garantiertes Abbild des ursprünglich ausgeführten Codes."
}
]
},
"prometheus": {
"heading": "Prometheus-Metriken",
"intro": "Der authentifizierte Endpunkt <code>GET /api/prometheus</code> liefert das Prometheus-Textformat 0.0.4. Jede Metrik enthält <code>node=\"&lt;hostname&gt;\"</code> und einen Zeitstempel. Erfassen Sie sie mit Prometheus oder einer kompatiblen Zeitreihendatenbank.",
"exportedTitle": "Exportierte Metriken",
"headerGroup": "Gruppe",
"headerMetric": "Metrik",
"headerDesc": "Beschreibung",
"groups": [
{
"group": "System",
"metrics": [
{
"metric": "proxmox_cpu_usage",
"desc": "CPU-Auslastung in Prozent, Typ Gauge."
},
{
"metric": "proxmox_memory_total_bytes",
"desc": "Physikalischer Gesamtspeicher in Bytes."
},
{
"metric": "proxmox_memory_used_bytes",
"desc": "Belegter Arbeitsspeicher in Bytes."
},
{
"metric": "proxmox_memory_usage_percent",
"desc": "Prozentsatz des Speicherverbrauchs."
},
{
"metric": "proxmox_load_average",
"desc": "Systemlastdurchschnitt. Kennzeichnung <code>period=\"1m\" | \"5m\" | \"15m\"</code>."
}
]
},
{
"group": "Betriebszeit",
"metrics": [
{
"metric": "proxmox_uptime_seconds",
"desc": "Sekunden seit dem letzten Systemstart."
}
]
},
{
"group": "Hardware",
"metrics": [
{
"metric": "proxmox_cpu_temperature_celsius",
"desc": "CPU-Package-Temperatur."
},
{
"metric": "proxmox_disk_temperature_celsius",
"desc": "Temperatur je Datenträger. Label <code>disk</code>."
},
{
"metric": "proxmox_fan_speed_rpm",
"desc": "Lüfterdrehzahlen. Label <code>fan</code>."
}
]
},
{
"group": "Speicherplatz",
"metrics": [
{
"metric": "proxmox_disk_total_bytes",
"desc": "Gesamtkapazität je exportiertem Datenträgereintrag. Label <code>disk</code>."
},
{
"metric": "proxmox_disk_used_bytes",
"desc": "Belegte Kapazität je exportiertem Datenträgereintrag."
},
{
"metric": "proxmox_disk_usage_percent",
"desc": "Prozentual belegte Kapazität je exportiertem Datenträgereintrag."
}
]
},
{
"group": "Netzwerk",
"metrics": [
{
"metric": "proxmox_network_bytes_sent_total",
"desc": "Gesendete Bytes insgesamt, Typ Counter."
},
{
"metric": "proxmox_network_bytes_received_total",
"desc": "Empfangene Bytes insgesamt, Typ Counter."
},
{
"metric": "proxmox_interface_bytes_sent_total",
"desc": "Gesendete Bytes je Schnittstelle. Label <code>interface</code>."
},
{
"metric": "proxmox_interface_bytes_received_total",
"desc": "Empfangene Bytes je Schnittstelle."
}
]
},
{
"group": "VMs / CTs",
"metrics": [
{
"metric": "proxmox_vms_total",
"desc": "Gesamtzahl VMs und LXCs."
},
{
"metric": "proxmox_vms_running",
"desc": "Anzahl laufender Gäste."
},
{
"metric": "proxmox_vms_stopped",
"desc": "Anzahl der gestoppten Gäste."
},
{
"metric": "proxmox_vm_status",
"desc": "Zustand je VM/CT: 1 läuft, 0 sonst. Labels <code>node</code>, <code>vmid</code> und <code>name</code>."
},
{
"metric": "proxmox_vm_cpu_usage",
"desc": "CPU-Auslastung je VM/CT mit denselben Labels."
},
{
"metric": "proxmox_vm_memory_used_bytes / _max_bytes",
"desc": "Belegter RAM und konfiguriertes Maximum je VM/CT."
}
]
},
{
"group": "GPU",
"metrics": [
{
"metric": "proxmox_gpu_temperature_celsius",
"desc": "GPU-Temperatur. Labels <code>slot</code> und <code>vendor</code>; gpu enthält zusätzlich den GPU-Namen."
},
{
"metric": "proxmox_gpu_utilization_percent",
"desc": "GPU-Auslastung in Prozent."
},
{
"metric": "proxmox_gpu_memory_total_bytes",
"desc": "Gesamter GPU-Speicher."
},
{
"metric": "proxmox_gpu_power_draw_watts",
"desc": "GPU-Leistungsaufnahme in Watt."
},
{
"metric": "proxmox_gpu_clock_speed_mhz",
"desc": "GPU-Kerntakt."
},
{
"metric": "proxmox_gpu_memory_clock_mhz",
"desc": "GPU-Speichertakt."
}
]
},
{
"group": "UPS",
"metrics": [
{
"metric": "proxmox_ups_battery_charge_percent",
"desc": "Batterieladung in Prozent."
},
{
"metric": "proxmox_ups_load_percent",
"desc": "Aktuelle Belastung der USV."
},
{
"metric": "proxmox_ups_runtime_seconds",
"desc": "Geschätzte Laufzeit im Batteriebetrieb."
},
{
"metric": "proxmox_ups_input_voltage_volts",
"desc": "Eingangsspannung."
}
]
}
],
"scrapeTitle": "Prometheus-Scrape-Konfiguration",
"scrapeIntro": "Bei aktiver Authentifizierung tragen Sie ein API-Token als Bearer-Header in die Prometheus-Erfassungskonfiguration ein:",
"perHostTitle": "Erfassung je Host",
"perHostBody": "Jede Instanz exportiert Metriken ihres eigenen Hosts. Lassen Sie Prometheus im Cluster jeden Knoten abfragen. Das Label <code>node</code> unterscheidet die Reihen in Grafana (<code>proxmox_vms_running'{'node=\"pve01\"'}'</code>)."
},
"puttingItTogether": {
"heading": "Integrationen zusammenführen",
"body": "<link>Integrationen</link> erklärt die Anbindung an Home-Assistant-Sensoren, Homepage-Karten, Grafana-Dashboards, n8n-Abläufe und weitere Werkzeuge. Dort finden Sie typische Konfigurationen zum Kopieren. Diese Seite enthält den Endpunktkatalog."
},
"whereNext": {
"heading": "Weitere Schritte",
"items": [
{
"label": "Zugriff und Authentifizierung",
"href": "/docs/monitor/access-auth",
"tail": " — Token-Erstellung, Auditprotokoll, optionales Fail2Ban-Jail und TLS."
},
{
"label": "Benachrichtigungen",
"href": "/docs/monitor/notifications",
"tailRich": " — Inhalt von <code>data</code> je Ereignistyp beim Aufruf von <code>/api/notifications/send</code>."
},
{
"label": "KI-Assistent",
"href": "/docs/monitor/ai-assistant",
"tailRich": " — Funktionsweise von <code>/api/notifications/test-ai</code> und <code>/api/notifications/provider-models</code>."
},
{
"label": "Gesundheitsmonitor",
"href": "/docs/monitor/health-monitor",
"tailRich": " — Antwortformat von <code>/api/health/*</code> und Bedeutung der zehn Kategorien."
}
]
}
}
@@ -0,0 +1,303 @@
{
"meta": {
"title": "Architektur von ProxMenux Monitor — AppImage, Flask, SQLite, WebSocket | ProxMenux",
"description": "Aufbau von ProxMenux Monitor: AppImage-Struktur, Flask-Blueprints, Hintergrundaufgaben, Daten aus psutil, pvesh, smartctl und journalctl, SQLite-Speicherung, WebSocket-Terminal, KI-Anbieter, Benachrichtigungskanäle, Reverse-Proxy und optionales Fail2Ban.",
"ogTitle": "ProxMenux Monitor Architektur",
"ogDescription": "ProxMenux Monitor intern: AppImage, Flask-Blueprints, Hintergrundaufgaben, SQLite, WebSocket, KI-Anbieter und Benachrichtigungskanäle.",
"twitterTitle": "ProxMenux Monitor Architektur",
"twitterDescription": "AppImage, Flask, SQLite, WebSocket, KI-Anbieter und Benachrichtigungskanäle — innerhalb des Monitors."
},
"header": {
"title": "Architektur",
"description": "Wie ProxMenux Monitor ausgeliefert wird, was das AppImage enthält und wie Browseranfragen über Flask zu Host-Werkzeugen und SQLite gelangen.",
"section": "ProxMenux Monitor"
},
"intro": {
"title": "Ein Prozess, viele Verantwortlichkeiten",
"body": "Ein Python-Prozess lauscht auf TCP 8008. Er liefert den statischen Next.js-Build aus, stellt die REST-API bereit, verwaltet das WebSocket-Terminal, führt den Health Monitor aus und versendet Meldungen. Ein separater Webserver, Nachrichtenbroker oder externer Datenbankserver ist nicht erforderlich."
},
"requestFlow": {
"heading": "Ablauf einer Anfrage",
"intro": "Eine typische Datenanfrage folgt diesem Weg; reine Browsereinstellungen können lokal bleiben:",
"diagramCaption": "Geschützte Routen prüfen JWT bei aktiver Authentifizierung. Kernrouten und Blueprints liefern zwischengespeicherte oder neu erfasste Host-Daten. Der optionale Fail2Ban-Hook prüft seine zwischengespeicherte Sperrliste. Weitergeleitete IP-Header gelten nur mit PROXMENUX_TRUST_PROXY=1; sonst zählt die Gegenstellenadresse. Dauerhafter Zustand liegt in SQLite und JSON-Dateien wie auth.json.",
"diagramArrowLabel": "HTTP / WS",
"nodes": {
"clientLabel": "Client",
"clientDetail": "Browser oder PWA\n+ optionaler Proxy\nNginx / Caddy /\nTraefik",
"flaskLabel": "Flask :8008",
"flaskDetail": "Blueprints\nJWT-Middleware\nFail2Ban-Hook\n(falls installiert)",
"hostLabel": "Host-Tools",
"hostDetail": "psutil\npvesh\nsmartctl\njournalctl",
"stateLabel": "Lokaler Zustand",
"stateDetail": "SQLite DB\n+ auth.json"
},
"threadsIntro": "Der Prozess führt auch <strong>Hintergrundthreads</strong> aus. Diese Beispiele erfassen Daten, aktualisieren Caches und SQLite und versenden Meldungen. Weitere Aufgaben existieren; der Versand hängt von seiner Aktivierung ab:",
"headerThread": "Thread",
"headerCadence": "Intervall",
"headerJob": "Auftrag",
"rows": [
{
"thread": "_temperature_collector_loop",
"cadence": "60 s",
"job": "Speichert CPU-Temperatur und Latenzproben in der Verlaufsdatenbank, damit Diagramme auch ohne verbundenen Browser Daten haben."
},
{
"thread": "_health_collector_loop",
"cadence": "5 min",
"job": "Führt den Health-Monitor-Zyklus mit zehn Kategorien aus, speichert Fehler und Datenträgerbeobachtungen, berücksichtigt Unterdrückungen und übergibt neue Ereignisse an den Benachrichtigungsdienst."
},
{
"thread": "_vital_signs_sampler",
"cadence": "CPU 5 s; Temperatur 15 s; RAM 30 s",
"job": "Erfasst CPU-Auslastung, RAM und CPU-Temperatur für aktuelle Anzeigen und anhaltende Zustände, unabhängig von der fünfminütigen Gesamtprüfung."
},
{
"thread": "notification_manager.start()",
"cadence": "Ereignisgesteuert",
"job": "Startet Beobachter für Journal, Tasks und Hooks (<code>JournalWatcher</code>, <code>TaskWatcher</code>, <code>ProxmoxHookWatcher</code>) und sendet an eingerichtete Kanäle, optional mit KI-Umformulierung."
}
]
},
"systemd": {
"heading": "systemd-Einheit",
"intro": "Der Installer erstellt die Unit <code>/etc/systemd/system/proxmenux-monitor.service</code>. Standardkonfiguration:",
"items": [
"<strong><code>User=root</code></strong>: Der Dienst verwendet Root-Rechte für Host-Operationen wie SMART, <code>pvesh</code> und ZFS-Verwaltung. Die Webterminal-Prozesse erben diese Rechte.",
"<strong><code>Restart=on-failure</code></strong> mit zehn Sekunden Wartezeit: Nach fehlerhaftem Ende startet der Dienst automatisch neu.",
"<strong><code>After=network.target</code></strong>: ordnet den Start nach diesem Ziel ein; garantiert keine IP-Adresse, DNS oder externe Verbindung."
],
"inspectTitle": "Aktuelle Unit prüfen"
},
"appimage": {
"heading": "Was das AppImage enthält",
"intro": "Das AppImage enthält ein beim Start eingehängtes Dateisystem. <code>AppRun</code> im Wurzelverzeichnis bereitet die Umgebung vor und startet <code>flask_server.py</code>:",
"consequencesIntro": "Zwei Konsequenzen dieses Layouts:",
"consequences": [
"<strong>Mitgelieferte Python-Pakete.</strong> Die Python-Pakete liegen im AppImage und laufen mit dem Python-Interpreter des Hosts, 3.11 (PVE 8) oder 3.13 (PVE 9), ohne dass etwas in das System-Python des Hosts installiert wird. Die Anwendung nutzt weiterhin Kernel-Schnittstellen des Hosts und externe Host-Werkzeuge.",
"<strong>Hardware-Clients sind enthalten.</strong> Mitgeliefert werden <code>ipmitool</code>, <code>lm-sensors</code> und <code>upsc</code>. Messwerte erfordern unterstützte Hardware, Sensorzugriff und für USV-Daten einen eingerichteten NUT-Server."
]
},
"flask": {
"heading": "Struktur der Flask-Anwendung",
"intro": "<code>flask_server.py</code> erstellt eine <code>Flask(__name__)</code>-Instanz mit eingeschränkten CORS-Ursprüngen, registriert zehn Blueprints direkt und initialisiert Terminalrouten. Die Tabelle zeigt die Hauptmodule; die Blueprints für PBS, Monitor-Links, Audit und VM-Sicherung sind ebenfalls registriert. PVE-spezifische Vorwärmer laufen nur auf PVE-Hosts.",
"headerBlueprint": "Blueprint / Modul",
"headerPrefix": "Routenpräfix",
"headerOwns": "Zuständigkeit",
"rows": [
{
"blueprint": "flask_server.py",
"prefix": [
"/api/system",
"/api/storage",
"/api/network",
"/api/vms",
"/api/hardware",
"/api/logs",
"/api/prometheus"
],
"owns": "Kernendpunkte, statische Weboberfläche und optionale Fail2Ban-Prüfung bei vorhandenem Jail <code>proxmenux</code> auf dem Host."
},
{
"blueprint": "flask_auth_routes.py",
"prefix": [
"/api/auth/*"
],
"owns": "Anmeldung, JWT-Ausgabe, TOTP-Einrichtung und -Prüfung, Passwortänderung und API-Token."
},
{
"blueprint": "flask_health_routes.py",
"prefix": [
"/api/health/*"
],
"owns": "Zustandsprüfungen, Detailstatus, aktive und unterdrückte Fehler sowie Unterdrückungseinstellungen. Geschützte Routen verlangen Authentifizierung, wenn aktiviert."
},
{
"blueprint": "flask_terminal_routes.py",
"prefix": [
"/api/terminal/* + WS"
],
"owns": "Stellt je Sitzung ein PTY bereit und verbindet es über WebSocket mit <code>xterm.js</code> im Browser."
},
{
"blueprint": "flask_notification_routes.py",
"prefix": [
"/api/notifications/*"
],
"owns": "Kanäle anlegen, lesen, ändern und löschen; Testversand, KI, Verlauf und manuelle Meldungen."
},
{
"blueprint": "flask_security_routes.py",
"prefix": [
"/api/security/*"
],
"owns": "Anmeldefehler und bei installiertem Fail2Ban Jail-Zustand, Sperrereignisse und manuelles Entsperren."
},
{
"blueprint": "flask_proxmenux_routes.py",
"prefix": [
"/api/proxmenux/*"
],
"owns": "Liest die im Host-Bestand registrierten ProxMenux-Optimierungen."
},
{
"blueprint": "flask_oci_routes.py",
"prefix": [
"/api/oci/*"
],
"owns": "Hilfen zur Bereitstellung von OCI- und Container-Apps auf Proxmox VE 9.1+."
}
],
"endpointsLink": "Integrationsendpunkte und ihre Formate erklärt <link>API-Referenz</link>."
},
"dataSources": {
"heading": "Datenquellen",
"intro": "Host-Daten stammen überwiegend aus Standardbibliotheken, Dateien und Verwaltungsbefehlen. Einige Gastdaten benötigen zusätzlich den QEMU Guest Agent oder Befehle innerhalb eines CT:",
"headerSource": "Quelle",
"headerUsedFor": "Verwendet für",
"rows": [
{
"source": "psutil",
"usedFor": "CPU-Last, RAM, Swap, Belegung von Einhängepunkten, Netzwerkzähler und Prozesse."
},
{
"source": "pvesh / qm / pct",
"usedFor": "Proxmox-Knoteninformationen, VM-/CT-Bestand und Konfiguration, Speicher sowie Task-Verlauf."
},
{
"source": "smartctl",
"usedFor": "SATA-/NVMe-Attribute, SMART-Zustand, Verschleiß, Lebensdauer, Modell und Seriennummer."
},
{
"source": "zpool / zfs",
"usedFor": "Poolzustand (ONLINE / DEGRADED / FAULTED / UNAVAIL), Scrub-Fortschritt und Dataset-Belegung."
},
{
"source": "journalctl",
"usedFor": "Systemprotokolle, OOM-Abbrüche, ATA-/NVMe-/dm-Fehler, Sicherheitsereignisse und eigene Service-Units."
},
{
"source": "ip / iproute2",
"usedFor": "Schnittstellen, Adressen, Bridges, Bonds und OVS-verwaltete Geräte."
},
{
"source": "nvidia-smi · intel_gpu_top",
"usedFor": "Verfügbare GPU-Daten zu Auslastung, VRAM, Temperatur und Encoder/Decoder. Felder hängen von Hersteller, Werkzeug und Treiber ab."
},
{
"source": "lspci · lscpu · dmidecode",
"usedFor": "PCIe-Topologie, CPU-Modell und -Topologie sowie Mainboard- und BIOS-Daten."
},
{
"source": "ipmitool · sensors",
"usedFor": "Out-of-Band-Sensoren, Lüfterdrehzahlen und Mainboard-Temperaturen bei unterstützter Hardware."
},
{
"source": "upsc (NUT)",
"usedFor": "Batteriezustand, Last und Restlaufzeit der USV bei eingerichtetem NUT-Server."
}
],
"cacheTitle": "Caches reduzieren Host-Abfragen",
"cacheBody": "Aufwendige Ergebnisse von <code>smartctl -a</code> und <code>pvesh get</code> werden im Flask-Prozess zeitweise gespeichert, um Datenträger und Cluster-API seltener abzufragen. Die Dauer hängt von der Quelle ab: Sekunden für aktuelle Metriken, Minuten für SMART."
},
"persistence": {
"heading": "Persistenz",
"intro": "Mehrere Zustandsdateien haben unterschiedliche Inhalte und Zugriffsanforderungen:",
"headerPath": "Path",
"headerOwner": "Eigentümer",
"headerContents": "Inhalt",
"rows": [
{
"path": "/usr/local/share/proxmenux/health_monitor.db",
"owner": "root:root",
"contents": "SQLite-Datenbank. Tabellen: <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>. WAL-Journalmodus."
},
{
"path": "/usr/local/share/proxmenux/.notification_key",
"owner": "root <code>0600</code>",
"contents": "32-Byte-Hauptschlüssel für Benachrichtigungsgeheimnisse im ENC2-Format. Verwendet zufälliges Salt je Wert, abgeleitete Schlüssel und MAC. Alte XOR-Werte werden zur Migration unterstützt."
},
{
"path": "/root/.config/proxmenux-monitor/auth.json",
"owner": "root:root",
"contents": "Authentifizierungskonfiguration: Aktivierung, Benutzername, gesalzener PBKDF2-HMAC-SHA256-Passworthash, TOTP-Geheimnis, Wiederherstellungscodes, installationsbezogener JWT-Schlüssel, API-Token-Metadaten und Widerrufshashes. Alte SHA-256-Hashes werden nach erfolgreicher Anmeldung migriert."
},
{
"path": "/var/log/proxmenux-auth.log",
"owner": "root:root",
"contents": "Klartextprotokoll der Authentifizierung, unabhängig von Fail2Ban. Ist das Jail <code>[proxmenux]</code> installiert und aktiv, liest es das Protokoll zur Erkennung wiederholter Anmeldefehler. Ohne Jail bleibt das Protokoll zur Prüfung verfügbar."
}
],
"backupTitle": "auth.json vor der Neuinstallation sichern",
"backupBody": "Ein AppImage-Austausch bewahrt normalerweise <code>/root/.config/proxmenux-monitor/auth.json</code> und <code>/usr/local/share/proxmenux/health_monitor.db</code>. Bewahren Sie <code>auth.json</code> samt jwt_secret für gültige Token und Metadaten. Die Datenbank enthält unabhängig Zustands- und Meldungsdaten. Sichern Sie <code>.notification_key</code> mit ihr für verschlüsselte Kanaleinstellungen; die Datenbank allein stellt API-Authentifizierung nicht wieder her."
},
"health": {
"heading": "Health-Monitor-Zyklus",
"intro": "Etwa alle fünf Minuten ruft der Hintergrundkollektor <code>health_monitor.py</code> für die Prüfungen der zehn Dashboard-Kategorien auf:",
"items": [
"Kritische PVE-Dienste (<code>pveproxy</code>, <code>pvedaemon</code>, <code>pvestatd</code>, <code>pve-cluster</code>).",
"Proxmox-Speicher: <code>pvesh get /storage</code> und Verfügbarkeit je Speicher.",
"Datenträger und Dateisysteme: SMART, E/A-Fehler in dmesg, ZFS-Zustand und Belegung von Einhängepunkten.",
"VMs und CTs: Startfehler, Abstürze, QMP-Fehler und Probleme beim Herunterfahren.",
"Netzwerk: Bridge- und Bond-Zustand, Verbindungsstatus und Gateway-Latenz.",
"Updates: ausstehende Paketaktualisierungen und Sicherheitspatches.",
"Protokolle: anhaltende Muster, Spitzen und Kaskaden im Systemjournal.",
"Arbeitsspeicher: OOM-Killer-Aktivität und anhaltender Speicherdruck.",
"CPU: Auslastung und CPU-Temperatur im Vergleich zu den konfigurierbaren Schwellen; verfügbare Sensoren hängen von der Hardware ab.",
"Sicherheit: Anmeldefehler, Sperrereignisse und Fail2Ban-Jail-Zustand."
],
"afterIntro": "Befunde verwenden stabile <code>error_key</code>, Kategorie und Schweregrad. Vorhandene Einträge in <code>errors</code> werden an Ort und Stelle aktualisiert (<code>last_seen</code>, Schweregrad, Grund), statt dupliziert zu werden. Der Benachrichtigungsversand hat zudem eigene Regeln für Fingerabdrücke und Wartezeiten.",
"cycleEnd": "Die Bereinigung kann alte Fehler anhand der <em>Unterdrückungsdauer</em> je Kategorie und Zustandsregeln auflösen, verwaiste Einträge entfernter Ressourcen entfernen und <code>events</code> über 30 Tage löschen. Kategorien erklärt <link>Dashboard → Health Monitor</link>."
},
"notifications": {
"heading": "Benachrichtigungsmotor",
"intro": "<code>notification_manager.py</code> koordiniert den Versand: lädt Kanäle, verwaltet die Warteschlange und bietet eine Python-API für Flask und Health Monitor sowie einen CLI-Einstieg für ProxMenux-Hooks in <code>.sh</code>.",
"items": [
"<strong>Beobachter</strong> erzeugen Ereignisse: <code>JournalWatcher</code> verfolgt das Journal, <code>TaskWatcher</code> fragt Proxmox-Tasks ab, <code>ProxmoxHookWatcher</code> empfängt Sicherungs-, Replikations- und Snapshot-Hooks und <code>PollingCollector</code> verarbeitet langsame Quellen.",
"<strong>Vorlagen</strong> erzeugen Titel und Nachricht aus Ereignissen. Der konfigurierte KI-Anbieter (OpenAI / Anthropic / Gemini / Groq / Ollama / OpenRouter) kann sie verständlich umformulieren. Beide Fassungen werden in <code>notification_history</code> gespeichert.",
"<strong>Kanäle</strong> versenden über Dienste wie Telegram, Discord, E-Mail, Gotify, Pushover und Apprise. Implementierungen in <code>notification_channels.py</code> teilen die Schnittstelle <code>create_channel()</code> / <code>send()</code>.",
"<strong>Verschlüsselung.</strong> Vertrauliche Einstellungen (<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>) werden vor dem Speichern mit dem Schlüssel aus <code>.notification_key</code> verschlüsselt und in der Oberfläche maskiert."
],
"linksFooter": "Ereignisschalter, kanalspezifische Einstellungen und KI erklären <notifLink>Einstellungen → Benachrichtigungen</notifLink> und <aiLink>Einstellungen → KI-Assistent</aiLink>."
},
"websocket": {
"heading": "WebSocket Terminal",
"intro": "Die Registerkarte <em>Terminal</em> verbindet einen schlanken <code>xterm.js</code>-Client über WebSocket mit einem serverseitigen PTY. Es gibt zwei Betriebsarten:",
"items": [
"<strong>HTTP-Modus, Standard:</strong> Der integrierte Flask-Server verarbeitet mit <code>flask-sock</code> WebSocket-Upgrade-Anfragen.",
"<strong>HTTPS-/WSS-Modus:</strong> Der TLS-Server verwendet <code>gevent.pywsgi.WSGIServer</code> mit dessen Standard-Handler; <code>flask-sock</code> verarbeitet WebSocket-Verbindungen über TLS."
],
"outro": "Terminal-Kindprozesse erben <code>User=root</code> vom Dienst. Das Öffnen eines WebSockets erfordert ein kurzlebiges Einmalticket vom authentifizierten Terminal-Ticket-Endpunkt mit Verwaltungsrechten.",
"proxyNote": "Beim Reverse-Proxy muss WebSocket-Weiterleitung mit den Headern <code>Upgrade</code> und <code>Connection</code> funktionieren. Das Terminal benötigt diese Weiterleitung."
},
"proxy": {
"heading": "Reverse-Proxy und Fail2Ban",
"intro": "Client-IP-Auswahl und optionale Sperrung in der Anwendung hängen von diesen Einstellungen und Komponenten ab:",
"items": [
"<strong>Client-IP-Auswahl.</strong> Die Sperrprüfung in <code>before_request</code> und das Auth-Protokoll vertrauen <code>X-Forwarded-For</code>, danach <code>X-Real-IP</code>, nur mit PROXMENUX_TRUST_PROXY=1. Sonst gilt <code>request.remote_addr</code>. Weitergeleitete Header werden nicht automatisch akzeptiert.",
"<strong>Optionales Fail2Ban in der Anwendung.</strong> Bei Proxyverbindungen kann die Proxy-IP als TCP-Gegenstelle erscheinen. Sind die vertrauenswürdige Client-IP und das aktive Jail <code>proxmenux</code> verfügbar, weist Flask gesperrte IPs mit HTTP 403 zurück. Die Liste wird 30 Sekunden gespeichert und bei späteren Anfragen erneuert, nicht durch einen eigenen Timer."
],
"calloutTitle": "Fail2Ban ist nicht enthalten",
"calloutBody": "Fail2Ban ist <strong>nicht</strong> enthalten und wird nicht automatisch installiert. Die Installation ist über Monitor-Sicherheit oder <link>Sicherheit → Fail2Ban</link> in ProxMenux Scripts möglich. Fehlen <code>fail2ban-client</code> oder das Jail <code>proxmenux</code>, blockiert dieser Hook keine Anfragen. Die eingestellte Authentifizierung gilt weiter.",
"outro": "Beispiele für Nginx, Caddy und Traefik sowie die Jail-Anleitung stehen unter <accessLink>Zugriff und Authentifizierung</accessLink> und <fail2banLink>Sicherheit → Fail2Ban</fail2banLink>."
},
"whereNext": {
"heading": "Weitere Schritte",
"items": [
{
"label": "Zugriff und Authentifizierung",
"href": "/docs/monitor/access-auth",
"tail": " — Ersteinrichtung, Passwort und TOTP-2FA, Reverse-Proxy-Beispiele und Fail2Ban-Jail."
},
{
"label": "API-Referenz",
"href": "/docs/monitor/api",
"tail": " — Integrationsendpunkte, Token-Verwaltung und Authentifizierungskonventionen."
},
{
"label": "Einstellungen → ProxMenux Monitor",
"href": "/docs/settings/proxmenux-monitor",
"tail": " — Dienststeuerung und Zustandsprüfung im ProxMenux-Textmenü."
}
]
}
}
@@ -0,0 +1,218 @@
{
"meta": {
"title": "Bewertung und Bestandsaufnahme | Prüfung und Bericht",
"description": "Bewertung in Prüfung und Bericht: Berichtsprofile, Einstufung der Ergebnisse, akzeptierte Risiken, nicht lesbare Quellen, Lynis und Bestandsaufnahme des Knotens."
},
"header": {
"title": "Bewertung und Bestandsaufnahme",
"description": "Die Bewertung überprüft den Knoten, behält seine Ergebnisse und beantwortet je nach Berichtsprofil verschiedene Fragen.",
"section": "Prüfung und Bericht"
},
"sections": [
{
"id": "read-only",
"blocks": [
{
"calloutInfo": {
"title": "Eine Bewertung prüft; sie ändert keine Konfiguration",
"body": "Es liest die Konfiguration und den Zustand des Hosts. Es schreibt seine Ergebnisse, Berichte und Protokolle, und die Boot-Checks können EFI-Systempartitionen für einen Moment montieren. Die von ihm bewertete Konfiguration wird nicht geändert."
}
},
{
"p": "<strong>Bewertung ausführen</strong> startet einen Durchlauf mit dem unter <strong>Bericht</strong> gewählten Profil. Die Ansicht zeigt das Datum des letzten Durchlaufs und die seitdem vergangene Zeit."
}
]
},
{
"id": "profiles",
"title": "Berichtsprofile",
"intro": "Jedes Profil beantwortet eine andere Frage. Die Prüfungen und Abschnitte werden ausgewählt, bevor das Dokument erstellt wird.",
"blocks": [
{
"table": {
"headers": [
"Profil",
"Was es abdeckt"
],
"rows": [
[
"Vollständiges Audit",
"Alle Prüfungen und die gesamte verfügbare Struktur."
],
[
"Schnelldiagnose",
"Jede Überprüfung; das Ergebnis beginnt mit den kritischen Ergebnissen, den Warnungen und den Messwerten, die nicht verifiziert werden konnten."
],
[
"Inventar",
"Eine Beschreibung des Knotens, ohne Überprüfungen und ohne Klassifizierung."
],
[
"Sicherheitsüberprüfung",
"Exposition, Zugriff, Privilegien, Zertifikate, Updates, Repositories und Lynis."
],
[
"Überprüfung der Sicherungen",
"Abdeckung, Alter, Ergebnisse, Verifizierung, Aufbewahrung und Wiederherstellung der Backups."
],
[
"Kapazität und Verschleiß",
"Wachstumsmarge, Speicher, Platzverbrauch und Lebensdauer der Festplatten."
]
]
}
},
{
"p": "Der Inhalt jedes Dokuments wird unter <reportsLink>Berichte und Vergleiche</reportsLink> beschrieben."
}
]
},
{
"id": "results",
"title": "Wie die Ergebnisse klassifiziert werden",
"blocks": [
{
"table": {
"headers": [
"Einstufung",
"Bedeutung"
],
"rows": [
[
"Kritisch",
"Ein gescheiterter Zustand, der Priorität hat."
],
[
"Warnung",
"Eine Bedingung, die anhand der Nachweise oder der Richtlinie überprüft werden muss."
],
[
"Beobachtung",
"Informationen über den Knoten, der nicht als Fehler gemeldet wird."
],
[
"Nicht verifiziert",
"Die für die Prüfung benötigte Quelle konnte nicht gelesen werden. Das bedeutet nicht, dass kein Problem vorliegt."
],
[
"Konform",
"Die Bedingung erfüllt das angewandte Kriterium."
],
[
"Nicht zutreffend",
"Es gilt nichts im Rahmen der Prüfung."
],
[
"Akzeptiertes Risiko",
"Der Befund existiert und eine Entscheidung darüber wurde aufgezeichnet."
],
[
"Per Richtlinie ausgenommen",
"Die Richtlinie legt fest, dass dieses Element nicht mitgezählt wird."
]
]
}
},
{
"p": "Befunde lassen sich nach Bereich filtern: System, Speicher, Netzwerk, Sicherheit, Sicherung, Gastsysteme und Hardware. Jeder Befund enthält seine Nachweise und deren Quelle."
}
]
},
{
"id": "unverified",
"title": "Wenn eine Quelle nicht gelesen werden kann",
"blocks": [
{
"table": {
"headers": [
"Fall",
"Verhalten"
],
"rows": [
[
"Nicht verifiziert",
"Die Prüfung behält ihre Kennung bei, nennt in den Nachweisen die fehlerhafte Quelle und bewertet fehlende Daten nicht als konformes Ergebnis."
],
[
"Unvollständige Nachweise",
"Der Bericht nennt Quelle und Erfassungszeitpunkt, um ein tatsächliches Problem von einer unzureichenden Erfassung zu unterscheiden."
],
[
"Ein neuer Durchlauf",
"Sobald der Zugriff, das Paket oder der Dienst korrigiert wurde, läuft das gleiche Profil erneut und der Vergleich zeigt, ob das Ergebnis verifiziert werden konnte."
]
]
}
}
]
},
{
"id": "lynis",
"title": "Lynis",
"blocks": [
{
"p": "Die Sicherheitsprüfung nutzt den Lynis-Bericht des Hosts. Wurde Lynis noch nicht ausgeführt oder ist der Bericht älter als die Richtlinie erlaubt, bietet ein Dialog <strong>Mit Lynis ausführen</strong>, was einige Minuten länger dauert, oder <strong>Ohne Lynis ausführen</strong>, das den vorhandenen Bericht nutzt."
},
{
"figure": {
"src": "/monitor/audit/lynis-dialog.png",
"alt": "Dialog, der anbietet, das Assessment mit oder ohne Lynis durchzuführen",
"caption": "Der Lynis-Dialog vor einer Sicherheitsüberprüfung."
}
}
]
},
{
"id": "accept",
"title": "Annahme eines Risikos",
"blocks": [
{
"p": "<strong>Risiko akzeptieren</strong> erfasst eine Entscheidung zu einem Befund. Eine Begründung ist erforderlich und wird mit Autor und Datum gespeichert."
},
{
"table": {
"headers": [
"Feld",
"Optionen"
],
"rows": [
[
"Grund",
"Freitext, erforderlich."
],
[
"Gilt nicht mehr nach",
"90 Tage, 180 Tage, 1 Jahr oder läuft nicht ab. Wenn der Zeitraum endet, wird der Befund wieder aktiv."
],
[
"An Überprüfung erinnern",
"Eine Erinnerung, die die Entscheidung wieder auf sich aufmerksam macht, während sie in Kraft bleibt."
]
]
}
},
{
"p": "Ein akzeptierter Befund bleibt mit der Entscheidung sichtbar; <strong>Wieder aktiv setzen</strong> widerruft die Akzeptanz. Ein akzeptiertes Risiko ist keine Behebung: Der Vergleich meldet es als akzeptiert und nicht als gelöst."
}
]
},
{
"id": "inventory",
"title": "Inventar",
"blocks": [
{
"list": {
"items": [
"Identität, Proxmox VE-Version, Kernel, Subscription und Cluster.",
"CPU, Speicher, Board, BIOS, Controller und IOMMU.",
"Festplatten, SMART, Power-On-Stunden und aufgezeichnete Ereignisse.",
"Adapter, Bonds, Bridges, Latenz und Verbindungen.",
"Speicher, Gäste mit ihren Festplatten und Schnittstellen und Backups.",
"PCI Passthrough und die Software ProxMenux verwaltet."
]
}
}
]
}
]
}
@@ -0,0 +1,208 @@
{
"meta": {
"title": "Änderungen | Prüfung und Bericht",
"description": "Änderungsprotokoll von Prüfung und Bericht: ProxMenux-Änderungen am Host, vorheriger Zustand, Unterschiede und Möglichkeiten zum Rückgängigmachen."
},
"header": {
"title": "Änderungen",
"description": "Protokoll der von ProxMenux am Host ausgeführten Operationen und, soweit erfasst, des jeweiligen Zustands davor und danach.",
"section": "Prüfung und Bericht"
},
"sections": [
{
"id": "purpose",
"blocks": [
{
"calloutInfo": {
"title": "Vom ausgeführten Skript zur bewirkten Änderung",
"body": "Eine lange Funktion ändert möglicherweise nur zwei Zeilen. Das Protokoll erfasst jede konkrete Operation mit verantwortlichem Skript, Funktion und Version, betroffener Ressource, Unterschied und Möglichkeit zum Rückgängigmachen."
}
},
{
"flow": {
"nodes": [
{
"label": "Skript",
"detail": "Funktion + Version"
},
{
"label": "Erfassung",
"detail": "Inhalt vor"
},
{
"label": "Operation",
"detail": "Datei · Paket · Service"
},
{
"label": "Änderungsprotokoll",
"detail": "Attribution + Differenz"
}
],
"caption": "Die Erfassung erfolgt bei Ausführung der Operation und wird zusammengeführt, wenn Monitor das Protokoll liest."
}
},
{
"figure": {
"src": "/monitor/audit/changes-view.png",
"alt": "Ansicht Änderungen von Prüfung und Bericht mit Einträgen nach Nachinstallationsoption und Skript gruppiert",
"caption": "Die Ansicht Änderungen mit dem Unterschied einer von ProxMenux bearbeiteten Datei."
}
}
]
},
{
"id": "types",
"title": "Arten von Einträgen",
"intro": "Der Filter oben trennt die Einträge nach Art.",
"blocks": [
{
"table": {
"headers": [
"Art",
"Was es aufzeichnet"
],
"rows": [
[
"Konfiguration",
"ProxMenux hat eine Datei geschrieben, bearbeitet oder entfernt, eine Einstellung geändert oder einen Dienst geändert."
],
[
"Installationen",
"ProxMenux hat ein Paket oder eine Komponente hinzugefügt, und die tatsächlich erschienenen Pakete werden aufgezeichnet."
],
[
"Ausführungen",
"ProxMenux hat einen Befehl ausgeführt; seine Auswirkungen hängen vom Befehl selbst ab."
],
[
"Angewandt",
"Eine Funktion wurde angewendet, bevor das Protokoll existierte; ihr vorheriger Zustand wurde nicht erfasst."
]
]
}
}
]
},
{
"id": "groups",
"title": "Wie die Ansicht organisiert ist",
"blocks": [
{
"table": {
"headers": [
"Abschnitt",
"Inhalt"
],
"rows": [
[
"Post-Install-Optimierungen",
"Gruppiert nach der Option nach der Installation, die der Benutzer ausgewählt hat."
],
[
"ProxMenux-Skripte",
"GPU, Coral, Netzwerk, Speicher, Sicherheit, Werkzeuge und weitere instrumentierte Skripte, einschließlich ProxMenux-Installer und ProxMenux Monitor."
],
[
"Installierte Pakete und Werkzeuge",
"Von ProxMenux auf dem Host installierte Software."
]
]
}
},
{
"p": "<strong>Nach Funktion</strong> gruppiert die Einträge jedes Abschnitts nach der Funktion, die sie erzeugt hat."
}
]
},
{
"id": "entry",
"title": "Was jeder Eintrag zeigt",
"blocks": [
{
"list": {
"items": [
"Das verantwortliche Skript mit Funktion und Version.",
"Datum und betroffene Ressource.",
"Der bekannte Zustand vor und nach der Änderung.",
"Die hinzugefügten und entfernten Zeilen.",
"Die Pakete, die tatsächlich hinzugefügt wurden.",
"Der Zustandswechsel eines Dienstes.",
"<strong>Rückgängigmachen</strong>: <em>Stellt exakt den vorherigen Zustand wieder her</em>, <em>Löscht die Datei (vorher existierte keine)</em>, <em>Das Paket kann deinstalliert werden</em>, teilweises Rückgängigmachen oder <em>Kann nicht aus dem Protokoll rückgängig gemacht werden</em>."
]
}
}
]
},
{
"id": "before",
"title": "Was der vorherige Zustand bedeutet",
"blocks": [
{
"p": "Der vorherige Zustand kann erfasster Inhalt, eine erstmals erstellte Datei oder ein unbekannter Zustand sein. Änderungen vor Einführung des Protokolls lassen sich nicht rekonstruieren; eine erneute Ausführung erfasst zunächst den dann vorgefundenen Zustand."
}
]
},
{
"id": "limits",
"title": "Umfang des Änderungsprotokolls",
"blocks": [
{
"list": {
"items": [
"Manuelle Änderungen und Änderungen durch andere Software werden nicht aufgezeichnet.",
"Nur Operationen, die die ProxMenux-Auditprimitiven durchlaufen, werden abgedeckt.",
"Die Protokollierung blockiert nie die beschriebene Operation: Kann ein Eintrag nicht geschrieben werden, läuft die Operation weiter.",
"Aufeinanderfolgende Änderungen an einer Ressource werden als bekannter Ursprung gegen den aktuellen Zustand angezeigt."
]
}
}
]
},
{
"id": "retention",
"title": "Gespeicherte Nachweise",
"blocks": [
{
"table": {
"headers": [
"Element",
"Verhalten"
],
"rows": [
[
"Einträge",
"Sie werden auf dem Host aufbewahrt; nichts wird automatisch aus dem Journal entfernt."
],
[
"Erfasster Inhalt",
"Ein erfasstes Objekt wird beibehalten, während sich ein Eintrag darauf bezieht."
],
[
"Größe einer Erfassung",
"Inhalt über 1 MiB wird nicht als Ganzes gespeichert; der Eintrag zeichnet auf, dass die Aufnahme wegen seiner Größe übersprungen wurde."
],
[
"Lesen",
"Der Monitor lädt keine gespeicherten Objekte über 2 MiB."
],
[
"Unterschied",
"Es werden höchstens 400 Zeilen angezeigt; längere Unterschiede werden als gekürzt markiert."
],
[
"Liste",
"Die API liefert standardmäßig 200 Einträge je Anfrage, maximal 1000."
]
]
}
},
{
"calloutWarning": {
"title": "Gespeicherter Inhalt bedeutet kein automatisches Rückgängigmachen",
"body": "Der vorherige Inhalt kann geprüft und manuell wiederhergestellt werden; die Ansicht Änderungen macht jedoch keine Operationen rückgängig. Ein Ausführungseintrag erfasst den Befehl, ohne alle Auswirkungen des ausgeführten Werkzeugs zu kennen."
}
}
]
}
]
}
@@ -0,0 +1,136 @@
{
"meta": {
"title": "Prüfung und Bericht | ProxMenux Monitor",
"description": "Bewerten Sie einen Proxmox-VE-Knoten, dokumentieren Sie ProxMenux-Änderungen und legen Sie Erwartungen an Gastsysteme und Speicher fest, mit druckbaren Berichten."
},
"header": {
"title": "Prüfung und Bericht",
"description": "Bewertung des Knotens, Protokoll der ProxMenux-Änderungen und festgelegte Erwartungen, mit Dokumenten zum Drucken oder Speichern als PDF.",
"section": "ProxMenux Monitor"
},
"sections": [
{
"id": "views",
"blocks": [
{
"calloutInfo": {
"title": "Drei Ansichten, drei Fragen",
"body": "Prüfung und Bericht trennt Fakten zum Knoten, Eingriffe von ProxMenux und festgelegte Erwartungen. Lässt sich eine Konfiguration keinem erklärten Zweck gegenüberstellen, wird sie beschrieben und nicht als Fehler gemeldet."
}
},
{
"cards": {
"items": [
{
"icon": "shield",
"title": "Bewertung - wie ist der Knoten?",
"body": "Führt die Überprüfungen des gewählten Profils aus, erstellt das Inventar und klassifiziert, was Aufmerksamkeit benötigt, mit dem Nachweis jedes Ergebnisses."
},
{
"icon": "refresh",
"title": "Änderungen - was hat ProxMenux getan?",
"body": "Listet Dateien, Pakete, Dienste und Befehle auf, die durch instrumentierte ProxMenux-Skripte geändert wurden, samt vorherigem Zustand, sofern er erfasst wurde."
},
{
"icon": "fileText",
"title": "Richtlinie — was wird erwartet?",
"body": "Legt fest, welche Gastsysteme eine Sicherung benötigen oder mit dem Host starten müssen, welcher Speicher wesentlich ist und welche Prüfschwellen gelten."
}
]
}
},
{
"flow": {
"nodes": [
{
"label": "Bewertung",
"detail": "Fakten"
},
{
"label": "Richtlinie",
"detail": "Kontext"
},
{
"label": "Änderungen",
"detail": "Interventionen"
}
],
"caption": "Die Bewertung liefert die Fakten, die Richtlinie gibt ihnen Kontext und das Änderungsprotokoll erfasst die Eingriffe von ProxMenux."
}
},
{
"figure": {
"src": "/monitor/audit/assessment-view.png",
"alt": "Prüfung und Bericht in ProxMenux Monitor mit den Ansichten Bewertung, Änderungen und Richtlinie",
"caption": "Prüfung und Bericht mit geöffneter Ansicht Bewertung."
}
}
]
},
{
"id": "boundaries",
"title": "Drei verschiedene Funktionen",
"blocks": [
{
"table": {
"headers": [
"Funktion",
"Was es tut"
],
"rows": [
[
"<healthLink>Zustandsüberwachung</healthLink>",
"Beobachtet Metriken und Ereignisse kontinuierlich und kann Benachrichtigungen auslösen."
],
[
"Prüfung und Bericht",
"Führt auf Anforderung eine Bewertung aus, dokumentiert den Knoten und vergleicht Durchläufe miteinander."
],
[
"Änderungsprotokoll",
"Erfasst die von ProxMenux über seine Audit-Grundfunktionen ausgeführten Operationen."
]
]
}
}
]
},
{
"id": "pages",
"title": "Seiten dieses Abschnitts",
"blocks": [
{
"next": {
"items": [
{
"label": "Bewertung und Bestandsaufnahme",
"href": "/docs/monitor/audit-report/assessment",
"tail": "Profile, Ergebnisse, akzeptierte Risiken und Bestandsaufnahme."
},
{
"label": "Änderungen",
"href": "/docs/monitor/audit-report/changes",
"tail": "das Journal, was ProxMenux auf dem Host geändert hat."
},
{
"label": "Richtlinie",
"href": "/docs/monitor/audit-report/policy",
"tail": "Gäste, Speicher und Schwellenwerte."
},
{
"label": "Berichte und Vergleiche",
"href": "/docs/monitor/audit-report/reports",
"tail": "die sechs Dokumente und den Referenzlauf."
},
{
"label": "Anwendungsbereich und Garantien",
"href": "/docs/monitor/audit-report/scope",
"tail": "Quellen, Grenzen und gespeicherte Daten."
}
]
}
}
]
}
]
}
@@ -0,0 +1,111 @@
{
"meta": {
"title": "Richtlinie | Prüfung und Bericht",
"description": "Knotenrichtlinie von Prüfung und Bericht: Sicherung, Autostart und Wiederherstellungsziel jedes Gastsystems, Rolle jedes Speichers und Prüfschwellenwerte."
},
"header": {
"title": "Richtlinie",
"description": "Die Richtlinie legt fest, was keine Prüfung ableiten kann: Zweck jedes Gastsystems und Speichers sowie die Schwellenwerte der Prüfungen.",
"section": "Prüfung und Bericht"
},
"sections": [
{
"id": "principle",
"blocks": [
{
"calloutInfo": {
"title": "Ohne Festlegung beschreibt der Bericht; mit ihr bewertet er",
"body": "Eine Bewertung sieht, was der Host tut, nicht, wozu er dient. Ein Gast ohne Backup, dessen Verwendungszweck nicht angegeben ist, wird als Beobachtung gemeldet. Wenn dessen Sicherung als erforderlich erklärt wird, wird die gleiche Abwesenheit als Warnung gemeldet. Es muss nichts deklariert werden."
}
},
{
"figure": {
"src": "/monitor/audit/policy-view.png",
"alt": "Richtlinienansicht mit Gastsystemen, Speicher und Schwellenwerten des Knotens",
"caption": "Die Richtlinienansicht."
}
}
]
},
{
"id": "guests",
"title": "Gäste",
"intro": "Jede VM und jeder LXC des Knotens hat drei Felder. Ein auf Standard belassenes Feld übernimmt den daneben angezeigten allgemeinen Wert.",
"blocks": [
{
"table": {
"headers": [
"Feld",
"Werte",
"Auswirkungen auf die Bewertung"
],
"rows": [
[
"Sicherung",
"Erforderlich, Nicht erforderlich, Nicht angegeben",
"Ein fehlendes Backup ist eine Warnung, wenn es erforderlich ist, eine Beobachtung, wenn es nicht angegeben ist, und es wird aus der Zählung ausgelassen, wenn es nicht erforderlich ist."
],
[
"Autostart",
"Erforderlich, Nicht erforderlich, Nicht angegeben",
"Ob das Gastsystem mit dem Host starten muss."
],
[
"Wiederherstellungsziel",
"Std",
"Das maximal akzeptable Alter des letzten Backups."
]
]
}
}
]
},
{
"id": "storage",
"title": "Speicher",
"blocks": [
{
"p": "Ein nicht erreichbarer Speicher wird als kritisch gemeldet, wenn er für wesentlich erklärt wird oder einem laufenden Gast dient, als Warnung, wenn seine Rolle nicht angegeben wird, und als Beobachtung, wenn er für optional erklärt wird."
}
],
"intro": "Jeder Speicher des Knotens wird als wesentlich, optional oder nicht angegeben deklariert."
},
{
"id": "thresholds",
"title": "Schwellenwerte",
"intro": "Ein leeres Schwellenwertfeld verwendet den mitgelieferten Standardwert, der als Platzhalter angezeigt wird.",
"blocks": [
{
"list": {
"items": [
"Prüfung von Speicherkapazität (%) und Thin-Pool-Füllstand (%).",
"Verhältnis der Thin-Überprovisionierung und der Speicherüberbelegung.",
"ZFS-Scrub-Intervall (Tage).",
"Ersatzgrenze für das Sicherungsalter (Tage) und Toleranz des Zeitplans (Verhältnis).",
"Hinweis vor Zertifikatsablauf (Tage).",
"Festplattendienstdauer (Stunden) und letztes Festplattenfehlerfenster (Tage).",
"Alter des Lynis-Berichts (Tage) und der Paketindizes (Tage).",
"Journal-Belegung im Verhältnis zur Obergrenze (%).",
"Prüfung des Dateisystem-Speicherplatzes (%) und der Inodes (%)."
]
}
}
]
},
{
"id": "save",
"title": "Wie die Richtlinie gespeichert wird",
"blocks": [
{
"p": "Die Festlegung wird geprüft und atomar in <code>/usr/local/share/proxmenux/audit_policy.json</code> gespeichert. Jeder Speichervorgang enthält eine Revision: Hat eine andere Sitzung die Festlegung geändert, wird der Entwurf nicht gespeichert und die Ansicht bietet an, die gespeicherte Fassung neu zu laden."
},
{
"calloutWarning": {
"title": "Die Richtlinie wird nie automatisch abgeleitet",
"body": "ProxMenux fügt keine eigenen Anforderungen hinzu. Ein leeres Feld behält den mitgelieferten Standardwert oder bleibt nicht angegeben; eine teilweise Festlegung betrifft nur die benannten Elemente."
}
}
]
}
]
}
@@ -0,0 +1,247 @@
{
"meta": {
"title": "Berichte und Vergleiche | Prüfung und Bericht",
"description": "Die sechs Dokumente von Prüfung und Bericht, ihr Druck oder Speichern als PDF und der Vergleich von Durchläufen mit einem Referenzlauf."
},
"header": {
"title": "Berichte und Vergleiche",
"description": "Sechs Dokumente für unterschiedliche Fragen und der Vergleich jedes Durchlaufs mit einem Referenzlauf.",
"section": "Prüfung und Bericht"
},
"sections": [
{
"id": "intro",
"blocks": [
{
"calloutInfo": {
"title": "Sechs Dokumente, nicht sechs Stile",
"body": "Die Engine wählt Prüfungen und Abschnitte aus, bevor sie das Dokument erstellt. Eine schnelle Diagnose ist kein vollständiges Audit mit weniger Seiten, und ein Inventar zeigt keine Bewertungsergebnisse. Die folgenden Beispieldokumente verwenden fiktive Daten."
}
}
]
},
{
"id": "documents",
"title": "Die sechs Dokumente",
"blocks": [
{
"downloads": {
"items": [
{
"title": "Vollständiges Audit",
"body": "Dokumentiert den gesamten Knoten als technische Bestandsaufnahme.",
"href": "/monitor/audit/sample-audit-full-report.pdf",
"facts": [
{
"label": "Kontrollen",
"value": "Alle verfügbaren Prüfungen."
},
{
"label": "Inhalt",
"value": "Ergebnisübersicht; Identität und Cluster; Hardware; Netzwerk und Latenz; Speicher; Gastsysteme; Passthrough; Anwendungen; Befunde mit Nachweisen; Quellen und Umfang."
}
]
},
{
"title": "Schnelldiagnose",
"body": "Zeigt, was Aufmerksamkeit braucht, ohne das komplette Inventar.",
"href": "/monitor/audit/sample-audit-diagnostic-report.pdf",
"facts": [
{
"label": "Kontrollen",
"value": "Die gleichen Prüfungen wie das vollständige Audit."
},
{
"label": "Inhalt",
"value": "Minimale Identität; kritische Befunde; Warnungen; relevante Beobachtungen; nicht verifizierte Messwerte und prioritäre Maßnahmen. Diagramme, Inventar und lange Anhänge werden ausgelassen."
}
]
},
{
"title": "Inventar",
"body": "Beschreibt, was auf dem Knoten existiert, ohne es zu bewerten.",
"href": "/monitor/audit/sample-audit-inventory-report.pdf",
"facts": [
{
"label": "Kontrollen",
"value": "Keine; kein Befund ist klassifiziert."
},
{
"label": "Inhalt",
"value": "Identität; Cluster; CPU und Speicher; Board, BIOS und Controller; Netzwerk; Storage; VMs und LXCs; Passthrough; Anwendungen und Elemente, die von ProxMenux verwaltet werden."
}
]
},
{
"title": "Sicherheitsüberprüfung",
"body": "Umfasst die Exposition und die Kontrollen über den Zugang zum Knoten.",
"href": "/monitor/audit/sample-audit-security-report.pdf",
"facts": [
{
"label": "Kontrollen",
"value": "Der Sicherheitsbereich sowie Containerprivilegien, Updates, Repositories und die APT-Kette."
},
{
"label": "Inhalt",
"value": "Identität und Cluster; Netzwerk und Latenz; Zugriff; Firewall; 2FA; Zertifikate; Privilegien; Updates; Repositories; Zustand und Alter von Lynis."
}
]
},
{
"title": "Überprüfung der Sicherungen",
"body": "Prüft, ob der deklarierte Schutz vorhanden ist und ob seine Backups verwendbar sind.",
"href": "/monitor/audit/sample-audit-backup-report.pdf",
"facts": [
{
"label": "Kontrollen",
"value": "Der Backup-Bereich plus Storage-Konnektivität und Benachrichtigungszustellung."
},
{
"label": "Inhalt",
"value": "Abdeckung pro Gast; erklärtes Wiederherstellungsziel; Alter und Ergebnis; Ziel; Aufbewahrung; Überprüfung; gescheiterte Jobs; Wiederherstellung und unvollständige Quellen."
}
]
},
{
"title": "Kapazität und Verschleiß",
"body": "Misst Wachstumsspielraum und Anzeichen von Erschöpfung oder Alterung.",
"href": "/monitor/audit/sample-audit-capacity-report.pdf",
"facts": [
{
"label": "Kontrollen",
"value": "Die Speicher- und Hardwarebereiche sowie Speicher, Swap, Journal und das Host-Dateisystem."
},
{
"label": "Inhalt",
"value": "Belegung und Schwellenwerte; Thin Pools; Überprovisionierung; Arbeitsspeicher; Inodes; ZFS; Temperaturen; Betriebsstunden; SMART-Fehler und NVMe/SSD-Lebensdauer."
}
]
}
]
}
},
{
"figure": {
"src": "/monitor/audit/audit-report-preview.png",
"alt": "Erste Seite eines vollständigen Auditberichts",
"caption": "Jedes Dokument teilt die Berichtskennung, die nummerierten Abschnitte, das Datum, den Knoten, das Profil und die Fußzeile."
}
},
{
"p": "Je nach Profil enthält das Dokument Knotenidentität und Bewertungsdatum, Ergebnisübersicht, Zusammenfassung nach Bereichen, Hardware-, Netzwerk- und Speicherstruktur, Schutz der Gastsysteme, Befunde mit Nachweisen, nicht lesbare Quellen sowie angewandten Umfang und Richtlinie."
}
]
},
{
"id": "print",
"title": "Drucken oder Speichern als PDF",
"blocks": [
{
"steps": {
"items": [
{
"title": "Starten",
"body": "Die Bewertung nutzt das unter <strong>Bericht</strong> ausgewählte Profil."
},
{
"title": "Überprüfung",
"body": "Der abgeschlossene Durchlauf zeigt Befunde, nicht lesbare Quellen und die angewandte Richtlinie."
},
{
"title": "Bericht erzeugen",
"body": "<strong>Bericht erzeugen</strong> öffnet die als Dokument aufbereitete Ansicht."
},
{
"title": "Druck",
"body": "<strong>Drucken oder als PDF speichern</strong> öffnet den Druckdialog des Browsers zur Auswahl eines Druckers oder von <em>Als PDF speichern</em>."
}
]
}
},
{
"calloutTip": {
"title": "Der Ausdruck ist ein Dokument, kein Screenshot",
"body": "Die Aktionsleiste ist ausgeblendet, eine Tabelle, die auf der nächsten Seite fortgesetzt wird, wiederholt ihre Kopfzeile, Blöcke vermeiden unnötige Pausen und jede Seite behält die Identifikation und Nummerierung."
}
}
]
},
{
"id": "compare",
"title": "Vergleich mit einem Referenzlauf",
"intro": "<strong>Als Referenz verwenden</strong> markiert einen abgeschlossenen Durchlauf. Spätere Durchläufe werden damit verglichen und ihre Befunde aufgeteilt in :",
"blocks": [
{
"table": {
"headers": [
"Gruppe",
"Bedeutung"
],
"rows": [
[
"Neu",
"Jetzt berichtet und nicht vorher."
],
[
"Verschlechtert",
"Weiterhin gemeldet, aber schwerwiegender oder umfassender als zuvor."
],
[
"Verbessert",
"Weiterhin gemeldet, aber weniger schwerwiegend oder umfassend als zuvor."
],
[
"gelöst",
"Nicht mehr gemeldet und von niemandem als Risiko akzeptiert."
],
[
"Akzeptiert",
"Wird nicht mehr gezählt, weil ein Risiko akzeptiert wurde, nicht weil sich der Host geändert hat."
],
[
"Nicht mehr bewertet",
"Zuvor vorhanden, in diesem Durchlauf nicht enthalten; ihr Wegfall wurde nicht verifiziert."
]
]
}
},
{
"table": {
"headers": [
"Bezugslauf",
"Verhalten"
],
"rows": [
[
"Setzen Sie es",
"Jeder fertige Lauf kann markiert werden; keiner wird automatisch markiert."
],
[
"Es ändern",
"Ein anderer markierter Durchlauf ersetzt die Referenz, ohne den Verlauf zu löschen."
],
[
"Vergleichen",
"Wenn keine zwei Durchläufe ausgewählt sind, verwendet der Vergleich die Referenz und den ausgewählten oder letzten Durchlauf."
],
[
"Durchläufe aufbewahren",
"Die 30 neuesten Durchläufe werden aufbewahrt; der Referenzlauf wird nie entfernt."
],
[
"Ohne Referenz",
"Die Ansicht zeigt, dass noch kein Referenzlauf gewählt wurde und somit keine Vergleichsgrundlage vorhanden ist."
]
]
}
},
{
"calloutWarning": {
"title": "Ein Bericht beschreibt einen Moment",
"body": "Eine Bewertung bestätigt keinen ganzen Zeitraum. Ältere Ergebnisse beschreiben den aktuellen Zustand nicht mehr; die Ansicht zeigt das Alter des letzten Durchlaufs und jede Quelle behält ihren Erfassungszeitpunkt."
}
}
]
}
]
}
@@ -0,0 +1,115 @@
{
"meta": {
"title": "Umfang und Garantien | Prüfung und Bericht",
"description": "Herkunft der Daten von Prüfung und Bericht, Grenzen des Prüfbereichs, Entwurfsgarantien und Speicherorte."
},
"header": {
"title": "Umfang und Garantien",
"description": "Woher Bewertungsdaten stammen, was außerhalb des Prüfbereichs liegt und wo Prüfung und Bericht seine Daten speichert.",
"section": "Prüfung und Bericht"
},
"sections": [
{
"id": "sees",
"title": "Was er beobachtet",
"blocks": [
{
"list": {
"items": [
"Konfiguration und Zustand des lokalen Knotens.",
"Die deklarierte Konfiguration der VMs und LXCs.",
"Der Speicherzustand, wie ihn Proxmox VE erfasst.",
"Die verfügbare Historie von Backups und Verifizierungen.",
"SMART-Daten und die Ereignisse, die der Monitor gesammelt hat.",
"Der Zustand von Diensten, Cluster, HA und lokalen Quellen."
]
}
}
]
},
{
"id": "outside",
"title": "Was außerhalb seiner Sicht ist",
"blocks": [
{
"list": {
"items": [
"Das Innere der Gäste, über das hinaus, was sie Proxmox VE erklären.",
"Netzwerkausrüstung außerhalb des Hosts.",
"Fernabhängigkeiten, die der Knoten nicht beobachten kann.",
"Physischer Zustand, den die Hardware nicht bereitstellt.",
"Das Änderungsprotokoll erfasst keine manuellen Aktionen oder Aktionen anderer Software."
]
}
},
{
"calloutWarning": {
"title": "Fehlende Beweise sind keine Beweise für Abwesenheit",
"body": "Eine Quelle, die nicht gelesen werden kann, liefert ein nicht verifiziertes oder unvollständiges Ergebnis, niemals ein konformes. Der Bericht listet die Quellen auf, die nicht verfügbar waren."
}
}
]
},
{
"id": "guarantees",
"title": "Garantien für das Design",
"blocks": [
{
"list": {
"items": [
"Stabile Kennzeichen für die Kontrollen.",
"Verlauf der Durchläufe und Befunde.",
"Eine validierte, atomar gespeicherte Richtlinie.",
"Akzeptierte Risiken mit einem Grund, sichtbar.",
"Zuweisung von Änderungen an Skript und Funktion.",
"Erfassung des Zustands vor und nach der Änderung, soweit verfügbar.",
"Ein explizites Ergebnis, wenn etwas nicht gemessen oder erfasst werden kann."
]
}
}
]
},
{
"id": "storage",
"title": "Wo die Daten gespeichert werden",
"blocks": [
{
"table": {
"headers": [
"Daten",
"Ort"
],
"rows": [
[
"Richtlinie",
"<code>/usr/local/share/proxmenux/audit_policy.json</code>"
],
[
"Bewertungen",
"Die Prüfdatenbank des Monitors"
],
[
"Erfasste Objekte",
"<code>/usr/local/share/proxmenux/changes/objects/</code>"
],
[
"Ausstehende Einträge",
"<code>/usr/local/share/proxmenux/changes/spool/</code>"
],
[
"Zusammengeführtes Änderungsprotokoll",
"<code>/usr/local/share/proxmenux/changes.db</code>"
]
]
}
},
{
"calloutInfo": {
"title": "Ein Tool zur Überprüfung, keine Zertifizierung",
"body": "Prüfung und Bericht prüft, vergleicht und dokumentiert den Knoten. Die Ergebnisse werden im Kontext des Systemzwecks, der festgelegten Richtlinie und der verfügbaren Quellen bewertet."
}
}
]
}
]
}
@@ -0,0 +1,174 @@
{
"meta": {
"title": "Apps-Dashboard: ein Starter für alle Weblinks | ProxMenux",
"description": "Verwenden Sie das Apps-Dashboard, um registrierte LXC-Weblinks und benutzerdefinierte Links zu öffnen, sie nach Kategorie zu ordnen und zu dem Gast zurückzukehren, der jeden Dienst besitzt."
},
"header": {
"title": "Dashboard: Apps Tab",
"description": "Ein einzelner Launcher für die Web-Schnittstellen, die Sie über den Knoten verwenden, unabhängig davon, ob sie von einer registrierten LXC-Anwendung oder einem benutzerdefinierten Weblink stammen.",
"section": "ProxMenux Monitor · Übersicht"
},
"intro": {
"title": "Ein Launcher, kein Application Installer",
"body": "Der Reiter <strong>Apps</strong> installiert keine Software und sucht nicht selbst nach Diensten. Er zeigt gespeicherte Weblinks in einem durchsuchbaren Raster. LXC-Links werden im <appTabLink>App-Reiter</appTabLink> des Gastsystems konfiguriert; eigene Links ergänzen VM-Dienste, Reverse Proxys und externe Dashboards."
},
"sources": {
"heading": "Was in Apps erscheint",
"intro": "Jede startbare URL wird zu einer eigenen Karte. Die Quelle bestimmt, wo diese Karte bearbeitet wird, aber nicht, wie sie während des normalen Gebrauchs aussieht.",
"colSource": "Quelle",
"colAppears": "Was erscheint",
"colManagedFrom": "Wo es verwaltet wird",
"rows": [
{
"source": "Registrierte LXC-Anwendung",
"appears": "Eine Karte für jeden Weblink, der im Anwendungsprotokoll gespeichert ist.",
"managedFrom": "VMs und LXCs → LXC-Dialog → App"
},
{
"source": "Benutzerdefinierter Link an einen Gast gebunden",
"appears": "Eine Service-URL, die mit einem bestimmten VM oder LXC verknüpft ist.",
"managedFrom": "Apps → Bearbeiten"
},
{
"source": "Eigener Link ohne Gastzuordnung",
"appears": "Beliebiges HTTP(S)-Ziel, einschließlich externer Dienste und Dienste hinter einem Reverse Proxy.",
"managedFrom": "Apps → Bearbeiten"
}
],
"relationshipTitle": "Apps und der LXC App-Tab haben unterschiedliche Jobs",
"relationshipBody": "Der <appTabLink>App-Reiter</appTabLink> des LXC verwaltet Anwendungsidentität, Weblinks und optionales Versionstracking. <strong>Apps</strong> verwendet diese Links als Schnellzugriff. Die Bearbeitung einer LXC-Karte öffnet daher den Gastdatensatz, ohne die Konfiguration zu duplizieren."
},
"cards": {
"heading": "Wie man eine Karte benutzt",
"intro": "Die gesamte Karte ist das Startziel, während ihre kleineren Kontrollen einen Kontext bieten, ohne den Dienst zu öffnen.",
"items": [
"Klicken Sie auf die Karte, um ihre URL in einem neuen Browser-Tab zu öffnen.",
"Das Logo verwendet zuerst das Web Link-Logo und fällt gegebenenfalls auf das Anwendungslogo zurück.",
"Der Kategoriechip verwendet die gleiche Farbe und Beschriftung wie der entsprechende Weblink im LXC App-Tab.",
"Die Gastanzeige nennt die zugeordnete VM oder den LXC. Ein Klick öffnet dessen Dialog: LXC-Links öffnen <strong>App</strong>, VM-Links <strong>Status</strong>.",
"Ein violetter Aufwärtspfeil kennzeichnet ein verfügbares Update der betreffenden Anwendung oder des Docker-Images. Er ist keine Gesamtzahl aller Updates des Gastsystems."
]
},
"toolbar": {
"heading": "Suche, Filter und Sortierung",
"intro": "Die Symbolleiste verengt eine große Anwendungssammlung, ohne die gespeicherten Datensätze zu ändern.",
"items": [
"Die Suche entspricht dem Anwendungsnamen, dem Gastnamen, dem VMID und der Kategorie.",
"Der Kategoriefilter zeigt jeweils eine Kategorie oder alle Anwendungen an.",
"Sortieren Sie nach <strong>Name</strong>, <strong>ID</strong> oder <strong>Kategorie</strong>. Die Kategoriesortierung fügt Überschriften zwischen Kartengruppen ein.",
"Die Sortierung wird in diesem Browser gespeichert. Suchtext und Kategoriefilter werden beim erneuten Seitenaufruf zurückgesetzt.",
"Die Registerkarte Apps bleibt verfügbar, wenn das Raster leer ist, so dass der erste benutzerdefinierte Link hinzugefügt werden kann, ohne zuerst eine LXC-Anwendung zu registrieren."
]
},
"customLinks": {
"heading": "Hinzufügen und Bearbeiten von benutzerdefinierten Weblinks",
"intro": "Verwenden Sie einen benutzerdefinierten Link, wenn der Dienst nicht durch eine registrierte LXC-Anwendung dargestellt wird.",
"steps": [
"Wählen Sie <strong>Link hinzufügen</strong> in der Werkzeugleiste oder der leeren Ansicht.",
"Geben Sie einen Namen und eine vollständige <code>http://</code> oder <code>https://</code> URL ein.",
"Optional ein Logo hinzufügen, eine Kategorie auswählen oder erstellen und den Link an einen VM oder LXC binden.",
"Speichern Sie den Link. Seine Karte erscheint sofort im Raster.",
"Zum Ändern oder Entfernen eines eigenen Links wählen Sie <strong>Bearbeiten</strong> und den Stift auf seiner Karte."
],
"colField": "Feld",
"colRequired": "Erforderlich",
"colPurpose": "Zweck",
"fields": [
{
"field": "Name",
"required": "Ja",
"purpose": "Der kartentitel und der suchbegriff."
},
{
"field": "URL",
"required": "Ja",
"purpose": "Das vollständige HTTP(S) Ziel, das von der Karte geöffnet wird."
},
{
"field": "Logo-URL",
"required": "Nein",
"purpose": "Ein Fernbild, das auf der Karte angezeigt wird."
},
{
"field": "Kategorie",
"required": "Nein",
"purpose": "Fügt ein gemeinsames Badge hinzu und ermöglicht die Kategoriefilterung."
},
{
"field": "Gastzuordnung",
"required": "Nein",
"purpose": "Verbindet den Link mit einem VM oder LXC und aktiviert die Gastverknüpfung."
}
],
"editTitle": "Bearbeiten der Quelle der Wahrheit",
"editBody": "Stifte erscheinen im Bearbeitungsmodus nur bei eigenen Links. Für eine LXC-Anwendungskarte öffnen Sie den <appTabLink>App-Reiter</appTabLink> des Gastsystems und ändern dort den gespeicherten Weblink."
},
"categories": {
"heading": "Kategorien und Aktualisierungssignale",
"intro": "Kategorien organisieren Links; Updatesignale melden den Softwarezustand. Sie sind absichtlich getrennt.",
"items": [
"Kataloggestützte LXC-Registrierung kann eine Kategorie vorfüllen, bleibt aber editierbar.",
"Benutzerdefinierte Kategorienamen können aus dem gleichen Selektor erstellt und dann vom Filter wiederverwendet werden.",
"Kategoriefarben sind deterministisch und passen sich dem hellen oder dunklen Thema an. Lila und rote Bereiche sind für Update- und Gefahrenzustände reserviert.",
"Bei Docker-Weblinks ordnet ProxMenux die Karte einem Container oder Image zu und zeigt dessen Image-Updatezustand. Docker-Engine-Updates bleiben im <updatesLink>Reiter Aktualisierungen</updatesLink> des LXC."
]
},
"persistence": {
"heading": "Persistenz und Cache-Verhalten",
"intro": "Das Dashboard ist so konzipiert, dass es sich von bereits verfügbaren Monitordaten öffnet, anstatt jeden Gast neu zu scannen.",
"items": [
"Eigene Links werden atomar in <code>/etc/proxmenux/custom_links.json</code> gespeichert und beim Start von Monitor in den Arbeitsspeicher geladen.",
"Registrierte LXC-Links bleiben Teil des gespeicherten Monitor-Datensatzes ihrer Anwendung; das Apps-Dashboard dupliziert sie nicht in die benutzerdefinierte Link-Datei.",
"Das Erstellen, Bearbeiten oder Löschen eines benutzerdefinierten Links aktualisiert die In-Memory-Liste sofort.",
"Die Sortierpräferenz gilt nur für diesen Browser und wird nicht zwischen Geräten oder Benutzern synchronisiert.",
"Die Position von Apps in der Hauptnavigation wird unter <settingsLink>Einstellungen → Navigationsreihenfolge</settingsLink> festgelegt."
]
},
"troubleshooting": {
"heading": "Häufige Situationen",
"colProblem": "Lage",
"colResolution": "Lösung",
"rows": [
{
"problem": "Eine LXC-Anwendung ist registriert, aber keine Karte erscheint",
"resolution": "Öffnen Sie den Tab App und fügen Sie mindestens einen Weblink hinzu. Versions-Tracking allein erstellt keine Launcher-Karte."
},
{
"problem": "URL oder Logo ist falsch",
"resolution": "Bearbeiten Sie den benutzerdefinierten Link in Apps oder bearbeiten Sie den Weblink im LXC App-Tab."
},
{
"problem": "Ein Docker-Service fehlt",
"resolution": "Bearbeiten Sie die registrierte Docker-Anwendung und speichern Sie den veröffentlichten Webport des Dienstes als Weblink."
},
{
"problem": "Der lila Pfeil bezieht sich auf das falsche Docker Update",
"resolution": "Überprüfen Sie den Weblink-Namen und die Beschreibung, damit sie mit dem beabsichtigten Container oder Image übereinstimmen können."
},
{
"problem": "Apps öffnen sich zuerst statt Systemübersicht",
"resolution": "Der erste gespeicherte Eintrag unter Einstellungen → Navigationsreihenfolge wird zum Startreiter. Stellen Sie die Standardreihenfolge wieder her oder verschieben Sie Übersicht an die erste Stelle."
}
]
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "LXC App Tab",
"href": "/docs/monitor/dashboard/vms-lxcs/app",
"tail": "— Anwendungen registrieren, Weblinks und optionales Versions-Tracking."
},
{
"label": "LXC Updates Tab",
"href": "/docs/monitor/dashboard/vms-lxcs/updates",
"tail": " — Aktualisierungen für Anwendungen, Docker Engine und Images konfigurieren und ausführen."
},
{
"label": "Tab Einstellungen",
"href": "/docs/monitor/dashboard/settings#navigation-order",
"tail": " — Navigationsreihenfolge und Startreiter ändern."
}
]
}
}
@@ -0,0 +1,248 @@
{
"meta": {
"title": "ProxMenux Monitor — Dashboard: Hardware | ProxMenux-Dokumentation",
"description": "Die Hardware-Registerkarte inventarisiert die physische Maschine: CPU und Motherboard, Speichermodule, thermische Sensoren, GPUs (mit Echtzeitüberwachung pro Slot und Ein-Klick-Treiber-Installation), Coral TPU-Beschleuniger, Speicherzusammenfassung mit Link-Geschwindigkeitsprüfungen, vollständige PCI- und USB-Gerätelisten, Stromverbrauch, PSUs, Lüfter und USV-Zustand."
},
"header": {
"title": "Dashboard: Hardware",
"description": "Die physische Maschine in einem Bildschirm - CPU und Motherboard-Identität, jedes Speichermodul, thermische Sensoren über alle Subsysteme hinweg, GPUs mit Live-Auslastung und ein eingebautes Treiber-Installationsprogramm, Coral-TPUs, jedes PCI- und USB-Gerät mit seinem Kernel-Treiber, das vollständige Festplatteninventar mit ausgehandelten Verbindungsgeschwindigkeiten sowie Strom, Kühlung und USV.",
"section": "ProxMenux Monitor · Übersicht"
},
"intro": {
"title": "Gebaut aus Standardwerkzeugen",
"body": "Der größte Teil dieser Registerkarte wird aus <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> und <code>upsc</code> analysiert. Abschnitte werden nur dann dargestellt, wenn das betreffende Tool Daten zurückgibt, so dass ein Host ohne USV die USV-Karte nicht zeigt und ein Host ohne IPMI keine Out-of-Band-Leistungszahlen anzeigt."
},
"thresholds": {
"title": "Hier angewendete Statusfarben und -schwellen",
"intro": "Alle Temperaturanzeigen verwenden dieselbe Einteilung: <green/> <strong>grün</strong> unter der Warnschwelle, <amber/> <strong>bernsteinfarben</strong> zwischen Warn- und kritischer Schwelle, <red/> <strong>rot</strong> ab der kritischen Schwelle. Empfohlene Standardwerte von ProxMenux :",
"items": [
"<strong>CPU-Temperatur</strong> — Warnung 80 °C, kritisch 90 °C.",
"<strong>Disk Temperatur</strong> — HDD 60/65 °C · SSD 70/75 °C · NVMe 80/85 °C · SAS 55/65 °C (Warnung/kritisch)."
],
"outro": "Alle Werte sind pro Host konfigurierbar. <link>Einstellungen → Grenzwerte der Zustandsüberwachung</link> ist die zentrale Referenz und erklärt ihre Anpassung."
},
"sections": {
"heading": "Abschnitte",
"intro": "Die Abschnitte erscheinen von oben nach unten in dieser Reihenfolge. Manche benötigen die passende Hardware oder ein installiertes Werkzeug und sind unten als <em>(bedingt)</em> markiert.",
"systemInfoTitle": "Systeminformationen",
"systemInfoIntro": "Zwei nebeneinander liegende Blöcke, immer vorhanden:",
"systemInfoItems": [
"<strong>CPU</strong> — Modell, Mikroarchitektur, Sockel/Kerne/Threads, Basis-/Boost-Takt, Virtualisierungsmerkmale (VT-x / AMD-V) und Cache-Topologie.",
"<strong>Mainboard</strong> — Hersteller, Modell, BIOS-Version und -Datum sowie SMBIOS-UUID. Hilft beim Finden der passenden Hersteller-Downloadseite für Firmware-Updates."
],
"memoryTitle": "Speichermodule",
"memoryBody": "Eine Zeile je belegtem Steckplatz aus <code>dmidecode</code>: Steckplatzbezeichnung, Modulgröße, Typ (DDR4/DDR5/ECC), konfigurierter und spezifizierter Takt, Hersteller, Teile- und Seriennummer. Leere Steckplätze sind ausgegraut, damit das Erweiterungspotenzial sichtbar bleibt.",
"thermalTitle": "Thermische Überwachung",
"thermalIntro": "Sieben Bereiche mit Daten aus <code>lm-sensors</code>, <code>sysfs</code> und werkzeugspezifischen Auswertungen. Speicher-hwmon-Sensoren werden dem physischen Blockgerät zugeordnet, sodass jedes Laufwerk mit Modell und <code>/dev/...</code>-Pfad erscheint. Ohne Sensoren einer Kategorie bleibt deren Bereich verborgen.",
"thermalItems": [
"<strong>CPU</strong> — Temperatur des CPU-Packages und der einzelnen Kerne.",
"<strong>GPU</strong> — Sensoren dedizierter GPUs über <code>nvidia-smi</code>/<code>amdgpu_top</code> sowie Intel-iGPU. Hotspot- und Speicher-Junction-Temperatur, sofern der Treiber sie bereitstellt.",
"<strong>NVME</strong> — zusammengesetzte Controllertemperatur, dem genauen NVMe-Namespace zugeordnet.",
"<strong>HDD</strong> — <code>drivetemp</code>-Messwerte für Rotationsblockgeräte.",
"<strong>SSD</strong> — <code>drivetemp</code>-Messwerte für nicht rotierende SATA/SAS-Blockgeräte.",
"<strong>PCI</strong> — Sensoren, die als PCI-befestigte Geräte auftauchen (HBAs, Netzwerkkarten mit internen Sensoren).",
"<strong>OTHER</strong> - Chipsatz, VRM, Umgebungssensoren, die anderswo nicht passen."
]
},
"graphics": {
"heading": "Grafikkarten",
"intro": "Jeder Videocontroller erscheint als Karte mit Hersteller, Modell, Typ (<em>Integriert</em>/<em>PCI</em>/BMC), PCI-Adresse (BDF), Kerneltreiber und Modulen. <strong>Modus wechseln</strong> schaltet zwischen LXC-Freigabe mit nativem Treiber und VM-Passthrough (<code>vfio-pci</code>) um. <link>GPU-Modus wechseln (VM ↔ LXC)</link> beschreibt die Änderungen auf dem Host.",
"vfioImageAlt": "Grafikkarten-Abschnitt mit einer an mgag200 gebundenen Matrox G200EH integrierten GPU (Ready for LXC) und einer an vfio-pci gebundenen NVIDIA Quadro P400 (Ready for VM passthrough)",
"vfioImageCaption": "Zwei GPUs erkannt: Der Matrox BMC Chip ist auf dem nativen Treiber und bereit für LXC; der NVIDIA Quadro P400 ist an <code>vfio-pci</code> gebunden, bereit für VM Passthrough.",
"lxcImageAlt": "Grafikkarten: Intel UHD Graphics iGPU mit i915 und NVIDIA Quadro P1000 mit nvidia, beide bereit für LXC-Container",
"lxcImageCaption": "Der gleiche Knoten nach dem Umschalten der NVIDIA-Karte zurück zum nativen Treiber - beide GPUs sind jetzt bereit für LXC-Container.",
"realtimeTitle": "Dialog zur Echtzeitüberwachung",
"realtimeBody": "Ein Klick auf eine GPU öffnet die Überwachung dieses Steckplatzes. Alle drei Sekunden wird das passende Herstellerwerkzeug abgefragt. Sichtbar sind Hersteller, Typ, PCI-Steckplatz, Treiber, Kernelmodule, Engine-Auslastung (Render/3D, Video, Blitter, VideoEnhance), Grafik- und Speichertakt, Temperatur, gemeldete Leistungsaufnahme, VRAM und aktive Prozesse mit jeweiliger Engine-Last. Daten aus <code>/api/gpu/&lt;slot&gt;/realtime</code>.",
"toolsIntro": "Das je GPU verwendete Herstellerwerkzeug :",
"headerVendor": "Hersteller",
"headerTool": "Werkzeug",
"headerProject": "Projekt",
"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": "— (nur Anzeige)",
"projectLabel": "Als BMC erkannt und gekennzeichnet; keine Echtzeitüberwachung."
}
],
"nvidiaImageAlt": "Überwachung einer NVIDIA Quadro P1000: Hersteller NVIDIA, Treiber nvidia geladen, Grafiktakt 1.26 GHz, Speichertakt 2.50 GHz, Temperatur 50 °C, alle Engines bei 0 %, keine aktiven Prozesse, 4096 MiB Gesamtspeicher",
"nvidiaImageCaption": "NVIDIA Quadro P1000 mit proprietärem Treiber: Taktfrequenzen, Temperatur, Engine-Auslastungsbalken und aktive Prozesse.",
"intelImageAlt": "Überwachung einer Intel UHD Graphics iGPU mit i915: 11.31 W Leistungsaufnahme, 1 % Video-Engine-Last und ein ffmpeg-Prozess mit 8 MB",
"intelImageCaption": "Intel iGPU mit <code>i915</code> aktiv. Die Tabelle Aktive Prozesse nimmt einen ffmpeg-Job mit der Video-Engine auf.",
"amdImageAlt": "Überwachung der integrierten AMD Lucienne GPU mit amdgpu: Engine-Auslastung bei 0 % und amdgpu_top als aktiver Prozess",
"amdImageCaption": "AMD-iGPU mit <code>amdgpu_top</code> überwacht. Das Werkzeug erscheint selbst als aktiver Prozess, weil es die Live-Daten erfasst.",
"installTitle": "NVIDIA-Treiber aus dem Dialog installieren",
"installBody": "Bei einer NVIDIA-GPU mit <code>nouveau</code>/<code>nvidiafb</code> ohne proprietären Treiber fehlen Takt-, Leistungs- und Prozesslastdaten. Der Dialog zeigt dann <strong>NVIDIA-Treiber installieren</strong> und startet das unter <link>NVIDIA-Treiber installieren (Host)</link> beschriebene Skript.",
"noDriverAlt": "Überwachung einer NVIDIA Quadro P620 mit nvidiafb und nouveau, Hinweis Erweiterte Überwachung nicht verfügbar und blauer Schaltfläche NVIDIA-Treiber installieren",
"noDriverCaption": "Noch kein proprietärer Treiber installiert — der Dialog bietet einen Ein-Klick-Installer.",
"promptAlt": "NVIDIA GPU-Treiber-Installationsbestätigungsdialog mit erkannten GPUs, LXC-Containern mit NVIDIA-Durchgang und einem Yes/Cancel-Paar",
"promptCaption": "Zusammenfassung vor der Installation: erkannte GPUs, LXC-Container, die bereits NVIDIA-Passthrough haben, und was das Skript tun wird. Nichts wird berührt, bis Sie bestätigen.",
"successAlt": "Terminalausgang mit erfolgreich installiertem NVIDIA-Treiber 580.105.08 und nvidia-smi mit Quadro P620",
"successCaption": "Erfolgreiche Installation - der NVIDIA <code>.run</code> wurde über DKMS gebaut, der Persistenzdienst ist vorhanden, und <code>nvidia-smi</code> meldet den GPU.",
"warningTitle": "Eine von der GPU unterstützte Treiberversion wählen",
"warningBody": "Neuere NVIDIA-Treiberzweige stellen die Unterstützung älterer GPU-Familien wie Maxwell oder Kepler ein. Meldet <code>nvidia-smi</code> nach der Installation <em>\"No devices were found\"</em> oder schlägt DKMS fehl, passt der gewählte Zweig möglicherweise nicht zur GPU. Starten Sie die Installation mit einem älteren Zweig, etwa Legacy 470.x für Kepler. Die Kompatibilität steht auf der <a>offiziellen Treibersuchseite</a>.",
"whereGoIntro": "Wohin gehen von hier aus:",
"whereGoItems": [
"<link1>NVIDIA-Treiber installieren (Host)</link1> — vollständige Installationsanleitung, Kernel-Kompatibilitätsmatrix, optionaler NVENC-Patch und Übertragung auf LXCs.",
"<link2>GPU-Modus wechseln (VM ↔ LXC)</link2> — Funktion des direkten Schalters <em>Modus wechseln</em>.",
"<link3>GPU zu VM hinzufügen (Passthrough)</link3> und <link4>GPU zu LXC hinzufügen</link4> — erstmalige Zuweisung einer ungebundenen GPU."
]
},
"coral": {
"heading": "Coral TPU / AI-Beschleuniger",
"subHeading": "(bedingt)",
"intro": "Erscheint bei angeschlossenen Google-Coral- oder anderen KI-Beschleunigern. Der Gerätedialog zeigt Verbindung (M.2/Mini-PCIe/USB), PCIe-Breite, Hersteller-/Produkt-ID, Softwareunterstützung (<code>apex</code> im Kernel für PCIe, <code>libedgetpu</code> im Userspace für USB), Module (<code>gasket</code> + <code>apex</code>), Geräteknoten (<code>/dev/apex_*</code>), Edge-TPU-Laufzeitstatus, Live-Temperatur und Firmware-Warnschwellen.",
"imageAlt": "Coral Edge TPU Detail modal: PCIe / M.2 Verbindung, PCIe 5.0 GT/s x1 Link, Anbieter 1ac1:089a, Kernel-Treiber apex, gasket und apex Module geladen, /dev/apex_0 vorhanden, Edge TPU Runtime nicht installiert, Temperatur 53.5 °C mit Hardware-Warnschwellenwerten",
"imageCaption": "M.2 Coral mit den geladenen Host-Kernel-Modulen, dem Geräteknoten und den freigegebenen Firmware-Temperaturwarnungen. Die Laufzeitlinie wird grün, sobald die passende Edge TPU-Laufzeit installiert ist.",
"pathsIntro": "Je nach Formfaktor gibt es zwei Installationspfade:",
"pathsItems": [
"<strong>M.2 / Mini-PCIe</strong> - der Host benötigt die Kernelmodule <code>gasket</code> + <code>apex</code>, die über DKMS erstellt wurden, damit der Geräteknoten <code>/dev/apex_0</code> beim Booten erscheint.",
"<strong>USB Accelerator</strong> – der Host benötigt nur die Edge TPU User-Space Runtime (<code>libedgetpu1-std</code>) aus dem APT-Repository von Google."
],
"outro": "<installLink>Coral TPU auf dem Host installieren</installLink> erkennt und verwaltet beide Varianten. Hintergrundinformationen und die offizielle Laufzeit finden Sie unter <a>coral.ai/docs</a>. Anschließend weisen Sie das Gerät mit <lxcLink>Coral TPU zu LXC hinzufügen</lxcLink> einem Container zu."
},
"storage": {
"heading": "Speicherzusammenfassung",
"intro": "Alle dem Kernel bekannten Blockgeräte nach Typ. Je Datenträger: Kernelname (<code>sda</code>, <code>nvme0n1</code>, <code>zram0</code>…), Typ (<em>SSD</em>, <em>HDD</em>, <em>NVMe SSD</em>), Modell und ausgehandelte Verbindung. Ein Klick öffnet Modell, Seriennummer, Kapazität, Schnittstelle sowie aktuelle und maximale Verbindungsgeschwindigkeit.",
"imageAlt": "Storage Summary-Karte mit elf Blockgeräten (SATA SSDs, SATA HDDs, NVMe SSDs und zram) mit Modellzeichenfolgen und ausgehandelten Verbindungsgeschwindigkeiten; die beiden NVMe-Laufwerke zeigen 3.0 x4 mit der aktuellen Geschwindigkeit hervorgehoben",
"imageCaption": "Elf Geräte auf diesem Knoten. SATA-Verbindungen erscheinen als <em>SATA &lt;version&gt;, &lt;Gb/s&gt; (current: ...)</em>, NVMe-Laufwerke als <em>&lt;PCIe gen&gt; x&lt;width&gt;</em>.",
"nvmeBody": "Bei NVMe wird die ausgehandelte Verbindung mit dem Gerätemaximum verglichen. Bei Abweichungen, etwa einer Gen3-x4-SSD mit <strong>3.0 x1</strong> in einem einspurig angebundenen Steckplatz, erscheint der aktuelle Wert bernsteinfarben. Das hilft bei langsamen Laufwerken oder nach einer geänderten Lane-Zuordnung durch ein BIOS-Update.",
"nvmeModalAlt": "NVMe-Detaildialog für nvme0n1: NVMe SSD, 953.9 GB, aktueller Link 3.0 x1 bernsteinfarben, Maximum 3.0 x4, WDC CL SN720, Seriennummer, PCIe/NVMe",
"nvmeModalCaption": "NVMe-Details mit reduzierter Lane-Anzahl: Das Laufwerk unterstützt x4, der Steckplatz ist nur x1 angebunden.",
"outro": "SMART-Daten, Selbsttests, Verlauf und PDF-Bericht stehen unter <storageLink>Dashboard: Speicher</storageLink>. Dieselben Daten nutzt <smartLink>SMART-Datenträgerzustand und Tests</smartLink>. Ein langer Test über das Skript schreibt die JSON-Datei für <em>Speicher → Verlauf</em> in Monitor."
},
"pci": {
"heading": "PCI-Geräte",
"intro": "PCI-Geräte mit <strong>PCI-BDF</strong> (Bus:Device.Function, etwa <code>03:00.0</code>) und Klasse (<em>Speichercontroller</em>, <em>USB-Controller</em>, <em>Grafikkarte</em>, <em>Netzwerkcontroller</em>, <em>Audiocontroller</em>…). Jede Karte zeigt Hersteller, Gerätenamen und <strong>aktuell gebundenen Kerneltreiber</strong>, hilfreich bei Passthrough-, IOMMU- oder Treiberproblemen.",
"imageAlt": "PCI Devices Abschnitt listet fünfzehn Geräte nach Klasse gruppiert: Speicher-Controller auf ahci / nvme, USB-Controller, Grafikkarten (einer auf vfio-pci, einer auf dem nativen Treiber), Netzwerk-Controller auf igb / tg3, ein Audio-Controller neben einem durchgelassenen GPU",
"imageCaption": "Fünfzehn Geräte auf diesem Knoten. Beachten Sie, dass die GPU und die dazugehörige Audiofunktion beide an <code>vfio-pci</code> gebunden sind - eine Karte, die für den VM-Durchgang vorbereitet ist.",
"bdfTitle": "Lesen des BDF",
"bdfBody": "<code>03:00.0</code> steht für PCI-Bus <code>03</code>, Gerät <code>00</code>, Funktion <code>0</code>. Dedizierte GPUs verwenden meist <code>.0</code> für Grafik und <code>.1</code> für HDMI-Audio. Beide Funktionen werden gemeinsam durchgereicht; deshalb bereinigt <link>GPU-Modus wechseln</link> beim Verlassen des VM-Modus auch verwaiste Audiozuordnungen."
},
"usb": {
"heading": "USB-Geräte",
"intro": "USB-Geräte mit Hersteller und Produkt, USB-Version, <code>bus:device</code>-Adresse, <code>vendor:product</code>-ID und Kerneltreiber. Die Anzeige ordnet typische Rollen zu: <em>Kommunikation</em> (Z-Wave-/Zigbee-Sticks), <em>USV</em>, Speicher und HID. So lassen sich die Adapter ohne ID-Abgleich unterscheiden.",
"imageAlt": "USB-Gerätekarte mit drei Geräten: einem Aeotec Z-Wave Z-Stick, einem ConBee II Zigbee-Koordinator und einem Ellipse ECO USV mit jeweils USB-Version, Adresse, Vendor:product ID und gebundenem Treiber",
"imageCaption": "Drei USB-Geräte - zwei Heimautomationsradios auf <code>usbfs</code> und ein USV auf <code>usbfs</code> (NUT spricht mit ihm über libusb)."
},
"power": {
"heading": "Stromverbrauch",
"subHeading": "(bedingt)",
"intro": "Erscheint, wenn der Host Leistungsdaten liefert. Zwei unabhängige Quellen werden angezeigt, sofern verfügbar :",
"items": [
"<strong>Gesamtleistung ACPI/IPMI</strong> — Leistungsaufnahme des ganzen Systems über einen Mainboard-Sensor oder BMC. Typisch für Server-Mainboards.",
"<strong>CPU-Package-Leistung</strong> — aus Intel-RAPL-Zählern oder AMD-Entsprechung. Trennt die CPU-Leistung vom übrigen System auf Consumer-Mainboards ohne Gesamtsensor."
],
"supplyImageAlt": "Abschnitt Stromverbrauch zeigt die Gesamtentnahme von 198 W über die ACPI-Schnittstelle sowie eine Power Supplies-Karte mit zwei PSUs, die beide OK melden (185 W und 5 W Ausgang)",
"supplyImageCaption": "Serverplatine mit einem einzigen ACPI-Leistungssensor und zwei PSUs, die über IPMI gemeldet werden — die zweite PSU ist die redundante, im Leerlauf bei 5 W.",
"cpuImageAlt": "Abschnitt Stromverbrauch auf einer Verbraucherplatine mit nur CPU Power 8.7 W über Intel RAPL",
"cpuImageCaption": "Verbraucherplatine ohne Ganzsystemsensor - der Abschnitt fällt nur auf RAPL CPU zurück."
},
"psu": {
"heading": "Netzteile",
"subHeading": "(bedingt)",
"body": "Auf Server-Mainboards mit mehreren Netzteilen zeigt IPMI deren Vorhandensein (PSU 1 / PSU 2 / …), Eingangsspannung, Ausgangsleistung und Zustand OK/Fehler. Nach einer Stromstörung ist dies die erste Prüfung bei redundanten Netzteilen."
},
"fans": {
"heading": "Systemlüfter",
"subHeading": "(bedingt)",
"body": "Drehzahl jedes Lüfters mit Minidiagramm, sofern unterstützt. Ohne Einzelwerte wird ein einziger Gehäuselüfterwert angezeigt."
},
"ups": {
"heading": "UPS-Status",
"subHeading": "(bedingt)",
"body": "Erscheint bei konfiguriertem und erreichbarem NUT-Server (Network UPS Tools). Sichtbar sind Status (Netzbetrieb/Batteriebetrieb/Laden/Batterie schwach), Batterieladung, Restlaufzeit, Last, Eingangsspannung, Modell und Firmware. Dieselben Daten fließen in <em>Sicherheit und Zertifikate</em> der Zustandsüberwachung ein; Batteriebetrieb wird sofort gemeldet."
},
"dataCollected": {
"heading": "Wie die Daten gesammelt werden",
"headerSection": "Abschnitt des Reiters",
"headerEndpoint": "Endpunkt",
"headerSource": "Quelle",
"rows": [
{
"section": "Statisches Inventar (PCI, CPU, BIOS)",
"endpoint": "/api/hardware",
"source": "<code>lspci -vmm</code>, <code>/proc/cpuinfo</code>, <code>dmidecode</code>; für die Laufzeit des Prozesses zwischengespeichert."
},
{
"section": "Live-Sensorwerte",
"endpoint": "/api/hardware/live",
"source": "<code>sensors</code> (lm-sensors), <code>/sys/class/hwmon</code> und <code>/sys/block</code> identifizieren Speichergeräte. Temperaturen bleiben live; nur die Zuordnung von hwmon zu Geräten wird 60 Sekunden zwischengespeichert."
},
{
"section": "CPU Temperaturverlauf",
"endpoint": "/api/temperature/history",
"source": "Zeitreihe, die der Temperatur-Collector alle 60 Sekunden erfasst und in SQLite speichert."
},
{
"section": "GPU Live-Metriken",
"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": "# Inventar mit der Betriebssystemansicht abgleichen",
"codeComment2": "# Bestätigen Sie die GPU-Karte, die das Dashboard sieht"
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "Installieren Sie NVIDIA Treiber (Host)",
"href": "/docs/hardware/nvidia-host",
"tail": "— was die Installationsschaltfläche des GPU-Modals ausführt."
},
{
"label": "GPU-Modus wechseln (VM ↔ LXC)",
"href": "/docs/hardware/switch-gpu-mode",
"tail": "— was der Inline-Modus-Schalter auf jeder GPU-Karte mit dem Host macht."
},
{
"label": "Installieren Sie Coral TPU auf dem Host",
"href": "/docs/hardware/install-coral-tpu-host",
"tail": " — Installation von Coral-Kernelmodul und -Laufzeit."
},
{
"label": "SMART-Festplattenstatus und -test",
"href": "/docs/disk-manager/smart-disk-test",
"tail": " — das Skript hinter den SMART-Daten in der Datenträger-Detailansicht unter Speicher."
},
{
"label": "Dashboard: Speicher-Tab",
"href": "/docs/monitor/dashboard/storage",
"tail": "— vollständige SMART-Attributtabelle, Selbsttestverlauf und PDF-Bericht."
},
{
"label": "Gesundheitsmonitor",
"href": "/docs/monitor/health-monitor",
"tail": " — die Kategorie CPU und Temperatur, die dieselben Sensoren nutzt."
},
{
"label": "API-Referenz",
"href": "/docs/monitor/api",
"tail": " — die Endpunkte für Hardware und GPU."
},
{
"label": "Dashboard-Index",
"href": "/docs/monitor/dashboard",
"tail": " — die anderen Reiter."
}
]
}
}
@@ -0,0 +1,101 @@
{
"meta": {
"title": "ProxMenux Monitor — Dashboard | ProxMenux-Dokumentation",
"description": "Das Dashboard ist die Hauptoberfläche von ProxMenux Monitor: zehn Inhaltsreiter einschließlich Apps-Starter, eine globale Kopfzeile und eine konfigurierbare Navigationsreihenfolge."
},
"header": {
"title": "Dashboard",
"description": "Die Alltagsansicht von ProxMenux Monitor: zehn Inhaltsreiter einschließlich Apps-Starter, eine globale Kopfzeile und eine konfigurierbare Navigationsreihenfolge.",
"section": "ProxMenux Monitor"
},
"oneHeader": {
"title": "Ein Header, zehn Tabs",
"body": "Die Kopfzeile mit Logo, Knotenname, Statusanzeige, Laufzeit, Aktualisierung und Designauswahl bleibt sichtbar. Der aktive Reiter wechselt den gesamten Inhalt darunter. Die Statusfarbe entspricht der schwerwiegendsten Kategorie der <link>Zustandsüberwachung</link>; im Dashboard wird derselbe Wert angezeigt."
},
"tabs": {
"heading": "Die zehn Tabs",
"intro": "Jeder Tab hat eine eigene eigene Seite. Seiten werden schrittweise hinzugefügt, wenn die Dokumentation ausgefüllt wird; unten ist die vollständige Liste und wofür jeder verantwortlich ist.",
"headerTab": "Tab.",
"headerOwns": "Zuständig für",
"rows": [
{
"name": "Systemübersicht",
"linksTo": "/docs/monitor/dashboard/system-overview",
"owns": "CPU / Speicher / Temperatur-Widgets, aktive VM & LXC Anzahl, historische Metriken Charts, Speicher und Netzwerk-Zusammenfassungen. Standardlanderegisterkarte, bis die Navigationsreihenfolge angepasst ist."
},
{
"name": "Apps",
"linksTo": "/docs/monitor/dashboard/apps",
"owns": "Gemeinsamer Starter für registrierte LXC-Weblinks und eigene Links, mit Kategorien, Suche, Gastsystem-Verknüpfungen und Aktualisierungshinweisen je Anwendung."
},
{
"name": "Speicher",
"owns": "Proxmox-Pools, physische Festplatten, SMART-Daten, ZFS-Zustand, Verschleiß & Lebensdauer, Beobachtungshistorie."
},
{
"name": "Netzwerk",
"owns": "Physische Schnittstellen, Bonds, Bridges und OVS, IP/MAC-Adressen, RX/TX-Diagramme und RRD-Verlauf je Schnittstelle."
},
{
"name": "VMs und LXCs",
"owns": "Bestandsaufnahme der Gastsysteme, Detailansicht für Konfiguration, Metriken und Protokolle sowie Starten, Stoppen, Neustarten und Herunterfahren."
},
{
"name": "Hardware",
"owns": "CPU-Modell und Topologie, Speicherlayout, PCIe-Topologie, GPUs mit Echtzeitüberwachung pro Slot."
},
{
"name": "Systemprotokolle",
"owns": "Live <code>journalctl</code> mit Filtern, Proxmox Task History, Benachrichtigungsprotokoll, herunterladbare Log-Bundles."
},
{
"name": "Terminal",
"owns": "Shell-Zugriff auf Host oder VM/CT im Browser mit <code>xterm.js</code> über WebSockets."
},
{
"name": "Sicherheit",
"owns": "Auth-Setup, Passwort / 2FA / API-Token, Audit-Log, optionales Fail2Ban-Panel, Secure Gateway-Bereitstellung."
},
{
"name": "Einstellungen",
"owns": "Monitor-Sprache, Navigationsreihenfolge, Benachrichtigungskanäle, KI-Anbieter, Zustandsschwellen, Ausschlüsse und Nachinstallationsoptimierungen."
}
]
},
"headerAnatomy": {
"heading": "Kopfanatomie",
"items": [
"<strong>Logo + Produktname</strong> auf der linken Seite. Das Logo wird zu einer \"update available\"-Variante, wenn eine neuere Monitor-Version erkannt wird.",
"<strong>Knotenidentität</strong>: Name aus <code>pvesh get /nodes</code>, ersatzweise <code>hostname</code>.",
"<strong>Zustandsanzeige</strong>: Gesund (grün), Warnung (gelb), Kritisch (rot). Ein Klick öffnet die Zustandsüberwachung. Ein blaues <em>Info</em>-Abzeichen erscheint, wenn ausgeblendete Elemente noch innerhalb ihrer Unterdrückungsfrist liegen.",
"<strong>Laufzeit</strong>: Betriebszeit des Hosts in gut lesbarem Format.",
"<strong>Aktualisieren</strong>: wiederholt die Live-API-Aufrufe, ohne die gesamte Seite neu zu laden.",
"<strong>Designauswahl</strong>: hell, dunkel oder System. In <code>localStorage</code> gespeichert."
]
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "Apps Tab",
"href": "/docs/monitor/dashboard/apps",
"tail": " — gemeinsamer Weblink-Starter und seine Beziehung zu registrierten LXC-Anwendungen."
},
{
"label": "Registerkarte Systemübersicht",
"href": "/docs/monitor/dashboard/system-overview",
"tail": "— die Landekarte, vollständig dokumentiert."
},
{
"label": "Gesundheitsmonitor",
"href": "/docs/monitor/health-monitor",
"tail": " — Dialog hinter der Zustandsanzeige mit Details zu zehn Kategorien."
},
{
"label": "Architektur",
"href": "/docs/monitor/architecture",
"tail": "— wie das Dashboard mit dem Flask-Backend spricht."
}
]
}
}
@@ -0,0 +1,251 @@
{
"meta": {
"title": "ProxMenux Monitor — Dashboard: Registerkarte Netzwerk | ProxMenux-Dokumentation",
"description": "Die Registerkarte Netzwerk erfasst alle Hostschnittstellen: physische Netzwerkkarten, Bridges, Bonds, VLANs und virtuelle VM/LXC-Schnittstellen. Die Detailansicht zeigt IP, MAC, Status, Bond-Mitglieder, Verkehr seit dem Start und ein RRD-Verlaufsdiagramm."
},
"header": {
"title": "Dashboard: Netzwerk-Tab",
"description": "Alle vom Kernel gemeldeten Schnittstellen — physische Karten, Bridges, Bonds, VLANs und virtuelle VM/LXC-Ports — sind in drei Karten gruppiert. Ein Klick auf eine Zeile öffnet Adressen, Verkehrszähler und RRD-Verlaufsdaten.",
"section": "ProxMenux Monitor · Übersicht"
},
"intro": {
"title": "Aktuelle Daten und Verlauf",
"body": "Der aktuelle Status stammt aus <code>psutil.net_if_stats()</code> und <code>ip</code>, der Bandbreitenverlauf aus dem Proxmox-RRD-Speicher über <code>/api/network/&lt;interface&gt;/metrics</code>. Zähler werden etwa alle 5 Sekunden aktualisiert, RRD-Daten für das Diagramm bei Bedarf geladen."
},
"topRow": {
"heading": "Obere Reihe: vier Kennzahlenkarten",
"headerCard": "Karte",
"headerWhat": "Was es zeigt",
"rows": [
{
"card": "Netzwerkverkehr",
"what": "Aggregierte RX / TX-Rate über alle Schnittstellen hinweg, formatiert in der richtigen Einheit (bps / Kbps / Mbps / Gbps)."
},
{
"card": "Aktive Schnittstellen",
"what": "Zwei Zähler: <em>Physical X / Y</em> und <em>Bridges X / Y</em>, jeweils aktiv im Verhältnis zur Gesamtzahl. Ein erster Anhaltspunkt, wenn etwas nicht mehr funktioniert."
},
{
"card": "Netzwerkstatus",
"what": "Schnelle Bewertung: In Ordnung / Warnung / Kritisch anhand von Verbindungsstatus, Gateway-Erreichbarkeit und Bridge-Integrität. Entspricht der Kategorie <em>Netzwerkschnittstellen</em> im Health Monitor."
},
{
"card": "Netzwerklatenz",
"what": "Paketumlaufzeit zum Gateway mit kleinem Verlaufsdiagramm. Ein Klick öffnet den unten beschriebenen <strong>Dialog Netzwerklatenz</strong>: Verlauf und Ping-Test bei Bedarf zu Gateway, Cloudflare oder Google mit herunterladbarem PDF-Bericht."
}
]
},
"flow": {
"heading": "Netzwerkflussdiagramm",
"intro": "Zwischen oberer Reihe und Gruppenkarten zeigt <strong>Network Flow</strong> die aktuelle Topologie. Die Paketwege führen von physischen Netzwerkkarten über Bridges zu VMs und Containern. Animierte Impulse stellen den aktuellen rx/tx-Verkehr jeder Verbindung dar.",
"imageAlt": "Netzwerkflussdiagramm — NICs links, Host und Bridges in der Mitte, VMs und LXCs rechts, mit animierten Impulsen auf jeder Verbindung",
"imageCaption": "Network Flow – farbkodierte Knoten sowie animierte Kometen, deren Richtung und Dicke Live-Verkehr widerspiegeln.",
"elementsTitle": "Was das Diagramm zeigt",
"elementsIntro": "Jeder Knoten stellt einen Eintrag aus demselben Inventar wie die Karten darunter dar. Die Anordnung als Topologie macht ihre Beziehungen sofort sichtbar:",
"elements": [
"<strong>Netzwerkkarten</strong> (orange) — physische Schnittstellen mit aktiver Verbindung; inaktive erscheinen blass.",
"<strong>Host</strong> (orange) — der Proxmox-Host zwischen Netzwerkkarten und Bridges. Ein fester Bezugspunkt, nicht anklickbar.",
"<strong>Bridges</strong> (cyan) — Linux- und OVS-Bridges mit mindestens einem aktiven Gast. Ungenutzte Bridges werden ausgeblendet, damit das Diagramm den tatsächlichen Verkehr zeigt.",
"<strong>LXCs</strong> (cyan) — laufende Container an einer Bridge.",
"<strong>VMs</strong> (lila) — laufende virtuelle Maschinen an einer Bridge.",
"Gestoppte VMs und Container werden ausgeblendet."
],
"pulsesTitle": "Was die Animation kodiert",
"pulsesBody": "Die animierten Kometen, die sich entlang jeder Kante bewegen, repräsentieren Live-Verkehr:",
"pulses": [
"<strong>Richtung</strong> — zur Netzwerkkarte bedeutet <em>tx</em> des Gastes, zum Gast bedeutet <em>rx</em>.",
"Die <strong>Linienbreite</strong> wächst mit der rx+tx-Rate des Gastes. Bei wenig Verkehr bleibt eine schwache animierte Linie sichtbar, bei hohem Verkehr wird sie dick.",
"<strong>Leuchten des Kometenkopfs</strong> — warm bei etwa 1 MB/s, intensiv ab 30 MB/s. Zeigt auf einen Blick, welcher Gast eine Netzwerkkarte stark auslastet.",
"<strong>Klick</strong> — alle Knoten außer dem Host öffnen den unten beschriebenen Schnittstellendialog. Ein Klick auf den Host hat keine Wirkung; dafür gibt es hier keinen Dialog."
],
"useTitle": "Wenn es nützlich ist",
"useBody": "Die Karten zeigen, <em>was</em> vorhanden ist; das Diagramm zeigt, <em>wie es verbunden ist</em> und wo Verkehr fließt. Sichtbar werden Gäste an derselben Bridge, zwei stark ausgelastete Gäste an derselben Netzwerkkarte als möglicher Engpass oder eine VM, die eine Verbindung allein auslastet."
},
"groups": {
"heading": "Drei Schnittstellengruppen",
"intro": "Drei Karten gruppieren Schnittstellen nach Funktion. Jede Kopfzeile zeigt die Anzahl aktiver Schnittstellen. Eine farbige Kennzeichnung nennt den <strong>Typ</strong> jeder Schnittstelle:",
"badges": [
"Blaues <strong>Physical</strong> — physische Netzwerkkarte.",
"Grünes <strong>Bridge</strong> — Linux- oder OVS-Bridge (<code>vmbr*</code>).",
"Purple <strong>Bond</strong> — Bond / LACP / Active-Backup-Aggregator.",
"Cyanfarbenes <strong>VLAN</strong> — VLAN-Unterschnittstelle (<code>vmbr0.10</code>, <code>eno1.42</code>, …)."
],
"clickable": "<strong>Jede Zeile ist anklickbar</strong>: physische und virtuelle Schnittstellen, Bridges und Bonds. Der unten beschriebene Dialog zeigt Basisdaten, IPs, Zähler und den RX/TX-Verlauf aus dem Proxmox-RRD-Speicher.",
"physicalTitle": "Physikalische Schnittstellen",
"physicalBody": "Vom Kernel erkannte physische Schnittstellen: <code>eno1</code>, <code>enp4s0</code>, <code>eth0</code>, <code>wlp3s0</code> usw. Jedes Gerät hat eine Zeile mit blauem <strong>Physical</strong>-Label und Verbindungsstatus. Auch <em>Bond-Mitglieder</em> erscheinen hier mit Verweis auf den zugehörigen Bond.",
"bridgeTitle": "Bridge-Schnittstellen",
"bridgeBody": "Von Proxmox verwaltete Linux-Bridges (<code>vmbr0</code>, <code>vmbr1</code>, …) und OVS-Bridges. Jede Zeile zeigt das grüne <strong>Bridge</strong>-Label, bei nur einem Port die physische Schnittstelle und den Status. Bonds tragen das lila <strong>Bond</strong>-Label, VLAN-Unterschnittstellen das cyanfarbene <strong>VLAN</strong>-Label.",
"vmTitle": "VM-/LXC-Schnittstellen",
"vmBody": "Beim Gaststart erzeugte <code>tap*</code>- und <code>veth*</code>-Schnittstellen, eine je virtueller Netzwerkkarte. Die Kopfzeile zeigt <em>X / Y Active</em>; die Zeilen verlinken zur VM/CT auf der Registerkarte VMs & LXCs. Nach dem Stoppen verschwinden inaktive Einträge mit dem nächsten Aktualisierungszyklus."
},
"drillIn": {
"heading": "Schnittstellendetails",
"intro": "Ein Klick auf eine Zeile öffnet einen Dialog mit fünf Bereichen:",
"headerBlock": "Block",
"headerContents": "Inhalt",
"rows": [
{
"block": "Grundlegende Informationen",
"contents": "Name, Typ (physisch / Bridge / Bond / VLAN / vm), MAC-Adresse, Status (aktiv / inaktiv), MTU und zugrunde liegende physische Schnittstelle bei virtuellen Typen."
},
{
"block": "Bond-Mitglieder",
"contents": "Nur für Bonds: jede zugeordnete Netzwerkkarte mit Aktiv-/Fehlerstatus, Bond-Modus (active-backup / 802.3ad / balance-alb / …) und gegebenenfalls primäre Schnittstelle."
},
{
"block": "IP-Adressen",
"contents": "Jede IPv4/IPv6-Adresse mit der Präfixlänge. Autokonfigurierte link-lokale Adressen werden aufgelistet, aber ausgegraut."
},
{
"block": "Verlaufsdiagramm",
"contents": "RX/TX-Bandbreite im gewählten Zeitraum (1 Stunde / 24 Stunden / 7 Tage / 30 Tage / 1 Jahr), geladen über <code>/api/network/&lt;interface&gt;/metrics</code> aus Proxmox-RRD."
},
{
"block": "Verkehr seit dem letzten Start",
"contents": "RX/TX-Bytes und -Pakete seit dem letzten Hoststart sowie Zähler für Fehler und verworfene Pakete."
}
],
"inactiveTitle": "Auch inaktive Schnittstellen haben eine Detailansicht",
"inactiveBody": "Ist die Schnittstelle <em>inaktiv</em>, zeigt der Dialog den Hinweis „Schnittstelle inaktiv“ ohne aktuelle Zähler. Konfiguration mit Adressen und Bond-Mitgliedern sowie Verlaufsdaten bleiben zur Fehlerdiagnose sichtbar."
},
"latency": {
"heading": "Dialog Netzwerklatenz",
"intro": "Die Karte <em>Netzwerklatenz</em> in der oberen Reihe öffnet einen eigenen Dialog mit Verlauf, Tests bei Bedarf, drei Zielen und herunterladbarem PDF-Bericht.",
"targetsTitle": "Ziele",
"targetsIntro": "Die Auswahlliste oben bestimmt das Ping-Ziel:",
"targets": [
"<strong>Gateway</strong> — Ihr LAN-Router. Prüft nur den lokalen Abschnitt, um Switch- oder Kabelprobleme ohne WAN-Einfluss zu untersuchen.",
"<strong>Cloudflare (1.1.1.1)</strong> — öffentlicher DNS-Resolver im Anycast-Netz. Prüft den WAN-Abschnitt.",
"<strong>Google (8.8.8.8)</strong> — alternatives öffentliches Ziel zur Gegenprüfung oder bei regionalen Cloudflare-Störungen."
],
"mode1Title": "Modus 1 — Historische Ansicht",
"mode1Alt": "Latenzdialog im Verlaufsmodus mit Ziel Gateway, Zeitraum von einer Stunde und eingezeichneten früheren Messwerten",
"mode1Caption": "Gateway-Verlauf der letzten Stunde. Der Temperatur-/Latenz-Sammler schreibt die Messwerte alle 60 Sekunden in die Verlaufsdatenbank.",
"mode1Body1": "Standardmodus beim Öffnen. Eine zweite Auswahl bestimmt den Zeitraum (<em>1 Stunde / 6 Stunden / 24 Stunden / 3 Tage / 7 Tage</em>). Über dem Diagramm stehen Aktuell / Minimum / Mittelwert / Maximum und ein Status Ausgezeichnet / Gut / Mittelmäßig / Schlecht nach den folgenden Schwellen.",
"mode1Body2": "Quelle sind die Messwerte, mit denen Health Monitor anhaltende Netzwerkverzögerungen erkennt. Der Hintergrund-Thread <code>_temperature_collector_loop</code> misst das Gateway alle 60 Sekunden und speichert die Werte lokal in SQLite.",
"mode2Title": "Modus 2 — Echtzeitprüfung",
"mode2Alt": "Latenzdialog mit laufendem Echtzeit-Ping zu Cloudflare, 50 % Fortschritt und fortlaufenden Messwerten im Diagramm",
"mode2Caption": "Zweiminütiger Cloudflare-Test mit einer Messung alle fünf Sekunden, die sofort im Diagramm erscheint. <em>Stoppen</em> beendet vorzeitig; <em>Erneut testen</em> ergänzt denselben Datensatz.",
"mode2Intro": "Die Umstellung des Ziels auf Cloudflare oder Google startet einen On-Demand-Ping-Test. Verhalten:",
"mode2Items": [
"<strong>Dauer</strong> — zwei Minuten je Lauf mit Fortschrittsbalken und verbleibenden Sekunden.",
"<strong>Intervall</strong> — eine Messung alle fünf Sekunden, 24 je Lauf.",
"<strong>Methode</strong> — ICMP Echo Request (<code>ping</code>), drei aufeinanderfolgende Pings je Messwert mit gemittelter Latenz.",
"<strong>Stop</strong> — beendet den Test sofort; Teildaten bleiben erhalten.",
"<strong>Erneut testen</strong> — ergänzt die vorhandenen Daten um weitere Messwerte, sodass über mehrere Läufe ein längerer Verlauf entsteht.",
"<strong>Aktuelle Statusanzeige</strong> — wird nach jeder Messung anhand derselben Schwellen für Ausgezeichnet / Gut / Mittelmäßig / Schlecht neu bewertet."
],
"thresholdsTitle": "Leistungsschwellen",
"headerStatus": "Status",
"headerRange": "Bereich",
"headerImpact": "Praktische Auswirkungen",
"thresholdRows": [
{
"status": "Exzellent",
"range": "< 50 ms",
"impact": "Optimal für Echtzeit-Apps, Spiele und Videoanrufe."
},
{
"status": "Gut",
"range": "50 – 100 ms",
"impact": "Für die meisten Anwendungen akzeptabel, mit minimalen Auswirkungen."
},
{
"status": "Mittelmäßig",
"range": "100 – 200 ms",
"impact": "Spürbare Verzögerung. Kann VoIP und interaktive Anwendungen beeinträchtigen."
},
{
"status": "Schlecht",
"range": "> 200 ms",
"impact": "Erhebliche Latenz. Untersuchung empfohlen."
}
],
"reportTitle": "Netzwerklatenzbericht (PDF)",
"reportIntro": "Beide Modi haben neben der Zielauswahl eine Schaltfläche <strong>Bericht</strong>. Sie öffnet einen druckbaren Bericht der Messungen; speichern Sie ihn über den Druckdialog des Browsers als PDF und hängen Sie ihn an eine Störungsmeldung beim Internetanbieter an.",
"reportPreviewAlt": "Erste PDF-Seite des Latenzberichts mit Zusammenfassung, Messanzeige, Statistik, Diagramm und Schwellenwerten",
"reportPreviewCaption": "Die erste Seite enthält Zusammenfassung, Messanzeige, Hauptstatistik, Latenzverlauf und Schwellenwerte. Ab Seite 2 folgen die Messwerttabelle und die Methodik.",
"downloadLabel": "Beispiel-Latenzbericht herunterladen (PDF)",
"sectionsIntro": "Der Bericht umfasst sechs Abschnitte:",
"sections": [
"<strong>Zusammenfassung</strong> — Messanzeige von 0 bis über 300 ms mit grünen, gelben und roten Zonen; Status Ausgezeichnet / Gut / Mittelmäßig / Schlecht; Ziel, Modus, Messwertanzahl und Paketverlustübersicht.",
"<strong>Latenzstatistik</strong> — vier Anzeigen für aktuellen Wert, Minimum, Mittelwert und Maximum sowie Messwertanzahl, mittleren Paketverlust und Testzeitraum.",
"<strong>Latenzdiagramm</strong> — Flächendiagramm der Messwerte im Testzeitraum mit Minimum, Mittelwert und Maximum an der vertikalen Achse.",
"<strong>Leistungsschwellen</strong> — die oben beschriebene vierstufige Skala mit einem Farbpunkt je Stufe.",
"<strong>Detaillierte Ergebnisse</strong> — nummerierte Tabelle mit Zeitstempel, Latenz, Paketverlust und Status jeder Messung. Zeigt kurze Spitzen, die Mittelwerte verbergen können.",
"<strong>Methodik</strong> — ICMP Echo Request, drei aufeinanderfolgende Pings je Messwert, Zielname und IP sowie abschließende Bewertung anhand des Status."
],
"useCaseTitle": "Anwendungsfall: Support beim Internetanbieter",
"useCaseBody": "Führen Sie bei langsamer Verbindung den zweiminütigen Cloudflare-Test aus, verlängern Sie die Aufzeichnung mit <em>Erneut testen</em> und wählen Sie <em>Bericht</em>. Das PDF enthält alle Messwerte und die Methodik. Sie können es mit den Störungszeiten an eine Supportanfrage anhängen; der Anbieter bestimmt die erforderlichen Nachweise."
},
"excluding": {
"heading": "Schnittstellen von der Überwachung ausschließen",
"body1": "Schnittstellen lassen sich von der Überwachung ausschließen, etwa absichtlich deaktivierte Bridges, Testschnittstellen oder entfernte Netzwerkkarten mit verbliebener Konfiguration. Die Einstellung liegt in <code>excluded_interfaces</code>: Health Monitor erzeugt dafür weder Warnungen noch Benachrichtigungen und berücksichtigt sie nicht im Gesamtstatus.",
"body2": "Wählen Sie im Kontextmenü <em>Von Überwachung ausschließen</em>. Die Schnittstelle bleibt mit lila Kennzeichnung <strong>ausgeschlossen</strong> sichtbar. Im selben Menü lässt sich die Überwachung wieder aktivieren."
},
"dataCollected": {
"heading": "Wie die Daten gesammelt werden",
"headerSection": "Abschnitt des Reiters",
"headerEndpoint": "Endpunkt",
"headerSource": "Quelle",
"rows": [
{
"section": "Schnittstelleninventar",
"endpoint": "/api/network",
"source": "<code>ip -j addr</code> + <code>ip -j link</code> und Abfragen zu Bonds und Bridges."
},
{
"section": "Übersichtskarten",
"endpoint": "/api/network/summary",
"source": "Zusammenfassung des Inventars und Anzahl aktiver und inaktiver Schnittstellen."
},
{
"section": "RX/TX-Verlauf je Schnittstelle",
"endpoint": "/api/network/<iface>/metrics",
"source": "Aktuelle Zähler verwenden <code>/proc/net/dev</code>; der Diagrammverlauf stammt über pvesh aus Proxmox-RRD. VM/LXC-Schnittstellen nutzen Gastdaten, physische Schnittstellen und Bridges die Daten des Knotens."
},
{
"section": "Latenz: aktuell",
"endpoint": "/api/network/latency/current",
"source": "Kurze Folge von <code>ping</code>-Anfragen an das konfigurierte Gateway oder Ziel."
},
{
"section": "Latenz: historisch",
"endpoint": "/api/network/latency/history",
"source": "Messwerte werden etwa alle 60 Sekunden vom Hintergrundsammler für Temperatur und Latenz gespeichert."
}
],
"codeComment1": "# Den im Dashboard angezeigten Schnittstellenstatus prüfen",
"codeComment2": "# Eine aktuelle Latenzmessung über die gesamte Verbindung prüfen"
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "Gesundheitsmonitor",
"href": "/docs/monitor/health-monitor",
"tail": " — Netzwerkkategorie und Schwellenwerte des Latenzverlaufs."
},
{
"label": "API-Referenz",
"href": "/docs/monitor/api",
"tail": " — Netzwerk- und Latenz-Endpunkte."
},
{
"label": "Integrationen",
"href": "/docs/monitor/integrations",
"tail": " — die Prometheus-Abfrage liefert dieselben Netzwerkmetriken."
},
{
"label": "Dashboard-Index",
"href": "/docs/monitor/dashboard",
"tail": "Die anderen Tabs."
},
{
"label": "ProxMenux → Netzwerk",
"href": "/docs/network",
"tail": "— die Aktionsseite: Brückenanalyse, persistente Schnittstellennamen, Backup & Neustart, iperf3."
}
]
}
}
@@ -0,0 +1,246 @@
{
"meta": {
"title": "ProxMenux Monitor — Dashboard: Registerkarte Sicherheit | ProxMenux-Dokumentation",
"description": "Die Registerkarte Sicherheit bündelt die Schutzfunktionen in zwei Spalten: ProxMenux Monitor (Authentifizierung, SSL/HTTPS, API-Tokens, Secure Gateway) und Proxmox VE (Firewall, Fail2Ban, Lynis-Audit). Mit Anleitungen zum Secure-Gateway-Assistenten, zum Lynis-Audit sowie zur Installation und Regelkonfiguration von Fail2Ban."
},
"header": {
"title": "Dashboard: Sicherheits-Tab",
"description": "Die Sicherheitsfunktionen im Dashboard sind in zwei Bereiche gegliedert: Einstellungen für Monitor selbst (Authentifizierung, SSL, Tokens, Secure Gateway) und für den überwachten Proxmox-Host (Firewall, Fail2Ban, Lynis).",
"section": "ProxMenux Monitor · Übersicht"
},
"intro": {
"title": "Zwei Bereiche, ein Tab",
"body": "Die Registerkarte Sicherheit hat zwei Bereiche: <strong>ProxMenux Monitor</strong> (Dashboard-Einstellungen) und <strong>Proxmox VE</strong> (Host-Einstellungen). Die Karten für Fail2Ban und Lynis bieten bei fehlenden Werkzeugen deren Installation an und zeigen nach der Installation die Bedienelemente."
},
"monitor": {
"heading": "ProxMenux Monitor",
"intro": "Vier Karten steuern den Zugriff auf das Dashboard und die Authentifizierung."
},
"auth": {
"heading": "Authentifizierung",
"imageAlt": "Authentifizierungskarte mit Status Aktiviert, Abmelden, Passwort ändern, Informationen zur Zwei-Faktor-Authentifizierung und Schaltflächen zum Aktivieren von 2FA und Deaktivieren der Authentifizierung",
"imageCaption": "Karte bei aktivierter Authentifizierung: Statusanzeige, Passwort ändern, 2FA aktivieren und die destruktive Aktion Authentifizierung deaktivieren.",
"intro": "Die Karte verwaltet die Anmeldung am Dashboard. Ersteinrichtung, Passwortrichtlinie, TOTP-Einrichtung und Wiederherstellung bei verlorenem Authenticator sind unter <link>Zugriff und Authentifizierung</link> beschrieben. Diese Karte bietet die Einstellungen für den täglichen Gebrauch:",
"items": [
"<strong>Authentifizierungsstatus</strong> — Anzeige mit <em>Aktiviert</em> / <em>Deaktiviert</em> / <em>Abgelehnt</em>.",
"<strong>Passwort ändern</strong> — aktuelles Passwort + neues Passwort + Bestätigung.",
"<strong>Zwei-Faktor-Authentifizierung aktivieren / deaktivieren</strong> — öffnet beim Aktivieren den Einrichtungsdialog mit QR-Code und fragt beim Deaktivieren nach dem aktuellen Passwort.",
"<strong>Authentifizierung deaktivieren</strong> — destruktive Aktion, die beim nächsten Besuch erneut den Einrichtungsdialog <em>Dashboard schützen?</em> anzeigt."
]
},
"ssl": {
"heading": "SSL / HTTPS",
"imageAlt": "SSL/HTTPS-Karte mit Status HTTP ohne SSL, erkanntem Proxmox-Hostzertifikat samt Zertifikatsinhaber, Aussteller und Ablaufdatum sowie Optionen für das Proxmox-Zertifikat oder ein eigenes Zertifikat",
"imageCaption": "SSL/HTTPS-Karte bei deaktiviertem HTTPS. Monitor erkennt das Zertifikat auf dem Proxmox-Host und bietet dessen Verwendung mit einem Klick an. Für eigene Dateien an anderer Stelle gibt es <em>Eigenes Zertifikat verwenden</em>.",
"intro": "Stellt das Dashboard über HTTPS ohne vorgeschalteten Reverse-Proxy bereit. Die Karte erkennt das von Proxmox verwendete Zertifikat unter <code>/etc/pve/local/</code> und zeigt Zertifikatsinhaber, Aussteller und Ablaufdatum zur Prüfung vor der Aktivierung. HTTPS lässt sich auf zwei Wegen aktivieren:",
"items": [
"<strong>Proxmox-Zertifikat verwenden</strong> — Monitor übernimmt das Hostzertifikat mit einem Klick. Geeignet, wenn PVE und Dashboard denselben DNS-Namen verwenden.",
"<strong>Eigenes Zertifikat verwenden</strong> — absolute Pfade zum <code>.pem</code>-Zertifikat und privaten <code>.key</code>-Schlüssel einfügen. Sie werden vor dem Dienstneustart geprüft. Scheitert das Laden, wechselt das Dashboard automatisch zurück zu HTTP und bleibt erreichbar."
],
"enabledAlt": "SSL/HTTPS-Karte mit aktiviertem HTTPS, aktivem Zertifikat samt Pfaden zu pve-ssl.pem und pve-ssl.key sowie Schaltfläche HTTPS deaktivieren",
"enabledCaption": "HTTPS aktiv — die Karte zeigt das verwendete Zertifikat, die Dateipfade und die Aktion <em>HTTPS deaktivieren</em>, die auf HTTP am selben Port zurückschaltet.",
"acmeTitle": "ACME / Let's Encrypt über Proxmox",
"acmeBody": "Wenn Let’s Encrypt auf Ihrem Proxmox-Knoten unter <em>Datacenter → Certificates → ACME</em> eingerichtet ist, verwendet das Dashboard mit <em>Proxmox-Zertifikat verwenden</em> dasselbe Zertifikat, das der Host den Browsern bereitstellt. Eine eigene ACME-Einrichtung für Monitor ist nicht nötig.",
"walkthroughLink": "Die Anleitung <link>HTTPS für ProxMenux Monitor</link> beschreibt die automatische Erkennung des ACME-Zertifikats, die auf dem Datenträger gespeicherten Daten und die Verwendung eines eigenen <code>.pem</code> / <code>.key</code>-Paars."
},
"apiTokens": {
"heading": "API-Zugriffstokens",
"emptyAlt": "Leere Karte für API-Zugriffstokens mit Informationen zu API-Tokens und Schaltfläche Neues API-Token erzeugen",
"emptyCaption": "API-Token-Karte nach einer Neuinstallation. Das Feld <em>Informationen zu API-Tokens</em> erklärt Gültigkeitsdauer, Verwendung und Einbindung in <code>Authorization: Bearer</code>-Header.",
"intro": "Tokens mit einem Jahr Gültigkeit für automatisierte Integrationen: Homepage-Widgets, REST-Sensoren für Home Assistant, Grafana-Datensammler, n8n-Abläufe und eigene Skripte. Die Karte führt durch drei Zustände: leer → Formular → erzeugt.",
"generateBody": "<strong>Token erzeugen.</strong> Klicken Sie auf <em>Neues API-Token erzeugen</em>. Geben Sie einen aussagekräftigen <em>Tokennamen</em> zur späteren Identifizierung und Ihr <em>Passwort</em> zur zusätzlichen Bestätigung ein. Bei aktiviertem 2FA wird auch der aktuelle TOTP-Code verlangt.",
"generateAlt": "Formular zum Erzeugen eines API-Tokens mit Feldern für Tokenname und Passwort sowie Schaltflächen Token erzeugen und Abbrechen",
"generateCaption": "Formular zum Erzeugen eines API-Tokens: Namen eingeben und mit Passwort sowie bei aktivem 2FA mit TOTP-Code bestätigen.",
"saveBody": "<strong>Speichern Sie das Token sofort.</strong> Der vollständige Tokenwert wird nach dem Erzeugen <strong>nur einmal</strong> angezeigt. Die Karte weist mit einem orangefarbenen Hinweis und einer Kopierschaltfläche darauf hin. Später lässt sich der Wert nicht abrufen; die Liste aktiver Tokens zeigt nur das Präfix.",
"generatedAlt": "Erzeugtes API-Token mit maskiertem Wert, Kopierschaltfläche, Anleitung für den Header Authorization: Bearer und Liste aktiver Tokens samt Präfix",
"generatedCaption": "Token erzeugt: Der Wert erscheint einmal mit Kopierschaltfläche und dem genauen Muster <code>Authorization: Bearer</code>. Darunter zeigt die Liste aktiver Tokens Name, Präfix und Erstellungsdatum, damit Sie einzelne Tokens widerrufen können.",
"outro": "Jedes aktive Token hat eine Schaltfläche <em>Widerrufen</em>. Ein Widerruf macht das Token sofort ungültig; Integrationen mit diesem Token funktionieren dann nicht mehr. Anleitungen für Homepage, Home Assistant, n8n und Prometheus finden Sie unter <link>Integrationen</link>."
},
"gateway": {
"heading": "Secure Gateway",
"cardAlt": "Secure-Gateway-Karte vor der ersten Bereitstellung mit der Schaltfläche Secure Gateway bereitstellen",
"cardCaption": "Secure-Gateway-Karte nach der Ersteinrichtung: Ein Klick startet den Assistenten.",
"intro": "Greifen Sie von überall in Ihrem <a>Tailscale</a>-Tailnet auf Dashboard, Proxmox-Weboberfläche und Gäste zu, ohne Ports im Internet freizugeben. Monitor stellt auf dem Host einen Alpine-LXC-Container mit <code>tailscaled</code> als Subnetz-Router bereit. Nach der Freigabe in der Tailscale-Administrationskonsole erreichen entfernte Geräte die LAN-IP des Hosts.",
"wizardTitle": "Schritt-für-Schritt-Assistent",
"wizardIntro": "Erzeugen Sie vor dem Klick auf <em>Deploy Secure Gateway</em> einen Authentifizierungsschlüssel in der Tailscale-Konsole. Der Assistent fragt ihn in Schritt 2 ab.",
"step0Title": "0. Tailscale-Authentifizierungsschlüssel erzeugen",
"step0Body": "Melden Sie sich bei <a>login.tailscale.com/admin/settings/keys</a> an und klicken Sie auf <em>Generate auth key…</em>. Wählen Sie einen <em>vorab authentifizierten</em> Schlüssel, damit keine interaktive Tailscale-Anmeldung nötig ist. Kopieren Sie den Wert; er wird nur einmal angezeigt.",
"step0Alt": "Seite Settings → Keys der Tailscale-Administrationskonsole mit hervorgehobener Schaltfläche Generate auth key",
"step0Caption": "Tailscale-Admin-Konsole — <em>Settings → Keys → Auth Key generieren...</em>. Verwenden Sie ein kostenloses Tailscale-Konto, wenn Sie noch keins haben (Link innerhalb des Assistenten).",
"step1Title": "1. Assistenten öffnen",
"step1Body": "Klicken Sie auf der Registerkarte Sicherheit auf <em>Deploy Secure Gateway</em>. Der erste Schritt erläutert Funktionen und Voraussetzungen.",
"step1Alt": "Einführung des Secure-Gateway-Assistenten: VPN-Zugriff ohne Portweiterleitung und mit Ende-zu-Ende-Verschlüsselung",
"step1Caption": "Schritt 1 - Überblick über das, was das Secure Gateway bietet und eine Erinnerung daran, dass Sie ein kostenloses Tailscale-Konto benötigen.",
"step2Title": "2. Tailscale-Authentifizierung",
"step2Body": "Fügen Sie den Authentifizierungsschlüssel aus Schritt 0 ein und wählen Sie einen Hostnamen. Unter diesem Namen erscheint das Gateway in der Tailscale-Konsole, üblicherweise <code>proxmox-gateway</code> oder der Knotenname.",
"step2Alt": "Schritt des Secure-Gateway-Assistenten mit Feldern für Tailscale-Authentifizierungsschlüssel und Gerätehostname sowie Link zum Erzeugen des Schlüssels",
"step2Caption": "Schritt 2: Vorab authentifizierten Schlüssel einfügen und Gerätehostnamen wählen. Falls Sie Schritt 0 übersprungen haben, öffnet der Link unter dem Feld die entsprechende Tailscale-Seite.",
"step3Title": "3. Zugangsbereich",
"step3Intro": "Wählen Sie, was Ihr Tailnet durch das Gateway erreichen kann:",
"step3Items": [
"<strong>Proxmox Only</strong> — nur die Proxmox-Benutzeroberfläche und der Monitor. kleinste Angriffsfläche.",
"<strong>Full Local Network</strong> — das gesamte LAN-Subnetz (automatisch von der primären Schnittstelle des Hosts erkannt). Sie erreichen NAS, Drucker, VMs und jedes andere LAN-Gerät.",
"<strong>Eigene Subnetze</strong> — bestimmte CIDR-Netze angeben. Für Umgebungen mit mehreren VLANs, in denen nur ausgewählte Segmente erreichbar sein sollen."
],
"step3Alt": "Schritt Zugriffsbereich des Secure-Gateway-Assistenten mit den Optionen Nur Proxmox, Gesamtes lokales Netzwerk und Eigene Subnetze",
"step3Caption": "Schritt 3: Zugriffsbereich wählen. <em>Gesamtes lokales Netzwerk</em> übernimmt automatisch das erkannte LAN-Subnetz.",
"step4Title": "4. Erweiterte Optionen (optional)",
"step4Intro": "Zwei optionale Schalter, beide <strong>standardmäßig deaktiviert</strong>:",
"step4Items": [
"<strong>Exit Node</strong> — nach Aktivierung und Auswahl auf einem entfernten Gerät wird dessen gesamter Internetverkehr über den WAN-Anschluss des Proxmox-Hosts geleitet. Auf Reisen erscheint der Datenverkehr des Telefons so mit der heimischen Internetverbindung.",
"<strong>Routen akzeptieren</strong> — dieses Gateway erreicht Netze, die von <em>anderen</em> Subnetz-Routern im Tailnet angekündigt werden, etwa bei mehreren Standorten."
],
"step4Alt": "Schritt Erweiterte Optionen im Secure-Gateway-Assistenten mit den Kontrollkästchen Exit Node und Accept Routes",
"step4Caption": "Schritt 4: Exit Node und Accept Routes. Lassen Sie beide deaktiviert, wenn Sie nur vom Telefon oder Laptop auf das Dashboard zugreifen möchten.",
"step5Title": "5. Prüfen und bereitstellen",
"step5Body": "Letzte Zusammenfassung vor der Bereitstellung. Der Assistent erinnert an einen anschließenden manuellen Schritt in der Tailscale-Konsole: <strong>die Subnetzroute genehmigen</strong>.",
"step5Alt": "Schritt Prüfen und bereitstellen im Secure-Gateway-Assistenten mit Zusammenfassung von Hostname, Zugriffsmodus, Netzen, Exit Node und Accept Routes sowie Schaltfläche Gateway bereitstellen",
"step5Caption": "Schritt 5 — Überprüfen Sie die Konfiguration und Bereitstellung. Der blaue Hinweis unten markiert die ausstehende Routengenehmigung.",
"approvalTitle": "Ein letzter manueller Schritt im Tailscale-Admin",
"approvalBody": "Öffnen Sie nach der Bereitstellung <a>login.tailscale.com/admin/machines</a> und genehmigen Sie die vom Gateway angekündigte Subnetzroute. Erst dann können entfernte Geräte im Tailnet über das Gateway auf LAN-IPs zugreifen. Tailscale markiert ausstehende Routen mit einer gelben Warnung in der Gerätezeile. Klicken Sie auf <em>Edit route settings</em> und aktivieren Sie die Route."
},
"pve": {
"heading": "Proxmox VE",
"intro": "Die Schutzfunktionen des Hosts: Firewall, Angriffserkennung und Sicherheitsprüfung. Die Karten für Fail2Ban und Lynis bieten bei Bedarf die Installation an und zeigen danach die Verwaltungsfunktionen."
},
"firewall": {
"heading": "Proxmox Firewall",
"imageAlt": "Proxmox-Firewall-Karte mit Cluster- und Hoststatus, Schnellzugriffsregeln für Monitor und die Proxmox-Weboberfläche, Zählern, Regelliste und Schaltfläche Regel hinzufügen",
"imageCaption": "Proxmox-Firewall-Karte: Schalter für Cluster und Host, häufige Ports unter <em>Schnellzugriffsregeln</em>, Zähler unter <em>Regelübersicht</em> und vollständige Liste mit <em>+ Regel hinzufügen</em>.",
"intro": "Die Karte verwaltet die Firewall-Konfiguration von Proxmox VE. Das klassische Backend verwendet <code>iptables</code>, das alternative <code>nftables</code>. Beliebige außerhalb von Proxmox erstellte Regeln werden nicht verwaltet. Drei Bereiche:",
"items": [
"<strong>Cluster-Firewall + Host-Firewall</strong> — globale Schalter. Die Cluster-Firewall muss aktiv sein, damit die Hostregeln greifen. Die Karte zeigt diese Abhängigkeit direkt an der Einstellung.",
"<strong>Schnellzugriffsregeln</strong> — vorbereitete Zeilen für <code>8008/TCP</code> (Monitor) und <code>8006/TCP</code> (Proxmox-Weboberfläche) mit Status erlaubt, gesperrt oder ungeschützt. Die Proxmox-Oberfläche wird über ein <em>integriertes</em> Firewall-Makro erlaubt, das sich nicht versehentlich löschen lässt.",
"<strong>Regelübersicht</strong> — Zähler für alle Regeln, accept-Regeln, drop/reject-Regeln und verschiedene geschützte Ports. Die Werte stammen aus <code>/etc/pve/firewall/cluster.fw</code> und <code>/etc/pve/nodes/&lt;node&gt;/host.fw</code>.",
"<strong>Firewall-Regeln</strong> — Liste mit Aktion, Protokoll, Port, Quelle und Ebene. <em>+ Regel hinzufügen</em> öffnet den Editor in der Karte, das Papierkorbsymbol löscht die jeweilige Regel. Änderungen werden in den Proxmox-Dateien gespeichert und erscheinen auch in dessen Oberfläche (Datacenter / Node → Firewall)."
]
},
"fail2ban": {
"heading": "Fail2Ban",
"subHeading": "(abhängig vom Status)",
"whatIs": "<strong>Was ist das?</strong> Fail2Ban ist ein quelloffener Dienst, der wiederholte fehlgeschlagene Anmeldungen in Protokollen erkennt und die IP-Adresse per Firewall sperrt. Er schützt SSH und Webanmeldungen vor fortlaufenden Brute-Force-Angriffen. ProxMenux richtet drei Jails ein: SSH, Proxmox-Webanmeldung (Port 8006) und ProxMenux-Monitor-Anmeldung (Port 8008).",
"notBundled": "Fail2Ban ist <strong>nicht im Lieferumfang enthalten</strong>. Die Karte passt sich daran an, ob es installiert ist: Fehlt es, lässt es sich mit einem Klick installieren. Danach zeigt sie den aktuellen Jail-Status und gesperrte IP-Adressen und ermöglicht es, die Anzahl der Versuche sowie die Sperrdauer pro Jail anzupassen.",
"notInstalledAlt": "Fail2Ban-Karte im Zustand Nicht installiert mit Beschreibung des Schutzes für SSH, Proxmox-Weboberfläche und Monitor über nftables sowie Schaltfläche Fail2Ban installieren und konfigurieren",
"notInstalledCaption": "Fail2Ban-Karte vor der Installation - die blaue Box zeigt an, was die Installation konfigurieren würde.",
"clickBody": "Klicken Sie auf <em>Fail2Ban installieren und konfigurieren</em>. Ein Bestätigungsdialog listet alle Änderungen auf, die das Skript am Host vornehmen wird:",
"confirmAlt": "Fail2Ban-Bestätigung mit aggressivem SSH-Modus, Schutz für Proxmox auf Port 8006 und Monitor auf Port 8008, nftables-Erkennung, journald-Protokollanpassung und SSH-Härtung über MaxAuthTries",
"confirmCaption": "Installationsbestätigung: Jail-Liste, angepasste journald-Protokollstufe zum Lesen von SSH-Ereignissen und zusätzliche SSH-Härtung (<code>MaxAuthTries=3</code>).",
"confirmIntro": "Nach der Bestätigung zeigt ein Panel die Installation live an: apt, Jail-Konfiguration und Prüfungen. Es verwendet denselben Mechanismus wie der ProxMenux-CLI-Installer.",
"progressAlt": "Panel mit Fail2Ban-Installationsprotokoll: Paket, journald MaxLevelStore für Anmeldungen, Jails, nftables-Erkennung, MaxAuthTries-Härtung, Kommunikationstest mit fail2ban-client und Abschlussmeldung",
"progressCaption": "Installation läuft: Jeder Schritt wird im Panel protokolliert. Connection closed am Ende kennzeichnet das Ende der Übertragung.",
"afterInstall": "Nach der Installation zeigt die Karte den aktuellen Status: konfigurierte Jails, gesperrte IPs und jüngste Sperrereignisse. Die Registerkarten trennen <em>Jails und gesperrte IPs</em> von <em>Letzte Aktivitäten</em> mit den letzten N Fail2Ban-Protokolleinträgen.",
"activeAlt": "Aktive Fail2Ban-Karte mit drei Jails (proxmenux, proxmox, sshd), Zählern für gesperrte IPs, alle Sperren und fehlgeschlagene Versuche sowie Zeilen mit Versuchen, Sperrdauer, Zeitraum und Zahnradsymbol",
"activeCaption": "Fail2Ban aktiv: die drei Standard-Jails (<code>proxmenux</code>, <code>proxmox</code>, <code>sshd</code>) mit Einstellungen für Versuche, Sperrdauer und Erkennungszeitraum.",
"tuneBody": "<strong>Jail-Regeln anpassen.</strong> Über das Zahnradsymbol ändern Sie <em>Max Retries</em>, <em>Ban Time</em> und <em>Find Time</em>, den gleitenden Zeitraum zum Zählen der Versuche. Eine dauerhafte Sperre bleibt bis zur manuellen Aufhebung bestehen. Das Formular erklärt übliche Werte.",
"configAlt": "Konfigurationsformular für das Jail sshd mit Max Retries, Ban Time in Sekunden, Permanent Ban, Find Time, Hinweisen zu üblichen Werten und Schaltfläche Konfiguration speichern",
"configCaption": "Jail sshd bearbeiten: Wählen Sie einen niedrigeren Wert für <em>Max Retries</em>, wenn SSH nur aus Ihrem Subnetz genutzt wird, oder verlängern Sie <em>Ban Time</em> für ein öffentlich erreichbares Dashboard.",
"outro": "Die Anleitung <em>Installation, Konfiguration und Deinstallation</em> behandelt auch die manuelle Installation, die Änderung von SSH MaxAuthTries und das Protokoll <code>proxmenux-auth.log</code>. Sie finden sie unter <link>ProxMenux → Sicherheit → Fail2Ban</link>.",
"calloutTitle": "Ohne Fail2Ban sperrt dieser Mechanismus keine IPs",
"calloutBody": "ProxMenux Monitor prüft die im Fail2Ban-Jail <code>proxmenux</code> gesperrten IPs auf <em>Anwendungsebene</em>, bevor Flask-Anfragen verarbeitet werden, und speichert das Ergebnis 30 Sekunden zwischen. Ohne Fail2Ban werden fehlgeschlagene Anmeldungen in <code>proxmenux-auth.log</code> protokolliert und der Login-Endpunkt ist auf 5 Versuche pro IP alle 5 Minuten begrenzt, es wird aber keine IP gesperrt."
},
"lynis": {
"heading": "Lynis-Sicherheitsprüfung",
"subHeading": "(abhängig vom Status)",
"whatIs": "<strong>Was ist das?</strong> Lynis ist ein quelloffenes Sicherheitsprüfwerkzeug mit rund 280 Hostprüfungen, etwa zu Dateirechten, Kernel-Härtung, SSH, Paketschwachstellen, Kryptografie, geplanten Aufgaben und Dienstkennungen. Es liefert einen Härtungsindex von 0 bis 100, Warnungen und Vorschläge. Es dient als verbreitete Ausgangsbasis zur Bewertung von Debian-Servern.",
"whyUseful": "<strong>Warum ist es nützlich?</strong> Die Sicherheit anhand einzelner Konfigurationsdateien zu bewerten ist schwierig. Lynis erkennt häufig übersehene Punkte: fehlende Kernel-Schutzoptionen, schwache SSH-Verfahren, nicht dauerhafte Protokolle oder <code>NOPASSWD</code> in sudoers für Standardkonten. Ein erneuter Lauf nach ProxMenux-Anpassungen macht die Veränderung als Punktwert vergleichbar.",
"notInstalledAlt": "Lynis-Karte im Zustand Nicht installiert mit Schaltfläche Lynis installieren und Funktionen: Härtungsindex, Schwachstellenerkennung, Konformitätsprüfung und GitHub-Quellcode",
"notInstalledCaption": "Lynis-Karte vor der Installation - die blaue Box fasst zusammen, was das Tool tut.",
"notBundled": "Lynis ist ebenfalls <strong>nicht enthalten</strong>. ProxMenux installiert es direkt aus dem offiziellen GitHub-Quellcode statt aus dem Debian-Paket.",
"confirmAlt": "Bestätigungsdialog für Lynis mit seinen Funktionen: Härtungsindex, Schwachstellenerkennung, Konfigurationsanalyse, Konformitätsprüfung und Bezug aus dem offiziellen GitHub-Repository",
"confirmCaption": "Installationsbestätigung mit ausdrücklichem Hinweis auf die GitHub-Quelle.",
"progressAlt": "Live-Installationspanel für Lynis mit Installation der aktuellen Version, Bestätigung von Version 3.1.6 und Abschlussmeldung",
"progressCaption": "Installation läuft: Das Panel zeigt den Verlauf wie bei Fail2Ban live an.",
"afterInstall": "Nach der Installation zeigt die Karte die Version und einen leeren Prüfverlauf. Klicken Sie auf <em>Sicherheitsprüfung starten</em>, um den ersten Scan auszuführen.",
"installedAlt": "Lynis-Karte nach der Installation mit Versionsanzeige 3.1.6, Zeitpunkt der letzten Prüfung, Härtungsindex 0, Warnungen 0, Vorschläge 0, leerem Bericht und Schaltfläche Sicherheitsprüfung starten",
"installedCaption": "Lynis ist installiert, es gibt noch keine Prüfung. Die Kennzahlen zeigen zunächst null.",
"runningAlt": "Lynis-Karte während der Prüfung mit Fortschrittsmeldung, geschätzter Dauer von 2 bis 5 Minuten und deaktivierter Schaltfläche Prüfung läuft",
"runningCaption": "Prüfung läuft: Die Schaltfläche zeigt eine Ladeanimation und die Karte weist auf eine Dauer von 2 bis 5 Minuten hin.",
"finishedBody": "Nach Abschluss zeigt die Karte die Ergebnisse: Härtungsindex, Warnungen, Vorschläge und die Liste <em>Prüfberichte</em> mit früheren Scans.",
"resultsAlt": "Lynis-Karte mit Index 71, Aufschlüsselung Lynis 66 und PVE 71, 3 Warnungen, 40 Vorschlägen, für Proxmox angepasstem Wert 71 von 100 im Bereich Gut, Berichten mit PDF-Download und Schaltfläche Sicherheitsprüfung starten",
"resultsCaption": "Beispielergebnis: Härtungsindex <strong>71/100 (Gut)</strong>. Die Karte zeigt den Lynis-Rohwert (66) und den für Proxmox angepassten Wert (71). Die Anpassung hängt vom Rohwert und vom Anteil der als erwartetes Proxmox-VE-Verhalten eingestuften Befunde ab; es werden keine festen 11 Punkte addiert.",
"scoreTitle": "Lynis-Rohwert und an Proxmox angepasster Wert",
"scoreIntro": "Lynis-Regeln sind auf allgemeine Debian-Systeme ausgelegt. Proxmox weicht aus berechtigten Gründen teilweise davon ab, etwa durch Cluster-Dienste als root oder eigene <code>journald</code>-Einstellungen. Die Karte zeigt beide Werte, damit Sie:",
"scoreItems": [
"Ihren <em>Lynis-Rohwert</em> wie externe Prüfer verfolgen.",
"Den <em>für Proxmox angepassten</em> Wert verfolgen, eine passendere Vergleichsbasis für Knoten desselben Clusters."
],
"reportBody": "<strong>Vollständiger Bericht.</strong> Die Schaltfläche <em>PDF</em> jeder Prüfung lädt einen mehrseitigen Bericht herunter: Zusammenfassung, Systeminformationen, Sicherheitslage, erläuterte Warnungen, nach Auswirkung geordnete Vorschläge und Paketinventar. Er eignet sich als Anhang für eine Sicherheitsprüfung.",
"reportAlt": "Beispiel der ersten PDF-Berichtsseite mit Zusammenfassung, Index 71 von 100, Anzahl der Warnungen und Vorschläge, Hostname, Kernel, Lynis-Version, Datum und Übersicht der Sicherheitslage",
"reportCaption": "Erste Seite des Berichts mit Zusammenfassung, Systeminformationen und Sicherheitslage. Es folgen ausführliche Warnungen, Vorschläge und die Liste installierter Pakete. Ein <a>Beispiel-PDF</a> ist als Referenz beigefügt.",
"runPeriodically": "Führen Sie das Audit regelmäßig durch (nach größeren Proxmox-Upgrades, nach der Anwendung von Nachinstallationsoptimierungen, bevor Sie einen Fernzugriffspfad öffnen) und bewahren Sie die Berichte auf - der Trend ist wichtiger als jede einzelne Zahl.",
"outro": "Die Anleitung zu <em>Installation, Konfiguration und Deinstallation</em> sowie die Erläuterung eines Beispielberichts finden Sie unter <link>ProxMenux → Sicherheit → Lynis</link>."
},
"dataCollected": {
"heading": "Wie die Daten gesammelt werden",
"headerCard": "Karte",
"headerEndpoint": "Endpunkt",
"headerSource": "Quelle",
"rows": [
{
"card": "Authentifizierung, 2FA, Passwortänderung",
"endpoint": "/api/auth/*",
"source": "Lokale Authentifizierungskonfiguration in ~/.config/proxmenux-monitor/auth.json; JWTs werden von Monitor ausgestellt."
},
{
"card": "SSL / HTTPS",
"endpoint": "/api/auth/ssl/*",
"source": "<code>openssl x509</code> auf <code>/etc/pve/local/pve-ssl.pem</code> + <code>/etc/proxmenux/ssl_config.json</code>."
},
{
"card": "API-Tokens auflisten, erzeugen und widerrufen",
"endpoint": "/api/auth/api-tokens",
"source": "Token-Zeilen lokal gehalten; nichts verlässt den Host."
},
{
"card": "Secure Gateway (Bereitstellung + Status)",
"endpoint": "/api/oci/*",
"source": "Erstellt einen Alpine-LXC-Container mit <code>tailscaled</code> über <code>pct create</code> / <code>pct exec</code>."
},
{
"card": "Firewall Status & Regeln",
"endpoint": "/api/security/firewall/*",
"source": "<code>pve-firewall</code> + <code>/etc/pve/firewall/&lt;cluster|host&gt;.fw</code>."
},
{
"card": "Fail2Ban (nur wenn installiert)",
"endpoint": "/api/security/fail2ban/*",
"source": "<code>fail2ban-client status</code>, <code>/var/log/fail2ban.log</code>, <code>/etc/fail2ban/jail.local</code>."
},
{
"card": "Lynis Audit (nur wenn installiert)",
"endpoint": "/api/security/lynis/*",
"source": "Führt <code>lynis audit system</code> im Hintergrund aus und liest den Bericht aus <code>/var/log/lynis-report.dat</code>."
}
]
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "Zugriff und Authentifizierung",
"href": "/docs/monitor/access-auth",
"tail": " — vollständige Ersteinrichtung, Auswahl einer 2FA-App, Wiederherstellung bei verlorenem Authenticator und Reverse-Proxy-Beispiele."
},
{
"label": "Integrationen",
"href": "/docs/monitor/integrations",
"tail": " — Anleitungen für API-Tokens mit Homepage, Home Assistant, Prometheus und n8n sowie die vollständige Secure-Gateway-Einrichtung."
},
{
"label": "API-Referenz",
"href": "/docs/monitor/api",
"tailRich": " — alle Endpunkte unter <code>/api/auth</code>, <code>/api/security</code> und <code>/api/oci</code> mit Methode, Anfrageinhalt und curl-Beispielen."
},
{
"label": "ProxMenux → Sicherheit → Fail2Ban",
"href": "/docs/security/fail2ban",
"tail": " — Installationsanleitung, eingerichtete Jails und manuelle Installation."
},
{
"label": "ProxMenux → Sicherheit → Lynis",
"href": "/docs/security/lynis",
"tail": " — Beispielbericht, Einordnung des Ergebnisses und Zeitpunkt für eine erneute Prüfung."
}
]
}
}
@@ -0,0 +1,367 @@
{
"meta": {
"title": "ProxMenux Monitor — Dashboard: Registerkarte Einstellungen | ProxMenux-Dokumentation",
"description": "Die Registerkarte Einstellungen verwaltet Sprache, Navigationsreihenfolge, Dashboard-Präferenzen, Überwachungsschwellen und Ausschlüsse, Benachrichtigungen, KI und das Inventar der Nachinstallationsoptimierungen."
},
"header": {
"title": "Dashboard: Tab Einstellungen",
"description": "Monitor-Sprache, Navigationsreihenfolge, Dashboard-Präferenzen, Überwachungsausschlüsse, Benachrichtigungen, KI-Konfiguration und aktuelles ProxMenux-Optimierungsinventar.",
"section": "ProxMenux Monitor · Übersicht"
},
"intro": {
"title": "Wo jede Einstellung gespeichert wird",
"body": "Einstellungen bündelt Dashboard-Darstellung, Health-Monitor-Überwachung, Alarmversand und bereits von ProxMenux vorgenommene Hoständerungen. Karten mit ausführlicher Dokumentation verlinken darauf; hier finden Sie den Einstieg."
},
"interfaceLanguage": {
"heading": "Schnittstellensprache",
"intro": "Wählen Sie die Sprache der <strong>Weboberfläche des Monitors</strong>. Die Änderung gilt sofort, ohne Dienstneustart und ohne die Sprache der ProxMenux-Shellmenüs zu ändern.",
"items": [
"ProxMenux Monitor bietet derzeit Englisch, Deutsch, Spanisch, Französisch, Italienisch, Portugiesisch, Slowakisch und Schwedisch an.",
"Beim ersten Besuch wird die Browsersprache verwendet, sofern unterstützt; andernfalls Englisch.",
"Die Auswahl ändert die Seitensprache und synchronisiert weitere offene Registerkarten desselben Browserprofils.",
"Fehlt eine Übersetzung, erscheint nur dieser Text auf Englisch statt als fehlerhafter Schlüssel oder Platzhalter."
],
"scopeTitle": "Lokale Browsereinstellung",
"scopeBody": "Die Auswahl liegt in <code>localStorage</code> unter <code>proxmenux-ui-language</code>. Sie gilt für das aktuelle Browserprofil und Gerät, nicht für den ganzen Knoten. Jeder Benutzer kann seine Sprache wählen."
},
"navigationOrder": {
"heading": "Navigationsreihenfolge",
"intro": "Ordnen Sie die sieben Haupteinträge: <strong>Übersicht, Apps, VMs & LXCs, Knoten, Sicherung, Terminal und Verwaltung</strong>. Klicken Sie auf <strong>Bearbeiten</strong>, ziehen Sie die Zeilen und speichern Sie.",
"items": [
"Mit der Maus beginnt das Ziehen beim Drücken. Auf Touchscreens ist ein 250-ms-Langdruck nötig, um es vom Scrollen zu unterscheiden.",
"Die Gruppen <strong>Knoten</strong> und <strong>Verwaltung</strong> werden als Ganzes verschoben; ihre Unterseiten behalten die festgelegte Reihenfolge.",
"Das Mobilmenü verwendet dieselbe gespeicherte Reihenfolge.",
"<strong>Standard wiederherstellen</strong> setzt den bearbeiteten Reihenfolgeentwurf zurück. Speichern übernimmt die Änderung.",
"Neue Hauptregisterkarten künftiger Versionen werden an die eigene Reihenfolge angehängt; Ihre Anordnung bleibt erhalten."
],
"landingTitle": "Der erste Eintrag ist die Startansicht",
"landingBody": "Monitor öffnet den ersten gespeicherten Eintrag. Bei <strong>Knoten</strong> ist das Speicher, bei <strong>Verwaltung</strong> Systemprotokolle. Die Reihenfolge liegt in diesem Browser unter <code>proxmenux-nav-order</code>; jedes Gerät kann eine eigene Anordnung verwenden."
},
"networkUnits": {
"heading": "Netzwerkeinheiten",
"imageAlt": "Karte Netzwerkeinheiten mit der Anzeigeauswahl Bytes",
"imageCaption": "Wählen Sie zwischen Bits pro Sekunde und Bytes pro Sekunde für jede im Dashboard angezeigte Netzwerkrate.",
"body": "Zeigt den Netzwerkdurchsatz in <strong>Bits pro Sekunde</strong> (Mbps/Gbps) oder <strong>Bytes pro Sekunde</strong> (MB/s/GB/s). Standard sind Bits wie bei Netzwerkkarten und Internetanbietern; Dateiübertragungen verwenden oft Bytes. Diagramme, Labels und Hinweise ändern sich sofort ohne Neuladen."
},
"health": {
"heading": "Gesundheitsmonitor",
"intro": "Die Karte legt die <strong>Unterdrückungsdauer</strong> fest: wie lange die Prüfung wartet, bevor eine verworfene Warnung erneut erscheinen darf. CPU, Speicher, Datenspeicher, Laufwerke, Netzwerk, VMs, PVE-Dienste, Protokolle, Updates und Sicherheit haben jeweils eine Auswahl:",
"items": [
"<strong>24 h</strong> — Standard für die meisten transienten Kategorien.",
"<strong>72 h</strong> — für Ereignisse, die Sie einige Tage stummschalten möchten.",
"<strong>168 h</strong> (1 Woche) und <strong>720 h</strong> (1 Monat) — regelmäßige Kontrollen.",
"<strong>8760 h</strong> (1 Jahr) — Unterdrückung für einen langen Zeitraum.",
"<strong>-1</strong> — permanente Stille, bis Sie es manuell wieder aktivieren.",
"<strong>Eigene Stundenanzahl</strong> — eine ganze Zahl für einen Zwischenwert."
],
"imageAlt": "Einstellungen, Health-Monitor-Karte mit Dauer je Kategorie und aktiven Unterdrückungen",
"imageCaption": "Die Auswahllisten bestimmen die Dauer künftiger Unterdrückungen. Der Bereich darunter zeigt stummgeschaltete Warnungen und ermöglicht ihre Reaktivierung.",
"editTitle": "Bearbeitungsmodus",
"editBody": "Die Karte ist zunächst schreibgeschützt. <strong>Bearbeiten</strong> oben rechts aktiviert Auswahllisten und Reaktivierungsschaltflächen. <strong>Speichern</strong> übernimmt geänderte Dauern und vorgemerkte Reaktivierungen gemeinsam; <strong>Abbrechen</strong> verwirft sie. Speichern wird erst bei Änderungen aktiv.",
"activeTitle": "Aktive Unterdrückungen",
"activeIntro": "Unter den Dauerangaben listet <strong>Aktive Unterdrückungen</strong> zeitlich begrenzte —24 Stunden, 7 Tage oder eigener Zeitraum— und <em>dauerhafte</em> Unterdrückungen auf. Jede Zeile zeigt:",
"activeItems": [
"Ein farbiges Abzeichen: <strong>Dauerhaft</strong> in Orange oder eine Restzeit wie <strong>noch 24 h</strong> / <strong>noch 7 Tage</strong> in Blau.",
"Die Warnungskennung in lesbarer Form (z. B. <code>pve_storage_full_PBS-Cloud</code> → <em>PVE-Speicher voll: PBS-Cloud</em>).",
"Kategorie, Schweregrad und Zeitpunkt, zu dem die Warnung verworfen wurde.",
"Eine Schaltfläche <strong>Reaktivieren</strong> im Bearbeitungsmodus merkt die Aufhebung der Unterdrückung beim Speichern vor."
],
"activeReenableTitle": "Warnung reaktivieren",
"activeReenableBody": "<strong>Reaktivieren</strong> markiert die Zeile beim Bearbeiten grün und streicht die Kennung durch; noch ist nichts übernommen. Erneuter Klick bedeutet <strong>Rückgängig</strong>. <strong>Speichern</strong> sendet je Reaktivierung parallel <code>POST /api/health/un-acknowledge</code> und entfernt die Zeilen. Besteht das Problem weiter und unterstützt die Kategorie erneute Meldungen, erscheint es beim nächsten Scan wieder unter Aktiv.",
"activePermanentNote": "Dauerhafte Unterdrückungen über <em>Dauerhaft</em> oder den Standardwert <code>-1</code> <strong>werden nur hier aufgehoben</strong>. Der allgemeine Dialog bietet dafür keinen Knopf; dieser Bereich vereint Übersicht und Reaktivierung.",
"activeAutoRefreshTitle": "Automatische Aktualisierung",
"activeAutoRefreshBody": "Die Liste aktualisiert sich beim Verwerfen oder Reaktivieren einer Warnung im Health Monitor, bei erneutem Tabfokus und bei Sichtbarkeitswechseln. Ein Neuladen ist nicht nötig.",
"calloutTitle": "Details auf der Health-Monitor-Seite",
"calloutBody": "Eskalation, automatische Auflösung bei verschwundenen Geräten und der Unterschied zwischen Verwerfen und Beheben stehen unter <link>Health Monitor → Warnungen verwerfen und Unterdrückungsdauer</link>. Diese Karte bietet die Auswahllisten und aktiven Unterdrückungen."
},
"thresholds": {
"heading": "Health-Monitor-Schwellenwerte",
"intro": "Die vorige Karte regelt <em>die Ruhezeit nach einer Unterdrückung</em>; diese bestimmt <strong>den Auslösewert einer Warnung</strong>. Die meisten Schwellenprüfungen bieten anpassbare Werte für <strong>Warnung</strong> und <strong>Kritisch</strong>. Die Tabelle unten erklärt Ausnahmen wie die kombinierte Swap-Regel.",
"whatForTitle": "Wozu es dient",
"whatForIntro": "Die Standardwerte sind ein Ausgangspunkt, aber jede Umgebung hat eigene Betriebsbedingungen:",
"whatForItems": [
"Ein Homelab mit einer SSD kann früher bei 75/90 % Belegung warnen, um Platz für Snapshots zu lassen.",
"Speicherschwellen sollten Messwerte und Last des Hosts berücksichtigen. Ceph-Redundanz allein rechtfertigt keine lockereren Warnungen; hohe ZFS-ARC-Nutzung ist nicht mit nicht rückgewinnbarem Arbeitsspeicher gleichzusetzen.",
"Wählen Sie Temperaturschwellen anhand der Laufwerksspezifikationen und tatsächlichen Bedingungen. Passive oder aktive Kühlung allein bestimmt keine allgemein niedrigere oder höhere sichere Grenze.",
"Ein stark virtualisierter Host kann bei Builds CPU-Spitzen erreichen, ohne für jeden 80-%-Peak zu warnen; anhaltende Überlast muss weiter gemeldet werden."
],
"whatForOutro": "Unterstützte Schwellenänderungen gelten <strong>bei der nächsten Prüfung</strong>. Der Health Monitor liest <code>/usr/local/share/proxmenux/health_thresholds.json</code> in jedem Zyklus ohne Neustart. Ausgewählte Anzeigen, darunter die Datenträgertemperatur, verwenden diese Werte; manche Kapazitätsbalken behalten eigene visuelle Grenzen.",
"coloursTitle": "Statusfarben für Warnung und Kritisch",
"coloursIntro": "Widgets mit dem konfigurierten Paar Warnung/Kritisch verwenden die drei folgenden Zustände. Andere Anzeigen, etwa PVE-Kapazitätsbalken, haben eigene Grenzen; ihre Farbe allein belegt keine Health-Monitor-Warnung.",
"headerColour": "Farbe",
"headerRange": "Bereich",
"headerMeaning": "Bedeutung",
"colourRows": [
{
"colour": "Grün",
"range": "Wert < Warnung",
"meaning": "Normaler Betriebsbereich. Keine Warnung wird erzeugt."
},
{
"colour": "Orange",
"range": "Warnung ≤ Wert < Kritisch",
"meaning": "Warnzustand. Health Monitor erzeugt ein WARNING-Ereignis; Benachrichtigungen beachten Kanalfilter und Ruhezeiten."
},
{
"colour": "rot",
"range": "Wert ≥ kritisch",
"meaning": "Kritischer Zustand. Health Monitor erzeugt ein CRITICAL-Ereignis, das Ruhezeiten umgeht. Kategorie- und Ereigniseinstellungen des Kanals gelten weiter; die Zustellung hängt auch von seiner Verfügbarkeit ab."
}
],
"sectionsTitle": "Abschnitte und empfohlene Standardwerte",
"sectionsIntro": "Dies sind die ProxMenux-Standardwerte, bis Sie sie ändern. Die Abschnitte folgen <em>Rechenlast</em>, <em>Temperatur</em> und <em>Speicherkapazität</em>, von aktueller Last bis belegtem Platz.",
"headerSection": "Abschnitt",
"headerWarning": "Warnung",
"headerCritical": "Kritisch",
"headerGates": "Gesteuerte Prüfung",
"thresholdRows": [
{
"section": "CPU-Auslastung",
"warning": "85 %",
"critical": "95 %",
"gates": "Dauerlastwarnung, wenn die mittlere CPU-Auslastung im Prüfzeitraum über der Schwelle liegt."
},
{
"section": "Arbeitsspeicher",
"warning": "85 %",
"critical": "95 %",
"gates": "RAM-Druck des Hosts."
},
{
"section": "Swap (nur kritischer Schwellenwert)",
"warning": "—",
"critical": "80 %",
"gates": "Swap-CRITICAL erfordert zugleich mehr als 80 % Swap und weniger als 15 % verfügbaren RAM über mehrere Messungen. Belegter Swap allein löst die Regel nicht aus."
},
{
"section": "CPU-Temperatur",
"warning": "80 °C",
"critical": "90 °C",
"gates": "CPU-Package- oder Kerntemperatur aus <code>lm-sensors</code>."
},
{
"section": "Festplattentemperatur — HDD",
"warning": "60 °C",
"critical": "65 °C",
"gates": "HDD-Temperatur. Standard: Warnung bei 60 °C, Kritisch bei 65 °C. Das sind Überwachungswerte, keine universelle Herstellergrenze; prüfen Sie die Modellspezifikation."
},
{
"section": "Datenträgertemperatur — SSD",
"warning": "70 °C",
"critical": "75 °C",
"gates": "SATA-SSDs in 2,5-Zoll- oder M.2-Bauform. Diese Klasse verwendet 70/75 °C als Standard; tatsächliche Grenzen hängen vom Modell ab."
},
{
"section": "Datenträgertemperatur — NVMe",
"warning": "80 °C",
"critical": "85 °C",
"gates": "NVMe-Temperatur. Standardwerte dieser Klasse sind 80/85 °C. Die Drosseltemperatur des Controllers hängt vom Modell ab und beträgt nicht immer 85 °C."
},
{
"section": "Datenträgertemperatur — SAS",
"warning": "55 °C",
"critical": "65 °C",
"gates": "SAS-Temperatur. Diese Klasse verwendet Warnung bei 55 °C und Kritisch bei 65 °C. Das sind <em>Überwachungsstandards</em>, kein Beweis eines Kühlfehlers bei 55 °C oder eine allgemeine Herstellergrenze."
},
{
"section": "Datenträgerplatz — Host",
"warning": "85 %",
"critical": "95 %",
"gates": "Kapazität von <code>/</code> und jedem Einhängepunkt des Hosts (<code>/var/lib/vz</code>, <code>/mnt/*</code>…)."
},
{
"section": "Plattenraum — LXC Rootfs",
"warning": "85 %",
"critical": "95 %",
"gates": "Root-Laufwerk pro Container, bewertet anhand der Rootfs-Größe von PVE."
},
{
"section": "LXC-Einhängepunkte",
"warning": "85 %",
"critical": "95 %",
"gates": "Kapazität von Einhängepunkten laufender CTs: mp0, mp1, NFS und Bind-Mounts. Ohne rootfs."
},
{
"section": "PVE-Speicher",
"warning": "85 %",
"critical": "95 %",
"gates": "Nur PVE-Speicher der Typen LVM, LVM-thin, ZFS-pool, RBD, CephFS und PBS. Verzeichnis-, NFS- und CIFS-Speicher deckt die Zeile zum Host-Speicherplatz ab."
},
{
"section": "ZFS-Pool",
"warning": "85 %",
"critical": "95 %",
"gates": "ZFS-Pools auf dem Host, unabhängig von ihrer Registrierung in PVE."
}
],
"defaultsTitle": "Standardwerte, Anpassungen und Zurücksetzen",
"defaultsBody": "Jeder Abschnitt beginnt mit Standardwerten; Sie speichern nur gewünschte Änderungen. Die Karte zeigt den <em>wirksamen</em> Wert: Ihre Änderung oder den Standard. <strong>Zurücksetzen</strong> entfernt alle Änderungen in sämtlichen Abschnitten.",
"validationTitle": "Validierung",
"validationBody": "Beim Speichern werden erlaubte Bereiche geprüft und Kritisch unter Warnung abgelehnt. Die Oberfläche zeigt Fehler; der Server validiert API-Anfragen vor dem Speichern erneut."
},
"lxcDetection": {
"heading": "LXC-Update-Erkennung",
"imageAlt": "LXC-Update-Erkennung mit Schalter zur Suche nach Paketupdates in laufenden Debian-, Ubuntu- und Alpine-Containern",
"imageCaption": "Schalter für regelmäßige Prüfungen mit <code>apt list --upgradable</code> / <code>apk list -u</code> in laufenden CTs. Standardmäßig aktiviert. Der zugehörige Schalter unter Benachrichtigungen → Dienste erscheint bei aktiver Erkennung.",
"intro": "Der Schalter zwischen Schwellen und Benachrichtigungen steuert den LXC-Scan. Aktiv fragt er Paketmanager laufender CTs ab; Hardware zeigt Ergebnisse und <code>lxc_updates_available</code> erhält sie. Deaktiviert stoppt er seine <code>pct exec</code>-Aufrufe und entfernt LXC-Einträge aus <code>managed_installs.json</code>; <code>/api/managed-installs</code> meldet den Status dann ohne 24-Stunden-Wartezeit nicht mehr.",
"whatRunsTitle": "Was die Prüfung ausführt",
"whatRunsIntro": "Für jeden CT im Zustand <code>running</code> mit unterstütztem Paketmanager:",
"whatRunsItems": [
"<strong>Metadatenaktualität.</strong> Ist der apt/apk-Cache älter als <strong>24 Stunden</strong>, wird eine Aktualisierung mit <code>apt-get update -qq</code> auf Debian/Ubuntu oder <code>apk update</code> auf Alpine versucht, mit 60 s Zeitlimit. Bei Fehlern verwendet die Liste den vorhandenen, eventuell veralteten Cache.",
"<strong>Auflistung.</strong> Führt <code>apt list --upgradable</code> / <code>apk list -u</code> aus und ermittelt Paketanzahl und einige Paketnamen.",
"<strong>Duplikate je CT vermeiden.</strong> Ein Fingerabdruck aus Gesamtzahl, Sicherheitsupdates und sortierten Namen verhindert tägliche Wiederholungen desselben Bestands. Wesentliche Änderungen melden erneut."
],
"selfUpdateTitle": "CTs mit Updates außerhalb von apt können 0 melden",
"selfUpdateBody": "Die Erkennung umfasst nur den Paketmanager im CT. Außerhalb von apt aktualisierte Software, etwa ein eingerichteter <code>plexupdate</code>-Job oder Images aus <code>docker pull</code>, zählt nicht dazu. Null apt-Updates beweisen nicht, dass alle Anwendungen aktuell sind. Ausstehende Basissystempakete werden weiter erkannt.",
"refreshTitle": "Warum Metadaten nach 24 Stunden erneuert werden",
"refreshBody": "Lange laufende CTs können alte apt-Metadaten haben, wenn niemand <code>apt update</code> ausführt. <code>apt list --upgradable</code> kann dann neue Updates übersehen. ProxMenux versucht eine Erneuerung nach mehr als 24 Stunden und überspringt sie bei neuerem Cache.",
"toggleTitle": "Benachrichtigungsschalter bei aktiver Erkennung",
"toggleBody": "Der Schalter <code>lxc_updates_available</code> je Kanal unter <strong>Benachrichtigungen → Dienste</strong> erscheint nur bei aktiver Erkennung. Beim Abschalten verschwindet die Zeile in allen Kanälen. Die Datenbank bewahrt die Einstellung; beim Einschalten kehrt der bisherige Wert zurück.",
"purgeTitle": "Was beim Abschalten der Erkennung gelöscht wird",
"purgeBody": "Das Abschalten entfernt sofort alle <code>type=lxc</code>-Einträge aus <code>/usr/local/share/proxmenux/managed_installs.json</code>. Die LXC-Updatezähler auf der Registerkarte VMs und LXCs verschwinden beim nächsten Neuladen des Dashboards. Nach dem Einschalten füllt der nächste Erkennungszyklus den Bestand erneut; ein manueller API-Aufruf kann dies vorziehen."
},
"storageExclusions": {
"heading": "Ausschlüsse von Remote-Speicher",
"imageAlt": "Karte für entfernte Speicherausschlüsse mit PBS-Cloud, PBS und PBS2 sowie Schaltern für Zustand und Warnungen je Zeile",
"imageCaption": "Schalter für <em>Zustand</em> und <em>Warnungen</em> je Speicher. Sind beide aus, zählt der Speicher nicht mehr im Health Monitor und sendet keine Meldungen. Unter Speicher bleibt er als ausgeschlossen sichtbar.",
"intro": "Von Proxmox verwaltete Speicher (NFS / CIFS / PBS / Ceph / iSCSI usw.) lassen sich mit zwei unabhängigen Schaltern ausschließen:",
"items": [
"<strong>Zustand</strong> — wird dieser Schalter deaktiviert, zählt der Speicher nicht mehr zur Speicherkategorie des Health Monitor. Hilfreich für meist abgeschaltete Archiv-Volumes oder entfernte Sicherungsziele, die nur nach Zeitplan eingeschaltet werden.",
"<strong>Warnungen</strong> — ausgeschaltet verhindert dieser Schalter Meldungen für den Speicher über eingerichtete Kanäle, auch bei aktiven Zustandsprüfungen. Hilfreich, wenn Sie den Zustand im Dashboard sehen möchten, ohne Meldungen zu erhalten."
],
"outro": "Ausgeschlossene Speicher bleiben auf der <link>Registerkarte Speicher</link> mit dem violetten Abzeichen <em>ausgeschlossen</em> sichtbar. Der Zustand wird in der SQLite-Tabelle <code>excluded_storages</code> gespeichert."
},
"interfaceExclusions": {
"heading": "Ausschlüsse von Netzwerkschnittstellen",
"imageAlt": "Karte für Schnittstellenausschlüsse mit vmbr0, vmbr1, vmbr2, bond0 und eno1 sowie Zustands- und Warnungsschaltern je Schnittstelle",
"imageCaption": "Wie bei Speicherausschlüssen gibt es <em>Zustand</em> und <em>Warnungen</em> je Schnittstelle. Jede Zeile zeigt Namen, Typ (Bridge / Bond / physisch), IP und Verbindungsgeschwindigkeit.",
"intro": "Dasselbe Prinzip gilt für Netzwerkschnittstellen: Jede lässt sich von Zustandsprüfungen, Benachrichtigungen oder beiden ausschließen. Typische Beispiele:",
"items": [
"Eine bewusst deaktivierte Reserve-Bridge.",
"Eine physisch entfernte Netzwerkkarte, die noch in <code>/etc/network/interfaces</code> steht.",
"Eine VLAN-Unterschnittstelle, die nur bei Wartungsarbeiten genutzt wird.",
"Eine Verwaltungs-Bridge mit bekannten, wiederholten Verbindungswechseln während der Wartung."
],
"outro": "Der Zustand wird in der SQLite-Tabelle <code>excluded_interfaces</code> gespeichert. Das violette Abzeichen <em>ausgeschlossen</em> auf der <link>Registerkarte Netzwerk</link> hält ausgeschlossene Schnittstellen sichtbar."
},
"notifications": {
"heading": "Benachrichtigungen und KI",
"body1": "Hier aktivieren Sie ProxMenux-Monitor-Benachrichtigungen und die KI-Umformulierung. <em>Benachrichtigungen aktivieren</em> startet den Hintergrundversand, registriert ein Proxmox-VE-Webhook-Ziel für dessen Ereignisse und öffnet die Kanaleinstellungen für Telegram, Discord, E-Mail, Gotify und weitere Dienste. Die KI-Umformulierung liegt im selben Bereich unter aufklappbaren erweiterten Einstellungen.",
"body2": "Eigene Seiten erklären die Optionen: Kanäle, Ereignisschalter, formatierte Nachrichten, Anzeigename, Versand mit Duplikatfilter, Wartezeiten, Bündelung und Ruhezeiten, PVE-Webhook, KI-Anbieter und Prompt-Modi:",
"items": [
"<notifLink>Benachrichtigungen</notifLink>: Kanaleinrichtung (Telegram, Discord, Gotify, E-Mail mit Gmail-/Microsoft-App-Passwörtern, ntfy, Slack, Teams und allgemeiner Webhook), Ereigniskategorien, formatierte Nachrichten, Anzeigename, Versand, PVE-Webhook, Verlauf und API.",
"<aiLink>KI-Assistent</aiLink>: Anbieter (OpenAI, Anthropic, Gemini, Groq, OpenRouter, Ollama), Modelle, Standard- oder eigene Prompts, Ausgabesprache, Detailgrad je Kanal und KI-Vorschläge."
]
},
"optimizations": {
"heading": "ProxMenux-Optimierungen",
"intro": "Bestand der von ProxMenux auf dem Host registrierten Nachinstallationsoptimierungen. Optionen aus <autoLink>Automatisierte Nachinstallation</autoLink> und <customLink>Anpassbare Nachinstallation</customLink> tragen ihre Anwendung in <code>/usr/local/share/proxmenux/installed_tools.json</code> ein. Der Monitor liest diesen Bestand. Ein Eintrag prüft nicht erneut, ob alle Einstellungen unverändert sind.",
"imageAlt": "ProxMenux-Optimierungskarte mit 14 Einträgen aus Farbpunkt, Name und Version: 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 mit Legacy, Kernel Panic Configuration, Logrotate Optimization, Network Optimizations, Subscription Banner Removal und VFIO IOMMU Passthrough.",
"imageCaption": "Jede Optimierung erscheint mit Name, Version und Farbpunkt. Oben rechts steht der orange Zähler <em>14 aktiv</em>. Werkzeuge mit verfügbarem Quellcode lassen sich öffnen.",
"dotsTitle": "Was die Punkte bedeuten",
"dotsItems": [
"<green/> <strong>Grüner Punkt</strong>: registrierte Optimierung ohne Legacy-Markierung und ohne angezeigtes Update. Öffnen Sie die Zeile, wenn Quellcode verfügbar ist.",
"<amber/> <strong>Oranger Punkt und <em>legacy</em>-Abzeichen</strong>: registrierte Optimierung, deren Skript umbenannt oder ersetzt wurde. Der erhaltene Quellcode öffnet sich im Legacy-Modus mit oranger Hervorhebung. Die aktuelle Host-Konfiguration wird dabei nicht erneut geprüft."
],
"clickTitle": "Quellcode öffnen",
"clickBody": "Ein Klick zeigt die zugeordnete Bash-Funktion und den Skriptnamen (<code>auto_post_install.sh</code> oder <code>customizable_post_install.sh</code>). Aktuelle Werkzeuge stammen aus Host-Dateien, ältere können erhaltenen Quellcode nutzen. Syntaxhervorhebung und Kopieren erleichtern die Prüfung. Dies ist kein garantiertes Abbild des bei der Installation ausgeführten Codes.",
"detailAlt": "Quellcodefenster für APT IPv4 Force mit der Bash-Funktion force_apt_ipv4 aus customizable_post_install.sh Version 1.0. Der hervorgehobene Code konfiguriert /etc/apt/apt.conf.d/99-force-ipv4 mit Acquire ForceIPv4 true, registriert das Werkzeug und zeigt eine übersetzte Abschlussmeldung zur APT-IPv4-Konfiguration.",
"detailCaption": "Quellcode von <em>APT IPv4 Force</em>: Funktion <code>force_apt_ipv4()</code> aus <code>customizable_post_install.sh v1.0</code>, mit Syntaxhervorhebung und Kopieren per Klick.",
"whyTitle": "Warum das wichtig ist",
"whyBody": "ProxMenux kann Kernel-Parameter, Paketquellen, Netzwerk, Logrotation und GPU-Durchreichung ändern. Prüfen Sie die registrierten Optimierungen vor manuellen Änderungen, besonders wenn jemand anderes den Host eingerichtet hat. Die Karte zeigt Bestand und verfügbaren Quellcode; sie prüft nicht jede aktuelle Einstellung und bewahrt keinen exakten Ausführungsverlauf.",
"updatesTitle": "Hinweis auf verfügbare Updates",
"updatesBody": "Ist die Optimierung auf dem Datenträger neuer als die auf dem Host registrierte Version, erscheint ein Hinweis mit Anzahl und <strong>Anwenden</strong>. <strong>Anwenden</strong> öffnet die Auswahl der Optimierungen, wie <em>Verfügbare Updates anwenden</em> im Nachinstallationsmenü. Wählen Sie die Updates; ProxMenux führt ihre Funktionen erneut aus und aktualisiert den Bestand. Sind alle aktuell, verschwindet der Hinweis.",
"updatesAlt": "ProxMenux-Optimierungskarte mit Hinweis auf verfügbare Updates, deren Anzahl und Anwenden-Schaltfläche für die Auswahl",
"updatesCaption": "Der Hinweis erscheint, wenn mindestens eine Optimierung auf dem Datenträger neuer ist. <link>Verfügbare Updates anwenden</link> erklärt den Ablauf und die entsprechende Path-A-Option im Shell-Menü.",
"revertTitle": "Eine Optimierung rückgängig machen",
"revertBody": "Um eine Optimierung rückgängig zu machen, wählen Sie die passende Option unter <link>Optimierungen deinstallieren</link> im ProxMenux-Scripts-Menü. Dies entfernt den Eintrag aus <code>installed_tools.json</code>; nach dem Neuladen erscheint er nicht mehr."
},
"dataCollected": {
"heading": "Wie die Daten gesammelt werden",
"headerCard": "Karte",
"headerEndpoint": "Endpunkt",
"headerSource": "Quelle",
"rows": [
{
"card": "Schnittstellensprache",
"endpoint": "localStorage",
"source": "Browser-Einstellung <code>proxmenux-ui-language</code>; ohne gespeicherte Wahl wird zunächst die Browsersprache verwendet."
},
{
"card": "Navigationsreihenfolge",
"endpoint": "localStorage",
"source": "Browser-Einstellung <code>proxmenux-nav-order</code>; sie legt auch die Startregisterkarte fest."
},
{
"card": "Netzwerkeinheiten",
"endpoint": "/api/settings",
"source": "In der SQLite-Einstellungstabelle des Dashboards gespeichert."
},
{
"card": "Health-Monitor-Zeitdauern",
"endpoint": "/api/health/settings",
"source": "Unterdrückungsdauer je Kategorie in der Health-Monitor-Datenbank."
},
{
"card": "Speicher-/Schnittstellenausschlüsse",
"endpoint": "/api/storage/exclusions, /api/network/exclusions",
"source": "SQLite Tabellen <code>excluded_storages</code> und <code>excluded_interfaces</code>."
},
{
"card": "Bereich Benachrichtigungen und KI",
"endpoint": "/api/notifications/*",
"source": "Siehe <notifLink>Benachrichtigungen</notifLink> und <aiLink>KI-Assistent</aiLink>."
},
{
"card": "ProxMenux-Optimierungsliste",
"endpoint": "/api/proxmenux/installed-tools",
"source": "Liest <code>/usr/local/share/proxmenux/installed_tools.json</code>, geschrieben durch <code>register_tool</code>-Aufrufe der Nachinstallationsskripte."
},
{
"card": "Quellcodefenster einer Optimierung",
"endpoint": "/api/proxmenux/tool-source",
"source": "Extrahiert die zugeordnete Bash-Funktion aus <code>auto_post_install.sh</code> oder <code>customizable_post_install.sh</code> auf dem Host; ältere Werkzeuge können erhaltenen Quellcode nutzen."
}
]
},
"whereNext": {
"heading": "Weitere Schritte",
"items": [
{
"label": "Registerkarte Apps",
"href": "/docs/monitor/dashboard/apps",
"tail": " — der App-Starter, dessen Position die Navigationsreihenfolge bestimmt."
},
{
"label": "Benachrichtigungen",
"href": "/docs/monitor/notifications",
"tail": " — Kanäle, Ereignisschalter, kanalbezogene Anpassungen, Verlauf und Testversand."
},
{
"label": "KI-Assistent",
"href": "/docs/monitor/ai-assistant",
"tail": " — Anbieter, Modelle, Prompt-Modi, Sprachen und Detailgrad je Kanal."
},
{
"label": "Health Monitor → Warnungen unterdrücken und Unterdrückungsdauer",
"href": "/docs/monitor/health-monitor#dismissing-alerts-and-the-suppression-duration",
"tail": " — wie die obigen Auswahllisten je Kategorie funktionieren."
},
{
"label": "ProxMenux Scripts → Automatisierte Nachinstallation",
"href": "/docs/post-install/automated",
"tailRich": " und <customLink>Anpassbare Nachinstallation</customLink> — die Skripte, die Einträge in der obigen Optimierungsliste registrieren."
},
{
"label": "Optimierungen deinstallieren",
"href": "/docs/post-install/uninstall",
"tail": " — wie Sie eine oben registrierte Optimierung rückgängig machen."
},
{
"label": "Dashboard-Index",
"href": "/docs/monitor/dashboard",
"tail": " — zurück zur Übersicht der Registerkarten."
}
]
}
}
@@ -0,0 +1,268 @@
{
"meta": {
"title": "ProxMenux Monitor — Dashboard: Registerkarte Speicher | ProxMenux-Dokumentation",
"description": "Die Registerkarte Speicher vereint vier Ansichten: Proxmox-Speicher mit Status, ZFS-Pools, interne Laufwerke mit SMART und externe USB-Laufwerke. Die Laufwerksdetails zeigen SMART-Attribute, Verschleiß, Lebensdauer und dauerhaft gespeicherte Beobachtungen."
},
"header": {
"title": "Dashboard: Registerkarte Speicher",
"description": "Der gesamte Hostspeicher auf einer Seite: Proxmox-Speicher NFS / CIFS / LVM / ZFS / dir, ZFS-Poolzustand, interne SATA/NVMe-Laufwerke mit SMART und externe USB-Laufwerke. Ein Klick auf ein Laufwerk öffnet SMART-Attribute und Beobachtungsverlauf.",
"section": "ProxMenux Monitor · Übersicht"
},
"intro": {
"title": "Unterstützt durch drei Quellen",
"body": "Proxmox-Speicher stammen aus <code>pvesm status</code>, ZFS aus <code>zpool status</code>, physische Laufwerke aus <code>lsblk</code> + <code>smartctl</code> und NVMe-Felder aus <code>nvme</code>. Die Seite aktualisiert sich etwa alle 60 Sekunden; die Detailansicht fordert eine SMART-Abfrage an."
},
"thresholds": {
"title": "Hier angewendete Statusfarben und -schwellen",
"intro": "Health Monitor bewertet den Status als <green/> <strong>grün</strong> unter Warnung, <amber/> <strong>orange</strong> zwischen Warnung und Kritisch und <red/> <strong>rot</strong> ab Kritisch. Die Standardwerte folgen. Einzelne Dashboard-Balken können andere, unten beschriebene Farbgrenzen verwenden.",
"items": [
"<strong>Kapazität</strong> (Hostlaufwerke, PVE-Speicher, ZFS-Pools, LXC-Einhängepunkte) — Warnung 85 %, Kritisch 95 %.",
"<strong>Laufwerkstemperatur</strong> — HDD 60/65 °C · SSD 70/75 °C · NVMe 80/85 °C · SAS 55/65 °C (Warnung / Kritisch)."
],
"outro": "Alle Werte lassen sich je Host konfigurieren. <link>Einstellungen → Health-Monitor-Schwellen</link> nennt die maßgeblichen Werte und erklärt ihre Anpassung."
},
"topRow": {
"heading": "Obere Reihe: Speicherübersicht",
"intro": "Vier Karten fassen beim Öffnen Gesamtkapazität, lokale Nutzung, entfernte Nutzung und physische Laufwerke zusammen. Sie geben schnelle Antworten; die Karten darunter enthalten die Details.",
"imageAlt": "Registerkarte Speicher mit vier Karten: Gesamtspeicher, lokale Nutzung, entfernte Nutzung und physische Laufwerke",
"imageCaption": "Obere Reihe: Gesamtkapazität und Laufwerksanzahl, lokal und entfernt belegte Bytes sowie physische Laufwerke nach Typ mit Zustandsübersicht.",
"headerCard": "Karte",
"headerWhat": "Was es zeigt",
"totalLabel": "Gesamtspeicher",
"totalWhat": "Gesamte Rohkapazität aller physischen Laufwerke. Die Fußzeile nennt die Anzahl erkannter Laufwerke.",
"localLabel": "Lokale Nutzung",
"localWhat": "Belegte Bytes auf lokalem Speicher: LVM / LVM-thin / ZFS / dir auf den Hostlaufwerken. Der Hauptwert zeigt belegte Bytes, die Fußzeile <em>X.XX % von Y TB</em> zusätzlich den Belegungsgrad.",
"remoteLabel": "Entfernte Nutzung",
"remoteWhat": "Dasselbe Format wie Lokale Nutzung für entfernte Speicher NFS / CIFS / PBS / Ceph / iSCSI. Sie werden getrennt gezählt, da lokale und entfernte Ausfälle unterschiedlich wirken und die Ressourcen anders geplant und überwacht werden.",
"disksLabel": "Physische Laufwerke",
"disksIntro": "Zwei Aufschlüsselungslinien für das Inventar:",
"disksItems": [
"<strong>Nach Typ</strong> — Anzahl der NVMe-Laufwerke in Lila, SSDs und HDDs in Blau. Angezeigt werden erkannte Typen; ein reiner NVMe-Host zeigt nur diesen Zähler.",
"<strong>Nach Zustand</strong> — Anzahl <em>normaler</em> Laufwerke in Grün, mit <em>Warnung</em> in Gelb und <em>kritischer</em> in Rot. Ohne Probleme erscheint nur „X normal“; die anderen Zustände werden erst bei entsprechenden Befunden angezeigt."
]
},
"pveStorage": {
"heading": "Proxmox Speicherkarte",
"intro": "Je Speicher aus <code>/etc/pve/storage.cfg</code> eine Zeile mit Typ (<code>nfs</code> / <code>cifs</code> / <code>zfspool</code> / <code>lvm</code> / <code>lvmthin</code> / <code>dir</code> / <code>pbs</code>), Name, Status aktiv/Fehler/nicht überwacht, Belegungsgrad und Farbbalken:",
"items": [
"<strong>Bis 75 %</strong> — blauer Balken und Wert.",
"<strong>Über 75 % bis 90 %</strong> — gelber Balken und Wert. Diese Farbgrenzen sind von den Health-Monitor-Schwellen getrennt.",
"<strong>> 90 %</strong> — roter Balken und Wert. Diese Farbgrenze ist von der Eskalation im Health Monitor getrennt.",
"<strong>Fehler</strong> — roter Rahmen um die Zeile bei konfiguriertem, aber unerreichbarem Speicher, etwa ausgefallenem NFS-Server oder abgelaufenen CIFS-Zugangsdaten.",
"<strong>Ausgeschlossen</strong> — lila Rahmen und Kennzeichnung „nicht überwacht“. Vom Benutzer ausgeschlossene Speicher, etwa absichtlich getrennte Archivvolumes."
],
"calloutTitle": "Speicher von der Überwachung ausschließen",
"calloutBody": "Im Speichermenü lässt sich der Speicher als <em>von Überwachung ausgeschlossen</em> markieren. Die Einstellung liegt in <code>excluded_storages</code> und gilt für Dashboard und Health Monitor: keine Benachrichtigungen und kein Einfluss auf den Gesamtstatus."
},
"zfs": {
"heading": "ZFS Poolkarte",
"intro": "Erscheint nur bei installiertem ZFS und mindestens einem Pool. Jede Zeile zeigt einen Pool mit Status, Größe, belegtem und freiem Platz sowie Statussymbol:",
"items": [
"<strong>ONLINE</strong> — grün. Alles gesund.",
"<strong>DEGRADED</strong> — gelb. Der Pool liefert Daten, aber mindestens ein Gerät ist nicht verfügbar; ein Austausch muss geprüft werden.",
"<strong>FAULTED</strong> / <strong>UNAVAIL</strong> / <strong>SUSPENDED</strong> — rot. Der Pool liefert keine Daten und erfordert sofortiges Eingreifen."
],
"outro": "ZFS-Zustand und SMART-Status jedes Laufwerks fließen in die Kategorie <em>Laufwerke und E/A</em> im <link>Health Monitor</link> ein."
},
"physical": {
"heading": "Physische Laufwerke und SMART-Status",
"intro": "Interne Festplatten (SATA / NVMe). Jede Zeile kondensiert die nützlichsten Felder auf einen Blick:",
"items": [
"<strong>Gerätepfad</strong> — <code>/dev/sda</code>, <code>/dev/nvme0n1</code>.",
"<strong>Typkennzeichnung</strong> — SATA / NVMe und passendes Symbol.",
"<strong>Systemkennzeichnung</strong> — orange Markierung für Laufwerke, die der Host verwendet: Systemeinhängepunkte (<code>/</code>, <code>/boot</code>, <code>/usr</code>, <code>/var</code>…), aktiver Swap, ZFS-Poolmitglieder, physische LVM-Volumes, aktive RAID-Mitglieder oder Bezeichnungen von Systempartitionen. Eine fehlende Markierung beweist nicht, dass das Laufwerk gefahrlos gelöscht oder anders verwendet werden kann.",
"<strong>Modell</strong> — Hersteller und Modell aus <code>smartctl -i</code>.",
"<strong>Kapazität</strong> — in gut lesbaren Einheiten.",
"<strong>Temperatur</strong> — aktueller Wert in °C, eingefärbt nach Laufwerkstyp; NVMe verwendet höhere Schwellen als SATA.",
"<strong>SMART-Status</strong> — bestanden / fehlgeschlagen / unbekannt.",
"<strong>Beobachtungsanzeige</strong> — enthält der dauerhafte Verlauf <code>disk_observations</code> Einträge für das Laufwerk, erscheint eine blaue Kennzeichnung mit der Anzahl, etwa <em>3 obs.</em>. Ein Klick öffnet die Beobachtungen.",
"<strong>Zustandsanzeige</strong> — In Ordnung / Warnung / Kritisch anhand von SMART und jüngsten Beobachtungen."
],
"clickHint": "Die gesamte Zeile öffnet per Klick die unten beschriebenen Laufwerksdetails.",
"warningTitle": "Systemlaufwerke mit Bedacht behandeln",
"warningBody": "Laufwerke mit orangefarbenem <strong>System</strong> enthalten das laufende Betriebssystem. Die Kennzeichnung hilft bei der Erkennung; <link>ProxMenux → Laufwerksverwaltung → Formatieren / Löschen</link> verweigert destruktive Aktionen darauf. Verwenden Sie zur Umnutzung einer Startplatte eine Rettungsumgebung außerhalb des laufenden Proxmox."
},
"external": {
"heading": "Externer Speicher (USB)",
"body": "USB-Laufwerke haben eine eigene Karte, die nur bei angeschlossenen Geräten erscheint. Sie zeigt dieselben Felder wie interne Laufwerke und ein orangefarbenes <strong>USB</strong>-Label. Da sie oft nur für Sicherungen oder gelegentliche Übertragungen verbunden sind, bleiben Beobachtungen erhalten, während E/A-Fehler getrennter USB-Laufwerke nicht eskalieren."
},
"drillIn": {
"heading": "Dialog mit Laufwerksdetails",
"intro": "Ein Klick auf ein Laufwerk öffnet vier Registerkarten: <strong>Übersicht</strong> · <strong>SMART</strong> · <strong>Verlauf</strong> · <strong>Zeitplan</strong>. Die Kopfzeile zeigt Gerätepfad, Modell, Kapazität und gegebenenfalls das orangefarbene <em>System</em>-Label.",
"overviewTitle": "Registerkarte 1 — Übersicht",
"overviewImageAlt": "Laufwerksdetails mit Übersicht, Zustand, Ringanzeige für Verschleiß und Lebensdauer sowie wichtigen SMART-Attributen",
"overviewImageCaption": "Übersicht: Identifikation, Zustand, Restlebensdauer mit aktuellem Verschleiß und geschriebenen Daten sowie wichtige SMART-Attribute.",
"overviewIntro": "Standardansicht zum Prüfen des Laufwerkszustands ohne Testlauf. Drei Bereiche:",
"overviewItems": [
"<strong>Identifikation</strong> — Modell, Seriennummer, Kapazität und Zustand In Ordnung / Warnung / Kritisch.",
"<strong>Verschleiß und Lebensdauer</strong> — Ring für Restlebensdauer (97 %, 50 %, …) mit Quellattribut (<em>Media Wearout Indicator</em>, <em>Percentage Used</em>, …), Verschleißbalken, Prognose <em>Geschätzte Lebensdauer</em> in Jahren und geschriebenen Gesamtdaten. NVMe zeigt auch <em>Available Spare</em>.",
"<strong>SMART-Attribute</strong>: Die wichtigsten Werte erscheinen in einem Raster mit zwei Spalten: Temperatur, Betriebsstunden mit lesbarer Dauer wie <em>3 Jahre und 116 Tage</em>, Drehzahl oder <em>SSD</em>, Einschaltzyklen, SMART-Status, neu zugewiesene Sektoren, ausstehende Sektoren und CRC-Fehler. Die vollständige Attributtabelle befindet sich auf der Registerkarte SMART."
],
"smartTitle": "Tab. 2 — SMART",
"smartImageAlt": "Laufwerksdetails, SMART-Registerkarte mit kurzem und erweitertem Test, letztem Ergebnis und vollständiger Attributtabelle",
"smartImageCaption": "SMART-Registerkarte: kurzen oder erweiterten Test starten, letztes Ergebnis und alle Attribute prüfen sowie den vollständigen Bericht zum Drucken oder Speichern als PDF öffnen.",
"smartIntro": "Verfügbare Aktionen in drei Bereichen:",
"smartItems": [
"<strong>SMART-Test starten</strong> — zwei Schaltflächen. <em>Kurzer Test (~2 Min.)</em> wartet auf das Ergebnis und zeigt es im Dialog. <em>Erweiterter Test (Hintergrund)</em> kann bei großen Laufwerken Stunden dauern, läuft auf dem Server weiter und benachrichtigt bei Abschluss.",
"<strong>Letzter Test</strong> — Typ, Status (<em>bestanden</em> / <em>fehlgeschlagen</em>) und Zeitstempel des letzten Laufs.",
"<strong>SMART-Attribute</strong> — vollständige Tabelle mit ID, Name, Wert, schlechtestem Wert und Status In Ordnung, Warnung oder Kritisch. SATA/SAS zeigt die nummerierte Liste. NVMe verwendet <code>nvme smart-log</code>: Temperatur, verfügbare Reserve, verbrauchter Anteil, gelesene/geschriebene Einheiten, Hostzugriffe, Controller-Auslastungszeit, Einschaltzyklen, unsichere Abschaltungen, Medienfehler, Fehlerprotokolleinträge und Zeit im Warn-/Kritischbereich der Gesamttemperatur."
],
"pdfTitle": "Vollständigen SMART-Bericht anzeigen (PDF)",
"pdfIntro": "Unten auf SMART öffnet <strong>Vollständigen SMART-Bericht anzeigen</strong> einen druckbaren Bericht. Speichern Sie ihn über den Browser-Druckdialog als PDF zum Archivieren oder für den Herstellersupport bei einer RMA.",
"pdfPreviewAlt": "Erste Seite des SMART-Berichts mit Zusammenfassung, PASSED-Ring und Laufwerksinformationen",
"pdfPreviewCaption": "Erste Seite: Zusammenfassung, PASSED-Ring und vollständige Laufwerksinformationen. Das Beispiel-PDF enthält SSD-Verschleiß, alle SMART-Attribute und den Testverlauf.",
"pdfDownloadLabel": "Beispiel-SMART-Bericht herunterladen (PDF)",
"pdfSectionsIntro": "Der Bericht enthält diese Hauptabschnitte:",
"pdfSections": [
"<strong>Zusammenfassung</strong> — PASSED/FAILED, verständliche Zustandsbewertung — in Ordnung, Verschleiß oder Ausfall — und vier Angaben: Berichtszeit, letzter Testtyp, Ergebnis und geprüfte Attribute.",
"<strong>Laufwerksinformationen</strong> — Modell, Seriennummer, Kapazität, Typ HDD/SSD/NVMe, Familie, Bauform, Schnittstelle (SATA 3.3 · 6.0 Gb/s, …), TRIM, Temperatur und optimale Schwelle, Betriebsstunden, Einschaltzyklen, SMART, ausstehende/neu zugewiesene Sektoren und CRC-Fehler.",
"<strong>SSD-Verschleiß und Lebensdauer</strong> (nur SSD/NVMe) — Restlebensdauer, Quellattribut, aktueller Verschleiß, geschriebene Daten und Betriebsstunden.",
"<strong>Vollständige SMART-Attribute</strong> — ID, Name, Wert, schlechtester Wert, Schwelle, Rohwert und Status jedes Attributs. Wichtige Attribute wie Reallocated Sector Ct, Power On Hours, Reported Uncorrect, UDMA CRC Error Count und Media Wearout Indicator werden unter der Zeile kurz erklärt.",
"<strong>Letzter Selbsttest und vollständiger Verlauf</strong> — letzter Test mit Typ, Ergebnis, Abschlussmeldung und damaligen Betriebsstunden sowie nummerierte Tabelle aller aufbewahrten Tests.",
"<strong>Empfehlungen</strong> — Maßnahmen anhand des Ergebnisses. Für gesunde Laufwerke: <em>Laufwerk in Ordnung / regelmäßige Tests / Sicherungsstrategie</em>. Bei auffälligen Attributen folgen Hinweise zum Austausch."
],
"pdfOutro": "Der Browser erstellt den druckbaren Bericht; Drucken und Als PDF speichern öffnen beide den Druckdialog. Wählen Sie einen Namen wie <code>SMART-&lt;short-id&gt;.pdf</code>. Bewahren Sie datierte Berichte zum Vergleich oder für den Herstellersupport auf.",
"historyTitle": "Registerkarte 3 — Verlauf",
"historyImageAlt": "Laufwerksdetails, Verlauf mit früheren SMART-Tests sowie Download und Löschen",
"historyImageCaption": "SMART-Testverlauf des Laufwerks. Jede Zeile zeigt Typ, Zeit, Alter, Markierung des neuesten Tests sowie Download der <code>smartctl</code>-Ausgabe und Löschen.",
"historyIntro": "Aufbewahrte abgeschlossene kurze und erweiterte Tests des Laufwerks. Jeder Eintrag enthält die ursprüngliche <code>smartctl</code>-Ausgabe und die von Monitor für das Dashboard ausgewerteten Felder. Aktionen je Zeile:",
"historyItems": [
"<strong>Herunterladen</strong> — speichert den JSON-Snapshot dieses Tests (Ausgabe von <code>smartctl -a --json</code> oder bei NVMe <code>nvme smart-log</code>, wenn smartctl fehlschlägt). Hilfreich, wenn der Herstellersupport die ursprünglichen Diagnosefelder benötigt.",
"<strong>Löschen</strong> — entfernt einen Test manuell aus dem Verlauf. Die Aufbewahrung im Zeitplan (<em>letzte 5 / 10 / 20</em>) löscht automatisch die ältesten."
],
"scheduleTitle": "Registerkarte 4 — Zeitplan",
"scheduleImageAlt": "Laufwerksdetails, Zeitplan-Registerkarte mit Schalter für automatische SMART-Tests, Zeitplanliste und Schaltfläche Zeitplan hinzufügen",
"scheduleImageCaption": "Zeitplan: Testtyp, Intervall und Aufbewahrung wählen; Monitor richtet <code>cron</code> für automatische Tests ein.",
"scheduleIntro": "Automatische SMART-Tests über cron ohne Terminal. Drei Bereiche:",
"scheduleItems": [
"<strong>Automatische SMART-Tests</strong> — gemeinsamer Schalter für alle Zeitpläne des Laufwerks. Er pausiert sie während der Wartung, ohne ihre Konfiguration zu löschen.",
"<strong>Konfigurierte Zeitpläne</strong> — je Zeitplan eine Zeile mit Typ (<em>kurz</em> / <em>lang</em>), lesbarem Cron-Ausdruck (<em>„Am 1. des Monats um 03:00“</em>, <em>„Jeden Sonntag um 02:00“</em>), betroffenen Laufwerken und Aufbewahrung.",
"<strong>Zeitplan hinzufügen / bearbeiten</strong> — Typ (<em>kurz ~2 Min.</em> / <em>lang 1–4 Std.</em>), Intervall (<em>täglich / wöchentlich / monatlich</em>), Monats- oder Wochentag, Uhrzeit und Ergebnisse aufbewahren (<em>letzte 5 / 10 / 20</em>)."
],
"scheduleOutro": "Der Zeitplan erzeugt einen Cron-Eintrag auf dem Host, der Monitor aufruft. Ergebnisse landen im SMART-Verlauf auf Registerkarte 3; die Aufbewahrung entfernt nach neuen Tests automatisch die ältesten Ergebnisse.",
"tempTitle": "Dialog mit Temperaturverlauf",
"tempIntro": "Monitor erfasst regelmäßig Messwerte von Laufwerken mit Temperatursensor und speichert sie lokal als Verlauf. Der aktuelle Wert steht in der Übersicht; ein Klick öffnet den Temperaturverlauf.",
"tempImageAlt": "Temperaturverlauf mit Gerätepfad und Modell, Zeiträumen von 1 Stunde, 24 Stunden, 7 oder 30 Tagen, Anzeigen für Aktuell/Minimum/Mittelwert/Maximum und Liniendiagramm nach den Schwellen des Laufwerkstyps",
"tempImageCaption": "Der Temperaturdialog öffnet sich aus der Übersicht bei einem Sensorwert ungleich null. Das Diagramm verwendet die Schwellen für HDD / SSD / NVMe / SAS.",
"tempShowsTitle": "Inhalt des Dialogs",
"tempShowsItems": [
"<strong>Zeitraumauswahl</strong>: <em>1 Stunde</em>, standardmäßig <em>24 Stunden</em>, <em>7 Tage</em> oder <em>30 Tage</em>. Die Auflösung wird je Anfrage für ein lesbares Diagramm angepasst.",
"<strong>Vier Kennzahlen</strong>: <em>Aktuell</em>, <em>Minimum</em>, <em>Mittelwert</em> und <em>Maximum</em> im Zeitraum. <em>Aktuell</em> verwendet dieselben Schwellen wie Speicheransicht und Benachrichtigungen für normale, erhöhte oder hohe Temperatur.",
"<strong>Liniendiagramm</strong> der Temperatur im Zeitverlauf, dessen Linie und Fläche nach Laufwerkstyp eingefärbt sind:"
],
"tempDiskTypes": [
"HDD - typischerweise kühlere Schwellenwerte.",
"SSD — moderate Schwellenwerte.",
"NVMe — höhere Schwellenwerte (NVMe läuft vom Design her heißer).",
"SAS — Warnung bei 55 °C und Kritisch bei 65 °C; die Warnschwelle unterscheidet sich von HDD."
],
"tempConfigurable": "Alle vier Typen werden unter <em>Einstellungen → Health-Monitor-Schwellen</em> konfiguriert.",
"tempWhyTitle": "Warum der Verlauf wichtig ist",
"tempWhyItems": [
"<strong>Trends erkennen.</strong> Ein einzelner Wert zeigt nicht, dass ein Laufwerk seit Wochen wärmer wird, etwa durch Lüfterprobleme, Staub oder benachbarte Wärmequellen. Die Ansichten für 7 und 30 Tage zeigen den Verlauf.",
"<strong>Spitzen zuordnen.</strong> Hat eine Sicherung oder Wiederherstellung die Temperatur kurz über die Schwelle erhöht, zeigen die Ansichten für 1 und 24 Stunden, ob es einmalig oder wiederkehrend war.",
"<strong>Schwellen anpassen.</strong> Prüfen Sie vor Änderungen unter <em>Einstellungen → Health-Monitor-Schwellen</em> im 30-Tage-Diagramm den tatsächlichen Betriebsbereich des Laufwerks."
],
"obsTitle": "Beobachtungsverlauf über Registerkarten hinweg",
"obsIntro": "Laufwerksfehler können sich allmählich entwickeln. Ein Laufwerk kann SMART <strong>PASSED</strong> melden und dennoch Lesefehler in dmesg, SATA-Verbindungsabbrüche oder zeitweise ausstehende Sektoren zeigen. ProxMenux speichert diese <em>Signale</em> und zeigt sie im Dialog neben dem aktuellen SMART-Status.",
"obsImageAlt": "Übersicht eines Laufwerks mit bestandenem SMART und null neu zugewiesenen/ausstehenden Sektoren und CRC-Fehlern, aber einer E/A-Beobachtung mit ursprünglicher Kernelmeldung, ATA-Erklärung, erstem und letztem Zeitpunkt und Zähler",
"obsImageCaption": "Ein Laufwerk mit <strong>bestandenem SMART</strong> kann frühere Beobachtungen haben. Die Karte ergänzt den aktuellen Status um den Signalverlauf.",
"obsWhatTitle": "Was ist eine Beobachtung?",
"obsWhatIntro": "ProxMenux speichert erkannte Laufwerksereignisse aus Kernelprotokoll, dmesg oder SMART als <strong>Beobachtung</strong>, wenn sie einzeln zu detailliert für eine Benachrichtigung wären. Jede Zeile zeigt:",
"obsWhatItems": [
"<strong>Typ</strong> — E/A-, SMART-, Dateisystem-, ZFS-Pool- oder Verbindungsfehler.",
"<strong>Ursprüngliche Kernelmeldung</strong> aus dmesg zum Kopieren in eine Suchmaschine oder Supportanfrage.",
"<strong>Kurze Erklärung</strong> bekannter ATA-Codes: <code>IDNF</code>, Sektoradresse nicht gefunden, möglicher Sektor- oder Kabelfehler; <code>UNC</code>, nicht korrigierbarer Lesefehler, defekter Sektor; und weitere Standardcodes.",
"<strong>Erster und letzter Zeitpunkt</strong> sowie <strong>Anzahl der Vorkommen</strong>, gruppiert nach Fehlersignatur."
],
"obsWhyTitle": "Warum ProxMenux sie speichert und anzeigt",
"obsWhyItems": [
"<strong>Fehler können sich entwickeln.</strong> ATA-Busfehler, UNC-Sektoren oder Medienfehler können auftreten, bevor SMART <em>FAILED</em> meldet. Der dmesg-Puffer bewahrt sie nicht über Neustarts hinweg; der Beobachtungsverlauf schon.",
"<strong>SMART schließt nicht jeden Fehler aus.</strong> Ein Laufwerk kann grüne Attribute und trotzdem Probleme haben. Beobachtungen bewahren zusätzliche Symptome wie ICRC, IDNF, SATA-Verbindungsresets oder Geschwindigkeitsreduzierungen.",
"<strong>Trennt aktuell von kürzlich.</strong> Health Monitor löst vorübergehende Fehler automatisch, wenn sie nicht mehr auftreten. Der Verlauf zeigt noch Tage später beispielsweise drei E/A-Fehler einer Nacht.",
"<strong>Grundlage abgestufter Benachrichtigungen.</strong> disk_io verwendet die Beobachtungsrate der Tabelle für still, WARNING oder CRITICAL über das seit 1.2.1.2 gleitende 24-Stunden-Fenster."
],
"obsDedupTitle": "Duplikate und erneute Benachrichtigungen",
"obsDedupBody1": "Beobachtungen werden nach <strong>Signatur</strong> gruppiert, einem stabilen Fingerabdruck aus Fehlertyp, Gerät und wichtigen Meldungsfeldern. Wiederholungen erhöhen <code>occurrence_count</code> der vorhandenen Zeile. Eine <strong>andere Signatur</strong> erzeugt eine weitere Beobachtung und gilt für Benachrichtigungen als neues Ereignis.",
"obsDedupBody2": "Gegen Benachrichtigungskaskaden meldet die erste Kombination aus Laufwerk, Signatur und Schweregrad den Befund. Dieselbe Kombination meldet sich trotz steigender Anzahl erst nach 24 Stunden erneut. Ein Wechsel von WARNING zu CRITICAL unterbricht diese Wartezeit.",
"obsDismissTitle": "Dauerhafter Verlauf und aktive Fehler",
"obsDismissBody1": "Beobachtungen lassen sich nicht verwerfen, ausblenden oder löschen. Jede Signatur hat eine Karte; Wiederholungen erhöhen die Anzahl und aktualisieren den letzten Zeitpunkt. Der Verlauf folgt der Seriennummer: Ein anderes Laufwerk beginnt leer, auch am selben Port; eine Kernel-Umbenennung bewahrt seinen Verlauf.",
"obsDismissBody2": "Das Beheben oder Verwerfen eines aktiven Fehlers im Health Monitor verändert die Beobachtungen nicht. Sie bleiben nach automatischer Auflösung erhalten, sodass eine vorübergehende Warnung von letzter Woche heute sichtbar bleibt. Aktive Fehler verwalten Sie unter <link>Health Monitor</link>."
},
"dataCollected": {
"heading": "Wie die Daten gesammelt werden",
"headerSection": "Abschnitt des Reiters",
"headerEndpoint": "Endpunkt",
"headerSource": "Quelle",
"rows": [
{
"section": "Obere Übersichtskarten",
"endpoint": "/api/storage/summary",
"source": "Aggregiert aus <code>lsblk</code>, <code>zpool list</code>, <code>vgs</code> / <code>lvs</code>."
},
{
"section": "Inventar je Laufwerk",
"endpoint": "/api/storage",
"source": "<code>lsblk -O</code> + <code>smartctl -i</code> je Gerät mit Identitätscache, der bei Hotplug-Ereignissen geleert wird."
},
{
"section": "Proxmox-Speicher",
"endpoint": "/api/proxmox-storage",
"source": "<code>pvesh get /nodes/&lt;node&gt;/storage</code> mit dem aktiven / Online-Zustand von jedem."
},
{
"section": "Aktuelle SMART-Werte",
"endpoint": "/api/storage/smart/<disk>",
"source": "<code>smartctl -A &lt;dev&gt;</code> ist eine mögliche Abfrage; der Detail-Endpunkt verwendet auch vollständige SMART-JSON-Daten und NVMe-spezifische Werte."
},
{
"section": "SMART-Selbsttestverlauf",
"endpoint": "/api/storage/smart/<disk>/history",
"source": "Als JSON-Snapshots unter <code>/usr/local/share/proxmenux/smart/&lt;disk&gt;/</code> gespeichert."
},
{
"section": "Dauerhafte Beobachtungen",
"endpoint": "/api/storage/observations",
"source": "SQLite-Tabelle, die Health Monitor in jedem Zyklus aktualisiert und nach Auflösung aktiver Fehler beibehält."
}
],
"outro": "Überprüfung der Sammelkette auf dem Host:",
"codeComment1": "# Aktuellen Stand aus einem Skript abrufen",
"codeComment2": "# Dashboard-Daten mit der direkten Betriebssystemansicht vergleichen"
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "Gesundheitsmonitor",
"href": "/docs/monitor/health-monitor",
"tail": " — Kategorie Laufwerke und E/A sowie Unterdrückungsregeln."
},
{
"label": "API-Referenz",
"href": "/docs/monitor/api",
"tail": " — Speicher- und SMART-Endpunkte."
},
{
"label": "Benachrichtigungen",
"href": "/docs/monitor/notifications",
"tailRich": " — welche Folgeaktionen <code>disk_io_error</code>, <code>storage_unavailable</code> und <code>smart_test_failed</code> auslösen."
},
{
"label": "Dashboard-Index",
"href": "/docs/monitor/dashboard",
"tail": "Die anderen Tabs."
},
{
"label": "ProxMenux → Datenträgerverwaltung",
"href": "/docs/disk-manager",
"tail": " — TUI-Aktionen: Formatieren, Löschen, SMART-Tests und Laufwerke in VMs oder Container importieren."
},
{
"label": "ProxMenux → SMART-Laufwerkszustand und Tests",
"href": "/docs/disk-manager/smart-disk-test",
"tail": " — CLI-Entsprechung: SMART-Tests planen, das angezeigte JSON exportieren und Testtypen sowie Ergebnisinterpretation nachschlagen."
}
]
}
}
@@ -0,0 +1,120 @@
{
"meta": {
"title": "ProxMenux Monitor — Dashboard: Systemprotokolle | ProxMenux-Dokumentation",
"description": "Die Registerkarte Systemprotokolle konsolidiert drei Quellen in einem Bildschirm: journalctl mit Filtern und Download, Proxmox Task History (UPIDs) und Benachrichtigungsprotokoll - alle durchsuchbar, nach Schweregrad / Zeitbereich filterbar und als Textbündel herunterladbar."
},
"header": {
"title": "Dashboard: Systemprotokolle",
"description": "Drei Unterreiter in einer Ansicht: das Systemjournal (journalctl mit Filtern), der Proxmox-Aufgabenverlauf und das Benachrichtigungsprotokoll. Alle drei lassen sich durchsuchen, filtern und als Textpakete herunterladen.",
"section": "ProxMenux Monitor · Übersicht"
},
"readOnly": {
"title": "Read-only nach Design",
"body": "Dieser Reiter verändert keine Protokolldateien. Die Filter werden in der URL bzw. im Ansichtsstatus gehalten; Downloads werden auf dem Server erstellt. Das Dashboard löscht keine Einträge. Zur Protokollpflege verwenden Sie auf dem Host <code>journalctl --vacuum-time=&lt;N&gt;</code> oder <code>logrotate</code>."
},
"topRow": {
"heading": "Obere Reihe: vier Zähler",
"items": [
"<strong>Einträge insgesamt</strong> — Anzahl der Protokolleinträge im aktiven Filterzeitraum.",
"<strong>Fehler</strong> — Anzahl der Einträge mit Schweregrad ≤ 3 (<code>err</code> / <code>crit</code> / <code>alert</code> / <code>emerg</code>).",
"<strong>Warnungen</strong> — Anzahl der Einträge mit Schweregrad 4 (<code>warning</code>).",
"<strong>Sicherungen</strong> — Anzahl der vzdump-/PBS-Aufgabeneinträge im selben Zeitraum."
]
},
"subtabs": {
"heading": "Drei Unterreiter",
"logsTitle": "Protokolle",
"logsIntro": "Das Systemjournal wird auf dem Server mit <code>journalctl</code> abgerufen. Die Werkzeugleiste bietet folgende Filter :",
"logsFilters": [
"<strong>Schweregrad</strong> — emerg / alert / crit / err / warning / notice / info / debug oder eine beliebige Kombination.",
"<strong>Zeitbereich</strong> — zuletzt 5 min. / 15 min. / 1 h / 6 h / 24 h / 7 d / Custom.",
"<strong>Freitextsuche</strong> — Teilzeichenfolge oder regulärer Ausdruck (<code>journalctl --grep</code>).",
"<strong>Unit-Filter</strong> — auf eine bestimmte systemd-Unit beschränken (<code>pveproxy.service</code>, <code>nginx.service</code>, …)."
],
"logsRowsAfter": "Jede Zeile zeigt Zeitstempel, Schweregradabzeichen, Quelleinheit und die Nachricht. Lange Nachrichten brechen mit einem \"mehr anzeigen\"-Schalter zusammen. Die Aktion <strong>Download</strong> bündelt den aktuellen Filter über <code>GET /api/logs/download</code> in einer einzigen <code>.txt</code>-Datei – nützlich, wenn Sie ein Stück Journal mit jemandem teilen möchten.",
"logDetailsModalTitle": "Dialog Protokolldetails",
"logDetailsBody": "Ein Klick auf eine Zeile öffnet <strong>Protokolldetails</strong> mit allen strukturierten Feldern, die journald für diesen Eintrag erfasst hat — wie bei <code>journalctl --output=verbose</code> auf dem Host.",
"logDetailsImageAlt": "Dialog Protokolldetails — einzelner Journaleintrag mit Stufe, Dienst, Zeitstempel, Quelle, systemd-Unit, Prozess-ID, Hostname und vollständiger Nachricht",
"logDetailsImageCaption": "Protokolldetails — alle strukturierten journald-Felder dieses Eintrags mit der vollständigen, ungekürzten Nachricht am Ende. Hilfreich bei cron- und Dienstprotokollen, wenn die ausgeführte Befehlszeile wichtig ist.",
"fieldsIntro": "Gezeigte Felder:",
"fields": [
"<strong>Level</strong> — farbiges Schweregradabzeichen (INFO / WARNUNG / ERROR / KRITIKAL).",
"<strong>Service</strong> — Kurzname der Einheit / des Prozesses, der den Eintrag ausgegeben hat.",
"<strong>Timestamp</strong> — vollständiges Datum und Uhrzeit der Logzeile.",
"<strong>Source</strong> — Ursprung des Eintrags (Journal, Kernel, Audit, ...).",
"<strong>Systemd Unit</strong> — die tatsächliche <code>.service</code>/<code>.timer</code>/<code>.socket</code>-Einheit, wenn der Eintrag mit einer Einheit verknüpft war.",
"<strong>Process ID</strong> — PID des Sendevorgangs.",
"<strong>Hostname</strong> — nützlich, wenn Zeitschriften über Clusterknoten weitergeleitet werden.",
"<strong>Nachricht</strong> — vollständige, ungekürzte Nachricht in einem Monospace-Block zum Kopieren."
],
"maxLevelStoreTitle": "Journald MaxLevelStore",
"maxLevelStoreBody": "Bei einer neuen Proxmox-Installation verwendet journald standardmäßig <code>MaxLevelStore=warning</code> und verwirft dadurch Info-Meldungen. Monitor erkennt dies beim Start und ergänzt eine Drop-in-Datei (<code>/etc/systemd/journald.conf.d/proxmenux-loglevel.conf</code>) mit dem Grenzwert <code>info</code>. So werden Informationsmeldungen und schwerwiegendere Meldungen gespeichert; debug ist darin nicht enthalten.",
"backupsTitle": "Sicherungen",
"backupsBody": "Proxmox-Taskhistorie gefiltert auf Backup-bezogene Einträge. Eine Zeile pro Aufgabe (<code>vzdump</code>, PBS-Transfers, Garbage Collect, Verify) mit dem Status (OK / WARNINGS / ERROR), beteiligter Gast, Quellspeicher, Dauer und UPID. Klicken Sie auf eine Zeile, um das vollständige Aufgabenprotokoll über <code>GET /api/task-log/&lt;upid&gt;</code> zu laden - die gleichen Daten, die Proxmox über <em>Datacenter → Tasks</em>, die auf Backups beschränkt sind, freigibt.",
"notificationsTitle": "Benachrichtigungen",
"notificationsBody1": "Alle von Monitor versendeten Benachrichtigungen: Telegram, Discord, E-Mail, Gotify, ntfy, Slack, Teams und Webhook. Jede Zeile zeigt Zeitstempel, Kanal, Ereignistyp, Schweregrad, erzeugten Titel und Nachrichtentext sowie bei aktivierter KI einen Schalter zum Vergleich der KI-Fassung mit dem Original.",
"notificationsBody2": "Hier prüfen Sie, ob ein Kanal tatsächlich Nachrichten zustellt, und vergleichen die KI-Fassung mit der ursprünglichen Vorlage. Die Kanäle konfigurieren Sie auf der Detailseite <link>Benachrichtigungen</link>."
},
"dataCollected": {
"heading": "Wie die Daten gesammelt werden",
"headerSubtab": "Unterregisterkarte",
"headerEndpoint": "Endpunkt",
"headerSource": "Quelle",
"rows": [
{
"subtab": "Protokolle (Live-Filter)",
"endpoint": "/api/logs",
"source": "<code>journalctl --output json --since &lt;range&gt;</code> mit serverseitigen Filtern für Schweregrad, Unit und Suche."
},
{
"subtab": "Herunterladen",
"endpoint": "/api/logs/download",
"source": "Dieselbe Abfrage als Klartext für grep / less."
},
{
"subtab": "Sicherungen",
"endpoint": "/api/backups",
"source": "PVE-Taskhistorie gefiltert nach <code>vzdump</code>, PBS-Transfers, Garbage Collect, Verify."
},
{
"subtab": "Details einer Sicherungsaufgabe",
"endpoint": "/api/task-log/&lt;upid&gt;",
"source": "Vollständiges Aufgabenprotokoll im Klartext aus <code>/var/log/pve/tasks/&lt;index&gt;/&lt;upid&gt;</code>."
},
{
"subtab": "Meldeverlauf",
"endpoint": "/api/notifications/history",
"source": "Die SQLite-Tabelle <code>notification_history</code> wird von der Versandschleife gefüllt."
}
],
"apiIntro": "Live-Filter und Downloads sind auch über die API erreichbar:",
"codeComment1": "# Fehler und schwerwiegendere Meldungen der letzten Stunde mit einem Suchwort",
"codeComment2": "# Laden Sie das vollständige Journal der letzten 6 Stunden als Klartext herunter",
"codeComment3": "# Vollständige Ausgabe einer bestimmten Aufgabe anhand ihrer UPID abrufen"
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "Gesundheitsmonitor",
"href": "/docs/monitor/health-monitor",
"tail": " — die Kategorie Systemprotokolle zur Erkennung dauerhafter, sprunghafter oder kaskadierender Muster."
},
{
"label": "Benachrichtigungen",
"href": "/docs/monitor/notifications",
"tail": " — die Journalüberwachung liest dieselbe Quelle und erzeugt bei Treffern Benachrichtigungen."
},
{
"label": "API-Referenz",
"href": "/docs/monitor/api",
"tail": " — die Endpunkte logs und task-log mit ihren Abfrageparametern."
},
{
"label": "Dashboard-Index",
"href": "/docs/monitor/dashboard",
"tail": " — die anderen Reiter."
}
]
}
}
@@ -0,0 +1,177 @@
{
"meta": {
"title": "ProxMenux Monitor — Dashboard: Systemübersicht | ProxMenux-Dokumentation",
"description": "Der Standardstartreiter von ProxMenux Monitor: vier Kennzahlenkarten (CPU, Arbeitsspeicher, aktive VMs und LXCs, Temperatur) mit Live-Aktualisierung und Minidiagramm, ein Verlaufsdiagramm und kompakte Speicher- und Netzwerkübersichten mit Links zu ihren Detailreitern."
},
"header": {
"title": "Dashboard: Registerkarte Systemübersicht",
"description": "Der Reiter, den das Dashboard standardmäßig öffnet: vier Live-Kennzahlenkarten oben, ein Verlaufsdiagramm in der Mitte und kompakte Speicher- und Netzwerkübersichten unten. Sie verwenden dieselben APIs wie die jeweiligen Detailreiter.",
"section": "ProxMenux Monitor · Übersicht"
},
"readOnly": {
"title": "Eine schreibgeschützte Momentaufnahme",
"body": "Alle Bereiche dieses Reiters dienen der Information. Aktionen finden Sie in den verlinkten Detailreitern: Speicher zur Datenträgerverwaltung, VMs und LXCs zum Starten und Stoppen von Gästen sowie Sicherheit zur Authentifizierung."
},
"captureAlt": "Registerkarte Systemübersicht — vier metrische Karten (CPU, Speicher, aktive VMs, Temperatur), Knotenmetrikdiagramm und Speicher- / Netzwerkzusammenfassungskarten",
"captureCaption": "Systemübersicht, der Standardstartreiter. Die vier Karten zeigen Live-Werte, das Diagramm zeigt den Verlauf und die beiden unteren Karten fassen Speicher und Netzwerk zusammen.",
"topRow": {
"heading": "Obere Reihe: Live-Kennzahlenkarten",
"intro": "Vier Karten im 2×2-Raster auf Mobilgeräten und in einer Reihe auf dem Desktop. Jede wird alle paar Sekunden über <code>/api/system</code> aktualisiert.",
"headerCard": "Karte",
"headerWhat": "Was es zeigt",
"headerSource": "Quelle",
"rows": [
{
"card": "CPU-Auslastung",
"what": "Aktueller Prozentsatz mit Fortschrittsbalken. Der Vitaldaten-Sampler aktualisiert ihn etwa jede Sekunde.",
"source": "psutil.cpu_percent()"
},
{
"card": "Arbeitsspeichernutzung",
"what": "Belegte GB, Prozentsatz und Gesamt-GB. Der Balken zeigt den Prozentsatz.",
"source": "psutil.virtual_memory()"
},
{
"card": "Aktive VM und LXC",
"what": "Anzahl laufender Gäste mit Aufschlüsselung nach Laufend/Gestoppt und Gesamtzahlen der VMs und LXCs in der Fußzeile.",
"source": "/api/vms (konsolidiert)"
},
{
"card": "Temperatur",
"what": "CPU-Temperatur in °C mit Statusanzeige (kühl/warm/heiß) und einem Minidiagramm der letzten 5 Minuten im Hintergrund. Ohne Sensor erscheint <em>N/A</em>. Ein Klick öffnet die Temperaturdetails.",
"source": "sensors / coretemp"
}
],
"thresholdsTitle": "Hier angewendete Statusfarben und -schwellen",
"thresholdsIntro": "Ringe, Balken und Minidiagramme verwenden dieselbe Einteilung: <green/> <strong>grün</strong> unter der Warnschwelle, <amber/> <strong>bernsteinfarben</strong> zwischen Warn- und kritischer Schwelle, <red/> <strong>rot</strong> ab der kritischen Schwelle. Empfohlene Standardwerte von ProxMenux :",
"thresholdsItems": [
"<strong>CPU-Auslastung</strong> — Warnung 85 %, kritisch 95 %.",
"<strong>Arbeitsspeicher</strong> — Warnung 85 %, kritisch 95 %. Swap löst ebenfalls ab 5 % Nutzung den kritischen Zustand aus; ein gesunder Proxmox-Host sollte Swap nur selten verwenden.",
"<strong>CPU-Temperatur</strong> — Warnung 80 °C, kritisch 90 °C."
],
"thresholdsOutro": "Alle Werte sind pro Host konfigurierbar. <link>Einstellungen → Grenzwerte der Zustandsüberwachung</link> ist die zentrale Referenz und erklärt ihre Anpassung.",
"sparklineTitle": "Das Minidiagramm zeigt den Verlauf",
"sparklineBody": "Die Temperaturkarte zeichnet eine 5-Minuten-Spur unter dem Wert, wobei die Linie und die Farbverlaufsfarbe dem gleichen Warning/Critical-Paar folgen, das oben dokumentiert ist. Es ist der schnellste Weg, um zu sehen, ob der Host in einem thermischen Aufstieg ist, ohne das Detail Modal zu öffnen."
},
"processes": {
"heading": "Prozesse mit der höchsten CPU- und Arbeitsspeichernutzung",
"intro": "Die Karten CPU-Auslastung und Arbeitsspeicher öffnen eine sortierbare Liste der 25 führenden Prozesse: nach CPU-Auslastung beim Öffnen über CPU, nach residentem Speicher beim Öffnen über Arbeitsspeicher.",
"listTitle": "Der Listendialog",
"listItems": [
"<strong>Automatische Aktualisierung</strong> — die Liste wird bei geöffnetem Dialog alle 5 Sekunden aktualisiert. Beim Schließen enden die Abfragen.",
"<strong>Filter</strong> — das Suchfeld grenzt die Liste nach Befehl, Benutzer oder PID ein.",
"<strong>Inline bar</strong> — die primäre metrische Spalte zeichnet einen kleinen Balken, der auf den höchsten Wert in der gefilterten Liste skaliert ist, so dass das Ranking auch dann sichtbar bleibt, wenn kein Prozess in der Nähe von 100 % liegt.",
"<strong>Mobiles Layout</strong> — unter 640 px werden PID und Benutzer ausgeblendet. Befehl, CPU % und Arbeitsspeicher passen so ohne horizontales Scrollen auf den Telefonbildschirm."
],
"captureListAlt": "Dialog Prozesse nach Arbeitsspeichernutzung — nach RSS sortierte Tabelle mit PID, Benutzer, Befehl, CPU % und Arbeitsspeicher",
"captureListCaption": "Die Speicherkarte öffnet die nach RSS (indigo accent) sortierte Liste. Die CPU-Karte öffnet die gleiche Liste, sortiert nach CPU-Nutzung (blauer Akzent).",
"detailTitle": "Angaben zu den einzelnen Prozessen",
"detailIntro": "Ein Klick auf eine Zeile öffnet einen zweiten Dialog mit Live-Daten dieses Prozesses in vier Abschnitten :",
"detailItems": [
"<strong>Übersicht</strong> — Zustand, Elternprozess, Threadanzahl, offene Dateideskriptoren, Benutzer und Gruppe.",
"<strong>Ressourcen</strong> — CPU %, Arbeitsspeicher %, residenter Speicher (RSS), virtuelle Größe, Swap und gesamte gelesene/geschriebene I/O-Daten.",
"<strong>Befehl</strong> — Kurzname, vollständige Befehlszeile, Pfad der ausführbaren Datei und Arbeitsverzeichnis.",
"<strong>Laufzeit</strong> — Startzeitpunkt und bisherige Laufzeit."
],
"detailRefresh": "Der Detaildialog wird alle 3 Sekunden aktualisiert. Endet der Prozess, stoppen die Abfragen und der bernsteinfarbene Hinweis <em>Dieser Prozess wurde beendet</em> erscheint. Die letzte erfasste Ansicht bleibt abgeblendet sichtbar und zeigt den Zustand vor dem Ende.",
"captureDetailAlt": "Prozessdetaildialog — Übersicht, Ressourcen, Befehl und Laufzeit für eine PID",
"captureDetailCaption": "Pro-Prozess-Detaildialog geöffnet von einer Listenzeile. Die Akzentfarbe stimmt mit der Karte überein, die sie geöffnet hat (blau für CPU, indigo für Memory)."
},
"middle": {
"heading": "Mitte: Knotenmetrikdiagramme",
"body1": "Unter den Karten zeigt <code>NodeMetricsCharts</code> CPU-, Arbeitsspeicher- und Datenträger-I/O-Verläufe aus dem RRD-Speicher von Proxmox über <code>/api/node/metrics</code>. Wählbar sind <em>1 Stunde / 24 Stunden / 7 Tage / 30 Tage / 1 Jahr</em>. Bei größeren Zeiträumen sinkt die Datenauflösung, damit die Anzeige flüssig bleibt.",
"body2": "Dies sind die gleichen Graphen, die die Proxmox-Web-Benutzeroberfläche für einen Knoten darstellt, nur in das dunkle Thema des Monitors konsolidiert und mit den anderen Panels ausgerichtet."
},
"bottom": {
"heading": "Untere Reihe: Speicher- und Netzwerkübersichten",
"storageTitle": "Speicherübersichtskarte",
"storageIntro": "Eine verdichtete Ansicht des Speicherzustands des Hosts, unterteilt in drei Blöcke:",
"storageItems": [
"<strong>Gesamtkapazität des Knotens</strong> — Summe aller VM-/LXC-Speicher und des lokalen Systemspeichers mit einem Verlaufsbalken für belegten und freien Platz.",
"<strong>Gesamtkapazität / Physische Datenträger</strong> — Rohkapazität und Anzahl der erkannten physischen Datenträger.",
"<strong>VM-/LXC-Speicher</strong> — belegter und freier Platz sowie Prozentsatz der Gastspeicher, ergänzt um deren Anzahl bei mehreren Speichern.",
"<strong>Lokaler Speicher (System)</strong> — Root-/Systemeinhängepunkt des Hosts, getrennt vom Gastpool."
],
"storageDrillIn": "Details finden Sie im <link>Reiter Speicher</link>: SMART pro Datenträger, ZFS-Pools, Beobachtungsverlauf usw.",
"networkTitle": "Netzwerkübersichtskarte",
"networkBody1": "Die obere Zeile zeigt die Anzahl der aktiven Schnittstellen (physisch + Brücken kombiniert). Darunter befinden sich zwei Reihen farbiger Abzeichen für die Schnittstellen <code>up</code> — physische NICs in blau, Brücken in einer Sekundärfarbe. Ein Zeitrahmen-Selektor oben rechts (1 Stunde / 24 Stunden / 7 Tage / 30 Tage / 1 Jahr) steuert ein kleines RX / TX-Verkehrsdiagramm.",
"networkBody2": "Details pro Schnittstelle (IP/MAC, RRD-Diagramm, Bridge-Mitglieder, Bond-Modus usw.) stehen im <link>Reiter Netzwerk</link>."
},
"refresh": {
"heading": "Aktualisierungsmodell",
"intro": "Jeder Bereich verwaltet seinen Ladezustand (<code>loadingStates.cpu</code>, <code>loadingStates.storage</code>, …), damit eine langsame Quelle die anderen nicht blockiert. Beim Laden erscheint ein pulsierender Platzhalter. Fehler werden abgefangen; ohne Temperatursensor zeigt die Karte etwa <em>N/A</em> statt eines Fehlers.",
"items": [
"<strong>Obere Kennzahlenkarten</strong> — Aktualisierung etwa alle 5 Sekunden. CPU und Temperatur erhalten zusätzlich jede Sekunde Daten vom Vitaldaten-Sampler.",
"<strong>Knotenmetrikdiagramm</strong> — lädt beim Öffnen sowie bei Änderung von Zeitraum oder Sprache. Erforderliche Wiederholungsversuche erfolgen nach 60 Sekunden.",
"<strong>Speicherkarte</strong> — Aktualisierung etwa alle 60 Sekunden. SMART-Daten bleiben länger im Cache; der Speicherreiter fordert bei Bedarf eine neue Abfrage an.",
"<strong>Netzwerkkarte</strong> — Zusammenfassung alle 59 Sekunden und Verkehrsdiagramm alle 60 Sekunden für den gewählten Zeitraum.",
"<strong>Manuell aktualisieren</strong> — die Schaltfläche Aktualisieren im Kopf lädt alle Bereiche sofort neu."
]
},
"dataCollected": {
"heading": "Wie die Daten gesammelt werden",
"headerCard": "Karte",
"headerEndpoint": "Endpunkt",
"headerSource": "Quelle",
"rows": [
{
"card": "Statusanzeige im Kopf",
"endpoint": "/api/health",
"source": "Der zwischengespeicherte Gesamtstatus, der vom Health Monitor in jedem Zyklus erzeugt wird."
},
{
"card": "CPU / RAM / Swap / Betriebszeit",
"endpoint": "/api/system",
"source": "<code>/proc/stat</code>, <code>/proc/meminfo</code>, <code>/proc/uptime</code> mit Kurzfenster-CPU-Probenahme."
},
{
"card": "Host-Info (Kernel, BIOS, Distro)",
"endpoint": "/api/info",
"source": "<code>uname -a</code>, <code>dmidecode</code>, PVE-Version. Pro Prozess zwischengespeichert."
},
{
"card": "Speicher / Netzwerk / VMs Karten",
"endpoint": "/api/storage/summary, /api/network/summary, /api/vms",
"source": "Siehe die dedizierten Tabs für jeden. Die Kopfkarten zeigen eine verdichtete Ansicht von den gleichen Endpunkten."
},
{
"card": "Aktualisierungsintervall",
"endpoint": "—",
"source": "Systemdaten alle 5 Sekunden; Speicher, VMs und Netzwerkzusammenfassung alle 59 Sekunden. Aktualisieren im Kopf lädt alle Bereiche sofort neu."
}
],
"codeComment1": "# Aufruf für die Statusanzeige im Kopf",
"codeComment2": "# öffentlich, kein Token",
"codeComment3": "# Authentifizierter Snapshot, der von den Karten verwendet wird"
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "Gesundheitsmonitor",
"href": "/docs/monitor/health-monitor",
"tail": " — der Dialog hinter der Statusanzeige im Kopf: zehn Kategorien sowie Ausblenden und Unterdrücken von Meldungen."
},
{
"label": "API-Referenz",
"href": "/docs/monitor/api",
"tail": " — die Endpunkte system, info und health."
},
{
"label": "Benachrichtigungen",
"href": "/docs/monitor/notifications",
"tail": "— wie sich die gleichen Status in Telegram / Discord / E-Mail-Nachrichten verwandeln."
},
{
"label": "Dashboard-Index",
"href": "/docs/monitor/dashboard",
"tail": " — die übrigen Dashboard-Reiter auf einen Blick."
},
{
"label": "Architektur",
"href": "/docs/monitor/architecture",
"tail": " — die Hintergrundthreads und APIs hinter dieser Ansicht."
}
]
}
}
@@ -0,0 +1,174 @@
{
"meta": {
"title": "ProxMenux Monitor — Dashboard: Terminal | ProxMenux-Dokumentation",
"description": "Browser-Shell auf dem Proxmox-Host: bis zu 4 Terminals in Rasteransicht, Tastaturhilfen für Mobilgeräte (ESC, TAB, Pfeile, Ctrl-Kombinationen), integrierte Befehlsübersicht mit cheat.sh und JWT-Schutz."
},
"header": {
"title": "Dashboard: Terminal Tab",
"description": "Eine echte Shell-Sitzung auf dem Proxmox-Host im Browser: bis zu vier Terminals gleichzeitig, Tastaturhilfen für Mobilgeräte und eine integrierte Befehlsübersicht im selben Design wie das übrige Dashboard.",
"section": "ProxMenux Monitor · Übersicht"
},
"intro": {
"title": "Ein echter PTY im Browser",
"body": "Das Terminal legt über <code>flask_terminal_routes</code> eine serverseitige PTY an, verbindet sie per WebSocket mit <code>xterm.js</code> im Browser und läuft als <code>root</code>, dem Benutzer der systemd-Unit. Wie bei <code>ssh root@&lt;host&gt;</code> stehen <code>vim</code>, <code>tmux</code>, ncurses-Werkzeuge und die Proxmox-CLIs (<code>qm</code>, <code>pct</code>, <code>pvesh</code>, <code>pvecm</code>) zur Verfügung. Jede PTY exportiert <code>PROXMENUX_TERMINAL=monitor</code>. Alle untergeordneten <code>bash</code>-Prozesse, auch ein späterer Start von <code>menu</code>, erben die Variable, damit ProxMenux den Browserterminal-Kontext erkennt."
},
"singleAlt": "ProxMenux Monitor Terminal Registerkarte — Einzelterminalsitzung mit Fastfetch-Systemzusammenfassung beim Login",
"singleCaption": "Ein Host-Terminal offen — die obige Symbolleiste zeigt die Anzahl (<em>1 / 4 Terminals</em>), <em> + New</em>, <em>Search</em>, <em>Clear</em> und <em>Close</em>. Die mobilen Tastaturhelfer erscheinen unter dem Terminal auf Touch-Geräten.",
"target": {
"heading": "Verbindungsziel",
"body1": "Die Registerkarte Terminal öffnet eine Shell auf dem <strong>Proxmox-Host selbst</strong> - die gleiche Anmeldung, die Sie über SSH erhalten würden. Jeder Tab öffnet ein brandneues Host-Terminal.",
"body2": "Um einen <strong>LXC-Container</strong> aus dem Browser zu erreichen, verwenden Sie die dedizierte <em>Console</em>-Taste auf jeder laufenden CT-Karte in der <link>VMs & LXCs tab</link>. Es öffnet ein Modal, auf dem <code>pct enter &lt;vmid&gt;</code> ausgeführt wird, und verwendet die gleiche mobilfreundliche Symbolleiste, die unten beschrieben wird."
},
"menuGuard": {
"heading": "Schutz bei der Selbstaktualisierung von menu in diesem Terminal",
"body1": "Bei der Selbstaktualisierung ersetzt <code>menu</code> nach Bestätigung seinen Skriptbaum und lädt sich neu. Über SSH oder die Proxmox-Konsole funktioniert das, im Browser würde dabei jedoch die PTY der Shell beendet und der WebSocket getrennt. Deshalb lesen <code>check_updates_stable</code>, <code>check_updates_beta</code> und <code>apply_release_channel</code> die Variable <code>PROXMENUX_TERMINAL</code> und erkennen den Monitor-Kontext.",
"body2": "Dann wird der Ja/Nein-Dialog durch einen Hinweis mit dem offiziellen Installationsbefehl ersetzt: <code>bash -c \"$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)\"</code> für Stable bzw. die entsprechende URL mit <code>install_proxmenux_beta.sh</code> für Beta. Die Aktualisierung wird über SSH oder die Proxmox-Hostkonsole ausgeführt; im Browserterminal lesen und bestätigen Sie nur den Hinweis."
},
"fourTerminals": {
"heading": "Bis zu vier Terminals gleichzeitig",
"intro": "Mit der Registerkarte können Sie bis zu vier Host-Terminals gleichzeitig öffnen. Jeder bekommt seinen eigenen PTY und seinen eigenen WebSocket - es sind völlig unabhängige Sitzungen. Zwei Layouts wechseln mit den Icons neben der Schaltfläche \"Neu\":",
"items": [
"<strong>Reiteransicht</strong> — ein sichtbares Terminal, die übrigen als benannte Reiter oben (<em>Terminal 1</em>, <em>Terminal 2</em>…). Gut für eine Aufgabe, während die anderen im Hintergrund laufen.",
"<strong>Rasteransicht</strong> — alle offenen Terminals gleichzeitig in einem 2×2-Raster. So können Sie <code>htop</code> und <code>iftop</code> beobachten und im dritten Terminal bearbeiten, ohne die Ansicht zu wechseln."
],
"outro": "Die Werkzeugleiste zeigt die Anzahl (<em>1/4 Terminals</em>, <em>4/4 Terminals</em>). <strong>+ Neu</strong> öffnet einen Reiter, das kleine <code>×</code> in dessen Kopf schließt ihn. Die große rote Schaltfläche <strong>Schließen</strong> oben beendet alle Terminals."
},
"gridAlt": "ProxMenux Monitor Terminal Registerkarte — Rasteransicht mit vier Host-Terminals mit ls, Netzwerkkonfiguration, iftop und ProxMenux Hauptmenü nebeneinander",
"gridCaption": "Rasteransicht (4 / 4 Terminals) — vier unabhängige Host-PTYs parallel mit Verzeichnisliste, <code>/etc/network/interfaces</code>, <code>iftop</code> und ProxMenux-Hauptmenü. Der Layout-Schalter in der Werkzeugleiste wechselt zwischen Raster und Reitern.",
"keyboard": {
"heading": "Tastaturhilfen für Mobilgeräte",
"intro": "Telefon- und Tablet-Tastaturen bieten meist kein ESC, TAB, keine Pfeiltasten oder Tastenkombinationen mit Modifikatoren. Diese werden für <code>vim</code>, <code>nano</code>, <code>htop</code> und TUI-Menüs benötigt. Der Terminalreiter zeigt daher auf kleinen oder berührungsempfindlichen Geräten eine Reihe von Touch-Schaltflächen darunter an :",
"headerButton": "Schaltfläche",
"headerSends": "Sendet",
"headerUse": "Typische Verwendung",
"rows": [
{
"button": "ESC",
"sends": "\\x1b",
"use": "Einfügemodus in <code>vim</code> verlassen, einen TUI-Dialog abbrechen, eine Suche beenden."
},
{
"button": "TAB",
"sends": "\\t",
"use": "Pfadvervollständigung und Feldnavigation in dialog/whiptail."
},
{
"button": "↑ ↓ ← →",
"sends": "\\x1bO[ABCD]",
"use": "Shell-Historie, Cursorbewegung, Menünavigation."
},
{
"button": "↵ Eingabetaste",
"sends": "\\r",
"use": "Bestätigen. Manche Bildschirmtastaturen ersetzen Enter durch Los/Fertig; diese Schaltfläche ist eindeutig."
},
{
"button": "Ctrl ▾",
"sends": "Auswahlliste",
"useRich": true
}
],
"ctrlIntro": "Drei Kontrollsequenzen:",
"ctrlItems": [
"<code>Ctrl+C</code> — laufenden Befehl abbrechen oder unterbrechen (<code>\\x03</code>).",
"<code>Ctrl+X</code> — <code>nano</code> beenden (<code>\\x18</code>).",
"<code>Ctrl+R</code> — Rückwärtssuche im bash-Verlauf (<code>\\x12</code>)."
],
"modalTitle": "Dieselbe Werkzeugleiste im LXC-Konsolendialog",
"modalBody": "Die über <link>VMs und LXCs → Konsole</link> gestartete Containerkonsole zeigt dieselben Tastaturhilfen unter dem Dialog. Beim Verbinden gibt sie automatisch <code>pct enter &lt;vmid&gt;</code> ein, sodass Sie direkt im Container landen."
},
"lxcAlt": "ProxMenux Monitor — LXC-Konsolendialog, Terminal: ubuntu (ID: 103), mit derselben mobilen Werkzeugleiste (ESC, TAB, Pfeile, Enter, Ctrl) darunter",
"lxcCaption": "LXC-Konsolendialog, geöffnet über <em>VMs und LXCs → Konsole</em>. Der Kopf zeigt den Zielcontainer (<em>Terminal: ubuntu (ID: 103)</em>), darunter erscheint dieselbe Touch-Werkzeugleiste.",
"search": {
"heading": "Befehle suchen — integrierte Kurzübersicht",
"intro": "Die blaue Schaltfläche <strong>Suchen</strong> öffnet eine fehlertolerante Befehlssuche. Geben Sie einige Buchstaben eines Linux- oder Proxmox-Befehls (<code>ls</code>, <code>tar</code>, <code>qm</code>, <code>pct</code>, <code>zpool</code>, <code>systemctl</code>…) ein. Der Dialog zeigt Beispiele mit <em>An aktives Terminal senden</em>. So müssen Sie zur Suche nach einer Option keinen anderen Browserreiter öffnen.",
"modalAlt": "ProxMenux Monitor — Dialog Befehle suchen mit fehlertoleranter Suche nach Linux- und Proxmox-Befehlen über cheat.sh und mehreren ls-Beispielen",
"modalCaption": "Befehlssuche nach <code>ls</code> — jedes Ergebnis zeigt Befehl, Beschreibung und einen kleinen Sendepfeil zum aktiven Terminal. Unten rechts steht die Datenquelle (<em>Bereitgestellt von cheat.sh</em>).",
"aboutLabel": "Über cheat.sh:",
"aboutBody": "ist eine quelloffene, von der Community gepflegte Kurzübersicht mit kurzen Praxisbeispielen für Hunderte von Linux-Befehlen, Administrationswerkzeugen und Programmiersprachen. Ursprünglich für <code>curl cheat.sh/&lt;command&gt;</code> im Terminal entwickelt, ist sie auch im Browser erreichbar. ProxMenux Monitor leitet die Abfragen serverseitig weiter, damit der Dialog denselben Ursprung wie das Dashboard verwendet.",
"headerSource": "Quelle",
"headerWhen": "Wenn es verwendet wird",
"headerWhat": "Was du siehst",
"onlineLabel": "(online)",
"onlineWhen": "Wenn der Host einen Internetzugang hat und der cheat.sh-Proxy antwortet.",
"onlineWhat": "Mehrere Praxisbeispiele pro Befehl mit einer Beschreibung darüber. Der Statuspunkt im Dialogkopf ist <green>grün</green>.",
"fallbackLabel": "Lokale Ersatzliste",
"fallbackWhen": "Wenn cheat.sh nicht erreichbar ist (Offline-Host, restriktive Firewall, cheat.sh-Ausfall).",
"fallbackWhat": "Eine mitgelieferte Liste gängiger Linux- und Proxmox-Befehle. Kleinerer Katalog, aber immer verfügbar. Der Statuspunkt ist <red>rot</red>.",
"sendingNote": "<strong>So funktioniert das Senden</strong>: Der kleine Pfeil neben dem Ergebnis sendet den Befehlstext an das aktive Terminal: den gewählten Reiter oder das zuletzt angeklickte Terminal im Raster. Der Dialog schließt sich automatisch, sodass Sie direkt Enter drücken können."
},
"auth": {
"heading": "Authentifizierung",
"items": [
"Der Browser fordert zunächst über <code>POST /api/terminal/ticket</code> mit JWT im <code>Authorization</code>-Header ein Einmalticket an. Dieses wird beim Öffnen des WebSockets übergeben und läuft nach 5 Sekunden ab. Bei aktivierter Authentifizierung wird eine Verbindung ohne gültiges Ticket geschlossen, bevor eine PTY angelegt wird.",
"Bei einem Reverse Proxy muss dieser WebSocket-Upgrades weiterleiten. Beispiele für Nginx / Caddy / Traefik stehen unter <link>Zugriff und Authentifizierung</link>."
]
},
"clipboard": {
"heading": "Zwischenablage, Scrollback und Größenänderung",
"items": [
"<strong>Kopieren und Einfügen</strong> — über die Zwischenablage des Browsers. Text mit Maus oder Trackpad auswählen und das Systemtastenkürzel verwenden (<code>Cmd+C</code> unter macOS, <code>Ctrl+Shift+C</code> unter Linux/Windows). Linux-Desktops unterstützen auch Einfügen per Mittelklick.",
"<strong>Scrollback</strong> — mit Mausrad oder Zwei-Finger-Geste blättern. xterm.js hält die letzten mehreren Tausend Zeilen im Speicher.",
"<strong>Größe ändern</strong> — bei einer Größenänderung des Dashboardbereichs wird die PTY-Fenstergröße angepasst, damit <code>htop</code> und <code>vim</code> korrekt dargestellt werden.",
"<strong>Wiederverbinden beim Zurückkehren</strong> — ein App-Wechsel auf Telefon oder Tablet, etwa dem iPad, kann den WebSocket trennen. Der Terminalreiter erkennt die Sichtbarkeitsänderung und verbindet sich beim Zurückkehren automatisch neu, mit 15 Sekunden Zeitlimit für langsame VPN-Verbindungen."
]
},
"disconnect": {
"heading": "Ursachen für Verbindungsabbrüche",
"intro": "Die häufigsten Gründe, warum eine Sitzung endet und was mit jedem zu tun ist:",
"headerCause": "Ursache",
"headerFix": "Lösung",
"rows": [
{
"cause": "Sitzungs-JWT beim Öffnen oder Wiederverbinden abgelaufen (24 Stunden).",
"fix": "Aktualisieren Sie die Seite und melden Sie sich erneut an. Das Terminal ist nicht für unbeaufsichtigte Sitzungen konzipiert, so dass die JWT-Lebensdauer dem regulären Dashboard-Login entspricht."
},
{
"cause": "Inaktivitätszeitlimit des Reverse Proxys.",
"fix": "Erhöhen Sie <code>proxy_read_timeout</code> in Nginx oder den entsprechenden Wert in Caddy / Traefik (Beispiele unter Zugriff und Authentifizierung)."
},
{
"cause": "Telefon oder Tablet im Ruhezustand.",
"fix": "Beim Aufwecken des Geräts verbindet sich der Reiter automatisch neu (15 Sekunden Zeitlimit für VPN-Verbindungen). Falls nicht, laden Sie ihn neu."
},
{
"cause": "Service-Neustart auf dem Host.",
"fix": "Jeder Neustart von <code>proxmenux-monitor.service</code> beendet alle PTYs. Öffnen Sie neue Terminals, sobald das Dashboard fertig geladen ist."
}
]
},
"warning": {
"title": "Das Terminal ist eine Root-Shell auf dem Host",
"body": "Das Terminal übernimmt den Benutzer der systemd-Unit (<code>root</code>) und hat volle Rechte auf dem Proxmox-Host. Konfigurieren Sie Benutzername, Passwort und 2FA unter <authLink>Zugriff und Authentifizierung</authLink>, bevor Sie Zugriffe außerhalb des lokalen Netzes erlauben. Bei deaktivierter Authentifizierung kann jeder mit Zugriff auf Port 8008 ohne weitere Rückfragen oder SSH-Zugangsdaten eine Root-Shell öffnen. Nutzen Sie extern <gatewayLink>Secure Gateway</gatewayLink> (Tailscale) oder einen HTTPS-Reverse-Proxy, statt den Port im Internet freizugeben."
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "Zugriff und Authentifizierung",
"href": "/docs/monitor/access-auth",
"tail": " — Reverse-Proxy-Beispiele mit den für das Terminal erforderlichen WebSocket-Upgrade-Zeilen."
},
{
"label": "Architektur",
"href": "/docs/monitor/architecture",
"tail": " — WebSocket-Transport (HTTP über flask-sock bzw. HTTPS / WSS über gevent)."
},
{
"label": "API-Referenz",
"href": "/docs/monitor/api",
"tail": " — die WebSocket-Endpunkte /ws/terminal und /ws/script/<sid> neben der übrigen API."
},
{
"label": "Integrationen → Secure Gateway",
"href": "/docs/monitor/integrations",
"tail": "- wenn Sie einen Terminalzugriff von außerhalb des LAN wünschen, ohne den Port 8008 freizulegen."
},
{
"label": "Dashboard-Index",
"href": "/docs/monitor/dashboard",
"tail": " — die anderen Reiter."
}
]
}
}
@@ -0,0 +1,245 @@
{
"meta": {
"title": "LXC-App-Reiter: Erkennung, Links und Versionsverfolgung | ProxMenux",
"description": "Entdecken und registrieren Sie LXC-Anwendungen, erstellen Sie Weblinks und verfolgen Sie optional installierte und verfügbare Versionen."
},
"header": {
"title": "LXC-App-Reiter: Erkennung, Links und Versionsverfolgung",
"description": "Geben Sie jeder LXC-Anwendung eine dauerhafte Identität, einen Webzugang und einen optionalen Versionsnachweis, ohne die Registrierung an Updates zu koppeln."
},
"intro": {
"p1": "Die Registerkarte <strong>App</strong> zeichnet auf, welche Anwendungen zu einer LXC gehören. Eine Registrierung kann nur einen Namen und einen Weblink enthalten oder auch einen Detektor für installierte Versionen und eine Upstream-Quelle enthalten.",
"p2": "Das Verfahren zur Softwareänderung wird separat im <link>Reiter Aktualisierungen</link> konfiguriert. Das Speichern einer App startet niemals einen Installer oder Updater.",
"callout": "Registrierung, Versionsverfolgung und Aktualisierung sind drei unabhängige Funktionen. Jeder kann verwendet werden, ohne die anderen beiden zu benötigen.",
"dashboardTitle": "Von der Registrierung bis zum Apps Launcher",
"dashboard": "Jeder hier gespeicherte Weblink erscheint auch als Karte im übergeordneten <appsLink>Apps-Reiter</appsLink>. Diese LXC-Seite bleibt die maßgebliche Stelle für Name, Logo, Links und Versionsverfolgung."
},
"overview": {
"heading": "Was ein Anwendungsdatensatz bietet",
"lead": "Ein einzelner gespeicherter Datensatz kann Folgendes umfassen:",
"items": [
"Anzeigename und ein an das Farbschema angepasstes Logo.",
"Ein oder mehrere anklickbare Weblinks, die aus der LXC-Adresse, dem Schema und dem gespeicherten Port erstellt wurden.",
"Ein optionaler Detektor für die derzeit im LXC installierte Version.",
"Eine optionale GitHub, HTTP JSON oder Docker Hub-Quelle für die neueste verfügbare Version.",
"Benachrichtigungen über neue Versionen und Einstellungen zur Aufnahme in den Aktualisierungszähler pro App.",
"Ein entsprechender Abschnitt auf der Registerkarte Updates, auch wenn die Versionsverfolgung deaktiviert ist."
]
},
"discovery": {
"heading": "Zwischengespeicherte Erkennung und Anwendungen suchen",
"lead": "Anwendungsvorschläge sind Teil des per-LXC modalen Cache. Der Start-Scan bereitet sie im Hintergrund vor, so dass das Öffnen des App-Tabs zwischengespeicherte Ergebnisse sofort anzeigen kann.",
"items": [
"Das Öffnen des App-Reiters startet <strong>keinen</strong> neuen Katalogscan und fragt den LXC nicht wiederholt ab.",
"<strong>Anwendungen suchen</strong> startet ausdrücklich eine neue Erkennung für diesen LXC. Verwenden Sie dies nach einer Softwareinstallation bei bereits laufendem ProxMenux.",
"Die vorherige Liste bleibt sichtbar, während der explizite Scan ausgeführt wird. Neue Übereinstimmungen werden hinzugefügt, wenn sie beendet sind.",
"Wird keine neue Übereinstimmung gefunden, steht das Ergebnis neben den Aktionen. <strong>Anwendung registrieren</strong> bleibt für manuelle Einträge verfügbar.",
"Das Speichern, Entfernen oder Wiederherstellen einer App aktualisiert den gleichen Cache sofort. Das Starten oder Wiederherstellen eines LXC aktualisiert nur diesen Gast durch sein bestehendes Lebenszyklusereignis."
],
"callout": "Ein Vorschlag ist keine Registrierung. Er bleibt schreibgeschützt, bis <strong>Registrieren</strong> gewählt und das Formular gespeichert wird."
},
"registration": {
"heading": "Eine Anwendung registrieren",
"lead": "Ein erkannter Vorschlag und eine manuelle Aufzeichnung verwenden denselben Editor:",
"steps": [
"Klicken Sie bei einem Vorschlag auf <strong>Registrieren</strong> oder auf <strong>Anwendung registrieren</strong>, um im Katalog zu wählen oder einen eigenen Namen einzugeben.",
"Überprüfen Sie den Namen und das Logo, die im Katalog vorgeschlagen werden.",
"Ergänzen Sie die benötigten Weblinks. Erkannte lauschende Ports werden als Vorschläge angeboten, aber nicht automatisch gespeichert.",
"Lassen Sie <strong>Upstream-Version verfolgen</strong> für reine Link-Datensätze deaktiviert oder aktivieren Sie es und prüfen Sie den Detektor für die installierte Version sowie die Upstream-Quelle.",
"Bei aktivierter Versionsverfolgung <strong>Detektor testen</strong> verwenden und danach speichern.",
"Nach der Bearbeitung <strong>Fertig</strong> wählen. App und Aktualisierungen verwenden denselben aktualisierten Cache-Datensatz."
]
},
"catalog": {
"heading": "Kataloggestützte Registrierung",
"lead": "Der Katalog liefert Standardwerte, aber der gespeicherte Datensatz bleibt editierbar.",
"items": [
"Suchergebnisse können den kanonischen Namen, das Logo und die gemeinsamen Web-Ports vorfüllen.",
"Bekannte Versionsdetektoren basieren auf echten Paketnamen, Binärdateien, Dateien, Python-Distributionen, OCI-Beschriftungen oder Befehlen und nicht auf einer universellen <code>/root/.app</code>-Annahme.",
"Verifizierte Laufzeitüberschreibungen haben Vorrang, wenn eine Installation einen Pfad verwendet, der sich von den Metadaten des Installationsprogramms unterscheidet.",
"Proxmox VE Helper-Scripts-Marker wie <code>/root/.slug</code> bleiben ein Kompatibilitätssignal für neuere Helferinstallationen, nicht der einzige Detektor.",
"Alle vorgeschlagenen Werte sind vor dem Speichern bearbeitbar, um offizielle Installationsprogramme und manuelle Installationen abzudecken."
]
},
"docker": {
"heading": "Wie Docker LXCs dargestellt sind",
"lead": "Für einen LXC, dessen primäre Plattform Docker ist, ist <strong>Docker</strong> die auf LXC registrierte Anwendung.",
"items": [
"Eine containerisierte Arbeitslast wie Portainer, Frigate oder Vaultwarden wird nicht als unabhängige native LXC-Anwendung vorgeschlagen.",
"Docker-Dienste mit veröffentlichten TCP-Ports werden im Docker-Editor als optionale Weblinks angeboten.",
"Jeder vorgeschlagene Link zeigt den Service, Host-Port und Container-Port an. Nur Links, die ein Webinterface bereitstellen, sollten gespeichert werden.",
"Das globale Docker-Logo wird verwendet, wenn ein Link kein bestimmtes Logo hat. Ein Per-Link-Logo überschreibt es, wenn eines konfiguriert ist.",
"Nachdem Docker registriert wurde, werden Docker Engine und Bildaktualisierungen zusammen im Abschnitt auf der Registerkarte Updates angezeigt."
],
"callout": "Diese Struktur verhindert, dass ein Docker-Workload wie eine direkt im LXC installierte Software aussieht, während gleichzeitig schnelle Verbindungen zu seinen Schnittstellen erhalten bleiben."
},
"webLinks": {
"heading": "Weblinks und Logos",
"lead": "Weblinks funktionieren mit oder ohne Versionsverfolgung.",
"items": [
"Jeder Link speichert ein Schema, einen Port, eine optionale Beschreibung und eine optionale Logo-URL.",
"Die angezeigte URL verwendet die aktuelle Adresse, die bereits für den LXC erkannt wurde; die Adresse wird nicht in jedem App-Record dupliziert.",
"Ein Link ohne eigenes Logo fällt auf das App-Level-Logo zurück.",
"Mehrere Links können eine Admin-Schnittstelle, API, eine sekundäre Benutzeroberfläche oder einen anderen Endpunkt derselben App darstellen.",
"Eine nur gespeicherte Link-App wird auch in Updates angezeigt, wo ein benutzerdefinierter Updater später konfiguriert werden kann."
]
},
"tracking": {
"heading": "Optionale Versionsverfolgung",
"lead": "Die Versionsverfolgung kombiniert einen Detektor für die installierte Version mit einer optionalen Upstream-Quelle. Beide Seiten werden unabhängig geprüft.",
"colMethod": "Methode zur Ermittlung der installierten Version",
"colUse": "Verwendung",
"detectorRows": [
{
"method": "dpkg / apk",
"use": "Lies die installierte Paketversion aus Debian, Ubuntu oder Alpine Paket-Metadaten."
},
{
"method": "binary",
"use": "Führt einen absoluten binären Pfad oder einen Befehlsnamen mit Versionsargumenten aus."
},
{
"method": "file + regex",
"use": "Lies eine echte Datei und extrahiert die Version mit einer Capture-Gruppe."
},
{
"method": "docker label / docker exec",
"use": "Lesen Sie ein OCI-Versionslabel oder führen Sie einen Versionsbefehl in einem Docker-Container aus."
},
{
"method": "python distribution",
"use": "Verwendet importlib.metadata über den ausgewählten Python-Interpreter."
},
{
"method": "command",
"use": "Führt einen fortgeschrittenen Befehl im argv-Format ohne Shell aus und extrahiert die Version aus seiner Ausgabe."
},
{
"method": "manual",
"use": "Speichert eine manuell eingegebene Version; sie muss nach dem Upgrade der App geändert werden."
},
{
"method": "OCI image",
"use": "Für Container aus OCI manager Apps. Liest App- und Image-Versionen aus dem Installationsdatensatz und vergleicht den installierten Digest mit dem veröffentlichten Registry-Digest. Keine Konfiguration erforderlich."
}
],
"sourcesHeading": "Quellen für die verfügbare Version",
"sources": [
"<strong>GitHub-Repository</strong>: neueste Version oder Tag aus einem öffentlichen <code>owner/name</code>-Repository.",
"<strong>HTTP JSON</strong>: ein öffentlicher Endpunkt plus ein gepunkteter Pfad wie <code>data.version</code> oder <code>releases[0].tag_name</code>.",
"<strong>Docker Hub</strong>: versionierte Tags, die durch einen regulären Ausdruck gefiltert werden. Eine Live-Vorschau zeigt echte übereinstimmende Tags, bevor der Datensatz gespeichert wird.",
"Veränderliche Tags wie <code>latest</code>, <code>stable</code> oder <code>lts</code> enthalten keine Version. Verfolgen Sie solche Images anhand ihres Digests über die Docker-Image-Aktualisierungen."
],
"regexHeading": "Schreiben des Capture-Ausdrucks",
"regexLead": "Der reguläre Ausdruck muss die Version in seiner <strong>ersten Erfassungsgruppe</strong> zurückgeben.",
"regexRules": [
"Passen Sie den Text an, der von der ausgewählten Binär-, Datei-, Befehls- oder Tag-Quelle ausgegeben wird; raten Sie keinen generischen Pfad.",
"Schreiben Sie literale Punkte als <code>\\.</code>, damit sie nicht für beliebige Zeichen stehen.",
"Lassen Sie einen führenden <code>v</code> nur zu, wenn die Quelle ihn enthalten kann.",
"Fügen Sie Suffixe wie Pre-Release oder Distro-Revisionen nur dann hinzu, wenn sie für den Vergleich aussagekräftig sind.",
"Vor dem Speichern <strong>Detektor testen</strong> verwenden und prüfen, ob die angezeigte installierte Version zum LXC passt."
],
"regexExampleLead": "Gemeinsame semantische Versionserfassung:",
"regexExample": "v?(\\d+\\.\\d+\\.\\d+)",
"regexCallout": "Ein erfolgreiches Regex-Match ist kein Beweis dafür, dass der Detektorpfad korrekt ist. Der Pfad oder das Paket muss auch in der registrierten realen Anlage vorhanden sein."
},
"updater": {
"heading": "Versionsverfolgung und -aktualisierung sind unabhängig",
"lead": "Der <link>Reiter Aktualisierungen</link> legt einen App-Abschnitt an, sobald ein Anwendungsdatensatz gespeichert wird.",
"items": [
"Ein Link-only-Record zeigt an, dass die Versionsverfolgung nicht konfiguriert ist, aber dennoch einen benutzerdefinierten Update-Befehl erhalten kann.",
"Eine App mit Tracking, aber ohne ausführbare Methode zeigt eine neutrale Nachricht an, in der ein benutzerdefinierter Befehl angefordert wird.",
"Eine App mit einem verifizierten Proxmox VE Helper-Scripts-Wrapper kann diesen integrierten Updater auch dann verwenden, wenn die Registrierung über einen Weblink begann.",
"Durch Hinzufügen oder Bearbeiten eines Updaters wird der Detektor oder die Upstream-Quelle, die auf der Registerkarte App gespeichert ist, nicht geändert."
]
},
"states": {
"heading": "Versionsangaben auf der App-Karte",
"colState": "Zustand",
"colDisplay": "Anzeige",
"colMeaning": "Bedeutung",
"rows": [
{
"state": "Update verfügbar",
"display": "Verfügbare Version in lila mit einem nach oben gerichteten Symbol",
"meaning": "Die installierten und Upstream-Versionen unterscheiden sich."
},
{
"state": "Aktuell",
"display": "Installierte und neueste Versionen ohne den lila Alarm",
"meaning": "Der letzte Check fand keine neuere Upstream-Version."
},
{
"state": "Versionsprüfung ausstehend",
"display": "Prüfung läuft oder steht aus",
"meaning": "Der Datensatz ist konfiguriert, hat aber noch nicht beide Prüfungen abgeschlossen."
},
{
"state": "Tracking deaktiviert",
"display": "Nur Weblinks; kein Versionsvergleichsblock",
"meaning": "Der Datensatz bleibt gültig und kann immer noch einen Updater haben."
},
{
"state": "Prüffehler",
"display": "Bernstein Erklärung im Inneren der Karte",
"meaning": "Der zuvor gespeicherte Zustand bleibt sichtbar, während der Detektor oder Upstream-Fehler gemeldet wird."
}
]
},
"management": {
"heading": "Verwalten von gespeicherten und vorgeschlagenen Apps",
"lead": "Die Aktionen am unteren Rand des Tabs haben unterschiedliche Rollen:",
"items": [
"<strong>Anwendungen suchen</strong> aktualisiert die Erkennung nur für diesen LXC.",
"<strong>Registrieren Sie eine andere Anwendung</strong> öffnet den Katalog und den manuellen Editor, ohne den LXC neu zu scannen.",
"<strong>Bearbeiten</strong> zeigt je Karte Entfernen, Prüfen, Benachrichtigungen und Felder bearbeiten.",
"<strong>Ausblenden</strong> entfernt einen unerwünschten Vorschlag. Ausgeblendete Erkennungen lassen sich in der Registrierungsübersicht wiederherstellen.",
"<strong>Prüfen</strong> aktualisiert die Versionsdaten der gewählten gespeicherten App und sucht keine neuen Apps."
]
},
"troubleshooting": {
"heading": "Häufige Situationen",
"colProblem": "Situation",
"colResolution": "Lösung",
"rows": [
{
"problem": "Software wurde installiert, nachdem ProxMenux gestartet wurde",
"resolution": "Wählen Sie Anwendungen suchen. Der explizite Scan aktualisiert die zwischengespeicherten Vorschläge dieses LXC."
},
{
"problem": "Keine Anwendung festgestellt",
"resolution": "Registrieren Sie es manuell. Ein Name und ein Weblink sind ausreichend; Tracking kann später hinzugefügt werden."
},
{
"problem": "Der vorgeschlagene Detektor gibt die falsche Version zurück",
"resolution": "Öffnen Sie Felder bearbeiten, wählen Sie den realen Paket-, Binär- oder Dateipfad aus und testen Sie den Detektor vor dem Speichern."
},
{
"problem": "Ein Docker Workload wird nicht als LXC App angeboten",
"resolution": "Registrieren Sie Docker und fügen Sie die veröffentlichte Benutzeroberfläche des Workloads als Docker-Weblink hinzu. Image-Updates bleiben im Docker Abschnitt."
},
{
"problem": "Eine gespeicherte App hat keinen Update-Button",
"resolution": "Öffnen Sie die Registerkarte Updates und konfigurieren Sie die Aktualisierungsmethode. Versions-Tracking allein definiert nicht, wie ein Update installiert wird."
}
]
},
"figures": {
"catalog": {
"alt": "Anwendungsregistrierungskatalog mit Suchergebnissen, Logos, Ports und Detektorfeldern",
"caption": "Katalog-Metadaten beschleunigen die Registrierung, während jeder vorgeschlagene Wert editierbar bleibt."
},
"webLinks": {
"alt": "Gespeicherte LXC-Anwendungskarte mit einem anklickbaren Weblink",
"caption": "Ein Link-Only-Record ist gültig: Das Versions-Tracking kann deaktiviert bleiben und ein Updater kann unabhängig hinzugefügt werden."
},
"tracking": {
"alt": "Optionale Felder für den Detektor der installierten Version und die Upstream-Quelle",
"caption": "Die Installationsversionserkennung und die Upstream-Quelle werden separat konfiguriert und getestet."
},
"card": {
"alt": "Gespeicherte Anwendungskarte mit installierten und verfügbaren Versionen sowie einem Weblink",
"caption": "Die Karte kombiniert Identität, Versionsnachweis und Webzugriff, ohne Update-Aktionen von diesem Tab aus auszuführen."
}
}
}
@@ -0,0 +1,203 @@
{
"meta": {
"title": "LXC-Aktualisierungen: Betriebssystem, Apps und Docker | ProxMenux",
"description": "Konfigurieren und Ausführen von Betriebssystem-, Anwendungs-, Docker Engine- und Docker-Image-Updates aus einem LXC-Container."
},
"header": {
"title": "LXC-Aktualisierungen: Betriebssystem, Apps und Docker",
"description": "Überprüfen Sie jedes Update-Ziel an einem Ort, führen Sie es unabhängig aus oder kombinieren Sie ausgewählte Ziele in einer kontrollierten Massenaktion."
},
"intro": {
"p1": "Der Reiter <strong>Aktualisierungen</strong> trennt Versionserkennung und Installation. Registrierung und optionale Versionsverfolgung erfolgen im <link>App-Reiter</link>; ausführbare Aktualisierungsmethoden werden hier verwaltet.",
"p2": "Eine gespeicherte Anwendung wird in Updates angezeigt, auch wenn sie nur einen Weblink enthält. Die Versionsverfolgung ist optional und ein Updater kann unabhängig konfiguriert werden.",
"callout": "Die Registrierung wählt keinen Updater aus. Wird ein passender Helper-Scripts-Updater erkannt, wählen und speichern Sie <strong>Helper-Scripts</strong> oder <strong>Eigener Befehl</strong>. Die Erkennung garantiert keine Kompatibilität. Die Wahl gilt pro App, auch wenn mehrere denselben LXC nutzen."
},
"overview": {
"heading": "Was der Tab enthält",
"lead": "Jedes verfügbare Ziel hat seinen eigenen Abschnitt und seine eigene Aktion:",
"items": [
"<strong>Betriebssystempakete</strong> für Debian-, Ubuntu- und Alpine-Container.",
"Ein Abschnitt je <strong>registrierter Anwendung</strong>, auch für Datensätze mit nur einem Link.",
"Ein <strong>Docker</strong>-Abschnitt, wenn Docker registriert ist, wobei Docker Engine und getaggte Images gruppiert sind.",
"Ein konfigurierbarer Abschnitt <strong>Sammelaktualisierung</strong> mit anschließenden Sicherungs-, Neustart- und Zeitplanoptionen."
]
},
"mechanisms": {
"heading": "Wie eine Aktualisierungsmethode ausgewählt wird",
"lead": "Der integrierte Weg für Proxmox VE Helper-Scripts verwendet den offiziellen <helper>update-apps-Mechanismus</helper>. Andere Installationen verwenden die passende Paket-, Docker- oder eigene Methode.",
"officialReference": "Offizielle Referenz: Die <helper>Proxmox VE Helper-Scripts-Update-Apps-Dokumentation</helper> umfasst interaktive und unbeaufsichtigte Modi, Backups, Trockenläufe, temporäre Build-Ressourcen, Protokolle und Exit-Codes.",
"colSource": "Quelle",
"colAction": "Gezeigte Aktion",
"colNotes": "Was läuft",
"rows": [
{
"source": "APT- oder APK-Pakete",
"action": "OS Updates anwenden",
"notes": "Aktualisiert die Containerpakete. Als dpkg- oder apk-Pakete installierte registrierte Apps werden im selben Lauf berücksichtigt."
},
{
"source": "Proxmox VE Helper-Scripts",
"action": "Update anwenden",
"notes": "Nachdem Helper-Scripts explizit ausgewählt wurde, wird das offizielle Anwendungsskript ausgeführt, das durch den validierten /usr/bin/update-Wrapper identifiziert wurde. Eine Marker- oder Katalogübereinstimmung allein ermöglicht niemals die Ausführung."
},
{
"source": "Eigener Befehl",
"action": "Führen Sie den Updater aus",
"notes": "Führt den gespeicherten Befehl im LXC aus und ersetzt jeden integrierten App-Updater für diesen Datensatz."
},
{
"source": "Docker Engine",
"action": "Docker Engine aktualisieren",
"notes": "Aktualisiert nur installierte Docker-Pakete und deren erforderliche Abhängigkeiten. Andere Betriebssystempakete und Container bleiben unverändert."
},
{
"source": "Docker-Image",
"action": "Image aktualisieren",
"notes": "Zieht das ausgewählte Image und erstellt die Compose-Servicegruppe oder den geschützten eigenständigen Container neu."
}
],
"callout": "Ein eigener Befehl <strong>ersetzt</strong> Helper-Scripts für diese Anwendung. Manuelle, Sammel- und geplante Läufe beachten die gespeicherte Wahl. Vorhandene eigene Befehle und ausdrücklich gespeicherte ältere Sammel- bzw. aktivierte Zeitplanauswahlen bleiben erhalten. Neu registrierte Apps werden nie durch einen alten Zeitplan aufgenommen."
},
"docker": {
"heading": "Docker Engine und Docker Images",
"lead": "Nach der Docker-Registrierung im App-Reiter erscheinen Docker Engine und Image-Inventar im selben Abschnitt <strong>Docker</strong>.",
"items": [
"Die Docker Engine-Versionsverfolgung ist vom OS-Paketzähler getrennt und verfügt über einen eigenen Update-Button.",
"Lokale Images mit Tags werden anhand unveränderlicher Digests mit ihrer Registry verglichen. <strong>Jetzt prüfen</strong> aktualisiert das Inventar, ohne Images herunterzuladen oder Container neu zu starten.",
"Compose-Dienste werden von ihrem deklarierten Projekt aktualisiert. Images, die zur gleichen Servicegruppe gehören, werden zusammen bearbeitet, damit das Projekt nicht wiederholt neu erstellt wird.",
"Ein eigenständiger Container wird anhand seiner aktuellen Konfiguration neu erstellt. Der geschützte Ablauf bewahrt Rücksetzungsdaten auf und stellt bei einem Fehler den vorherigen Container wieder her.",
"Jedes Image kann separat in manuellen, massenhaften und geplanten Updates ausgewählt werden, mit Ausnahme deklarierter Compose-Abhängigkeiten, die dem übergeordneten Service folgen müssen."
],
"callout": "Container, die innerhalb von Docker laufen, werden nicht als unabhängige LXC-Anwendungen angezeigt. Ihre veröffentlichten Webports können als Links unter der Docker-Registrierung gespeichert werden, während Bildaktualisierungen im Docker-Bereich verbleiben."
},
"actions": {
"heading": "Individuelle Aktionen und Statusfarben",
"lead": "Jeder Abschnitt bleibt unabhängig voneinander umsetzbar, unabhängig davon, ob ein Bulk-Update konfiguriert ist oder nicht.",
"items": [
"<strong>Configure</strong> öffnet den Updater-Selektor, wenn keine Methode ausgewählt ist; <strong>Edit</strong> ändert eine gespeicherte Auswahl. Die Informationsschaltflächen erklären jede Option, verlinken auf die offizielle Dokumentation und zeigen ein benutzerdefiniertes Skriptbeispiel an. Die Auswahl einer Option führt sie nicht aus.",
"Wenn die Versionsverfolgung deaktiviert ist, aber ein Updater vorhanden ist, wird die neutrale Aktion <strong>Run updater</strong> angezeigt. ProxMenux behauptet nicht, dass ein Update anhängig ist.",
"Konfigurieren Sie ohne einen verfügbaren Helper-Scripts-Updater einen benutzerdefinierten Befehl. Das Deaktivieren einer Methode wählt nicht stillschweigend eine andere aus; bestehende Plan-/Zeitplanauswahlen bleiben gespeichert und nicht verfügbare Ziele werden gemeldet.",
"Die Aktion <strong>Update image</strong> gilt nur für die ausgewählte Docker-Einheit; sie aktualisiert weder Docker Engine noch nicht verwandte Images."
],
"statusColState": "Bekannter Zustand",
"statusColAppearance": "Aussehen",
"statusColMeaning": "Bedeutung",
"statusRows": [
{
"state": "Verifiziertes Update verfügbar",
"appearance": "Lila Text, nach oben gerichtetes Symbol und lila Aktion",
"meaning": "Installierte und verfügbare Versionen bzw. Image-Digests unterscheiden sich."
},
{
"state": "Nachweislich aktuell",
"appearance": "Grünes Häkchen und grüne Aktion Aktualisiert",
"meaning": "Die letzte abgeschlossene Überprüfung bestätigt, dass das Ziel aktuell ist."
},
{
"state": "Version unbekannt",
"appearance": "Neutraler Text und neutrale Handlung",
"meaning": "Ein Updater kann ausgeführt werden, aber es gibt keinen Versionsnachweis, um ihn als anhängig oder aktuell zu kennzeichnen."
}
]
},
"custom": {
"heading": "Benutzerdefinierte Aktualisierungsbefehle",
"lead": "Verwenden Sie einen benutzerdefinierten Befehl, wenn die Installation keinen verifizierten integrierten Updater hat oder wenn die normale Prozedur ersetzt werden muss.",
"items": [
"Öffnen Sie <strong>Configure</strong>, wenn das Feld leer ist, oder <strong>Edit</strong>, wenn bereits eine Methode vorhanden ist.",
"Bei einer integrierten App oder Docker Engine zeigt der Editor den aktuell verwendeten Befehl an. Das Speichern verschiedener Inhalte macht es zum expliziten Override für diesen Datensatz.",
"Testen Sie zuerst die komplette Prozedur im LXC Terminal. Es muss nicht interaktiv sein, das korrekte Arbeitsverzeichnis verwenden und beim Ausfall einen Nicht-Null-Ausgangsstatus zurückgeben.",
"<code>pct exec</code> nicht einschließen; ProxMenux betritt bereits den Container und führt den Befehl als root aus."
],
"exampleLead": "Beispiel eines vollständigen Containerverfahrens:",
"example": "cd /opt/my-app && ./update.sh",
"callout": "Ein Versionsbefehl wie <code>myapp --version</code> liest nur eine Version; es ist kein Updater. Befehle laufen mit administrativen Privilegien, so dass gespeicherte Inhalte mit der gleichen Sorgfalt wie ein Root-Shell-Befehl überprüft werden müssen."
},
"bulk": {
"heading": "Sammelaktualisierung",
"lead": "Die Sammelaktualisierung erstellt eine wiederverwendbare Aktion für eine genau festgelegte Zielauswahl im LXC. Sie steht nach den App- und Docker-Abschnitten und vor <strong>Optionen</strong>.",
"items": [
"Betriebssystempakete sind Pflicht. Zusätzlich muss mindestens eine App, Docker Engine oder eine Docker-Image-Einheit ausgewählt werden.",
"Apps und Docker-Einheiten werden einzeln ausgewählt. Der übergeordnete Compose-Dienst zeigt die mit ihm zu aktualisierenden Abhängigkeiten.",
"Nicht verfügbare oder entfernte Ziele werden als veraltet markiert und müssen entfernt werden, bevor die Konfiguration gespeichert werden kann.",
"<strong>Aktualisierungen anwenden</strong> ist lila, wenn ein gewähltes Ziel ein nachgewiesenes Update hat, grün, wenn alle nachweislich aktuell sind, und neutral bei unbekanntem Ergebnis.",
"Durch das Entfernen der Bulk-Konfiguration werden keine einzelnen Aktualisierungsmethoden oder Einstellungen für geplante Aktualisierungen entfernt."
],
"callout": "Bulk Update ersetzt nicht die einzelnen Buttons. Es ist eine optionale Abkürzung für eine Auswahl, die zusammen laufen sollte."
},
"options": {
"heading": "Backup- und Neustartoptionen",
"lead": "Die gleichen Optionen gelten für manuelle, Massen- und geplante Durchläufe:",
"items": [
"<strong>Sicherung vor dem Anwenden</strong> erstellt ein vzdump-Backup auf dem gewählten Speicher. Schlägt die erforderliche Sicherung fehl, startet die Aktualisierung nicht.",
"<strong>Neustart nach dem Anwenden</strong> startet den LXC nur nach einem erfolgreichen Lauf neu.",
"Die Auswahlen werden pro LXC gespeichert und bleiben unabhängig von der Zielliste."
]
},
"scheduled": {
"heading": "Geplante Updates",
"lead": "Geplante Updates verwenden die gleichen ausführbaren Ziele und Sicherheitsoptionen wie manuelle Aktionen.",
"items": [
"Wählen Sie einen voreingestellten oder cron-Ausdruck und wählen Sie dann genaue Ziele aus: Betriebssystempakete, einzelne Apps, Docker Engine, eigenständige Docker-Einheiten oder Compose-Dienstgruppen.",
"Ein Release Hold gilt nur für ausgewählte Anwendungen mit Versionstracking. Apps ohne Tracking führen ihren Updater immer dann aus, wenn ihr Zeitplan fällig ist.",
"Der Zustand des letzten Laufs unterscheidet Erfolg, Teilerfolg, Fehler, Sicherheitsaufschub und keine ausstehenden Updates. Nach dem ersten geplanten Lauf öffnet <strong>Aktualisierungen → Geplante Aktualisierungen → Protokoll anzeigen</strong> die vollständige Ausgabe des Updaters und seiner aufgerufenen Unterskripte.",
"Nach jedem Durchlauf überprüft ProxMenux den standardmäßigen Debian-Reboot-erforderlichen Marker. Wenn ein Neustart erforderlich ist, wird dies auf der Registerkarte Updates und der Abschlussbenachrichtigung angezeigt; die Warnung wird gelöscht, wenn der LXC gestartet oder neu gestartet wird.",
"Protokolle geplanter Läufe liegen auf dem Proxmox-Host in <code>/usr/local/share/proxmenux/logs/lxc-updates/</code> mit dem Namen <code>&lt;VMID&gt;-scheduled-&lt;run-id&gt;.log</code>. Pro LXC bleiben die letzten zehn Protokolle erhalten; ältere Dateien werden automatisch gelöscht.",
"Diese beibehaltene Historie gilt für geplante Updates. Ein manuelles Update zeigt seine Ausgabe live im Monitor-Ausführungsfenster an und erstellt kein geplantes Protokoll in diesem Verzeichnis.",
"Externe Host-Zeitpläne, die von Proxmox VE Helper-Scripts erkannt wurden, werden separat angezeigt, so dass eine überlappende Automatisierung sichtbar ist."
],
"callout": "Führen Sie jede ausgewählte Methode manuell aus, bevor Sie einen Zeitplan aktivieren. Geplante Befehle können keine Eingabeaufforderungen beantworten."
},
"completion": {
"heading": "Was passiert nach einem Update",
"lead": "Das Update gilt nicht als abgeschlossen, wenn der Terminalbefehl lediglich beendet wird.",
"items": [
"Derselbe Lauf zeichnet sein Endergebnis auf und aktualisiert den OS-Paketzustand, die registrierten App-Versionen und das Docker-Inventar.",
"Geplante Durchläufe behalten ihre Terminalausgabe bei und melden, ob ein Neustart noch erforderlich ist, um die Anwendung von Paketänderungen abzuschließen.",
"Der LXC-Cache wird durch den verifizierten Post-Update-Zustand ersetzt, so dass Badges und Buttons das vorherige Ergebnis nicht beibehalten.",
"Wenn ein angehaltener oder wiederhergestellter LXC startet, aktualisiert das vorhandene Lebenszyklusereignis diesen LXC erneut. Docker-Inventar wartet, bis der Daemon fertig ist, anstatt ein leeres Startergebnis als endgültig zwischenzuspeichern.",
"Aktivierte Benachrichtigungen werden vom finalisierten Durchlauf ausgegeben, einschließlich Teilfehlern und gruppierten Docker-Bildergebnissen."
]
},
"troubleshooting": {
"heading": "Häufige Situationen",
"colProblem": "Situation",
"colResolution": "Lösung",
"rows": [
{
"problem": "Es wurde keine Aktualisierungsmethode identifiziert",
"resolution": "Öffnen Sie die Konfiguration, fügen Sie die offizielle nicht-interaktive Prozedur hinzu und testen Sie sie manuell, bevor Sie sie planen."
},
{
"problem": "Eine Proxmox VE Helper-Scripts-Identität wird angezeigt, aber es gibt keine Aktion",
"resolution": "Der LXC hat Legacy-Identifikationsdaten, aber keinen verifizierten /usr/bin/update-Wrapper. Fügen Sie eine benutzerdefinierte Methode erst hinzu, nachdem Sie das korrekte Verfahren bestätigt haben."
},
{
"problem": "Docker-Bilder sind nach dem Start oder der Wiederherstellung vorübergehend leer",
"resolution": "Warten Sie, bis Docker fertig ist, oder drücken Sie jetzt Überprüfen. Das Inventar wiederholt den Start und behandelt ein vorübergehendes leeres Ergebnis nicht als endgültig."
},
{
"problem": "Ein gespeichertes Bulk-Ziel ist nicht mehr verfügbar",
"resolution": "Bearbeiten Sie die Bulk-Konfiguration, entfernen Sie das veraltete Ziel und wählen Sie den aktuellen Ersatz aus, wenn eines vorhanden ist."
},
{
"problem": "Ein benutzerdefinierter Befehl scheitert",
"resolution": "Führen Sie es im LXC-Terminal aus und überprüfen Sie dessen Pfad, Abhängigkeiten, nicht-interaktive Flags und Exit-Code."
},
{
"problem": "Ein geplantes Update sagt, dass ein Neustart erforderlich ist",
"resolution": "Öffnen Sie Protokoll anzeigen, prüfen Sie den abgeschlossenen Lauf und starten Sie den LXC neu. ProxMenux löscht die Warnung, sobald das Lebenszyklusereignis den erneuten Start meldet."
}
]
},
"figures": {
"osPending": {
"alt": "Abschnitt Betriebssystempakete mit ausstehenden und Sicherheitsupdates",
"caption": "Der Betriebssystembereich hält Paketaktualisierungen unabhängig von Anwendungs- und Docker-Aktionen."
},
"options": {
"alt": "LXC Update-Optionen mit Pre-Update-Backup und Post-Update-Neustart",
"caption": "Backup- und Neustarteinstellungen gelten für manuelle, Massen- und geplante Ausführung."
}
}
}
@@ -0,0 +1,244 @@
{
"meta": {
"title": "ProxMenux Monitor — Dashboard: VMs und LXCs | ProxMenux-Dokumentation",
"description": "Die Registerkarte VMs und LXCs listet alle Gäste des Hosts mit CPU-, Arbeitsspeicher- und Datenträgernutzung in Echtzeit. Die Details je Gast zeigen Konfiguration, Ressourcen, Sicherungen, das Konsolenprotokoll von OCI-Containern, Notizen und die Steuerung Starten / Herunterfahren / Neustart / Stopp erzwingen."
},
"header": {
"title": "Dashboard: VMs und LXCs",
"description": "Vollständiges Gastinventar des Knotens: vier Kennzahlen oben, eine sortierbare Liste aller VMs und LXCs darunter und Gastdetails mit Konfiguration, Ressourcen, Sicherungen, dem Konsolenprotokoll von OCI-Containern sowie den vier Lebenszyklus-Steuerungen (Starten / Herunterfahren / Neustart / Stopp erzwingen).",
"section": "ProxMenux Monitor · Übersicht"
},
"intro": {
"title": "Steuerung der Gäste",
"body": "Hier steuern Sie den Lebenszyklus der Gäste. Lebenszyklusaktionen laufen über <code>POST /api/vms/&lt;vmid&gt;/control</code>; bei Neustart und Stopp erzwingen geben Sie zur Bestätigung die VMID ein, und die Antwort wird in der Gastzeile angezeigt. Erzwungenes Ausschalten erfordert die eigene Schaltfläche Stopp erzwingen."
},
"topRow": {
"heading": "Obere Reihe: vier Stat-Karten",
"intro": "Vier Karten fassen den Gastzustand zusammen: Gesamtzahl, CPU-Auslastung, zugewiesener Arbeitsspeicher im Verhältnis zur Hostkapazität und Datenträgerzuweisung.",
"imageAlt": "Registerkarte VMs & LXCs — oberste Reihe von vier Statistikkarten: Total VMs & LXCs, Total CPU, Total Memory, Total Disk",
"imageCaption": "Obere Reihe: Gesamtzahlen und Laufend/Gestoppt, aktuelle CPU-Auslastung, belegter Speicher / laufenden Gästen zugewiesener Speicher / insgesamt zugewiesener Speicher mit Grenzwertanzeige sowie zugewiesener Datenträgerplatz.",
"headerCard": "Karte",
"headerWhat": "Was es zeigt",
"totalLabel": "Gesamtzahl der VMs und LXCs",
"totalWhat": "Gesamtzahl mit zwei Abzeichen — <em>X Running</em> (grün) und <em>Y Stopped</em> (rot, nur wenn > 0). Die Nummer, die Sie sehen, wenn etwas nach einem Neustart nicht wieder auftaucht.",
"cpuLabel": "CPU gesamt",
"cpuWhat": "Gesamte aktuelle CPU-Auslastung aller Gäste als Anteil der physischen Host-CPU mit der Fußzeile <em>„Zugewiesene CPU-Auslastung“</em>.",
"memoryLabel": "Gesamtspeicher",
"memoryIntro": "Drei Messwerte vertikal gestapelt:",
"memoryItems": [
"<strong>Aktuell belegt</strong> — großer Wert, etwa <em>15.4 GB</em>, und <em>X.X % von Y GB</em> des Host-RAMs. Der blaue Balken zeigt den Prozentsatz.",
"<strong>Laufenden Gästen zugewiesen</strong> + <strong>Insgesamt zugewiesen</strong> — Summe von <code>maxmem</code> der <em>laufenden</em> Gäste neben der Summe <em>aller</em> Gäste einschließlich gestoppter. Die erste ist jetzt relevant, die zweite beim gleichzeitigen Start aller Gäste.",
"<strong>Innerhalb der Grenzen</strong> ist grün und wechselt zu <em>Überbucht</em>, wenn die Gesamtzuweisung den Host-RAM übersteigt. Kontrollierte Überbuchung kann mit KSM funktionieren; die Anzeige warnt früh bei knappem Spielraum."
],
"diskLabel": "Gesamtes Laufwerk",
"diskWhat": "Summe des Speicherplatzes, der allen Gästen in der entsprechenden Einheit (GB / TB) zugewiesen ist, mit der Fußzeile <em>\"Zugeordneter Speicherplatz\"</em>."
},
"inventory": {
"heading": "Liste virtueller Maschinen und Container",
"intro": "Eine Reihe pro Gast. Die Liste stammt aus <code>/api/vms</code>, die <code>qm list</code> + <code>pct list</code> + <code>pvesh /cluster/resources</code> auf dem Host konsolidiert.",
"imageAlt": "Liste virtueller Maschinen und Container — eine Zeile pro Gast mit Status, Typabzeichen, Name, ID und Inline-CPU / Speicher / Festplattenprozentsatz",
"imageCaption": "Das mobil optimierte Layout des Inventars - die gleichen Daten, die die Desktop-Ansicht zeigt, werden in einer einzigen Spalte neu gestapelt, wobei die Prozentsätze und Statusindikatoren kompakt gehalten werden.",
"rowsIntro": "Jede Zeile zeigt:",
"rows": [
"<strong>Statussymbol</strong> — grünes Wiedergabedreieck für laufend oder rotes Quadrat für gestoppt. Gestoppte Gäste werden abgeblendet und fallen sofort auf.",
"<strong>Typanzeige</strong> — <em>LXC</em> in Cyan für Container, <em>VM</em> in Lila für virtuelle Maschinen.",
"<strong>Name</strong> — Hostname oder Anzeigename des Gasts.",
"<strong>VMID</strong> — die numerische ID von Proxmox unter dem Namen.",
"<strong>Inline-Metriken</strong> — drei Prozent mit ihrem Symbol (CPU %, Memory %, Disk %). Jedes Symbol wird orange, wenn die Metrik eine Aufmerksamkeitsschwelle überschreitet (z. B. Speicher über 90 %), so dass ein schneller Scan Ihnen sagt, welcher Gast unter Druck steht, ohne ihn zu öffnen."
],
"clickHint": "Ein Klick auf eine Zeile öffnet den Detaildialog, unabhängig davon, ob der Gast läuft oder gestoppt ist.",
"mobileTitle": "Die Liste ist für Mobilgeräte entworfen",
"mobileBody": "Auf Telefonen und in schmalen Fenstern stehen Typ, Name, ID und die drei Prozentwerte untereinander wie im Bild. Auf breiten Ansichten verteilen sie sich horizontal. In beiden Fällen öffnet ein Tippen auf die gesamte Zeile die Details."
},
"drillIn": {
"heading": "Gastdetaildialog",
"intro": "Der Detaildialog zeigt Gastname, VMID, Typ, Zustand und Laufzeit. Seine Navigation passt sich dem Gast an: <strong>Status</strong>, <strong>App</strong> und <strong>Updates</strong> für die LXC-Anwendungsverwaltung, <strong>Mounts</strong> bei vorhandenen LXC-Mountpoints, <strong>Logs</strong> für durch OCI manager Apps installierte Container sowie <strong>Backups</strong> und <strong>Firewall</strong>. Die feste Aktionsleiste hält die Start- und Stoppfunktionen sowie das LXC-Terminal in jeder Registerkarte bereit.",
"statusTitle": "Tab. 1 — Status",
"statusImageAlt": "Gastdetails — Status mit Live-Werten für CPU, Arbeitsspeicher und Datenträger, Datenträger-/Netzwerk-I/O, Betriebssystemlogo und Ressourcen/IP-Adressen",
"statusImageCaption": "Status: oben CPU, Arbeitsspeicher und Datenträger mit Balken; darunter gesamte I/O-Daten (Datenträger gelesen/geschrieben, Netzwerk empfangen/gesendet); anschließend Ressourcen mit Notizen, + Info und IP-Adressliste.",
"statusIntro": "Der Standardreiter zum Prüfen des Gastzustands. Drei Bereiche:",
"liveTitle": "1. Zeile Live-Metriken",
"liveItems": [
"<strong>CPU-Auslastung (X Kerne)</strong> — Prozentsatz mit Balken. Die konfigurierte Kernzahl im Kopf erklärt, worauf sich 100 % bezieht.",
"<strong>Arbeitsspeicher</strong> — <em>belegt / maximal</em> in GB mit Balken.",
"<strong>Datenträger</strong> — <em>belegt / maximal</em> für das primäre Gast-Image im selben Format."
],
"ioTitle": "2. I/O-Gesamtwerte + OS-Logo",
"ioItems": [
"<strong>Datenträger-I/O</strong> — gelesene (↓) und geschriebene (↑) Daten seit dem Start. Zeigt einen plötzlichen I/O-Anstieg gegenüber dem üblichen Gastverhalten.",
"<strong>Netzwerk-I/O</strong> — insgesamt empfangene (↓) und gesendete (↑) Daten, entsprechend den Datenträgerwerten.",
"<strong>OS-Verteilungslogo</strong> - das Debian / Ubuntu / Alpine / Windows / usw.-Symbol, das vom Betriebssystemtyp des Gastes erkannt wird. Ein schneller visueller Hinweis beim Scrollen mehrerer geöffneter Modals."
],
"resourcesTitle": "3. Ressourcenblock",
"resourcesIntro": "Gastkonfiguration aus Proxmox: CPU-Kerne, Arbeitsspeicher (konfiguriertes <code>maxmem</code>) und Swap. Zwei aufklappbare Bereiche im Kopf:",
"resourcesItems": [
"<strong>Notizen</strong> — bearbeitbare Gastbeschreibung. Speichern ruft <code>PUT /api/vms/&lt;vmid&gt;/config</code> auf und schreibt in <code>/etc/pve/qemu-server/&lt;vmid&gt;.conf</code> oder <code>/etc/pve/lxc/&lt;vmid&gt;.conf</code>.",
"<strong>+ Info</strong> — BIOS-Modus, Maschinentyp, Agentstatus, hostpci-Passthrough-Einträge, CT-Einhängepunkte und Startreihenfolge."
],
"ipsTitle": "4. IP-Adressen",
"ipsBody": "Jede IPv4-/IPv6-Adresse des Gasts erscheint als grüne Anzeige. Die Liste bleibt bei gestopptem Gast oder einer VM ohne QEMU-Agent leer. LXCs melden ihre Adressen direkt.",
"appTitle": "Tab 2 — App (nur LXC)",
"appIntro": "Registriert Anwendungen, die zum LXC gehören, speichert Weblinks und vergleicht optional installierte und verfügbare Versionen. Vorschläge kommen aus dem Start-Cache; <strong>Find-Anwendungen</strong> aktualisiert ausdrücklich die Entdeckung für diesen LXC, nachdem neue Software installiert wurde.",
"appLinkLead": "Siehe die",
"appLinkLabel": "dedizierte App-Seite",
"appLinkTail": "für zwischengespeicherte Erkennung, kataloggestützte Registrierung, Docker-Weblinks und Versionsdetektoren.",
"updatesTitle": "Tab 3 — Updates (nur LXC)",
"updatesIntro": "<strong>Betriebssystempakete</strong>, Apps, <strong>Docker Engine</strong> und Docker-Images bleiben getrennte Ziele. Jedes lässt sich einzeln starten oder in einer genau festgelegten Sammelaktion bzw. einem Zeitplan auswählen.",
"updatesLinkLead": "Siehe die",
"updatesLinkLabel": "dedizierte Updates Seite",
"updatesLinkTail": "für integrierte und eigene Updater, Neuerstellung von Docker-Containern, Sammelauswahl, Sicherheitsoptionen und Zeitplanung.",
"mountsTitle": "Reiter 4 — Einhängepunkte (nur LXC, falls vorhanden)",
"mountsImageAlt": "LXC-Details, Einhängepunkte: PVE-Volumes, Bind-Mounts vom Host oder PVE-Speicher sowie im CT eingehängte NFS-/CIFS-Freigaben. Je Karte: Typ, Kapazität, belegte/gesamte Bytes, Optionen und Statuspunkt — grün intakt, bernsteinfarben schreibgeschützt/abweichend, rot nicht erreichbar.",
"mountsImageCaption": "Einhängepunkte erscheint nur bei LXCs mit mindestens einem konfigurierten oder nachträglich hinzugefügten Remote-Einhängepunkt. Ohne Einhängepunkte fehlt der Reiter.",
"mountsIntro": "Proxmox zeigt konfigurierte <code>mpX</code>-Einhängepunkte, jedoch keine später im CT über <code>mount.cifs</code>, NFS mit <code>autofs</code> usw. hinzugefügten. Dieser Reiter verbindet <strong>beide Ansichten</strong>: konfigurierte Einhängepunkte <strong>und</strong> im Container erkannte Laufzeiteinhängungen, mit Status und abrufbarer Kapazität.",
"mountTypesTitle": "Erkannte Einhängepunkttypen",
"mountTypesItems": [
"<strong>PVE-Volume</strong> — liegt auf Proxmox-verwaltetem Speicher, etwa ZFS-Subvolume, Verzeichnis oder Ceph RBD. Die Kapazität stammt aus den PVE-Speicherstatistiken und entspricht der Proxmox-Anzeige.",
"<strong>Bind-Mount aus PVE-Speicher</strong> — <code>mpX</code>-Eintrag mit einem Pfad auf PVE-bekanntem Speicher.",
"<strong>Bind-Mount vom Host</strong> — <code>mpX</code>-Eintrag mit beliebigem Hostpfad (<code>/mnt/something</code>). Die Kapazität liefert <code>df</code> für diesen Pfad.",
"<strong>Ad-hoc in CT</strong> – Mount, der <em>nur</em> im Mount-Namespace des Containers existiert (z. B. eine NFS-Freigabe, die der CT selbstständig mountet). Die Kapazität wird über <code>pct exec &lt;vmid&gt; df</code> gelesen, was die einzige Möglichkeit ist, sie anzuzeigen – <code>/proc/&lt;pid&gt;/root</code> vom Host stellt die tatsächlichen Statistiken des Remote-Mounts nicht offen."
],
"mountStateTitle": "Statuspunkt und Warnungen je Karte",
"mountStateItems": [
"<green/> <strong>Grün</strong> — Einhängepunkt intakt und erreichbar.",
"<amber/> <strong>Bernsteinfarben</strong> — konfiguriert, aber nicht eingehängt, schreibgeschützt oder <em>Zombie-Bind</em>. Dabei fehlt die Hostquelle, während der CT sie noch als eingehängt sieht, etwa nach Entfernen eines USB-Laufwerks oder <code>umount</code> auf dem Host.",
"<red/> <strong>Rot</strong> — nicht erreichbar: Die Laufzeitprüfung konnte den Einhängepunkt nicht erreichen, etwa eine NFS-Freigabe bei ausgefallenem Server."
],
"mountsCalloutTitle": "Zusätzliche Informationen gegenüber Proxmox",
"mountsCalloutBody": "Zeigt alle Lese- und Schreibziele des Containers samt Kapazität. Im CT eingehängte NFS-/CIFS-Freigaben, die Proxmox nicht anzeigt, erhalten dieselbe Darstellung und Zustandsprüfung. Nicht erreichbare Remote-Mounts und Zombie-Binds werden vor Problemen bei einer Sicherung markiert.",
"logsTitle": "Tab 5 — Protokolle (nur OCI-Container)",
"logsBody": "Nur für Container aus OCI manager Apps. Zeigt die Hauptprozess-Konsole des Images aus <code>/var/log/proxmenux/oci/VMID.console.log</code>: letzte 100, 500 oder 1000 Zeilen, Live-Verfolgung bei laufendem Container, Filter und Download. Die Datei wird beim Öffnen neu gelesen, auch bei gestopptem Container. Details: <ociLink>OCI-Container in ProxMenux Monitor</ociLink>.",
"backupsTitle": "Tab. 6 — Backups",
"backupsImageAlt": "Pro-Gast-Bohr-in-Modal - Backups-Registerkarte mit der verfügbaren Backup-Liste, Ziel-Tag, Größen und der Create Backup-Schaltfläche",
"backupsImageCaption": "Alle Sicherungen dieses Gasts auf konfigurierten Proxmox-Speichern, neueste zuerst. Die Kopfzeile zeigt ihre Anzahl.",
"backupsIntro": "Listet alle Gastsicherungen auf konfigurierten Proxmox-Speichern, neueste zuerst. Der Zähler im Titel zeigt, ob Sicherungen vorhanden sind. Jede Zeile enthält :",
"backupsItems": [
"<strong>Zeitstempel</strong> — Datum und Uhrzeit des Laufs.",
"<strong>Zielanzeige</strong> — Speicherort (PBS-Cloud, PBS-Local, NFS-Backup, …), nach Zustand eingefärbt.",
"<strong>Größe</strong> — endgültige Größe der Sicherung auf dem Datenträger."
],
"backupsOutro": "<strong>+ Sicherung erstellen</strong> startet eine Sicherung auf dem in Proxmox als „Backup target“ markierten Speicher. Die Wiederherstellung erfolgt in der Proxmox-Weboberfläche; Monitor zeigt aktuelle Sicherungen des Gasts und erstellt neue.",
"firewallTitle": "Tab. 7 — Firewall",
"firewallIntro": "Liest das Proxmox-Firewallprotokoll des Gasts direkt vom Host, ohne Zusatzdienst oder regelmäßige Abfragen. Der Reiter ist immer sichtbar; der Inhalt hängt davon ab, ob die Firewall aktiv ist und Regeln tatsächlich protokollieren.",
"firewallItems": [
"<strong>Firewall deaktiviert</strong> — eine bernsteinfarbene Mitteilung erklärt genau, wo sie in der Proxmox-Benutzeroberfläche aktiviert werden soll (<em>&lt;Container|VM&gt; → Firewall → Options</em>) und erinnert Sie daran, dass mindestens eine Regel <code>log: info</code> (oder höher) benötigt, bevor Pakete angezeigt werden.",
"<strong>Firewall aktiv, noch keine Ereignisse</strong> — Hinweis im leeren Bereich auf die nötige Protokollierung, hilfreich direkt nach dem Aktivieren.",
"<strong>Ereignisse vorhanden</strong> — scrollbarer Monospace-Bereich mit Originaleinträgen nach Aktion: <green>ACCEPT</green> grün, <orange>REJECT</orange> orange, <red>DROP</red> rot. Der Zähler im Kopf nennt die geladenen Einträge."
],
"firewallRefresh": "<em>Aktualisieren</em> lädt neue Einträge bei Bedarf. Ohne automatische Abfrage bleibt die Ansicht eine Momentaufnahme des Öffnens oder letzten Aktualisierens. Quelle ist <code>/var/log/pve-firewall.log</code>, nach VMID gefiltert über <code>GET /api/vms/&lt;vmid&gt;/firewall/log</code>.",
"firewallCalloutTitle": "Warum haben Sie es hier, wenn die Proxmox-Benutzeroberfläche es bereits zeigt?",
"firewallCalloutBody": "Spart den Wechsel zur Proxmox-Oberfläche und hält die Ansicht auf dieselbe VMID beschränkt: Gast starten, Einhängepunkte und Firewallereignisse prüfen, Gast wieder stoppen. Regeln werden in Proxmox bearbeitet; Monitor verändert sie nicht.",
"actionBarTitle": "Untere Aktionsleiste",
"actionBarIntro": "Immer sichtbar am Fuß des Modals, unabhängig davon, welcher Tab aktiv ist:",
"consoleItem": "<strong>Konsole</strong> öffnet bei laufenden LXCs <code>pct enter &lt;vmid&gt;</code> im Container. Sie nutzt wie der <link>Terminalreiter</link> xterm.js und WebSocket sowie die <strong>mobile Werkzeugleiste</strong> mit ESC, TAB, Pfeilen, Enter und Ctrl+C / Ctrl+X / Ctrl+R. Damit ist die Bedienung per Telefon oder Tablet möglich. VMs nutzen hier keine Konsole; verwenden Sie Proxmox noVNC.",
"lifecycleIntro": "Darunter stehen vier Schaltflächen im 2×2-Raster. Jede sendet <code>POST /api/vms/&lt;vmid&gt;/control</code> mit der passenden <code>action</code>. Ihre Verfügbarkeit hängt vom Gastzustand ab.",
"headerButton": "Schaltfläche",
"headerEnabled": "Aktiviert, wenn",
"headerAction": "Aktion an Host gesendet",
"lifecycleRows": [
{
"button": "Starten",
"color": "green",
"enabled": "Der Gast ist gestoppt.",
"action": "qm start / pct start"
},
{
"button": "Herunterfahren",
"color": "blue",
"enabled": "Der Gast läuft.",
"action": "qm shutdown / pct shutdown — geordnetes Herunterfahren, ACPI"
},
{
"button": "Neustart",
"color": "blue",
"enabled": "Der Gast läuft.",
"action": "qm reboot / pct reboot — geordneter Neustart"
},
{
"button": "Stopp erzwingen",
"color": "red",
"enabled": "Der Gast läuft.",
"action": "qm stop / pct stop — hartes Ausschalten"
}
],
"forceStopTitle": "Stopp erzwingen schaltet sofort aus",
"forceStopBody": "<strong>Stopp erzwingen</strong> umgeht das Herunterfahren wie ein Ziehen des Stromkabels. Nutzen Sie <strong>Herunterfahren</strong>, solange der Gast reagiert. Erzwingen Sie den Stopp nur bei hängendem Herunterfahren und akzeptiertem Datenverlustrisiko. Farbe und Beschriftung warnen vor versehentlichem Auslösen."
},
"dataCollected": {
"heading": "Wie die Daten gesammelt werden",
"headerSection": "Abschnitt des Reiters",
"headerEndpoint": "Endpunkt",
"headerSource": "Quelle",
"rows": [
{
"section": "Bestandsverzeichnis",
"endpoint": "/api/vms",
"source": "<code>pvesh get /cluster/resources --type vm</code> für VM und CT."
},
{
"section": "Detail-Panel (Konfiguration, Netzwerk, Festplatten)",
"endpoint": "/api/vms/<vmid>",
"source": "<code>qm config &lt;id&gt;</code> für VMs / <code>pct config &lt;id&gt;</code> für CTs."
},
{
"section": "Kennzahlendiagramm pro Gast",
"endpoint": "/api/vms/<vmid>/metrics",
"source": "PVE RRD-Daten (<code>pvesh get /nodes/&lt;node&gt;/qemu/&lt;id&gt;/rrddata</code>) werden zu einer chartfreundlichen Form verdichtet."
},
{
"section": "OCI-Konsolenprotokoll (Registerkarte Logs)",
"endpoint": "/api/lxc/<vmid>/console-log",
"source": "Konsolenausgabe des Hauptprozesses des Images, gelesen aus <code>/var/log/proxmenux/oci/&lt;vmid&gt;.console.log</code> auf dem Host. Nur für OCI-Container angezeigt."
},
{
"section": "Backups für Gäste verfügbar",
"endpoint": "/api/vms/<vmid>/backups",
"source": "<code>pvesm list &lt;storage&gt;</code> durch VMID gefiltert."
},
{
"section": "Pro-Gast-Firewall-Log (Firewall-Tab)",
"endpoint": "/api/vms/<vmid>/firewall/log",
"source": "<code>/var/log/pve-firewall.log</code> durch VMID gefiltert."
},
{
"section": "Einschalttasten (Start / Stop / Reboot / Shutdown)",
"endpoint": "/api/vms/<vmid>/control",
"source": "<code>qm start|stop|reboot|shutdown</code> oder <code>pct</code>-Äquivalente."
}
],
"codeComment1": "# Dashboard-Daten mit PVE abgleichen",
"codeComment2": "# Gastkonfiguration genau wie im Detaildialog prüfen",
"codeComment3": "# VM",
"codeComment4": "# CT"
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "Gesundheitsmonitor",
"href": "/docs/monitor/health-monitor",
"tailRich": " — Kategorie VMs und Container: Startfehler, QMP-Zeitüberschreitungen und CT-Herunterfahrfehler."
},
{
"label": "Benachrichtigungen",
"href": "/docs/monitor/notifications",
"tailRich": "— was die <code>vm_*</code>, <code>ct_*</code>, <code>migration_*</code> und <code>backup_*</code> Ereignisse nachgeschaltet auslösen."
},
{
"label": "API-Referenz",
"href": "/docs/monitor/api",
"tailRich": " — die Endpunkte für VMs und Sicherungen."
},
{
"label": "Dashboard-Index",
"href": "/docs/monitor/dashboard",
"tailRich": " — die anderen Reiter."
},
{
"label": "ProxMenux: VM erstellen",
"href": "/docs/create-vm",
"tailRich": " — Bereitstellung: NAS-Systemvorlagen (Synology und andere), Linux-/Windows-VMs und für Proxmox angepasste Standardwerte."
}
]
}
}
@@ -0,0 +1,372 @@
{
"meta": {
"title": "Proxmox-Zustandsüberwachung — CPU, Arbeitsspeicher, Datenspeicher, SMART, ZFS, Protokolle | ProxMenux",
"description": "Proaktive Zustandsüberwachung für Proxmox VE: zehn Kategorien alle fünf Minuten (CPU und Temperatur, Arbeitsspeicher und Swap, Datenspeicher, Laufwerke/SMART, Netzwerk, VMs, Dienste, Protokolle, Updates und Sicherheit), vier Schweregrade, Unterdrückungsdauer je Kategorie, automatische Bereinigung behobener Fehler, dauerhafter Laufwerksverlauf und Meldungen über Telegram, Discord, Gotify oder E-Mail.",
"ogTitle": "Proxmox-Zustandsüberwachung — CPU, Arbeitsspeicher, Datenspeicher, SMART, ZFS, Protokolle",
"ogDescription": "Proaktive Zustandsüberwachung für Proxmox VE in zehn Kategorien, mit Schweregraden, Unterdrückungsdauer und ereignisbasierten Benachrichtigungen.",
"twitterTitle": "Proxmox Gesundheitsmonitor | ProxMenux",
"twitterDescription": "Proaktive Zustandsüberwachung für Proxmox VE in zehn Kategorien mit Schweregraden und Benachrichtigungen."
},
"header": {
"title": "Gesundheitsmonitor",
"description": "Die fortlaufende Selbstprüfung untersucht zehn Kategorien des Hostzustands im Fünfminutentakt. Dazwischen erfasst sie Messwerte, fasst doppelte Befunde zu strukturierten Ereignissen zusammen und versorgt Dashboard, Benachrichtigungen und optionale KI-Überarbeitung aus derselben Datenquelle.",
"section": "ProxMenux-Monitor"
},
"intro": {
"title": "Ein Scanner, drei Verbraucher",
"body": "Ein Hintergrundthread führt alle fünf Minuten die vollständige Prüfung aus und speichert jeden Befund unter einem stabilen <code>error_key</code> in SQLite. Damit kann <strong>(1)</strong> das Dashboard den aktuellen Zustand anzeigen, <strong>(2)</strong> das Benachrichtigungssystem neue Ereignisse an die eingerichteten Kanäle verteilen und <strong>(3)</strong> der optionale KI-Assistent Warnungen verständlich umformulieren. Eine Konfiguration versorgt alle nachfolgenden Komponenten."
},
"howItWorks": {
"heading": "Wie es funktioniert",
"intro": "Die Zustandsüberwachung nutzt zwei parallele Threads. Ein leichter <strong>Messwertsammler</strong> füllt Verlaufspuffer für CPU, Arbeitsspeicher und Temperatur. Der <strong>vollständige Prüfzyklus</strong> liest die Puffer, bewertet anhaltende Zustände und führt etwa alle fünf Minuten die übrigen Prüfungen aus. Anschließend speichert er Befunde für Dashboard und Benachrichtigungen in SQLite.",
"scannerTitle": "Von der Probe zum gespeicherten Befund",
"scannerCaption": "Der Sammler füllt zwischen den Prüfzyklen Verlaufspuffer: CPU alle 5 s, Arbeitsspeicher alle 30 s und Temperatur alle 15 s. Er wertet selbst keine Warnungen aus. Der vollständige Zyklus bewertet die Puffer und führt aufwendigere Prüfungen für SMART, ZFS, Protokolle und Dienste aus, bevor er Befunde in SQLite speichert.",
"scannerArrowLabel": "Schritt",
"scannerNodes": {
"samplerLabel": "Messwertsammler",
"samplerDetail": "CPU-Auslastung 5 s\nArbeitsspeicher 30 s\nTemperatur 15 s\n→ Verlaufspuffer",
"cycleLabel": "Vollständiger Gesundheitszyklus",
"cycleDetail": "Alle 5 min\nLiest Puffer\n+ aktuelle Prüfungen\n(SMART, ZFS,\nDienste, Journal …)",
"checksLabel": "Prüfungen nach Kategorien",
"checksDetail": "Zehn Kategorien\n(CPU, Arbeitsspeicher,\nDatenspeicher, Laufwerke,\nNetzwerk, VMs,\nDienste, Protokolle,\nUpdates, Sicherheit)",
"sqliteLabel": "SQLite",
"sqliteDetail": "Tabelle errors\n(aktiv +\nunterdrückt)\n+ disk_observations\n(dauerhafter Verlauf\nje Laufwerk)"
},
"notifTitle": "Vom gespeicherten Befund zum Benutzer",
"notifCaption": "Der Meldepfad. Die gleiche Fehlertabelle steuert auch die Dashboard-Ansicht (Active / Dismissed-Listen live gerendert) und wird von der Bereinigungsroutine am Ende jedes Zyklus verbraucht, um veraltete Einträge automatisch aufzulösen - beide laufen aus den gleichen Daten, ohne den Dispatcher zu durchlaufen.",
"notifArrowLabel": "Ereignis",
"notifNodes": {
"errorsLabel": "Fehlertabelle",
"errorsDetail": "Aktive +\nunterdrückte Zeilen\nmit Schlüssel\nerror_key",
"dispatcherLabel": "Benachrichtigungsversender",
"dispatcherDetail": "Neue + verschärfte\nEreignisse einreihen\nNach Schaltern\n+ Sperrzeit",
"templatesLabel": "Vorlagen + KI-Überarbeitung",
"templatesDetail": "Vorlage\nje Ereignis\n→ optionale KI-\nÜberarbeitung in\nverständliche Sprache",
"channelsLabel": "Kanäle",
"channelsDetail": "Telegram\nDiscord\nGotify\nE-Mail (SMTP)"
}
},
"categories": {
"heading": "Die zehn Kategorien",
"imageAlt": "Zustandsüberwachung mit zehn Kategorien und aktuellem Status: CPU, Arbeitsspeicher, Datenspeicher, Laufwerke, Netzwerk, VMs, Dienste, Protokolle, Updates und Sicherheit",
"imageCaption": "Health Monitor Ansicht - die zehn Kategorien mit ihrem aktuellen Status. Kategorien auf einem gesunden Host zeigen alle OK; Warnungen und kritische Ereignisse erscheinen inline mit den Zeilen, die sie erzeugt haben.",
"intro": "Jeder Zyklus führt zehn unabhängige Prüfungen aus. Jede liefert einen von vier Zuständen (<strong>OK</strong>, <strong>INFO</strong>, <strong>WARNING</strong>, <strong>CRITICAL</strong>) und strukturierte Daten wie Gerätenamen, Protokollauszüge und genaue Schwellenwerte. Diese erscheinen im Dashboard und im Benachrichtigungstext.",
"headerCategory": "Kategorie",
"headerChecks": "Sub-Kontrollen",
"headerEvents": "Typische Ereignisse",
"rows": [
{
"category": "CPU & Temperatur",
"checks": "CPU Nutzung mit Hysterese, Sensortemperatur",
"events": "Anhaltend hohe CPU-Auslastung; Temperaturwarnungen anhand gesammelter Sensormesswerte."
},
{
"category": "Arbeitsspeicher & Swap",
"checks": "RAM Nutzung, Swap Nutzung",
"events": "Anhaltender Speicherdruck; Aktivität des OOM-Killers; ausgeschöpfter Swap."
},
{
"category": "Speicher",
"checks": "Proxmox-Speicher, Root-Dateisystem",
"events": "Konfigurierte Belegungsschwellen auf Root oder anderen überwachten Dateisystemen überschritten (standardmäßig 85% Warnung / 95% kritisch); nicht verfügbare PVE-Speicher; hängende oder unerwartet schreibgeschützte NFS-/CIFS-Einhängungen; LVM-thin- und andere Pool-Speicher, die dieselben Schwellen überschreiten."
},
{
"category": "Platten und SMART",
"checks": "SMART, dmesg I/O-Fehler, ZFS Pools, LVM, Dateisystemfehler",
"events": "SMART-Gesundheit fehlgeschlagen; neu zugewiesene / ausstehende Sektoren; ATA-I / O-Fehler; ZFS-Pool DEGRADED / FAULTED; ext4-Read-only-Remount."
},
{
"category": "Netzwerk",
"checks": "Konnektivität, Verbindungszustand, Gateway-Latenz",
"events": "Brücken- oder Bond-Down; Gateway nicht erreichbar; persistente Latenzspitzen."
},
{
"category": "VMs und Container",
"checks": "QMP Kommunikation, VM Startup, Container Startup",
"events": "Fehlgeschlagener VM-Boot; CT-Abschaltungsfehler; QMP-Sockel-Timeout; fehlende Konfiguration / Festplatte nach einem Klon."
},
{
"category": "PVE-Dienste",
"checks": "<code>pveproxy</code>, <code>pvedaemon</code>, <code>pvestatd</code>, <code>pve-cluster</code>, Cluster-Modus",
"events": "Dienst abgestürzt; Cluster-Quorum verloren; <code>pmxcfs</code> hängt."
},
{
"category": "Systemprotokolle",
"checks": "Persistente Fehler, Fehlerspitzen, Fehlerkaskaden, kritische Kernelmeldungen",
"events": "Wiederholte identische Fehler; plötzliches Warnsignal (Kaskadenmuster); <code>BUG:</code> / <code>OOPS:</code> / <code>oom-killer</code> in dmesg."
},
{
"category": "Systemaktualisierungen",
"checks": "Ausstehende Updates, Sicherheitsupdates, Kernel / PVE-Version, Systemalter",
"events": "Ausstehende Sicherheits- oder Kernelupdates; lange nicht aktualisiertes System. Die Kategorie Updates im Dialog zum Gesundheitszustand zeigt bei ausstehenden Updates die Schaltfläche <em>Jetzt aktualisieren</em>. Sie startet den vollständigen ProxMenux-Updateablauf direkt im Dialog; beim Schließen wird der Zustand mit <code>?refresh=1</code> neu abgefragt, damit die Anzeige den neuen Zustand ohne Warten auf den nächsten Zyklus widerspiegelt."
},
{
"category": "Sicherheit & Zertifikate",
"checks": "Anmeldeversuche, Zertifikate laufen ab, optionaler Fail2Ban jail Status",
"events": "Wiederholte fehlgeschlagene SSH- oder Webanmeldungen; PVE-Zertifikat läuft in weniger als 30 Tagen ab; aktive Fail2Ban-Sperren."
}
]
},
"severity": {
"heading": "Schweregradmodell",
"headerStatus": "Status",
"headerColour": "Farbe",
"headerMeaning": "Bedeutung",
"headerNotification": "Benachrichtigung",
"rows": [
{
"status": "OK",
"colour": "Grün",
"meaning": "Gesund. Keine Befunde in dieser Kategorie.",
"notification": "Keine Benachrichtigung."
},
{
"status": "INFO",
"colour": "Blau",
"meaning": "Vorübergehender oder bereits behobener Zustand, der es wert ist, einmal notiert zu werden. Wird auch für Kategorien verwendet, die <em>nur noch</em> verworfene Elemente übrig haben.",
"notification": "Fakultativ. Jeder Ereignistyp kann pro Kanal ein- oder ausgeschaltet werden."
},
{
"status": "WARNING",
"colour": "Gelb",
"meaning": "Aufmerksamkeit ist erforderlich, aber der Host ist immer noch funktionsfähig. Ursache ist nicht trivial - lesen Sie die Details.",
"notification": "Wird gesendet, wenn der Ereignisschalter für diesen Kanal aktiv ist."
},
{
"status": "CRITICAL",
"colour": "rot",
"meaning": "Funktionalität gebrochen oder Datenverlust möglich. Erforderliche Maßnahmen.",
"notification": "Wird gesendet, wenn der Ereignisschalter für den Kanal aktiv ist. Eine CPU-Temperaturmeldung mit CRITICAL löst als Sicherheitswarnung auch nach vorheriger Bestätigung erneut aus."
}
],
"infoNote": "Eine Kategorie mit <strong>OK</strong>, die noch unterdrückte Ereignisse mit laufender Frist enthält, erscheint als <strong>INFO</strong>. So bleibt sichtbar, dass Meldungen unterdrückt werden.",
"unknownTitle": "UNKNOWN, wenn eine Prüfung nicht abgeschlossen werden kann",
"unknownBody": "Eine nicht verfügbare Prüfung liefert <code>UNKNOWN</code>. Nach drei aufeinanderfolgenden Zyklen wird ein dauerhafter Befund gespeichert. Das Dashboard zeigt die Prüfung gelb an. Im Gesamtzustand ist <code>UNKNOWN</code> auf <strong>WARNING</strong> begrenzt; eine fehlende Prüfung allein macht den Host nicht kritisch."
},
"dashboardView": {
"heading": "Die Dashboard-Ansicht",
"intro": "Die Zustandsüberwachung befindet sich auf der Registerkarte <strong>Übersicht</strong>. Die Statusanzeige im Kopfbereich (Gesund / Warnung / Kritisch) öffnet ein Dialogfenster mit zwei Listen:",
"items": [
"<strong>Aktiv</strong> — Kategorien mit ungelösten Befunden. Aufgeklappte Zeilen zeigen die auslösenden Einzelprüfungen, den ursprünglichen Text in <code>reason</code>, die Geräte- oder VM-ID und gegebenenfalls einen Link zu Datenspeicher, Netzwerk, VMs, Protokollen oder Hardware.",
"<strong>Unterdrückt</strong> — vom Benutzer bestätigte Einträge mit noch laufender Unterdrückungsfrist. Jede Zeile zeigt Restzeit und eingestellte Dauer. Nach Ablauf verschwindet sie aus dieser Liste. Besteht die Ursache weiter und unterstützt die Kategorie erneutes Auslösen, erscheint der Eintrag wieder unter <em>Aktiv</em>."
],
"pillTitle": "Die Statusanzeige folgt der schwerwiegendsten Kategorie",
"pillBody": "Die Farbe im Dashboard-Kopf folgt dem höchsten Schweregrad: CRITICAL → rot, sonst WARNING → gelb, sonst INFO → blau, sonst grün. Dieselbe Logik steuert den Punkt im Favicon und das PWA-Symbol.",
"updateNowTitle": "Schaltfläche Jetzt Aktualisieren im Overview-Header",
"updateNowBody1": "Meldet <em>Systemupdates</em> ausstehende Updates, erscheint neben der Statusanzeige <strong>Jetzt aktualisieren</strong>. Der Dialog startet denselben Hostablauf wie <em>ProxMenux → Settings post-install Proxmox → Proxmox System Update</em>: Repository-Bereinigung, <code>apt full-upgrade</code> über <code>update-pve-safe.sh</code>, DKMS-Neubau verwalteter Treiber bei neuem Kernel, autoremove/autoclean und gegebenenfalls eine Neustartabfrage. Der Fortschritt wird laufend angezeigt.",
"updateNowBody2": "Nach Abschluss ruft das Schließen des Dialogs <code>GET /api/health/details?refresh=1</code> auf und verwirft damit den Cache dieses Endpunkts. Ausstehende Updates und Statusanzeige werden anhand des neuen Paketstands neu berechnet. Der Hinweis verschwindet ohne Warten auf den nächsten Zyklus. Auf einem aktuellen Host bleibt die Schaltfläche verborgen."
},
"dismiss": {
"heading": "Warnungen bestätigen und die Unterdrückungsdauer",
"intro": "Manche Ereignisse bleiben naturgemäß lange bestehen: <em>Systemupdates: Updates verfügbar</em> gilt bis zur Aktualisierung des Hosts, und eine Nachricht alle fünf Minuten über eine ganze Woche ist nicht erwünscht. Die Schaltfläche <em>Jetzt aktualisieren</em> in der Kategorie Updates des Dialogs zum Gesundheitszustand behebt genau diesen Fall direkt. Für andere Fälle oder aufgeschobene Updates bietet die Zustandsüberwachung zudem zwei verbundene Möglichkeiten zum Unterdrücken von Meldungen:",
"step1": "<strong>Einzelnes Ereignis bestätigen</strong> im Dialog. Das Menü bietet <strong>24 Stunden</strong>, <strong>7 Tage</strong> oder <strong>Dauerhaft</strong>, unabhängig vom Kategoriestandard. Die Auswahl sendet <code>POST /api/health/acknowledge</code> mit <code>error_key</code> und gewählten <code>suppression_hours</code> (<code>-1</code> für dauerhaft). Das Ereignis wechselt mit Zeitstempel <code>acknowledged_at</code> in die unterdrückte Liste.",
"dropdownImageAlt": "Menü zum Unterdrücken einer Warnung: 24 Stunden, 7 Tage oder dauerhaft",
"dropdownImageCaption": "Die gewählte Dauer gilt nur für diese Warnung; ohne Einzelauswahl greift der Kategoriestandard. Dauerhafte Bestätigungen erhalten die bernsteinfarbene Markierung <em>Dauerhaft</em> und lösen normalerweise nicht erneut aus. Eine Ausnahme ist die unten beschriebene kritische CPU-Temperatur.",
"step2": "<strong>Unterdrückungsdauer je Kategorie</strong>. Unter Einstellungen → Zustandsüberwachung oder über <code>POST /api/health/settings</code> lässt sich für jede der zehn Kategorien die Standarddauer ohne Einzelauswahl festlegen:",
"imageAlt": "Einstellung der Unterdrückungsdauer je Kategorie unter Einstellungen → Zustandsüberwachung",
"imageCaption": "Ein Auswahlmenü je Kategorie. Für häufige Meldungen wie ausstehende Updates eignet sich eine längere Dauer, für schnell neu zu bewertende Ereignisse eine kürzere. Darunter stehen die aktiven Unterdrückungen.",
"outro": "Während der Unterdrückung läuft die Prüfung weiter und aktualisiert <code>last_seen</code>, ohne neue Meldung. Nach Ablauf bewertet der nächste Zyklus die Ursache erneut: Er löst gegebenenfalls wieder aus oder entfernt den Eintrag, wenn der Zustand behoben ist.",
"activeSuppressionsTitle": "Bestätigungen prüfen und aufheben — Aktive Unterdrückungen",
"activeSuppressionsBody": "Alle zeitweise oder dauerhaft unterdrückten Warnungen stehen unter <strong>Einstellungen → Zustandsüberwachung → Aktive Unterdrückungen</strong>. Jede Zeile zeigt Kennung, Kategorie, Schweregrad, Bestätigungszeit und Restzeit. <strong>Wieder aktivieren</strong> hebt die Bestätigung für den nächsten Scan auf. Dauerhafte Bestätigungen lassen sich hier zurücknehmen, zeitlich begrenzte vorzeitig beenden. Aktivieren Sie <em>Bearbeiten</em>, wählen Sie die gewünschten Zeilen (grüner Rand und durchgestrichen) und speichern Sie. Abbrechen verwirft die Auswahl.",
"autoTitle": "Automatische Unterdrückung nach Änderung der Dauer",
"autoBody": "Ein anderer Wert als die standardmäßigen 24 Stunden hat eine zweite Wirkung: <strong>Neue Befunde der Kategorie werden bereits bestätigt gespeichert</strong>. Eine eingestellte Woche für Laufwerksmeldungen gilt damit auch für neue Meldungen, ohne jede einzeln zu bestätigen. Sie erscheinen direkt unter Unterdrückt mit der gewählten Restzeit. Kategorien mit 24 Stunden behalten das normale Verhalten: Neue Befunde bleiben aktiv, bis Sie handeln.",
"tempTitle": "Ausnahme für CPU-Temperatur CRITICAL",
"tempBody": "Die Persistenzschicht besitzt eine Sonderregel für <strong>CPU-Temperatur CRITICAL</strong>: Ein solcher Datensatz umgeht frühere Bestätigung und automatische Unterdrückung. Daraus folgt nicht, dass jede Temperaturprüfung beim Überschreiten eines konfigurierten kritischen Werts einen kritischen Datensatz erzeugt.",
"nonDismissableTitle": "Welche Befunde lassen sich bestätigen?",
"nonDismissableBody": "Der Dialog zeigt Bestätigen nur, wenn die Einzelprüfung ausdrücklich dismissable = true liefert. Bei false oder fehlendem Feld bleibt die Schaltfläche verborgen. Der Schweregrad bestimmt diese Erlaubnis nicht: Mehrere kritische Prüfungen erlauben eine Bestätigung. Die Beispiele beschreiben aktuelle Daten; Unterdrücken behebt keine Ursache.",
"headerFinding": "Feststellung",
"headerWhy": "Verhalten beim Bestätigen",
"rows": [
{
"finding": "CPU-Temperatur: Warnung / kritisch",
"why": "Die aus Messwerten ermittelte Temperaturwarnung erlaubt ausdrücklich die Bestätigung. Eine separate Persistenzregel umgeht sie, wenn ein CPU-Temperaturdatensatz mit CRITICAL eintrifft."
},
{
"finding": "Kritische Belegung des Root-Dateisystems",
"why": "Die Belegungsprüfungen erlauben ausdrücklich die Bestätigung, auch bei kritischer Auslastung. Sie schafft weder Platz noch beseitigt sie das Risiko fehlgeschlagener Schreibzugriffe."
},
{
"finding": "ZFS pool DEGRADED / FAULTED",
"why": "Befunde zum ZFS-Poolzustand (DEGRADED, FAULTED, UNAVAIL) erlauben ausdrücklich die Bestätigung, ebenso Prüfungen der Poolbelegung. Bestätigen repariert keinen beeinträchtigten oder ausgefallenen Pool."
},
{
"finding": "Festplatten-I/O-Fehler mit SMART FAILED",
"why": "Gespeicherte Laufwerksbefunde aus dem Journal können eine Bestätigung erlauben. SMART FAILED muss trotzdem untersucht werden; die Schaltfläche hängt vom Kennzeichen der Einzelprüfung ab, nicht nur vom Warntext."
},
{
"finding": "Netzschnittstelle DOWN",
"why": "Gespeicherte Schnittstellenprüfungen mit DOWN erlauben ausdrücklich die Bestätigung. Das stellt weder Bridge, Bond noch physische Verbindung oder Fernzugriff wieder her."
},
{
"finding": "I/O-Ereignisse auf gesunden Festplatten (INFO)",
"why": "Vorübergehende ATA- oder dmesg-Ereignisse bei gesundem SMART können rein informativ sein und sich selbst auflösen. Solche Zeilen brauchen keine Bestätigungsschaltfläche; die Prüfung bestimmt, wann der Zustand behoben ist."
}
],
"principle": "Nutzen Sie die beim tatsächlichen Befund angebotene Schaltfläche, statt ihre Verfügbarkeit aus Kategorie oder Schweregrad abzuleiten. Die Bestätigung steuert Anzeige und Meldungen. Wiederherstellungsprüfungen und Laufwerksverlauf bleiben davon getrennt."
},
"autoresolve": {
"heading": "Autoauflösung und Reinigung",
"intro": "Viele Warnungen sollen verschwinden, wenn die Ursache entfällt: eine VM startet wieder, ein Laufwerk wurde entfernt oder die Temperatur ist wieder normal. Die Bereinigung am Ende jedes Fünfminutenzyklus wendet diese Regeln an:",
"headerTrigger": "Trigger",
"headerAction": "Aktion",
"rows": [
{
"trigger": "CPU-Auslastung / Temperatur wieder normal.",
"action": "Als behoben markiert; verschwindet aus der aktiven Liste."
},
{
"trigger": "Speicherdruck wieder unterhalb der Warnschwelle nach einer OOM / Memory Warnung.",
"action": "Als behoben markiert."
},
{
"trigger": "VM / CT, auf den der Fehler verweist, existiert nicht mehr (<code>qm status</code> / <code>pct status</code> ungleich Null).",
"action": "Aufgelöst als entfernte Ressource markiert."
},
{
"trigger": "Disk, auf den der Fehler verwiesen wird, ist in <code>/dev/</code> nicht mehr vorhanden.",
"action": "Markiert aufgelöst als entferntes Gerät. Die permanente Beobachtungsgeschichte bleibt erhalten (siehe nächster Abschnitt)."
},
{
"trigger": "Befunde aus dem Systemjournal (Kategorie <code>logs</code>, SMART-Einträge, ATA-/I/O-Fehler), deren Unterdrückungsfrist abläuft.",
"action": "Werden entfernt. Jeder Scan prüft ab diesem Zeitpunkt neue Journaleinträge; dieselbe historische Zeile wird nicht erneut ausgegeben."
},
{
"trigger": "Seit mehr als sieben Tagen behobene Fehler.",
"action": "Aus der Datenbank gelöscht, um die Tabelle klein zu halten. Die Benachrichtigungshistorie ist unabhängig und wird länger aufbewahrt."
}
],
"permanentTitle": "Dauerhaft unterdrückt bedeutet nicht behoben",
"permanentBody": "Die Kategoriedauer <code>-1</code> (<em>dauerhaft</em>) unterdrückt weitere Warnungen für bestätigte Einträge, überspringt aber nicht die automatische Prüfung. Entfällt die Ursache, etwa nach Löschen der Ressource oder Unterschreiten des Schwellenwerts, wird der Eintrag weiterhin automatisch bereinigt."
},
"observations": {
"heading": "Laufwerksbeobachtungen — der dauerhafte Verlauf",
"intro": "Laufwerksereignisse sollen erhalten bleiben. Eine SMART-Warnung auf <code>/dev/sdh</code> um 02:14 Uhr bleibt wichtig, auch wenn die I/O-Störung vorbei und der Fehler automatisch behoben ist. Das Laufwerk hat nun eine Vorgeschichte. Dafür führt die Zustandsüberwachung eine separate <strong>dauerhafte</strong> Tabelle: <code>disk_observations</code>.",
"headerProperty": "Eigenschaft",
"headerErrors": "Tabelle <code>errors</code> (Aktiv)",
"headerObs": "Tabelle <code>disk_observations</code>",
"rows": [
{
"property": "Zweck",
"errors": "Versorgt die <em>aktuelle</em> Zustandsansicht und den Benachrichtigungsversand.",
"obs": "Dauerhaftes Prüfprotokoll je Laufwerk."
},
{
"property": "Automatische Auflösung",
"errors": "Ja — Zeilen werden gelöscht, wenn die Bedingung verschwindet.",
"obs": "Nein - Einträge bleiben für immer bestehen, es sei denn, der Benutzer weist sie ausdrücklich ab."
},
{
"property": "Deduplizierungsschlüssel",
"errors": "<code>error_key</code> (z.B. <code>smart_sdh</code>).",
"obs": "<code>(disk_registry_id, error_type, error_signature)</code> mit stabilen Signaturen, die von flüchtigen Daten befreit sind."
},
{
"property": "Wo gezeigt",
"errors": "Dialog der Zustandsüberwachung (Listen Aktiv / Unterdrückt).",
"obs": "Laufwerksdetailkarte auf der Registerkarte <strong>Datenspeicher</strong>, mit „X obs.“ je Laufwerk."
},
{
"property": "Was es aufzeichnet",
"errors": "Was auch immer derzeit scheitert.",
"obs": "SMART-Warnungen (Sektorprobleme / Temperatur / CRC / fehlgeschlagene Selbsttests), I/O-Fehler (ATA / NVMe/dm), Dateisystemfehler, ZFS-Poolereignisse."
}
],
"outro": "Eine Warnung kann aus dem Dashboard verschwinden, während der Vorfall im Laufwerksverlauf bleibt. Die Detailkarte unter Datenspeicher zeigt die Anzahl offener Beobachtungen sowie Zeitstempel, Schweregrad und ursprünglichen Rohtext. Das hilft bei der Entscheidung über einen Austausch.",
"renameTitle": "Geänderte Gerätenamen werden automatisch zusammengeführt",
"renameBody": "Laufwerke können zunächst unter vorläufigen Namen wie <code>ata8</code> oder <code>nvme0n1p3</code> erscheinen. Die Beobachtungsschicht ordnet Einträge anhand bekannter Seriennummern zu: Wird derselbe Datenträger später als <code>sdh</code> erkannt, werden frühere Beobachtungen zu <code>ata8</code> im nächsten Zyklus an <code>sdh</code> angehängt. Der Verlauf bleibt zusammenhängend."
},
"notification": {
"heading": "Vom Befund zur Benachrichtigung",
"intro": "Jeder aktive Fehler ist auch ein Kandidat für die Benachrichtigungsmaschine. Der Fluss:",
"items": [
"Der Scanner zeichnet den Befund mit Kategorie + Schweregrad + strukturierten Details auf.",
"Ist der Ereignistyp in den globalen Benachrichtigungen <strong>aktiviert</strong> und hat der Kanal die Kategorie nicht stummgeschaltet, wird ein Ereignis eingereiht.",
"Die Vorlagenlogik erzeugt aus den strukturierten Daten Titel und Text. Bei aktivierter KI-Überarbeitung erhält der eingerichtete Anbieter dieses Paar für eine verständliche Fassung.",
"Die Kanalimplementierung versendet es: Telegram Nachricht, Discord Einbettung, Gotify Push oder E-Mail. Das Versandergebnis wird in <code>notification_history</code> gespeichert.",
"Bestätigen startet die Unterdrückungsfrist. Weitere Erkennungen desselben <code>error_key</code> erzeugen währenddessen normalerweise keine Meldung und werden nicht automatisch für das Fristende eingereiht. Die Ausnahme für kritische CPU-Temperatur bleibt bestehen."
],
"outro": "Die Kanalkonfiguration mit Telegram-Bot-Token, Webhook-URLs, KI-Schlüsseln, Ereignisschaltern und Kanalanpassungen ist unter <notifLink>Benachrichtigungen</notifLink> und <aiLink>KI-Assistent</aiLink> beschrieben."
},
"rest": {
"heading": "REST-Endpunkte",
"intro": "Die Dialogaktionen sind auch per API für Skripte, eigene Dashboards und Chatbots verfügbar. Aufrufe benötigen ein gültiges Bearer-Token aus Anmeldung oder API-Tokenverwaltung. Änderungen wie das Bestätigen von Warnungen, das Speichern von Unterdrückungseinstellungen oder das Bereinigen verwaister Fehler erfordern den Bereich full_admin; read_only erhält 403.",
"headerEndpoint": "Endpunkt",
"headerMethod": "Methode",
"headerUse": "Verwendung",
"rows": [
{
"endpoint": "/api/health",
"method": "GET",
"use": "Leichte Zustandsabfrage mit JSON-Feldern <code>status</code>, <code>timestamp</code> und <code>version</code>. Für Schlüsselwortprüfungen in Uptime Kuma geeignet; der Client muss einen Bearer-Header senden."
},
{
"endpoint": "/api/health/status",
"method": "GET",
"use": "Gesamtzustand mit einem Schweregrad und einer Zusammenfassung. Authentifiziert."
},
{
"endpoint": "/api/health/details",
"method": "GET",
"use": "Alle zehn Kategorien mit jeweiligem Status und den zugrunde liegenden strukturierten Daten."
},
{
"endpoint": "/api/health/full",
"method": "GET",
"use": "Vollständige Momentaufnahme: Kategorien, aktive und unterdrückte Fehler sowie eigene Unterdrückungsdauer. Versorgt den Dialog mit einer Anfrage und nutzt für schnelle Antworten einen sechs Minuten gültigen Hintergrundcache."
},
{
"endpoint": "/api/health/active-errors",
"method": "GET",
"use": "Nur die aktive Liste. Filterbar durch <code>?category=&lt;name&gt;</code>."
},
{
"endpoint": "/api/health/dismissed",
"method": "GET",
"use": "Nur die unterdrückten Einträge mit verbleibenden Stunden."
},
{
"endpoint": "/api/health/acknowledge",
"method": "POST",
"use": "Körper: <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Deaktivieren Sie eine Warnung mit dem konfigurierten Fenster der Kategorie."
},
{
"endpoint": "/api/health/settings",
"method": "GET / POST",
"use": "Lesen oder schreiben Sie die Werte für die Unterdrückungsdauer pro Kategorie."
},
{
"endpoint": "/api/health/cleanup-orphans",
"method": "POST",
"use": "Manuelle Bereinigung von Fehlern, deren zugrunde liegendes Gerät / VM verschwunden ist. Idempotent."
}
],
"codeComment1": "# Aktuellen Zustand für ein Skript abrufen",
"codeComment2": "# Verwerfen Sie einen bestimmten Fehler",
"codeComment3": "# Setzen Sie die Unterdrückung der Festplatten-Kategorie auf eine Woche"
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "Dashboard",
"href": "/docs/monitor/dashboard",
"tail": " — hier lässt sich der Dialog der Zustandsüberwachung öffnen."
},
{
"label": "Benachrichtigungen",
"href": "/docs/monitor/notifications",
"tail": " — Kanäle, Ereignisschalter, KI-Überarbeitung und Verlauf."
},
{
"label": "KI-Assistent",
"href": "/docs/monitor/ai-assistant",
"tail": " — Anbieter (OpenAI / Anthropic / Gemini / Groq / Ollama / OpenRouter), Promptmodus, Detailgrad je Kanal und Sprache."
},
{
"label": "Architektur",
"href": "/docs/monitor/architecture",
"tailRich": "— das SQLite-Schema (<code>errors</code>, <code>disk_observations</code>, <code>events</code>) und die Hintergrund-Thread-Kadenz."
}
]
}
}
+151
View File
@@ -0,0 +1,151 @@
{
"meta": {
"title": "ProxMenux Monitor – Selbstgehostetes Web-Dashboard für Proxmox VE | ProxMenux",
"description": "ProxMenux Monitor ist ein selbst gehostetes Web-Dashboard für Proxmox VE: Echtzeit-Hostmetriken, Speicher und SMART Daten, Netzwerk, VMs und Container, Hardware, Protokolle, ein integriertes Web-Terminal, ein proaktiver Health Monitor, Benachrichtigungen an Telegram / Discord / E-Mail, ein optionaler KI-Assistent, ein REST API und Integrationen mit Tools wie Homepage und Home Assistant.",
"ogTitle": "ProxMenux Monitor – Selbstgehostetes Web-Dashboard für Proxmox VE",
"ogDescription": "Echtzeit-Dashboard Proxmox VE: Hostmetriken, Speicher SMART, Netzwerk, VMs und Container, Hardware, Protokolle, Webterminal, Gesundheitsmonitor, Benachrichtigungen, KI-Assistent, REST API.",
"twitterTitle": "ProxMenux Monitor | ProxMenux",
"twitterDescription": "Selbst gehostetes Proxmox VE Dashboard mit Health Monitor, Benachrichtigungen, KI-Assistent und REST API."
},
"header": {
"title": "ProxMenux Monitor",
"description": "Ein selbst gehostetes Proxmox-VE-Web-Dashboard als AppImage. Es läuft als einzelner systemd-Dienst auf dem Host, lauscht auf TCP-Port 8008 und stellt API und Oberfläche aus einem Prozess bereit.",
"section": "ProxMenux Monitor"
},
"atGlance": {
"title": "Auf einen Blick",
"body": "Einzelner AppImage auf dem Proxmox-Host → Flask Backend (Port 8008), der Live-Daten über <code>psutil</code>, <code>pvesh</code>, <code>smartctl</code>, <code>journalctl</code> sammelt → Next.js-Dashboard, das vom selben Prozess bereitgestellt wird. Optionale Authentifizierung (Passwort + 2FA), optionaler KI-Assistent, optionale Benachrichtigungen, REST API für Integrationen."
},
"hero": {
"alt": "ProxMenux Monitor Dashboard – Systemübersichtsbildschirm mit CPU, Speicher-, Temperatur- und Betriebszeit-Widgets",
"caption": "Standard-Startbildschirm – Metriken und Gesundheitszustand auf Hostebene auf einen Blick."
},
"coverage": {
"heading": "Was das Dashboard abdeckt",
"intro": "Acht erstklassige Abschnitte, jeder unterstützt durch seine eigenen API Endpunkte:",
"tableSection": "Abschnitt",
"tableWhat": "Was angezeigt wird",
"sections": [
{
"name": "Gesundheitsmonitor",
"description": "Aktive und verworfene Warnungen für CPU, Arbeitsspeicher, Speicher, Festplatten, Netzwerk, Dienste, Protokolle, VMs, Updates und Sicherheit. Steuert die Benachrichtigungs-Engine."
},
{
"name": "Speicher",
"description": "Proxmox-Speicher pools, physische Festplatten (SATA / NVMe / USB), SMART Attribute, ZFS pool Status, Verschleiß und Lebensdauer, I/O-Aktivität."
},
{
"name": "Netzwerk",
"description": "Alle Schnittstellen (physisch, Bonds, Bridges, OVS), IP/MAC/Status, Echtzeit-RX/TX-Diagramme, historische RRD-Daten pro Schnittstelle."
},
{
"name": "VMs und Container",
"description": "VM-/LXC-Inventar mit Status, Ressourcen und Betriebszeit. Die Detailansicht zeigt Konfiguration, historische Metriken, Proxmox-Logdownloads und Start-/Stopp-/Neustart-/Herunterfahraktionen. Die Logs hängen vom Proxmox-Endpunkt ab; es ist kein vollständiges Gastbetriebssystem-Logarchiv."
},
{
"name": "Hardware",
"description": "CPU Modell und Topologie, Speicherlayout, PCIe-Geräte, GPU Liste mit Treiber und Echtzeitüberwachung pro Steckplatz (NVIDIA / Intel iGPU)."
},
{
"name": "Protokolle und Ereignisse",
"description": "Live <code>journalctl</code> mit Schweregrad-/Zeitbereichs-/Schlüsselwortfiltern, Proxmox-Aufgabenverlauf, Benachrichtigungsprotokoll, herunterladbaren Protokollpaketen."
},
{
"name": "Terminal",
"description": "Browser-Shell für den Host und unterstützte VM-/CT-Konsolen über <code>xterm.js</code> und WebSockets. Sitzungen werden nicht pro Befehl protokolliert."
},
{
"name": "Sicherheit",
"description": "Fehlgeschlagene Anmeldungen, Status der Fail2Ban-Jails, kürzlich gesperrte IP-Adressen und Integration mit dem Jail <code>[proxmenux]</code> des Hosts."
}
],
"footer": "Jeder Abschnitt verfügt über eine eigene Dokumentationsseite unter <link>Dashboard</link> in der Seitenleiste."
},
"howItRuns": {
"heading": "Wie es läuft",
"intro": "ProxMenux Monitor wird als eigenständige AppImage bereitgestellt. Eine einzelne systemd-Unit (<code>proxmenux-monitor.service</code>) startet einen Flask-Prozess, der:",
"bullets": [
"Hört auf <strong>TCP 8008</strong> auf dem Host (HTTP).",
"Stellt das Next.js-Dashboard als statische Dateien unter <code>/</code> und die API unter <code>/api/*</code> aus demselben Prozess bereit.",
"Zieht Live-Daten mit Standard-Host-Tools ab: <code>psutil</code>, <code>pvesh</code>, <code>smartctl</code>, <code>journalctl</code>, <code>zpool</code>, <code>ip</code>, <code>nvidia-smi</code> usw.",
"Behält seinen eigenen Status in einer lokalen SQLite-Datenbank bei (<code>/usr/local/share/proxmenux/health_monitor.db</code>): verworfene Warnungen, Festplattenbeobachtungen, Benachrichtigungskonfiguration, AI-Konfiguration. Der Authentifizierungsstatus befindet sich separat in <code>/root/.config/proxmenux-monitor/auth.json</code>."
],
"footer": "Der vollständige Anfrageablauf, das Dateilayout und die systemd-Integration werden in <link>Architektur</link> beschrieben."
},
"noAgent": {
"title": "Kein Agent für die Gäste",
"body": "Der Monitor liest alle Daten auf dem Host aus. Auf VMs und CTs muss kein Agent installiert werden: Die Gastdaten stammen aus der Proxmox-API und aus den Informationen, die der Kernel des Hosts über die laufenden Gastsysteme bereitstellt."
},
"access": {
"heading": "Zugriff auf das Dashboard",
"intro": "Zwei Zugriffsmuster werden unterstützt und die Anwendung erkennt, welches verwendet wird:",
"codeComment1": "# 1) Direkter Zugriff auf dem Host",
"codeComment2": "# 2) Über Reverse Proxy (Nginx / Caddy / Traefik)",
"afterCode": "Der Reverse-Proxy sollte <code>X-Forwarded-For</code>, <code>X-Forwarded-Proto</code> und <code>X-Forwarded-Host</code> korrekt setzen und WebSocket-Upgrades weiterleiten. Bei Standardports nutzt der Browser seinen aktuellen Ursprung. Für Client-IPs vertraut das Backend weitergeleiteten Adressen nur mit explizitem PROXMENUX_TRUST_PROXY=1; beschränken Sie dabei direkten Backendzugriff.",
"footer": "Einrichtung beim ersten Start, Passwort + TOTP 2FA und Reverse-Proxy-Snippets werden unter <link>Zugriff und Authentifizierung</link> behandelt."
},
"mobile": {
"heading": "Mobile Nutzung und Installation auf dem Startbildschirm",
"intro": "Das Dashboard passt sich der Bildschirmgröße an und wird als Progressive Web App geliefert. <code>public/manifest.json</code> deklariert <code>display: standalone</code>, App-Namen, Symbol und Designfarbe. Das Hinzufügen zum Startbildschirm ermöglicht einen eigenständigen Start ohne Adressleiste, mit angepasstem Startbildschirm und dunklem Dashboard-Design.",
"phoneAlt": "ProxMenux Monitor läuft auf einem Telefon – Haupt-Dashboard-Ansicht",
"phoneCaption": "Haupt-Dashboard auf einem Telefon – das Layout wird für kleine Ansichtsfenster neu gestaltet.",
"addHeading": "Zum Startbildschirm hinzufügen",
"iosLabel": "iOS Safari:",
"iosBody": "Teilen-Schaltfläche → <em>Zum Startbildschirm hinzufügen</em>. Das Symbol stammt von <code>/apple-touch-icon.png</code>, das im AppImage ausgeliefert wird.",
"androidLabel": "Android Chrome / Edge:",
"androidBody": "Menü mit drei Punkten → <em>App installieren</em> (oder <em>Zum Startbildschirm hinzufügen</em> bei älteren Versionen).",
"afterInstall": "Nach der Installation wird durch Öffnen des Symbols das Dashboard im Standalone-Modus mit einem eigenen Task-Switcher-Eintrag gestartet.",
"onlineOnlyTitle": "Nur online nutzbar",
"onlineOnlyBody": "Die PWA lässt sich installieren, ist aber <strong>nicht</strong> offlinefähig: Es gibt keinen Service Worker. Die Verknüpfung verhält sich wie eine native App. Zum Laden des Dashboards muss das Gerät den Host jedoch weiterhin über TCP 8008 erreichen können, etwa über LAN, VPN oder HTTPS mit einem Reverse-Proxy."
},
"health": {
"heading": "Der Gesundheitsmonitor und Benachrichtigungen",
"alt": "Health Monitor-Bildschirm mit den verfolgten 10-Kategorien (CPU, Arbeitsspeicher, Speicher, Festplatten, Netzwerk, Dienste, Protokolle, VMs, Updates, Sicherheit) mit aktuellem Status",
"caption": "Health Monitor-Ansicht – die verfolgten 10-Kategorien mit ihrem aktuellen Status. Aktive und verworfene Warnungen werden hier angezeigt, wenn das System welche auslöst.",
"body1": "Im Dashboard läuft der <strong>Health Monitor</strong> im Hintergrund und erzeugt strukturierte Ereignisse: hohe CPU-Temperatur, SMART-Warnungen, verschlechterte ZFS-Pools, OOM-Prozessabbrüche, VM-/CT-Ausfälle und Sicherheitsvorfälle. Jedes Ereignis hat Kategorie, Schweregrad (INFO / WARNING / CRITICAL) und einen stabilen <code>error_key</code>, der Duplikate zusammenfasst.",
"feedsIntro": "Ereignisse versorgen drei Dinge gleichzeitig:",
"feedsHealth": "Die <strong>Health Monitor-Ansicht</strong> im Dashboard (aktive + verworfene Listen).",
"feedsChannels": "Die <strong>Benachrichtigungs-Engine</strong> – Telegram, Discord, E-Mail, Gotify, Pushover und Apprise (Mehrkanal). Jeder Kanal wird unabhängig konfiguriert und die Kategorien pro Ereignis können stummgeschaltet werden.",
"feedsAI": "Der optionale <strong>KI-Assistent</strong> erklärt mit dem gewählten Anbieter (OpenAI, Anthropic, Gemini, Groq, Ollama oder OpenRouter) eingehende Ereignisse verständlich und schlägt bei Aktivierung in den KI-Einstellungen weitere Schritte vor.",
"suppressionTitle": "Einzelne Warnungen unterdrücken statt alles stummschalten",
"suppressionBody": "Jede Kategorie hat eine eigene <em>Unterdrückungsdauer</em>. Nach Verwerfen wird dieselbe Warnung für diesen Zeitraum stummgeschaltet (standardmäßig 24 Stunden, je Kategorie bis dauerhaft einstellbar). Echte Verschärfungen, etwa CPU-Temperatur über der kritischen Schwelle, lösen unabhängig davon erneut aus."
},
"api": {
"heading": "REST API und Integrationen",
"intro": "REST-Endpunkte liefern Überwachungsdaten als JSON über HTTP/HTTPS für Homepage, Home Assistant, Uptime Kuma und eigene Skripte. Grafana kann den separaten Prometheus-Textexporter unter <code>/api/prometheus</code> nutzen. Anfragen sind mit <code>curl</code> möglich.",
"tokens": "Langlebige API-Tokens (365 Tage) werden aus <strong>Einstellungen → API Zugriffstokens</strong> oder über <code>POST /api/auth/generate-api-token</code> generiert.",
"bearer": "Token werden als <code>Authorization: Bearer …</code> gesendet. Auch <code>/api/health</code> erwartet den Bearer-Header, daher benötigen Verfügbarkeitsprüfungen ein read_only-Token. Unter <code>/api/auth/*</code> liegen sowohl öffentliche Setup-/Login-/Statusrouten als auch geschützte Routen der Konto-/Tokenverwaltung; nicht alle sind anonym.",
"catalog": "Der vollständige Endpunktkatalog, Anleitungen zur Token-Rotation und Best Practices für die Sicherheit finden Sie in der <linkApi>API-Referenz</linkApi>; Vorgefertigte Beispiele für Homepage, Home Assistant, Grafana, Uptime Kuma und ein generisches cURL-Muster finden Sie in <linkIntegrations>Integrationen</linkIntegrations>."
},
"serviceControl": {
"heading": "Dienststeuerung",
"intro": "Der Monitor wird wie jeder systemd-Dienst verwaltet. Zusätzlich gibt es zwei Einträge in der ProxMenux-Textoberfläche unter <em>Einstellungen</em>:",
"codeComment": "# Manuelle Steuerung",
"footer": "Siehe <link>Einstellungen → ProxMenux Monitor</link> für die Umschaltung im Menü und den Statusüberprüfungsablauf."
},
"nextSteps": {
"heading": "Wo geht es weiter?",
"items": [
{
"label": "Architektur",
"description": "– Flask Backend, systemd Einheit, SQLite Schema, KI-Anbieter, Benachrichtigungskanäle."
},
{
"label": "Zugriff und Authentifizierung",
"description": "– erster Start, Passwort-Einrichtung, TOTP 2FA, Reverse-Proxy-Konfiguration, Fail2Ban-Integration."
},
{
"label": "Dashboard",
"description": "— jede Sektion der Oberfläche auf einer eigenen Seite."
},
{
"label": "API-Referenz",
"description": "– alle Endpunkte, Anforderungs-/Antwortformen und Token-Verwaltung."
},
{
"label": "Integrationen",
"description": "– Homepage, Home Assistant, Grafana / Prometheus, Uptime Kuma, generisches cURL Muster."
}
]
}
}
@@ -0,0 +1,255 @@
{
"meta": {
"title": "Proxmox-Integrationen — Homepage, Home Assistant, Grafana, Prometheus | ProxMenux Monitor",
"description": "Konfigurationsbeispiele zum Kopieren für Homepage, Home Assistant, Grafana über Prometheus und Uptime Kuma. Jedes Beispiel zeigt die benötigte Konfiguration, die Monitor-API-Endpunkte und den Authentifizierungsheader.",
"ogTitle": "Proxmox-Integrationen — Homepage, Home Assistant, Grafana, Prometheus",
"ogDescription": "Anleitungen zur Verbindung von ProxMenux Monitor mit Homepage, Home Assistant, Grafana, Prometheus und Uptime Kuma.",
"twitterTitle": "Proxmox Integrationen | ProxMenux Monitor",
"twitterDescription": "Rezepte für Homepage, Home Assistant, Grafana, Prometheus und Uptime Kuma."
},
"header": {
"title": "Integrationen",
"description": "Beispiele zum Kopieren für die Werkzeuge Ihres Homelabs: Homepage, Home Assistant, Grafana über Prometheus und Uptime Kuma. Jedes Beispiel zeigt die vom Zielwerkzeug erwartete Konfiguration, den verwendeten Monitor-Endpunkt und den nötigen Authentifizierungsheader.",
"section": "ProxMenux-Monitor"
},
"intro": {
"title": "Was Sie von dieser Seite aus erstellen können",
"body": "Kopieren Sie das jeweilige Beispiel in Ihr Werkzeug. Die Endpunkte sind in der <link>API-Referenz</link> beschrieben; diese Seite zeigt ihre Verwendung in Homepage, Home Assistant und Grafana. Die Screenshots zeigen die Ausgabe der Beispiele."
},
"auth": {
"heading": "Authentifizierung: Das Einzige, was jedes Rezept braucht",
"intro": "Die meisten von diesen Integrationen verwendeten Endpunkte werden authentifiziert. Sie haben zwei Möglichkeiten, diese Anforderung zu erfüllen.",
"optAtitle": "Option A — API-Token (für Integrationen empfohlen)",
"optAbody1": "Öffnen Sie <strong>Einstellungen → Sicherheit → API-Token</strong>. Wählen Sie <em>Token erzeugen</em>, vergeben Sie einen Namen wie <em>homepage</em>, <em>home-assistant</em> oder <em>prometheus</em> und kopieren Sie das Token: Es erscheint <em>nur einmal</em>. Es läuft standardmäßig nach einem Jahr ab und ist einzeln widerrufbar. Nutzen Sie es für Clients außerhalb des Browsers.",
"optAbody2": "Ab diesem Zeitpunkt ist jede Anfrage nur noch:",
"optBtitle": "Option B — Login-Flow (Benutzername + Passwort)",
"optBbody": "Nützlich für Skripte, die sich als menschlicher Benutzer authentifizieren. Das zurückgegebene Token ist kurzlebig; die meisten Integrationen sollten Option A bevorzugen.",
"outro": "Das TOTP-Feld ist nur bei aktivierter Zwei-Faktor-Authentifizierung nötig. Tokenwechsel, Widerruf, Passwortrichtlinien und Prüfprotokoll sind unter <link>Zugriff und Authentifizierung</link> beschrieben.",
"httpsTitle": "Verwendung von HTTPS anstelle von HTTP",
"httpsIntro": "Jedes Rezept unten verwendet <code>http://</code> in den URLs, um die Beispiele kurz zu halten. Wenn Sie TLS auf dem Monitor aktiviert haben (<strong>Settings → Security → SSL/HTTPS</strong>), tauschen Sie <code>http://</code> in jeder URL gegen <code>https://</code> aus – das ist die einzige Änderung. Zwei spezielle Anmerkungen zu bestimmten Werkzeugen:",
"httpsItems": [
"<strong>Selbstsignierte Zertifikate.</strong> Die Home-Assistant-Integration <code>rest:</code> prüft TLS standardmäßig. Für ein selbstsigniertes Monitor-Zertifikat setzen Sie <code>verify_ssl: false</code> in jeden REST-Block neben <code>scan_interval:</code> oder nehmen die Monitor-CA in den Vertrauensspeicher auf. Entsprechendes gilt für andere Werkzeuge mit Zertifikatsprüfung.",
"<strong>Prometheus</strong> enthält unten bereits <code>scheme: https</code>. Aktivieren oder behalten Sie <code>https</code>, wenn TLS im Monitor aktiv ist."
]
},
"homepage": {
"heading": "Homepage",
"headingHref": "https://gethomepage.dev",
"intro": "Homepage ist ein vollständig statisches, anpassbares Anwendungs-Dashboard. ProxMenux Monitor wird über das eingebaute <code>customapi</code>-Widget angeschlossen - fügen Sie einen Diensteintrag in <code>services.yaml</code> ein, starten Sie die Homepage neu und die Karte erscheint mit Live-Nummern.",
"iconCalloutTitle": "Das offizielle ProxMenux-Logo ist auf dashboardicons.com",
"iconCalloutBody": "Die Beispiele nutzen <code>icon: proxmenux.png</code>. Homepage sucht einfache Dateinamen automatisch bei <a1>dashboardicons.com</a1>, einer Symbolsammlung für selbst gehostete Dashboards. Der ProxMenux-Eintrag steht unter <a2>dashboardicons.com/icons/external/proxmenux</a2> und wird beim ersten Anzeigen geladen. Dasselbe funktioniert für Tausende anderer Werkzeuge wie Telegram, Discord, Grafana oder Tailscale: <code>icon: &lt;name&gt;.png</code> genügt im Diensteintrag.",
"imageAlt": "Homepage Dashboard mit drei ProxMenux Monitor Karten (EDGE, VOID, DREAM) mit Uptime, CPU, RAM und Temperatur für jeden Proxmox Host",
"imageCaption": "Drei ProxMenux Monitor-Instanzen, die als Homepage-Karten gerendert wurden – Uptime, CPU, RAM und CPU Temperatur live von <code>/api/system</code> auf jedem Host alle 10 s gelesen.",
"basicTitle": "Grundlegendes Widget — keine Authentifizierung",
"basicIntro": "Verwenden Sie dies, wenn sich ProxMenux Monitor in einem vertrauenswürdigen Netzwerk befindet und Sie die Authentifizierung auf der Monitorseite noch nicht aktiviert haben. Der einfachste mögliche <code>services.yaml</code>-Eintrag:",
"authedTitle": "Authentifiziertes Widget",
"authedIntro": "Generieren Sie ein API-Token in <strong>Settings → Security → API Tokens</strong> auf dem Monitor, kopieren Sie es und fügen Sie es in den <code>Authorization</code>-Header unten ein - ersetzen Sie das Beispiel-Token, das nach <code>Bearer</code> angezeigt wird, durch das, das Sie gerade kopiert haben:",
"authedOutro": "Starten Sie die Homepage neu und die Karte leuchtet mit Live-Werten auf. Verwenden Sie das gleiche Token für alle Homepage-Widgets, die auf denselben ProxMenux Monitor-Host zeigen.",
"multiTitle": "Einrichtung von Multiwidgets — System, Speicher, Netzwerk",
"multiIntro": "Für mehr Details nutzen Sie drei Karten mit unterschiedlichen Endpunkten: Systemmetriken, Datenspeicher und Netzwerk. Für dieselbe Monitor-Instanz verwenden alle dasselbe Token.",
"multiCalloutTitle": "Mehrere Proxmox Hosts",
"multiCalloutBody": "Wiederholen Sie den Block je Host für die gezeigten Karten. Jeder Eintrag nutzt <code>http://&lt;host&gt;:8008</code> seiner Monitor-Instanz. Erzeugen und speichern Sie ein Token je Host: Getrennte Installationen besitzen eigene Signierschlüssel, daher gilt ein fremdes Token nicht automatisch."
},
"homeAssistant": {
"heading": "Home Assistant",
"headingHref": "https://www.home-assistant.io",
"intro": "Die Beispiele nutzen Home Assistants integrierte <code>rest</code>-Integration; eine eigene HACS-Komponente ist nicht nötig. Sie liest Monitor-Endpunkte aus der <link>API-Referenz</link> und erzeugt Sensoren und Attribute für Automatisierungen. Die Konfiguration liefert ungefähr 25 Sensoren für Ressourcen, Zustand, VMs/CTs, Datenspeicher, Netzwerk und Updates. Fügen Sie sie in <code>configuration.yaml</code> ein und laden oder starten Sie HA neu.",
"imageAlt": "Home-Assistant-Übersicht mit ProxMenux-Entitäten: Zustandsanzeige, CPU-/RAM-/Temperaturanzeigen, VM-Anzahl, Datenspeicherbelegung und aktive Fehler",
"imageCaption": "ProxMenux Monitor als erstklassige Home Assistant-Integration - Sensoren, die aus dem untenstehenden YAML-Rezept aufgebaut sind.",
"step1Title": "1 · Speichern Sie den API-Token",
"step1Body": "Speichern Sie das Token getrennt von der Hauptkonfiguration in <code>secrets.yaml</code>. Bearer-Präfix und Token stehen in einem Wert, der als Header referenziert wird. Die Datei ist nicht verschlüsselt und muss ebenfalls privat bleiben. Ihr Ort hängt von der Installation ab, meist <code>/config/secrets.yaml</code> unter HA OS oder Container.",
"step2Title": "2 · REST-Konfiguration einfügen",
"step2Body": "Sechs REST-Blöcke decken die Hauptbereiche ab. Ihr <code>scan_interval</code> passt zur Änderungsrate: Systemressourcen alle 30 s, Zustand alle 60 s, langsam veränderliche Bestände alle 5–10 Minuten. In <code>configuration.yaml</code> einfügen:",
"step3Title": "3 · Hinzufügen von binären Sensoren und Vorlagenhelfern",
"step3Body": "Zwei binäre Sensoren und zwei Vorlagensensoren ergänzen die Integration. Damit werden Automatisierungen und bedingte Lovelace-Karten übersichtlicher, ohne überall Jinja-Ausdrücke zu wiederholen.",
"step4Title": "4 · Neu laden und prüfen",
"step4Body": "Prüfen Sie zuerst die Syntax unter <em>Entwicklerwerkzeuge → YAML → Konfiguration prüfen</em>. Laden Sie dann <em>Gesamte YAML-Konfiguration</em> neu oder starten Sie HA neu. Filtern Sie unter <em>Einstellungen → Geräte & Dienste → Entitäten</em> nach <em>proxmenux</em>. Die ungefähr 25 Entitäten sollten sich innerhalb eines Abfrageintervalls füllen.",
"replaceTitle": "Ersetzen einer früheren Version dieses Rezepts?",
"replaceBody": "Falls Sie eine ältere Version dieser YAML-Blöcke verwendet haben, kann die Entitätsregistrierung von Home Assistant noch alte Entitäts-IDs enthalten. Veraltete Entitäten erscheinen dann weiterhin; Lovelace-Karten melden beispielsweise <em>Entität nicht gefunden</em>. Bereinigen Sie die Konfiguration in zwei Schritten: Entfernen Sie zunächst die bisherigen Blöcke <code>rest:</code> und <code>template:</code> aus <code>configuration.yaml</code> und laden Sie die Konfiguration neu. Filtern Sie anschließend unter <em>Einstellungen → Geräte & Dienste → Entitäten</em> nach <em>proxmenux</em> und entfernen Sie Einträge, die als „Wiederhergestellt“ oder nicht verfügbar angezeigt werden. Fügen Sie danach das aktuelle YAML ein und laden Sie die Konfiguration erneut. Die neuen Entitäten werden dann ohne die alten Einträge registriert.",
"step5Title": "5 · Lovelace-Dashboard",
"step5Body": "Das YAML bildet eine <strong>vertical-stack</strong>-Karte mit Logo, Kennzahlen, System, VMs, Datenspeicher, Netzwerk und einer bedingten Problemkarte. Öffnen Sie Ihr Dashboard, wählen Sie den Stift, dann <em>Karte hinzufügen</em> und unten <em>Manuell</em>. Fügen Sie Folgendes ein:",
"viewTipTitle": "Möchten Sie es als vollständige Dashboard-Ansicht anstelle einer einzelnen Karte?",
"viewTipBody": "Öffnen Sie das Dreipunktmenü → <em>Rohkonfigurationseditor</em> und ergänzen Sie eine Ansicht mit diesem Kopf über der <code>cards:</code>-Liste:",
"viewTipOutro": "Das gibt Ihnen eine dedizierte Registerkarte / Ansicht in Ihrem Dashboard mit einem eigenen Symbol und Titel anstelle einer langen Karte in einer vorhandenen Ansicht.",
"altViewTitle": "Alternative — eine dedizierte Dashboard-Ansicht",
"altViewIntro": "Für eine eigene Registerkarte innerhalb eines bestehenden Dashboards fügen Sie eine Ansicht mit dem folgenden YAML hinzu. Eine Ansicht ist ein Dashboard-Tab und kein neuer Eintrag in der Seitenleiste. Schritte:",
"altViewSteps": [
"Öffnen Sie das Dashboard, wo Sie den neuen Tab möchten.",
"Klicken Sie oben rechts auf den Bleistift (Dashboard bearbeiten).",
"Klicken Sie auf die Registerkarte <em>+</em> am Ende der vorhandenen Registerkarten, um eine neue Ansicht zu erstellen.",
"Wechseln Sie im Dialog oben rechts zu <em>Code-Editor</em>, um zwischen visueller Ansicht und YAML umzuschalten.",
"Fügen Sie die YAML unten ein.",
"Speichern Sie. Die Ansicht <em>ProxMenux Monitor</em> erscheint als Registerkarte im Dashboard mit ihren Karten."
],
"twoEditorsTitle": "Zwei YAML-Editoren in HA - wählen Sie den richtigen",
"twoEditorsIntro": "Home Assistant hat zwei YAML-Editoren, die ähnlich aussehen, aber unterschiedliche Formate erwarten:",
"twoEditorsItems": [
"<strong>Editor für eine Ansicht</strong> — über <em>+</em> oder <em>Ansicht bearbeiten → Code-Editor</em>. Erwartet eine einzelne Ansicht mit <code>title:</code>, <code>path:</code> und <code>cards:</code> auf oberster Ebene, ohne führenden Bindestrich.",
"<strong>Rohkonfigurationseditor für das ganze Dashboard</strong> — über das Dreipunktmenü. Erwartet die vollständige <code>views:</code>-Liste mit jeder Ansicht als Listeneintrag, beginnend mit <code>-</code>."
],
"twoEditorsOutro": "Das falsche Format kann eine <em>Unbenannte Ansicht</em> und <code>cards: []</code> erzeugen. Das folgende YAML ist für den Editor einer einzelnen Ansicht; kopieren Sie es unverändert.",
"viewImageAlt": "Eigene Home-Assistant-Ansicht für ProxMenux Monitor: picture-entity-Kopf, glance-Kennzahlen und Entitätskarten für System, VMs, Datenspeicher und Netzwerk in mehreren Spalten",
"viewImageCaption": "Die Ansicht <em>ProxMenux Monitor</em> auf einem breiten Bildschirm. Masonry ordnet Karten automatisch in Spalten an; das Layout hängt vom eingestellten Ansichtstyp ab.",
"twoColTipTitle": "Möchten Sie ein festes zweispaltiges Layout anstelle des Autolayouts?",
"twoColTipBody": "Ersetzen Sie ein Kartenpaar, etwa <em>System</em> + <em>VMs</em> oder <em>Datenspeicher</em> + <em>Netzwerk</em>, durch einen gemeinsamen <code>horizontal-stack</code>. So stehen die Karten unabhängig von der Bildschirmbreite nebeneinander:",
"twoColTipOutro": "Auf Mobilgeräten bleibt die Zeile zusammengedrückt. Das automatische HA-Layout ohne horizontal-stack passt sich schmalen Bildschirmen besser an.",
"step6Title": "6 · Automatisierungen",
"step6Body": "Drei Automatisierungen, die die häufigsten reaktiven Szenarien abdecken - ersetzen Sie <code>notify.mobile_app_&lt;your_phone&gt;</code> durch den von Ihnen verwendeten Benachrichtigungsdienst:",
"logoTitle": "Über das ProxMenux Logo",
"logoBody": "Die picture-entity-Karte lädt das offizielle Logo von <a1>dashboardicons.com</a1>, einer kostenlosen Symbolsammlung für selbst gehostete Dashboards. Der Eintrag steht unter <a2>dashboardicons.com/icons/external/proxmenux</a2>. Home Assistant lädt die SVG beim ersten Anzeigen per HTTPS und speichert sie im Cache.",
"logoBrokenTitle": "Wenn die Logokarte ein defektes Bild zeigt",
"logoBrokenIntro": "Einige HA-Installationen (Firewalled-Netzwerke, Inhaltsblocker, Hosts ohne öffentliches Internet) können jsdelivr.net zum Renderzeitpunkt nicht erreichen. Der Fix ist eine lokale Kopie:",
"logoBrokenSteps": [
"Laden Sie die SVG von <a>cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/proxmenux.svg</a>.",
"Speichern Sie es in <code>/config/www/icons/proxmenux.svg</code> auf Ihrem HA-Host.",
"Ersetzen Sie im Lovelace YAML die <code>image:</code> URL durch <code>/local/icons/proxmenux.svg</code>. Speichern und neu laden - das Bild rendert aus der lokalen Datei, kein Internet erforderlich."
],
"scanTipTitle": "scan_interval Faustregel",
"scanTipBody": "Für <code>/api/system</code> sind 30 s ein sinnvoller Startwert. <code>/api/health/full</code> liest normalerweise bis zu sechs Minuten gültige Hintergrunddaten; Abfragen alle 60 s umgehen diesen Cache nicht. Versuchen Sie fünf Minuten für <code>/api/storage/summary</code> und eine Stunde für <code>/api/proxmenux/update-status</code>. Passen Sie die Zeiten an Hardware und Hostanzahl an."
},
"grafana": {
"heading": "Prometheus + Grafana",
"promHref": "https://prometheus.io",
"grafanaHref": "https://grafana.com",
"intro": "ProxMenux Monitor stellt <code>GET /api/prometheus</code> im Prometheus-Textformat 0.0.4 bereit. Bei aktiver Authentifizierung ist ein Bearer-Token nötig. Lassen Sie Prometheus die Metriken sammeln und Grafana die Zeitreihendatenbank visualisieren.",
"imageAlt": "Grafana-Dashboard mit ProxMenux-Metriken: CPU-Anzeige, Arbeitsspeicherverlauf, Anzahl laufender VMs und Netzwerkdurchsatz",
"imageCaption": "Ein einfaches Grafana-Dashboard aus den von Prometheus gesammelten ProxMenux-Daten: CPU, Arbeitsspeicher, laufende VMs und Netzwerkdurchsatz. Den vollständigen Katalog finden Sie unter <link>API-Referenz → Prometheus-Metriken</link>.",
"step1Title": "1 · Fügen Sie den Scrape Job zu Prometheus hinzu",
"step1Body": "Geben Sie den API-Token über den nativen <code>authorization</code>-Block von Prometheus weiter (sauberer als benutzerdefinierte Header und funktioniert mit Secret Stores):",
"step1After": "Laden Sie Prometheus mit <code>kill -HUP &lt;PID&gt;</code> neu (PID durch seine Prozess-ID ersetzen), mit <code>systemctl reload prometheus</code>, sofern unterstützt, oder im Container mit <code>docker compose restart prometheus</code>. Unter <em>Status → Targets</em> sollte proxmenux innerhalb eines Intervalls UP zeigen. Das Label <code>node=\"&lt;hostname&gt;\"</code> unterscheidet Hosts.",
"tokenTipTitle": "Token in einer separaten Datei speichern",
"tokenTipBody": "Speichern Sie das Token im Produktivbetrieb getrennt von der Konfiguration. Mit <code>credentials_file: /etc/prometheus/secrets/proxmenux.token</code> liest Prometheus es aus einer Datei mit Berechtigung 0600.",
"step2Title": "2 · Überprüfen Sie den Scrape mit ein paar Abfragen",
"step2Body": "Prüfen Sie vor Grafana, ob Prometheus Daten enthält. Öffnen Sie <code>http://&lt;prometheus-host&gt;:9090</code>, wählen Sie <em>Query</em> und führen Sie eine der folgenden Abfragen aus. Sie sollten aktuelle Werte des Proxmox-Hosts erhalten:",
"headerQuery": "Abfrage",
"headerConfirms": "Was es bestätigt",
"verifyRows": [
{
"query": "up{job=\"proxmenux\"}",
"confirms": "Liefert <code>1</code>, wenn Prometheus erfolgreich Daten abruft, sonst <code>0</code>. Die schnellste erste Prüfung."
},
{
"query": "proxmox_cpu_usage",
"confirms": "Aktuelle CPU-Auslastung des Proxmox-Hosts in Prozent. Der Wert sollte sich bei Abfragen im Abstand einiger Sekunden ändern."
},
{
"query": "proxmox_vms_running",
"confirms": "Anzahl der laufenden Gäste. Vergleichen Sie mit dem, was Sie in der Proxmox UI sehen."
},
{
"query": "proxmox_uptime_seconds / 86400",
"confirms": "Host Uptime in Tagen. Sollte dem Wert entsprechen, den Sie in <code>uptime</code> auf der Proxmox-Shell sehen würden."
}
],
"calloutTitle": "Die 401, die Sie beim Klicken auf die Endpunkt-URL sehen können, ist in Ordnung",
"calloutBody": "Bei aktiver Authentifizierung ruft der Browser über <em>Status → Targets</em> den Endpunkt <code>/api/prometheus</code> ohne Prometheus-Bearer-Header ab. Die Antwort kann <code>'{'\"error\":\"Authentication required\"'}'</code> enthalten. Prüfen Sie den tatsächlichen <em>State: UP</em>, um den erfolgreichen Abruf durch Prometheus zu bestätigen.",
"step3Title": "3 · Hinzufügen von Prometheus als Grafana-Datenquelle",
"step3Body": "Öffnen Sie in Grafana <em>Connections → Data sources → Add new → Prometheus</em>. Tragen Sie die Prometheus-URL ein, etwa <code>http://prometheus.lan:9090</code>, speichern und testen Sie. Eine vom Prometheus-Server verlangte Anmeldung wird hier separat eingerichtet. Das Monitor-Token gehört in den Prometheus-Abrufauftrag.",
"step4Title": "4 · Erstellen Sie Panels mit diesen PromQL-Abfragen",
"step4Body": "Ein Einstieg mit den typischen Kennzahlen eines Proxmox-Hosts:",
"headerPanel": "Panel-Idee",
"headerPromql": "PromQL-Abfrage",
"panelRows": [
{
"panel": "CPU-Auslastungsanzeige je Host",
"promql": "proxmox_cpu_usage"
},
{
"panel": "Speichernutzungsmessgerät pro Host",
"promql": "proxmox_memory_usage_percent"
},
{
"panel": "Genutzter und gesamter Arbeitsspeicher (Zeitreihen)",
"promql": "proxmox_memory_used_bytes / 1024 / 1024 / 1024"
},
{
"panel": "Laufende VMs / CTs pro Host",
"promql": "proxmox_vms_running"
},
{
"panel": "CPU-Temperatur",
"promql": "proxmox_cpu_temperature_celsius"
},
{
"panel": "Netzdurchsatz RX (Bytes/s)",
"promql": "rate(proxmox_interface_bytes_received_total[5m])"
},
{
"panel": "Netzdurchsatz TX (Bytes/s)",
"promql": "rate(proxmox_interface_bytes_sent_total[5m])"
},
{
"panel": "Lastmittelwert (1 m)",
"promql": "proxmox_load_average{period=\"1m\"}"
},
{
"panel": "Belegter Speicherplatz je Einhängepunkt in Prozent",
"promql": "proxmox_disk_usage_percent"
},
{
"panel": "UPS Batterieladung",
"promql": "proxmox_ups_battery_charge_percent"
},
{
"panel": "GPU Temperatur pro Slot",
"promql": "proxmox_gpu_temperature_celsius"
}
],
"outro": "Fügen Sie jede Abfrage als Grafana-Panel hinzu, legen Sie die richtige Visualisierung fest (<em>Stat</em> für Messgeräte, <em>Time series</em> für Trends) und gruppieren Sie Panels in Zeilen nach Kategorie. Verwenden Sie das <code>node</code>-Label als Dashboard-Variable (<em>Settings → Variables → New → Query → label_values(proxmox_cpu_usage, node)</em>), um alle Panels nach Host zu filtern."
},
"uptimeKuma": {
"heading": "Uptime Kuma und andere Statuschecker",
"href": "https://github.com/louislam/uptime-kuma",
"intro": "Für Schlüsselwortprüfungen nutzen Sie <code>GET /api/system-info</code>. Diese Route verlangt kein Token und liefert Hostname, Laufzeit und Zustand als <code>healthy</code>, <code>warning</code> oder <code>critical</code>. Sie ist öffentlich, anders als die geschützten detaillierten Zustandsendpunkte.",
"kumaTitle": "Uptime Kuma — HTTP Keyword Monitor",
"kumaSteps": [
"Klicken Sie in Uptime Kuma auf <em>+ Neuen Monitor hinzufügen</em>.",
"Monitortyp: <em>HTTP(s) - Keyword</em>.",
"Freundlicher Name: <em>ProxMenux Monitor — pve01</em>.",
"URL: <code>http://pve01.lan:8008/api/system-info</code>.",
"Schlüsselwort: <code>healthy</code> (der Wert von <code>health.status</code>, wenn der Host in Ordnung ist).",
"Heartbeat Intervall: 60 Sekunden sind genug.",
"Speichern Sie. Die Route system-info benötigt keinen Bearer-Header."
],
"healthchecksTitle": "healthchecks.io / Pings nach Cron-Zeitplan",
"healthchecksBody": "Ein Cronjob kann <code>/api/system-info</code> abfragen und <code>.health.status == \"healthy\"</code> prüfen. Erst nach erfolgreicher Prüfung sendet er einen Erfolgsping an seine Healthchecks.io-URL. Der Dienst empfängt Job-Pings und fragt den Monitor nicht selbst ab. HTTP 2xx allein beweist keinen gesunden Host.",
"richTitle": "Möchten Sie reichhaltige Gesundheitsdaten",
"richBody": "Für den vollständigen Zustand mit zehn Kategorien, aktiven und unterdrückten Fehlern nutzen Sie <code>GET /api/health/full</code>. Die Antwort enthält die Daten des Dashboard-Dialogs. Bei aktiver Authentifizierung ist ein Bearer-Token nötig."
},
"workflows": {
"heading": "n8n, Zapier und eigene Skripte",
"intro": "Workflow-Werkzeuge und Skripte können mit POST an <code>/api/notifications/send</code> Meldungen <em>senden</em>, etwa bei CI-Fehlern oder langen Cronjobs. Der direkte Versand umgeht Ereigniswarteschlange und Fingerprint-Sperrzeit. Kanalformatierung, optionale KI und Versand bleiben erhalten. Erforderliche Duplikatkontrolle übernimmt der Aufrufer.",
"n8nBody": "Nutzen Sie in n8n einen <em>HTTP Request</em>-Knoten mit POST, obiger URL und demselben JSON wie curl. Wählen Sie generische Header-Auth-Zugangsdaten mit <em>Authorization</em> und <code>Bearer YOUR_API_TOKEN</code>; ersetzen Sie den Platzhalter. Ein Zeitplan, Webhook oder vorheriger Knoten löst die Anfrage aus.",
"severityBody": "Schweregrade sind <code>INFO</code>, <code>WARNING</code> oder <code>CRITICAL</code> in Großbuchstaben. Das Objekt <code>data</code> liefert Ereigniskontext und Vorlagenfelder. An diesem Endpunkt erhält die KI-Umschreibung nur Titel und Text; Felder in <code>data</code> werden nicht an den Anbieter gesendet. Zur Bedeutung der Ereignisse siehe <link>Benachrichtigungen → Ereigniskatalog</link>."
},
"pveWebhook": {
"heading": "Nativer Proxmox-VE-Webhook (eingehend)",
"intro1": "PVE erhielt sein Benachrichtigungssystem mit 8.1; native Webhook-Ziele erfordern Proxmox VE 8.3 oder neuer. <em>Benachrichtigungen aktivieren</em> in Einstellungen versucht, den Monitor als Ziel einzutragen. Dorthin geleitete PVE-Meldungen wie Sicherungs- oder Replikationsberichte gelangen in seinen Versandablauf. Die Einrichtung benötigt eine verfügbare, beschreibbare Konfiguration.",
"intro2": "Ablauf, PVE-Nachrichtenvorlage, Einträge in <code>/etc/pve/notifications.cfg</code> und Clusterverhalten beschreibt <link>Benachrichtigungen → PVE-Webhook-Integration</link>."
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "API-Referenz",
"href": "/docs/monitor/api",
"tail": " — alle Endpunkte mit Methode, Pfad und vollständigem Prometheus-Metrikkatalog."
},
{
"label": "Benachrichtigungen",
"href": "/docs/monitor/notifications",
"tail": " — Ereignisquellen, Kanäle, Versandablauf und PVE-Webhook-Integration im Detail."
},
{
"label": "KI-Assistent",
"href": "/docs/monitor/ai-assistant",
"tail": " — optionale Überarbeitung von Vorlagentexten in verständliche Sprache vor dem Versand an Telegram, Discord, E-Mail oder Gotify."
},
{
"label": "Zugriff und Authentifizierung",
"href": "/docs/monitor/access-auth",
"tail": " — Erzeugen und Widerrufen der API-Token für diese Beispiele, Prüfprotokoll und TLS-Konfiguration."
}
]
}
}
@@ -0,0 +1,535 @@
{
"meta": {
"title": "Proxmox-Benachrichtigungen — Telegram, Discord, E-Mail, Gotify, Pushover, Apprise | ProxMenux Monitor",
"description": "Senden Sie Proxmox VE-Benachrichtigungen an Telegram, Discord, E-Mail, Gotify, Pushover und ~80 zusätzliche Dienste über Apprise. ProxMenux Monitor verwandelt Ereignisse aus dem Health Monitor, dem Journal Watcher und dem Proxmox VE webhook in reichhaltige Nachrichten mit Deduplizierung, Cooldown, Burst-Aggregation, einer optionalen KI-Umschreibung und einer vollständigen Historie.",
"ogTitle": "Proxmox-Benachrichtigungen — Telegram, Discord, E-Mail, Gotify, Pushover, Apprise",
"ogDescription": "Senden Sie Proxmox VE-Benachrichtigungen an Telegram, Discord, E-Mail, Gotify, Pushover und ~80 zusätzliche Dienste über Apprise - mit Deduplizierung, Cooldown, Burst-Aggregation und einer optionalen KI-Umschreibung.",
"twitterTitle": "Proxmox Benachrichtigungen | ProxMenux Monitor",
"twitterDescription": "Senden Sie Proxmox VE-Benachrichtigungen an Telegram, Discord, E-Mail, Gotify, Pushover und ~80 zusätzliche Dienste über Apprise."
},
"header": {
"title": "Benachrichtigungen",
"description": "Verteilt Ereignisse der Monitor-Datensammler an Telegram, Discord, E-Mail, Gotify, Pushover und etwa 80 Dienste über Apprise. Mit Deduplizierung, Wartezeiten für Wiederholungen, Zusammenfassung von Ereignisspitzen, Ereignis-/Kanalfiltern, optionaler KI und abrufbarem Verlauf.",
"section": "ProxMenux-Monitor"
},
"intro": {
"title": "Woher die Nachrichten kommen",
"body": "Benachrichtigungen verteilen die Ereignisse bestehender Monitor-Quellen: <link>Health Monitor</link>, Systemjournal- und Aufgabenüberwachung, PVE-Webhook, regelmäßige Abfragen und direkte Aufrufe der ProxMenux-Skripte. Jedes Ereignis durchläuft denselben Versandprozess."
},
"howItWorks": {
"heading": "Wie es funktioniert",
"intro": "Jede Benachrichtigung folgt dem gleichen Pfad durch den Monitor-Prozess. Ereignisse werden von einer Handvoll unabhängiger Sammler produziert, in eine strukturierte Nutzlast normalisiert, durch eine Versandpipeline geleitet, die entscheidet, ob und in welcher Form gesendet werden soll, optional von einem LLM umgeschrieben und schließlich auf die Kanäle aufgefächert, die der Benutzer konfiguriert hat.",
"arrowLabel": "Ereignis",
"caption": "Übersicht des Ablaufs. Tatsächliche Versandversuche werden bei Erfolg, Zusammenfassung oder Fehler im SQLite-Verlauf gespeichert. Durch Wartezeiten unterdrückte Ereignisse werden nicht protokolliert.",
"nodes": {
"sourcesLabel": "Quellen",
"sourcesDetail": "Health Monitor\nSystemjournal-Überwachung\nAufgabenüberwachung\nPVE-Webhook\nRegelmäßige Abfragen\nDirekte Ereignisquellen",
"dispatchLabel": "Versandablauf",
"dispatchDetail": "Ereignisspitzen zusammenfassen\nFingerabdruck / Wartezeit prüfen\nGruppenlimits\nKanalsteuerung",
"aiLabel": "KI-Überarbeitung (optional)",
"aiDetail": "OpenAI / Anthropic\nGemini / Groq\nOpenRouter / Ollama\n(standardmäßig deaktiviert)",
"channelsLabel": "Kanäle",
"channelsDetail": "Telegram\nDiscord\nE-Mail (SMTP)\nGotify\nPushover\nApprise (~80 Dienste)"
}
},
"enabling": {
"heading": "Benachrichtigungen aktivieren",
"intro": "Nach einer Neuinstallation zeigt die Karte unter Einstellungen <em>Deaktiviert</em> und die Schaltfläche <em>Benachrichtigungen aktivieren</em>. Zuvor wird nichts versendet und keine PVE-Konfiguration geändert.",
"disabledAlt": "Benachrichtigungskarte nach Neuinstallation mit Status Deaktiviert und Schaltfläche zum Aktivieren",
"disabledCaption": "Der erste Zustand - ein Klick zum Aktivieren.",
"stepsIntro": "Das Drücken des Knopfes macht drei Dinge in der Reihenfolge:",
"steps": [
"Wechselt zu <em>Aktiv</em> und zeigt das Kanalformular an.",
"Registriert ein Proxmox-Webhook-Ziel in <code>/etc/pve/notifications.cfg</code>. Ohne HTTPS verwendet es <code>POST http://127.0.0.1:8008/api/notifications/webhook</code>, mit HTTPS den lokalen HTTP-Empfänger auf Port 8009. PVE-Meldungen gelangen in den Versandprozess des Monitors. Siehe <pvelink>PVE-Webhook-Integration</pvelink>.",
"Startet den Versandthread, der die Ereigniswarteschlange abfragt und jedes Ereignis verarbeitet."
],
"activeAlt": "Aktivierte Benachrichtigungskarte mit Kanälen, Anzeigename und aufklappbaren erweiterten KI-Einstellungen",
"activeCaption": "Aktiv: Kanalregister oben (Telegram / Gotify / Discord / E-Mail / Pushover / Apprise), Anzeigename, Kanal-Kategorien und aufklappbarer Abschnitt <em>Erweitert: KI-Verbesserung</em>."
},
"sources": {
"heading": "Ereignisquellen",
"intro": "Sechs Quelltypen liefern Ereignisse: Hintergrundsammler, Webhook-Empfänger und direkte Quellen im Prozess. Sie erzeugen strukturierte <code>NotificationEvent</code>-Objekte.",
"headerCollector": "Sammler",
"headerWatches": "Überwacht",
"headerEvents": "Typische Ereignisse",
"rows": [
{
"collector": "Gesundheitsmonitor",
"watches": "Zehn Kategorien, alle 5 Minuten",
"events": "<code>new_error</code>, <code>error_resolved</code>, <code>error_escalated</code>, <code>health_degraded</code>, <code>health_persistent</code>."
},
{
"collector": "Journal-Überwachung",
"watches": "<code>journalctl --follow</code> mit Mustern für SSH-/Web-Anmeldefehler, Fail2Ban-Sperren bei installierter Jail, Kernel-E/A-Fehler, OOM und smartd-Ereignisse.",
"events": "<code>auth_fail</code>, <code>ip_block</code>, <code>oom_kill</code>, <code>disk_io_error</code>, <code>service_fail</code>."
},
{
"collector": "Aufgabenüberwachung",
"watches": "Prüft <code>/var/log/pve/tasks/index</code> auf neue Aufgaben-UPIDs und verfolgt deren Protokolldateien.",
"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": "Proxmox-Webhook-Empfänger",
"watches": "Empfängt <code>POST /api/notifications/webhook</code>. PVE-Versionen mit Webhook-Zielen können nach der Einrichtung Meldungen hierher senden; siehe <pvelink>unten</pvelink>.",
"events": "Alles, was PVE aussendet - einschließlich Ereignisse, die der Monitor sonst verpassen würde (HA, Replikation, vzdump von der GUI)."
},
{
"collector": "Regelmäßige Abfragen",
"watches": "Regelmäßige Vergleiche von Cluster-Erreichbarkeit, Zertifikatsablauf, GPU-Passthrough und verfügbaren PVE-/ProxMenux-Updates.",
"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": "In-Prozess-Emittenten",
"watches": "Direkte Aufrufe aus ProxMenux-Skripten und dem Monitor selbst (<code>notification_manager.emit_event(...)</code>).",
"events": "<code>system_startup</code>, <code>system_shutdown</code>, <code>system_reboot</code>, <code>ai_model_migrated</code>, benutzerdefinierte Testereignisse."
}
],
"after1": "Jedes Ereignis trägt eine stabile <code>event_type</code> (der Katalog ist unten), eine <code>severity</code> (<code>INFO</code>, <code>WARNING</code>, <code>CRITICAL</code>), eine <code>category</code> (für Emoji-Anreicherung und Pro-Gruppen-Filter verwendet) und eine <code>data</code> Nutzlast mit allem, was die Vorlage benötigt (<code>vmid</code>, <code>device</code>, <code>source_ip</code>, <code>reason</code>...).",
"after2": "Für jeden <code>event_type</code> erzeugt eine Vorlage in <code>notification_templates.py</code> den Nachrichtentext. Dieser durchläuft den Versand und kann bei aktivierter KI umgeschrieben werden. Die <ailink>Seite zum KI-Assistenten</ailink> beschreibt das Zusammenspiel."
},
"channels": {
"heading": "Kanäle einrichten",
"intro": "Derzeit werden sechs Kanäle unterstützt: Telegram, Discord, Gotify, Email (SMTP), Pushover und Apprise. Die ersten fünf sind native Integrationen mit eigenen Konfigurationsfeldern. Apprise ist ein allgemeiner Hub, der 80 zusätzliche Dienste (ntfy, Matrix, Slack, Teams, Pushbullet, AWS SNS, Mattermost ...) über ein einziges URL-Feld hinzufügt. Sie sind alle Schritt für Schritt unten dokumentiert.",
"credsTitle": "Speicherort der Zugangsdaten",
"credsBody": "Tokens, Schlüssel, webhook-URLs und SMTP-Passwörter werden lokal in der SQLite-Datenbank des Monitors unter <code>/usr/local/share/proxmenux/</code> gespeichert. Sensible Werte werden in der Schnittstelle geschützt und maskiert. Sie verlassen den Gastgeber nie, außer um ihre jeweiligen Dienste zu erreichen. Eine Sicherung dieses Verzeichnisses reicht aus, um die konfigurierten Kanäle wiederherzustellen."
},
"telegram": {
"heading": "Telegram",
"intro": "Benötigt werden ein <strong>Bot-Token</strong>, das für mehrere Chats nutzbar ist, und eine <strong>Chat-ID</strong> für den Zielchat, eine Gruppe oder ein Supergruppen-Thema. Die integrierte Anleitung führt durch die Einrichtung; unten werden auch die ID-Formate erklärt.",
"guideAlt": "Telegram-Einrichtung mit vier Schritten: BotFather, Bot-Token, Chat-ID und Gruppen oder Kanäle",
"guideCaption": "Der Link <em>+ Einrichtungsanleitung</em> öffnet vier Schritte, mit denen der Bot und der Kanal in etwa zwei Minuten eingerichtet werden.",
"step1Title": "1 · Erstellen Sie einen Bot mit BotFather",
"step1Items": [
"Öffnen Sie Telegram und starten Sie einen Chat mit <a>@BotFather</a> (derjenige mit dem blauen Verifizierungshaken - Kopien sind üblich).",
"<code>/newbot</code> senden.",
"Anzeigenamen wählen, etwa <em>ProxMenux Lab</em>. Später änderbar.",
"Einen eindeutigen Telegram-Benutzernamen wählen, der mit <code>bot</code> endet, etwa <em>proxmenux_lab_bot</em>.",
"BotFather antwortet mit einem Token wie <code>123456789:ABCdef…</code>. Dies ist das Bot-Token; wie ein Passwort behandeln."
],
"step2Title": "2 · Erhalten Sie die Chat-ID",
"step2Intro": "Die Chat-ID bestimmt, <em>wohin</em> der Bot sendet. Je nach Ziel gibt es zwei Formen.",
"privateLabel": "Privater Chat (Sie erhalten die Benachrichtigungen auf Ihrem eigenen Konto):",
"privateItems": [
"Dem neuen Bot eine Nachricht wie <code>/start</code> senden.",
"Mit <a1>@userinfobot</a1> oder <a2>@myidbot</a2> chatten und <code>/start</code> senden. Die Antwort enthält Ihre numerische Benutzer-ID, zugleich die positive Chat-ID."
],
"privateAlt": "Telegram-Kanalformular gefüllt mit Bot Token (maskiert), positiver Chat-ID für einen privaten Chat und einem leeren optionalen Themen-ID-Feld",
"privateCaption": "Privater Bot-Chat: Chat-ID ist die positive persönliche Benutzer-ID.",
"groupLabel": "Gruppe oder Supergruppe mit Themen:",
"groupItems": [
"Bot als Mitglied hinzufügen; bei Bedarf Schreibrechte als Administrator erteilen.",
"Senden Sie eine Nachricht in der Gruppe.",
"Öffnen Sie <code>https://api.telegram.org/bot&lt;YOUR_TOKEN&gt;/getUpdates</code> in einem Browser. Suchen Sie nach <code>chat.id</code> in der JSON-Antwort - für Gruppen ist es eine negative Zahl, für Supergruppen beginnt es mit <code>-100</code>.",
"Bei Supergruppen mit <em>Themen</em> die gewünschte <code>message_thread_id</code> im optionalen Feld <em>Themen-ID</em> eintragen."
],
"groupAlt": "Telegram-Formular mit maskiertem Bot-Token, negativer Supergruppen-ID beginnend mit -100 und Themen-ID 3",
"groupCaption": "Die Chat ID beginnt mit <code>-100…</code> und die optionale <em>Topic ID</em> zielt auf einen bestimmten Thread ab.",
"step3Title": "3 · Speichern und Testen",
"step3Body": "Bot-Token und Chat-ID eintragen, speichern und <em>Test senden</em> wählen. Die Nachricht sollte binnen einer Sekunde eintreffen. Bei Fehlern zeigt der Verlauf den Grund, etwa ungültiges Token, fehlende Gruppenmitgliedschaft oder Blockierung durch den Benutzer."
},
"discord": {
"heading": "Discord",
"intro": "Discord-Kanäle akzeptieren eingehende Nachrichten über einen <em>Webhook URL</em>, der an einen einzelnen Kanal gebunden ist. Der Monitor benötigt diese URL und nichts anderes.",
"items": [
"In Discord den Server öffnen und <em>Servereinstellungen → Integrationen → Webhooks</em> wählen.",
"<em>Neuer Webhook</em> wählen, einen Namen wie <em>ProxMenux</em> vergeben und den Zielkanal wählen. Avatar optional.",
"<em>Webhook-URL kopieren</em> wählen. Format: <code>https://discord.com/api/webhooks/&lt;id&gt;/&lt;token&gt;</code>.",
"Fügen Sie es in das Webhook URL-Feld des Discord-Tabs im Benachrichtigungsfeld ein und speichern Sie es."
],
"imageAlt": "Discord Kanalformular mit Webhook URL Feld beginnend mit https://discord.com/api/webhooks/",
"imageCaption": "Discord — Fügen Sie die Webhook-URL aus <em>Server-Einstellungen → Integrationen → Webhooks</em> ein."
},
"gotify": {
"heading": "Gotify",
"intro": "Gotify ist ein selbst betriebener Push-Server. Benötigt werden seine Basis-URL und ein in der Verwaltung erzeugtes <em>Anwendungstoken</em>.",
"items": [
"Falls Gotify noch nicht läuft, folgen Sie der <a>offiziellen Installationsanleitung</a>.",
"Als Administrator in Gotify <em>Apps</em> → <em>Anwendung erstellen</em> öffnen, einen Namen wie <em>ProxMenux</em> vergeben und das Token kopieren.",
"Im Gotify-Kanal <em>Server-URL</em> auf die Basis-URL setzen, etwa <code>https://gotify.example.com</code>, und das Anwendungstoken einfügen.",
"Speichern und <em>Test senden</em> wählen."
],
"imageAlt": "Gotify-Kanalformular mit Server-URL-Feld auf https://gotify.example.com und ein App-Token-Feld mit Platzhalter A_valid_gotify_token",
"imageCaption": "Gotify - Server-URL Ihrer selbst gehosteten Instanz sowie das App-Token von der Gotify-Admin-Benutzeroberfläche."
},
"email": {
"heading": "E-Mail (SMTP)",
"intro": "E-Mail ist der flexibelste Kanal - und der mit den meisten Feldern. Sie benötigen einen SMTP-Server, einen Port, einen TLS-Modus, optional einen Benutzernamen und ein Passwort, eine Absenderadresse und mindestens einen Empfänger.",
"imageAlt": "SMTP-Formular mit Host, Port, TLS-Modus, Benutzername, Passwort, Absender, durch Kommas getrennten Empfängern und Betreffpräfix",
"imageCaption": "SMTP-Host, Port, TLS-Modus, optional Benutzername und Passwort, Absender, Empfänger und Betreffpräfix zum Filtern im Posteingang.",
"appNote": "Der Monitor nutzt SMTP mit Passwort. Gmail kann ein <strong>App-Passwort</strong> verlangen. Bei Microsoft hängt die Unterstützung vom Dienst und den Mandantenrichtlinien ab; ein App-Passwort umgeht keine Sperre der Basisauthentifizierung. Zulässigkeit vorab prüfen.",
"gmailTitle": "Gmail App Passwort",
"gmailIntro": "Gmail-App-Passwörter benötigen aktive <strong>Bestätigung in zwei Schritten</strong>. Andernfalls ist <em>App-Passwörter</em> nicht verfügbar.",
"gmailItems": [
"Öffnen Sie <a>myaccount.google.com/security</a> und aktivieren Sie <em>2-Schritt-Verifizierung</em>, wenn es nicht bereits eingeschaltet ist.",
"Gehen Sie zu <a>myaccount.google.com/apppasswords</a>.",
"Einen Namen wie <em>ProxMenux</em> eingeben und <em>Erstellen</em> wählen. Das 16-stellige Passwort kopieren.",
"Eintragen: <em>Host</em> <code>smtp.gmail.com</code>, <em>Port</em> <code>587</code>, <em>TLS-Modus</em> <code>STARTTLS</code>, <em>Benutzername</em> Ihre Gmail-Adresse, <em>Passwort</em> das 16-stellige App-Passwort."
],
"outlookTitle": "Microsoft / Outlook App Passwort",
"outlookIntro": "Microsoft-App-Passwörter erfordern <strong>zweistufige Überprüfung</strong>, gewährleisten aber keine SMTP-Kompatibilität. Verlangt der Dienst oder Mandant OAuth2, kann sich der Passwort-SMTP-Client des Monitors nicht anmelden. Nutzen Sie ein Relay mit passender Authentifizierung zum Anbieter.",
"outlookItems": [
"Öffnen Sie <a>account.microsoft.com/security</a> und ermöglichen Sie eine zweistufige Verifizierung.",
"Falls angeboten, unter <em>Erweiterte Sicherheitsoptionen</em> → <em>App-Passwörter</em> die Option <em>Neues App-Passwort erstellen</em> wählen. Das garantiert keine Unterstützung für SMTP mit Passwort.",
"Falls ein App-Passwort erzeugt wird, kopieren und die SMTP-Zulässigkeit prüfen.",
"Nur wenn Ihr Anbieter Passwort-SMTP erlaubt, die genehmigten Werte eintragen: <em>SMTP-Host</em> <code>smtp.office365.com</code> für Exchange Online, <em>Port</em> <code>587</code>, <em>TLS-Modus</em> <code>STARTTLS</code>, <em>Benutzername</em> Ihre Postfachadresse und <em>Passwort</em> die erlaubte SMTP-Zugangsinformation. Persönliches Outlook.com hat andere Einstellungen und Authentifizierungsanforderungen; gehen Sie nicht davon aus, dass diese Zugangsdaten funktionieren."
],
"relayTitle": "Selbst gehostetes SMTP-Relay",
"relayBody": "Den Monitor auf ein eigenes SMTP-Relay wie Postfix richten. Das Relay authentifiziert sich beim Anbieter. Authentifizierung und TLS des Monitors müssen zum Relay passen; ein lokales Relay deaktiviert die Verschlüsselung nicht automatisch."
},
"pushover": {
"heading": "Pushover",
"intro": "Pushover ist ein mobiler Push-Service mit offiziellen Apps für iOS, Android und Desktop-Browser. Der dedizierte ProxMenux-Kanal spricht direkt mit dem <a>Pushover API</a>, so dass keine Apprise-URL erforderlich ist.",
"stepsTitle": "Einrichtung",
"steps": [
"Ein <a>Pushover-Konto</a> erstellen, die App auf den gewünschten Empfängergeräten installieren und anmelden.",
"Kopieren Sie den <em>User Key</em>, der auf Ihrem Pushover-Dashboard angezeigt wird. Ein Gruppenschlüssel kann stattdessen verwendet werden, wenn mehrere Personen oder Geräte die gleiche Warnung erhalten müssen.",
"<a>Anwendung/API-Token erstellen</a> öffnen, eine Anwendung namens <em>ProxMenux</em> erstellen und ihr 30-stelliges API-Token kopieren.",
"Unter <em>Einstellungen → Benachrichtigungen → Pushover</em> Benutzer- oder Gruppenschlüssel und API-Token eintragen. Gerät und Ton sind optional.",
"Speichern und <em>Test senden</em> wählen. Die App sollte die Nachricht sofort empfangen."
],
"priorityTitle": "Prioritäre Zuordnung",
"priorityBody": "Normale Meldungen verwenden Pushover-Priorität 0. Mit <strong>Hohe Priorität für kritische Warnungen</strong> verwenden CRITICAL-Ereignisse Priorität 1 und umgehen Pushover-Ruhezeiten. Notfallpriorität 2 mit wiederholten Meldungen und Bestätigung wird nicht verwendet.",
"secretTitle": "Schützen Sie beide Werte",
"secretBody": "Der Benutzer- oder Gruppenschlüssel und das Anwendungstoken API autorisieren beide die Nachrichtenzustellung. ProxMenux speichert sie als geschützte Benachrichtigungsgeheimnisse und maskiert sie in der Schnittstelle; Veröffentlichen Sie keinen Wert in Screenshots oder Support-Protokollen."
},
"apprise": {
"heading": "Apprise (generischer Hub für ~ 80-Dienste)",
"intro": "Apprise unterstützt etwa 80 Dienste über URLs. So erreichen Sie ntfy, Matrix, Slack, Microsoft Teams, Mattermost, Pushbullet, AWS SNS, Pushsafer, Rocket.Chat, Signal API und weitere Dienste ohne eigene Monitor-Integration. Auch Pushover ist möglich; für ein einzelnes Pushover-Ziel ist dessen eigener Kanal einfacher.",
"listIntro": "Die vollständige Liste der unterstützten Dienste und das genaue URL-Format für jeden einzelnen finden Sie in der offiziellen Apprise-Dokumentation:",
"listItems": [
"<a>Apprise-Dokumentation der Dienste</a> — vollständige Liste.",
"<a>URL-Grundlagen</a> — Aufbau der Apprise-URLs."
],
"stepsTitle": "Schritte",
"steps": [
"Wählen Sie den Zieldienst im <a>Apprise wiki</a> und kopieren Sie die URL-Vorlage dafür. Jede Serviceseite zeigt das genaue zu verwendende Schema (<code>ntfy://</code>, <code>matrix://</code>, <code>pover://</code>, <code>slack://</code>...) sowie alle erforderlichen Token, Kanäle oder Hostnamen.",
"Füllen Sie die Platzhalter mit Ihren eigenen Anmeldeinformationen aus. Zum Beispiel sieht ein ntfy.sh-Thema aus wie <code>ntfy://ntfy.sh/my-topic</code>; eine Pushover-URL sieht aus wie <code>pover://user@token</code>; eine Matrix-URL sieht aus wie <code>matrix://user:pass@host:port/#room</code>.",
"Fügen Sie die endgültige URL in das Feld <em>Apprise URL</em> im Apprise-Tab des Benachrichtigungsfelds ein und speichern Sie es.",
"Drücken Sie <em>Send Test</em>, um zu überprüfen, ob die URL erreichbar ist und die Anmeldeinformationen akzeptiert werden."
],
"deliveredTitle": "Was geliefert wird",
"deliveredBody": "Apprise erhält die gleiche Nutzlast wie die anderen Kanäle - Titel, Körper und Schweregrad (Info / Erfolg / Warnung / Misserfolg). Der Schweregrad wird dem zugeordnet, was der Zieldienst ausstellt (Icon, Priorität, Farbe). Rich-Message-Formatierung und die AI-Rewrite-Ebene laufen alle, bevor die URL aufgerufen wird, genau wie bei Telegram oder E-Mail.",
"fanoutTitle": "Eine URL pro Apprise Kanal",
"fanoutBody": "Der Monitor bietet ein URL-Feld pro Apprise-Kanal. Für mehrere Dienste, etwa ntfy.sh und Matrix, einen <a>Apprise-API-Server</a> mit markierter Konfiguration verwenden. Er verteilt den Monitor-Aufruf an alle URLs des gewählten Tags."
},
"rich": {
"heading": "Formatierte Meldungen, Kategorien und Kanalfilter",
"intro": "Jeder Kanal hat drei Steuerelemente: <em>Formatierte Meldungen</em> oben, elf aufklappbare <em>Benachrichtigungskategorien</em> mit Ereignisschaltern und <em>Test senden</em> unten.",
"imageAlt": "Benachrichtigungskategorien-Panel mit Rich-Nachrichten-Master-Schalter oben hervorgehoben, zusammenklappbare Abschnitte für VM/CT, Backups, Ressourcen, Speicher, Netzwerk, Sicherheit, Cluster, Dienste, Gesundheitsmonitor, Updates jeweils mit Umschalt- und Ereignisanzahl und eine Send-Test-Schaltfläche",
"imageCaption": "Der Pfeil markiert <em>Formatierte Meldungen</em>. Darunter liegen elf Kategorien mit Ereignisschaltern; <em>Test senden</em> steht unten.",
"richTitle": "Formatierte Meldungen",
"richIntro": "Mit <em>Formatierten Meldungen</em> erscheint ein Kategorie-Emoji und das native Kanalformat, etwa Telegram-HTML oder farbige Discord-Einbettungen. Ohne diese Option wird derselbe Inhalt als einfacher Text gesendet:",
"plainHeader": "Einfacher Text — Formatierung aus",
"richHeader": "Formatierter Text — Formatierung ein",
"richOutro": "Jeder Kanal entscheidet separat. E-Mail kann einfach bleiben, während Telegram und Discord formatiert werden. Kanäle ohne unterstützte Formatierung wie einfache E-Mail oder Gotify erhalten Text.",
"togglesTitle": "Per-Event Kategorien",
"togglesIntro": "Jeder Kanal steuert Kategorien und Ereignisse unabhängig. Eine deaktivierte Kategorie unterdrückt ihre Ereignisse für diesen Kanal. Einzelne Schalter wirken innerhalb aktivierter Kategorien; im Dispatcher gibt es keinen globalen Ereignis-Hauptschalter.",
"togglesItems": [
"<strong>Kategorieschalter je Kanal.</strong> Eine deaktivierte VM/CT-Kategorie unterdrückt <code>vm_start</code> und verwandte Ereignisse. Gespeichert als <code>&lt;channel&gt;.events.&lt;group&gt;</code>.",
"<strong>Ereignisschalter je Kanal.</strong> In einer aktiven Kategorie etwa <em><code>backup_complete</code> an Discord, aber nicht an Telegram senden</em>. Gespeichert als <code>&lt;channel&gt;.event.&lt;event_type&gt;</code>."
],
"togglesOutro": "Jede Kategorie zeigt <em>aktivierte Ereignisse</em> / <em>Gesamtzahl</em> und einen Schalter für die ganze Gruppe, etwa <code>info</code>-Sicherungen oder Update-Meldungen, ohne Aufklappen."
},
"quiet": {
"heading": "Ruhezeiten",
"intro": "Während der Ruhezeit eines Kanals passieren nur <strong>CRITICAL</strong>-Ereignisse. INFO, WARNING und Aktionen werden auf Datenträger gespeichert und nach Ende des Fensters zusammengefasst gesendet.",
"imageAlt": "Kanaleinstellungen: Ruhezeit 22:00–07:00 mit Vorschau, darunter tägliche Zusammenfassung um 09:00 und Hinweis, dass diese CRITICAL und WARNING nicht verzögert",
"imageCaption": "Zwei unabhängige Einstellungen je Kanal: Ruhezeiten oben, tägliche Zusammenfassung darunter.",
"purposeTitle": "Wofür es ist",
"purposeItems": [
"<strong>Keine Update-Meldung um 03:00.</strong> Sicherungen, App-Updates, Optimierungen und andere INFO-Ereignisse wecken Sie nachts nicht.",
"<strong>Kritische Ereignisse kommen weiterhin an.</strong> Nur als CRITICAL eingestufte Ereignisse umgehen Ruhezeiten. Der Name bestimmt den Schweregrad nicht: Die Journal-Überwachung meldet Fail2Ban-Sperren sowie Host-Abschaltung/Neustart als INFO; sie können daher gepuffert werden.",
"<strong>Zurückgestellte Meldungen behalten.</strong> Sie werden bis zum Ende des Fensters in SQLite gepuffert."
],
"howTitle": "Wie es funktioniert",
"howItems": [
"<strong>Pro Kanal.</strong> Telegram kann von 22:00 bis 07:00 ruhen, während E-Mail rund um die Uhr empfängt.",
"<strong>Beginn und Ende</strong> in lokaler Zeitzone: Beginn eingeschlossen, Ende ausgeschlossen. Das Fenster kann Mitternacht überschreiten, etwa 22:00–07:00.",
"<strong>Aktuelle Vorschau.</strong> Unter den Feldern werden der aktive Zustand und der nächste Wechsel angezeigt.",
"<strong>Während des Fensters:</strong> CRITICAL wird normal versendet. INFO und WARNING bleiben in der SQLite-Tabelle <code>quiet_pending</code>.",
"<strong>Wenn sich das Fenster schließt:</strong> wird eine einzige gruppierte Benachrichtigung mit allem, was sich angesammelt hat, gesendet - eine Zeile pro gepuffertem Ereignis in chronologischer Reihenfolge. Der Puffer wird erst gelöscht, nachdem der Kanal die Lieferung bestätigt hat, so dass ein vorübergehender Telegram / SMTP-Ausfall den Nachtkontext nicht verliert.",
"<strong>Über Neustarts hinweg.</strong> Der Puffer bleibt auf Datenträger. Nach einem Neustart erkennt der nächste Zyklus ausstehende Zeilen und versendet sie gegebenenfalls als Wiederherstellungszusammenfassung."
],
"criticalTitle": "Welche Ereignisse CRITICAL sind",
"criticalBody": "Der Erzeuger legt den Schweregrad fest. Festplatten-, Abschalt- oder Sicherheitsereignisse sind nicht allein wegen ihres Namens CRITICAL. Die Journal-Überwachung erzeugt ip_block, system_shutdown und system_reboot als INFO. Der <link>Ereigniskatalog</link> nennt die Typen; den tatsächlichen Schweregrad bestimmen Erzeuger und empfangenes Ereignis."
},
"digest": {
"heading": "Tägliche Zusammenfassung der INFO-Ereignisse",
"intro1": "Die tägliche Zusammenfassung ist <strong>freiwillig aktivierbar</strong>. Geeignete INFO-Meldungen, etwa verfügbare Updates, werden um 09:00 oder zur gewählten Zeit gebündelt. Sicherungs-/Replikationsergebnisse und direkte Aktionen sind ausgenommen. Ruhezeiten verzögern nicht kritische Meldungen innerhalb eines Fensters.",
"intro2": "Die Einstellung steht unter den Ruhezeiten in derselben Karte, siehe <link>Ruhezeiten</link>. Beide sind unabhängig aktivierbar.",
"purposeTitle": "Wofür es ist",
"purposeItems": [
"<strong>Morgendlicher Überblick.</strong> Eine Zusammenfassung um 09:00 ersetzt etwa 20 einzelne Meldungen vom Vortag, ohne 20 Telegram-Nachrichten lesen zu müssen.",
"<strong>Aktivität und Dringlichkeit unterscheiden.</strong> INFO beschreibt Geschehenes; CRITICAL und WARNING zeigen Handlungsbedarf. Geeignete INFO-Ereignisse werden gebündelt, andere behalten die direkte Zustellung."
],
"howTitle": "Wie es funktioniert",
"howItems": [
"<strong>Je Kanal aktivieren.</strong> Standardmäßig aus. Nur gewünschte Kanäle zusammenfassen; andere weiter direkt beliefern.",
"<strong>Zustellzeit</strong> in lokaler Zeitzone, standardmäßig 09:00. Der Versand erfolgt etwa innerhalb von 60 s um diese Minute.",
"<strong>In der Zusammenfassung enthalten:</strong> geeignete allgemeine Ereignisse mit Schwere <strong>INFO</strong>. Beispiele sind <em>App-Update verfügbar</em>, <em>Tailscale-Update verfügbar</em>, <em>ProxMenux-Optimierungsupdate verfügbar</em> und <em>APT-Sicherheitsupdates ausstehend</em>. Sicherungsergebnisse und andere ausgenommene Aktionsereignisse bleiben direkt.",
"<strong>Was ist nie verzögert:</strong>",
"<strong>Dauerhafte Speicherung.</strong> Ausstehende Ereignisse bleiben bis zur Zustellzeit in <code>digest_pending</code> in SQLite und überstehen Neustarts.",
"<strong>Leere Tage sind still.</strong> Wenn nichts INFO-Level passiert ist, wird kein Digest gesendet - der Kanal bleibt ruhig, anstatt eine Nachricht \"keine Ereignisse zu melden\" zu erhalten."
],
"neverDelayedSub": [
"<strong>CRITICAL</strong>-Ereignisse gehen immer sofort durch.",
"<strong>WARNING</strong>-Ereignisse gehen immer sofort durch.",
"VM/CT-Aktionen und Fehler, Sicherungsbeginn und -ergebnisse, Replikationsergebnisse sowie Host-Abschaltung/Neustart umgehen die tägliche Zusammenfassung auch als INFO. Ruhezeiten können nicht kritische Ereignisse weiterhin verzögern."
],
"comboTitle": "Kombinieren von ruhigen Stunden und täglichem Digest",
"comboBody": "Ein Kanal kann <em>beides</em> verwenden: Ruhezeit 22:00–07:00 und Zusammenfassung um 09:00. Nicht kritische Ereignisse des Fensters werden um07:00 freigegeben; geeignete INFO-Ereignisse außerhalb gelangen in die Tageszusammenfassung. CRITICAL umgeht beides; WARNING nur die Tageszusammenfassung, nicht die Ruhezeit. Wählen Sie ein <em>Ruhefenster</em>, eine <em>Zusammenfassung zur festen Zeit</em> oder beides."
},
"displayName": {
"heading": "Anzeigename",
"intro": "Jede Meldung trägt einen <em>Anzeigenamen</em> für den Host, etwa <code>🏠 home-lab</code>, im Fuß der formatierten Meldung und im E-Mail-Betreffpräfix.",
"imageAlt": "Anzeigename mit Beispiel amd; eigener Name möglich, leeres Feld verwendet Systemhostnamen",
"imageCaption": "Anzeigename leer lassen, um den Systemhostnamen zu verwenden, oder einen eigenen Namen eintragen.",
"outro": "Wenn das Feld leer ist, greift der Monitor auf den Systemhostnamen zurück. Der Override ist vor allem nützlich, wenn Sie mehrere ProxMenux-Hosts ausführen, die an denselben Telegram-Chat oder Posteingang senden - ein freundlicheres Label (<em>home-lab</em>, <em>office-pve</em>) ist einfacher zu lesen als <code>pve01.lan</code> oder <code>pmx-prod-01</code>."
},
"dispatch": {
"heading": "Versandablauf",
"intro": "Die Tabelle beschreibt drei Mechanismen. Tatsächlich folgen auf die Zusammenfassung von Ereignisspitzen Zustellreservierung, Wiederholungsprüfung und Gruppenlimit; danach Textaufbereitung und Kanalsteuerung:",
"headerStage": "Phase",
"headerWhat": "Was es tut",
"headerTunable": "Anpassbar?",
"rows": [
{
"stage": "Deduplizierung per Fingerabdruck",
"what": "Jedes Ereignis wird in einen Fingerabdruck gehasht (<code>event_type + key fields from data</code>). Identische Fingerabdrücke innerhalb eines kurzen Fensters gelten als Duplikate des ersten.",
"tunable": "Nein — interne Dispatcherlogik."
},
{
"stage": "Wartezeit für Wiederholungen",
"what": "Nach erfolgreichem Versand werden Wiederholungen unterdrückt; der Zustand steht in <code>notification_last_sent</code>. Basiswerte für <code>CRITICAL</code>, <code>WARNING</code>, <code>INFO</code>, <code>resources</code> und <code>updates</code>: 86400 s. Ausnahmen: 5 s für VM/CT-Aktionen und Host-Neustart/Abschaltung, 10 s für Sicherungs-/Replikationsergebnisse, 1800–3600 s für mehrere Gesundheitskategorien. Explizite Ereignis-/Gruppeneinstellungen haben Vorrang.",
"tunable": "Nur über die Einstellungs-API — ein Schlüssel <code>cooldown.&lt;event_type&gt;</code> oder <code>cooldown.&lt;group&gt;</code> überschreibt die Vorgaben; in der Oberfläche gibt es dafür kein Steuerelement."
},
{
"stage": "Zusammenfassung von Ereignisspitzen",
"what": "Wenn N-Ereignisse in einem kurzen Fenster ankommen (z. B. eine Brute-Force-Flut von SSH), werden sie zu einer einzigen <code>burst_*</code>-Nachricht mit einer Zählung und einer Stichprobe zusammengefasst.",
"tunable": "Nein — Fenster und Schwellenwert sind pro Ereignistyp fest codiert."
}
],
"calloutTitle": "Versand im Hintergrundthread",
"calloutBody": "Die Dispatchschleife läuft in einem eigenen Thread. Die HTTP-Anforderung, die ein Ereignis aussendet, kehrt zurück, sobald das Ereignis in der Warteschlange steht – sie wartet nicht auf Telegram, SMTP oder webhook RTT. Jedes Sendeergebnis wird zur retrospektiven Überprüfung in der Historientabelle erfasst."
},
"aiRewrite": {
"heading": "Optionales AI-Rewrite",
"body1": "Geeignete Ereignisse können vor dem Versand durch ein LLM umgeschrieben werden. backup_complete und backup_fail sind ausgenommen. KI ist standardmäßig aus und läuft im Versandthread. Bei Fehler oder Zeitüberschreitung wird der Vorlagentext verwendet.",
"body2": "Unterstützt OpenAI, Anthropic, Google Gemini, Groq, OpenRouter und lokales Ollama. Pro Kanal: Detailgrad (<code>brief</code>, <code>standard</code>, <code>detailed</code>), Sprache, Anweisungsmodus (<code>default</code> oder <code>custom</code>) und eigene Anweisung. Anleitung und Beispiele unter <link>KI-Assistent</link>.",
"privacyTitle": "Datenschutzerklärung",
"privacyBody": "KI-Anfragen können Titel, Schweregrad, Text, System-/Benutzeranweisungen und Kontext mit Hostnamen, IPs, Benutzernamen, Fehlern und Journalzeilen enthalten. Sie gehen an den gewählten Endpunkt. Ollama bleibt nur mit lokalem Server und lokalem Modell lokal; entfernte Server oder Cloudmodelle übertragen Daten nach außen. Bei lokalen Anforderungen KI deaktivieren oder kontrollierten lokalen Server und Modell nutzen."
},
"pveWebhook": {
"heading": "PVE webhook Integration",
"intro1": "Proxmox verwendet <em>Benachrichtigungsziele</em>: sendmail, Gotify, SMTP und auf unterstützten Versionen Webhook. Der Monitor registriert ein <code>webhook</code>-Ziel. PVE-Meldungen zu HA, Replikation und GUI-Sicherungen gelangen damit in denselben Versandprozess.",
"intro2": "Das Ziel ist von der Proxmox GUI unter <em>Datacenter → Benachrichtigungen → Benachrichtigungsziele</em> sichtbar:",
"imageAlt": "Proxmox VE Webhook-Dialog bearbeiten, der das automatisch erstellte proxmenux-webhook-Ziel mit der Methode POST, URL http://127.0.0.1:8008/api/notifications/webhook und einer JSON-Körpervorlage mit Escape-Titel, Escape-Nachricht, Escape-Schweregrad, Escape-Zeitstempel und json-Feldern zeigt",
"imageCaption": "Das PVE-seitige webhook-Ziel, wie Proxmox es sieht (die GUI befindet sich im konfigurierten Gebietsschema des Hosts - Spanisch in diesem Beispiel). Gleiche Felder gelten in jeder Sprache.",
"registeredIntro": "Was registriert wird:",
"registeredItems": [
"<strong>Methode und URL.</strong> <code>POST http://127.0.0.1:8008/api/notifications/webhook</code> ohne Monitor-HTTPS; mit HTTPS der gesonderte lokale HTTP-Port 8009. Beide bleiben auf demselben Host.",
"<strong>Nachrichtenvorlage.</strong> JSON mit nativen Handlebars-Helfern von PVE, in der Konfiguration als Base64 gespeichert. Dekodiert ergibt es:",
"<strong>Matcher.</strong> Ein Begleiter <code>matcher: proxmenux-matcher</code> Block mit <code>mode all</code>, so dass jede PVE-Benachrichtigung das Ziel erreicht.",
"<strong>Private Konfiguration.</strong> Die Einrichtung schreibt den passenden Block <code>webhook: proxmenux-webhook</code> in <code>/etc/pve/priv/notifications.cfg</code> mit einem Base64-kodierten <code>secret</code>-Eintrag namens X-Webhook-Secret. Der öffentliche Zielblock enthält nur Body-Vorlage, Methode und URL. Der private Block ist kein leerer Platzhalter."
],
"securityTitle": "Wie der Empfänger gesichert ist",
"securityIntro": "Der webhook-Empfänger bei <code>POST /api/notifications/webhook</code> verwendet verschiedene Sicherheitsschichten, je nachdem, woher die Anforderung stammt:",
"securityItems": [
"<strong>Lokale Quellen (<code>127.0.0.1</code> / <code>::1</code>).</strong> Mengenbegrenzung gilt; entfernte Geheimnis-, Zeitstempel- und Wiederholungsprüfungen entfallen. Auch Adressen lokaler Host-Schnittstellen gelten als lokal. Das automatische PVE-Ziel verwendet Loopback.",
"<strong>Entfernte Aufrufer.</strong> Zusätzlich zum Mengenlimit werden Geheimnis in <code>X-Webhook-Secret</code>, Zeitstempel in <code>X-ProxMenux-Timestamp</code> oder JSON, Wiederholungen und eine optionale IP-Liste geprüft. Das Geheimnis steht in SQLite und als Base64-Kopie in <code>/etc/pve/priv/notifications.cfg</code>, damit PVE den Header sendet."
],
"practiceTitle": "In der Praxis",
"practiceBody": "PVE verwendet <code>http://127.0.0.1:8008</code> ohne HTTPS, sonst HTTP-Port 8009. Externe Integrationen an <code>https://&lt;monitor-host&gt;:&lt;port&gt;/api/notifications/webhook</code> müssen <code>X-Webhook-Secret</code> und aktuellen Zeitstempel liefern sowie Wiederholungs-/IP-Prüfungen bestehen. Nur der Geheimnis-Header reicht nicht.",
"actionsIntro": "Der Monitor verwaltet dieses Ziel durch drei Aktionen auf der Registerkarte Einstellungen:",
"actionsItems": [
"<strong>Einrichten</strong> legt beim Aktivieren den Eintrag in <code>/etc/pve/notifications.cfg</code> an. Nur Änderungen werden geschrieben; die drei jüngsten Sicherungen bleiben unter <code>/usr/local/share/proxmenux/backups/pve-notifications/</code>. Solange <code>/etc/pve</code> nicht eingehängt ist, wird gewartet, bis <code>pve-cluster</code> wieder verfügbar ist.",
"<strong>Bereinigen</strong> entfernt den Eintrag und behält die vorherige Sicherung.",
"<strong>Konfiguration lesen</strong> zeigt Ziele und Zuordnungsregeln zur Kontrolle mehrerer PVE-Versandrouten."
],
"clusterTitle": "Clusterknoten",
"clusterBody": "<code>/etc/pve/</code> samt Ziel-URL und Geheimnis wird im Cluster geteilt. Jeder Knoten ruft seinen <em>eigenen</em> Empfänger auf: <code>127.0.0.1:8008</code> ohne HTTPS, sonst HTTP 8009. Monitor auf jedem relevanten Knoten betreiben und das gemeinsame Ziel an alle Empfänger anpassen."
},
"catalogue": {
"heading": "Ereigniskatalog",
"intro": "Rund siebzig Ereignistypen sind in elf UI-Kategorien unterteilt. Das Benachrichtigungsfeld macht einen zusammenklappbaren Abschnitt pro Gruppe mit einem Umschalter für jedes Ereignis darin. Jedes Ereignis ist standardmäßig aktiviert, sofern nicht ausdrücklich anders gekennzeichnet.",
"headerGroup": "Gruppe",
"headerEvents": "Ereignisse",
"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 die <code>ct_*</code> Äquivalente, <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": "Sicherungen",
"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": "Ressourcen",
"events": "<code>cpu_high</code>, <code>ram_high</code>, <code>temp_high</code>, <code>load_high</code>."
},
{
"group": "Speicher",
"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": "Netzwerk",
"events": "<code>network_down</code>, <code>network_latency</code>."
},
{
"group": "Sicherheit",
"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": "Dienste",
"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": "Gesundheitsmonitor",
"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": "Aktualisierungen",
"events": "<code>update_summary</code>, <code>update_available</code>, <code>pve_update</code>, <code>update_complete</code>, <code>proxmenux_update</code>."
},
{
"group": "Hardware / GPU",
"events": "<code>gpu_mode_switch</code>, <code>gpu_passthrough_blocked</code>, <code>pci_passthrough_conflict</code>, <code>ai_model_migrated</code>."
}
],
"burstNote": "Eine Handvoll <code>burst_*</code>-Aggregationstypen (<code>burst_auth_fail</code>, <code>burst_ip_block</code>, <code>burst_disk_io</code> usw.) gibt es nur im Dispatcher — sie ersetzen einzelne Ereignisse durch eine einzige Zusammenfassungsnachricht und werden nicht als Umschaltungen in der Benutzeroberfläche angezeigt. Sie erben den Ein/Aus-Zustand ihres übergeordneten Ereignistyps.",
"backupResults": {
"heading": "Backup Ergebnisse",
"intro": "Eine Benachrichtigung über einen Proxmox Backup-Job gibt an, wie der Job beendet wurde. Das Ergebnis wird aus dem Bericht gelesen, den Proxmox sendet, und setzt den Titel, das Symbol, das mit <em>Rich-Nachrichten</em> angezeigt wird, und die Statuszeile der E-Mail.",
"headerIcon": "Icon",
"headerResult": "Ergebnis",
"headerWhen": "Wann",
"rows": [
{
"icon": "💾✅",
"result": "Backup vollständig",
"when": "Alle Gäste wurden gesichert; der Bericht enthält keine Warnungen."
},
{
"icon": "💾⚠️",
"result": "Backup mit Warnungen abgeschlossen",
"when": "Alle Gäste wurden gesichert; der Bericht enthält mindestens eine Warnung."
},
{
"icon": "💾❌",
"result": "Backup-Fehler gemeldet",
"when": "Ein Gast scheiterte oder der Job endete mit einem Fehler."
},
{
"icon": "💾❔",
"result": "Backup-Ergebnis nicht bestätigt",
"when": "Der Bericht ist unvollständig oder gibt kein Ergebnis für jeden Gast an."
}
],
"items": [
"<strong>Der Titel identifiziert den Auftrag.</strong> Er nennt Speicher sowie bei einem Gast dessen Typ, Name und ID. Bei einem Fehler wird der betroffene Gast genannt.",
"<strong>Der Text listet jeden Gast</strong> mit Ergebnis, Größe, Dauer und Archiv sowie anschließend die Gesamtwerte auf.",
"<strong>Warnungen und Fehler werden einmal aufgelistet.</strong> Wiederholte Zeilen werden ein einziges Mal mit der Hauptursache zuerst angezeigt; Nach acht Zeilen wird der Rest in einer Schlusszeile gezählt und bleibt im Proxmox-Taskprotokoll.",
"<strong>Ein Fehler vor dem ersten Gast</strong> zeigt die Proxmox-Ursache, etwa einen nicht vorhandenen Speicher.",
"<strong>Zusammenfassungen behalten das Ergebnis.</strong> Sicherungen in der Ruhezeit-Zusammenfassung behalten ihr Ergebnissymbol. Sicherungsergebnisse umgehen die Tageszusammenfassung."
]
}
},
"history": {
"heading": "Verlauf",
"body1": "Jeder tatsächliche <em>Versandversuch</em> steht in <code>notification_history</code>: Zeit <code>sent_at</code>, Kanal, Ereignis, Schwere, Titel, Text, <code>success</code> und bei Fehler <code>error_message</code>. Spitzen erscheinen als Typ <code>burst_*</code>. Durch Wartezeiten unterdrückte Ereignisse werden nicht protokolliert.",
"body2": "Einstellungen → Benachrichtigungen enthält den standardmäßig geschlossenen <em>Benachrichtigungsverlauf</em> mit den letzten 20 Einträgen: Ergebnis, Kanal, Datum, Fehler und Status jedes Tageszusammenfassungslaufs. Die Seite bietet kein Löschen; Audit & Report prüft dieselben Zustelldaten.",
"body3": "Die gleichen Daten werden bei <code>GET /api/notifications/history</code> mit optionalen <code>limit</code>, <code>offset</code>, <code>severity</code> und <code>channel</code> Abfrageparametern ausgesetzt und können mit <code>DELETE /api/notifications/history</code> gelöscht werden."
},
"api": {
"heading": "API-Endpunkte",
"headerEndpoint": "Endpunkt",
"headerMethod": "Methode",
"headerUse": "Verwenden",
"rows": [
{
"endpoint": "/api/notifications/settings",
"method": "GET / POST",
"use": "Lesen oder schreiben Sie die vollständige Konfiguration (Kanäle, Per-Event-Toggles, AI-Rewriter, Display Name)."
},
{
"endpoint": "/api/notifications/test",
"method": "POST",
"use": "Sende eine Testbenachrichtigung an einen Kanal: <code>'{'\"channel\":\"telegram\"'}'</code>."
},
{
"endpoint": "/api/notifications/test-ai",
"method": "POST",
"use": "Rendern und schreiben Sie ein Beispielereignis um, ohne es zu versenden."
},
{
"endpoint": "/api/notifications/provider-models",
"method": "POST",
"use": "Listen Sie verfügbare Modelle für den ausgewählten AI-Anbieter auf."
},
{
"endpoint": "/api/notifications/send",
"method": "POST",
"use": "Emittieren Sie ein Ereignis von außen (benutzerdefinierte Integrationen)."
},
{
"endpoint": "/api/notifications/history",
"method": "GET / DELETE",
"use": "Lesen Sie Geschichte mit Filtern; löschen Sie es."
},
{
"endpoint": "/api/notifications/webhook",
"method": "POST",
"use": "Empfängt Proxmox-Meldungen. Lokale Quellen umgehen entfernte Authentifizierungsprüfungen, bleiben aber mengenbegrenzt. Entfernte Anfragen werden anhand <code>X-Webhook-Secret</code>, Zeitstempel in <code>X-ProxMenux-Timestamp</code> oder JSON, Wiederholungen und konfigurierter IP-Liste geprüft."
},
{
"endpoint": "/api/notifications/proxmox/setup-webhook",
"method": "POST",
"use": "Registrieren Sie den Monitor als Ziel in <code>/etc/pve/notifications.cfg</code>."
},
{
"endpoint": "/api/notifications/proxmox/cleanup-webhook",
"method": "POST",
"use": "Entfernen Sie das Monitor-Ziel aus der Benachrichtigungskonfiguration von PVE."
},
{
"endpoint": "/api/notifications/proxmox/read-cfg",
"method": "GET",
"use": "Zeigen Sie die aktuelle PVE-Benachrichtigungskonfiguration so an, wie PVE sie sieht."
}
]
},
"whereNext": {
"heading": "Wohin als nächstes",
"items": [
{
"label": "KI-Assistent",
"href": "/docs/monitor/ai-assistant",
"tail": " — Anbieter, Modelle, Anweisungsmodi, Sprachen und Kanal-Detailgrad."
},
{
"label": "Gesundheitsmonitor",
"href": "/docs/monitor/health-monitor",
"tail": " — wichtigste einzelne Ereignisquelle mit eigenen Wartezeiten je Kategorie."
},
{
"label": "Architektur",
"href": "/docs/monitor/architecture",
"tailRich": " — Rolle der SQLite-Tabellen <code>notification_last_sent</code>, <code>notification_history</code> und des Versandthreads im Monitor."
},
{
"label": "Zugriff und Authentifizierung",
"href": "/docs/monitor/access-auth",
"tailRich": " — API-Tokens für Skripte erstellen, die <code>/api/notifications/send</code> aufrufen."
},
{
"label": "Dashboard → Systemprotokolle",
"href": "/docs/monitor/dashboard/system-logs",
"tail": " — Live-Ansicht des Systemjournals, das die Journal-Überwachung auswertet."
}
]
}
}
+29 -29
View File
@@ -19,7 +19,7 @@
"reaching": {
"heading": "Reaching the dashboard",
"intro": "ProxMenux Monitor binds to <code>0.0.0.0:8008</code>. There are three common ways to reach it:",
"outro": "Direct access matches what the systemd unit ships out of the box. The reverse-proxy and Secure Gateway sections below cover the other two. The Monitor honours <code>X-Forwarded-For</code>, <code>X-Forwarded-Proto</code> and <code>X-Forwarded-Host</code> so URLs and CORS work behind any of them without manual configuration."
"outro": "Direct access matches the default systemd unit. Reverse-proxy and Secure Gateway access are described below. Trust for client IPs in <code>X-Forwarded-For</code> requires PROXMENUX_TRUST_PROXY=1 and a proxy you control. The presence of <code>X-Forwarded-Proto</code> or <code>X-Forwarded-Host</code> alone does not enable proxy trust. On ports 80/443 the frontend uses relative <code>/api/*</code> URLs; on any other port it calls port 8008 on the same host name."
},
"firstLaunch": {
"heading": "First-launch flow",
@@ -32,7 +32,7 @@
"rows": [
{
"button": "Yes, Setup Password",
"what": "Opens a form with the mandatory username + password and an optional <em>display name</em> + <em>avatar image</em>. Stores them in <code>auth.json</code> with <code>enabled: true</code>. Returns a JWT so you're logged in immediately. The form is documented in detail below.",
"what": "Opens a form requiring a username and password, with optional <em>display name</em> and <em>avatar image</em>. Enables authentication in <code>auth.json</code> with <code>enabled: true</code> and returns a JWT to log you in. Optional profile fields are saved by subsequent calls, as documented below.",
"api": "POST /api/auth/setup"
},
{
@@ -103,12 +103,12 @@
"what": "Removes the avatar. The header falls back to the initial-on-coloured-circle placeholder."
}
],
"reversibleTitle": "Continuing without protection is reversible — but only from the host",
"reversibleTitle": "Continuing without protection is reversible",
"reversibleBody": "Once you click <em>No, Continue Without Protection</em>, the welcome dialog never appears again. You can re-enable authentication from <strong>the Security tab</strong> inside the dashboard, or by editing <code>/root/.config/proxmenux-monitor/auth.json</code> and removing the <code>declined</code> flag, then restarting the service."
},
"password": {
"heading": "Password authentication",
"intro": "After Set up, every API call (except the few public endpoints listed below) requires a JWT in <code>Authorization: Bearer &lt;token&gt;</code>:",
"intro": "After setup, protected API calls require a JWT in <code>Authorization: Bearer &lt;token&gt;</code>:",
"items": [
"<strong>Session token (login):</strong> 24-hour expiration. Issued by <code>POST /api/auth/login</code>.",
"<strong>API token (integrations):</strong> 365-day expiration. Issued by <code>POST /api/auth/generate-api-token</code>. Documented separately in the next section."
@@ -118,10 +118,10 @@
"loginFlowTitle": "Login flow",
"twofaIntro": "With 2FA enabled, the same call returns <code>requires_totp: true</code> first. Re-issue with the 6-digit code:",
"publicTitle": "Public endpoints (no token)",
"publicIntro": "These are the only endpoints that work without authentication, even when auth is enabled:",
"publicIntro": "Login, authentication status, initial setup and the lightweight <code>/api/system-info</code> endpoint are public:",
"publicItems": [
"<code>/api/auth/login</code>, <code>/api/auth/status</code>, <code>/api/auth/setup</code> — the auth flow itself, by necessity.",
"<code>/api/system-info</code> — lightweight system snapshot (hostname, uptime, <code>health.status</code>). The right endpoint for external probes (Uptime Kuma, load-balancer health checks, status pages)."
"<code>/api/auth/login</code> and <code>/api/auth/status</code> are public. <code>/api/auth/setup</code> creates the initial account and rejects attempts to overwrite existing credentials.",
"<code>/api/system-info</code> is a public lightweight system-information endpoint, including <code>health.status</code>. It is not decorated with the token requirement. /api/auth/status is another public endpoint suitable for a reachability check."
],
"cryptoTitle": "Cryptography and storage",
"cryptoIntro": "ProxMenux Monitor is open source — none of this is secret. Documenting the stack here explicitly is a deliberate choice: operators who store credentials on their host deserve to know how those credentials are protected before they decide to trust them. The algorithms below are the same ones the code in <code>scripts/auth_manager.py</code> uses; this section is a contract, not a marketing promise.",
@@ -146,7 +146,7 @@
},
{
"asset": "2FA TOTP secret",
"algorithm": "Standard TOTP (RFC 6238) base32-encoded. Backup codes are pre-generated, single-use, hashed with the same PBKDF2 scheme as the password.",
"algorithm": "Standard TOTP (RFC 6238), with a base32-encoded secret. The eight backup codes are single-use and stored as SHA-256 hashes.",
"where": "<code>auth.json</code> → <code>totp_secret</code> + <code>backup_codes[]</code>"
},
{
@@ -170,7 +170,7 @@
"heading": "Two-Factor Authentication (TOTP)",
"intro": "2FA adds a second factor on top of your password: a 6-digit code that rotates every 30 seconds, generated on a phone or password manager you control. Even if someone obtains the password, they still can't log in without the code from your device. ProxMenux Monitor implements the standard <strong>TOTP</strong> protocol (RFC 6238), so any authenticator app works.",
"pickTitle": "Pick an authenticator app",
"pickIntro": "If you already use one for Google / GitHub / your bank, that one will work — skip to the setup walkthrough. If not, here's a survey of common options. All of them are free; the differences are mainly about which platforms they run on and how (or whether) they back up your secrets.",
"pickIntro": "If you already have a TOTP app, you can use it here. Common choices are listed below. Some are free and others require a subscription; supported platforms and backup methods also differ.",
"headerApp": "App",
"headerPlatforms": "Platforms",
"headerAppNotes": "Notes",
@@ -190,8 +190,8 @@
{
"name": "Authy",
"href": "https://authy.com/",
"platforms": "iOS, Android, desktop",
"notes": "Multi-device encrypted sync (the desktop app is being phased out — check the latest status)."
"platforms": "iOS, Android",
"notes": "Encrypted sync across devices. The desktop app reached end of life on 19 March 2024 and is no longer supported."
},
{
"name": "Apple Passwords",
@@ -203,7 +203,7 @@
"name": "Bitwarden",
"href": "https://bitwarden.com/",
"platforms": "iOS, Android, desktop, browser",
"notes": "Open source. TOTP lives next to the password it protects (handy if you also use BW for passwords; defeats \"separate device\" if you don't)."
"notes": "Open source. TOTP can be stored alongside passwords in the vault. Keeping both in the same vault is convenient, but does not provide separation onto a second device."
},
{
"name": "1Password",
@@ -238,22 +238,22 @@
{
"name": "FreeOTP+",
"href": "https://github.com/helloworld1/FreeOTPPlus",
"platforms": "Android, iOS",
"notes": "Open source (Red Hat-led). Minimal — no cloud, no account."
"platforms": "Android",
"notes": "Open-source fork of FreeOTP for Android, with import/export features. No account required."
}
],
"backupTitle": "What \"backup\" really matters for",
"backupBody": "If you lose the device that has the authenticator on it, the only ways back in are (1) a backup code saved when you enabled 2FA, or (2) a backup of the authenticator's vault. Apps with cloud sync (Google Auth, Microsoft Auth, Authy, Apple Passwords, Ente, 2FAS, Bitwarden, 1Password) can restore on a new device. Apps without cloud (Aegis, Raivo, FreeOTP+) need an encrypted export file you've copied somewhere safe. Either approach works — the bad case is \"no backup at all\".",
"backupBody": "If you lose the authenticator device, use a saved backup code or restore the app from a backup you configured beforehand. Cloud sync and local exports differ by app; check that your chosen method actually restores the TOTP secrets. Root access to the host also allows recovery, as explained below. Keep a separate, secure backup.",
"setupTitle": "Step-by-step setup from the dashboard",
"setupImageAlt": "2FA setup screen with QR code and backup codes",
"setupImageCaption": "The 2FA setup dialog — QR code, Base32 secret (for manual entry), and the ten one-time backup codes. The codes are only displayed here; if you close the dialog without copying them, they're gone.",
"setupImageCaption": "The 2FA setup dialog shows a QR code, a Base32 secret for manual entry and, after verification, eight one-time backup codes. Copy the codes before closing the dialog; they are not displayed again.",
"setupSteps": [
"<strong>Install the authenticator app on your phone</strong> (or open your password manager). One of the apps from the table above. You only need to do this once — the same app will hold codes for every service you protect.",
"<strong>Log into the dashboard</strong> with your username and password.",
"<strong>Open the Security tab</strong> in the dashboard sidebar, then click <strong>Enable 2FA</strong>. A dialog opens with a QR code, a long string in Base32 format and ten short codes labelled \"backup codes\".",
"<strong>Open the Security tab</strong> in the dashboard sidebar, then click <strong>Enable 2FA</strong> and <strong>Start setup</strong>. The dialog shows a QR code and the manual key; the eight backup codes appear after the code is verified.",
"<strong>Add the entry to the authenticator app:</strong>",
"<strong>Save the backup codes.</strong> Copy the ten codes somewhere safe — a password manager, an encrypted note, a printed copy in a drawer. Treat them like spare keys: each works exactly once and gets you in if your phone is gone or broken.",
"<strong>Confirm by typing the current 6-digit code</strong> from the app into the \"Verification code\" field of the setup dialog and submit. Codes refresh every 30 seconds, so if it expires while you're typing, just enter the next one.",
"<strong>Save the backup codes.</strong> After verification, store all eight safely in a password manager, encrypted note or secure printed copy. Each works once if your authenticator is unavailable.",
"<strong>Done.</strong> 2FA is now active. Next time you log in, the dashboard asks for the password first; once it's accepted it asks for the current 6-digit code."
],
"setupStep4Sub": [
@@ -261,17 +261,17 @@
"<em>Manual fallback</em> (when scanning isn't possible — e.g. setting up on the same phone you opened the dashboard with): tap <em>Add account</em> → <em>Enter setup key</em>. Type any name (e.g. <em>Proxmox Monitor</em>), paste the Base32 string from the dialog, leave <em>Type</em> as <em>Time-based</em>, save."
],
"testTitle": "Test before logging out",
"testBody": "Once you click Save, log out and log back in <em>immediately</em>, while the setup dialog is still fresh in your mind. If the code is rejected (clock-skew between server and phone is the most common cause), you can still fix it from the open session. Logging out without testing first means a one-trip-no-return — at that point only a backup code or editing <code>auth.json</code> on the host gets you back in.",
"testBody": "Keep your current session open and test a new login in a private window <em>immediately</em> after setup. If the code is rejected, check the server and phone clocks before logging out of the working session. If access is already lost, use a backup code or edit <code>auth.json</code> from the host shell.",
"lostTitle": "Lost authenticator",
"lostIntro": "Three escape hatches, in order of how disruptive they are:",
"lostItems": [
"<strong>Use a backup code.</strong> At the login screen, in the TOTP field, type one of the ten codes you saved at setup time. Each works once and is then consumed; the remaining codes still work. Once you're in, regenerate 2FA from Settings to get a fresh ten.",
"<strong>Use a backup code.</strong> Enter one of the eight saved codes in the TOTP field. It works once; unused codes remain valid. After logging in, open Security, choose <strong>Disable 2FA</strong> and then <strong>Enable 2FA</strong> to obtain eight new codes.",
"<strong>Restore the authenticator from cloud / backup.</strong> If your app has a cloud sync (Google, Microsoft, Authy, Apple Passwords via iCloud Keychain, Ente, 2FAS) install it on a new device, sign in, and the entries reappear. If your app uses an encrypted export file (Aegis, Raivo, FreeOTP+), install the app on the new device and import the file.",
"<strong>Disable 2FA from the host shell.</strong> When the previous options aren't available, edit <code>/root/.config/proxmenux-monitor/auth.json</code> on the Proxmox host (you need root SSH or console access), set <code>totp_enabled</code> to <code>false</code>, save, and restart the service:"
],
"lostShellOutro": "You can log in with username + password only, then re-enable 2FA from Settings.",
"disableTitle": "Disable 2FA",
"disableBody": "From the dashboard, open the <strong>Security</strong> tab and click <strong>Disable 2FA</strong>. The endpoint <code>POST /api/auth/totp/disable</code> requires the current password as confirmation, then deletes the TOTP secret and clears the backup codes. Remember to also remove the entry in the authenticator app — the app doesn't know the server side is gone, so the dead entry will sit there forever otherwise.",
"disableBody": "Open <strong>Security</strong> and choose <strong>Disable 2FA</strong>. <code>POST /api/auth/totp/disable</code> requires the current password and a valid TOTP or backup code. It removes the TOTP secret and backup codes. Remove the old entry from your authenticator app too.",
"rejectedTitle": "The 6-digit code is always rejected",
"rejectedIntro": "TOTP is time-based — server clock and phone clock must agree to within ~30 s. Two checks:",
"rejectedItems": [
@@ -310,31 +310,31 @@
"intro": "Two paths to TLS:",
"items": [
"<strong>Reverse proxy (recommended).</strong> Terminate TLS on Nginx / Caddy / Traefik and forward HTTP on port 8008 to the Flask process. Snippets below.",
"<strong>Direct HTTPS in the AppImage.</strong> Configure a certificate via <code>POST /api/ssl/configure</code> (UI: <strong>Settings → SSL</strong>). When SSL is configured the process switches from Flask's dev server to <code>gevent.pywsgi</code> with the gevent-websocket handler so WebSocket terminal also works over WSS. The cert files live wherever you point them; the paths are stored in the SSL config."
"<strong>Direct HTTPS in the AppImage.</strong> Configure a certificate with <code>POST /api/ssl/configure</code> (UI: <strong>Settings → SSL</strong>). The HTTPS path uses <code>gevent.pywsgi</code> with its standard handler; flask-sock handles WebSocket upgrades for WSS. Certificate paths are stored in the SSL configuration."
],
"calloutTitle": "Direct HTTPS limitations",
"calloutBody": "The bundled gevent path is suitable for self-signed or LAN-only certificates. For Let's Encrypt / ACME and automatic renewal, run a real reverse proxy in front — Caddy auto-renews and Traefik / Nginx have well-known patterns. The Monitor doesn't implement ACME on its own."
"calloutBody": "The Monitor can use a Proxmox-managed certificate or custom certificate files. It does not issue ACME certificates itself. For automatic issuance and renewal, use Proxmox ACME or a reverse proxy such as Caddy, Traefik or Nginx, and ensure renewed certificates are loaded."
},
"gateway": {
"heading": "Secure Gateway (Tailscale)",
"intro": "Reverse proxies are the classic answer to \"reach the dashboard from outside\" but they require a public domain, certificate, and an open port on the edge. <strong>Secure Gateway</strong> is the zero-port alternative shipped inside the Monitor itself — a pre-built deployable app that spins up an Alpine LXC running <a>Tailscale</a> as a subnet router. Once joined to your tailnet, every device on it can hit the Monitor at the host's own LAN IP — from a laptop on holiday, a phone on 5G, or another node — without exposing TCP 8008 to the internet.",
"intro": "A reverse proxy is one way to provide remote access. <strong>Secure Gateway</strong> offers access without exposing TCP 8008: it deploys an Alpine LXC running <a>Tailscale</a> as a subnet router. Access to the host’s LAN IP depends on approved subnet routes and tailnet access rules.",
"calloutTitle": "Why this is convenient",
"calloutBody": "The URL stays the same as on the LAN — <code>http://&lt;proxmox-lan-ip&gt;:8008</code> works everywhere Tailscale works. No certificates, no DNS, no port forwarding. The Monitor itself sees the request as coming from a tailnet IP (typically <code>100.x.y.z</code>), so the auth log and the Fail2Ban hook still function as on the LAN.",
"calloutBody": "Use the LAN URL <code>http://&lt;proxmox-lan-ip&gt;:8008</code> through the approved subnet route. Tailscale subnet routers use SNAT by default, so the Monitor normally sees the gateway’s LAN address, not the client’s <code>100.x.y.z</code> address. Logs and Fail2Ban therefore identify the source address the host actually receives.",
"deployBody": "The deploy flow is one screen — pick the host LXC storage, paste a Tailscale auth-key (generated at <a>login.tailscale.com/admin/settings/keys</a>), choose which subnets to advertise, click Deploy. The LXC takes ~30 seconds to bootstrap and registers in the tailnet automatically.",
"outro": "Step-by-step deployment, subnet-routes configuration, Tailscale ACLs and Exit Node mode are documented separately in <link>Dashboard → Security → Secure Gateway</link> — that's where the deploy wizard lives in the dashboard UI. This page only covers the access pattern."
},
"proxy": {
"heading": "Reverse proxy snippets",
"intro": "The simplest layout is a <strong>dedicated host name</strong> for the Monitor (e.g. <code>monitor.example.com</code>) pointing at port 8008 on the Proxmox host. Snippets below use that pattern. Sub-path mounts (<code>example.com/proxmenux-monitor/</code>) are possible but require extra rewriting and are not the default — see the callout at the end.",
"intro": "Use a <strong>dedicated host name</strong> such as <code>monitor.example.com</code> forwarding to port 8008 on the Proxmox host. The examples follow this pattern. A sub-path such as <code>example.com/proxmenux-monitor/</code> needs additional frontend and proxy work; it is not supported by prefix stripping alone.",
"nginxTitle": "Nginx",
"caddyTitle": "Caddy",
"traefikTitle": "Traefik (labels — Docker / Kubernetes)",
"subPathTitle": "Advanced: sub-path mounts under an existing domain",
"subPathBody": "If you don't want a dedicated host name, you can mount the Monitor under a path on an existing domain — for example <code>example.com/proxmenux-monitor/</code>. The Next.js build uses relative asset paths so static files resolve, but the proxy must <strong>strip the prefix</strong> before forwarding so the Monitor still receives plain <code>/api/*</code> URLs. On Nginx that's a <code>location /proxmenux-monitor/ &rbrace; proxy_pass http://127.0.0.1:8008/; &lbrace;</code> (the trailing slash on <code>proxy_pass</code> does the strip). On Caddy, use <code>handle_path /proxmenux-monitor/*</code>. A dedicated host name is simpler."
"subPathBody": "The current frontend has no configured sub-path base and builds API calls from root-relative <code>/api/*</code> URLs. Merely stripping a prefix such as <code>example.com/proxmenux-monitor/</code> does not handle those API calls or all frontend assets. Use a dedicated host name. A sub-path deployment requires coordinated frontend and proxy changes and separate testing."
},
"audit": {
"heading": "Audit log",
"intro": "Every authentication event (success and failure) is appended to <code>/var/log/proxmenux-auth.log</code> in a single line, syslog-style format:",
"intro": "Login failures and rate-limit warnings are written to <code>/var/log/proxmenux-auth.log</code> in a single-line format. Successful logins are not recorded by this logger:",
"outro": "Tail it the usual way: <code>tail -F /var/log/proxmenux-auth.log</code>. The file is rotated by <code>logrotate</code> if a config drop-in is added; the Monitor itself does not rotate it."
},
"fail2ban": {
@@ -346,7 +346,7 @@
"Reads <code>/var/log/proxmenux-auth.log</code>.",
"Matches the <code>authentication failure; rhost=&lt;ip&gt;</code> pattern with a dedicated filter.",
"Bans the offending IP at the kernel firewall level by default.",
"Is queried by the Flask <code>before_request</code> hook every 30 s — so even when the firewall can't block (because the connection comes from the reverse proxy), the application returns HTTP 403 to banned IPs based on what Fail2Ban knows."
"The Flask <code>before_request</code> hook checks requests against the ban list, cached for 30 s. Behind a reverse proxy, client-IP blocking also requires PROXMENUX_TRUST_PROXY=1 and a controlled proxy that sets trustworthy forwarding headers."
],
"outro": "Configuration, ban time tuning and unban procedures are in <link>Security → Fail2Ban</link>."
},
+30 -30
View File
@@ -1,7 +1,7 @@
{
"meta": {
"title": "Proxmox AI Assistant — OpenAI, Claude, Gemini, Groq, Ollama | ProxMenux Monitor",
"description": "ProxMenux Monitor's optional AI Assistant rewrites Proxmox VE notification bodies in plain language. Six providers supported: OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter and local Ollama. Twelve languages, three detail levels per channel, custom prompt mode with a community library, and a context-enrichment layer that adds uptime, recurrence and SMART data to disk events.",
"description": "The optional AI Assistant rewrites Proxmox VE notifications in plain language. Six providers: OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter and Ollama. The UI offers thirteen languages, three detail levels per channel, custom prompts with a community library, and event context including uptime, recurrence and SMART data.",
"ogTitle": "Proxmox AI Assistant — OpenAI, Claude, Gemini, Groq, Ollama",
"ogDescription": "Rewrite Proxmox VE notifications in plain language with OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter or local Ollama.",
"twitterTitle": "Proxmox AI Assistant | ProxMenux Monitor",
@@ -9,12 +9,12 @@
},
"header": {
"title": "AI Assistant",
"description": "The opt-in rewriter that runs every outbound notification through an LLM before fan-out — turning structured templates into plain-language messages, with per-channel detail levels, twelve languages, a custom prompt mode with a public community library, and a context-enrichment layer that adds uptime, recurrence, SMART data and known-error matches to the prompt.",
"description": "Optional AI rewriting turns eligible notification templates into plain-language messages, with per-channel detail levels, thirteen UI languages, custom prompts, a public community library and context enrichment. Backup reports <code>backup_complete</code> and <code>backup_fail</code> bypass AI entirely.",
"section": "ProxMenux Monitor"
},
"intro": {
"title": "Off by default, single switch to enable",
"body": "AI rewrite is opt-in. Until you flip the master toggle inside <em>Settings → Notifications → Advanced: AI Enhancement</em>, every event is dispatched with the original templated body. When the toggle is on and a provider call fails or times out, the dispatcher falls back to the templated body silently — your notifications never block on the LLM."
"body": "AI rewriting is off by default. Enable it in <em>Settings → Notifications → Advanced: AI Enhancement</em>. If enrichment or rewriting fails, the dispatcher sends the original template. Rewrites in the event dispatch queue have a 25-second timeout; reaching it sends the template instead of waiting."
},
"howItWorks": {
"heading": "How it works",
@@ -83,7 +83,7 @@
"intro1": "Every commercial provider charges per <em>token</em>, so it's worth understanding what a token is before picking a plan. A token is roughly four characters of English text or about three quarters of a word. The phrase <em>\"Backup completed on storage local-bak\"</em> is around eight tokens. A short journal excerpt of ten lines can be 200-400 tokens depending on the technical density.",
"intro2": "Two things are billed on every call:",
"items": [
"<strong>Input tokens</strong> — the system prompt plus the user message (severity, title, body, enriched context). For ProxMenux the system prompt alone is on the order of 1.5-2 KB (≈ 400-500 tokens) and the user message varies from 50 tokens (a clean backup-complete) to ~1500 tokens (a disk error with 30 lines of journal context).",
"<strong>Input tokens</strong> cover the system prompt and user message: severity, title, rendered body and enriched context. Their number depends on the actual prompt and event content. Each rewritten channel can incur its own input-token usage; backup-complete and backup-fail reports bypass AI.",
"<strong>Output tokens</strong> — what the model writes back. The Monitor caps this with <code>max_tokens</code> (see the table below). The cap is a <em>limit</em>, not a charge: if the model produces 250 tokens with a cap of 1500, you pay for 250."
],
"capsIntro": "These are the actual caps the dispatcher applies, taken straight from <code>AI_DETAIL_TOKENS</code> in <code>notification_templates.py</code>:",
@@ -109,7 +109,7 @@
],
"customNote": "Custom prompt mode uses a fixed cap of 500 output tokens regardless of detail level — the custom prompt is in your control and the cap protects against runaway responses.",
"sizingTitle": "Practical sizing",
"sizingBody": "A homelab with 50-100 events per day on <code>standard</code> typically consumes a few thousand tokens per day. With the free tiers offered by Groq and Gemini, that fits without touching a paid plan. With OpenAI or Anthropic, billed per-token, the cost lands in the cents-per-month range for that volume. If your event count is much higher, the <link>Detail level per channel</link> section explains how to keep chat channels on <code>brief</code> while letting Email take the full report."
"sizingBody": "Estimate usage as rewritten events × AI-enabled channels × input-plus-output tokens per call. For example, 50 events × one channel × (2,000 input + 300 output tokens) is about 115,000 tokens per day, since the default system prompt alone is roughly 1,500 tokens. Actual usage and charges depend on model, context, caching and provider limits. The <link>Detail level per channel</link> section shows how to use <code>brief</code> for chat instead of <code>standard</code>, while keeping detailed email reports."
},
"providers": {
"heading": "AI providers",
@@ -121,8 +121,8 @@
"tagline": "Very fast, generous free tier (30 req/min). Ideal to start.",
"items": [
"API key: <a>console.groq.com/keys</a>",
"Verified models: <code>llama-3.3-70b-versatile</code>, <code>llama-3.1-70b-versatile</code>, <code>llama-3.1-8b-instant</code>, <code>llama3-70b-8192</code>, <code>llama3-8b-8192</code>, <code>mixtral-8x7b-32768</code>, <code>gemma2-9b-it</code>.",
"Recommended: <strong><code>llama-3.3-70b-versatile</code></strong> — best quality at full Groq inference speed."
"Examples from the bundled model list: <code>allam-2-7b</code>, <code>qwen/qwen3.8-27b</code>, <code>openai/gpt-oss-20b</code>, <code>groq/compound-mini</code>.",
"Bundled recommendation: <strong><code>openai/gpt-oss-20b</code></strong>. Use the provider selector and connection test to check availability for your account."
]
},
"openai": {
@@ -130,8 +130,8 @@
"tagline": "Industry standard. Very accurate and widely used.",
"items": [
"API key: <a>platform.openai.com/api-keys</a>",
"Verified models: <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-chat-latest</code>, <code>gpt-5.4-nano</code>, <code>gpt-5.4-mini</code>.",
"Recommended: <strong><code>gpt-4.1-nano</code></strong> — the cheapest member of the chat family, sufficient quality for translation and re-formatting. Reasoning models (o-series, gpt-5 non-chat) are supported by the provider plumbing but kept off the verified list: higher latency without measurable quality gain on this workload."
"Examples from the bundled model list: <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>.",
"Bundled recommendation: <strong><code>gpt-4.1-nano</code></strong>. The adapter also handles model-specific requirements for reasoning models; the bundled list includes gpt-5-nano, so reasoning models are not universally excluded."
],
"baseUrlTitle": "OpenAI-compatible base URL",
"baseUrlBody": "The OpenAI provider also accepts a custom <em>Base URL</em>, which lets you point the Monitor at any OpenAI-compatible endpoint. Confirmed to work with <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>, and any other service that speaks the OpenAI <code>/v1/chat/completions</code> dialect. Set the URL in the OpenAI tab next to the API key field."
@@ -141,8 +141,8 @@
"tagline": "Excellent for writing and translation. Fast and economical.",
"items": [
"API key: <a>console.anthropic.com/settings/keys</a>",
"Verified models: <code>claude-3-5-haiku-latest</code>, <code>claude-3-5-sonnet-latest</code>, <code>claude-3-opus-latest</code>.",
"Recommended: <strong><code>claude-3-5-haiku-latest</code></strong> — Claude's smallest, fastest model with strong language quality for the translation workload."
"Examples from the bundled model list: <code>claude-haiku-4-5-20251001</code>, <code>claude-sonnet-4-6</code>, <code>claude-opus-4-6</code>.",
"Bundled recommendation: <strong><code>claude-haiku-4-5-20251001</code></strong>, a pinned snapshot rather than a moving alias."
]
},
"gemini": {
@@ -150,7 +150,7 @@
"tagline": "Free tier available, great quality/price ratio.",
"items": [
"API key: <a>aistudio.google.com/app/apikey</a>",
"Verified models: <code>gemini-2.5-flash-lite</code>, <code>gemini-2.5-flash</code>, <code>gemini-3-flash-preview</code>.",
"Examples from the bundled model list: <code>gemini-2.5-flash-lite</code>, <code>gemini-2.5-flash</code>, <code>gemini-3-flash-preview</code>.",
"Recommended: <strong><code>gemini-2.5-flash-lite</code></strong> — flash and flash-lite pass the verifier consistently. The pro variants reject the <code>thinkingBudget=0</code> setting the Monitor uses and are overkill for this workload."
]
},
@@ -159,13 +159,13 @@
"tagline": "Aggregator with access to 100+ models using a single API key. Maximum flexibility.",
"items": [
"API key: <a>openrouter.ai/keys</a>",
"Verified models: <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-3.5-haiku</code>, <code>anthropic/claude-3.5-sonnet</code>, <code>google/gemini-flash-1.5</code>, <code>openai/gpt-4o-mini</code>, <code>mistralai/mistral-7b-instruct</code>, <code>mistralai/mixtral-8x7b-instruct</code>.",
"Examples from the bundled model list: <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>.",
"Recommended: <strong><code>meta-llama/llama-3.3-70b-instruct</code></strong> — same model as the Groq entry but routed through OpenRouter, which means a single key for all the listed models."
]
},
"ollama": {
"heading": "Ollama (Local)",
"tagline": "Uses models available on your Ollama server. 100% local, no costs, total privacy.",
"tagline": "Uses models exposed by your configured Ollama server. Local models execute there; Ollama cloud models forward requests to a cloud provider. Local execution avoids a hosted API charge but still uses your hardware and electricity.",
"items": [
"No API key. Set the <em>Ollama URL</em> field to your server (default <code>http://localhost:11434</code> or whatever host runs your Ollama instance).",
"Models: <strong>not filtered.</strong> The Monitor reads whichever models you have pulled on the Ollama side via <code>ollama pull &lt;model&gt;</code>. The dropdown is populated from <code>GET /api/tags</code> on your Ollama server.",
@@ -175,14 +175,14 @@
},
"models": {
"heading": "Why these specific models",
"intro": "The model dropdown for each commercial provider is populated from a curated list shipped with the Monitor (<code>verified_ai_models.json</code>). Models on this list have been tested end-to-end with the chat / completions API format the Monitor uses, with the exact <code>system_prompt + user_message + max_tokens</code> shape the AI Enhancer sends. The list is refreshed before each ProxMenux release with a private verifier tool that probes every candidate model and prunes the ones that misbehave.",
"intro": "Commercial-provider model choices come from the bundled compatibility catalogue <code>verified_ai_models.json</code>, combined with the provider adapter’s availability checks. Adapters map the internal <code>system_prompt + user_message + max_tokens</code> request to each provider’s API. The catalogue contains tested entries and manual additions; it is a snapshot, not a guarantee of current account access or a promise that every entry passed the same verifier.",
"consequencesIntro": "Two consequences worth being aware of:",
"consequences": [
"<strong>The recommended model</strong> for each provider is the one that has the best balance of quality, latency and cost for notification translation specifically — not the most capable model the provider sells. Notification rewrites don't need frontier-model reasoning; they need fast and cheap.",
"<strong>You can still pick another verified model</strong> from the dropdown — sometimes you have a free-tier quota you want to spend on a particular model, or you have a strong preference. Pick any of the listed entries; they've all passed the verifier."
"<strong>The bundled recommendation</strong> is a starting point selected for notification formatting. Assess language quality, latency and cost for your own event content and provider account rather than treating it as a universal model ranking.",
"<strong>You can choose another listed model</strong> from the dropdown to suit your quota or preferences. Check its availability with the connection test; being listed does not guarantee current access for your account."
],
"ollamaTitle": "Ollama is the exception",
"ollamaBody": "Ollama models are local and the Monitor doesn't filter them — the dropdown reflects whatever you have pulled. Pick a model in the 7B-13B range with at least an 8K context window for the AI rewrite to behave reasonably with the journal context blocks."
"ollamaBody": "The Ollama dropdown is not filtered by the commercial-provider catalogue; it reflects models exposed by your Ollama server. For local execution choose a local model that fits your RAM and has enough context for the journal blocks. Cloud-tagged models are remote even when accessed through a local Ollama server."
},
"defaultPrompt": {
"heading": "Default prompt",
@@ -205,8 +205,8 @@
"changes": [
"<strong>The default prompt is replaced entirely.</strong> The Proxmox mappings, the context-handling rules and the emoji instructions are all gone. If you want to keep any of them, paste them into your prompt — the bundled <code>EXAMPLE_CUSTOM_PROMPT</code> shown below is a starting point.",
"<strong>The Language selector is ignored.</strong> The default prompt has a <code>'{'language'}'</code> placeholder; the custom prompt does not. If you want output in a specific language, declare it inside your prompt (\"Translate to Spanish\", \"Output everything in French\").",
"<strong>Detail level still applies</strong> in the sense that it's available as a setting per channel, but the cap on output tokens becomes a fixed 500 in custom mode (vs the 500 / 1500 / 3000 ramp of the default prompt). If your custom prompt asks for a long report, raise the cap by editing the prompt or split the request.",
"<strong>The Output Format markers are still mandatory.</strong> The Monitor parses the response by looking for <code>[TITLE]</code> and <code>[BODY]</code> on their own lines. A custom prompt that doesn't emit those markers will break the parser and fall back to the original templated body.",
"<strong>The custom-mode output cap is fixed at 500 tokens</strong>, independent of the stored per-channel detail setting. Default mode uses the 500 / 1500 / 3000 limits. Editing the custom prompt cannot raise the cap; request a shorter answer or use an appropriate Default detail level.",
"<strong>The output markers remain mandatory.</strong> Include <code>[TITLE]</code> and <code>[BODY]</code> in the response format. The parser extracts their content; if either marker is missing, it returns the original template instead.",
"<strong>Rich messages emoji rules are not auto-injected.</strong> If you want emojis, tell the prompt to use them. If you want plain text, tell it not to. The toggle only gates the bundled blocks of the default prompt, not your custom string."
],
"starterTitle": "Starter prompt",
@@ -224,10 +224,10 @@
"rulesIntro": "The rules baked into the addon (visible in the collapsible block under the Default prompt section above):",
"rules": [
"The tip is included <em>only</em> if the journal context or the Known Errors database clearly points to a specific fix.",
"The tip is capped at 100 characters.",
"It must be specific (concrete command or path) — generic advice is rejected by the prompt itself.",
"The prompt requests a tip under 100 characters; the parser does not independently enforce that length.",
"The prompt requires a specific command or path and instructs the model to avoid generic advice.",
"If a Known Error provides a solution, the LLM must use that solution, not invent a new one.",
"If nothing in the input gives the LLM enough certainty to suggest a concrete fix, the tip is skipped — no guessing."
"The prompt instructs the model to omit the tip if the input does not support a concrete fix."
],
"betaTitle": "Why BETA",
"betaBody": "Tip quality depends on two things outside of ProxMenux: the model picked, and how rich the journal context for the event was. With a strong model (Claude 3.5 Haiku, GPT-4.1 Mini, Llama 3.3 70B) and a disk error that comes with smartctl + journal lines, the tip is consistently useful. With a tiny local Ollama model and a one-line event, the tip can fall flat or get skipped entirely. Disable the toggle if you find the tips noisy and re-enable it when you want it back."
@@ -265,12 +265,12 @@
"<strong>Email</strong> — <code>detailed</code>. Email is the channel where you typically want the full picture for archival."
],
"emailTitle": "Email detail level appends the original",
"emailBody": "When Email is on <code>detailed</code> and the original templated body has substantial content (more than 50 characters), the dispatcher appends the original message at the bottom of the AI rewrite, separated by a 40-dash divider and an <code>Original message:</code> label. This means a detailed email always carries both the AI-friendly version and the machine-friendly raw template — useful when you want to grep an old alert later."
"emailBody": "When the AI formatter returns a result for Email on <code>detailed</code> and the original body is longer than 50 characters, the formatter appends that original text after a 40-dash divider and the label <code>Original message:</code>. This retains the source details for later searches. AI bypasses and failures can instead deliver the original template alone."
},
"language": {
"heading": "Language",
"intro": "Twelve languages are wired in. The dropdown sets <code>ai_language</code> in the config and the value is interpolated into the system prompt at the place where the prompt says <em>\"translate alerts into '{'language'}'\"</em>. The full list:",
"list": "English (<code>en</code>), Spanish (<code>es</code>), French (<code>fr</code>), German (<code>de</code>), Portuguese (<code>pt</code>), Italian (<code>it</code>), Russian (<code>ru</code>), Swedish (<code>sv</code>), Norwegian (<code>no</code>), Japanese (<code>ja</code>), Chinese (<code>zh</code>), Dutch (<code>nl</code>).",
"intro": "The UI selector offers thirteen languages. It stores <code>ai_language</code>, which the default system prompt uses in <em>\"translate alerts into '{'language'}'\"</em>. The UI list is:",
"list": "English (<code>en</code>), Slovak (<code>sk</code>), Spanish (<code>es</code>), French (<code>fr</code>), German (<code>de</code>), Portuguese (<code>pt</code>), Italian (<code>it</code>), Russian (<code>ru</code>), Swedish (<code>sv</code>), Norwegian (<code>no</code>), Japanese (<code>ja</code>), Chinese (<code>zh</code>), Dutch (<code>nl</code>).",
"rulesIntro": "Two important rules taken straight from the prompt:",
"rules": [
"<strong>Translate</strong>: labels, descriptions, status words, units (e.g. GB → Go in French).",
@@ -280,7 +280,7 @@
},
"templates": {
"heading": "A note on templates",
"body1": "The body the AI receives is not raw event data — it's a pre-rendered template. Each event type (<code>backup_complete</code>, <code>vm_start</code>, <code>auth_fail</code>, <code>health_degraded</code>, etc.) has a template in <code>notification_templates.py</code> that knows how to format that specific event into a structured plain-text body. The AI rewrites that body, it doesn't replace the templating step.",
"body1": "The AI receives a rendered template rather than raw event data. Types such as <code>vm_start</code>, <code>auth_fail</code> and <code>health_degraded</code> have templates in <code>notification_templates.py</code>. The AI rewrites eligible template output; <code>backup_complete</code> and <code>backup_fail</code> retain their deterministic reports and bypass AI.",
"body2": "Two practical implications: the AI never sees a hostname or VMID it has to invent — those fields are placed by the template before the rewrite. And if AI is disabled, the templated body is what gets dispatched directly. The <link>Notifications</link> page documents the dispatch pipeline in full and is the right cross-reference for everything that happens to an event before it reaches this layer."
},
"privacy": {
@@ -291,11 +291,11 @@
"rows": [
{
"provider": "Ollama",
"destination": "Stays on the Ollama host. If Ollama runs on the same Proxmox node, nothing leaves the network at all."
"destination": "Local models run on the configured Ollama host. Their requests stay on that host when it is the Proxmox node itself. Ollama cloud models forward requests outside the host, even through a local Ollama server."
},
{
"provider": "OpenAI",
"destination": "<code>api.openai.com</code> (or your custom Base URL endpoint). Subject to OpenAI's data-handling policy at the time of the call."
"destination": "<code>api.openai.com</code> by default, or the configured custom Base URL. The data-handling policy of the actual endpoint operator applies."
},
{
"provider": "Anthropic",
@@ -315,7 +315,7 @@
}
],
"calloutTitle": "If event content cannot leave the network",
"calloutBody": "Use Ollama, or disable the AI rewriter. There is no middle ground — the dispatcher does not try to redact hostnames or IPs before sending; the prompt is built from the actual event payload as the Monitor sees it."
"calloutBody": "Use a locally hosted endpoint with a local model, such as local Ollama or an OpenAI-compatible server, or disable AI rewriting. Ollama cloud models do not keep processing local. The dispatcher does not redact hostnames or IPs; it builds the prompt from the actual event content."
},
"whereNext": {
"heading": "Where to next",
+35 -35
View File
@@ -1,7 +1,7 @@
{
"meta": {
"title": "Proxmox Monitor API — Integration Reference | ProxMenux",
"description": "HTTP endpoints exposed by ProxMenux Monitor for integrations: Home Assistant, Homepage, Grafana, Prometheus, n8n and custom dashboards. Read-only data export plus the safe write operations needed by automations — VM control, backup trigger, notification dispatch, alert acknowledgement.",
"description": "HTTP endpoints exposed by ProxMenux Monitor for Home Assistant, Homepage, Grafana, Prometheus, n8n and custom dashboards. Read state and invoke documented write operations such as VM control, backup submission, notification dispatch and alert acknowledgement.",
"ogTitle": "Proxmox Monitor API — Integration Reference",
"ogDescription": "Endpoints exposed by ProxMenux Monitor for Home Assistant, Homepage, Grafana, Prometheus, n8n and custom dashboards.",
"twitterTitle": "Proxmox Monitor API | ProxMenux",
@@ -9,7 +9,7 @@
},
"header": {
"title": "API Reference",
"description": "The HTTP endpoints integrators use to read state and trigger safe actions on ProxMenux Monitor — Home Assistant sensors, Homepage cards, Grafana dashboards, Prometheus scrapes, n8n flows and custom scripts. Every category, plus a complete list of Prometheus metrics, with curl examples.",
"description": "HTTP endpoints for reading state and invoking documented actions on ProxMenux Monitor: Home Assistant sensors, Homepage cards, Grafana dashboards, Prometheus collection, n8n flows and custom scripts. Includes endpoint categories, exported metrics and curl examples.",
"section": "ProxMenux Monitor"
},
"intro": {
@@ -21,18 +21,18 @@
"headerUse": "Use",
"auth": {
"heading": "Authentication",
"intro": "Every endpoint marked \"authenticated\" expects a JWT bearer token in the request header:",
"intro": "When authentication is enabled, protected endpoints expect a JWT bearer token in the request header:",
"tokensIntro": "Two ways to obtain the token:",
"items": [
"<strong>API tokens (recommended for integrations).</strong> Long-lived tokens minted from <strong>Settings → Security → API Tokens</strong> in the dashboard. Each token is named, can be revoked individually, and is what you should hand to Home Assistant / Homepage / Grafana / n8n.",
"<strong>Login flow (short-lived JWT).</strong> <code>POST /api/auth/login</code> with a username, password and TOTP token if 2FA is enabled. The returned JWT is short-lived and refreshed by the dashboard automatically; useful for ad-hoc scripts that authenticate as a human user."
"<strong>API tokens (recommended for integrations).</strong> Tokens valid for 365 days, created under <strong>Security → API Tokens</strong>. Each has a name and can be revoked individually. Use read_only for data collection and select full_admin only for integrations that need administrative actions.",
"<strong>Login flow (24-hour JWT).</strong> <code>POST /api/auth/login</code> with a username, password and TOTP token when required by 2FA. The returned session JWT expires after 24 hours; scripts must authenticate again when it expires."
],
"flowLink": "The auth flow, password policy, 2FA setup, audit log and TLS configuration all live in <link>Access & Authentication</link>.",
"rows": [
{
"endpoint": "/api/auth/login",
"method": "POST",
"use": "Body: <code>'{'\"username\",\"password\",\"totp_token?\"'}'</code>. Returns a short-lived JWT."
"use": "Body fields (schematic): <code>'{'\"username\",\"password\",\"totp_token?\"'}'</code>. Returns a 24-hour session JWT."
},
{
"endpoint": "/api/auth/api-tokens",
@@ -40,9 +40,9 @@
"use": "List API tokens (metadata only — names, prefixes, dates; never the actual secret)."
},
{
"endpoint": "/api/auth/api-tokens",
"endpoint": "/api/auth/generate-api-token",
"method": "POST",
"use": "Mint a new long-lived API token. Body: <code>'{'\"name\":\"'<'label'>'\"'}'</code>. The token value is returned once and cannot be retrieved again."
"use": "Create a 365-day API token using an authenticated session. Body fields: <code>password, token_name?, totp_token?, scope?</code>. Password and any required TOTP are checked again. Scope defaults to read_only; full_admin must be selected explicitly. The secret is returned only once."
},
{
"endpoint": "/api/auth/api-tokens/<id>",
@@ -54,10 +54,10 @@
"conventions": {
"heading": "Conventions",
"items": [
"All requests and responses are JSON unless explicitly noted (log download is plain text, <code>/api/prometheus</code> is text/plain in the OpenMetrics format, task log is plain text).",
"Successful mutating endpoints return <code>'{'\"success\": true, ...'}'</code>. Error responses use a non-2xx HTTP status with <code>'{'\"success\": false, \"error\": \"'<'reason'>'\"'}'</code>.",
"List endpoints accept optional <code>limit</code>, <code>offset</code>, <code>since</code> and category-specific filters via query string.",
"Time fields are returned as Unix epoch seconds or ISO-8601 with explicit timezone, never as locale strings."
"Most endpoints use JSON. Downloads can return plain text, and <code>/api/prometheus</code> returns Prometheus text exposition format version 0.0.4 rather than OpenMetrics. Check the response type of the specific route.",
"Many write endpoints return <code>'{'\"success\": true, ...'}'</code>. Error formats vary; a common form is <code>'{'\"success\": false, \"error\": \"'<'reason'>'\"'}'</code>. Check both HTTP status and response fields: some authentication challenges return HTTP 200 with success false.",
"Query parameters vary by endpoint. Use <code>limit</code>, <code>offset</code>, <code>since</code> and category-specific filters only where the route supports them.",
"Time formats vary by endpoint: Unix timestamps, ISO-8601 strings and systemd-formatted dates all occur. Do not assume every time field has the same unit or an explicit timezone."
]
},
"system": {
@@ -102,12 +102,12 @@
},
"actions": {
"heading": "System actions",
"intro": "Fire-and-forget endpoints that trigger the same operations the operator would run from the Monitor UI or the shell menu — designed for Home Assistant, Homepage, Ansible, custom dashboards and any other automation that needs to reach into the host over HTTP. Every mutating route requires a token with <code>full_admin</code> scope; read-only <code>read_only</code> tokens can still poll the <code>.../status</code> endpoints without triggering anything. Each action returns 202 with a state snapshot; poll the matching <code>.../status</code> to observe progress.",
"intro": "The asynchronous system actions below start operations in transient systemd units. With authentication enabled, their write routes require <code>full_admin</code>; <code>read_only</code> tokens can poll <code>.../status</code>. Accepted starts return HTTP 202 with a state snapshot; poll the matching <code>.../status</code> for progress. Guest control and backup use different response contracts, described below.",
"shapeTitle": "Common response shape",
"shapeIntro": "All action endpoints return the same JSON object — one shape to parse from any client:",
"shapeIntro": "Asynchronous system actions share the JSON state object below. Guest-control and backup responses have different shapes:",
"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": "Concurrency and cancellation",
"concurrencyBody": "A second POST while a run is in flight returns 409 with the current running state. Cancel an in-flight run with a DELETE to the action's base URL; the state moves to <code>cancelled</code> and timestamps are preserved so the caller can still see when it was triggered and stopped. The last terminal state (success / failed / cancelled) is remembered until the next run replaces it.",
"concurrencyBody": "Starting a second run of the same system action returns HTTP 409 while it is active. Cancellation is available only for actions with a documented DELETE route, such as PVE update. Their state becomes <code>cancelled</code> and preserves timestamps. Terminal snapshots are kept in process memory and can be lost when the Monitor restarts.",
"rows": [
{
"endpoint": "/api/system/power/reboot",
@@ -147,7 +147,7 @@
{
"endpoint": "/api/proxmenux/self-update/run",
"method": "POST",
"use": "Update ProxMenux itself by piping the canonical stable installer. Runs in its own systemd unit so the update completes across the proxmenux-monitor restart the installer performs."
"use": "Update ProxMenux using the installer for the configured stable or beta channel. It runs in its own systemd unit so the job can survive the proxmenux-monitor service restart performed by the installer."
},
{
"endpoint": "/api/proxmenux/self-update/status",
@@ -157,12 +157,12 @@
{
"endpoint": "/api/vms/<vmid>/control",
"method": "POST",
"use": "Start / stop / shutdown / reboot a VM or LXC container (the same operations the Monitor's VM & LXC modal exposes). The body carries <code>action</code>: <code>start</code>, <code>stop</code>, <code>shutdown</code> or <code>reboot</code>. Synchronous — returns the outcome directly with no polling needed."
"use": "Submit VM or LXC power control. Body field <code>action</code> accepts <code>start</code>, <code>stop</code>, <code>shutdown</code> or <code>reboot</code>. A successful response returns a confirmed PVE task; it does not mean the operation has completed. Poll the guest control-task endpoint for its outcome."
},
{
"endpoint": "/api/vms/<vmid>/backup",
"method": "POST",
"use": "Create a vzdump backup of a VM or LXC. Body fields, all optional unless the defaults do not match the storage layout: <code>storage</code> (a PVE storage), <code>mode</code> (<code>snapshot</code>, <code>suspend</code> or <code>stop</code>), <code>compress</code> (<code>zstd</code>, <code>lzo</code>, <code>gz</code> or <code>none</code>), <code>protected</code> (<code>true</code> or <code>false</code>), <code>notes</code>, <code>notification</code> (<code>auto</code>, <code>always</code>, <code>failure</code> or <code>never</code>) and <code>pbs_change_detection</code> (<code>default</code>, <code>legacy</code> or <code>data</code>). Returns the PVE task UPID."
"use": "Create a vzdump backup of a VM or LXC. Body fields, all optional unless the defaults do not match the storage layout: <code>storage</code> (a PVE storage), <code>mode</code> (<code>snapshot</code>, <code>suspend</code> or <code>stop</code>), <code>compress</code> (<code>zstd</code>, <code>lzo</code>, <code>gzip</code> or <code>none</code>), <code>protected</code> (<code>true</code> or <code>false</code>), <code>notes</code> and <code>pbs_change_detection</code> (<code>default</code>, <code>legacy</code> or <code>data</code>). Returns the PVE task UPID."
},
{
"endpoint": "/api/vms/<vmid>/backups",
@@ -171,7 +171,7 @@
}
],
"syncVsAsyncTitle": "Two flavours of action",
"syncVsAsyncBody": "System-level actions (host power, PVE update, ProxMenux self-update) can take minutes — they run in their own transient systemd unit and expose a <code>.../status</code> endpoint plus a <code>DELETE</code> to cancel. VM / LXC actions (start, stop, shutdown, reboot, backup) are fast and use the fire-and-return style the Monitor's UI already exposes: the POST returns the outcome directly. Both flavours share the same authentication model (JWT or long-lived API token).",
"syncVsAsyncBody": "Host power, PVE update and ProxMenux self-update run in transient systemd units with a <code>.../status</code> endpoint. Only PVE update has the <code>DELETE</code> cancellation route listed here. VM/LXC control returns a PVE task that must be polled; backup returns a UPID for a background job. An accepted request is not completion. Authentication and scope requirements depend on the route.",
"curlTitle": "curl example",
"curlBody": "Fire a PVE update and poll for completion — the exact same sequence a Home Assistant automation or an Ansible playbook would run:",
"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\"",
@@ -185,7 +185,7 @@
{
"endpoint": "/api/health",
"method": "GET",
"use": "Small health probe — returns JSON with <code>status</code>, <code>timestamp</code>, <code>version</code>. Suitable for Uptime Kuma keyword checks; the receiver must send the bearer header."
"use": "Small health probe returning JSON with <code>status</code>, <code>timestamp</code> and <code>version</code>. Suitable for Uptime Kuma keyword checks; when authentication is enabled, the client must send the bearer header."
},
{
"endpoint": "/api/health/status",
@@ -200,7 +200,7 @@
{
"endpoint": "/api/health/full",
"method": "GET",
"use": "Full snapshot — categories + active errors + dismissed list + custom suppression settings. Backs the modal in one round-trip; uses a 6-min background cache for instant response."
"use": "Full snapshot: categories, active errors, dismissed alerts and custom suppression settings. It uses background check results when less than six minutes old; otherwise, or on a forced refresh, it runs a fresh check."
},
{
"endpoint": "/api/health/active-errors",
@@ -286,7 +286,7 @@
{
"endpoint": "/api/storage/smart/<disk>/test",
"method": "POST",
"use": "Trigger a SMART self-test. Body: <code>'{'\"type\":\"short\"|\"long\"'}'</code>."
"use": "Start a SMART self-test. Body schema: <code>'{'\"test_type\":\"short\"|\"long\"'}'</code>."
},
{
"endpoint": "/api/storage/smart/schedules",
@@ -336,7 +336,7 @@
{
"endpoint": "/api/vms",
"method": "GET",
"use": "List of all VMs and CTs with status, vmid, name."
"use": "VMs and CTs on the local node, with status, vmid and name."
},
{
"endpoint": "/api/vms/<vmid>",
@@ -361,7 +361,7 @@
{
"endpoint": "/api/vms/<vmid>/control",
"method": "POST",
"use": "Body: <code>'{'\"action\":\"start|stop|reboot|shutdown\"'}'</code>. Power-cycle a guest."
"use": "Choose one action from the body schema: <code>'{'\"action\":\"start|stop|reboot|shutdown\"'}'</code>. Controls guest power state."
},
{
"endpoint": "/api/vms/<vmid>/backup",
@@ -386,7 +386,7 @@
{
"endpoint": "/api/backups",
"method": "GET",
"use": "Cluster-wide list of backups."
"use": "Backups found in dir, NFS, CIFS and PBS storages queried through the local node. This is not an exhaustive scan of every cluster node."
},
{
"endpoint": "/api/backup-storages",
@@ -467,7 +467,7 @@
{
"endpoint": "/api/notifications/test-ai",
"method": "POST",
"use": "Test the AI provider connection. Body: <code>'{'\"provider\",\"api_key\",\"model\",\"ollama_url?\"'}'</code>."
"use": "Test the AI provider connection. Body fields (schematic): <code>'{'\"provider\",\"api_key\",\"model\",\"ollama_url?\"'}'</code>."
},
{
"endpoint": "/api/notifications/provider-models",
@@ -542,13 +542,13 @@
{
"endpoint": "/api/proxmenux/tool-source/<key>",
"method": "GET",
"use": "Source code of a specific post-install function — the exact bash that was applied."
"use": "Source of the mapped post-install function, extracted from current host scripts or preserved legacy code. This is not a guaranteed snapshot of the exact code originally executed."
}
]
},
"prometheus": {
"heading": "Prometheus metrics",
"intro": "ProxMenux Monitor exposes a Prometheus-format scrape endpoint at <code>GET /api/prometheus</code> (authenticated) returning OpenMetrics-format text. Every metric is labelled with <code>node=\"&lt;hostname&gt;\"</code> and carries an explicit timestamp so it ingests cleanly into Prometheus, VictoriaMetrics, Mimir or any compatible TSDB.",
"intro": "The authenticated <code>GET /api/prometheus</code> endpoint returns Prometheus text exposition format version 0.0.4. Every metric includes <code>node=\"&lt;hostname&gt;\"</code> and an explicit timestamp. Collect it with Prometheus or another compatible time-series database.",
"exportedTitle": "Exported metrics",
"headerGroup": "Group",
"headerMetric": "Metric",
@@ -597,7 +597,7 @@
},
{
"metric": "proxmox_disk_temperature_celsius",
"desc": "Per-disk temperature. Label <code>device</code>."
"desc": "Temperature per disk. Label <code>disk</code>."
},
{
"metric": "proxmox_fan_speed_rpm",
@@ -610,15 +610,15 @@
"metrics": [
{
"metric": "proxmox_disk_total_bytes",
"desc": "Total disk space per mount. Label <code>mountpoint</code>."
"desc": "Total capacity per exported disk entry. Label <code>disk</code>."
},
{
"metric": "proxmox_disk_used_bytes",
"desc": "Used disk space per mount."
"desc": "Used capacity per exported disk entry."
},
{
"metric": "proxmox_disk_usage_percent",
"desc": "Disk usage percentage per mount."
"desc": "Used capacity percentage per exported disk entry."
}
]
},
@@ -660,7 +660,7 @@
},
{
"metric": "proxmox_vm_status",
"desc": "Per-VM/CT status (1 = running, 0 = stopped). Labels <code>vmid</code>, <code>name</code>, <code>type</code>."
"desc": "Status per VM/CT (1 = running, 0 = otherwise). Labels <code>node</code>, <code>vmid</code>, <code>name</code>."
},
{
"metric": "proxmox_vm_cpu_usage",
@@ -677,7 +677,7 @@
"metrics": [
{
"metric": "proxmox_gpu_temperature_celsius",
"desc": "GPU temperature. Labels <code>slot</code>, <code>vendor</code>."
"desc": "GPU temperature. Labels <code>slot</code>, <code>vendor</code>; also includes the gpu name label."
},
{
"metric": "proxmox_gpu_utilization_percent",
@@ -724,7 +724,7 @@
}
],
"scrapeTitle": "Prometheus scrape config",
"scrapeIntro": "The endpoint requires authentication. Pass the API token as a bearer header in your Prometheus scrape config:",
"scrapeIntro": "When authentication is enabled, pass an API token in the bearer header of your Prometheus collection configuration:",
"perHostTitle": "Per-host scrape",
"perHostBody": "Each ProxMenux Monitor instance exports metrics for the host it runs on. In a cluster, point Prometheus at every node — the <code>node</code> label on every series lets you distinguish them in Grafana queries (<code>proxmox_vms_running'{'node=\"pve01\"'}'</code>)."
},
+33 -33
View File
@@ -18,8 +18,8 @@
},
"requestFlow": {
"heading": "Request flow",
"intro": "From the browser to the kernel, every dashboard view follows the same path:",
"diagramCaption": "Each request is authenticated by JWT (when auth is enabled), dispatched to a blueprint, and answered with data collected on demand from host tooling. If Fail2Ban is installed and the proxmenux jail is active, the middleware also checks the request against the jail's banned IP list. The optional reverse proxy is transparent to Flask — it forwards X-Forwarded-* headers and the app recovers the real client IP from them. State that needs to outlive a request lives in SQLite.",
"intro": "A typical dashboard data request follows this path; browser-only preferences can be handled locally:",
"diagramCaption": "Protected routes validate JWT when authentication is enabled. Core routes and blueprints return cached or newly collected host data. The optional Fail2Ban hook checks its cached jail ban list. Forwarded client-IP headers are trusted only with PROXMENUX_TRUST_PROXY=1; otherwise the peer address is used. Persistent state includes SQLite databases and JSON files, including auth.json.",
"diagramArrowLabel": "HTTP / WS",
"nodes": {
"clientLabel": "Client",
@@ -31,7 +31,7 @@
"stateLabel": "Local state",
"stateDetail": "SQLite DB\n+ auth.json"
},
"threadsIntro": "The same process also runs four <strong>background threads</strong> started at boot — they don't serve HTTP, they push state into SQLite or into the notification queue while the host is up:",
"threadsIntro": "The process also runs <strong>background threads</strong>. The examples below sample host data, update caches and SQLite, and dispatch notifications. Other workers also exist, and notification delivery depends on its enabled setting:",
"headerThread": "Thread",
"headerCadence": "Cadence",
"headerJob": "Job",
@@ -48,8 +48,8 @@
},
{
"thread": "_vital_signs_sampler",
"cadence": "~1 s",
"job": "High-frequency CPU + temperature sampler used for live widgets in the Overview panel."
"cadence": "CPU 5 s; temperature 15 s; memory 30 s",
"job": "Samples CPU usage, memory and CPU temperature for live metrics and sustained-condition detection, independently of the five-minute health collector."
},
{
"thread": "notification_manager.start()",
@@ -62,9 +62,9 @@
"heading": "systemd unit",
"intro": "The installer drops a unit at <code>/etc/systemd/system/proxmenux-monitor.service</code>. Default content:",
"items": [
"<strong><code>User=root</code></strong> — required: SMART, <code>pvesh</code>, journal scopes, ZFS commands and the web terminal all need root.",
"<strong><code>User=root</code></strong> — the supported service runs with root privileges for host operations such as SMART access, <code>pvesh</code> and ZFS management. Its web-terminal processes inherit those privileges.",
"<strong><code>Restart=on-failure</code></strong> with a 10-second back-off — non-zero exits relaunch automatically.",
"<strong><code>After=network.target</code></strong> — waits for the host network stack to be online."
"<strong><code>After=network.target</code></strong> — orders startup after that target; it does not guarantee an assigned IP, DNS or external connectivity."
],
"inspectTitle": "Inspect the live unit"
},
@@ -73,13 +73,13 @@
"intro": "The AppImage is a self-mounting filesystem. <code>AppRun</code> at the root sets up the environment and execs <code>flask_server.py</code>:",
"consequencesIntro": "Two consequences of this layout:",
"consequences": [
"<strong>No host Python pollution.</strong> The vendored interpreter and packages are isolated inside the AppImage — upgrading the host's system Python doesn't affect the Monitor and vice-versa.",
"<strong>Hardware tools are bundled too.</strong> <code>ipmitool</code>, <code>lm-sensors</code> and <code>upsc</code> ship inside the AppImage so the dashboard can read out-of-band sensors and UPS state without forcing the user to install Debian packages."
"<strong>Bundled Python packages.</strong> Python packages ship inside the AppImage and run on the host's own Python 3.11 (PVE 8) or 3.13 (PVE 9) interpreter, without installing anything into the host's system Python. The application still uses host kernel interfaces and external host tools.",
"<strong>Hardware clients are bundled too.</strong> <code>ipmitool</code>, <code>lm-sensors</code> and <code>upsc</code> are included. Readings still depend on supported hardware, access to sensors and, for UPS data, a configured NUT server."
]
},
"flask": {
"heading": "Flask app structure",
"intro": "<code>flask_server.py</code> creates a single <code>Flask(__name__)</code> instance, enables CORS, and registers six blueprints plus a WebSocket initializer:",
"intro": "<code>flask_server.py</code> creates one <code>Flask(__name__)</code> instance with restricted CORS origins, registers ten blueprints directly and initializes terminal routes. The table highlights the main modules; PBS, Monitor links, audit and VM-backup blueprints are also registered. PVE-specific prewarmers run only on PVE hosts.",
"headerBlueprint": "Blueprint / module",
"headerPrefix": "Routes prefix",
"headerOwns": "Owns",
@@ -109,7 +109,7 @@
"prefix": [
"/api/health/*"
],
"owns": "Public health probe, detailed status, active / dismissed errors, suppression settings."
"owns": "Health probes, detailed status, active and dismissed errors, and suppression settings. Protected routes require authentication when it is enabled."
},
{
"blueprint": "flask_terminal_routes.py",
@@ -137,7 +137,7 @@
"prefix": [
"/api/proxmenux/*"
],
"owns": "Reads which ProxMenux post-install optimizations are installed on the host."
"owns": "Reads the ProxMenux post-install optimizations recorded in the host registry."
},
{
"blueprint": "flask_oci_routes.py",
@@ -147,11 +147,11 @@
"owns": "OCI / container app deployment helpers (Proxmox VE 9.1+)."
}
],
"endpointsLink": "The full endpoint list with request / response shapes is in <link>API Reference</link>."
"endpointsLink": "Integration endpoints and their request/response formats are described in <link>API Reference</link>."
},
"dataSources": {
"heading": "Data sources",
"intro": "Nothing is collected from a custom agent — the Monitor reads the same files and runs the same commands a human admin would:",
"intro": "Host data comes mainly from standard libraries, files and administrative commands. Some guest information also depends on the QEMU Guest Agent or commands executed inside a CT:",
"headerSource": "Source",
"headerUsedFor": "Used for",
"rows": [
@@ -181,7 +181,7 @@
},
{
"source": "nvidia-smi · intel_gpu_top",
"usedFor": "GPU utilisation, VRAM, temperature, encoder / decoder load."
"usedFor": "Available GPU utilisation, VRAM, temperature and encoder/decoder measurements; fields depend on the vendor, tool and driver."
},
{
"source": "lspci · lscpu · dmidecode",
@@ -201,7 +201,7 @@
},
"persistence": {
"heading": "Persistence",
"intro": "Two filesystem locations split state by sensitivity:",
"intro": "Several state files have different contents and access requirements:",
"headerPath": "Path",
"headerOwner": "Owner",
"headerContents": "Contents",
@@ -214,25 +214,25 @@
{
"path": "/usr/local/share/proxmenux/.notification_key",
"owner": "root <code>0600</code>",
"contents": "32-byte XOR key used to encrypt sensitive notification settings before storing them in the DB (Telegram tokens, AI API keys, etc.)."
"contents": "32-byte master key for the ENC2 notification-secret format. The implementation uses a per-value random salt, derived keys and a MAC; old fixed-key XOR values are supported for migration."
},
{
"path": "/root/.config/proxmenux-monitor/auth.json",
"owner": "root:root",
"contents": "Authentication state: enabled flag, username, SHA-256 password hash, TOTP secret, backup codes, list of issued API tokens, list of revoked token hashes."
"contents": "Authentication configuration: enabled flag, username, salted PBKDF2-HMAC-SHA256 password hash, TOTP secret, backup codes, per-install JWT signing secret, API-token metadata and revocation hashes. Legacy SHA-256 password hashes are migrated on successful login."
},
{
"path": "/var/log/proxmenux-auth.log",
"owner": "root:root",
"contents": "Plain-text auth event log. Always written. If Fail2Ban is installed with the <code>[proxmenux]</code> jail, the jail reads this file to ban brute-force attempts; if not, the file simply accumulates the log entries."
"contents": "Plain-text authentication event log, written independently of Fail2Ban. When the <code>[proxmenux]</code> jail is installed and enabled, it reads this log to detect repeated failed logins. Without that jail, the log remains available for inspection."
}
],
"backupTitle": "Back up auth.json before reinstalling",
"backupBody": "Reinstalling the AppImage replaces the binary but leaves <code>/root/.config/proxmenux-monitor/auth.json</code> and <code>/usr/local/share/proxmenux/health_monitor.db</code> intact. If you restore from a host backup, keep both files together — the API tokens stored in <code>auth.json</code> are validated against <code>JWT_SECRET</code>; if the DB and auth.json get out of sync, dismissed errors and stored tokens may misbehave."
"backupBody": "Replacing the AppImage normally preserves <code>/root/.config/proxmenux-monitor/auth.json</code> and <code>/usr/local/share/proxmenux/health_monitor.db</code>. Preserve <code>auth.json</code> with its per-install jwt_secret to retain token validity and metadata. The database stores health and notification state independently. Back up <code>.notification_key</code> with the database to restore encrypted channel settings; restoring the DB alone does not restore API authentication."
},
"health": {
"heading": "Health Monitor cycle",
"intro": "Every 5 minutes <code>health_monitor.py</code> runs a deterministic cycle across the ten categories shown on the dashboard:",
"intro": "About every five minutes, the background collector invokes <code>health_monitor.py</code> to run the checks behind the dashboard’s ten categories:",
"items": [
"Critical PVE services (<code>pveproxy</code>, <code>pvedaemon</code>, <code>pvestatd</code>, <code>pve-cluster</code>).",
"Proxmox storage pools (<code>pvesh get /storage</code> + per-storage availability).",
@@ -242,11 +242,11 @@
"Updates: pending package upgrades and security patches.",
"Logs: persistent / spike / cascade pattern detection in the system journal.",
"Memory: OOM killer activity, sustained high pressure.",
"Temperature: CPU / chassis sensors against vendor thresholds.",
"CPU: usage and CPU temperature checked against the configurable thresholds; available sensors depend on the hardware.",
"Security: authentication failures, ban events, fail2ban jail status."
],
"afterIntro": "Each finding is normalised into a stable <code>error_key</code> + category + severity. The persistence layer deduplicates against the existing <code>errors</code> table — repeated events update <code>last_seen</code> and the occurrence counter without spamming notifications.",
"cycleEnd": "The cycle also auto-resolves stale errors using the per-category <em>Suppression Duration</em> setting, cleans up errors for resources that no longer exist (deleted VMs / removed disks / unmounted storages), and prunes the <code>events</code> log older than 30 days. The full catalogue of categories and the dashboard view that surfaces them is documented in <link>Dashboard → Health Monitor</link>."
"afterIntro": "Findings use a stable <code>error_key</code>, category and severity. Existing records in <code>errors</code> are updated in place (<code>last_seen</code>, severity, reason) rather than duplicated. Notification delivery also has its own fingerprint and cooldown rules.",
"cycleEnd": "Cleanup can auto-resolve stale errors using category <em>Suppression Duration</em> values and state-based rules, remove orphan records for resources that were removed, and prune <code>events</code> older than 30 days. The categories and dashboard are described in <link>Dashboard → Health Monitor</link>."
},
"notifications": {
"heading": "Notification engine",
@@ -254,7 +254,7 @@
"items": [
"<strong>Watchers</strong> push events: <code>JournalWatcher</code> tails the system journal, <code>TaskWatcher</code> polls the Proxmox task list, <code>ProxmoxHookWatcher</code> reacts to backup / replication / snapshot hooks, and <code>PollingCollector</code> handles slow data sources.",
"<strong>Templates</strong> turn an event into a (title, body) pair. The same template can run through the configured AI provider (OpenAI / Anthropic / Gemini / Groq / Ollama / OpenRouter) to produce a plain-language rewrite; both versions are stored in <code>notification_history</code>.",
"<strong>Channels</strong> deliver messages: Telegram, Discord, Email, Gotify, Pushover and Apprise (multi-channel). Each is implemented in <code>notification_channels.py</code> behind the same <code>create_channel()</code> / <code>send()</code> interface, so adding a new channel is a single class.",
"<strong>Channels</strong> deliver messages through services including Telegram, Discord, Email, Gotify, Pushover and Apprise. Implementations in <code>notification_channels.py</code> use the shared <code>create_channel()</code> / <code>send()</code> interface.",
"<strong>Encryption.</strong> Sensitive settings (<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>) are encrypted with the key in <code>.notification_key</code> before being written to the DB and are masked in the interface."
],
"linksFooter": "Per-event toggles, channel overrides and AI configuration are surfaced in <notifLink>Settings → Notifications</notifLink> and <aiLink>Settings → AI Assistant</aiLink>."
@@ -263,21 +263,21 @@
"heading": "WebSocket terminal",
"intro": "The <em>Terminal</em> tab in the dashboard is a thin <code>xterm.js</code> client wired to a server-side PTY through a WebSocket. Two transport modes:",
"items": [
"<strong>HTTP mode (default):</strong> Flask's development server with <code>flask-sock</code> handles upgrade requests. Good enough for LAN / direct access.",
"<strong>HTTPS / WSS mode:</strong> when an SSL certificate is configured, the process switches to <code>gevent.pywsgi.WSGIServer</code> with <code>geventwebsocket.handler.WebSocketHandler</code>, so WebSockets work over TLS without polyfills."
"<strong>HTTP mode (default):</strong> the built-in Flask server with <code>flask-sock</code> handles WebSocket upgrade requests.",
"<strong>HTTPS / WSS mode:</strong> the TLS server uses <code>gevent.pywsgi.WSGIServer</code> with its default handler; <code>flask-sock</code> handles WebSocket connections over TLS."
],
"outro": "The PTY is a child of the Flask process, so it inherits <code>User=root</code> from the unit. Every terminal request goes through JWT auth; the user must already be logged in to the dashboard before a PTY is allocated.",
"outro": "Terminal child processes inherit <code>User=root</code> from the service. Opening a WebSocket requires a short-lived, single-use ticket obtained from the authenticated terminal-ticket endpoint with administrative scope.",
"proxyNote": "If you access the Monitor through a reverse proxy, make sure WebSocket forwarding is enabled (the <code>Upgrade</code> and <code>Connection</code> headers). Without it the terminal won't work."
},
"proxy": {
"heading": "Reverse proxy & Fail2Ban",
"intro": "Two safeguards make sure security works the same way whether the dashboard is hit directly or through a reverse proxy:",
"intro": "Client-IP selection and optional application-level blocking depend on these settings and components:",
"items": [
"<strong>Real client IP recovery.</strong> A <code>before_request</code> hook reads <code>X-Forwarded-For</code> and <code>X-Real-IP</code> in that order, falling back to <code>request.remote_addr</code>. The recovered address is what auth logging and rate limiting see. This is always on.",
"<strong>Application-level Fail2Ban check (optional).</strong> When the dashboard sits behind a proxy, the kernel firewall can't block the real attacker IP — the connection always comes from the proxy. To plug that gap, the same hook above queries the <code>proxmenux</code> Fail2Ban jail every 30 seconds, caches the banned IP set, and short-circuits requests from those IPs with HTTP 403 inside Flask."
"<strong>Client IP selection.</strong> The <code>before_request</code> ban check and auth logging trust <code>X-Forwarded-For</code>, then <code>X-Real-IP</code>, only when PROXMENUX_TRUST_PROXY=1. Otherwise they use <code>request.remote_addr</code>. Forwarded headers are not accepted automatically.",
"<strong>Optional application-level Fail2Ban.</strong> A proxy connection can present the proxy as the TCP peer. When the trusted client address is available and the <code>proxmenux</code> jail is active, Flask rejects listed IPs with HTTP 403. The ban list is cached for 30 seconds and refreshed by request processing after expiry, rather than polled by a dedicated timer."
],
"calloutTitle": "Fail2Ban is not bundled",
"calloutBody": "Fail2Ban is <strong>not</strong> installed by ProxMenux Monitor itself. The application-level check is a no-op until you install Fail2Ban on the host (e.g. via <link>Security → Fail2Ban</link> in the ProxMenux menu). When the <code>fail2ban-client</code> binary or the <code>proxmenux</code> jail is absent, the call fails silently and requests are not gated — auth still applies, but no IP-level banning.",
"calloutBody": "Fail2Ban is <strong>not</strong> bundled or installed automatically. It can be installed through the optional Monitor Security workflow or <link>Security → Fail2Ban</link> in ProxMenux Scripts. If <code>fail2ban-client</code> or the <code>proxmenux</code> jail is absent, this application hook does not block requests. The configured authentication policy still applies.",
"outro": "Reverse-proxy snippets (Nginx / Caddy / Traefik) and the Fail2Ban jail walkthrough are in <accessLink>Access & Authentication</accessLink> and <fail2banLink>Security → Fail2Ban</fail2banLink>."
},
"whereNext": {
@@ -291,7 +291,7 @@
{
"label": "API Reference",
"href": "/docs/monitor/api",
"tail": " — every endpoint, token management, security best-practices."
"tail": " — integration endpoints, token management and authentication conventions."
},
{
"label": "Settings → ProxMenux Monitor",
@@ -108,7 +108,7 @@
"coral": {
"heading": "Coral TPU / AI Accelerators",
"subHeading": "(conditional)",
"intro": "Renders when the host has Google Coral or other AI-accelerator devices wired up. Each device opens a modal with its connection type (M.2 / mini-PCIe / USB), PCIe link width, vendor / product ID, kernel driver (<code>apex</code> for PCIe, <code>libedgetpu</code> for USB), kernel modules (<code>gasket</code> + <code>apex</code>), device nodes (<code>/dev/apex_*</code>), Edge TPU runtime status, live temperature and the firmware hardware-warning thresholds.",
"intro": "Renders when the host has Google Coral or other AI-accelerator devices wired up. Each device opens a modal with its connection type (M.2 / mini-PCIe / USB), PCIe link width, vendor / product ID, software support (the <code>apex</code> kernel driver for PCIe, the <code>libedgetpu</code> user-space library for USB), kernel modules (<code>gasket</code> + <code>apex</code>), device nodes (<code>/dev/apex_*</code>), Edge TPU runtime status, live temperature and the firmware hardware-warning thresholds.",
"imageAlt": "Coral Edge TPU detail modal: PCIe / M.2 connection, PCIe 5.0 GT/s x1 link, vendor 1ac1:089a, kernel driver apex, gasket and apex modules loaded, /dev/apex_0 present, Edge TPU Runtime not installed, temperature 53.5 °C with hardware warning thresholds",
"imageCaption": "M.2 Coral with the host kernel modules loaded, the device node up and the firmware temperature warnings exposed. The runtime line goes green once the matching Edge TPU runtime is installed.",
"pathsIntro": "Two install paths exist depending on the form factor:",
@@ -189,7 +189,7 @@
{
"section": "CPU temperature history",
"endpoint": "/api/temperature/history",
"source": "Time series sampled by the Health Monitor every 5 min and persisted to SQLite."
"source": "Time series recorded by the temperature collector every 60 seconds and persisted to SQLite."
},
{
"section": "GPU live metrics",
@@ -59,7 +59,7 @@
"<strong>Click</strong> — every node except the host is clickable and opens the same per-interface drill-in modal documented below. Tapping the host is intentionally a no-op — there is no host-level modal in this view."
],
"useTitle": "When it's useful",
"useBody": "The group cards below tell you <em>what</em> exists; the diagram tells you <em>how it's connected</em> and where the traffic is flowing right now. Patterns easy to spot at a glance: a bridge with no active guest attached, two heavy guests going through the same NIC (bottleneck candidate), or a single VM saturating a link while everything else is quiet."
"useBody": "The group cards show <em>what</em> exists; the diagram shows <em>how it is connected</em> and where traffic is flowing. You can spot guests sharing a bridge, two busy guests sharing a NIC (a possible bottleneck), or one VM saturating a link while others are quiet."
},
"groups": {
"heading": "Three interface groups",
@@ -121,7 +121,7 @@
"mode1Title": "Mode 1 — Historical view",
"mode1Alt": "Network Latency modal in historical mode — Gateway target with a 1-hour timeframe and the past samples plotted",
"mode1Caption": "Historical view — Gateway target over the last hour, fed from the latency-history database written every 60 seconds by the temperature/latency collector thread.",
"mode1Body1": "The default mode when the modal opens. A second dropdown picks the timeframe (<em>1 Hour / 24 Hours / 7 Days / 30 Days / 1 Year</em>); data resolution drops with the window so the chart stays readable. Headline stats — Current / Min / Avg / Max — render above the chart, with a status pill (Excellent / Good / Fair / Poor) reflecting the current value against the thresholds below.",
"mode1Body1": "The default mode when the dialog opens. A second dropdown selects the timeframe (<em>1 Hour / 6 Hours / 24 Hours / 3 Days / 7 Days</em>). Current / Min / Avg / Max appear above the chart, with an Excellent / Good / Fair / Poor status indicator based on the thresholds below.",
"mode1Body2": "Source: the same latency samples the Health Monitor uses to detect persistent network slowdowns — sampled every 60 seconds against the gateway by the background <code>_temperature_collector_loop</code> thread, written to a local SQLite history.",
"mode2Title": "Mode 2 — Real-time test",
"mode2Alt": "Network Latency modal running a real-time ping test against Cloudflare — progress bar at 50%, live samples accumulating on the chart",
@@ -162,9 +162,9 @@
}
],
"reportTitle": "Network Latency Report (PDF)",
"reportIntro": "Both modes have a <strong>Report</strong> button next to the target selector. Clicking it generates a PDF with everything you'd send to your ISP if you wanted to make a case for poor service.",
"reportIntro": "Both modes have a <strong>Report</strong> button beside the target selector. It opens a printable report of the measurements; save it as PDF from the browser's print dialog and attach it to a troubleshooting request to your ISP.",
"reportPreviewAlt": "First page of the Network Latency Report PDF — Executive Summary with the gauge, latency statistics, the latency graph and the threshold guide",
"reportPreviewCaption": "First page of the Network Latency Report — Executive Summary with the gauge dial and headline stats, the per-second latency graph, and the threshold guide. Page 2 onwards has the per-sample table and methodology.",
"reportPreviewCaption": "The first page of the Network Latency Report contains the executive summary, gauge, main statistics, time-series latency graph and threshold guide. Page 2 onwards contains the per-sample table and methodology.",
"downloadLabel": "Download sample Network Latency report (PDF)",
"sectionsIntro": "The report has six sections:",
"sections": [
@@ -173,10 +173,10 @@
"<strong>Latency Graph</strong> — area chart of every sample over the test window with a min/avg/max y-axis grid.",
"<strong>Performance Thresholds</strong> — the same four-tier scale documented above, with a coloured dot per tier.",
"<strong>Detailed Test Results</strong> — numbered table with timestamp, latency, packet loss and status for every sample. Useful for spotting micro-bursts that the headline averages hide.",
"<strong>Methodology</strong> — test method (ICMP Echo Request), samples per test (3 consecutive pings), target name, target IP and a final \"Performance Assessment\" paragraph derived from the verdict."
"<strong>Methodology</strong> — ICMP Echo Request, 3 consecutive pings per sample, target name and IP, and a final performance assessment derived from the status."
],
"useCaseTitle": "Use case: claims to your ISP",
"useCaseBody": "Run the real-time test against Cloudflare for 2 minutes during a moment of perceived slowness, then click <em>Test Again</em> a few times to extend the dataset, and finally <em>Report</em>. The PDF carries the full per-sample table plus the methodology block — ISPs typically accept this as evidence, especially when correlated with timestamps from a separate complaint."
"useCaseTitle": "Use case: support from your ISP",
"useCaseBody": "Run the real-time Cloudflare test for 2 minutes while the connection feels slow, use <em>Test Again</em> to extend the record, then select <em>Report</em>. The PDF includes all samples and the methodology. You can attach it to a support request with the incident timestamps; your ISP decides what evidence it requires."
},
"excluding": {
"heading": "Excluding noisy interfaces",
@@ -202,7 +202,7 @@
{
"section": "Per-interface RX/TX time series",
"endpoint": "/api/network/<iface>/metrics",
"source": "<code>/proc/net/dev</code> sampled by the Health Monitor with byte-rate calculation."
"source": "Live counters use <code>/proc/net/dev</code>; chart history comes from Proxmox RRD through pvesh. VM/LXC interfaces use guest RRD data; physical and bridge interfaces use node-level RRD data."
},
{
"section": "Latency: current",
@@ -212,7 +212,7 @@
{
"section": "Latency: historical",
"endpoint": "/api/network/latency/history",
"source": "Persisted samples — every 5 min by the Health Monitor cycle."
"source": "Samples persisted about every 60 seconds by the background temperature/latency collector."
}
],
"codeComment1": "# Cross-check the interface state seen by the dashboard",
@@ -10,7 +10,7 @@
},
"intro": {
"title": "Two scopes, one tab",
"body": "The Security tab is divided into two clearly separated sections: <strong>ProxMenux Monitor</strong> (settings for the dashboard itself) and <strong>Proxmox VE</strong> (settings for the host underneath). Cards render conditionally — Fail2Ban and Lynis only appear once installed."
"body": "The Security tab has two sections: <strong>ProxMenux Monitor</strong> (dashboard settings) and <strong>Proxmox VE</strong> (host settings). The Fail2Ban and Lynis cards offer installation when those tools are missing, then show their controls once installed."
},
"monitor": {
"heading": "ProxMenux Monitor",
@@ -101,13 +101,13 @@
},
"pve": {
"heading": "Proxmox VE",
"intro": "The host's own protections — firewall, intrusion prevention and security audit. Last two only render when their respective tools are installed."
"intro": "The host’s protections: firewall, intrusion prevention and security audit. The Fail2Ban and Lynis cards offer installation if the tools are missing, then expose their management controls."
},
"firewall": {
"heading": "Proxmox Firewall",
"imageAlt": "Proxmox Firewall card showing Cluster Firewall and Host Firewall status, Quick Access Rules for ProxMenux Monitor and Proxmox Web UI, Rules Overview counters and a list of Firewall Rules with Add Rule button",
"imageCaption": "Proxmox Firewall card — cluster-level and host-level enable / disable toggles, common ports as <em>Quick Access Rules</em>, totals across <em>Rules Overview</em>, and the full rule list with <em>+ Add Rule</em>.",
"intro": "The card surfaces the Proxmox VE built-in firewall (which is independent from any host-level <code>iptables</code> / <code>nftables</code> you may run alongside). Three blocks:",
"intro": "The card manages the Proxmox VE firewall configuration. The classic backend uses <code>iptables</code>; the alternative backend uses <code>nftables</code>. It does not manage arbitrary rules created outside Proxmox. Three blocks:",
"items": [
"<strong>Cluster Firewall + Host Firewall</strong> — global toggles. The cluster firewall must be active for any host-level rule to take effect; the card flags this dependency inline.",
"<strong>Quick Access Rules</strong> — pre-defined rows for ports that matter to ProxMenux itself: <code>8008/TCP</code> (Monitor), <code>8006/TCP</code> (Proxmox Web UI). Each row shows the current allow / deny / unprotected state. The Proxmox Web UI is allowed via the <em>built-in</em> Proxmox firewall macro and can't be removed accidentally.",
@@ -135,8 +135,8 @@
"configAlt": "Configure sshd jail form with Max Retries, Ban Time in seconds with Permanent Ban option, Find Time, common values reminder, and Save Configuration button",
"configCaption": "Editing the sshd jail — pick a stricter <em>Max Retries</em> for SSH if you only ever log in from your own subnet, or extend <em>Ban Time</em> for the public-facing dashboard.",
"outro": "The full <em>What it installs / how it's configured / how to uninstall</em> walkthrough — including the manual install path, the SSH MaxAuthTries side effect, and the relationship with the <code>proxmenux-auth.log</code> journal — is in <link>ProxMenux → Security → Fail2Ban</link>.",
"calloutTitle": "Without Fail2Ban, brute-force protection is best-effort",
"calloutBody": "ProxMenux Monitor has its own <em>application-level</em> ban hook in the Flask request pipeline — but it only takes effect if Fail2Ban is installed and writes to the bans table. Without Fail2Ban, the Monitor logs failed logins to <code>proxmenux-auth.log</code> for future inspection but doesn't actively block IPs."
"calloutTitle": "Without Fail2Ban, this mechanism does not block IPs",
"calloutBody": "ProxMenux Monitor checks the IPs banned in Fail2Ban's <code>proxmenux</code> jail at the <em>application level</em> before handling Flask requests, caching the result for 30 seconds. Without Fail2Ban, failed logins are recorded in <code>proxmenux-auth.log</code> and the login endpoint is limited to 5 attempts per IP every 5 minutes, but no IP is banned."
},
"lynis": {
"heading": "Lynis Security Audit",
@@ -145,7 +145,7 @@
"whyUseful": "<strong>Why it's useful.</strong> Knowing the security posture of your server is hard to do by reading config files one by one. Lynis catches the things that are routinely overlooked: kernel hardening flags missing, weak SSH ciphers enabled, journal not persistent, sudoers <code>NOPASSWD</code> on default accounts, and many more. Re-running it after applying ProxMenux post-install tweaks gives you an objective number for the improvement.",
"notInstalledAlt": "Lynis Security Audit card with Not Installed state and Install Lynis button, listing features: hardening scoring, vulnerability detection, compliance checking and GitHub source",
"notInstalledCaption": "Lynis card before install — the blue box summarises what the tool does.",
"notBundled": "Lynis is also <strong>not bundled</strong>. ProxMenux installs the latest release directly from the official GitHub source (not the Debian package, which lags several minor versions).",
"notBundled": "Lynis is also <strong>not bundled</strong>. ProxMenux installs it directly from the official GitHub source rather than the Debian package.",
"confirmAlt": "Install Lynis confirmation modal listing what Lynis does: hardening scoring, vulnerability detection, configuration analysis, compliance checking, source from official GitHub repository",
"confirmCaption": "Install confirmation — explicit about the GitHub source.",
"progressAlt": "Lynis Installation streaming panel: installing latest scan tool, version 3.1.6 confirmed, installation completed message",
@@ -157,7 +157,7 @@
"runningCaption": "Audit in progress — the action button shows a spinner and the card explicitly warns that the scan can take 2–5 minutes.",
"finishedBody": "When it finishes, the card flips to the results view: hardening index, warnings, suggestions and an <em>Audit Reports</em> list with each historical scan.",
"resultsAlt": "Lynis Security Audit card with results: Hardening Index 71 with Lynis 66 PVE 71 breakdown, 3 warnings, 40 suggestions, Security Hardening Score progress bar Proxmox Adjusted 71 of 100 in the Good range, audit reports list with PDF download and Run Security Audit button",
"resultsCaption": "Audit results — Hardening Index <strong>71/100 (Good)</strong> on a sample run. The card also shows the \"Lynis raw score\" (66) versus the Proxmox-adjusted score (71) which adds back 11 points for findings the Lynis test corpus flags but are expected behaviour on Proxmox VE.",
"resultsCaption": "Audit results — Hardening Index <strong>71/100 (Good)</strong> in a sample run. The card shows the Lynis raw score (66) and the Proxmox-adjusted score (71). The adjustment depends on the raw score and the share of findings classified as expected on Proxmox VE; it is not a fixed 11-point addition.",
"scoreTitle": "Lynis raw score vs Proxmox-adjusted score",
"scoreIntro": "Lynis ships rules tuned for general-purpose Debian. Proxmox legitimately diverges from some of them (services running as root for cluster reasons, custom <code>journald</code> tuning, etc.). The card shows both numbers so you can:",
"scoreItems": [
@@ -179,7 +179,7 @@
{
"card": "Authentication, 2FA, password change",
"endpoint": "/api/auth/*",
"source": "Local SQLite + JWT issued by the Monitor."
"source": "Local auth configuration in ~/.config/proxmenux-monitor/auth.json; JWTs issued by the Monitor."
},
{
"card": "SSL / HTTPS",
@@ -76,18 +76,18 @@
},
"thresholds": {
"heading": "Health Monitor Thresholds",
"intro": "Where the previous card decides <em>how long to stay quiet after a dismiss</em>, this one decides <strong>at what value an alert fires in the first place</strong>. Every check the Health Monitor runs is parameterised by a pair of numbers — a <strong>Warning</strong> threshold and a <strong>Critical</strong> threshold — and both are exposed here for the operator to tune.",
"intro": "The previous card sets <em>how long to stay quiet after a dismiss</em>; this one sets <strong>the value at which an alert is raised</strong>. Most threshold-based checks have adjustable <strong>Warning</strong> and <strong>Critical</strong> values. The table below explains exceptions such as the combined swap rule.",
"whatForTitle": "What it is for",
"whatForIntro": "Defaults that ship with ProxMenux are sane for the average Proxmox host, but every environment has its own envelope:",
"whatForItems": [
"A small homelab with a single-disk SSD may want to page earlier on capacity (75 / 90 %) to leave room for snapshots.",
"A datacenter host with redundant Ceph nodes can be more relaxed on memory warnings (a 90 % working set is normal under ZFS ARC).",
"A passively-cooled mini-PC needs lower temperature thresholds than a server with forced-air cooling — same drive class, different physical envelope.",
"Memory thresholds should reflect the host’s memory measurements and workload. Ceph redundancy alone does not justify relaxing memory warnings, and high ZFS ARC usage must not be confused with an unreclaimable working set.",
"Choose drive-temperature thresholds using the drive’s specifications and observed operating conditions. Passive versus forced-air cooling alone does not determine a universally lower or higher safe limit.",
"A heavily-virtualized host that pegs CPU during builds should not page on every 80 % spike, but must still alert on sustained pressure."
],
"whatForOutro": "Editing a threshold takes effect <strong>on the next scan</strong> — the Health Monitor re-reads the values from <code>/usr/local/share/proxmenux/health_thresholds.json</code> on every cycle, no service restart needed. The same numbers also feed the colour ranges of the dashboard widgets (the temperature line in the disk-temperature modal, the bars on the storage cards) so the visual classification matches what triggers the alert.",
"whatForOutro": "Supported threshold changes take effect <strong>on the next scan</strong>. The Health Monitor reads <code>/usr/local/share/proxmenux/health_thresholds.json</code> each cycle without a restart. Selected widgets, including disk temperature, use these values; some capacity bars retain separate visual cutoffs.",
"coloursTitle": "Status colours: how Warning and Critical render in the dashboard",
"coloursIntro": "Every threshold below produces the same three-state classification across the dashboard — same colours for storage bars, CPU/memory rings, temperature chips, and the dot on the disk modal. Reading a colour anywhere in the Monitor maps to a definite range relative to the configured pair:",
"coloursIntro": "Widgets that use the configured Warning/Critical pair follow the three-state classification below. Some visual indicators, including the PVE storage capacity bars, use their own cutoffs; do not infer a Health Monitor alert solely from their colour.",
"headerColour": "Colour",
"headerRange": "Range",
"headerMeaning": "Meaning",
@@ -105,7 +105,7 @@
{
"colour": "Red",
"range": "value ≥ Critical",
"meaning": "Critical state. The Health Monitor fires a CRITICAL event; CRITICAL bypasses Quiet Hours and always reaches the channel."
"meaning": "Critical state. The Health Monitor raises a CRITICAL event, which bypasses Quiet Hours. Channel category/event settings still apply; delivery also depends on the channel being available."
}
],
"sectionsTitle": "Sections and recommended defaults",
@@ -125,13 +125,13 @@
"section": "Memory",
"warning": "85 %",
"critical": "95 %",
"gates": "RAM pressure on the host."
"gates": "Host RAM pressure."
},
{
"section": "Swap (critical only)",
"warning": "—",
"critical": "5 %",
"gates": "Swap actually being used. The number is intentionally low: a healthy Proxmox host should rarely touch swap, so even 5 % is a meaningful signal of RAM pressure."
"critical": "80 %",
"gates": "Swap CRITICAL requires both swap usage above 80 % and available RAM below 15 %, sustained across the detector’s samples. Used swap alone does not trigger this rule."
},
{
"section": "CPU temperature",
@@ -143,25 +143,25 @@
"section": "Disk temp — HDD",
"warning": "60 °C",
"critical": "65 °C",
"gates": "Standard spinning drives. Manufacturer envelope tops out around 60–65 °C, so Critical is set right at the hard limit."
"gates": "HDD temperature. The defaults are 60 °C Warning and 65 °C Critical; these are monitoring defaults, not a universal manufacturer limit. Check the specific drive model’s specifications."
},
{
"section": "Disk temp — SSD",
"warning": "70 °C",
"critical": "75 °C",
"gates": "2.5'' / M.2 SATA SSDs — run cooler than NVMe but warmer than HDDs."
"gates": "SATA SSDs in 2.5-inch or M.2 formats. This class uses 70/75 °C monitoring defaults; actual temperature limits depend on the drive model."
},
{
"section": "Disk temp — NVMe",
"warning": "80 °C",
"critical": "85 °C",
"gates": "NVMe drives run hotter by design; controllers self-throttle above ~85 °C, so Warning catches the climb before throttling kicks in."
"gates": "NVMe temperature. The class uses 80/85 °C monitoring defaults. Controller throttling temperatures vary by model and are not universally 85 °C."
},
{
"section": "Disk temp — SAS",
"warning": "55 °C",
"critical": "65 °C",
"gates": "Enterprise SAS drives share the same ~65 °C manufacturer limit as HDDs, but are normally deployed in rack chassis with active cooling. A reading at 55 °C already signals a cooling problem (failed fan, HVAC issue) <em>before</em> the drive itself is at risk — hence a lower Warning than HDD, not because SAS is less heat-tolerant."
"gates": "SAS temperature. This class uses 55 °C Warning and 65 °C Critical. These are <em>monitoring defaults</em>, not proof of a cooling fault at 55 °C or a universal manufacturer limit."
},
{
"section": "Disk space — host",
@@ -185,7 +185,7 @@
"section": "PVE storage",
"warning": "85 %",
"critical": "95 %",
"gates": "Block-style PVE storages (LVM, LVM-thin, ZFS-pool, RBD/Ceph, PBS)."
"gates": "Only PVE storages of type LVM, LVM-thin, ZFS-pool, RBD, CephFS and PBS. Directory, NFS and CIFS storages are covered by the host disk-space row."
},
{
"section": "ZFS pool",
@@ -197,7 +197,7 @@
"defaultsTitle": "Defaults, overrides and reset",
"defaultsBody": "The backend exposes a merged view: every section starts from the ProxMenux defaults (the values you see when the host is fresh) and you override only the knobs you care about. The card shows the <em>effective</em> value — the override if you set one, otherwise the default. A <strong>Reset</strong> button wipes every override and goes back to defaults across all sections at once.",
"validationTitle": "Validation",
"validationBody": "Saving rejects values that don't make sense (percentages outside 0–100, critical below warning, negative temperatures). The frontend shows the inline error; the backend validates again before persisting, so the API can't be tricked into a broken threshold by a hand-crafted PUT."
"validationBody": "Saving validates values against each field’s allowed range and rejects Critical below Warning. The interface shows validation errors, and the backend validates API requests again before persisting changes."
},
"lxcDetection": {
"heading": "LXC Update Detection",
@@ -207,18 +207,18 @@
"whatRunsTitle": "What the scan actually runs",
"whatRunsIntro": "For each CT in <code>running</code> state with a supported package manager:",
"whatRunsItems": [
"<strong>Cache freshness gate.</strong> If the in-container apt/apk metadata cache is older than <strong>24 hours</strong>, a best-effort refresh runs first (<code>apt-get update -qq</code> on Debian/Ubuntu, <code>apk update</code> on Alpine) with a 60 s timeout. Any failure (no network, broken repo, timeout) is swallowed silently — the listing below still runs against whatever cache exists, so a transient repo issue can never make detection worse than before.",
"<strong>Metadata freshness.</strong> If the in-container apt/apk metadata cache is older than <strong>24 hours</strong>, a refresh is attempted first (<code>apt-get update -qq</code> on Debian/Ubuntu, <code>apk update</code> on Alpine), with a 60 s timeout. If it fails, listing still uses the available cache; results may therefore be stale.",
"<strong>Listing.</strong> Then ProxMenux runs <code>apt list --upgradable</code> / <code>apk list -u</code> and parses the output into a structured count plus a sample of the top package names.",
"<strong>Per-CT dedup.</strong> A fingerprint built from count, security-count and the sorted top names is stored so a stable set of pending updates doesn't re-notify daily, while a meaningfully different set does."
],
"selfUpdateTitle": "CTs that self-update outside apt may legitimately report 0",
"selfUpdateBody": "Detection only sees what the in-container package manager knows about. A CT whose key software updates itself outside apt (Plex's <code>plexupdate</code> cron, Docker containers updated via <code>docker pull</code>, Frigate's built-in updater, etc.) will keep reporting low or zero apt updates even when the appliance is actively staying current — that's correct, not a bug. The apt-level base system on the same CT may still have its own pending updates, which the scan does surface.",
"selfUpdateBody": "Detection only covers the in-container package manager. Software updated outside apt, such as a configured <code>plexupdate</code> job or Docker images fetched with <code>docker pull</code>, is outside that count. Zero apt updates does not prove that every application is current. The same CT’s base system can still have package updates detected by the scan.",
"refreshTitle": "Why the 24 h auto-refresh",
"refreshBody": "Long-running appliance CTs frequently end up with apt caches months out of date because nobody routinely runs <code>apt update</code> inside them. Without the refresh, <code>apt list --upgradable</code> reports 0 updates from a frozen snapshot and the operator never sees the backlog. The threshold matches the rest of the check cycle — if the CT was refreshed within the last 24 h, ProxMenux trusts that signal and skips the refresh.",
"refreshBody": "Long-running CTs can have stale apt metadata if nobody runs <code>apt update</code>. Then <code>apt list --upgradable</code> can miss newer updates. ProxMenux attempts a refresh when the metadata is older than 24 hours and skips it when the cache was refreshed more recently.",
"toggleTitle": "Conditional notification toggle",
"toggleBody": "The <code>lxc_updates_available</code> per-channel notification toggle in <strong>Notifications → Services</strong> only renders while detection is enabled. When you turn detection OFF, that row disappears from every channel's category list — but its stored preference is preserved in the DB, so re-enabling detection brings the toggle back at the value it had before.",
"purgeTitle": "What gets purged when you disable detection",
"purgeBody": "Turning the switch OFF immediately removes every <code>type=lxc</code> entry from <code>/usr/local/share/proxmenux/managed_installs.json</code>. The Hardware tab badges drop to zero on the next dashboard refresh. Turning it back ON repopulates the registry on the next detection cycle (or sooner if you trigger a manual refresh from the API)."
"purgeBody": "Turning the switch OFF immediately removes every <code>type=lxc</code> entry from <code>/usr/local/share/proxmenux/managed_installs.json</code>. LXC update counts in the VMs & LXCs tab clear on the next dashboard refresh. Turning it back ON repopulates the registry on the next detection cycle, or sooner with a manual API refresh."
},
"storageExclusions": {
"heading": "Remote Storage Exclusions",
@@ -238,9 +238,9 @@
"intro": "Same shape as Storage Exclusions but for network interfaces. Per interface: exclude from Health checks and / or exclude from notifications. Typical use cases:",
"items": [
"An intentionally-down spare bridge.",
"A NIC that was physically removed but still references in <code>/etc/network/interfaces</code>.",
"A NIC that was physically removed but is still referenced in <code>/etc/network/interfaces</code>.",
"A VLAN sub-interface used only during maintenance windows.",
"A management bridge that is up but doesn't carry traffic — flapping noisily on every cycle."
"A management bridge with known, repeated link-state changes during maintenance."
],
"outro": "State is persisted in the <code>excluded_interfaces</code> SQLite table. Same purple <em>excluded</em> badge on the <link>Network tab</link> so excluded interfaces stay visible."
},
@@ -255,26 +255,26 @@
},
"optimizations": {
"heading": "ProxMenux Optimizations",
"intro": "A live, transparent inventory of every ProxMenux post-install optimization currently active on the host. Every time you apply a post-install option from the Scripts side — either via the <autoLink>Automated post-install</autoLink> or via the à-la-carte <customLink>Customizable post-install</customLink> — the corresponding script registers itself in <code>/usr/local/share/proxmenux/installed_tools.json</code>. The Monitor reads that file and renders this card so you can see, at a glance, what's been changed on your server.",
"intro": "An inventory of post-install optimizations recorded by ProxMenux on the host. Options from <autoLink>Automated post-install</autoLink> and <customLink>Customizable post-install</customLink> register their application in <code>/usr/local/share/proxmenux/installed_tools.json</code>. The Monitor reads that registry for this card. A recorded entry is not a fresh check that every underlying setting remains unchanged.",
"imageAlt": "ProxMenux Optimizations card with grid of installed tools, each row showing a green dot, tool name and version. Examples include 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 with Legacy badge, Kernel Panic Configuration, Logrotate Optimization, Network Optimizations, Subscription Banner Removal, VFIO IOMMU Passthrough — 14 active total",
"imageCaption": "The card lists every active optimization with its name, version, a coloured dot and an orange <em>14 active</em> counter at the top right. Tools whose source is reachable are clickable.",
"dotsTitle": "What the dots mean",
"dotsItems": [
"<green/> <strong>Green dot</strong> — current optimization, registered by the active version of ProxMenux. Source code is reachable: click the row to open it.",
"<amber/> <strong>Amber dot + <em>legacy</em> badge</strong> — applied by an older ProxMenux version whose script has since been renamed or replaced. Still active on the host; the source opens in \"legacy\" mode (with an amber accent) so you can audit what was actually run."
"<green/> <strong>Green dot</strong> — a registered optimization that is not marked legacy and has no available update indicated. Click the row when source code is available.",
"<amber/> <strong>Amber dot + <em>legacy</em> badge</strong> — a registered optimization whose script was renamed or replaced. Its preserved source opens in legacy mode with an amber accent. This does not revalidate the current host configuration."
],
"clickTitle": "Click-through to source code",
"clickBody": "Clicking a tool opens a modal with the exact bash function that applied the change, plus the script file path it lives in (<code>auto_post_install.sh</code> for the Automated bundle, <code>customizable_post_install.sh</code> for the à-la-carte side). Comments and shell constructs are syntax-highlighted; a Copy button puts the source on your clipboard. This is the \"show your work\" surface — verify what ProxMenux did to your host before any manual change you make on top.",
"clickBody": "Clicking a tool opens a modal with its mapped bash function and script name (<code>auto_post_install.sh</code> or <code>customizable_post_install.sh</code>). Current tools are extracted from files on the host; legacy tools can use preserved source. Syntax highlighting and Copy help inspect the code. This is not a guaranteed snapshot of the exact code that ran at installation time.",
"detailAlt": "Tool source code modal for APT IPv4 Force showing the bash function force_apt_ipv4 from customizable_post_install.sh version 1.0 with syntax-highlighted code that configures /etc/apt/apt.conf.d/99-force-ipv4 with Acquire ForceIPv4 true, registers the tool and emits a translate APT IPv4 configuration completed message",
"detailCaption": "Source modal for <em>APT IPv4 Force</em> — exact <code>force_apt_ipv4()</code> function from <code>customizable_post_install.sh v1.0</code>, with syntax highlighting and a one-click Copy.",
"whyTitle": "Why this matters",
"whyBody": "ProxMenux changes things on your host: kernel parameters, repository configuration, network bits, log rotation, GPU passthrough, etc. Knowing exactly what's active is essential before you start adding manual customisation on top — and even more so if a different admin runs the host than the one who set it up. This card is the auditable record of every optimisation currently in effect, with the exact code that produced it.",
"whyBody": "ProxMenux can change kernel parameters, repository settings, networking, log rotation and GPU passthrough. Review the recorded optimizations before adding manual changes, especially when another administrator set up the host. The card shows registry entries and available source; it does not audit every live setting or preserve an exact execution history.",
"updatesTitle": "Updates available banner",
"updatesBody": "When a post-install optimization gets a newer version on disk than the one currently registered on the host, the card shows an \"Updates available\" banner at the top with the count and an <strong>Apply</strong> button. Clicking <strong>Apply</strong> opens a per-optimization picker (the same one available from the Post-Install menu's <em>Apply available updates</em> entry). Pick which optimizations to lift; ProxMenux re-runs the corresponding function and refreshes the version in the registry. When everything is current the banner disappears.",
"updatesAlt": "ProxMenux Optimizations card with an Updates available banner at the top — count of pending updates plus an Apply button that opens the per-optimization picker",
"updatesCaption": "The banner only renders when at least one optimization has a newer version on disk. See <link>Apply Available Updates</link> for the full update flow and the Path-A equivalent in the shell menu.",
"revertTitle": "Reverting an optimization",
"revertBody": "The card is read-only — to undo an optimization, run the corresponding <link>Uninstall Optimizations</link> option from the ProxMenux Scripts menu. The uninstall step removes the entry from <code>installed_tools.json</code>, so it disappears from this card on the next refresh."
"revertBody": "To undo an optimization, use the corresponding <link>Uninstall Optimizations</link> option in the ProxMenux Scripts menu. Uninstalling removes its entry from <code>installed_tools.json</code>, so the card stops listing it on the next refresh."
},
"dataCollected": {
"heading": "How the data is collected",
@@ -320,7 +320,7 @@
{
"card": "Optimization source-code modal",
"endpoint": "/api/proxmenux/tool-source",
"source": "Extracts the matching bash function from <code>auto_post_install.sh</code> or <code>customizable_post_install.sh</code> on the host."
"source": "Extracts the mapped bash function from <code>auto_post_install.sh</code> or <code>customizable_post_install.sh</code> on the host; legacy tools can use preserved source."
}
]
},
@@ -14,7 +14,7 @@
},
"thresholds": {
"title": "Status colours and thresholds applied here",
"intro": "Every bar, chip, and dot on this tab follows the same three-state classification — <green/> <strong>green</strong> below Warning, <amber/> <strong>amber</strong> from Warning to Critical, <red/> <strong>red</strong> at Critical and above. Recommended defaults shipped with ProxMenux:",
"intro": "Health Monitor classifies status as <green/> <strong>green</strong> below Warning, <amber/> <strong>amber</strong> from Warning to Critical, and <red/> <strong>red</strong> at Critical and above. Its recommended defaults follow. Individual dashboard bars can use different visual cutoffs, described below.",
"items": [
"<strong>Capacity</strong> (host disks, PVE storages, ZFS pools, LXC mounts) — Warning 85 %, Critical 95 %.",
"<strong>Disk temperature</strong> — HDD 60/65 °C · SSD 70/75 °C · NVMe 80/85 °C · SAS 55/65 °C (warning / critical)."
@@ -33,7 +33,7 @@
"localLabel": "Local Used",
"localWhat": "Bytes used on local storages (LVM / LVM-thin / ZFS / dir on the host's own disks). Shows the used bytes prominently, with a footer line of <em>X.XX % of Y TB</em> so you see the fill-percentage at the same time.",
"remoteLabel": "Remote Used",
"remoteWhat": "Same shape as Local Used but for remote storages (NFS / CIFS / PBS / Ceph / iSCSI). Counted separately because remote outages don't affect local data and you typically size and monitor them differently.",
"remoteWhat": "Same format as Local Used, for remote storages (NFS / CIFS / PBS / Ceph / iSCSI). Counted separately because local and remote failures have different scopes and these resources are typically sized and monitored differently.",
"disksLabel": "Physical Disks",
"disksIntro": "Two lines of breakdown for the inventory:",
"disksItems": [
@@ -45,9 +45,9 @@
"heading": "Proxmox Storage card",
"intro": "One row per storage configured in <code>/etc/pve/storage.cfg</code>. Each row shows the type badge (<code>nfs</code> / <code>cifs</code> / <code>zfspool</code> / <code>lvm</code> / <code>lvmthin</code> / <code>dir</code> / <code>pbs</code>), the storage name, an active / error / not-monitored badge, the usage percentage and a coloured progress bar:",
"items": [
"<strong>&lt; 75 %</strong> — blue progress bar, value in blue.",
"<strong>75 – 90 %</strong> — yellow progress bar, value in yellow (Health Monitor warns at this point).",
"<strong>> 90 %</strong> — red progress bar, value in red (Health Monitor escalates).",
"<strong>Up to 75 %</strong> — blue progress bar and value.",
"<strong>Above 75 % through 90 %</strong> — yellow progress bar and value. These are visual cutoffs, separate from Health Monitor thresholds.",
"<strong>> 90 %</strong> — red progress bar and value; this visual cutoff is separate from Health Monitor escalation.",
"<strong>error</strong> — full row outlined in red, used when the storage is configured but unreachable (NFS server down, CIFS creds expired).",
"<strong>excluded</strong> — purple outline + the badge \"not monitored\". Storages explicitly excluded by the user from health checks (handy for manual / archive volumes that are intentionally offline)."
],
@@ -70,7 +70,7 @@
"items": [
"<strong>Device path</strong> — <code>/dev/sda</code>, <code>/dev/nvme0n1</code>.",
"<strong>Type badge</strong> — SATA / NVMe (and the relevant icon).",
"<strong>System badge</strong> — orange tag that marks disks the host's OS is running from. The dashboard derives this from the mountpoints of <code>/</code> and <code>/boot</code>: any physical disk hosting them gets the <em>System</em> tag so you don't accidentally wipe or repurpose it. Disks without the tag are pure data drives.",
"<strong>System badge</strong> — orange tag for disks in use by the host: system mountpoints (<code>/</code>, <code>/boot</code>, <code>/usr</code>, <code>/var</code>…), active swap, ZFS pool members, LVM physical volumes, active RAID members or system partition labels. A missing tag does not prove a disk is safe to erase or repurpose.",
"<strong>Model</strong> — vendor + model string from <code>smartctl -i</code>.",
"<strong>Capacity</strong> — formatted human-readable.",
"<strong>Temperature</strong> — current °C, coloured by the disk-type threshold (NVMe runs warmer than SATA).",
@@ -96,7 +96,7 @@
"overviewItems": [
"<strong>Identity</strong> — model, serial, capacity, Health badge (Healthy / Warning / Critical).",
"<strong>Wear & Lifetime</strong> — large life-remaining ring (97 %, 50 %, …) with the source attribute spelled out (<em>Media Wearout Indicator</em>, <em>Percentage Used</em>, …), a wear bar (current consumption %), an <em>Est. Life</em> projection in years and the total Data Written. NVMe drives also show <em>Available Spare</em>.",
"<strong>SMART Attributes</strong> — six headline fields on a 2-column grid: Temperature, Power On Hours (with humanised duration like <em>3y 116d</em>), Rotation Rate (or <em>SSD</em>), Power Cycles, SMART Status, Reallocated Sectors, Pending Sectors, CRC Errors. The full attribute table lives in the SMART tab."
"<strong>SMART Attributes</strong> — key fields on a 2-column grid: Temperature, Power On Hours (with humanised duration like <em>3y 116d</em>), Rotation Rate (or <em>SSD</em>), Power Cycles, SMART Status, Reallocated Sectors, Pending Sectors, CRC Errors. The full attribute table lives in the SMART tab."
],
"smartTitle": "Tab 2 — SMART",
"smartImageAlt": "Disk drill-in modal — SMART tab with Run SMART Test buttons (Short / Extended), last-test result and the full SMART attribute table",
@@ -108,11 +108,11 @@
"<strong>SMART Attributes</strong> — the full attribute table (ID / name / value / worst / status with OK / warning / critical icons). For SATA / SAS, the classical numbered list. For NVMe, the structured fields from <code>nvme smart-log</code> (temperature, available spare, percentage used, data units written / read, host reads / writes, controller busy time, power cycles, unsafe shutdowns, media errors, error-log entries, warning / critical composite temperature time)."
],
"pdfTitle": "View Full SMART Report (PDF)",
"pdfIntro": "At the bottom of the SMART tab, the <strong>View Full SMART Report</strong> button generates a printable, archive-ready PDF — the same structured report you'd send to a vendor for an RMA.",
"pdfIntro": "At the bottom of the SMART tab, <strong>View Full SMART Report</strong> opens a printable report. Use the browser’s print dialog to save it as PDF for archiving or to share with vendor support for an RMA.",
"pdfPreviewAlt": "First page of the generated SMART Health Report PDF — Executive Summary with the PASSED ring + Disk Information block",
"pdfPreviewCaption": "First page of the SMART Health Report — Executive Summary with the PASSED ring and the full Disk Information block. The full PDF below has the SSD wear ring, every SMART attribute and the test history.",
"pdfDownloadLabel": "Download sample SMART report (PDF)",
"pdfSectionsIntro": "The report has five top-level sections:",
"pdfSectionsIntro": "The report includes these main sections:",
"pdfSections": [
"<strong>Executive Summary</strong> — large PASSED / FAILED verdict, plain-language disk health assessment paragraph (\"your disk is healthy / showing signs of wear / failing\"), and four quick stats (report timestamp, last-test type, test result, attributes checked).",
"<strong>Disk Information</strong> — model, serial, capacity, type (HDD / SSD / NVMe), family, form factor, interface (SATA 3.3 · 6.0 Gb/s, …), TRIM support, current temperature with the optimal threshold, power-on time, power cycles, SMART status, plus the headline counters (pending sectors, CRC errors, reallocated sectors).",
@@ -121,13 +121,13 @@
"<strong>Last Self-Test Result + Full Self-Test History</strong> — the latest test (type, result, completion message, at which power-on-hours mark) plus a numbered table of every retained test.",
"<strong>Recommendations</strong> — action items based on the verdict: <em>Disk is Healthy / Schedule periodic tests / Backup strategy</em> for healthy drives, escalating language with replacement guidance when attributes are out of range."
],
"pdfOutro": "The PDF is produced server-side and downloaded with a stable filename pattern (<code>SMART-&lt;short-id&gt;.pdf</code>) so multiple snapshots over time can sit side-by-side in your archive. Useful when you're tracking degradation across months or sending evidence to vendor support.",
"pdfOutro": "The browser builds the printable report; Print and Save as PDF both open its print dialog. Choose a filename such as <code>SMART-&lt;short-id&gt;.pdf</code> when saving. Keep dated snapshots to compare changes over time or share them with vendor support.",
"historyTitle": "Tab 3 — History",
"historyImageAlt": "Disk drill-in modal — History tab listing past SMART tests with download and delete actions",
"historyImageCaption": "History tab — every retained SMART test for this disk. Per row: type, timestamp, \"X days ago\" tag, latest marker, download (raw <code>smartctl</code> output) and delete actions.",
"historyIntro": "The retained pool of SMART tests for this disk — both short and extended runs that completed. Each entry is the raw <code>smartctl</code> output captured at run time, plus the structured fields the Monitor parsed out for the dashboard. Per-row actions:",
"historyItems": [
"<strong>Download</strong> — saves the raw <code>smartctl -a</code> output as a text file. Identical to what the PDF report parses, useful when you need the exact line a vendor asks for.",
"<strong>Download</strong> — saves that test's JSON snapshot (<code>smartctl -a --json</code> output, or <code>nvme smart-log</code> on NVMe when smartctl fails). Useful when vendor support needs the original diagnostic fields.",
"<strong>Delete</strong> — removes the test from history. The retention limit set in the Schedule tab (<em>Last 5 / 10 / 20</em>) deletes oldest-first automatically; this action is the manual override."
],
"scheduleTitle": "Tab 4 — Schedule",
@@ -154,7 +154,7 @@
"HDD — typically cooler thresholds.",
"SSD — moderate thresholds.",
"NVMe — higher thresholds (NVMe runs hotter by design).",
"SAS — same defaults as HDD."
"SAS — defaults of 55 °C warning and 65 °C critical, distinct from HDD’s warning threshold."
],
"tempConfigurable": "All four are configurable from <em>Settings → Health Monitor Thresholds</em>.",
"tempWhyTitle": "Why a history matters here",
@@ -164,7 +164,7 @@
"<strong>Threshold tuning.</strong> Before raising or lowering a threshold in <em>Settings → Health Monitor Thresholds</em>, the 30-day chart shows the disk's actual operating range so the new value lines up with what the hardware really does rather than a guess."
],
"obsTitle": "Observation history (across tabs)",
"obsIntro": "Modern disks fail gradually. A disk can report SMART <strong>PASSED</strong> and still log occasional read errors in dmesg, drop SATA links, or expose pending sectors that come and go. The standard Proxmox UI shows you the current SMART verdict — it does not keep a history of those <em>signals</em>. ProxMenux does, and surfaces them right inside the disk modal.",
"obsIntro": "Disk faults can develop gradually. A disk may report SMART <strong>PASSED</strong> while logging read errors in dmesg, losing SATA links or reporting intermittent pending sectors. ProxMenux keeps a history of these <em>signals</em> and shows it inside the disk dialog alongside the current SMART verdict.",
"obsImageAlt": "Disk Details modal Overview tab showing a healthy disk with SMART status Passed, 0 reallocated/pending/CRC errors, and an Observations section listing one recorded I/O Error event with the raw kernel message, a human translation of the ATA error code, first and last occurrence timestamps and an occurrence count",
"obsImageCaption": "A disk that <strong>SMART says is fine</strong> can still have an observation history. The card is the historical signal layer underneath the SMART verdict.",
"obsWhatTitle": "What an observation is",
@@ -177,8 +177,8 @@
],
"obsWhyTitle": "Why ProxMenux records and shows them",
"obsWhyItems": [
"<strong>Disk failure is rarely a single event.</strong> It usually starts with sporadic ATA bus errors, the odd UNC sector, or a couple of medium errors weeks before SMART flips to <em>FAILED</em>. Without persistence those early warnings disappear from dmesg on the next boot.",
"<strong>SMART can lie.</strong> A drive can show all attributes green and still be on the way out — the observation layer catches the symptoms SMART doesn't expose (especially ICRC, IDNF, link resets at lower SATA speeds).",
"<strong>Faults can develop over time.</strong> Sporadic ATA bus errors, UNC sectors or media errors may appear before SMART reports <em>FAILED</em>. A dmesg buffer alone does not preserve them across a reboot; the observation history does.",
"<strong>SMART does not rule out every fault.</strong> A drive can show green attributes while experiencing problems. Observations retain additional symptoms, including ICRC, IDNF and SATA link resets or speed reductions.",
"<strong>It separates \"is happening now\" from \"happened recently\".</strong> The Health Monitor auto-resolves transient errors as soon as they stop firing, which is great for keeping the active alert list clean — but you still want to see, days later, that this disk had three I/O errors that night. The observation table is the answer.",
"<strong>It feeds the tiered notification model.</strong> The disk_io detector reads observation rate from this table to decide silent / WARNING / CRITICAL (the sliding 24h window introduced in 1.2.1.2). The history is what makes that classification possible."
],
@@ -213,12 +213,12 @@
{
"section": "SMART current values",
"endpoint": "/api/storage/smart/<disk>",
"source": "<code>smartctl -A &lt;dev&gt;</code> — refreshed on demand, not cached."
"source": "<code>smartctl -A &lt;dev&gt;</code> is one available probe; the detail endpoint also uses full SMART JSON and NVMe-specific data."
},
{
"section": "SMART self-test history",
"endpoint": "/api/storage/smart/<disk>/history",
"source": "Stored under <code>/var/lib/proxmenux-monitor/smart/&lt;disk&gt;/</code> as JSON snapshots."
"source": "Stored under <code>/usr/local/share/proxmenux/smart/&lt;disk&gt;/</code> as JSON snapshots."
},
{
"section": "Permanent observations",
@@ -48,7 +48,7 @@
"<strong>Message</strong> — the full untruncated message in a monospace block, ready to copy."
],
"maxLevelStoreTitle": "Journald MaxLevelStore",
"maxLevelStoreBody": "On a fresh Proxmox install, journald defaults to <code>MaxLevelStore=warning</code>, which silently drops info-level messages. The Monitor detects this on startup and adds a drop-in (<code>/etc/systemd/journald.conf.d/proxmenux-loglevel.conf</code>) raising the threshold to <code>info</code> so the Logs tab actually has something to show across all severities.",
"maxLevelStoreBody": "On a fresh Proxmox install, journald defaults to <code>MaxLevelStore=warning</code>, which silently drops info-level messages. The Monitor detects this on startup and adds a drop-in (<code>/etc/systemd/journald.conf.d/proxmenux-loglevel.conf</code>) raising the threshold to <code>info</code> so informational and more severe messages are stored. This does not include debug messages.",
"backupsTitle": "Backups",
"backupsBody": "Proxmox task history filtered to backup-related entries. One row per task (<code>vzdump</code>, PBS transfers, Garbage Collect, Verify) with the status (OK / WARNINGS / ERROR), guest involved, source storage, duration and the UPID. Click a row to load the full task log via <code>GET /api/task-log/&lt;upid&gt;</code> — the same data Proxmox exposes through <em>Datacenter → Tasks</em>, scoped to backups.",
"notificationsTitle": "Notifications",
@@ -5,7 +5,7 @@
},
"header": {
"title": "Dashboard: System Overview tab",
"description": "The first tab the dashboard opens on. Four live metric cards across the top, the historical-metrics chart in the middle, and condensed storage / network panels at the bottom — all derived from the same APIs that drive the dedicated tabs.",
"description": "The tab the dashboard opens on by default. Four live metric cards across the top, the historical-metrics chart in the middle, and condensed storage / network panels at the bottom — all derived from the same APIs that drive the dedicated tabs.",
"section": "ProxMenux Monitor · Dashboard"
},
"readOnly": {
@@ -13,7 +13,7 @@
"body": "Nothing on this tab is a control surface — every panel is informational. Actions live in the dedicated tabs they link to: drill into Storage to manage disks, into VMs & LXCs to start / stop guests, into the Security tab to configure auth, and so on."
},
"captureAlt": "System Overview tab — four metric cards (CPU, Memory, Active VMs, Temperature), node metrics chart, and Storage / Network summary cards",
"captureCaption": "The System Overview tab — what the dashboard opens on. The four cards are live, the chart below is historical, and the two cards at the bottom summarise Storage and Network.",
"captureCaption": "The System Overview tab — the default landing tab. The four cards are live, the chart below is historical, and the two cards at the bottom summarise Storage and Network.",
"topRow": {
"heading": "Top row: live metric cards",
"intro": "Four cards in a 2×2 grid on mobile, single row on desktop. Each updates from <code>/api/system</code> every few seconds.",
@@ -102,9 +102,9 @@
"intro": "Each panel manages its own loading state (<code>loadingStates.cpu</code>, <code>loadingStates.storage</code>, …) so a slow source doesn't block the rest. While a panel is fetching, it shows a pulse-animated skeleton; failed fetches degrade gracefully — for example, a missing temperature sensor renders the card as <em>N/A</em> instead of an error.",
"items": [
"<strong>Top metric cards</strong> — refresh every ~5 s. The CPU and temperature panels also receive a 1 s push from the vital-signs sampler.",
"<strong>Node metrics chart</strong> — refresh every 30 s, or on timeframe change.",
"<strong>Node metrics chart</strong> — loads when opened and when the timeframe or language changes. When a retry is needed, it waits 60 s.",
"<strong>Storage card</strong> — refresh every 60 s. SMART data is cached longer (the Storage tab triggers a fresh read on demand).",
"<strong>Network card</strong> — refresh every 5 s on the active timeframe.",
"<strong>Network card</strong> — summary refreshes every 59 s and the traffic chart every 60 s on the active timeframe.",
"<strong>Manual refresh</strong> — the Refresh button in the header forces all panels to re-fetch immediately."
]
},
@@ -137,7 +137,7 @@
{
"card": "Refresh cadence",
"endpoint": "—",
"source": "CPU / network 5 s; storage / VMs 30 s; static info every 5 min. The Refresh button in the header forces an immediate re-fetch on every panel."
"source": "System data every 5 s; storage, VMs and network summary every 59 s. The Refresh button in the header forces an immediate re-fetch on every panel."
}
],
"codeComment1": "# Single call that backs the header pill",
@@ -165,7 +165,7 @@
{
"label": "Dashboard index",
"href": "/docs/monitor/dashboard",
"tail": " — the other eight tabs at a glance."
"tail": " — the other dashboard tabs at a glance."
},
{
"label": "Architecture",
@@ -100,7 +100,7 @@
"auth": {
"heading": "Authentication",
"items": [
"The WebSocket upgrade carries the JWT in the <code>Authorization</code> header. If auth is enabled and the token is missing or expired, the connection is rejected with HTTP 401 before a PTY is allocated.",
"The browser first requests a single-use ticket through <code>POST /api/terminal/ticket</code>, authenticated with a JWT in the <code>Authorization</code> header. It then passes that ticket when opening the WebSocket. The ticket expires after 5 seconds; with authentication enabled, a missing or invalid ticket closes the connection before a PTY is allocated.",
"If the Monitor sits behind a reverse proxy, the proxy must forward WebSocket upgrades. See the <link>Access & Authentication</link> page for Nginx / Caddy / Traefik snippets."
]
},
@@ -120,7 +120,7 @@
"headerFix": "Fix",
"rows": [
{
"cause": "Session JWT expired (24 h window).",
"cause": "Session JWT expired when opening or reconnecting a terminal (24 h window).",
"fix": "Refresh the page and log in again. The terminal isn't designed for unattended sessions, so the JWT lifetime matches the regular dashboard login."
},
{
@@ -1,16 +1,16 @@
{
"meta": {
"title": "ProxMenux Monitor — Dashboard: VMs & LXCs tab | ProxMenux Documentation",
"description": "The VMs & LXCs tab inventories every guest on the host with live CPU / memory / disk usage. Per-guest drill-in shows configuration, resources, backups, full guest logs, notes, and Start / Shutdown / Reboot / Stop controls."
"description": "The VMs & LXCs tab inventories every guest on the host with live CPU / memory / disk usage. Per-guest details show configuration, resources, backups, the console log of OCI containers, notes, and Start / Shutdown / Reboot / Force Stop controls."
},
"header": {
"title": "Dashboard: VMs & LXCs tab",
"description": "The full inventory of guests on the node. Four headline metrics across the top, a sortable list of every VM and LXC below, and a drill-in per guest with config, resources, backups, logs and the four lifecycle controls (Start / Shutdown / Reboot / Stop).",
"description": "The full inventory of guests on the node. Four headline metrics across the top, a sortable list of every VM and LXC below, and a drill-in per guest with config, resources, backups, the console log of OCI containers and the four lifecycle controls (Start / Shutdown / Reboot / Force Stop).",
"section": "ProxMenux Monitor · Dashboard"
},
"intro": {
"title": "The control surface for guests",
"body": "Other tabs are read-only; this is the one you act from. Anything that changes guest state goes through <code>POST /api/vms/&lt;vmid&gt;/control</code> with an explicit confirmation and the response is reflected back in the guest's row. There is no force-shutdown without going through the dedicated Stop button."
"body": "Use this tab to control guest lifecycles. Lifecycle actions go through <code>POST /api/vms/&lt;vmid&gt;/control</code>; Reboot and Force Stop ask you to type the VMID to confirm, and the response is reflected back in the guest’s row. Force shutdown requires the dedicated Force Stop button."
},
"topRow": {
"heading": "Top row: four stat cards",
@@ -186,9 +186,9 @@
"source": "PVE RRD data (<code>pvesh get /nodes/&lt;node&gt;/qemu/&lt;id&gt;/rrddata</code>) condensed to a chart-friendly shape."
},
{
"section": "Recent task logs (modal)",
"endpoint": "/api/vms/<vmid>/logs",
"source": "Tasks for that <code>vmid</code> from <code>/var/log/pve/tasks/index</code>."
"section": "OCI console log (Logs tab)",
"endpoint": "/api/lxc/<vmid>/console-log",
"source": "Console output of the image's main process, read from <code>/var/log/proxmenux/oci/&lt;vmid&gt;.console.log</code> on the host. Shown for OCI containers only."
},
{
"section": "Backups available for guest",
@@ -18,13 +18,13 @@
},
"howItWorks": {
"heading": "How it works",
"intro": "The Health Monitor runs on two parallel lanes inside the Monitor process. A lightweight <strong>vital signs sampler</strong> reads CPU, memory and temperature every few seconds so that sustained-threshold conditions are detected fast; in parallel, the <strong>full health cycle</strong> runs every five minutes and exercises every category from end to end. Both lanes converge into the same SQLite tables — and from there, three consumers read the state independently.",
"intro": "The Health Monitor uses two parallel threads inside the Monitor process. A lightweight <strong>vital signs sampler</strong> fills CPU, memory and temperature history buffers. The <strong>full health cycle</strong> reads those buffers, evaluates sustained conditions and runs the other checks approximately every five minutes, then writes findings to SQLite for the dashboard and notification flow.",
"scannerTitle": "From sample to stored finding",
"scannerCaption": "The scanner. Vital signs are sampled fast so sustained-CPU / sustained-memory pressure can be detected before the next 5-min cycle. The full cycle reads those buffers and runs the heavier checks (SMART, ZFS pool state, journal scanning, service health, etc.) before writing the structured findings to SQLite.",
"scannerCaption": "The sampler fills history buffers between health cycles: CPU usage every 5 s, memory every 30 s and temperature every 15 s. It does not evaluate alerts itself. The full cycle evaluates those buffers and runs heavier checks (SMART, ZFS pool state, journal scanning and service health) before writing findings to SQLite.",
"scannerArrowLabel": "step",
"scannerNodes": {
"samplerLabel": "Vital signs sampler",
"samplerDetail": "CPU usage 30 s\nMemory 30 s\nTemperature 15 s\n→ history buffers",
"samplerDetail": "CPU usage 5 s\nMemory 30 s\nTemperature 15 s\n→ history buffers",
"cycleLabel": "Full health cycle",
"cycleDetail": "Every 5 min\nReads buffers\n+ live probes\n(SMART, ZFS,\nservices, journal…)",
"checksLabel": "Per-category checks",
@@ -58,7 +58,7 @@
{
"category": "CPU & Temperature",
"checks": "CPU usage with hysteresis, sensor temperature",
"events": "High sustained load; CPU temperature crossing the vendor warning / critical thresholds."
"events": "Sustained high CPU usage; sensor-temperature warnings based on sampled readings."
},
{
"category": "Memory & Swap",
@@ -68,7 +68,7 @@
{
"category": "Storage",
"checks": "Proxmox storages, root filesystem",
"events": "Storage offline (NFS server unreachable, CIFS expired creds); root mount > 90 %; LVM thin pool nearing full."
"events": "Root or other monitored filesystems crossing configured space thresholds (85% warning / 95% critical by default); unavailable PVE storages; stale or unexpectedly read-only NFS/CIFS mounts; LVM-thin and other pool storages crossing the same thresholds."
},
{
"category": "Disks & SMART",
@@ -98,7 +98,7 @@
{
"category": "System Updates",
"checks": "Pending updates, security updates, kernel / PVE version, system age",
"events": "Security updates available; pinned kernel several minor versions behind; host uptime > 90 days. When updates are pending, the Overview header shows an <em>Update Now</em> button that runs the full ProxMenux update flow inline; on close it re-hits the health endpoint with <code>?refresh=1</code> so the badge count reflects the new state without waiting for the next 5-min cycle."
"events": "Pending security or running-kernel updates; a system not updated for a long time. The Updates category of the Health Status modal shows an <em>Update Now</em> button when updates are pending. It runs the full ProxMenux update flow inline; closing it refreshes health with <code>?refresh=1</code> so the badge reflects the new state without waiting for the next cycle."
},
{
"category": "Security & Certificates",
@@ -141,7 +141,7 @@
],
"infoNote": "A category that is <strong>OK</strong> but has dismissed events still inside their suppression window is rendered as <strong>INFO</strong> — to remind you that something is being silenced rather than that nothing was ever wrong.",
"unknownTitle": "UNKNOWN, when a check can't complete",
"unknownBody": "A check that fails to produce a verdict for three cycles in a row (a probe that times out, a sensor that disappeared, a tool that exits with an error) is recorded internally as <code>UNKNOWN</code>. The dashboard surfaces this as a yellow status — the overall view caps <code>UNKNOWN</code> at <strong>WARNING</strong> so it never escalates a healthy host to CRITICAL on its own."
"unknownBody": "An unavailable check returns <code>UNKNOWN</code>; after three consecutive such cycles, a persistent finding is recorded. The dashboard shows an unavailable check in yellow. The overall view caps <code>UNKNOWN</code> at <strong>WARNING</strong>, so an unavailable check alone does not make the host CRITICAL."
},
"dashboardView": {
"heading": "The dashboard view",
@@ -158,10 +158,10 @@
},
"dismiss": {
"heading": "Dismissing alerts and the Suppression Duration",
"intro": "Some events are noisy by nature — a <em>System Updates: pending updates available</em> stays true until you patch the host, and you don't want a notification every five minutes for a week. The <em>Update Now</em> button in the Overview header is the direct shortcut to resolve that specific case in place; for everything else, or when patching is deferred, the Health Monitor also offers two coupled silencing mechanisms:",
"intro": "Some events are noisy by nature — a <em>System Updates: pending updates available</em> stays true until you patch the host, and you don't want a notification every five minutes for a week. The <em>Update Now</em> button in the Updates category of the Health Status modal is the direct shortcut to resolve that specific case in place; for everything else, or when patching is deferred, the Health Monitor also offers two coupled silencing mechanisms:",
"step1": "<strong>Per-event Dismiss action</strong> in the modal. The Dismiss button opens a small dropdown with three options — <strong>24 hours</strong>, <strong>7 days</strong> or <strong>Permanently</strong> — letting you choose how long this specific alert stays silenced regardless of the category's default. Picking one calls <code>POST /api/health/acknowledge</code> with the <code>error_key</code> and the chosen <code>suppression_hours</code> (<code>-1</code> for permanent). The event moves to the Dismissed list with a timestamped <code>acknowledged_at</code>.",
"dropdownImageAlt": "Dismiss dropdown on a Health Monitor alert — 24 hours, 7 days or Permanently",
"dropdownImageCaption": "Per-event Dismiss dropdown. The chosen window applies to this single alert; if no per-event window is selected the category's default is used. Permanent dismisses are tagged with a distinct amber <em>Permanent</em> badge in the Dismissed list and never re-fire.",
"dropdownImageCaption": "Per-event Dismiss dropdown. The chosen window applies to this single alert; without a per-event choice the category default is used. Permanent dismissals have an amber <em>Permanent</em> badge and normally do not re-fire. The critical CPU-temperature override described below is an exception.",
"step2": "<strong>Per-category Suppression Duration setting</strong>. From the Settings → Health Monitor card (or <code>POST /api/health/settings</code>), each of the ten categories has its own default window applied when a Dismiss is fired without a per-event choice:",
"imageAlt": "Per-category Suppression Duration settings card in Settings → Health Monitor",
"imageCaption": "Suppression Duration card — one dropdown per category. Pick a longer window for noisy events (e.g. pending updates) and shorter for ones you want to re-evaluate quickly. Active Suppressions are listed underneath (see below).",
@@ -171,38 +171,38 @@
"autoTitle": "Auto-suppression when you change the Duration",
"autoBody": "Setting a category's Suppression Duration to anything other than the default 24 h has a second effect beyond user-initiated dismissals: <strong>future findings in that category enter the table already acknowledged</strong> with that duration. This is by design — if you've told the Monitor that you want disk-related events silenced for a week, brand-new disk findings honour that intent without you having to dismiss each one by hand. They appear directly in the Dismissed list with the configured remaining time. Categories left at 24 h are unaffected and behave the classic way (new findings land in Active until you act).",
"tempTitle": "CPU temperature CRITICAL is the safety override",
"tempBody": "One specific finding bypasses the suppression entirely: <strong>CPU temperature CRITICAL</strong>. If the sensor crosses the critical threshold, the alert re-fires regardless of any prior dismissal — a cooked CPU is a cooked CPU. This is the only built-in override of the dismiss model.",
"nonDismissableTitle": "Findings that cannot be dismissed",
"nonDismissableBody": "A handful of findings are flagged non-dismissable on purpose — they signal a condition where silencing the alert could cost data, hardware or connectivity. The Dismiss button is hidden for these rows; the alert clears only when the underlying condition recovers and the auto-resolve cleanup picks it up. Other findings (transient I/O events on a healthy disk, recovered states) are also marked non-dismissable but for the opposite reason: there's nothing to silence because the row is already informational and self-clearing.",
"tempBody": "The persistence layer has a special guard for a record marked <strong>CPU temperature CRITICAL</strong>: if such a record is received, it bypasses prior acknowledgment and auto-suppression. This guard does not mean that every temperature checker emits a critical record whenever a configured critical threshold is crossed.",
"nonDismissableTitle": "Which findings can be dismissed?",
"nonDismissableBody": "The modal shows Dismiss only when an individual check explicitly returns dismissable = true. A false or missing flag hides that button. Severity alone does not determine this permission: several critical checks allow acknowledgment. The examples below describe the current payloads; silencing an alert does not repair its cause.",
"headerFinding": "Finding",
"headerWhy": "Why it can't be dismissed",
"headerWhy": "Dismiss behavior",
"rows": [
{
"finding": "CPU temperature warning / critical",
"why": "Hardware risk — sustained over-temperature damages silicon. Silencing would let a cooking CPU run unnoticed."
"why": "The sampled sensor-temperature warning explicitly allows dismissal. A separate persistence guard bypasses acknowledgment if a CPU-temperature record arrives with CRITICAL severity."
},
{
"finding": "Filesystem space critical (root mount)",
"why": "Data loss risk — a full root prevents writes and corrupts state. The alert must remain visible until you free space."
"why": "Filesystem-space checks explicitly allow dismissal, including critical usage. Acknowledging the alert does not free space or remove the risk of failed writes."
},
{
"finding": "ZFS pool DEGRADED / FAULTED",
"why": "Data integrity risk — pool failure threatens every dataset on it. Silencing while the pool is unhealthy is never the right answer."
"why": "ZFS pool-state findings (DEGRADED, FAULTED, UNAVAIL) explicitly allow dismissal, as do pool-capacity checks. Acknowledgment does not repair a degraded or faulted pool."
},
{
"finding": "Disk I/O errors with SMART FAILED",
"why": "Drive failure confirmed by SMART — masking hides real hardware dying. The alert stays until the device is replaced (or removed from the host)."
"why": "Persisted journal-derived disk findings can allow dismissal. SMART FAILED still needs investigation; whether the button appears depends on the individual check flag, not on the alert text alone."
},
{
"finding": "Network interface DOWN",
"why": "Connectivity loss — bridges, bonds and physical interfaces with active traffic must stay visible. Silencing them would mask a remote-management outage."
"why": "Persisted interface-DOWN checks explicitly allow dismissal. This does not restore a bridge, bond or physical link, or recover remote access."
},
{
"finding": "I/O events on healthy disks (INFO)",
"why": "Transient ATA / dmesg events on a disk whose SMART says OK — flagged INFO and self-clearing. Nothing to dismiss because the next cycle already removes them."
"why": "Transient ATA or dmesg events with healthy SMART can be informational and self-clearing. Informational rows need not expose a Dismiss button; the checker determines when the condition is resolved."
}
],
"principle": "Everything else can be dismissed. The principle is: alerts that indicate \"real damage in progress\" or that have already self-resolved are kept off the dismiss path; alerts about sustained conditions you may want to acknowledge and re-check later (high CPU usage, pending updates, certificate near expiry, log warnings, VM startup hiccups, etc.) all expose the Dismiss button."
"principle": "Use the button shown for the actual finding, rather than inferring availability from its category or severity. Acknowledgment controls alert presentation and notifications; recovery checks and disk history remain separate."
},
"autoresolve": {
"heading": "Auto-resolution and cleanup",
@@ -283,13 +283,13 @@
"If the event type is <strong>enabled</strong> in the global notification settings, and the channel hasn't silenced this category, an event is queued.",
"The template engine renders a (title, body) pair from the structured details. If the AI rewriter is enabled, the same pair is also passed through the configured provider for a plain-language version.",
"The channel implementation ships it: Telegram message, Discord embed, Gotify push or email. The dispatch outcome is stored in <code>notification_history</code>.",
"If a dismiss arrives later, the suppression window kicks in and any further re-fires of the same <code>error_key</code> stay queue-side until the window closes."
"Dismissing an alert starts its suppression window. Further detections of the same <code>error_key</code> normally produce no new notification during that window; they are not automatically queued for delivery when it ends. The critical CPU-temperature override remains an exception."
],
"outro": "Channel configuration (Telegram bot token, webhook URLs, AI provider keys, per-event toggles, channel overrides) is documented in <notifLink>Notifications</notifLink> and <aiLink>AI Assistant</aiLink>."
},
"rest": {
"heading": "REST endpoints",
"intro": "Everything the modal does is callable from the API — handy for scripts, custom dashboards or your own chat-bot integration. Every call needs an API token; calls that change something — dismissing an alert, saving the suppression settings, cleaning up orphans — require one with full_admin scope, and a read_only token receives 403.",
"intro": "The modal actions are also available through the API for scripts, custom dashboards or chatbots. Calls need a valid bearer token, either from login or the API-token screen. Changes such as acknowledging alerts, saving suppression settings or cleaning orphan errors require full_admin scope; read_only receives 403.",
"headerEndpoint": "Endpoint",
"headerMethod": "Method",
"headerUse": "Use",
@@ -297,7 +297,7 @@
{
"endpoint": "/api/health",
"method": "GET",
"use": "Small health probe — returns JSON with <code>status</code>, <code>timestamp</code> and <code>version</code>. Suitable for Uptime Kuma keyword checks; the receiver must send the bearer header."
"use": "Lightweight health probe returning JSON with <code>status</code>, <code>timestamp</code> and <code>version</code>. Suitable for Uptime Kuma keyword checks; the client must send a bearer header."
},
{
"endpoint": "/api/health/status",
+5 -5
View File
@@ -40,7 +40,7 @@
},
{
"name": "VMs & Containers",
"description": "Inventory of all VMs and LXCs with status, resources and uptime. Drill-in shows config, historical metrics, full guest logs and start/stop/reboot/shutdown actions."
"description": "Inventory of VMs and LXCs with status, resources and uptime. The detail view shows configuration, historical metrics, Proxmox log downloads and start/stop/reboot/shutdown actions. Log availability is limited by the Proxmox endpoint; this is not a complete guest OS log archive."
},
{
"name": "Hardware",
@@ -52,7 +52,7 @@
},
{
"name": "Terminal",
"description": "Browser shell to the host or to any VM/CT, powered by <code>xterm.js</code> over WebSockets. Authenticated and audited like the rest of the API."
"description": "Browser shell for the host and supported VM/CT console access, powered by <code>xterm.js</code> over WebSockets. Sessions are not audited per command."
},
{
"name": "Security",
@@ -81,7 +81,7 @@
"intro": "Two access patterns are supported and the application detects which one is in use:",
"codeComment1": "# 1) Direct access on the host",
"codeComment2": "# 2) Via reverse proxy (Nginx / Caddy / Traefik)",
"afterCode": "When fronted by a reverse proxy, the Monitor honours <code>X-Forwarded-For</code>, <code>X-Forwarded-Proto</code> and <code>X-Forwarded-Host</code> so URLs and CORS behave correctly without manual configuration.",
"afterCode": "A reverse proxy should set <code>X-Forwarded-For</code>, <code>X-Forwarded-Proto</code> and <code>X-Forwarded-Host</code> appropriately and forward WebSocket upgrades. The browser uses its current origin for standard proxy ports. For backend client-IP handling, forwarded addresses are trusted only when PROXMENUX_TRUST_PROXY=1 is explicitly set; restrict direct access to the backend when enabling that trust.",
"footer": "First-launch setup, password + TOTP 2FA, and reverse-proxy snippets are covered in <link>Access & Authentication</link>."
},
"mobile": {
@@ -112,9 +112,9 @@
},
"api": {
"heading": "REST API and integrations",
"intro": "Everything the UI shows is available as JSON over HTTP/HTTPS. The same endpoints power Homepage widgets, Home Assistant sensors, Grafana dashboards (via the Prometheus exporter at <code>/api/prometheus</code>), Uptime Kuma probes and any custom script that speaks <code>curl</code>.",
"intro": "The dashboard’s REST endpoints expose monitoring data as JSON over HTTP/HTTPS for Homepage widgets, Home Assistant sensors, Uptime Kuma probes and custom scripts. Grafana can use the separate Prometheus text exporter at <code>/api/prometheus</code>. Requests can be made with <code>curl</code>.",
"tokens": "Long-lived API tokens (365 days) are generated from <strong>Settings → API Access Tokens</strong> or via <code>POST /api/auth/generate-api-token</code>.",
"bearer": "Tokens travel as <code>Authorization: Bearer …</code>. Public endpoints (<code>/api/health</code>, <code>/api/auth/*</code>) work without a token so external uptime probes can hit the host without handing out credentials.",
"bearer": "Send tokens as <code>Authorization: Bearer …</code>. <code>/api/health</code> also expects the bearer header, so uptime probes need a read_only token. Routes under <code>/api/auth/*</code> include both public setup/login/status routes and protected account/token management routes; they are not all anonymous.",
"catalog": "The full endpoint catalog, token rotation guidance and security best-practices live in <linkApi>API Reference</linkApi>; ready-made examples for Homepage, Home Assistant, Grafana, Uptime Kuma and a generic cURL pattern are in <linkIntegrations>Integrations</linkIntegrations>."
},
"serviceControl": {
+20 -20
View File
@@ -48,16 +48,16 @@
"multiTitle": "Multi-widget setup — system, storage, network",
"multiIntro": "For a richer view, render three separate cards backed by different endpoints — one for system metrics, one for storage, one for network. Use the same token in every card; it's the same Monitor instance.",
"multiCalloutTitle": "Multiple Proxmox hosts",
"multiCalloutBody": "Repeat the entry block per host to get the multi-card layout in the screenshot above — each entry points at the <code>http://&lt;host&gt;:8008</code> URL of its own ProxMenux Monitor instance. The token can be different per host (one secret entry per host) or shared, depending on how you generate them."
"multiCalloutBody": "Repeat the entry block for each host to get the multi-card layout shown above. Each entry uses the URL <code>http://&lt;host&gt;:8008</code> of that host’s Monitor instance. Generate and store a token for each host; separate installations have their own signing secrets, so a token from one host should not be assumed to work on another."
},
"homeAssistant": {
"heading": "Home Assistant",
"headingHref": "https://www.home-assistant.io",
"intro": "There is no native HACS integration for ProxMenux Monitor (yet) — but you don't need one. The built-in <code>rest</code> integration in Home Assistant can pull every endpoint documented in the <link>API Reference</link> and turn the responses into sensors, attributes and triggers. The complete reference build below exposes ~25 sensors covering system resources, the Health Monitor, VMs / CTs, storage, network, gateway latency and ProxMenux update status — drop the YAML into <code>configuration.yaml</code>, restart, and you have a full Proxmox observability layer inside HA.",
"intro": "These examples use Home Assistant’s built-in <code>rest</code> integration, so a custom HACS component is not required. It reads Monitor endpoints described in the <link>API Reference</link> and turns their responses into sensors and attributes for automations. The reference configuration below provides roughly 25 sensors for system resources, health, VMs/CTs, storage, network and ProxMenux updates. Add it to <code>configuration.yaml</code> and reload or restart HA.",
"imageAlt": "Home Assistant dashboard showing ProxMenux Monitor entities — health status badge, CPU / RAM / Temp gauges, VM count, storage usage and active errors counter",
"imageCaption": "ProxMenux Monitor as a first-class Home Assistant integration — sensors built from the YAML recipe below.",
"step1Title": "1 · Store the API token",
"step1Body": "Drop the token into Home Assistant's <code>secrets.yaml</code> so it never leaks into a config dump. The whole bearer prefix goes in one line — that lets the YAML reference it directly as a header value. Filename and location depend on your HA install (typically <code>/config/secrets.yaml</code> for HA OS / Container).",
"step1Body": "Store the token in Home Assistant’s <code>secrets.yaml</code> to keep it separate from the main configuration. Include the full Bearer prefix and token in one value so YAML can reference it as a header. This file is not encrypted and must also be kept private. Its location depends on the installation, typically <code>/config/secrets.yaml</code> on HA OS or Container.",
"step2Title": "2 · Drop in the REST configuration",
"step2Body": "Six REST blocks cover the full surface — one per major Monitor area. Each block has a sensible <code>scan_interval</code> tuned to how often the underlying data changes (system resources every 30 s, health every 60 s, slowly-changing inventories every 5-10 min). Paste into <code>configuration.yaml</code>:",
"step3Title": "3 · Add binary sensors and template helpers",
@@ -72,14 +72,14 @@
"viewTipBody": "Open the dashboard's 3-dot menu → <em>Raw configuration editor</em> and add a new view with this header (above the <code>cards:</code> list from the YAML above):",
"viewTipOutro": "That gives you a dedicated tab/view in your dashboard with its own icon and title, instead of one long card on an existing view.",
"altViewTitle": "Alternative — a dedicated dashboard view",
"altViewIntro": "If you'd rather have a full dedicated page (its own tab in the dashboard sidebar) than a single card inside an existing view, Home Assistant lets you create a new view directly with YAML. Steps:",
"altViewIntro": "To create a dedicated view tab inside an existing dashboard, rather than one card within another view, add a view with the YAML below. A view is a tab within a dashboard; it does not create a new sidebar dashboard entry. Steps:",
"altViewSteps": [
"Open the dashboard where you want the new tab.",
"Click the pencil (edit dashboard) at the top right.",
"Click the <em>+</em> tab at the end of the existing tabs to create a new view.",
"In the dialog that opens, switch to the <em>Code editor</em> tab (top right of the dialog — toggles between visual editor and YAML).",
"Paste the YAML below.",
"Save. The new <em>ProxMenux Monitor</em> tab appears in the sidebar with all cards rendered."
"Save. The new <em>ProxMenux Monitor</em> view appears as a tab inside the dashboard with its cards."
],
"twoEditorsTitle": "Two YAML editors in HA — pick the right one",
"twoEditorsIntro": "Home Assistant has two YAML editors that look similar but expect different formats:",
@@ -89,7 +89,7 @@
],
"twoEditorsOutro": "Pasting view-body YAML into the whole-dashboard editor (or vice versa) leaves you with a <em>Vista sin nombre</em> and <code>cards: []</code>. The YAML below is for the single-view editor — paste exactly as shown.",
"viewImageAlt": "Home Assistant dedicated view rendering ProxMenux Monitor — picture-entity header, glance KPIs, and System / VMs / Storage / Network entity cards laid out automatically by HA across multiple columns",
"viewImageCaption": "The dedicated <em>ProxMenux Monitor</em> view as Home Assistant renders it on a wide screen — HA's default layout splits the cards into multiple columns automatically.",
"viewImageCaption": "The dedicated <em>ProxMenux Monitor</em> view on a wide screen. A Masonry layout arranges the cards into columns automatically; the layout depends on the configured view type.",
"twoColTipTitle": "Want a fixed two-column layout instead of the auto layout?",
"twoColTipBody": "Replace any pair of cards (e.g. <em>System</em> + <em>VMs</em>, or <em>Storage</em> + <em>Network</em>) with a single <code>horizontal-stack</code> wrapping both, so they always render side by side regardless of screen width:",
"twoColTipOutro": "On mobile the row stays compressed; HA's auto layout (no horizontal-stack) reflows better at narrow widths.",
@@ -105,19 +105,19 @@
"In the Lovelace YAML, replace the <code>image:</code> URL with <code>/local/icons/proxmenux.svg</code>. Save and reload — the image renders from the local file, no internet needed."
],
"scanTipTitle": "scan_interval rule of thumb",
"scanTipBody": "<code>/api/system</code> is cheap to call — 30 s is fine. <code>/api/health/full</code> uses an internal 6-min cache, so polling it more often than ~60 s gains you nothing. <code>/api/storage/summary</code> changes slowly — every 5 min is plenty. <code>/api/proxmenux/update-status</code> only matters once an hour. Tune to your hardware budget if you have many sensors across many hosts."
"scanTipBody": "Polling <code>/api/system</code> every 30 s is a reasonable starting point. <code>/api/health/full</code> normally reads a background result valid for up to 6 min; polling every 60 s does not bypass that cache. Try 5 min for <code>/api/storage/summary</code> and an hour for <code>/api/proxmenux/update-status</code>. Adjust intervals for your hardware and number of hosts."
},
"grafana": {
"heading": "Prometheus + Grafana",
"promHref": "https://prometheus.io",
"grafanaHref": "https://grafana.com",
"intro": "ProxMenux Monitor exposes a Prometheus-format scrape endpoint at <code>GET /api/prometheus</code> (authenticated) returning OpenMetrics text. Wire it into Prometheus, then build a Grafana dashboard on top — same data the dashboard UI shows, in the format your TSDB expects.",
"intro": "ProxMenux Monitor exposes <code>GET /api/prometheus</code>, returning Prometheus text exposition format 0.0.4. It requires a bearer token when Monitor authentication is enabled. Configure Prometheus to collect it, then use Grafana to visualize the metrics in your time-series database.",
"imageAlt": "Grafana dashboard rendering ProxMenux Monitor metrics — CPU usage gauge, memory usage timeseries, running VMs count, network throughput",
"imageCaption": "A basic Grafana dashboard built from the ProxMenux Prometheus scrape — CPU, memory, running VMs, network throughput. The full metric catalogue lives in the <link>API Reference → Prometheus metrics</link>.",
"step1Title": "1 · Add the scrape job to Prometheus",
"step1Body": "Pass the API token via Prometheus' native <code>authorization</code> block (cleaner than custom headers and works with secret stores):",
"step1After": "Reload Prometheus (<code>kill -HUP</code> or <code>systemctl reload prometheus</code>, or <code>docker compose restart prometheus</code> if you run it as a container) and check <em>Status → Targets</em> — the proxmenux job should turn green within one scrape interval. Each metric carries a <code>node=\"&lt;hostname&gt;\"</code> label so you can distinguish hosts in queries.",
"tokenTipTitle": "Token via file or env, not inline",
"step1After": "Reload Prometheus with <code>kill -HUP &lt;PID&gt;</code> (replace PID with the Prometheus process ID), <code>systemctl reload prometheus</code> if supported by your service, or <code>docker compose restart prometheus</code> for a container. Check <em>Status → Targets</em>: the proxmenux job should become UP within one collection interval. Monitor metrics carry a <code>node=\"&lt;hostname&gt;\"</code> label to distinguish hosts.",
"tokenTipTitle": "Keep the token in a separate file",
"tokenTipBody": "For production deployments avoid inlining the token. Prometheus supports <code>credentials_file: /etc/prometheus/secrets/proxmenux.token</code> as an alternative — keep the token in a 0600 file and let Prometheus read it.",
"step2Title": "2 · Verify the scrape with a couple of queries",
"step2Body": "Before configuring Grafana, confirm Prometheus actually has the data. Open Prometheus' own UI at <code>http://&lt;prometheus-host&gt;:9090</code>, click <em>Query</em> and run any of these — you should get back live numbers from your Proxmox host:",
@@ -142,9 +142,9 @@
}
],
"calloutTitle": "The 401 you may see when clicking the endpoint URL is fine",
"calloutBody": "On the <em>Status → Targets</em> page, clicking the endpoint link (<code>/api/prometheus</code>) makes your browser fetch it directly — without the bearer header that Prometheus uses for its own scrapes. So you'll see <code>'{'\"error\":\"Authentication required\"'}'</code>. That confirms the API is properly protected; Prometheus itself authenticates correctly because it has the token from the scrape config. Trust the green <em>State: UP</em>, not the click-through.",
"calloutBody": "With Monitor authentication enabled, clicking the endpoint link on <em>Status → Targets</em> fetches <code>/api/prometheus</code> in the browser without Prometheus’s bearer header. The response can contain <code>'{'\"error\":\"Authentication required\"'}'</code>. Check the target’s actual <em>State: UP</em> to confirm that Prometheus itself is collecting successfully with its configured token.",
"step3Title": "3 · Add Prometheus as a Grafana data source",
"step3Body": "In Grafana: <em>Connections → Data sources → Add new → Prometheus</em>. Set the URL to your Prometheus instance (e.g. <code>http://prometheus.lan:9090</code>), save and test. No extra auth needed at this layer — Prometheus has already authenticated to ProxMenux.",
"step3Body": "In Grafana, open <em>Connections → Data sources → Add new → Prometheus</em>. Set the Prometheus URL, for example <code>http://prometheus.lan:9090</code>, then save and test. If your Prometheus server requires authentication, configure that separately here. The Monitor API token belongs in the Prometheus collection job.",
"step4Title": "4 · Build panels with these PromQL queries",
"step4Body": "A starter set that maps directly to what users typically watch on a Proxmox host:",
"headerPanel": "Panel idea",
@@ -200,7 +200,7 @@
"uptimeKuma": {
"heading": "Uptime Kuma and other status checkers",
"href": "https://github.com/louislam/uptime-kuma",
"intro": "For external probes, use <code>GET /api/system-info</code> — it is the one endpoint that works without a token, returning a small JSON payload with hostname, uptime and the overall health status (mapped to <code>healthy</code> / <code>warning</code> / <code>critical</code>). That's exactly what a keyword-based monitor needs.",
"intro": "For a keyword-based check, use <code>GET /api/system-info</code>. This route has no token decorator and returns hostname, uptime and a health status mapped to <code>healthy</code>, <code>warning</code> or <code>critical</code>. It is a public probe, unlike the authenticated detailed health endpoints.",
"kumaTitle": "Uptime Kuma — HTTP keyword monitor",
"kumaSteps": [
"In Uptime Kuma, click <em>+ Add New Monitor</em>.",
@@ -209,22 +209,22 @@
"URL: <code>http://pve01.lan:8008/api/system-info</code>.",
"Keyword: <code>healthy</code> (the value of <code>health.status</code> when the host is OK).",
"Heartbeat Interval: 60 seconds is enough.",
"Save. No headers needed — the endpoint is public."
"Save. This system-info route does not require a bearer header."
],
"healthchecksTitle": "healthchecks.io / cron-style pings",
"healthchecksBody": "Same endpoint, same shape — point your cron-style ping at <code>/api/system-info</code> and assert <code>.health.status == \"healthy\"</code>. Most of these services accept a 2xx HTTP status as the \"up\" signal too, in which case even a curl without parsing is enough.",
"healthchecksBody": "A cron job can query <code>/api/system-info</code> and test <code>.health.status == \"healthy\"</code>. Only after a successful health test should it send a success ping to the check’s unique Healthchecks.io URL. Healthchecks.io receives pings from jobs; it does not poll the Monitor URL. An HTTP 2xx response alone does not prove that the reported host health is good.",
"richTitle": "Want richer health data",
"richBody": "For the full state (the ten Health Monitor categories + active errors + dismissed list), use <code>GET /api/health/full</code> instead — that one needs an API token but gives you everything the dashboard modal renders in a single response."
"richBody": "For the full state — ten health categories, active errors and dismissed items — use <code>GET /api/health/full</code>. It returns the dashboard modal’s data in one response and needs a bearer token when Monitor authentication is enabled."
},
"workflows": {
"heading": "n8n, Zapier and custom scripts",
"intro": "For workflow tools and ad-hoc scripts that need to <em>raise</em> notifications through the Monitor (a CI failure, a smart-home sensor, a cron job that ran too long), the recipe is one POST to <code>/api/notifications/send</code>. The event flows through the same dispatch pipeline as anything emitted internally — dedup, cooldown, optional AI rewrite, fan-out to the configured channels.",
"n8nBody": "In n8n, the equivalent is an <em>HTTP Request</em> node with method POST, the URL above, an <em>Authorization</em> header set to <code>Bearer '{''{'$credentials.proxmenux.token'}''}'</code> (using n8n credentials), and a JSON body matching the curl payload. Wire any preceding node as the trigger (cron, webhook, condition).",
"severityBody": "Severity values are <code>INFO</code>, <code>WARNING</code> or <code>CRITICAL</code> (uppercase). The <code>data</code> payload is free-form JSON — the AI rewriter, when enabled, will pull anything useful from it for the rendered body. Full event-type semantics live in <link>Notifications → Event catalogue</link>."
"intro": "Workflow tools and scripts can <em>send</em> notifications through a POST to <code>/api/notifications/send</code>, for example after a CI failure or an overlong cron job. This is a direct send: it bypasses the event queue and fingerprint cooldown. It still uses channel formatting, optional AI rewriting and delivery to configured channels. Apply any required duplicate control in the caller.",
"n8nBody": "In n8n, use an <em>HTTP Request</em> node with POST, the URL above and the same JSON body as curl. Choose generic Header Auth credentials: set the header name to <em>Authorization</em> and its value to <code>Bearer YOUR_API_TOKEN</code>, replacing the placeholder. Connect a schedule, webhook or other preceding node to trigger the request.",
"severityBody": "Severity values are <code>INFO</code>, <code>WARNING</code> or <code>CRITICAL</code> in uppercase. The <code>data</code> object supplies event context and template fields. On this endpoint, AI rewriting receives only the title and message; fields in <code>data</code> are not sent to the provider. See <link>Notifications → Event catalogue</link> for event semantics."
},
"pveWebhook": {
"heading": "Native Proxmox VE webhook (inbound)",
"intro1": "Proxmox VE 8.1+ has its own notification system. ProxMenux Monitor registers itself as a webhook target so that everything PVE emits on its own (HA fencing, replication, vzdump from the GUI, certificate renewal) lands in the same dispatch pipeline as the Monitor's own events. This happens automatically when you press <em>Enable Notifications</em> on the Settings tab — no integration work required on the user side.",
"intro1": "The PVE notification system was introduced in 8.1; native webhook targets require Proxmox VE 8.3 or later. Enabling notifications with <em>Enable Notifications</em> in Settings attempts to register the Monitor as a target. PVE notifications routed to that target, such as backup or replication reports, then enter the Monitor’s dispatch flow. Setup depends on the notification configuration being writable and available.",
"intro2": "Mechanics, the body template PVE sends, the entries written to <code>/etc/pve/notifications.cfg</code>, and behaviour in clusters are documented in <link>Notifications → PVE webhook integration</link>."
},
"whereNext": {
+36 -36
View File
@@ -25,7 +25,7 @@
"sourcesLabel": "Sources",
"sourcesDetail": "Health Monitor\nJournal watcher\nTask watcher\nPVE webhook hook\nPolling collector\nIn-process emitters",
"dispatchLabel": "Dispatch pipeline",
"dispatchDetail": "Per-event toggle\nFingerprint dedup\nCooldown\nBurst aggregation",
"dispatchDetail": "Burst aggregation\nFingerprint / cooldown checks\nGroup rate limits\nPer-channel controls",
"aiLabel": "AI rewrite (opt.)",
"aiDetail": "OpenAI / Anthropic\nGemini / Groq\nOpenRouter / Ollama\n(off by default)",
"channelsLabel": "Channels",
@@ -40,7 +40,7 @@
"stepsIntro": "Pressing the button does three things in sequence:",
"steps": [
"Flips the panel to its <em>Active</em> state and unfolds the channel form below.",
"Registers a Proxmox VE webhook target in <code>/etc/pve/notifications.cfg</code> pointing at <code>POST http://127.0.0.1:8008/api/notifications/webhook</code>. From this moment on, anything Proxmox VE emits on its own (HA, replication, vzdump from the GUI) flows into the same pipeline as the Monitor's own events. See <pvelink>PVE webhook integration</pvelink> below for the full mechanics.",
"Registers a Proxmox webhook target in <code>/etc/pve/notifications.cfg</code>. Without Monitor HTTPS, it uses <code>POST http://127.0.0.1:8008/api/notifications/webhook</code>; with HTTPS enabled, it uses the HTTP loopback listener on port 8009. PVE notifications then enter the Monitor’s dispatch process. See <pvelink>PVE webhook integration</pvelink> below.",
"Starts the dispatch background thread. The thread polls the event queue and walks every event through the pipeline diagrammed above."
],
"activeAlt": "Notifications card after enabling — Active badge, channel tabs, Display Name field and Advanced AI Enhancement collapsible section",
@@ -48,7 +48,7 @@
},
"sources": {
"heading": "Event sources",
"intro": "Six independent collectors feed the notification engine. They run as background threads inside the Monitor process and emit a structured <code>NotificationEvent</code> every time something happens.",
"intro": "Six source types feed the notification engine: background collectors, the webhook receiver and direct emitters inside the process. They produce structured <code>NotificationEvent</code> objects.",
"headerCollector": "Collector",
"headerWatches": "Watches",
"headerEvents": "Typical events",
@@ -70,7 +70,7 @@
},
{
"collector": "Proxmox webhook hook",
"watches": "Listens on <code>POST /api/notifications/webhook</code>. Proxmox VE 8.1+ pushes its own notifications here once the integration is set up (see <pvelink>below</pvelink>).",
"watches": "Receives <code>POST /api/notifications/webhook</code>. PVE versions with webhook notification targets can forward their notifications here after setup (see <pvelink>below</pvelink>).",
"events": "Anything PVE emits — including events the Monitor would otherwise miss (HA, replication, vzdump from the GUI)."
},
{
@@ -156,7 +156,7 @@
"intro": "Email is the most flexible channel — and the one with the most fields. You need an SMTP server, a port, a TLS mode, optionally a username and password, a sender address and at least one recipient.",
"imageAlt": "Email channel form with SMTP Host, Port, TLS Mode dropdown, Username, Password, From Address, To Addresses comma-separated and Subject Prefix fields",
"imageCaption": "Email — SMTP host / port / TLS mode, optional username + password, sender address, comma-separated recipients and a subject prefix to make alerts easy to filter inbox-side.",
"appNote": "If you use a personal Gmail or Microsoft 365 account, the password field cannot be your normal account password — both providers require an <strong>app password</strong> generated specifically for third-party clients. The two flows are below.",
"appNote": "The Monitor uses password-based SMTP authentication. Gmail may require an <strong>app password</strong>. Microsoft support depends on the service and tenant policy; an app password does not override a ban on Basic authentication. Verify that your SMTP service permits this method.",
"gmailTitle": "Gmail app password",
"gmailIntro": "Gmail app passwords require <strong>2-Step Verification</strong> to be active on the Google account. If it isn't, the <em>App passwords</em> page won't exist.",
"gmailItems": [
@@ -166,15 +166,15 @@
"Fill the Email tab with: <em>Host</em> <code>smtp.gmail.com</code>, <em>Port</em> <code>587</code>, <em>TLS Mode</em> <code>STARTTLS</code>, <em>Username</em> your Gmail address, <em>Password</em> the 16-character app password."
],
"outlookTitle": "Microsoft / Outlook app password",
"outlookIntro": "Microsoft now requires <strong>two-step verification</strong> on the personal account before an app password can be created. Enterprise tenants where the admin has disabled SMTP basic auth need a different path (OAuth2) which is not currently supported by the Monitor — point those at an SMTP relay you control instead.",
"outlookIntro": "Microsoft app passwords require <strong>two-step verification</strong>, but their availability does not guarantee SMTP compatibility. Where the service or tenant requires OAuth2, the Monitor’s password-based SMTP client cannot authenticate. Use an SMTP relay that supports the required upstream authentication.",
"outlookItems": [
"Open <a>account.microsoft.com/security</a> and enable two-step verification.",
"Open <em>Advanced security options</em>, scroll to <em>App passwords</em> and click <em>Create a new app password</em>.",
"Microsoft shows a long random password — copy it.",
"Fill the Email tab with: <em>Host</em> <code>smtp-mail.outlook.com</code>, <em>Port</em> <code>587</code>, <em>TLS Mode</em> <code>STARTTLS</code>, <em>Username</em> your Outlook / Microsoft 365 address, <em>Password</em> the generated app password."
"If your account offers <em>Advanced security options</em> → <em>App passwords</em>, choose <em>Create a new app password</em>. This option alone does not establish that your mail service accepts password-based SMTP.",
"If Microsoft generates an app password, copy it and verify that your SMTP service accepts it.",
"Only if your provider permits password-based SMTP, fill in its approved settings: <em>SMTP host</em> <code>smtp.office365.com</code> for Exchange Online, <em>Port</em> <code>587</code>, <em>TLS mode</em> <code>STARTTLS</code>, <em>Username</em> your mailbox address, and <em>Password</em> the permitted SMTP credential. Personal Outlook.com settings and authentication requirements are different; do not assume these credentials will work."
],
"relayTitle": "Self-hosted SMTP relay",
"relayBody": "If you run your own SMTP relay (Postfix, msmtp, etc.) on the LAN, point the Monitor at it and skip the app-password dance entirely. The relay handles auth upstream and the Monitor sends in cleartext on a trusted network."
"relayBody": "Point the Monitor at an SMTP relay you control, such as Postfix. The relay handles upstream authentication. Configure the Monitor’s authentication and TLS mode to match the relay; using a local relay does not itself disable encryption."
},
"pushover": {
"heading": "Pushover",
@@ -223,10 +223,10 @@
"richHeader": "Rich — Rich messages on",
"richOutro": "The toggle is per-channel: leave Email plain for inbox-rule readability while letting Telegram and Discord render the rich version. Channels that don't support inline formatting (plain-text email, Gotify) ignore the formatting and fall back to text either way.",
"togglesTitle": "Per-event categories",
"togglesIntro": "Around seventy event types are grouped into eleven UI categories. Each event has a master toggle and a per-channel override — two layers that decide whether a given event reaches a given channel:",
"togglesIntro": "Each channel independently controls categories and individual event types. Turning a category off suppresses its events for that channel. Individual event toggles apply within enabled categories; there is no global master-event filter in the dispatcher.",
"togglesItems": [
"<strong>Per-event master toggle.</strong> If <code>vm_start</code> is off everywhere, no channel ever sees a <code>vm_start</code>. Toggles persist as <code>event_toggles[event_type] = true | false</code>.",
"<strong>Per-channel overrides.</strong> An event type can also be muted for a specific channel (<em>\"send <code>backup_complete</code> to Discord but not to Telegram\"</em>). These live in <code>channel_overrides[channel_name][event_type]</code> and only apply if the event passed the master toggle."
"<strong>Per-channel category toggle.</strong> For example, disabling the VM/CT category suppresses <code>vm_start</code> and its peers for that channel. Category preferences are stored as <code>&lt;channel&gt;.events.&lt;group&gt;</code>.",
"<strong>Per-channel event toggle.</strong> Within an enabled category, you can choose <em>send <code>backup_complete</code> to Discord but not Telegram</em>. Individual preferences are stored as <code>&lt;channel&gt;.event.&lt;event_type&gt;</code>."
],
"togglesOutro": "Each category header in the screenshot also shows the count of events <em>currently enabled</em> / <em>total</em> for that group, and a category-level toggle that flips every event inside it on or off in one click — the shortcut for muting a whole group (e.g. all <code>info</code> backups, all update-related events) without expanding the section."
},
@@ -238,7 +238,7 @@
"purposeTitle": "What it is for",
"purposeItems": [
"<strong>Don't wake me at 03:00 for an update notice.</strong> Backups, app updates, post-install optimisations and other INFO-level events stop pinging your phone at night.",
"<strong>But still wake me for a fire.</strong> Disk failures, OOM kills, host shutdowns, fail2ban bans — anything classified as CRITICAL — bypass the window and arrive immediately.",
"<strong>Critical events still arrive.</strong> Events actually classified as CRITICAL bypass Quiet Hours. The event name alone does not make it critical: the journal watcher emits Fail2Ban blocks and host shutdown/reboot notices as INFO, so those can be buffered.",
"<strong>Don't miss anything either.</strong> The events suppressed during the window aren't silently dropped — they sit in a SQLite buffer until you're back on the clock."
],
"howTitle": "How it works",
@@ -251,11 +251,11 @@
"<strong>Across restarts.</strong> If the Monitor restarts mid-window, the buffer is intact on disk. If the restart happens just after the window closed, the next dispatch cycle detects the pending rows and flushes them with a single \"recovery\" summary — no notifications are lost to a deploy or a reboot."
],
"criticalTitle": "What counts as CRITICAL",
"criticalBody": "Severity is set at event creation, not at dispatch time. Disk failures, OOM kills, cluster split-brain, host shutdowns and the \"hard\" tier of disk I/O errors ship as CRITICAL by design. Everything else (backups OK, updates available, INFO logs, rate-limit hits) defaults to INFO or WARNING and is therefore quietable. You can verify a given event's default severity in the <link>Event catalogue</link> further down this page."
"criticalBody": "The producer sets the severity when creating each event. A disk, shutdown or security event is not automatically CRITICAL because of its name. For example, the journal watcher emits ip_block, system_shutdown and system_reboot as INFO. The <link>Event catalogue</link> lists the event types; inspect the producer and the received event for its actual severity."
},
"digest": {
"heading": "Daily digest of INFO events",
"intro1": "The Daily Digest is the opposite knob: an <strong>opt-in</strong> setting that says \"don't send me every successful backup or update notice as it happens — collect them and send me one summary per day at 09:00 (or whatever hour I choose)\". Same goal as Quiet Hours (less noise) but a different mechanism (time-based summary instead of a daily window).",
"intro1": "The Daily Digest is an <strong>opt-in</strong> setting that collects eligible INFO notices, such as available updates, into one summary at 09:00 or another chosen time. Backup and replication results and live-action events are exempt. Quiet Hours instead delays non-critical messages during a daily window.",
"intro2": "It lives in the same channel-settings card as Quiet Hours (see the figure under <link>Quiet Hours</link>), right underneath. You enable each one independently.",
"purposeTitle": "What it is for",
"purposeItems": [
@@ -266,7 +266,7 @@
"howItems": [
"<strong>Per-channel opt-in.</strong> Off by default — Telegram doesn't silently batch your alerts. You enable it on the channels where you want a digest, leaving others on live delivery.",
"<strong>Delivery time</strong> in your local timezone. Defaults to 09:00 but you can pick any time; the dispatcher fires the digest within ~60 s of that minute.",
"<strong>What goes into the digest:</strong> any event the channel would have received live whose severity is <strong>INFO</strong>. Examples — <em>vzdump complete</em>, <em>Tailscale update available</em>, <em>ProxMenux optimisation update available</em>, <em>APT security updates pending</em>, <em>rate-limit hit</em>.",
"<strong>Included in the digest:</strong> eligible generic events with severity <strong>INFO</strong>. Examples include <em>application update available</em>, <em>Tailscale update available</em>, <em>ProxMenux optimisation update available</em> and <em>APT security updates pending</em>. Backup results and other exempt action events remain live.",
"<strong>What is never delayed:</strong>",
"<strong>Persistence.</strong> Pending events sit in a SQLite table (<code>digest_pending</code>) until the configured hour. The Monitor can restart freely without losing what the digest will eventually contain.",
"<strong>Empty days are silent.</strong> If nothing INFO-level happened, no digest is sent — the channel stays quiet rather than receiving a \"no events to report\" message."
@@ -274,10 +274,10 @@
"neverDelayedSub": [
"<strong>CRITICAL</strong> events always go through immediately.",
"<strong>WARNING</strong> events always go through immediately.",
"Live-action events (VM/CT start / stop / shutdown / restart, vm_fail / ct_fail, backup start / fail, replication start / fail, host shutdown / reboot) bypass the digest even at INFO severity — you opted in to see those live, the digest would defeat that opt-in."
"Live-action events — VM/CT start, stop, shutdown, restart and failure; backup start and results; replication results; host shutdown and reboot — bypass the digest even at INFO severity. Quiet Hours can still delay non-critical events."
],
"comboTitle": "Combining Quiet Hours and Daily Digest",
"comboBody": "The two work together. A channel can have <em>both</em> active — Quiet Hours from 22:00 to 07:00 plus a Daily Digest at 09:00. INFO events during the quiet window go to the quiet buffer and arrive at 07:00 as the close-of-window summary; INFO events during the day go to the digest buffer and arrive at 09:00 the next morning. CRITICAL and WARNING always cut through both. Choose Quiet Hours when the goal is a <em>window of silence</em>, the Daily Digest when the goal is a <em>fixed-time summary</em>; many setups want both."
"comboBody": "A channel can have <em>both</em> enabled: Quiet Hours from 22:00 to 07:00 and a Daily Digest at 09:00. Non-critical events during Quiet Hours enter its buffer and are released in the 07:00 summary. Eligible INFO events outside that window enter the digest. CRITICAL bypasses both; WARNING bypasses the digest but still waits during Quiet Hours. Choose a <em>window of silence</em>, a <em>fixed-time summary</em>, or both."
},
"displayName": {
"heading": "Display Name",
@@ -288,23 +288,23 @@
},
"dispatch": {
"heading": "Dispatch pipeline",
"intro": "Between an event being raised and a message leaving the host, three stages run in this order:",
"intro": "The table describes three related mechanisms. The actual flow begins with burst aggregation, then delivery-claim/cooldown checks and group rate limiting, followed by rendering and per-channel delivery controls:",
"headerStage": "Stage",
"headerWhat": "What it does",
"headerTunable": "Tunable?",
"rows": [
{
"stage": "1. Fingerprint dedup",
"stage": "Fingerprint deduplication",
"what": "Each event is hashed into a fingerprint (<code>event_type + key fields from data</code>). Identical fingerprints inside a short window are considered duplicates of the first one.",
"tunable": "No — internal dispatcher logic."
},
{
"stage": "2. Cooldown",
"what": "After a fingerprint is sent, the same fingerprint is suppressed for the per-severity cooldown duration. Stored in the <code>notification_last_sent</code> SQLite table so it survives restarts. Defaults: <code>CRITICAL</code> 60 s, <code>WARNING</code> 300 s, <code>INFO</code> 900 s, plus a per-category override on top (e.g. <code>resources</code> 900 s, <code>updates</code> 86 400 s).",
"tunable": "No — defaults baked into the dispatcher."
"stage": "Cooldown",
"what": "After successful delivery, repeated fingerprints are suppressed and the state is saved in <code>notification_last_sent</code>. Base defaults for <code>CRITICAL</code>, <code>WARNING</code> and <code>INFO</code> are 86 400 s, as are <code>resources</code> and <code>updates</code>. Exceptions include 5 s for VM/CT actions and host shutdown/reboot, 10 s for backup/replication results, and 1 800–3 600 s for several health-state categories. Explicit event/group settings can override these values.",
"tunable": "Only through the settings API — a <code>cooldown.&lt;event_type&gt;</code> or <code>cooldown.&lt;group&gt;</code> key overrides the defaults; there is no control in the UI."
},
{
"stage": "3. Burst aggregation",
"stage": "Burst aggregation",
"what": "When N events of a kind arrive inside a short window (e.g. an SSH brute-force flood), they are merged into a single <code>burst_*</code> message with a count and a sample.",
"tunable": "No — window and threshold are hard-coded per event type."
}
@@ -314,32 +314,32 @@
},
"aiRewrite": {
"heading": "Optional AI rewrite",
"body1": "Any event can be passed through an LLM that rewrites its body in plain language and (optionally) in the target user's language before fan-out. The AI rewriter is off by default. When enabled it runs in the dispatch thread; if the provider call fails or times out, the original templated body is used instead.",
"body1": "Eligible events can be rewritten by an LLM before delivery. Backup results (backup_complete and backup_fail) bypass this rewrite. AI is off by default and runs in the dispatch thread when enabled. If the call fails or times out, the original template text is used.",
"body2": "Six providers are supported (OpenAI, Anthropic, Google Gemini, Groq, OpenRouter and local Ollama), with per-channel detail level (<code>brief</code>, <code>standard</code>, <code>detailed</code>), output language, prompt mode (<code>default</code> or <code>custom</code>) and an optional custom prompt. Full configuration walk-through, captures and prompt examples live in the dedicated <link>AI Assistant</link> page.",
"privacyTitle": "Privacy note",
"privacyBody": "AI rewrite sends the event body — which can include hostnames, IP addresses, usernames, error messages and journal lines — to the configured provider. Ollama keeps everything on-host; the other five providers transmit data to their respective endpoints. Disable the rewriter, or use Ollama, if the host runs in an environment where event content cannot leave the network."
"privacyBody": "AI requests can include the title, severity, rendered body, system/custom prompt and collected context, including hostnames, IPs, usernames, errors and journal lines. They go to the selected endpoint. Ollama keeps processing local only with both a local server and a local model; a remote server or cloud model sends data outside the host. Disable rewriting or use a controlled local endpoint and model when event content must stay on the network."
},
"pveWebhook": {
"heading": "PVE webhook integration",
"intro1": "Proxmox VE 8.1+ has its own notification system with built-in <em>endpoints</em> (sendmail, gotify, SMTP, webhook). When you enable Notifications on the Monitor, it registers itself as one of those endpoints — a <code>webhook</code> target that points back at the Monitor's own API. From that moment on, anything Proxmox itself emits (HA fencing, replication, vzdump from the GUI, certificate renewal, etc.) flows through the same dispatch pipeline as the Monitor's own events.",
"intro1": "Proxmox’s notification system uses <em>targets</em>, including sendmail, Gotify, SMTP and, on versions supporting it, webhook. Enabling Monitor notifications registers a <code>webhook</code> target. PVE-emitted notifications such as HA, replication and GUI backup reports can then enter the same dispatch process.",
"intro2": "The target is visible from the Proxmox GUI at <em>Datacenter → Notifications → Notification Targets</em>:",
"imageAlt": "Proxmox VE Edit Webhook dialog showing the auto-created proxmenux-webhook target with method POST, URL http://127.0.0.1:8008/api/notifications/webhook and a JSON body template using escape title, escape message, escape severity, escape timestamp and json fields",
"imageCaption": "The PVE-side webhook target as Proxmox sees it (the GUI is in the host's configured locale — Spanish in this example). Same fields apply in any language.",
"registeredIntro": "What gets registered:",
"registeredItems": [
"<strong>Method & URL.</strong> <code>POST http://127.0.0.1:8008/api/notifications/webhook</code>. Loopback only — PVE talks to the Monitor process running on the same host.",
"<strong>Method and URL.</strong> <code>POST http://127.0.0.1:8008/api/notifications/webhook</code> when Monitor HTTPS is off. With HTTPS enabled, the target uses the separate HTTP loopback listener on port 8009. Both stay on the same host.",
"<strong>Body template.</strong> A JSON body using PVE's native Handlebars helpers — stored base64-encoded in the config file by PVE, but it expands to:",
"<strong>Matcher.</strong> A companion <code>matcher: proxmenux-matcher</code> block with <code>mode all</code> so every PVE notification reaches the target.",
"<strong>Companion priv block.</strong> An empty <code>webhook: proxmenux-webhook</code> entry is appended to <code>/etc/pve/priv/notifications.cfg</code>. PVE refuses to instantiate any webhook endpoint without a matching private block, even when no secrets are needed — so the Monitor writes a header-only stub there. No tokens, headers or HMAC are configured on the PVE side."
"<strong>Private configuration.</strong> Setup writes the matching <code>webhook: proxmenux-webhook</code> block in <code>/etc/pve/priv/notifications.cfg</code> with a <code>secret</code> entry named X-Webhook-Secret, encoded in base64. The public target block holds only the body template, method and URL. The private block is not an empty stub."
],
"securityTitle": "How the receiver is secured",
"securityIntro": "The webhook receiver at <code>POST /api/notifications/webhook</code> applies different security layers depending on where the request comes from:",
"securityItems": [
"<strong>Loopback (<code>127.0.0.1</code> / <code>::1</code>).</strong> Rate-limit only. The endpoint trusts the loopback interface — only processes running on the host can reach it, and PVE itself cannot send custom auth headers in the body it generates. This is the path every PVE-emitted notification travels.",
"<strong>Remote callers.</strong> Five layers stack on top of rate-limiting: a shared secret in the <code>X-Webhook-Secret</code> header, a freshness timestamp in <code>X-ProxMenux-Timestamp</code> (rejected if it drifts more than the configured window), a replay-cache lookup, and an optional IP allowlist. The shared secret lives in the Monitor's SQLite settings table — not in <code>/etc/pve/priv/notifications.cfg</code> — and is generated at first setup. This path exists for custom integrations posting from outside the host; the PVE-configured target never exercises it."
"<strong>Local sources (<code>127.0.0.1</code> / <code>::1</code>).</strong> Rate limiting applies, but the remote secret/timestamp/replay checks are skipped. The receiver also treats addresses assigned to the host’s own interfaces as local. The automatically configured PVE target uses loopback.",
"<strong>Remote callers.</strong> In addition to rate limiting, the receiver checks the configured secret in <code>X-Webhook-Secret</code>, a timestamp from <code>X-ProxMenux-Timestamp</code> or the JSON body, replay detection and an optional IP allowlist. The secret is stored in SQLite; setup also writes a base64-encoded copy to <code>/etc/pve/priv/notifications.cfg</code> so PVE can send the header."
],
"practiceTitle": "In practice",
"practiceBody": "The PVE setup writes the target as <code>http://127.0.0.1:8008</code>, so PVE-emitted notifications always go through the loopback path with rate-limit-only security. The remote-caller path with the shared secret is opt-in for custom integrations — point an external service at <code>https://&lt;monitor-host&gt;:&lt;port&gt;/api/notifications/webhook</code> and supply the <code>X-Webhook-Secret</code> header to use it.",
"practiceBody": "The PVE target uses <code>http://127.0.0.1:8008</code> without HTTPS, or HTTP port 8009 with Monitor HTTPS. For external integrations at <code>https://&lt;monitor-host&gt;:&lt;port&gt;/api/notifications/webhook</code>, send the configured <code>X-Webhook-Secret</code> and a current timestamp, and satisfy replay and IP checks. A secret header alone is not sufficient.",
"actionsIntro": "The Monitor manages this target through three actions on the Settings tab:",
"actionsItems": [
"<strong>Setup</strong> — runs automatically when you enable Notifications. Creates the entry in <code>/etc/pve/notifications.cfg</code>. The file is written only when its content has to change, and a copy of the previous one is kept in <code>/usr/local/share/proxmenux/backups/pve-notifications/</code> (the three newest). Nothing is written while <code>/etc/pve</code> is not mounted: a Monitor that starts during a restart of <code>pve-cluster</code> registers the entry once it is back.",
@@ -347,7 +347,7 @@
"<strong>Read config</strong> — shows the current targets and matchers as PVE sees them. This is how you confirm the Monitor's entry is the one firing when PVE has multiple notification routes configured."
],
"clusterTitle": "Cluster nodes",
"clusterBody": "<code>/etc/pve/</code> is replicated across cluster members, so the webhook target is visible on every node. Each node, however, posts to its <em>own</em> <code>127.0.0.1:8008</code> — meaning the Monitor running on that node receives the events that PVE generated locally. Run the Monitor on every node you want to see in the Notifications history."
"clusterBody": "<code>/etc/pve/</code> is shared across cluster nodes, including the target URL and secret. Each node calls its <em>own</em> loopback listener: <code>127.0.0.1:8008</code> without HTTPS, or HTTP port 8009 with HTTPS. Run Monitor on each relevant node and keep the shared target consistent with every node’s listener configuration."
},
"catalogue": {
"heading": "Event catalogue",
@@ -434,7 +434,7 @@
"<strong>The body lists each guest</strong> with its own result, size, duration and archive, followed by a line with the totals of the job.",
"<strong>Warnings and errors are listed once.</strong> Repeated lines are shown a single time with the main cause first; past eight lines, the rest is counted in a closing line and stays in the Proxmox task log.",
"<strong>A job that fails before its first guest</strong> shows the cause Proxmox gave, for example a storage that does not exist.",
"<strong>Summaries keep the result.</strong> A backup listed in the Quiet Hours summary or the Daily Digest carries the icon of its own result."
"<strong>Summaries preserve the result.</strong> A backup in the Quiet Hours summary keeps its own result icon. Backup result events bypass the Daily Digest."
]
}
},
@@ -483,7 +483,7 @@
{
"endpoint": "/api/notifications/webhook",
"method": "POST",
"use": "Receives Proxmox VE's own notifications. Loopback callers are rate-limited only; remote callers must additionally pass the <code>X-Webhook-Secret</code> header, <code>X-ProxMenux-Timestamp</code> freshness check, replay cache and optional IP allowlist."
"use": "Receives Proxmox notifications. Local source addresses skip remote authentication checks but remain rate-limited. Remote requests are checked against <code>X-Webhook-Secret</code>, a timestamp in <code>X-ProxMenux-Timestamp</code> or the JSON body, replay detection and any configured IP allowlist."
},
{
"endpoint": "/api/notifications/proxmox/setup-webhook",
+62 -62
View File
@@ -1,8 +1,8 @@
{
"meta": {
"title": "Autenticación del panel de Proxmox — 2FA, API Tokens, perfil de usuario, reverse proxy | ProxMenux Monitor",
"title": "Autenticación del panel de Proxmox — 2FA, tokens API, perfil de usuario, proxy inverso | ProxMenux Monitor",
"description": "Acceder y asegurar ProxMenux Monitor: flujo de proteger-tu-panel en el primer arranque, autenticación con contraseña con nombre visible + avatar, página de perfil, alta de TOTP 2FA, API tokens de larga duración para scripts, configuración HTTPS, snippets de reverse proxy para Nginx, Caddy y Traefik, el log de auditoría y el jail Fail2Ban opcional.",
"ogTitle": "Autenticación del panel de Proxmox — 2FA, API Tokens, reverse proxy",
"ogTitle": "Autenticación del panel de Proxmox — 2FA, tokens API, proxy inverso",
"ogDescription": "Asegura ProxMenux Monitor con contraseña + TOTP 2FA, API tokens de larga duración, HTTPS, snippets de reverse proxy y un jail Fail2Ban opcional.",
"twitterTitle": "Autenticación del panel de Proxmox | ProxMenux Monitor",
"twitterDescription": "Contraseña + TOTP 2FA, API tokens, HTTPS, snippets de Nginx/Caddy/Traefik y log de auditoría."
@@ -10,16 +10,16 @@
"header": {
"title": "Acceso y autenticación",
"description": "Cómo llegar al panel, el flujo de seguridad de primer arranque y cada capa que puede situarse entre un atacante y el host: contraseña + TOTP, sesiones JWT, API tokens de larga duración, HTTPS, reverse proxies, Secure Gateway y el jail Fail2Ban opcional.",
"section": "ProxMenux Monitor"
"section": "Monitor de ProxMenux"
},
"intro": {
"title": "La autenticación es opt-in",
"body": "En el primer arranque el panel muestra un único diálogo — <em>\"¿Proteger tu panel?\"</em> — con dos botones: <strong>Sí, configurar contraseña</strong> y <strong>No, continuar sin protección</strong>. Decir que no deja todos los endpoints de la API abiertos en el puerto TCP 8008 — aceptable en una LAN de laboratorio aislada, peligroso en cualquier otro escenario. La autenticación de dos factores (2FA) <strong>no</strong> forma parte de esta elección inicial; se configura más tarde desde <strong>la pestaña Security</strong> una vez que hay una contraseña."
"body": "Al abrir el panel por primera vez aparece un diálogo: <em>«¿Proteger el panel?»</em>, con los botones <strong>Sí, configurar contraseña</strong> y <strong>No, continuar sin protección</strong>. Al elegir que no, los endpoints de la API quedan abiertos en TCP 8008: puede servir en una LAN de laboratorio aislada, pero resulta peligroso en otros entornos. La autenticación de dos factores (2FA) <strong>no</strong> forma parte de esta primera elección; se configura después desde <strong>la pestaña Seguridad</strong>, una vez establecida la contraseña."
},
"reaching": {
"heading": "Cómo llegar al panel",
"intro": "ProxMenux Monitor escucha en <code>0.0.0.0:8008</code>. Hay tres formas habituales de llegar a él:",
"outro": "El acceso directo coincide con lo que la unidad systemd trae por defecto. Las secciones de reverse proxy y Secure Gateway a continuación cubren las otras dos. El Monitor respeta <code>X-Forwarded-For</code>, <code>X-Forwarded-Proto</code> y <code>X-Forwarded-Host</code> para que las URLs y CORS funcionen detrás de cualquiera de ellos sin configuración manual."
"outro": "El acceso directo corresponde a la unidad systemd predeterminada. El proxy inverso y Secure Gateway se describen más abajo. Para confiar en la IP de <code>X-Forwarded-For</code> se requiere PROXMENUX_TRUST_PROXY=1 y un proxy que controles. La presencia de <code>X-Forwarded-Proto</code> o <code>X-Forwarded-Host</code> no activa esa confianza. En los puertos 80/443 el frontend usa URL relativas <code>/api/*</code>; en cualquier otro puerto llama al puerto 8008 del mismo nombre de host."
},
"firstLaunch": {
"heading": "Flujo de primer arranque",
@@ -32,27 +32,27 @@
"rows": [
{
"button": "Sí, configurar contraseña",
"what": "Abre un formulario con el usuario + contraseña obligatorios y un <em>nombre visible</em> + <em>imagen de avatar</em> opcionales. Los guarda en <code>auth.json</code> con <code>enabled: true</code>. Devuelve un JWT así que quedas logueado inmediatamente. El formulario se documenta en detalle más abajo.",
"what": "Abre un formulario con nombre de usuario y contraseña obligatorios, más <em>nombre visible</em> e <em>imagen de avatar</em> opcionales. Activa la autenticación en <code>auth.json</code> con <code>enabled: true</code> y devuelve un JWT para iniciar sesión. Los campos opcionales del perfil se guardan mediante llamadas posteriores, como se explica abajo.",
"api": "POST /api/auth/setup"
},
{
"button": "No, continuar sin protección",
"what": "Marca <code>declined: true</code> en <code>auth.json</code>. Todos los endpoints de la API son accesibles públicamente hasta que cambies de idea desde Settings.",
"what": "Marca <code>declined: true</code> en <code>auth.json</code>. Los endpoints de la API permanecen abiertos hasta que actives la protección desde Ajustes.",
"api": "POST /api/auth/skip"
}
],
"twofaCalloutTitle": "El 2FA se configura después, no aquí",
"twofaCalloutBody": "El diálogo de primer arranque solo cubre la decisión de la contraseña. La <strong>autenticación de dos factores (TOTP)</strong> se configura después desde <strong>la pestaña Security</strong> una vez logueado con una contraseña. El walkthrough completo de TOTP está más abajo en esta página.",
"twofaCalloutBody": "El diálogo inicial solo decide la protección con contraseña. La <strong>autenticación de dos factores (TOTP)</strong> se configura después desde <strong>la pestaña Seguridad</strong>, una vez iniciada la sesión con contraseña. El procedimiento completo de TOTP se explica más abajo.",
"createTitle": "Crear el primer usuario",
"createIntro": "Pulsar <em>Sí, configurar contraseña</em> abre un único formulario que crea la cuenta y, opcionalmente, siembra el perfil del usuario de una sola vez para que el avatar aparezca en la cabecera nada más guardar. Los campos son:",
"createIntro": "Al pulsar <em>Sí, configurar contraseña</em>, un formulario crea la cuenta y permite completar el perfil para que el avatar aparezca en la cabecera al guardar. Los campos son:",
"headerField": "Campo",
"headerRequired": "Requerido",
"headerNotes": "Notas",
"fieldRows": [
{
"field": "Username",
"field": "Nombre de usuario",
"required": "Sí",
"notes": "El identificador de login. No se puede cambiar después desde la UI; editarlo requiere tocar <code>auth.json</code> directamente."
"notes": "Identificador de inicio de sesión. No se puede cambiar desde la interfaz; hay que editar <code>auth.json</code> directamente."
},
{
"field": "Contraseña",
@@ -62,7 +62,7 @@
{
"field": "Nombre visible",
"required": "No",
"notes": "Etiqueta amistosa que se muestra en el dropdown de la cabecera y en la página de perfil. Cae al username cuando está vacío. Se puede cambiar después desde <strong>Avatar → Ver perfil</strong>."
"notes": "Nombre que aparece en el menú de la cabecera y en el perfil. Si está vacío se usa el nombre de usuario. Puedes cambiarlo desde <strong>Avatar → Ver perfil</strong>."
},
{
"field": "Imagen de avatar",
@@ -71,11 +71,11 @@
}
],
"createImageAlt": "Formulario de creación de usuario con campos obligatorios Username + Contraseña y la sección opcional Nombre visible + subida de Avatar",
"createImageCaption": "El formulario de creación de usuario del primer arranque. El nombre visible y el avatar son opcionales — dejarlos vacíos crea la cuenta y cae a un círculo con una sola letra en la cabecera.",
"createImageCaption": "Formulario inicial de creación de usuario. El nombre visible y el avatar son opcionales; si los dejas vacíos, la cuenta se crea y la cabecera muestra un círculo con una letra.",
"saveCalloutTitle": "Un único guardado, tres llamadas a la API por dentro",
"saveCalloutBody": "El formulario envía primero <code>POST /api/auth/setup</code> (username + contraseña). Si tiene éxito usa el JWT recién emitido para hacer a continuación <code>PUT /api/auth/profile</code> (nombre visible) y <code>POST /api/auth/profile/avatar</code> (bytes del avatar) si esos campos se rellenaron. Los fallos en las llamadas de perfil no son fatales — la cuenta ya está creada y puedes terminar el perfil después desde la página dedicada.",
"avatarTitle": "Menú del avatar y página de perfil",
"avatarBody1": "Una vez configurada la autenticación, aparece un círculo de avatar en la parte superior derecha de cada página del panel junto al toggle de tema. Pulsarlo abre un pequeño dropdown con accesos directos a la página de perfil y a la pestaña Security, además de una acción <strong>Sign out</strong> — cerrar la sesión se puede hacer desde aquí o desde la pestaña Security, lo que esté más cerca de donde te encuentres.",
"avatarBody1": "Tras configurar la autenticación, aparece el avatar arriba a la derecha, junto al selector de tema. Su menú contiene accesos al perfil, a Seguridad y la acción <strong>Cerrar sesión</strong>. También puedes cerrar la sesión desde Seguridad.",
"avatarBody2": "La página de perfil en sí es una pequeña tarjeta con una vista previa del avatar, el username (solo lectura) y el nombre visible con un botón de edición en línea. Las subidas, reemplazos y eliminaciones de avatar son atómicas — el avatar de la cabecera se refresca automáticamente cuando cualquiera tiene éxito, así que no hay necesidad de recargar la página. El mismo conjunto de endpoints documentado en la siguiente sección lo usan tanto el formulario de creación de usuario como la página de perfil.",
"profileImageAlt": "Página de perfil con círculo de vista previa del avatar, botones Subir / Reemplazar / Eliminar, username de solo lectura y campo de nombre visible editable",
"profileImageCaption": "La página de perfil dedicada. El username es solo lectura; el nombre visible y el avatar se pueden editar desde aquí sin tocar la pestaña Security.",
@@ -88,7 +88,7 @@
},
{
"endpoint": "PUT /api/auth/profile",
"what": "Actualiza el nombre visible. Body: <code>'{' \"display_name\": \"...\" '}'</code>."
"what": "Actualiza el nombre visible. Cuerpo de la petición: <code>'{' \"display_name\": \"...\" '}'</code>."
},
{
"endpoint": "GET /api/auth/profile/avatar",
@@ -100,15 +100,15 @@
},
{
"endpoint": "DELETE /api/auth/profile/avatar",
"what": "Elimina el avatar. La cabecera cae al placeholder de inicial-sobre-círculo-coloreado."
"what": "Elimina el avatar. La cabecera vuelve a mostrar una inicial en un círculo de color."
}
],
"reversibleTitle": "Continuar sin protección es reversible — pero solo desde el host",
"reversibleBody": "Una vez que pulsas <em>No, continuar sin protección</em>, el diálogo de bienvenida ya no vuelve a aparecer. Puedes reactivar la autenticación desde <strong>la pestaña Security</strong> dentro del panel, o editando <code>/root/.config/proxmenux-monitor/auth.json</code> y quitando el flag <code>declined</code>, luego reiniciando el servicio."
"reversibleTitle": "Puedes activar la protección más adelante",
"reversibleBody": "Tras pulsar <em>No, continuar sin protección</em>, el diálogo inicial no vuelve a aparecer. Puedes activar la autenticación desde <strong>la pestaña Seguridad</strong> o editar <code>/root/.config/proxmenux-monitor/auth.json</code>, quitar el indicador <code>declined</code> y reiniciar el servicio."
},
"password": {
"heading": "Autenticación con contraseña",
"intro": "Tras Setup, cada llamada a la API (excepto los pocos endpoints públicos listados abajo) requiere un JWT en <code>Authorization: Bearer &lt;token&gt;</code>:",
"intro": "Tras configurar la protección, las llamadas protegidas requieren un JWT en <code>Authorization: Bearer &lt;token&gt;</code>:",
"items": [
"<strong>Token de sesión (login):</strong> expiración de 24 horas. Emitido por <code>POST /api/auth/login</code>.",
"<strong>API token (integraciones):</strong> expiración de 365 días. Emitido por <code>POST /api/auth/generate-api-token</code>. Documentado por separado en la siguiente sección."
@@ -118,16 +118,16 @@
"loginFlowTitle": "Flujo de login",
"twofaIntro": "Con 2FA activado, la misma llamada devuelve primero <code>requires_totp: true</code>. Reemite con el código de 6 dígitos:",
"publicTitle": "Endpoints públicos (sin token)",
"publicIntro": "Estos son los únicos endpoints que funcionan sin autenticación, incluso cuando auth está activado:",
"publicIntro": "El inicio de sesión, su estado, la configuración inicial y el endpoint ligero <code>/api/system-info</code> son públicos:",
"publicItems": [
"<code>/api/auth/login</code>, <code>/api/auth/status</code>, <code>/api/auth/setup</code> — el propio flujo de auth, por necesidad.",
"<code>/api/system-info</code> — snapshot ligero del sistema (hostname, uptime, <code>health.status</code>). El endpoint adecuado para probes externos (Uptime Kuma, health checks de balanceador, páginas de estado)."
"<code>/api/auth/login</code> y <code>/api/auth/status</code> son públicos. <code>/api/auth/setup</code> crea la cuenta inicial y rechaza sobrescribir credenciales existentes.",
"<code>/api/system-info</code> es un endpoint público de información básica del sistema, incluido <code>health.status</code>. No lleva el requisito de token. /api/auth/status también es público y sirve para comprobar disponibilidad."
],
"cryptoTitle": "Criptografía y almacenamiento",
"cryptoIntro": "ProxMenux Monitor es código abierto — nada de esto es secreto. Documentar el stack aquí de forma explícita es una decisión deliberada: los operadores que guardan credenciales en su host merecen saber cómo se protegen esas credenciales antes de decidir confiar en ellas. Los algoritmos de abajo son los mismos que usa el código en <code>scripts/auth_manager.py</code>; esta sección es un contrato, no una promesa de marketing.",
"headerAsset": "Activo",
"cryptoIntro": "ProxMenux Monitor es código abierto — nada de esto es secreto. Documentar el stack aquí de forma explícita es una decisión deliberada: los usuarios que guardan credenciales en su host merecen saber cómo se protegen esas credenciales antes de decidir confiar en ellas. Los algoritmos de abajo son los mismos que usa el código en <code>scripts/auth_manager.py</code>; esta sección es un contrato, no una promesa de marketing.",
"headerAsset": "Elemento",
"headerAlgo": "Algoritmo",
"headerWhere": "Dónde vive",
"headerWhere": "Ubicación",
"cryptoRows": [
{
"asset": "Contraseña",
@@ -146,7 +146,7 @@
},
{
"asset": "Secret TOTP de 2FA",
"algorithm": "TOTP estándar (RFC 6238) codificado en base32. Los códigos de backup se pregeneran, son de un solo uso, hasheados con el mismo esquema PBKDF2 que la contraseña.",
"algorithm": "TOTP estándar (RFC 6238), con secreto codificado en base32. Los ocho códigos de backup son de un solo uso y se almacenan como hashes SHA-256.",
"where": "<code>auth.json</code> → <code>totp_secret</code> + <code>backup_codes[]</code>"
},
{
@@ -158,9 +158,9 @@
"authJsonTitle": "auth.json — qué contiene y cómo se protege",
"authJsonBody": "Todo lo que ProxMenux Monitor necesita para autenticarte vive en un único archivo: <code>/root/.config/proxmenux-monitor/auth.json</code>, modo <code>0600</code>, propietario <code>root</code>. El archivo guarda <em>hashes</em> (PBKDF2) y <em>material de firma</em> (<code>jwt_secret</code>, <code>totp_secret</code>) — nunca una contraseña en texto plano. Trátalo como cualquier otro secreto de solo-root: si haces backup o replicas el host, cifra el destino y nunca lo subas a control de versiones.",
"rotateTitle": "Rotar jwt_secret invalida todos los JWTs existentes",
"rotateBody": "Si <code>auth.json</code> se regenera (borrado manual, reinstalación, restauración desde un backup con un secret distinto) el <code>jwt_secret</code> cambia y cada JWT previamente emitido — tanto sesiones interactivas como API tokens de larga duración — falla la verificación con \"Invalid or expired token\". La UI marca los API tokens afectados con un badge <strong>Invalid — regenerate</strong> para que el operador sepa que tiene que revocarlos y volver a emitirlos; Home Assistant / scripts / cualquier cliente externo necesita un token fresco después de eso.",
"rotateBody": "Si <code>auth.json</code> se regenera (borrado manual, reinstalación, restauración desde un backup con un secret distinto) el <code>jwt_secret</code> cambia y cada JWT previamente emitido — tanto sesiones interactivas como API tokens de larga duración — falla la verificación con \"Invalid or expired token\". La UI marca los API tokens afectados con un badge <strong>Invalid — regenerate</strong> para que el usuario sepa que tiene que revocarlos y volver a emitirlos; Home Assistant / scripts / cualquier cliente externo necesita un token fresco después de eso.",
"recoverTitle": "Recuperar una contraseña perdida",
"recoverIntro": "No hay un flujo online de \"olvidé mi contraseña\" — por diseño, ya que el panel corre en el propio host del operador y el camino de recuperación es acceso shell a ese host. ProxMenux trae un reset guiado dentro del menú de configuración para que no tengas que editar a mano <code>auth.json</code>:",
"recoverIntro": "No hay un flujo online de \"olvidé mi contraseña\" — por diseño, ya que el panel corre en el propio host del usuario y el camino de recuperación es acceso shell a ese host. ProxMenux trae un reset guiado dentro del menú de configuración para que no tengas que editar a mano <code>auth.json</code>:",
"survivesTitle": "Qué sobrevive al reset",
"survivesBody": "Solo el login interactivo se borra. El <code>jwt_secret</code> y los <code>api_tokens</code> registrados se preservan — así que Home Assistant y cualquier otro script que use un API token de larga duración siguen funcionando sin reconfiguración. Si quieres una pizarra totalmente limpia (también rotar el secret JWT), borra <code>auth.json</code> manualmente y reinicia el servicio. El siguiente arranque genera un secret fresco y todos los tokens viejos se vuelven inválidos.",
"physicalTitle": "Prerrequisito de acceso físico",
@@ -170,8 +170,8 @@
"heading": "Autenticación de dos factores (TOTP)",
"intro": "El 2FA añade un segundo factor encima de tu contraseña: un código de 6 dígitos que rota cada 30 segundos, generado en un móvil o gestor de contraseñas que controlas. Aunque alguien obtenga la contraseña, sigue sin poder entrar sin el código de tu dispositivo. ProxMenux Monitor implementa el protocolo estándar <strong>TOTP</strong> (RFC 6238), así que cualquier app autenticadora funciona.",
"pickTitle": "Elige una app autenticadora",
"pickIntro": "Si ya usas una para Google / GitHub / tu banco, esa funcionará — salta al walkthrough de setup. Si no, aquí tienes un repaso de opciones habituales. Todas son gratis; las diferencias son sobre todo en qué plataformas corren y cómo (o si) hacen backup de tus secrets.",
"headerApp": "App",
"pickIntro": "Si ya tienes una aplicación TOTP, puedes usarla aquí. La tabla recoge opciones habituales: algunas son gratuitas y otras requieren suscripción. También cambian las plataformas y los métodos de backup.",
"headerApp": "Aplicación",
"headerPlatforms": "Plataformas",
"headerAppNotes": "Notas",
"apps": [
@@ -190,8 +190,8 @@
{
"name": "Authy",
"href": "https://authy.com/",
"platforms": "iOS, Android, escritorio",
"notes": "Sync cifrado multi-dispositivo (la app de escritorio se está retirando — comprueba el estado más reciente)."
"platforms": "iOS, Android",
"notes": "Sincronización cifrada entre dispositivos. La aplicación de escritorio dejó de recibir soporte el 19 de marzo de 2024."
},
{
"name": "Apple Passwords",
@@ -203,7 +203,7 @@
"name": "Bitwarden",
"href": "https://bitwarden.com/",
"platforms": "iOS, Android, escritorio, navegador",
"notes": "Código abierto. El TOTP vive junto a la contraseña que protege (cómodo si también usas BW para contraseñas; rompe el \"dispositivo separado\" si no)."
"notes": "Código abierto. Permite guardar TOTP junto a las contraseñas en la bóveda. Resulta cómodo, pero guardar ambos en ella no los separa en un segundo dispositivo."
},
{
"name": "1Password",
@@ -238,40 +238,40 @@
{
"name": "FreeOTP+",
"href": "https://github.com/helloworld1/FreeOTPPlus",
"platforms": "Android, iOS",
"notes": "Código abierto (impulsado por Red Hat). Mínimo — sin nube, sin cuenta."
"platforms": "Android",
"notes": "Bifurcación de código abierto de FreeOTP para Android, con importación y exportación. No requiere cuenta."
}
],
"backupTitle": "Para qué importa realmente el \"backup\"",
"backupBody": "Si pierdes el dispositivo que tiene el autenticador, las únicas formas de volver a entrar son (1) un código de backup guardado cuando activaste el 2FA, o (2) un backup de la bóveda del autenticador. Las apps con sync en la nube (Google Auth, Microsoft Auth, Authy, Apple Passwords, Ente, 2FAS, Bitwarden, 1Password) pueden restaurar en un dispositivo nuevo. Las apps sin nube (Aegis, Raivo, FreeOTP+) necesitan un archivo de exportación cifrado que hayas copiado a un sitio seguro. Cualquier enfoque funciona — el caso malo es \"sin backup en absoluto\".",
"backupBody": "Si pierdes el dispositivo autenticador, usa un código de backup guardado o restaura un backup de la app que hubieras configurado previamente. La sincronización en la nube y las exportaciones varían según la aplicación; comprueba que restauren los secretos TOTP. El acceso root al host también permite recuperar el acceso, como se explica abajo. Conserva un backup separado y seguro.",
"setupTitle": "Configuración paso a paso desde el panel",
"setupImageAlt": "Pantalla de configuración de 2FA con código QR y códigos de backup",
"setupImageCaption": "El diálogo de configuración de 2FA — código QR, secret en Base32 (para entrada manual) y los diez códigos de backup de un solo uso. Los códigos solo se muestran aquí; si cierras el diálogo sin copiarlos, se pierden.",
"setupImageCaption": "El diálogo de 2FA muestra un código QR, el secreto Base32 para introducirlo manualmente y, tras la verificación, ocho códigos de backup de un solo uso. Cópialos antes de cerrar; no volverán a mostrarse.",
"setupSteps": [
"<strong>Instala la app autenticadora en tu móvil</strong> (o abre tu gestor de contraseñas). Una de las apps de la tabla de arriba. Solo necesitas hacerlo una vez — la misma app guardará códigos para cada servicio que protejas.",
"<strong>Loguéate en el panel</strong> con tu usuario y contraseña.",
"<strong>Abre la pestaña Security</strong> en la barra lateral del panel, luego pulsa <strong>Enable 2FA</strong>. Se abre un diálogo con un código QR, una cadena larga en formato Base32 y diez códigos cortos etiquetados como \"códigos de backup\".",
"<strong>Abre la pestaña Seguridad</strong> en la barra lateral y pulsa <strong>Activar 2FA</strong> y <strong>Iniciar configuración</strong>. El diálogo muestra un QR y la clave manual; los ocho códigos de backup aparecen tras verificar el código.",
"<strong>Añade la entrada a la app autenticadora:</strong>",
"<strong>Guarda los códigos de backup.</strong> Copia los diez códigos a un sitio seguro — un gestor de contraseñas, una nota cifrada, una copia impresa en un cajón. Trátalos como llaves de repuesto: cada uno funciona exactamente una vez y te deja entrar si tu móvil se pierde o rompe.",
"<strong>Confirma escribiendo el código actual de 6 dígitos</strong> de la app en el campo \"Código de verificación\" del diálogo de setup y envía. Los códigos se refrescan cada 30 segundos, así que si caduca mientras escribes, simplemente introduce el siguiente.",
"<strong>Confirma escribiendo el código actual de 6 dígitos</strong> de la app en el campo \"Código de verificación\" del diálogo de configuración y envía. Los códigos se renuevan cada 30 segundos, así que si caduca mientras escribes, introduce el siguiente.",
"<strong>Guarda los códigos de backup.</strong> Tras la verificación, conserva los ocho en un gestor de contraseñas, nota cifrada o copia impresa segura. Cada uno funciona una vez si no tienes el autenticador.",
"<strong>Hecho.</strong> El 2FA está ahora activo. La próxima vez que te logues, el panel pide primero la contraseña; una vez aceptada pide el código actual de 6 dígitos."
],
"setupStep4Sub": [
"<em>Camino fácil:</em> en la app, pulsa <em>Añadir cuenta</em> → <em>Escanear código QR</em>, apunta la cámara al QR en la pantalla. La app nombra la entrada automáticamente (algo como <code>ProxMenux Monitor (your-username)</code>) y empieza a mostrar un código de 6 dígitos que se refresca cada 30 segundos.",
"<em>Plan B manual</em> (cuando escanear no es posible — p. ej. configurando en el mismo móvil con el que abriste el panel): pulsa <em>Añadir cuenta</em> → <em>Introducir clave de setup</em>. Escribe cualquier nombre (p. ej. <em>Proxmox Monitor</em>), pega la cadena Base32 del diálogo, deja <em>Tipo</em> como <em>Basado en tiempo</em>, guarda."
],
"testTitle": "Prueba antes de hacer logout",
"testBody": "Una vez que pulses Guardar, haz logout y vuelve a entrar <em>inmediatamente</em>, mientras el diálogo de setup esté todavía fresco en tu memoria. Si el código se rechaza (la causa más común es el desfase de reloj entre servidor y móvil), aún puedes arreglarlo desde la sesión abierta. Hacer logout sin probar primero significa un viaje de ida sin retorno — en ese punto solo un código de backup o editar <code>auth.json</code> en el host te deja volver a entrar.",
"testTitle": "Prueba antes de cerrar sesión",
"testBody": "Mantén la sesión actual abierta y prueba un nuevo acceso en una ventana privada <em>inmediatamente</em> después de configurar 2FA. Si el código falla, comprueba los relojes del servidor y del móvil antes de cerrar la sesión válida. Si ya perdiste el acceso, usa un código de backup o edita <code>auth.json</code> desde la consola del host.",
"lostTitle": "Autenticador perdido",
"lostIntro": "Tres salidas de emergencia, en orden de cuán disruptivas son:",
"lostItems": [
"<strong>Usa un código de backup.</strong> En la pantalla de login, en el campo TOTP, escribe uno de los diez códigos que guardaste durante el setup. Cada uno funciona una vez y luego se consume; los códigos restantes siguen funcionando. Una vez dentro, regenera el 2FA desde Settings para conseguir diez nuevos.",
"<strong>Usa un código de backup.</strong> Introduce uno de los ocho códigos guardados en el campo TOTP. Funciona una vez; los no usados siguen siendo válidos. Tras entrar, abre Seguridad, elige <strong>Desactivar 2FA</strong> y después <strong>Activar 2FA</strong> para obtener ocho códigos nuevos.",
"<strong>Restaura el autenticador desde la nube / backup.</strong> Si tu app tiene sync en la nube (Google, Microsoft, Authy, Apple Passwords vía iCloud Keychain, Ente, 2FAS) instálala en un dispositivo nuevo, loguéate y las entradas reaparecen. Si tu app usa un archivo de exportación cifrado (Aegis, Raivo, FreeOTP+), instala la app en el dispositivo nuevo e importa el archivo.",
"<strong>Desactiva el 2FA desde la shell del host.</strong> Cuando las opciones anteriores no están disponibles, edita <code>/root/.config/proxmenux-monitor/auth.json</code> en el host Proxmox (necesitas SSH root o acceso por consola), pon <code>totp_enabled</code> a <code>false</code>, guarda y reinicia el servicio:"
],
"lostShellOutro": "Puedes loguearte con usuario + contraseña solo, luego reactivar el 2FA desde Settings.",
"disableTitle": "Desactivar el 2FA",
"disableBody": "Desde el panel, abre la pestaña <strong>Security</strong> y pulsa <strong>Disable 2FA</strong>. El endpoint <code>POST /api/auth/totp/disable</code> requiere la contraseña actual como confirmación, luego elimina el secret TOTP y limpia los códigos de backup. Recuerda también quitar la entrada en la app autenticadora — la app no sabe que el lado del servidor ha desaparecido, así que la entrada muerta se quedaría ahí para siempre si no.",
"disableBody": "Abre <strong>Seguridad</strong> y elige <strong>Desactivar 2FA</strong>. <code>POST /api/auth/totp/disable</code> exige la contraseña actual y un código TOTP o de backup válido. Elimina el secreto TOTP y los códigos de backup. Elimina también la entrada antigua en la aplicación autenticadora.",
"rejectedTitle": "El código de 6 dígitos se rechaza siempre",
"rejectedIntro": "El TOTP está basado en tiempo — el reloj del servidor y el del móvil deben coincidir dentro de unos ~30 s. Dos comprobaciones:",
"rejectedItems": [
@@ -288,57 +288,57 @@
"generateTitle": "Generar un token",
"generateIntro": "Desde el panel:",
"generateSteps": [
"Navega a la sección <strong>pestaña Security → API Access Tokens</strong>.",
"Abre <strong>Seguridad → Tokens de acceso API</strong>.",
"Escribe un nombre descriptivo (<em>p. ej. \"Home Assistant\"</em>).",
"Vuelve a introducir tu contraseña. Si el 2FA está activado, también el código actual de 6 dígitos.",
"Pulsa <strong>Generate Token</strong>. El token aparece <strong>una vez</strong> — cópialo inmediatamente."
"Pulsa <strong>Generar token</strong>. Se muestra <strong>una sola vez</strong>: cópialo al momento."
],
"generateCli": "Desde la línea de comandos:",
"useTitle": "Usar un token",
"revokeTitle": "Revocar un token",
"revokeBody": "Desde el panel de arriba: cada fila tiene una acción <strong>Revoke</strong> que añade el hash del token a <code>revoked_tokens</code> en <code>auth.json</code>. Los tokens revocados fallan la validación inmediatamente en la siguiente petición.",
"revokeBody": "Cada fila ofrece <strong>Revocar</strong>, que añade el hash del token a <code>revoked_tokens</code> en <code>auth.json</code>. El token revocado falla la validación en la siguiente petición.",
"cheatTitle": "Chuleta de seguridad de tokens",
"cheatItems": [
"Guarda los tokens en el almacén de secrets nativo de tu integración — Homepage <code>secrets.yaml</code>, Home Assistant <code>!secret</code>, variables de entorno, etc. Nunca los subas a git.",
"Un token por integración, nombrado por el consumidor. Revoca individualmente al retirar una integración.",
"Rota cada 6-12 meses. La expiración es un límite duro, no una recomendación."
],
"outro": "Las mejores prácticas completas de almacenamiento y recetas de integración viven en <apiLink>API Reference → Token Management</apiLink> e <intLink>Integrations</intLink>."
"outro": "Consulta las recomendaciones de almacenamiento y los ejemplos en <apiLink>Referencia de la API → Gestión de tokens</apiLink> e <intLink>Integraciones</intLink>."
},
"https": {
"heading": "HTTPS",
"intro": "Dos rutas hacia TLS:",
"items": [
"<strong>Reverse proxy (recomendado).</strong> Termina TLS en Nginx / Caddy / Traefik y reenvía HTTP en el puerto 8008 al proceso Flask. Snippets más abajo.",
"<strong>HTTPS directo en el AppImage.</strong> Configura un certificado vía <code>POST /api/ssl/configure</code> (UI: <strong>Settings → SSL</strong>). Cuando SSL está configurado el proceso cambia del servidor dev de Flask a <code>gevent.pywsgi</code> con el handler gevent-websocket para que el terminal WebSocket también funcione sobre WSS. Los archivos del cert viven donde tú los pongas; las rutas se guardan en la configuración SSL."
"<strong>HTTPS directo en AppImage.</strong> Configura un certificado con <code>POST /api/ssl/configure</code> (interfaz: <strong>Ajustes → SSL</strong>). HTTPS usa <code>gevent.pywsgi</code> con su manejador estándar; flask-sock gestiona la conexión WebSocket para WSS. Las rutas de los certificados se guardan en la configuración SSL."
],
"calloutTitle": "Limitaciones del HTTPS directo",
"calloutBody": "La ruta gevent empaquetada es adecuada para certificados autofirmados o solo-LAN. Para Let's Encrypt / ACME y renovación automática, pon un reverse proxy real delante — Caddy autorrenueva y Traefik / Nginx tienen patrones bien conocidos. El Monitor no implementa ACME por sí mismo."
"calloutBody": "Monitor puede usar un certificado gestionado por Proxmox o archivos de certificados propios. No emite certificados ACME. Para emitirlos y renovarlos automáticamente, usa ACME de Proxmox o un proxy inverso como Caddy, Traefik o Nginx y asegúrate de cargar los certificados renovados."
},
"gateway": {
"heading": "Secure Gateway (Tailscale)",
"intro": "Los reverse proxies son la respuesta clásica a \"llegar al panel desde fuera\" pero requieren un dominio público, certificado y un puerto abierto en el borde. <strong>Secure Gateway</strong> es la alternativa cero-puertos que viene dentro del propio Monitor — una app desplegable preconstruida que levanta un LXC Alpine ejecutando <a>Tailscale</a> como subnet router. Una vez unido a tu tailnet, cada dispositivo en él puede llegar al Monitor en la propia IP LAN del host — desde un portátil de vacaciones, un móvil con 5G u otro nodo — sin exponer TCP 8008 a internet.",
"intro": "Un proxy inverso es una opción de acceso remoto. <strong>Secure Gateway</strong> permite acceder sin exponer TCP 8008: despliega un LXC Alpine con <a>Tailscale</a> como router de subred. El acceso a la IP LAN del host depende de las rutas aprobadas y de las reglas de acceso de la tailnet.",
"calloutTitle": "Por qué esto es cómodo",
"calloutBody": "La URL se mantiene igual que en la LAN — <code>http://&lt;proxmox-lan-ip&gt;:8008</code> funciona donde Tailscale funcione. Sin certificados, sin DNS, sin port forwarding. El propio Monitor ve la petición viniendo de una IP de tailnet (típicamente <code>100.x.y.z</code>), así que el log de auth y el hook de Fail2Ban siguen funcionando como en la LAN.",
"calloutBody": "Usa la URL LAN <code>http://&lt;proxmox-lan-ip&gt;:8008</code> mediante la ruta de subred aprobada. Tailscale usa SNAT por defecto, por lo que Monitor suele ver la IP LAN de la pasarela, no la dirección <code>100.x.y.z</code> del cliente. Los registros y Fail2Ban identifican la dirección de origen que recibe el host.",
"deployBody": "El flujo de despliegue es una sola pantalla — elige el storage LXC del host, pega un auth-key de Tailscale (generado en <a>login.tailscale.com/admin/settings/keys</a>), elige qué subnets anunciar, pulsa Deploy. El LXC tarda ~30 segundos en arrancar y se registra en el tailnet automáticamente.",
"outro": "El despliegue paso a paso, la configuración de subnet-routes, las ACLs de Tailscale y el modo Exit Node se documentan por separado en <link>Dashboard → Security → Secure Gateway</link> — ahí vive el wizard de despliegue en la UI del panel. Esta página solo cubre el patrón de acceso."
},
"proxy": {
"heading": "Snippets de reverse proxy",
"intro": "La distribución más simple es un <strong>nombre de host dedicado</strong> para el Monitor (p. ej. <code>monitor.example.com</code>) apuntando al puerto 8008 del host Proxmox. Los snippets de abajo usan ese patrón. Los montajes en sub-path (<code>example.com/proxmenux-monitor/</code>) son posibles pero requieren reescritura extra y no son el valor por defecto — mira el callout al final.",
"intro": "Usa un <strong>nombre de host dedicado</strong>, como <code>monitor.example.com</code>, que reenvíe al puerto 8008 del host Proxmox. Los ejemplos siguen ese patrón. Una subruta como <code>example.com/proxmenux-monitor/</code> requiere cambios adicionales en frontend y proxy; quitar el prefijo no basta.",
"nginxTitle": "Nginx",
"caddyTitle": "Caddy",
"traefikTitle": "Traefik (labels — Docker / Kubernetes)",
"traefikTitle": "Traefik (etiquetas: Docker / Kubernetes)",
"subPathTitle": "Avanzado: montajes en sub-path bajo un dominio existente",
"subPathBody": "Si no quieres un nombre de host dedicado, puedes montar el Monitor bajo un path de un dominio existente — por ejemplo <code>example.com/proxmenux-monitor/</code>. El build de Next.js usa rutas relativas para los assets así que los archivos estáticos resuelven, pero el proxy debe <strong>quitar el prefijo</strong> antes de reenviar para que el Monitor reciba URLs <code>/api/*</code> sin más. En Nginx eso es un <code>location /proxmenux-monitor/ &rbrace; proxy_pass http://127.0.0.1:8008/; &lbrace;</code> (la barra final en <code>proxy_pass</code> hace el strip). En Caddy, usa <code>handle_path /proxmenux-monitor/*</code>. Un nombre de host dedicado es más simple."
"subPathBody": "El frontend actual no tiene una base de subruta configurada y crea llamadas desde la raíz mediante URL <code>/api/*</code>. Quitar un prefijo como <code>example.com/proxmenux-monitor/</code> no resuelve esas llamadas ni todos los recursos de la interfaz. Usa un nombre de host dedicado. Una subruta exige cambios coordinados en frontend y proxy y pruebas específicas."
},
"audit": {
"heading": "Log de auditoría",
"intro": "Cada evento de autenticación (éxito y fallo) se añade a <code>/var/log/proxmenux-auth.log</code> en formato de una sola línea, estilo syslog:",
"intro": "Los fallos de inicio de sesión y los avisos del límite de intentos se escriben en <code>/var/log/proxmenux-auth.log</code>, con una línea por evento. Este logger no registra los accesos correctos:",
"outro": "Sigue la cola con el método habitual: <code>tail -F /var/log/proxmenux-auth.log</code>. El archivo se rota con <code>logrotate</code> si se añade un drop-in de configuración; el Monitor no lo rota por sí mismo."
},
"fail2ban": {
"heading": "Opcional: jail Fail2Ban",
"heading": "Opcional: jail de Fail2Ban",
"calloutTitle": "Fail2Ban no viene incluido con el Monitor",
"calloutBody": "Fail2Ban <strong>no</strong> lo instala ProxMenux Monitor por sí mismo. Instálalo vía <link>Seguridad → Fail2Ban</link> en el menú de ProxMenux (o con el paquete estándar de Debian). Sin él, el Monitor sigue escribiendo el log de auditoría de arriba — simplemente no banea automáticamente a los repetidores.",
"intro": "Cuando Fail2Ban está instalado, la integración de ProxMenux trae un jail <code>[proxmenux]</code> que:",
@@ -346,7 +346,7 @@
"Lee <code>/var/log/proxmenux-auth.log</code>.",
"Hace match con el patrón <code>authentication failure; rhost=&lt;ip&gt;</code> con un filtro dedicado.",
"Banea la IP infractora a nivel del firewall del kernel por defecto.",
"Se consulta desde el hook <code>before_request</code> de Flask cada 30 s — así que incluso cuando el firewall no puede bloquear (porque la conexión viene del reverse proxy), la aplicación devuelve HTTP 403 a las IPs baneadas según lo que Fail2Ban sabe."
"El hook <code>before_request</code> de Flask contrasta las peticiones con la lista de bloqueos, almacenada en caché durante 30 s. Tras un proxy inverso, el bloqueo por IP requiere también PROXMENUX_TRUST_PROXY=1 y un proxy controlado que establezca cabeceras fiables."
],
"outro": "La configuración, el ajuste del tiempo de ban y los procedimientos de desbaneo están en <link>Seguridad → Fail2Ban</link>."
},
@@ -367,17 +367,17 @@
"heading": "Por dónde seguir",
"items": [
{
"label": "API Reference → Token Management",
"label": "Referencia de la API → Gestión de tokens",
"href": "/docs/monitor/api",
"tail": " — ciclo de vida completo de API tokens (generar / listar / revocar), mejores prácticas de seguridad, patrones de almacenamiento de secrets."
},
{
"label": "Integrations",
"label": "Integraciones",
"href": "/docs/monitor/integrations",
"tail": " — Homepage, Home Assistant, Grafana / Prometheus, Uptime Kuma, cURL genérico."
},
{
"label": "Dashboard → Security → Secure Gateway",
"label": "Dashboard → Seguridad → Secure Gateway",
"href": "/docs/monitor/dashboard/security",
"tail": " — despliega el LXC gateway Tailscale paso a paso (subnet routes, ACLs, modo Exit Node)."
},
@@ -387,7 +387,7 @@
"tail": " — cómo instalar y configurar el jail opcional."
},
{
"label": "Settings → ProxMenux Monitor",
"label": "Ajustes → ProxMenux Monitor",
"href": "/docs/settings/proxmenux-monitor",
"tail": " — arranca / para el servicio systemd desde la TUI de ProxMenux."
}
+47 -47
View File
@@ -1,7 +1,7 @@
{
"meta": {
"title": "Asistente de IA de Proxmox — OpenAI, Claude, Gemini, Groq, Ollama | ProxMenux Monitor",
"description": "El Asistente de IA opcional de ProxMenux Monitor reescribe los cuerpos de las notificaciones de Proxmox VE en lenguaje natural. Seis proveedores soportados: OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter y Ollama local. Doce idiomas, tres niveles de detalle por canal, modo de prompt personalizado con una biblioteca comunitaria y una capa de enriquecimiento de contexto que añade uptime, recurrencia y datos SMART a los eventos de disco.",
"description": "El asistente de IA opcional reescribe las notificaciones de Proxmox VE en lenguaje claro. Seis proveedores: OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter y Ollama. La interfaz ofrece trece idiomas, tres niveles de detalle por canal, prompts personalizados con una biblioteca comunitaria y contexto del evento con tiempo de actividad, recurrencia y datos SMART.",
"ogTitle": "Asistente de IA de Proxmox — OpenAI, Claude, Gemini, Groq, Ollama",
"ogDescription": "Reescribe las notificaciones de Proxmox VE en lenguaje natural con OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter u Ollama local.",
"twitterTitle": "Asistente de IA de Proxmox | ProxMenux Monitor",
@@ -9,16 +9,16 @@
},
"header": {
"title": "Asistente de IA",
"description": "El reescritor opt-in que pasa cada notificación saliente por un LLM antes del fan-out — convirtiendo templates estructuradas en mensajes en lenguaje natural, con niveles de detalle por canal, doce idiomas, un modo de prompt personalizado con una biblioteca comunitaria pública y una capa de enriquecimiento de contexto que añade uptime, recurrencia, datos SMART y coincidencias con errores conocidos al prompt.",
"section": "ProxMenux Monitor"
"description": "La reescritura opcional con IA convierte las plantillas de notificación admitidas en mensajes claros, con detalle por canal, trece idiomas en la interfaz, prompts personalizados, una biblioteca comunitaria pública y contexto adicional. Los informes <code>backup_complete</code> y <code>backup_fail</code> omiten la IA por completo.",
"section": "Monitor de ProxMenux"
},
"intro": {
"title": "Desactivado por defecto, un solo interruptor para activarlo",
"body": "La reescritura con IA es opt-in. Hasta que pulses el toggle maestro dentro de <em>Settings → Notifications → Advanced: AI Enhancement</em>, cada evento se despacha con el cuerpo templated original. Cuando el toggle está activado y una llamada al proveedor falla o caduca, el dispatcher cae silenciosamente al cuerpo templated — tus notificaciones nunca se bloquean por el LLM."
"body": "La reescritura con IA viene desactivada. Actívala en <em>Ajustes → Notificaciones → Avanzado: mejora con IA</em>. Si falla el enriquecimiento o la reescritura, se envía la plantilla original. Las reescrituras de la cola de eventos tienen un tiempo límite de 25 segundos; al alcanzarlo se envía la plantilla en lugar de esperar."
},
"howItWorks": {
"heading": "Cómo funciona",
"intro": "Cada evento que despacha el Monitor pasa por la misma pipeline. El reescritor de IA es una etapa opcional que se sitúa entre el cuerpo templated y el envío del canal. De principio a fin, un solo evento camina por cuatro pasos:",
"intro": "Los eventos enviados por Monitor siguen el mismo proceso. La reescritura con IA es una etapa opcional entre el texto generado por la plantilla y el envío al canal. Un evento pasa por cuatro pasos:",
"steps": [
"<strong>Evento + template.</strong> Un evento llega desde uno de los seis colectores y se renderiza en un cuerpo estructurado de texto plano por <code>notification_templates.py</code>. Este es el cuerpo que el canal enviaría si la reescritura con IA estuviese desactivada.",
"<strong>Enriquecimiento de contexto.</strong> El dispatcher inspecciona el evento y añade condicionalmente las señales extra relevantes — uptime del sistema (solo para fallos críticos del sistema), frecuencia del evento, datos SMART (solo para eventos de disco), coincidencias con la base de datos de errores conocidos y líneas de log del journal.",
@@ -83,7 +83,7 @@
"intro1": "Cada proveedor comercial cobra por <em>token</em>, así que merece la pena entender qué es un token antes de elegir un plan. Un token son aproximadamente cuatro caracteres de texto en inglés o unas tres cuartas partes de una palabra. La frase <em>\"Backup completed on storage local-bak\"</em> son unos ocho tokens. Un extracto corto de journal de diez líneas puede ser 200-400 tokens según la densidad técnica.",
"intro2": "Se facturan dos cosas en cada llamada:",
"items": [
"<strong>Tokens de entrada</strong> — el system prompt más el user message (severidad, título, cuerpo, contexto enriquecido). Para ProxMenux el system prompt solo es del orden de 1.5-2 KB (≈ 400-500 tokens) y el user message varía de 50 tokens (un backup-complete limpio) a ~1500 tokens (un error de disco con 30 líneas de contexto del journal).",
"<strong>Tokens de entrada</strong>: incluyen las instrucciones del sistema y el mensaje de usuario: severidad, título, texto de la plantilla y contexto adicional. La cantidad depende del prompt y del evento. Cada canal reescrito puede consumir sus propios tokens de entrada; los informes de backup completado y fallido omiten la IA.",
"<strong>Tokens de salida</strong> — lo que el modelo escribe de vuelta. El Monitor lo limita con <code>max_tokens</code> (mira la tabla de abajo). El límite es un <em>tope</em>, no un cargo: si el modelo produce 250 tokens con un tope de 1500, pagas 250."
],
"capsIntro": "Estos son los topes reales que aplica el dispatcher, tomados directamente de <code>AI_DETAIL_TOKENS</code> en <code>notification_templates.py</code>:",
@@ -92,24 +92,24 @@
"headerConsumption": "Consumo real típico",
"capRows": [
{
"level": "brief",
"level": "breve",
"cap": "500",
"consumption": "50-200 tokens de salida para eventos cortos."
},
{
"level": "standard",
"level": "estándar",
"cap": "1500",
"consumption": "200-700 tokens de salida para eventos típicos con contexto ligero."
},
{
"level": "detailed",
"level": "detallado",
"cap": "3000",
"consumption": "500-2000 tokens de salida para reportes completos de email con logs y tablas SMART."
}
],
"customNote": "El modo de prompt personalizado usa un tope fijo de 500 tokens de salida independientemente del nivel de detalle — el prompt personalizado está bajo tu control y el tope protege contra respuestas descontroladas.",
"sizingTitle": "Dimensionamiento práctico",
"sizingBody": "Un homelab con 50-100 eventos al día en <code>standard</code> consume típicamente unos pocos miles de tokens al día. Con los niveles gratuitos que ofrecen Groq y Gemini, eso encaja sin tocar un plan de pago. Con OpenAI o Anthropic, facturados por token, el coste se queda en el rango de céntimos al mes para ese volumen. Si tu volumen de eventos es mucho mayor, la sección <link>Nivel de detalle por canal</link> explica cómo mantener los canales de chat en <code>brief</code> dejando que Email lleve el reporte completo."
"sizingBody": "Estima el consumo como eventos reescritos × canales con IA × tokens de entrada y salida por llamada. Por ejemplo: 50 eventos × un canal × (2.000 de entrada + 300 de salida) son unos 115.000 tokens al día, porque el prompt de sistema predeterminado ya ocupa unos 1.500 tokens. El consumo y coste reales dependen del modelo, contexto, caché y límites del proveedor. <link>Nivel de detalle por canal</link> explica cómo usar <code>brief</code> para chat en lugar de <code>standard</code>, manteniendo informes detallados por correo."
},
"providers": {
"heading": "Proveedores de IA",
@@ -120,18 +120,18 @@
"heading": "Groq",
"tagline": "Muy rápido, nivel gratuito generoso (30 req/min). Ideal para empezar.",
"items": [
"API key: <a>console.groq.com/keys</a>",
"Modelos verificados: <code>llama-3.3-70b-versatile</code>, <code>llama-3.1-70b-versatile</code>, <code>llama-3.1-8b-instant</code>, <code>llama3-70b-8192</code>, <code>llama3-8b-8192</code>, <code>mixtral-8x7b-32768</code>, <code>gemma2-9b-it</code>.",
"Recomendado: <strong><code>llama-3.3-70b-versatile</code></strong> — mejor calidad a la velocidad de inferencia completa de Groq."
"Clave API: <a>console.groq.com/keys</a>",
"Ejemplos de la lista de modelos incluida: <code>allam-2-7b</code>, <code>qwen/qwen3.8-27b</code>, <code>openai/gpt-oss-20b</code>, <code>groq/compound-mini</code>.",
"Recomendación incluida: <strong><code>openai/gpt-oss-20b</code></strong>. Comprueba su disponibilidad para tu cuenta con el selector del proveedor y la prueba de conexión."
]
},
"openai": {
"heading": "OpenAI",
"tagline": "Estándar de la industria. Muy preciso y ampliamente usado.",
"items": [
"API key: <a>platform.openai.com/api-keys</a>",
"Modelos verificados: <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-chat-latest</code>, <code>gpt-5.4-nano</code>, <code>gpt-5.4-mini</code>.",
"Recomendado: <strong><code>gpt-4.1-nano</code></strong> — el miembro más barato de la familia chat, calidad suficiente para traducción y reformateo. Los modelos de razonamiento (serie o, gpt-5 non-chat) están soportados por el plumbing del proveedor pero se mantienen fuera de la lista verificada: mayor latencia sin ganancia medible de calidad en esta carga de trabajo."
"Clave API: <a>platform.openai.com/api-keys</a>",
"Ejemplos de la lista de modelos incluida: <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>.",
"Recomendación incluida: <strong><code>gpt-4.1-nano</code></strong>. El adaptador también gestiona requisitos específicos de los modelos de razonamiento; la lista incluye gpt-5-nano, por lo que no se excluyen todos esos modelos."
],
"baseUrlTitle": "Base URL compatible con OpenAI",
"baseUrlBody": "El proveedor OpenAI también acepta una <em>Base URL</em> personalizada, que te permite apuntar el Monitor a cualquier endpoint compatible con OpenAI. Confirmado que funciona con <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> y cualquier otro servicio que hable el dialecto OpenAI <code>/v1/chat/completions</code>. Configura la URL en la pestaña OpenAI junto al campo de API key."
@@ -140,17 +140,17 @@
"heading": "Anthropic (Claude)",
"tagline": "Excelente para escritura y traducción. Rápido y económico.",
"items": [
"API key: <a>console.anthropic.com/settings/keys</a>",
"Modelos verificados: <code>claude-3-5-haiku-latest</code>, <code>claude-3-5-sonnet-latest</code>, <code>claude-3-opus-latest</code>.",
"Recomendado: <strong><code>claude-3-5-haiku-latest</code></strong> — el modelo más pequeño y rápido de Claude, con calidad lingüística fuerte para la carga de traducción."
"Clave API: <a>console.anthropic.com/settings/keys</a>",
"Ejemplos de la lista de modelos incluida: <code>claude-haiku-4-5-20251001</code>, <code>claude-sonnet-4-6</code>, <code>claude-opus-4-6</code>.",
"Recomendación incluida: <strong><code>claude-haiku-4-5-20251001</code></strong>, una versión fija y no un alias que cambie."
]
},
"gemini": {
"heading": "Google Gemini",
"tagline": "Nivel gratuito disponible, gran ratio calidad/precio.",
"items": [
"API key: <a>aistudio.google.com/app/apikey</a>",
"Modelos verificados: <code>gemini-2.5-flash-lite</code>, <code>gemini-2.5-flash</code>, <code>gemini-3-flash-preview</code>.",
"Clave API: <a>aistudio.google.com/app/apikey</a>",
"Ejemplos de la lista de modelos incluida: <code>gemini-2.5-flash-lite</code>, <code>gemini-2.5-flash</code>, <code>gemini-3-flash-preview</code>.",
"Recomendado: <strong><code>gemini-2.5-flash-lite</code></strong> — flash y flash-lite pasan el verificador consistentemente. Las variantes pro rechazan el ajuste <code>thinkingBudget=0</code> que usa el Monitor y son excesivas para esta carga."
]
},
@@ -158,14 +158,14 @@
"heading": "OpenRouter",
"tagline": "Agregador con acceso a más de 100 modelos usando una única API key. Máxima flexibilidad.",
"items": [
"API key: <a>openrouter.ai/keys</a>",
"Modelos verificados: <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-3.5-haiku</code>, <code>anthropic/claude-3.5-sonnet</code>, <code>google/gemini-flash-1.5</code>, <code>openai/gpt-4o-mini</code>, <code>mistralai/mistral-7b-instruct</code>, <code>mistralai/mixtral-8x7b-instruct</code>.",
"Clave API: <a>openrouter.ai/keys</a>",
"Ejemplos de la lista de modelos incluida: <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>.",
"Recomendado: <strong><code>meta-llama/llama-3.3-70b-instruct</code></strong> — mismo modelo que la entrada de Groq pero enrutado por OpenRouter, lo que significa una sola key para todos los modelos listados."
]
},
"ollama": {
"heading": "Ollama (Local)",
"tagline": "Usa los modelos disponibles en tu servidor Ollama. 100% local, sin costes, privacidad total.",
"heading": "Ollama (local)",
"tagline": "Usa los modelos expuestos por el servidor Ollama configurado. Los modelos locales se ejecutan allí; los modelos cloud de Ollama envían las peticiones a un proveedor externo. La ejecución local evita cargos de API alojada, pero utiliza tu hardware y electricidad.",
"items": [
"Sin API key. Configura el campo <em>Ollama URL</em> a tu servidor (por defecto <code>http://localhost:11434</code> o el host que ejecute tu instancia de Ollama).",
"Modelos: <strong>no filtrados.</strong> El Monitor lee los modelos que hayas descargado en el lado de Ollama vía <code>ollama pull &lt;model&gt;</code>. El dropdown se llena desde <code>GET /api/tags</code> en tu servidor Ollama.",
@@ -175,14 +175,14 @@
},
"models": {
"heading": "Por qué estos modelos en concreto",
"intro": "El dropdown de modelos para cada proveedor comercial se llena desde una lista curada que viene con el Monitor (<code>verified_ai_models.json</code>). Los modelos en esta lista se han probado de principio a fin con el formato de la API chat / completions que usa el Monitor, con la forma exacta <code>system_prompt + user_message + max_tokens</code> que envía el AI Enhancer. La lista se refresca antes de cada release de ProxMenux con una herramienta verificadora privada que prueba cada modelo candidato y poda los que se comportan mal.",
"intro": "Los modelos comerciales proceden del catálogo de compatibilidad incluido <code>verified_ai_models.json</code>, combinado con las comprobaciones del adaptador de cada proveedor. Los adaptadores convierten la petición interna <code>system_prompt + user_message + max_tokens</code> al formato de su API. El catálogo incluye entradas probadas y añadidos manuales; es una lista fechada, sin garantía de acceso actual ni de que todas las entradas hayan pasado el mismo verificador.",
"consequencesIntro": "Dos consecuencias que merece la pena conocer:",
"consequences": [
"<strong>El modelo recomendado</strong> para cada proveedor es el que tiene el mejor equilibrio de calidad, latencia y coste específicamente para traducción de notificaciones — no el modelo más capaz que vende el proveedor. Las reescrituras de notificaciones no necesitan razonamiento de modelo frontera; necesitan rapidez y bajo coste.",
"<strong>Aun así puedes elegir otro modelo verificado</strong> del dropdown — a veces tienes una cuota de nivel gratuito que quieres gastar en un modelo concreto, o tienes una preferencia fuerte. Elige cualquiera de las entradas listadas; todas han pasado el verificador."
"<strong>La recomendación incluida</strong> es un punto de partida para formatear notificaciones. Evalúa calidad lingüística, latencia y coste con tus eventos y tu cuenta; no es una clasificación universal de modelos.",
"<strong>Puedes elegir otro modelo de la lista</strong> según tu cuota o preferencias. Comprueba su disponibilidad con la prueba de conexión; aparecer en la lista no garantiza acceso actual para tu cuenta."
],
"ollamaTitle": "Ollama es la excepción",
"ollamaBody": "Los modelos de Ollama son locales y el Monitor no los filtra — el dropdown refleja lo que hayas descargado. Elige un modelo del rango 7B-13B con al menos una ventana de contexto de 8K para que la reescritura con IA se comporte razonablemente con los bloques de contexto de journal."
"ollamaBody": "La lista de Ollama no se filtra por el catálogo comercial; refleja los modelos del servidor Ollama. Para ejecución local, elige un modelo local que quepa en RAM y tenga contexto suficiente para los logs. Los modelos cloud son remotos aunque se acceda a ellos mediante un servidor Ollama local."
},
"defaultPrompt": {
"heading": "Prompt por defecto",
@@ -205,8 +205,8 @@
"changes": [
"<strong>El prompt por defecto se reemplaza por completo.</strong> Los mappings de Proxmox, las reglas de manejo de contexto y las instrucciones de emoji desaparecen todas. Si quieres conservar cualquiera de ellas, pégalas en tu prompt — el <code>EXAMPLE_CUSTOM_PROMPT</code> empaquetado mostrado abajo es un punto de partida.",
"<strong>El selector de Language se ignora.</strong> El prompt por defecto tiene un placeholder <code>'{'language'}'</code>; el prompt personalizado no. Si quieres salida en un idioma específico, declárala dentro de tu prompt (\"Translate to Spanish\", \"Output everything in French\").",
"<strong>El nivel de detalle sigue aplicando</strong> en el sentido de que está disponible como ajuste por canal, pero el tope de tokens de salida pasa a ser fijo de 500 en modo custom (vs la rampa 500 / 1500 / 3000 del prompt por defecto). Si tu prompt personalizado pide un reporte largo, sube el tope editando el prompt o divide la petición.",
"<strong>Los marcadores de Output Format siguen siendo obligatorios.</strong> El Monitor parsea la respuesta buscando <code>[TITLE]</code> y <code>[BODY]</code> en sus propias líneas. Un prompt personalizado que no emita esos marcadores romperá el parser y caerá al cuerpo templated original.",
"<strong>El tope del modo personalizado es fijo: 500 tokens</strong>, independientemente del detalle guardado por canal. El modo predeterminado usa 500 / 1500 / 3000. Editar el prompt no eleva el tope; pide una respuesta más breve o usa un nivel predeterminado adecuado.",
"<strong>Los marcadores de salida siguen siendo obligatorios.</strong> Incluye <code>[TITLE]</code> y <code>[BODY]</code> en el formato de respuesta. El analizador extrae su contenido; si falta uno, devuelve la plantilla original.",
"<strong>Las reglas de emoji de Rich messages no se autoinyectan.</strong> Si quieres emojis, dile al prompt que los use. Si quieres texto plano, dile que no. El toggle solo gatea los bloques empaquetados del prompt por defecto, no tu cadena personalizada."
],
"starterTitle": "Prompt inicial",
@@ -215,19 +215,19 @@
"shareTitle": "Compartir prompts con la comunidad",
"shareIntro": "El botón <em>Export</em> escribe tu prompt personalizado actual en un archivo (<code>.txt</code> / <code>.md</code>) que puedes guardar como backup o pasar a otra persona. <em>Import</em> lo trae de vuelta. El tercer botón al lado enlaza con una galería comunitaria pública en GitHub:",
"shareLinkLabel": "github.com/MacRimi/ProxMenux/discussions — Comparte prompts personalizados para notificaciones de IA",
"shareOutro": "Navega la discusión para ver qué han construido otros operadores — alertas escuetas tipo pager, reportes técnicos verbosos, variantes específicas por idioma. Si tuneas el tuyo y te gusta el resultado, publícalo allí: incluso una descripción de un párrafo de para qué optimiza tu prompt ayuda a la gente a elegir un buen punto de partida. El feedback sobre lo que funciona y lo que no es igualmente bienvenido."
"shareOutro": "Navega la discusión para ver qué han construido otros usuarios — alertas escuetas tipo pager, reportes técnicos verbosos, variantes específicas por idioma. Si tuneas el tuyo y te gusta el resultado, publícalo allí: incluso una descripción de un párrafo de para qué optimiza tu prompt ayuda a la gente a elegir un buen punto de partida. El feedback sobre lo que funciona y lo que no es igualmente bienvenido."
},
"suggestions": {
"heading": "AI Suggestions (BETA)",
"heading": "Sugerencias de IA (BETA)",
"intro": "AI Suggestions es un addon opt-in que deja al LLM añadir <strong>un</strong> consejo corto y accionable al final del cuerpo. Solo se activa cuando el modo de prompt es <em>Default</em>, el toggle maestro de IA está activado y el switch <em>AI Suggestions</em> está pulsado — e incluso entonces, el prompt instruye al modelo a saltarse el consejo cuando la causa o solución no esté clara.",
"formatIntro": "Cuando se añade un consejo, sigue este formato exacto:",
"rulesIntro": "Las reglas integradas en el addon (visibles en el bloque colapsable bajo la sección Default prompt de arriba):",
"rules": [
"El consejo se incluye <em>solo</em> si el contexto del journal o la base de datos de errores conocidos apunta claramente a una solución específica.",
"El consejo está limitado a 100 caracteres.",
"Debe ser específico (comando o ruta concretos) — los consejos genéricos los rechaza el propio prompt.",
"El prompt pide un consejo de menos de 100 caracteres; el analizador no comprueba ese límite por separado.",
"El prompt exige un comando o ruta concretos e indica al modelo que evite consejos genéricos.",
"Si un error conocido proporciona una solución, el LLM debe usar esa solución, no inventar una nueva.",
"Si nada en la entrada le da al LLM suficiente certeza para sugerir un arreglo concreto, el consejo se omite — sin adivinar."
"El prompt indica al modelo que omita el consejo si los datos no justifican una solución concreta."
],
"betaTitle": "Por qué BETA",
"betaBody": "La calidad del consejo depende de dos cosas fuera de ProxMenux: el modelo elegido y lo rico que era el contexto del journal para el evento. Con un modelo fuerte (Claude 3.5 Haiku, GPT-4.1 Mini, Llama 3.3 70B) y un error de disco que viene con smartctl + líneas de journal, el consejo es consistentemente útil. Con un modelo Ollama local pequeño y un evento de una línea, el consejo puede quedar pobre o saltarse por completo. Desactiva el toggle si encuentras los consejos ruidosos y reactívalo cuando lo quieras de vuelta."
@@ -241,19 +241,19 @@
"headerProduce": "Qué le pide el prompt al LLM que produzca",
"rows": [
{
"level": "brief",
"level": "breve",
"label": "2-3 líneas, solo esencial",
"cap": "500 tokens",
"produce": "\"Qué pasó + dónde\". Nada más."
},
{
"level": "standard",
"level": "estándar",
"label": "Conciso con contexto básico",
"cap": "1500 tokens",
"produce": "3-6 líneas: qué, dónde, causa, dispositivos afectados."
},
{
"level": "detailed",
"level": "detallado",
"label": "Detalles técnicos completos",
"cap": "3000 tokens",
"produce": "Reporte completo: qué, dónde, causa, afectados, logs, datos SMART, historial."
@@ -265,12 +265,12 @@
"<strong>Email</strong> — <code>detailed</code>. Email es el canal donde típicamente quieres la foto completa para archivo."
],
"emailTitle": "El nivel de detalle de Email añade el original",
"emailBody": "Cuando Email está en <code>detailed</code> y el cuerpo templated original tiene contenido sustancial (más de 50 caracteres), el dispatcher añade el mensaje original al final de la reescritura con IA, separado por un divisor de 40 guiones y una etiqueta <code>Original message:</code>. Esto significa que un email detallado siempre lleva tanto la versión amigable de IA como el template crudo amigable de máquina — útil cuando quieres hacer grep de una alerta antigua más tarde."
"emailBody": "Si el formateador devuelve un resultado para el correo en <code>detailed</code> y el texto original supera 50 caracteres, añade ese texto tras 40 guiones y la etiqueta <code>Original message:</code>. Así conserva los detalles para búsquedas posteriores. Cuando se omite la IA o falla, puede enviarse solo la plantilla original."
},
"language": {
"heading": "Idioma",
"intro": "Doce idiomas están cableados. El dropdown configura <code>ai_language</code> en la config y el valor se interpola en el system prompt en el sitio donde el prompt dice <em>\"translate alerts into '{'language'}'\"</em>. La lista completa:",
"list": "Inglés (<code>en</code>), Español (<code>es</code>), Francés (<code>fr</code>), Alemán (<code>de</code>), Portugués (<code>pt</code>), Italiano (<code>it</code>), Ruso (<code>ru</code>), Sueco (<code>sv</code>), Noruego (<code>no</code>), Japonés (<code>ja</code>), Chino (<code>zh</code>), Neerlandés (<code>nl</code>).",
"intro": "El selector de la interfaz ofrece trece idiomas. Guarda <code>ai_language</code>, que el prompt predeterminado usa en <em>\"translate alerts into '{'language'}'\"</em>. La lista es:",
"list": "Inglés (<code>en</code>), eslovaco (<code>sk</code>), español (<code>es</code>), francés (<code>fr</code>), alemán (<code>de</code>), portugués (<code>pt</code>), italiano (<code>it</code>), ruso (<code>ru</code>), sueco (<code>sv</code>), noruego (<code>no</code>), japonés (<code>ja</code>), chino (<code>zh</code>), neerlandés (<code>nl</code>).",
"rulesIntro": "Dos reglas importantes sacadas directamente del prompt:",
"rules": [
"<strong>Traducir</strong>: etiquetas, descripciones, palabras de estado, unidades (p. ej. GB → Go en francés).",
@@ -280,7 +280,7 @@
},
"templates": {
"heading": "Una nota sobre templates",
"body1": "El cuerpo que recibe la IA no es data cruda de evento — es una template prerrenderizada. Cada tipo de evento (<code>backup_complete</code>, <code>vm_start</code>, <code>auth_fail</code>, <code>health_degraded</code>, etc.) tiene una template en <code>notification_templates.py</code> que sabe cómo formatear ese evento específico en un cuerpo estructurado de texto plano. La IA reescribe ese cuerpo, no reemplaza el paso de templating.",
"body1": "La IA recibe una plantilla ya generada, no datos de evento sin procesar. Tipos como <code>vm_start</code>, <code>auth_fail</code> y <code>health_degraded</code> tienen plantillas en <code>notification_templates.py</code>. La IA reescribe los textos admitidos; <code>backup_complete</code> y <code>backup_fail</code> conservan sus informes deterministas y omiten la IA.",
"body2": "Dos implicaciones prácticas: la IA nunca ve un hostname o VMID que tenga que inventar — esos campos los pone la template antes de la reescritura. Y si la IA está desactivada, el cuerpo templated es lo que se despacha directamente. La página de <link>Notifications</link> documenta la pipeline de despacho completa y es la referencia cruzada correcta para todo lo que le pasa a un evento antes de llegar a esta capa."
},
"privacy": {
@@ -291,11 +291,11 @@
"rows": [
{
"provider": "Ollama",
"destination": "Se queda en el host Ollama. Si Ollama corre en el mismo nodo Proxmox, nada sale de la red en absoluto."
"destination": "Los modelos locales se ejecutan en el host Ollama configurado. Si es el propio nodo Proxmox, sus peticiones permanecen allí. Los modelos cloud de Ollama envían las peticiones fuera del host, incluso mediante un servidor Ollama local."
},
{
"provider": "OpenAI",
"destination": "<code>api.openai.com</code> (o tu endpoint Base URL personalizado). Sujeto a la política de manejo de datos de OpenAI en el momento de la llamada."
"destination": "<code>api.openai.com</code> de forma predeterminada o la URL base personalizada. Se aplica la política de datos del operador real de ese endpoint."
},
{
"provider": "Anthropic",
@@ -315,13 +315,13 @@
}
],
"calloutTitle": "Si el contenido del evento no puede salir de la red",
"calloutBody": "Usa Ollama, o desactiva el reescritor de IA. No hay terreno intermedio — el dispatcher no intenta redactar hostnames o IPs antes de enviar; el prompt se construye a partir del payload real del evento tal como lo ve el Monitor."
"calloutBody": "Usa un endpoint alojado en tu red con un modelo local, como Ollama local o un servidor compatible con OpenAI, o desactiva la IA. Los modelos cloud de Ollama no mantienen el procesamiento local. El sistema no anonimiza nombres de host ni IP; crea el prompt con el contenido real del evento."
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{
"label": "Notifications",
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tail": " — la pipeline de despacho, canales, toggles por evento y la integración del webhook de PVE que rodea esta capa."
},
+122 -122
View File
@@ -1,48 +1,48 @@
{
"meta": {
"title": "API de Proxmox Monitor — Referencia de integración | ProxMenux",
"description": "Endpoints HTTP expuestos por ProxMenux Monitor para integraciones: Home Assistant, Homepage, Grafana, Prometheus, n8n y paneles propios. Exportación de datos en solo lectura más las operaciones de escritura seguras que necesitan las automatizaciones — control de VMs, disparo de backup, despacho de notificaciones, acknowledgement de alertas.",
"description": "Endpoints HTTP de ProxMenux Monitor para Home Assistant, Homepage, Grafana, Prometheus, n8n y paneles propios. Consulta el estado y ejecuta operaciones documentadas: control de VM, inicio de backups, notificaciones y confirmación de alertas.",
"ogTitle": "API de Proxmox Monitor — Referencia de integración",
"ogDescription": "Endpoints expuestos por ProxMenux Monitor para Home Assistant, Homepage, Grafana, Prometheus, n8n y paneles propios.",
"ogDescription": "Endpoints de ProxMenux Monitor para Home Assistant, Homepage, Grafana, Prometheus, n8n y paneles propios.",
"twitterTitle": "API de Proxmox Monitor | ProxMenux",
"twitterDescription": "Endpoints para Home Assistant, Homepage, Grafana, Prometheus, n8n y paneles propios."
},
"header": {
"title": "API Reference",
"description": "Los endpoints HTTP que usan los integradores para leer estado y disparar acciones seguras en ProxMenux Monitor — sensores de Home Assistant, tarjetas de Homepage, paneles de Grafana, scrapes de Prometheus, flujos de n8n y scripts propios. Cada categoría, más una lista completa de métricas Prometheus, con ejemplos en curl.",
"title": "Referencia de la API",
"description": "Endpoints HTTP para consultar el estado y ejecutar acciones documentadas en ProxMenux Monitor: sensores de Home Assistant, tarjetas de Homepage, paneles Grafana, recogida de Prometheus, flujos n8n y scripts propios. Incluye categorías, métricas exportadas y ejemplos curl.",
"section": "ProxMenux Monitor"
},
"intro": {
"title": "Para qué es esta página",
"body": "Esta página lista los endpoints que esperamos que usen las integraciones externas — exportación de datos en solo lectura para cada parte del Monitor, más el pequeño conjunto de operaciones de escritura que las automatizaciones necesitan legítimamente (disparar un backup, enviar una notificación personalizada, dar acknowledgement a una alerta). Toda la API corre desde el mismo proceso Flask que sirve la UI del panel en TCP <strong>8008</strong>; la dirección de bind y TLS se configuran en <link>Access & Authentication</link>."
"body": "Esta página reúne endpoints para integraciones externas: datos de lectura y operaciones como iniciar backups, enviar avisos y confirmar alertas. La API usa el mismo proceso Flask que sirve el panel en TCP <strong>8008</strong>. La dirección de escucha y TLS se explican en <link>Acceso y autenticación</link>."
},
"headerEndpoint": "Endpoint",
"headerMethod": "Método",
"headerUse": "Uso",
"auth": {
"heading": "Autenticación",
"intro": "Cada endpoint marcado como \"authenticated\" espera un token bearer JWT en la cabecera de la petición:",
"intro": "Con la autenticación activada, los endpoints protegidos esperan un JWT Bearer en la cabecera de la petición:",
"tokensIntro": "Dos formas de obtener el token:",
"items": [
"<strong>API tokens (recomendado para integraciones).</strong> Tokens de larga duración emitidos desde <strong>Settings → Security → API Tokens</strong> en el panel. Cada token tiene un nombre, se puede revocar individualmente y es lo que deberías pasar a Home Assistant / Homepage / Grafana / n8n.",
"<strong>Flujo de login (JWT de corta duración).</strong> <code>POST /api/auth/login</code> con un username, password y token TOTP si el 2FA está activado. El JWT devuelto es de corta duración y el panel lo refresca automáticamente; útil para scripts ad-hoc que se autentican como un usuario humano."
"<strong>Tokens API, recomendados para integraciones.</strong> Valen 365 días y se crean en <strong>Seguridad → Tokens API</strong>. Tienen nombre y revocación individual. Usa read_only para datos y full_admin solo para acciones administrativas necesarias.",
"<strong>Inicio de sesión, JWT de 24 horas.</strong> <code>POST /api/auth/login</code> con usuario, contraseña y TOTP si lo exige 2FA. El JWT caduca a las 24 horas; los scripts deben volver a autenticarse después."
],
"flowLink": "El flujo de auth, la política de contraseñas, la configuración de 2FA, el log de auditoría y la configuración TLS viven todos en <link>Access & Authentication</link>.",
"flowLink": "El acceso, contraseñas, 2FA, auditoría y TLS se explican en <link>Acceso y autenticación</link>.",
"rows": [
{
"endpoint": "/api/auth/login",
"method": "POST",
"use": "Body: <code>'{'\"username\",\"password\",\"totp_token?\"'}'</code>. Devuelve un JWT de corta duración."
"use": "Campos del cuerpo (esquema): <code>'{'\"username\",\"password\",\"totp_token?\"'}'</code>. Devuelve un JWT de 24 horas."
},
{
"endpoint": "/api/auth/api-tokens",
"method": "GET",
"use": "Lista los API tokens (solo metadatos — nombres, prefijos, fechas; nunca el secret real)."
"use": "Lista los tokens API: nombres, prefijos y fechas; el valor secreto no se devuelve."
},
{
"endpoint": "/api/auth/api-tokens",
"endpoint": "/api/auth/generate-api-token",
"method": "POST",
"use": "Emite un nuevo API token de larga duración. Body: <code>'{'\"name\":\"'<'label'>'\"'}'</code>. El valor del token se devuelve una vez y no se puede recuperar de nuevo."
"use": "Crea un token API de 365 días con una sesión autenticada. Campos: <code>password, token_name?, totp_token?, scope?</code>. Se comprueban otra vez contraseña y TOTP requerido. scope usa read_only por defecto; full_admin se elige expresamente. El secreto se devuelve una sola vez."
},
{
"endpoint": "/api/auth/api-tokens/<id>",
@@ -54,10 +54,10 @@
"conventions": {
"heading": "Convenciones",
"items": [
"Todas las peticiones y respuestas son JSON salvo que se indique explícitamente (la descarga de logs es texto plano, <code>/api/prometheus</code> es text/plain en formato OpenMetrics, el log de tareas es texto plano).",
"Los endpoints que modifican estado con éxito devuelven <code>'{'\"success\": true, ...'}'</code>. Las respuestas de error usan un estado HTTP no-2xx con <code>'{'\"success\": false, \"error\": \"'<'reason'>'\"'}'</code>.",
"Los endpoints de listado aceptan <code>limit</code>, <code>offset</code>, <code>since</code> opcionales y filtros específicos por categoría vía query string.",
"Los campos de tiempo se devuelven como segundos epoch Unix o ISO-8601 con zona horaria explícita, nunca como cadenas de locale."
"La mayoría usa JSON. Algunas descargas son texto plano y <code>/api/prometheus</code> devuelve el formato de exposición de Prometheus 0.0.4, en vez de OpenMetrics. Comprueba el tipo de respuesta de cada ruta.",
"Muchas operaciones devuelven <code>'{'\"success\": true, ...'}'</code>. Los errores varían; una forma habitual es <code>'{'\"success\": false, \"error\": \"'<'reason'>'\"'}'</code>. Comprueba estado HTTP y campos: algunos retos de autenticación usan HTTP 200 con success false.",
"Los parámetros dependen del endpoint. Usa <code>limit</code>, <code>offset</code>, <code>since</code> y filtros por categoría solo si esa ruta los admite.",
"Los tiempos varían por endpoint: marcas Unix, cadenas ISO-8601 y fechas con formato systemd. No supongas una unidad común ni una zona horaria explícita en todos los campos."
]
},
"system": {
@@ -66,7 +66,7 @@
{
"endpoint": "/api/system",
"method": "GET",
"use": "CPU, memoria, swap, uptime, load — snapshot actual."
"use": "Valores actuales de CPU, memoria, swap, tiempo encendido y carga."
},
{
"endpoint": "/api/info",
@@ -76,93 +76,93 @@
{
"endpoint": "/api/system-info",
"method": "GET",
"use": "Snapshot extendido del sistema usado por la cabecera del panel (métricas globales + boot time)."
"use": "Datos ampliados usados por la cabecera del panel: métricas generales y hora de arranque."
},
{
"endpoint": "/api/hardware",
"method": "GET",
"use": "Inventario hardware detallado — dispositivos PCI, GPUs, mapa de sensores."
"use": "Inventario detallado de hardware: dispositivos PCI, GPU y sensores."
},
{
"endpoint": "/api/hardware/live",
"method": "GET",
"use": "Valores en vivo para sensores que cambian de segundo en segundo."
"use": "Valores actuales de sensores que cambian rápidamente."
},
{
"endpoint": "/api/temperature/history",
"method": "GET",
"use": "Serie temporal de temperaturas CPU / package."
"use": "Historial de temperaturas de CPU y encapsulado."
},
{
"endpoint": "/api/gpu/<slot>/realtime",
"method": "GET",
"use": "Métricas en vivo de GPU NVIDIA / Intel / AMD por slot PCI."
"use": "Métricas actuales de GPU NVIDIA, Intel y AMD por posición PCI."
}
]
},
"actions": {
"heading": "Acciones del sistema",
"intro": "Endpoints fire-and-forget que disparan las mismas operaciones que el usuario ejecutaría desde la interfaz del Monitor o desde el menú shell — pensados para Home Assistant, Homepage, Ansible, paneles personalizados y cualquier otra automatización que necesite alcanzar al host por HTTP. Toda ruta que muta el estado requiere un token con scope <code>full_admin</code>; los tokens <code>read_only</code> pueden consultar los endpoints <code>.../status</code> sin disparar nada. Cada acción devuelve 202 con una instantánea del estado; el cliente hace polling al <code>.../status</code> correspondiente para observar el progreso.",
"intro": "Estas acciones asíncronas se ejecutan en unidades systemd transitorias. Con autenticación activa, sus rutas de escritura exigen <code>full_admin</code>; <code>read_only</code> puede consultar <code>.../status</code>. El inicio aceptado devuelve HTTP 202 y estado; consulta <code>.../status</code> para el progreso. El control de invitados y los backups usan respuestas distintas, explicadas abajo.",
"shapeTitle": "Formato de respuesta común",
"shapeIntro": "Todos los endpoints de acción devuelven el mismo objeto JSON — una sola forma que parsear desde cualquier cliente:",
"shapeIntro": "Las acciones asíncronas del sistema comparten este objeto JSON de estado. El control de invitados y los backups tienen formatos distintos:",
"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": "Concurrencia y cancelación",
"concurrencyBody": "Un segundo POST mientras una ejecución está en curso devuelve 409 con el estado actual. Cancela una ejecución en curso con un DELETE a la URL base de la acción; el estado pasa a <code>cancelled</code> y los timestamps se conservan para que el cliente vea cuándo se disparó y se detuvo. El último estado terminal (success / failed / cancelled) se recuerda hasta que la siguiente ejecución lo reemplace.",
"concurrencyBody": "Iniciar otra ejecución de la misma acción activa devuelve HTTP 409. Solo se cancela si hay una ruta DELETE documentada, como en la actualización PVE. Su estado pasa a <code>cancelled</code> y conserva fechas. Los estados finales se guardan en memoria del proceso y pueden perderse al reiniciar Monitor.",
"rows": [
{
"endpoint": "/api/system/power/reboot",
"method": "POST",
"use": "Reiniciar el host Proxmox. Fire-and-forget — la conexión HTTP cae cuando systemd inicia la secuencia de apagado."
"use": "Inicia el reinicio del host Proxmox. La conexión HTTP puede cerrarse cuando systemd comienza el apagado."
},
{
"endpoint": "/api/system/power/reboot/status",
"method": "GET",
"use": "Estado de la última / actual acción de reinicio."
"use": "Estado del reinicio actual o anterior."
},
{
"endpoint": "/api/system/power/shutdown",
"method": "POST",
"use": "Apagar el host Proxmox. Útil como efecto conectado a una señal de apagado del SAI."
"use": "Apaga el host Proxmox; puede conectarse a una señal de apagado del SAI."
},
{
"endpoint": "/api/system/power/shutdown/status",
"method": "GET",
"use": "Estado de la última / actual acción de apagado."
"use": "Estado del apagado actual o anterior."
},
{
"endpoint": "/api/system/pve-update/run",
"method": "POST",
"use": "Disparar el flujo seguro de actualización de PVE (el mismo que ejecuta el botón Update Now del Health Monitor y el menú shell — delega en update-pve-safe.sh)."
"use": "Inicia la actualización de PVE usada por Actualizar ahora de Health Monitor y el menú de consola; delega en update-pve-safe.sh."
},
{
"endpoint": "/api/system/pve-update/status",
"method": "GET",
"use": "Estado de la última / actual ejecución de actualización de PVE."
"use": "Estado de la actualización PVE actual o anterior."
},
{
"endpoint": "/api/system/pve-update",
"method": "DELETE",
"use": "Cancelar una actualización de PVE en curso (SIGTERM al script en ejecución)."
"use": "Cancela una actualización PVE en curso mediante SIGTERM al proceso."
},
{
"endpoint": "/api/proxmenux/self-update/run",
"method": "POST",
"use": "Actualizar el propio ProxMenux canalizando el instalador estable canónico. Corre en su propia unit systemd para que la actualización complete a pesar del reinicio de proxmenux-monitor que el instalador realiza."
"use": "Actualiza ProxMenux con el instalador del canal estable o beta configurado. Usa su propia unidad systemd para poder continuar durante el reinicio de proxmenux-monitor que realiza el instalador."
},
{
"endpoint": "/api/proxmenux/self-update/status",
"method": "GET",
"use": "Estado de la última / actual ejecución de self-update de ProxMenux."
"use": "Estado de la actualización de ProxMenux actual o anterior."
},
{
"endpoint": "/api/vms/<vmid>/control",
"method": "POST",
"use": "Encender / apagar / apagar limpio / reiniciar una VM o contenedor LXC (las mismas operaciones que expone la modal VM & LXC del Monitor). El cuerpo lleva <code>action</code>: <code>start</code>, <code>stop</code>, <code>shutdown</code> o <code>reboot</code>. Síncrono — devuelve el resultado directo sin necesidad de polling."
"use": "Envía una orden de control de VM o LXC. El campo <code>action</code> admite <code>start</code>, <code>stop</code>, <code>shutdown</code> o <code>reboot</code>. La respuesta correcta devuelve una tarea PVE confirmada, sin indicar que ya haya terminado. Consulta el endpoint control-task del invitado para obtener el resultado."
},
{
"endpoint": "/api/vms/<vmid>/backup",
"method": "POST",
"use": "Crear un backup vzdump de una VM o LXC. Campos del cuerpo, todos opcionales salvo cuando los valores por defecto no encajan con la distribución del almacenamiento: <code>storage</code> (un almacenamiento de PVE), <code>mode</code> (<code>snapshot</code>, <code>suspend</code> o <code>stop</code>), <code>compress</code> (<code>zstd</code>, <code>lzo</code>, <code>gz</code> o <code>none</code>), <code>protected</code> (<code>true</code> o <code>false</code>), <code>notes</code>, <code>notification</code> (<code>auto</code>, <code>always</code>, <code>failure</code> o <code>never</code>) y <code>pbs_change_detection</code> (<code>default</code>, <code>legacy</code> o <code>data</code>). Devuelve el UPID de la tarea PVE."
"use": "Crea un backup vzdump de una VM o LXC. Campos opcionales, ajustables según el almacenamiento: <code>storage</code> (destino PVE), <code>mode</code> (<code>snapshot</code>, <code>suspend</code> o <code>stop</code>), <code>compress</code> (<code>zstd</code>, <code>lzo</code>, <code>gzip</code> o <code>none</code>), <code>protected</code> (<code>true</code> o <code>false</code>), <code>notes</code> y <code>pbs_change_detection</code> (<code>default</code>, <code>legacy</code> o <code>data</code>). Devuelve el UPID de la tarea PVE."
},
{
"endpoint": "/api/vms/<vmid>/backups",
@@ -170,14 +170,14 @@
"use": "Listar backups anteriores de una VM o LXC en todos los storages accesibles."
}
],
"syncVsAsyncTitle": "Dos estilos de acción",
"syncVsAsyncBody": "Las acciones a nivel de sistema (power del host, PVE update, self-update de ProxMenux) pueden tardar minutos — corren en su propia unit systemd transitoria y exponen un endpoint <code>.../status</code> más un <code>DELETE</code> para cancelar. Las acciones VM / LXC (start, stop, shutdown, reboot, backup) son rápidas y usan el estilo fire-and-return que la UI del Monitor ya expone: el POST devuelve el resultado directo. Ambos estilos comparten el mismo modelo de autenticación (JWT o token de API de larga duración).",
"curlTitle": "Ejemplo con curl",
"curlBody": "Disparar una actualización de PVE y hacer polling hasta que termine — exactamente la misma secuencia que ejecutaría una automatización de Home Assistant o un playbook de Ansible:",
"syncVsAsyncTitle": "Dos tipos de acción",
"syncVsAsyncBody": "Encendido, apagado y actualizaciones del host usan unidades systemd transitorias con <code>.../status</code>. Solo la actualización PVE tiene aquí una ruta de cancelación <code>DELETE</code>. El control VM/LXC devuelve una tarea que debe consultarse; el backup devuelve un UPID de trabajo en segundo plano. Aceptar la petición no equivale a terminarla. Autenticación y permisos dependen de la ruta.",
"curlTitle": "Ejemplo curl",
"curlBody": "Inicia una actualización PVE y consulta hasta que termine: la secuencia que usaría una automatización Home Assistant o 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": "Snippet de integración con Home Assistant",
"haBody": "Un sensor <code>rest</code> hace polling del estado y un <code>rest_command</code> dispara la actualización. Conecta ambos a un botón del dashboard y a las automatizaciones que quieras:",
"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 # Encender VM 100 (funciona igual para LXC — mismo 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 de la VM 100 al storage 'pbs-main'\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\""
"haTitle": "Ejemplo para Home Assistant",
"haBody": "Un sensor <code>rest</code> consulta el estado y <code>rest_command</code> inicia la actualización. Úsalos con un botón del panel y las automatizaciones que necesites:",
"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": "Monitor de salud",
@@ -185,22 +185,22 @@
{
"endpoint": "/api/health",
"method": "GET",
"use": "Probe pequeño de salud — devuelve JSON con <code>status</code>, <code>timestamp</code>, <code>version</code>. Adecuado para keyword checks de Uptime Kuma; el receptor debe enviar la cabecera bearer."
"use": "Comprobación ligera que devuelve JSON con <code>status</code>, <code>timestamp</code> y <code>version</code>. Sirve para palabras clave de Uptime Kuma; con autenticación activa, el cliente debe enviar la cabecera Bearer."
},
{
"endpoint": "/api/health/status",
"method": "GET",
"use": "Veredicto global de salud — severidad única + cadena de resumen."
"use": "Estado global: un nivel de gravedad y un resumen."
},
{
"endpoint": "/api/health/details",
"method": "GET",
"use": "Las diez categorías con estados por categoría y el payload estructurado que produjo cada uno."
"use": "Las diez categorías con estado y datos estructurados de cada comprobación."
},
{
"endpoint": "/api/health/full",
"method": "GET",
"use": "Snapshot completo — categorías + errores activos + lista de dismissed + ajustes de supresión personalizados. Alimenta el modal en un round-trip; usa una caché de fondo de 6 min para respuesta instantánea."
"use": "Datos completos: categorías, errores activos, alertas descartadas y ajustes de silenciamiento. Usa resultados de fondo con menos de seis minutos; si no hay caché reciente o fuerzas la actualización, ejecuta una comprobación nueva."
},
{
"endpoint": "/api/health/active-errors",
@@ -210,12 +210,12 @@
{
"endpoint": "/api/health/dismissed",
"method": "GET",
"use": "Lista de dismissed con las horas de supresión restantes."
"use": "Alertas descartadas con horas de silencio restantes."
},
{
"endpoint": "/api/health/settings",
"method": "GET",
"use": "Valores de Suppression Duration por categoría configurados actualmente."
"use": "Duración de silenciamiento configurada para cada categoría."
},
{
"endpoint": "/api/health/remote-storages",
@@ -225,12 +225,12 @@
{
"endpoint": "/api/health/interfaces",
"method": "GET",
"use": "Inventario de interfaces de red con tipo (bridge / bond / physical), IP y velocidad de enlace."
"use": "Interfaces de red con tipo (bridge / bond / física), IP y velocidad del enlace."
},
{
"endpoint": "/api/health/acknowledge",
"method": "POST",
"use": "Body: <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Descarta una alerta con la Suppression Duration configurada de la categoría."
"use": "Cuerpo: <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Silencia una alerta durante el periodo configurado para su categoría."
},
{
"endpoint": "/api/health/cleanup-orphans",
@@ -238,7 +238,7 @@
"use": "Limpieza manual de errores cuyo dispositivo o VM subyacente ha desaparecido. Idempotente."
}
],
"outro": "Las formas de respuesta y la semántica de las categorías viven en <link>Monitor de salud</link>."
"outro": "Los formatos de respuesta y las categorías se explican en <link>Health Monitor</link>."
},
"storage": {
"heading": "Almacenamiento",
@@ -246,7 +246,7 @@
{
"endpoint": "/api/storage",
"method": "GET",
"use": "Todos los discos visibles al host (block devices, pools ZFS, LVM)."
"use": "Discos visibles para el host: dispositivos de bloques, pools ZFS y LVM."
},
{
"endpoint": "/api/storage/summary",
@@ -261,7 +261,7 @@
{
"endpoint": "/api/storage/observations",
"method": "GET",
"use": "Historial permanente de observaciones de disco — advertencias SMART, errores I/O, eventos de pool ZFS, conservados a través de auto-resoluciones de errores."
"use": "Historial persistente de observaciones: avisos SMART, errores de E/S y eventos ZFS. Se conserva aunque se resuelva la alerta."
},
{
"endpoint": "/api/storage/smart/<disk>",
@@ -286,7 +286,7 @@
{
"endpoint": "/api/storage/smart/<disk>/test",
"method": "POST",
"use": "Dispara un self-test SMART. Body: <code>'{'\"type\":\"short\"|\"long\"'}'</code>."
"use": "Inicia una prueba SMART. Esquema del cuerpo: <code>'{'\"test_type\":\"short\"|\"long\"'}'</code>."
},
{
"endpoint": "/api/storage/smart/schedules",
@@ -296,7 +296,7 @@
{
"endpoint": "/api/storage/smart/tools",
"method": "GET",
"use": "Detecta si <code>smartctl</code> y compañía están instalados."
"use": "Comprueba si están instalados <code>smartctl</code> y las herramientas asociadas."
}
]
},
@@ -316,12 +316,12 @@
{
"endpoint": "/api/network/<iface>/metrics",
"method": "GET",
"use": "RX / TX por interfaz, contadores de errores, serie temporal RRD."
"use": "RX/TX por interfaz, contadores de errores y series temporales RRD."
},
{
"endpoint": "/api/network/latency/current",
"method": "GET",
"use": "Último probe de latencia al gateway."
"use": "Última medición de latencia hasta la puerta de enlace."
},
{
"endpoint": "/api/network/latency/history",
@@ -336,7 +336,7 @@
{
"endpoint": "/api/vms",
"method": "GET",
"use": "Lista de todas las VMs y CTs con estado, vmid, nombre."
"use": "VM y CT del nodo local con estado, vmid y nombre."
},
{
"endpoint": "/api/vms/<vmid>",
@@ -351,22 +351,22 @@
{
"endpoint": "/api/vms/<vmid>/logs",
"method": "GET",
"use": "Logs de tareas recientes acotados a ese guest."
"use": "Registros de tareas recientes de ese invitado."
},
{
"endpoint": "/api/vms/<vmid>/backups",
"method": "GET",
"use": "Lista los backups actualmente conservados para este guest."
"use": "Backups conservados para este invitado."
},
{
"endpoint": "/api/vms/<vmid>/control",
"method": "POST",
"use": "Body: <code>'{'\"action\":\"start|stop|reboot|shutdown\"'}'</code>. Power-cycle de un guest."
"use": "Selecciona una acción del esquema: <code>'{'\"action\":\"start|stop|reboot|shutdown\"'}'</code>. Controla el estado de encendido del invitado."
},
{
"endpoint": "/api/vms/<vmid>/backup",
"method": "POST",
"use": "Dispara <code>vzdump</code> para ese guest. El body elige storage y modo (<code>snapshot</code> / <code>suspend</code> / <code>stop</code>)."
"use": "Inicia <code>vzdump</code> para el invitado. El cuerpo indica almacenamiento y modo (<code>snapshot</code> / <code>suspend</code> / <code>stop</code>)."
},
{
"endpoint": "/api/vms/<vmid>/config",
@@ -376,7 +376,7 @@
{
"endpoint": "/api/node/metrics",
"method": "GET",
"use": "Métricas agregadas a nivel de nodo (RRD)."
"use": "Métricas agregadas del nodo en series RRD."
}
]
},
@@ -386,12 +386,12 @@
{
"endpoint": "/api/backups",
"method": "GET",
"use": "Lista de backups a nivel de cluster."
"use": "Backups encontrados en almacenamientos dir, NFS, CIFS y PBS consultados desde el nodo local. No explora todos los nodos del clúster."
},
{
"endpoint": "/api/backup-storages",
"method": "GET",
"use": "Almacenamientos marcados como destinos de backup, con espacio libre."
"use": "Almacenamientos que admiten backups, con espacio libre."
}
]
},
@@ -406,7 +406,7 @@
{
"endpoint": "/api/logs/download",
"method": "GET",
"use": "Volcado en texto plano del rango filtrado."
"use": "Exporta el intervalo filtrado como texto plano."
},
{
"endpoint": "/api/events",
@@ -416,13 +416,13 @@
{
"endpoint": "/api/task-log/<upid>",
"method": "GET",
"use": "Log completo en texto plano para una tarea Proxmox por UPID."
"use": "Registro completo de una tarea Proxmox, en texto plano, identificado por UPID."
}
]
},
"notifications": {
"heading": "Notifications e IA",
"intro": "La pipeline de despacho, los walk-throughs de canales y la configuración del reescritor de IA viven en <notifLink>Notifications</notifLink> y <aiLink>Asistente de IA</aiLink>.",
"heading": "Notificaciones e IA",
"intro": "El envío, la configuración de canales y la reformulación con IA se explican en <notifLink>Notificaciones</notifLink> y <aiLink>Asistente de IA</aiLink>.",
"rows": [
{
"endpoint": "/api/notifications",
@@ -432,42 +432,42 @@
{
"endpoint": "/api/notifications/download",
"method": "GET",
"use": "Exporta notificaciones como texto."
"use": "Exporta las notificaciones como texto."
},
{
"endpoint": "/api/notifications/status",
"method": "GET",
"use": "Estado del dispatcher — si el hilo de fondo está corriendo, profundidad de cola, último envío."
"use": "Estado del envío: proceso de fondo activo, longitud de cola y último envío."
},
{
"endpoint": "/api/notifications/settings",
"method": "GET",
"use": "Lee la configuración completa de notificaciones (canales, toggles por evento, reescritor de IA, Display Name)."
"use": "Lee la configuración de notificaciones: canales, controles por evento, reformulación con IA y nombre visible."
},
{
"endpoint": "/api/notifications/history",
"method": "GET",
"use": "Historial de despacho. Query: <code>?limit=&offset=&severity=&channel=</code>."
"use": "Historial de envío. Parámetros: <code>?limit=&offset=&severity=&channel=</code>."
},
{
"endpoint": "/api/notifications/history",
"method": "DELETE",
"use": "Borra la tabla de historial de despacho."
"use": "Borra la tabla del historial de envío."
},
{
"endpoint": "/api/notifications/test",
"method": "POST",
"use": "Envía una notificación de prueba a un canal. Body: <code>'{'\"channel\":\"telegram\"'}'</code>."
"use": "Envía un aviso de prueba a un canal. Cuerpo: <code>'{'\"channel\":\"telegram\"'}'</code>."
},
{
"endpoint": "/api/notifications/send",
"method": "POST",
"use": "Emite un evento personalizado. Body: <code>'{'\"event_type\":\"custom\",\"severity\":\"WARNING\",\"title\":\"...\",\"body\":\"...\",\"data\":'{''}''}'</code>."
"use": "Emite un evento personalizado. Cuerpo: <code>'{'\"event_type\":\"custom\",\"severity\":\"WARNING\",\"title\":\"...\",\"body\":\"...\",\"data\":'{''}''}'</code>."
},
{
"endpoint": "/api/notifications/test-ai",
"method": "POST",
"use": "Prueba la conexión del proveedor de IA. Body: <code>'{'\"provider\",\"api_key\",\"model\",\"ollama_url?\"'}'</code>."
"use": "Prueba la conexión con el proveedor de IA. Campos del cuerpo (esquema): <code>'{'\"provider\",\"api_key\",\"model\",\"ollama_url?\"'}'</code>."
},
{
"endpoint": "/api/notifications/provider-models",
@@ -502,22 +502,22 @@
{
"endpoint": "/api/security/fail2ban/details",
"method": "GET",
"use": "Estado del jail Fail2Ban — solo útil cuando el jail opcional está instalado."
"use": "Estado del jail Fail2Ban; requiere tener instalado ese componente opcional."
},
{
"endpoint": "/api/security/fail2ban/activity",
"method": "GET",
"use": "Eventos recientes de Fail2Ban (bans, unbans, arranques de jail)."
"use": "Eventos recientes de Fail2Ban: bloqueos, desbloqueos y arranques del jail."
},
{
"endpoint": "/api/security/lynis/status",
"method": "GET",
"use": "Estado de última ejecución de Lynis (si está instalado, timestamp de último scan)."
"use": "Estado de Lynis: instalación y fecha del último análisis."
},
{
"endpoint": "/api/security/lynis/report",
"method": "GET",
"use": "Último reporte de auditoría Lynis (warnings, sugerencias, hardening index)."
"use": "Último informe Lynis: avisos, sugerencias e índice de refuerzo de seguridad."
},
{
"endpoint": "/api/security/tools",
@@ -532,7 +532,7 @@
{
"endpoint": "/api/proxmenux/update-status",
"method": "GET",
"use": "Si ProxMenux Monitor tiene actualización disponible, versión actual y última."
"use": "Disponibilidad de actualización de ProxMenux Monitor, versión instalada y más reciente."
},
{
"endpoint": "/api/proxmenux/installed-tools",
@@ -542,13 +542,13 @@
{
"endpoint": "/api/proxmenux/tool-source/<key>",
"method": "GET",
"use": "Código fuente de una función post-instalación específica — el bash exacto que se aplicó."
"use": "Código de la función posterior a la instalación asociada, extraído del script actual del host o de código antiguo conservado. No garantiza una copia del código exacto ejecutado originalmente."
}
]
},
"prometheus": {
"heading": "Métricas Prometheus",
"intro": "ProxMenux Monitor expone un endpoint de scrape formato Prometheus en <code>GET /api/prometheus</code> (autenticado) devolviendo texto formato OpenMetrics. Cada métrica está etiquetada con <code>node=\"&lt;hostname&gt;\"</code> y lleva un timestamp explícito para que ingese limpio en Prometheus, VictoriaMetrics, Mimir o cualquier TSDB compatible.",
"intro": "<code>GET /api/prometheus</code> con autenticación devuelve el formato de texto Prometheus 0.0.4. Cada métrica incluye <code>node=\"&lt;hostname&gt;\"</code> y una marca de tiempo explícita. Recógela con Prometheus u otra base temporal compatible.",
"exportedTitle": "Métricas exportadas",
"headerGroup": "Grupo",
"headerMetric": "Métrica",
@@ -559,7 +559,7 @@
"metrics": [
{
"metric": "proxmox_cpu_usage",
"desc": "Porcentaje de uso de CPU (gauge)."
"desc": "Porcentaje de uso de CPU, de tipo gauge."
},
{
"metric": "proxmox_memory_total_bytes",
@@ -567,7 +567,7 @@
},
{
"metric": "proxmox_memory_used_bytes",
"desc": "Memoria usada en bytes."
"desc": "Memoria utilizada en bytes."
},
{
"metric": "proxmox_memory_usage_percent",
@@ -575,16 +575,16 @@
},
{
"metric": "proxmox_load_average",
"desc": "Load average del sistema. Etiqueta <code>period=\"1m\" | \"5m\" | \"15m\"</code>."
"desc": "Carga media del sistema. Etiqueta <code>period=\"1m\" | \"5m\" | \"15m\"</code>."
}
]
},
{
"group": "Uptime",
"group": "Tiempo de actividad",
"metrics": [
{
"metric": "proxmox_uptime_seconds",
"desc": "Segundos desde el último boot."
"desc": "Segundos desde el último arranque."
}
]
},
@@ -593,15 +593,15 @@
"metrics": [
{
"metric": "proxmox_cpu_temperature_celsius",
"desc": "Temperatura del package de CPU."
"desc": "Temperatura del encapsulado de CPU."
},
{
"metric": "proxmox_disk_temperature_celsius",
"desc": "Temperatura por disco. Etiqueta <code>device</code>."
"desc": "Temperatura por disco. Etiqueta <code>disk</code>."
},
{
"metric": "proxmox_fan_speed_rpm",
"desc": "Velocidades de ventilador. Etiqueta <code>fan</code>."
"desc": "Velocidades de ventiladores. Etiqueta <code>fan</code>."
}
]
},
@@ -610,15 +610,15 @@
"metrics": [
{
"metric": "proxmox_disk_total_bytes",
"desc": "Espacio total de disco por mount. Etiqueta <code>mountpoint</code>."
"desc": "Capacidad total de cada entrada de disco exportada. Etiqueta <code>disk</code>."
},
{
"metric": "proxmox_disk_used_bytes",
"desc": "Espacio usado de disco por mount."
"desc": "Capacidad utilizada de cada entrada de disco exportada."
},
{
"metric": "proxmox_disk_usage_percent",
"desc": "Porcentaje de uso de disco por mount."
"desc": "Porcentaje utilizado de cada entrada de disco exportada."
}
]
},
@@ -627,11 +627,11 @@
"metrics": [
{
"metric": "proxmox_network_bytes_sent_total",
"desc": "Total de bytes enviados (counter)."
"desc": "Total de bytes enviados, de tipo counter."
},
{
"metric": "proxmox_network_bytes_received_total",
"desc": "Total de bytes recibidos (counter)."
"desc": "Total de bytes recibidos, de tipo counter."
},
{
"metric": "proxmox_interface_bytes_sent_total",
@@ -652,23 +652,23 @@
},
{
"metric": "proxmox_vms_running",
"desc": "Número de guests en ejecución."
"desc": "Número de invitados en ejecución."
},
{
"metric": "proxmox_vms_stopped",
"desc": "Número de guests parados."
"desc": "Número de invitados detenidos."
},
{
"metric": "proxmox_vm_status",
"desc": "Estado por VM/CT (1 = running, 0 = stopped). Etiquetas <code>vmid</code>, <code>name</code>, <code>type</code>."
"desc": "Estado por VM/CT: 1 en ejecución, 0 en otro estado. Etiquetas <code>node</code>, <code>vmid</code> y <code>name</code>."
},
{
"metric": "proxmox_vm_cpu_usage",
"desc": "Uso de CPU por VM/CT. Mismas etiquetas."
"desc": "Uso de CPU por VM/CT, con las mismas etiquetas."
},
{
"metric": "proxmox_vm_memory_used_bytes / _max_bytes",
"desc": "Memoria usada por VM/CT y máximo configurado."
"desc": "Memoria utilizada y máximo configurado por VM/CT."
}
]
},
@@ -677,7 +677,7 @@
"metrics": [
{
"metric": "proxmox_gpu_temperature_celsius",
"desc": "Temperatura de GPU. Etiquetas <code>slot</code>, <code>vendor</code>."
"desc": "Temperatura GPU. Etiquetas <code>slot</code> y <code>vendor</code>; también incluye el nombre de GPU en gpu."
},
{
"metric": "proxmox_gpu_utilization_percent",
@@ -685,19 +685,19 @@
},
{
"metric": "proxmox_gpu_memory_total_bytes",
"desc": "Total de memoria de GPU."
"desc": "Memoria total de la GPU."
},
{
"metric": "proxmox_gpu_power_draw_watts",
"desc": "Consumo de potencia de GPU en vatios."
"desc": "Consumo eléctrico de la GPU en vatios."
},
{
"metric": "proxmox_gpu_clock_speed_mhz",
"desc": "Velocidad de reloj del core de GPU."
"desc": "Frecuencia del núcleo de la GPU."
},
{
"metric": "proxmox_gpu_memory_clock_mhz",
"desc": "Velocidad de reloj de memoria de GPU."
"desc": "Frecuencia de la memoria de la GPU."
}
]
},
@@ -706,7 +706,7 @@
"metrics": [
{
"metric": "proxmox_ups_battery_charge_percent",
"desc": "Porcentaje de carga de batería."
"desc": "Porcentaje de carga de la batería."
},
{
"metric": "proxmox_ups_load_percent",
@@ -714,7 +714,7 @@
},
{
"metric": "proxmox_ups_runtime_seconds",
"desc": "Autonomía estimada en batería."
"desc": "Autonomía estimada con batería."
},
{
"metric": "proxmox_ups_input_voltage_volts",
@@ -724,36 +724,36 @@
}
],
"scrapeTitle": "Configuración de scrape de Prometheus",
"scrapeIntro": "El endpoint requiere autenticación. Pasa el API token como cabecera bearer en tu configuración de scrape de Prometheus:",
"perHostTitle": "Scrape por host",
"perHostBody": "Cada instancia de ProxMenux Monitor exporta métricas para el host en el que corre. En un cluster, apunta Prometheus a cada nodo — la etiqueta <code>node</code> en cada serie te permite distinguirlos en consultas Grafana (<code>proxmox_vms_running'{'node=\"pve01\"'}'</code>)."
"scrapeIntro": "Con autenticación activa, añade un token API a la cabecera Bearer de la configuración de recogida de Prometheus:",
"perHostTitle": "Recogida por host",
"perHostBody": "Cada instancia exporta métricas de su propio host. En un clúster, configura Prometheus para consultar cada nodo. La etiqueta <code>node</code> distingue las series en Grafana (<code>proxmox_vms_running'{'node=\"pve01\"'}'</code>)."
},
"puttingItTogether": {
"heading": "Juntándolo todo",
"body": "Para guías de principio a fin que conectan estos endpoints con sensores de Home Assistant, tarjetas de Homepage, paneles de Grafana, flujos de n8n y otras herramientas, mira la página dedicada <link>Integrations</link> — recorre la configuración típica de cada plataforma con ejemplos copia-pega. Esta página se mantiene centrada en el catálogo en sí."
"heading": "Combinar las integraciones",
"body": "Consulta <link>Integraciones</link> para conectar estos endpoints con sensores Home Assistant, tarjetas Homepage, paneles Grafana, flujos n8n y otras herramientas. Incluye la configuración habitual de cada plataforma con ejemplos copiables. Esta página reúne el catálogo de endpoints."
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{
"label": "Access & Authentication",
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tail": " — emisión de tokens, log de auditoría, jail Fail2Ban opcional, configuración TLS."
"tail": " — creación de tokens, registro de auditoría, jail opcional de Fail2Ban y TLS."
},
{
"label": "Notifications",
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tailRich": " — qué transporta cada tipo de evento en <code>data</code> cuando llamas a <code>/api/notifications/send</code>."
"tailRich": " — contenido de <code>data</code> para cada evento al llamar a <code>/api/notifications/send</code>."
},
{
"label": "Asistente de IA",
"href": "/docs/monitor/ai-assistant",
"tailRich": " — cómo están cableados <code>/api/notifications/test-ai</code> y <code>/api/notifications/provider-models</code>."
"tailRich": " — funcionamiento de <code>/api/notifications/test-ai</code> y <code>/api/notifications/provider-models</code>."
},
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tailRich": " — la forma de respuesta de <code>/api/health/*</code> y la semántica de las diez categorías."
"tailRich": " — formato de respuesta de <code>/api/health/*</code> y significado de las diez categorías."
}
]
}
+91 -91
View File
@@ -1,37 +1,37 @@
{
"meta": {
"title": "Arquitectura de ProxMenux Monitor — AppImage, Flask, SQLite, WebSocket | ProxMenux",
"description": "Cómo está construido ProxMenux Monitor: estructura del AppImage, blueprints de Flask, hilos de fondo, fuentes de datos (psutil, pvesh, smartctl, journalctl), persistencia en SQLite, terminal WebSocket, proveedores de IA, canales de notificación, reverse proxy e integración opcional con Fail2Ban.",
"description": "Cómo se construye ProxMenux Monitor: estructura AppImage, blueprints Flask, tareas de fondo, datos de psutil, pvesh, smartctl y journalctl, almacenamiento SQLite, terminal WebSocket, proveedores de IA, canales de aviso, proxy inverso y Fail2Ban opcional.",
"ogTitle": "Arquitectura de ProxMenux Monitor",
"ogDescription": "Dentro de ProxMenux Monitor — estructura del AppImage, blueprints de Flask, hilos de fondo, SQLite, WebSocket, proveedores de IA, canales de notificación.",
"ogDescription": "Dentro de ProxMenux Monitor: AppImage, blueprints Flask, tareas de fondo, SQLite, WebSocket, proveedores de IA y canales de aviso.",
"twitterTitle": "Arquitectura de ProxMenux Monitor",
"twitterDescription": "AppImage, Flask, SQLite, WebSocket, proveedores de IA y canales de notificación — por dentro del Monitor."
},
"header": {
"title": "Arquitectura",
"description": "Cómo se empaqueta ProxMenux Monitor, qué corre dentro del AppImage y cómo fluyen las peticiones desde el navegador a través del backend Flask hasta las herramientas del host y el almacén SQLite.",
"description": "Cómo se distribuye ProxMenux Monitor, qué contiene el AppImage y cómo las peticiones del navegador pasan por Flask hasta las herramientas del host y el almacenamiento SQLite.",
"section": "ProxMenux Monitor"
},
"intro": {
"title": "Un proceso, muchas responsabilidades",
"body": "Un único proceso Python escucha en el puerto TCP 8008. Sirve el build estático de Next.js, expone la API REST, gestiona el terminal WebSocket, ejecuta el Monitor de salud periódico y despacha notificaciones. No hay un servidor web aparte, ni un broker de mensajes, ni una base de datos externa."
"body": "Un proceso Python escucha en TCP 8008. Sirve la web estática Next.js, ofrece la API REST, gestiona el terminal WebSocket, ejecuta Health Monitor y envía notificaciones. No necesita un servidor web separado, un intermediario de mensajes ni una base de datos externa."
},
"requestFlow": {
"heading": "Flujo de petición",
"intro": "Del navegador al kernel, cada vista del panel sigue el mismo camino:",
"diagramCaption": "Cada petición se autentica por JWT (cuando la autenticación está activada), se enruta a un blueprint y se responde con datos recogidos bajo demanda desde las herramientas del host. Si Fail2Ban está instalado y el jail proxmenux está activo, el middleware también comprueba la petición contra la lista de IPs baneadas del jail. El reverse proxy opcional es transparente para Flask — reenvía las cabeceras X-Forwarded-* y la app recupera la IP real del cliente a partir de ellas. El estado que necesita sobrevivir a una petición vive en SQLite.",
"heading": "Recorrido de una petición",
"intro": "Una petición de datos típica sigue este recorrido; las preferencias del navegador pueden gestionarse localmente:",
"diagramCaption": "Las rutas protegidas validan JWT si la autenticación está activa. Flask devuelve datos del host almacenados en caché o recién obtenidos. El control opcional de Fail2Ban consulta su lista de bloqueos en caché. Solo se confía en cabeceras de IP reenviadas con PROXMENUX_TRUST_PROXY=1; si no, se usa la IP de la conexión. El estado persistente incluye SQLite y archivos JSON como auth.json.",
"diagramArrowLabel": "HTTP / WS",
"nodes": {
"clientLabel": "Cliente",
"clientDetail": "Navegador o PWA\n+ proxy opcional\nNginx / Caddy /\nTraefik",
"flaskLabel": "Flask :8008",
"flaskDetail": "Blueprints\nMiddleware JWT\nHook Fail2Ban\n(si está instalado)",
"flaskDetail": "Blueprints\nMiddleware JWT\nControl Fail2Ban\n(si está instalado)",
"hostLabel": "Herramientas del host",
"hostDetail": "psutil\npvesh\nsmartctl\njournalctl",
"stateLabel": "Estado local",
"stateDetail": "DB SQLite\n+ auth.json"
},
"threadsIntro": "El mismo proceso también ejecuta cuatro <strong>hilos de fondo</strong> arrancados al boot — no sirven HTTP, empujan estado a SQLite o a la cola de notificaciones mientras el host está activo:",
"threadsIntro": "El proceso también ejecuta <strong>hilos en segundo plano</strong>. Estos ejemplos recogen datos, actualizan cachés y SQLite, y envían notificaciones. Hay más tareas y el envío depende de que esté activado:",
"headerThread": "Hilo",
"headerCadence": "Cadencia",
"headerJob": "Tarea",
@@ -39,50 +39,50 @@
{
"thread": "_temperature_collector_loop",
"cadence": "60 s",
"job": "Registra la temperatura de la CPU y una muestra de latencia de red en la DB de historial para que las gráficas del panel tengan datos incluso cuando ningún cliente está conectado."
"job": "Guarda temperatura CPU y muestras de latencia en la base de historial, de modo que haya datos para gráficas sin un navegador conectado."
},
{
"thread": "_health_collector_loop",
"cadence": "5 min",
"job": "Ejecuta el ciclo completo del Monitor de salud (10 categorías), persiste errores activos, dismissals y observaciones de disco, y alimenta nuevos eventos al motor de notificaciones."
"job": "Ejecuta el ciclo Health Monitor de diez categorías, guarda errores y observaciones de disco, mantiene los descartes y envía nuevos eventos al motor de avisos."
},
{
"thread": "_vital_signs_sampler",
"cadence": "~1 s",
"job": "Muestreador de alta frecuencia de CPU + temperatura usado por los widgets en vivo del panel Overview."
"cadence": "CPU 5 s; temperatura 15 s; memoria 30 s",
"job": "Muestrea uso CPU, memoria y temperatura CPU para los indicadores y la detección sostenida, con independencia del análisis general de cinco minutos."
},
{
"thread": "notification_manager.start()",
"cadence": "dirigido por eventos",
"job": "Lanza los watchers de journal / task / hook (<code>JournalWatcher</code>, <code>TaskWatcher</code>, <code>ProxmoxHookWatcher</code>) y despacha a los canales configurados con reescritura opcional con IA."
"job": "Inicia observadores del journal, tareas y hooks (<code>JournalWatcher</code>, <code>TaskWatcher</code>, <code>ProxmoxHookWatcher</code>) y envía a los canales configurados, con reformulación IA opcional."
}
]
},
"systemd": {
"heading": "Unidad systemd",
"intro": "El instalador deja una unidad en <code>/etc/systemd/system/proxmenux-monitor.service</code>. Contenido por defecto:",
"intro": "El instalador crea la unidad <code>/etc/systemd/system/proxmenux-monitor.service</code>. Configuración predeterminada:",
"items": [
"<strong><code>User=root</code></strong> — obligatorio: SMART, <code>pvesh</code>, scopes de journal, comandos ZFS y el terminal web requieren todos root.",
"<strong><code>Restart=on-failure</code></strong> con back-off de 10 segundos — las salidas con código distinto de cero relanzan automáticamente.",
"<strong><code>After=network.target</code></strong> — espera a que el stack de red del host esté online."
"<strong><code>User=root</code></strong>: el servicio usa privilegios root para operaciones del host como SMART, <code>pvesh</code> y gestión ZFS. Los procesos del terminal heredan esos permisos.",
"<strong><code>Restart=on-failure</code></strong> con espera de 10 segundos: se reinicia automáticamente tras una salida con error.",
"<strong><code>After=network.target</code></strong>: ordena el inicio después de ese objetivo; no garantiza IP asignada, DNS ni conectividad externa."
],
"inspectTitle": "Inspeccionar la unidad en vivo"
"inspectTitle": "Consultar la unidad actual"
},
"appimage": {
"heading": "Qué contiene el AppImage",
"intro": "El AppImage es un sistema de archivos automontable. <code>AppRun</code> en la raíz prepara el entorno y ejecuta <code>flask_server.py</code>:",
"intro": "AppImage es un sistema de archivos que se monta al ejecutarlo. <code>AppRun</code> en su raíz prepara el entorno y lanza <code>flask_server.py</code>:",
"consequencesIntro": "Dos consecuencias de esta estructura:",
"consequences": [
"<strong>Sin polución del Python del host.</strong> El intérprete y los paquetes empaquetados están aislados dentro del AppImage — actualizar el Python del sistema host no afecta al Monitor y viceversa.",
"<strong>Las herramientas de hardware también vienen incluidas.</strong> <code>ipmitool</code>, <code>lm-sensors</code> y <code>upsc</code> viajan dentro del AppImage para que el panel pueda leer sensores fuera de banda y el estado de la UPS sin forzar al usuario a instalar paquetes Debian."
"<strong>Paquetes Python incluidos.</strong> Los paquetes Python vienen en la AppImage y se ejecutan con el intérprete Python 3.11 (PVE 8) o 3.13 (PVE 9) del propio host, sin instalar nada en su Python del sistema. La aplicación sigue usando interfaces del kernel y herramientas externas del host.",
"<strong>Clientes de hardware incluidos.</strong> Contiene <code>ipmitool</code>, <code>lm-sensors</code> y <code>upsc</code>. Las lecturas dependen del hardware compatible, acceso a sensores y, para el SAI, un servidor NUT configurado."
]
},
"flask": {
"heading": "Estructura de la app Flask",
"intro": "<code>flask_server.py</code> crea una única instancia <code>Flask(__name__)</code>, habilita CORS y registra seis blueprints más un inicializador de WebSocket:",
"heading": "Estructura de la aplicación Flask",
"intro": "<code>flask_server.py</code> crea una instancia <code>Flask(__name__)</code> con CORS restringido, registra directamente diez blueprints e inicializa el terminal. La tabla destaca módulos principales; también registra PBS, enlaces del Monitor, auditoría y backups de VM. Las precargas PVE solo se ejecutan en hosts PVE.",
"headerBlueprint": "Blueprint / módulo",
"headerPrefix": "Prefijo de rutas",
"headerOwns": "Responsable de",
"headerOwns": "Responsabilidad",
"rows": [
{
"blueprint": "flask_server.py",
@@ -95,208 +95,208 @@
"/api/logs",
"/api/prometheus"
],
"owns": "Endpoints de datos principales + servir el panel estático + comprobación opcional de Fail2Ban a nivel de aplicación (activa solo cuando Fail2Ban está instalado en el host con el jail <code>proxmenux</code>)."
"owns": "Endpoints principales, web estática y control opcional Fail2Ban, activo si existe el jail <code>proxmenux</code> en el host."
},
{
"blueprint": "flask_auth_routes.py",
"prefix": [
"/api/auth/*"
],
"owns": "Login, emisión de JWT, configuración / verificación de TOTP, cambio de contraseña, generación de API tokens."
"owns": "Inicio de sesión, emisión JWT, configuración y verificación TOTP, cambio de contraseña y tokens API."
},
{
"blueprint": "flask_health_routes.py",
"prefix": [
"/api/health/*"
],
"owns": "Probe de salud público, estado detallado, errores activos / dismissed, ajustes de supresión."
"owns": "Comprobaciones de salud, estado detallado, errores activos y descartados, y silenciamientos. Las rutas protegidas exigen autenticación si está activada."
},
{
"blueprint": "flask_terminal_routes.py",
"prefix": [
"/api/terminal/* + WS"
],
"owns": "Asignación de PTY por sesión y pipe WebSocket hacia <code>xterm.js</code> en el navegador."
"owns": "Crea un PTY por sesión y lo conecta por WebSocket con <code>xterm.js</code> del navegador."
},
{
"blueprint": "flask_notification_routes.py",
"prefix": [
"/api/notifications/*"
],
"owns": "CRUD de canales, envío de prueba, configuración del proveedor de IA, historial, envíos manuales."
"owns": "Crear, consultar, editar y borrar canales; pruebas, IA, historial y envíos manuales."
},
{
"blueprint": "flask_security_routes.py",
"prefix": [
"/api/security/*"
],
"owns": "Fallos de autenticación y, cuando Fail2Ban está instalado, estado del jail, eventos de ban y desbaneo manual."
"owns": "Fallos de acceso y, con Fail2Ban instalado, estado del jail, bloqueos y desbloqueo manual."
},
{
"blueprint": "flask_proxmenux_routes.py",
"prefix": [
"/api/proxmenux/*"
],
"owns": "Lee qué optimizaciones post-instalación de ProxMenux están instaladas en el host."
"owns": "Lee las optimizaciones ProxMenux registradas en el host."
},
{
"blueprint": "flask_oci_routes.py",
"prefix": [
"/api/oci/*"
],
"owns": "Ayudantes de despliegue de apps OCI / container (Proxmox VE 9.1+)."
"owns": "Funciones de despliegue de aplicaciones OCI y contenedores en Proxmox VE 9.1+."
}
],
"endpointsLink": "La lista completa de endpoints con la forma de petición / respuesta está en <link>API Reference</link>."
"endpointsLink": "Los endpoints de integración y sus formatos se explican en <link>Referencia de la API</link>."
},
"dataSources": {
"heading": "Fuentes de datos",
"intro": "Nada se recoge a través de un agente propio — el Monitor lee los mismos archivos y ejecuta los mismos comandos que un administrador humano:",
"intro": "Los datos del host proceden principalmente de bibliotecas, archivos y comandos habituales de administración. Algunos datos del invitado dependen además de QEMU Guest Agent o de comandos ejecutados en el CT:",
"headerSource": "Fuente",
"headerUsedFor": "Usado para",
"rows": [
{
"source": "psutil",
"usedFor": "Carga de CPU, memoria, swap, uso de puntos de montaje, contadores de NIC, lista de procesos."
"usedFor": "Carga CPU, memoria, swap, ocupación de montajes, contadores de red y procesos."
},
{
"source": "pvesh / qm / pct",
"usedFor": "Información del nodo Proxmox, inventario y configuración de VMs y CTs, pools de almacenamiento, historial de tareas."
"usedFor": "Información del nodo Proxmox, inventario y configuración VM/CT, almacenamiento e historial de tareas."
},
{
"source": "smartctl",
"usedFor": "Atributos SATA / NVMe, salud SMART, desgaste / vida útil, modelo y número de serie."
"usedFor": "Atributos SATA/NVMe, estado SMART, desgaste, vida útil, modelo y número de serie."
},
{
"source": "zpool / zfs",
"usedFor": "Estado del pool (ONLINE / DEGRADED / FAULTED / UNAVAIL), progreso de scrub, uso de datasets."
"usedFor": "Estado del pool (ONLINE / DEGRADED / FAULTED / UNAVAIL), progreso del scrub y uso de datasets."
},
{
"source": "journalctl",
"usedFor": "Logs del sistema, OOM kills, errores ATA / NVMe / dm, eventos de seguridad, unidades de servicio propias."
"usedFor": "Registros del sistema, procesos terminados por OOM, errores ATA/NVMe/dm, seguridad y unidades de servicio propias."
},
{
"source": "ip / iproute2",
"usedFor": "Interfaces, direcciones, bridges, bonds, dispositivos gestionados por OVS."
"usedFor": "Interfaces, direcciones, bridges, bonds y dispositivos gestionados por OVS."
},
{
"source": "nvidia-smi · intel_gpu_top",
"usedFor": "Utilización de GPU, VRAM, temperatura, carga de encoder / decoder."
"usedFor": "Datos GPU disponibles de utilización, VRAM, temperatura y codificación/decodificación. Los campos dependen del fabricante, herramienta y controlador."
},
{
"source": "lspci · lscpu · dmidecode",
"usedFor": "Topología PCIe, modelo y topología de CPU, información de placa y BIOS."
"usedFor": "Topología PCIe, modelo y topología CPU, placa base y BIOS."
},
{
"source": "ipmitool · sensors",
"usedFor": "Sensores fuera de banda, velocidades de ventilador, temperaturas de placa (cuando son compatibles)."
"usedFor": "Sensores fuera de banda, ventiladores y temperaturas de la placa, si el hardware lo admite."
},
{
"source": "upsc (NUT)",
"usedFor": "Estado de batería de UPS, carga, autonomía — cuando hay un servidor NUT configurado en el host."
"usedFor": "Estado de batería, carga y autonomía del SAI si hay un servidor NUT configurado."
}
],
"cacheTitle": "La salida se cachea — no toda petición llega al host",
"cacheBody": "Las fuentes costosas (<code>smartctl -a</code>, <code>pvesh get</code>) se envuelven en cachés temporizadas dentro del proceso Flask para que una pestaña ocupada del panel no martillee el disco o la API del cluster. Los TTLs de la caché están ajustados por fuente (unos pocos segundos para métricas en vivo, varios minutos para SMART)."
"cacheTitle": "Caché para reducir las consultas al host",
"cacheBody": "Los resultados costosos de <code>smartctl -a</code> y <code>pvesh get</code> se guardan temporalmente en el proceso Flask para reducir consultas repetidas al disco y a la API del clúster. La duración depende de la fuente: segundos para métricas y minutos para SMART."
},
"persistence": {
"heading": "Persistencia",
"intro": "Dos ubicaciones del sistema de archivos separan el estado por sensibilidad:",
"headerPath": "Ruta",
"intro": "Varios archivos guardan estados con distinto contenido y requisitos de acceso:",
"headerPath": "Path",
"headerOwner": "Propietario",
"headerContents": "Contenido",
"rows": [
{
"path": "/usr/local/share/proxmenux/health_monitor.db",
"owner": "root:root",
"contents": "DB SQLite. Tablas: <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>. Modo journal WAL."
"contents": "Base SQLite. Tablas: <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>. Modo de registro WAL."
},
{
"path": "/usr/local/share/proxmenux/.notification_key",
"owner": "root <code>0600</code>",
"contents": "Clave XOR de 32 bytes usada para cifrar ajustes sensibles de notificaciones antes de guardarlos en la DB (tokens de Telegram, API keys de IA, etc.)."
"contents": "Clave maestra de 32 bytes para secretos de notificación ENC2. Usa sal aleatoria por valor, claves derivadas y MAC. Los valores XOR antiguos se admiten para migrarlos."
},
{
"path": "/root/.config/proxmenux-monitor/auth.json",
"owner": "root:root",
"contents": "Estado de autenticación: flag de activación, nombre de usuario, hash SHA-256 de la contraseña, secret TOTP, códigos de backup, lista de API tokens emitidos, lista de hashes de tokens revocados."
"contents": "Configuración de acceso: activación, usuario, hash de contraseña PBKDF2-HMAC-SHA256 con sal, secreto TOTP, códigos de recuperación, clave JWT propia de la instalación, metadatos de tokens API y hashes de revocación. Los hashes SHA-256 antiguos migran al iniciar sesión correctamente."
},
{
"path": "/var/log/proxmenux-auth.log",
"owner": "root:root",
"contents": "Log de eventos de autenticación en texto plano. Siempre se escribe. Si Fail2Ban está instalado con el jail <code>[proxmenux]</code>, el jail lee este archivo para banear intentos de fuerza bruta; si no, el archivo simplemente acumula las entradas del log."
"contents": "Registro de autenticación en texto plano, independiente de Fail2Ban. Si el jail <code>[proxmenux]</code> está instalado y activo, lee este archivo para detectar fallos repetidos de acceso. Sin ese jail, el registro sigue disponible para consulta."
}
],
"backupTitle": "Haz backup de auth.json antes de reinstalar",
"backupBody": "Reinstalar el AppImage reemplaza el binario pero deja <code>/root/.config/proxmenux-monitor/auth.json</code> y <code>/usr/local/share/proxmenux/health_monitor.db</code> intactos. Si restauras desde un backup del host, mantén ambos archivos juntos — los API tokens guardados en <code>auth.json</code> se validan contra <code>JWT_SECRET</code>; si la DB y auth.json se desincronizan, los errores dismissed y los tokens guardados pueden comportarse mal."
"backupTitle": "Guarda auth.json antes de reinstalar",
"backupBody": "Sustituir AppImage suele conservar <code>/root/.config/proxmenux-monitor/auth.json</code> y <code>/usr/local/share/proxmenux/health_monitor.db</code>. Conserva <code>auth.json</code> con su jwt_secret para mantener validez y metadatos de tokens. La base guarda estado de salud y avisos por separado. Guarda <code>.notification_key</code> con ella para restaurar secretos de canales; restaurar solo la base no restaura la autenticación API."
},
"health": {
"heading": "Ciclo del Monitor de salud",
"intro": "Cada 5 minutos <code>health_monitor.py</code> ejecuta un ciclo determinista a través de las diez categorías mostradas en el panel:",
"heading": "Ciclo Health Monitor",
"intro": "Aproximadamente cada cinco minutos, el proceso de fondo llama a <code>health_monitor.py</code> para comprobar las diez categorías del panel:",
"items": [
"Servicios críticos de PVE (<code>pveproxy</code>, <code>pvedaemon</code>, <code>pvestatd</code>, <code>pve-cluster</code>).",
"Pools de almacenamiento Proxmox (<code>pvesh get /storage</code> + disponibilidad por almacenamiento).",
"Discos y sistemas de archivos: SMART, errores de I/O en dmesg, salud de pool ZFS, capacidad de puntos de montaje.",
"VMs y CTs: arranques fallidos, guests caídos, errores QMP, fallos de apagado.",
"Red: estado de bridge / bond, estado de enlace, latencia al gateway.",
"Actualizaciones: actualizaciones de paquetes pendientes y parches de seguridad.",
"Logs: detección de patrones persistentes / spike / cascada en el journal del sistema.",
"Memoria: actividad del OOM killer, presión alta sostenida.",
"Temperatura: sensores CPU / chasis contra umbrales del fabricante.",
"Seguridad: fallos de autenticación, eventos de ban, estado del jail fail2ban."
"Almacenamientos Proxmox: <code>pvesh get /storage</code> y disponibilidad de cada uno.",
"Discos y sistemas de archivos: SMART, errores de E/S en dmesg, estado ZFS y capacidad de montajes.",
"VM y CT: fallos de arranque, caídas, errores QMP y fallos de apagado.",
"Red: estado de bridges y bonds, enlaces y latencia hasta la puerta de enlace.",
"Actualizaciones: paquetes pendientes y parches de seguridad.",
"Registros: patrones persistentes, picos y cascadas en el journal del sistema.",
"Memoria: actividad del OOM killer y presión RAM sostenida.",
"CPU: uso y temperatura de la CPU frente a los umbrales configurables; los sensores disponibles dependen del hardware.",
"Seguridad: fallos de acceso, bloqueos y estado del jail Fail2Ban."
],
"afterIntro": "Cada hallazgo se normaliza a un <code>error_key</code> + categoría + severidad estable. La capa de persistencia deduplica contra la tabla <code>errors</code> existente — los eventos repetidos actualizan <code>last_seen</code> y el contador de ocurrencias sin spamear notificaciones.",
"cycleEnd": "El ciclo también auto-resuelve errores obsoletos usando el ajuste de <em>Suppression Duration</em> por categoría, limpia errores de recursos que ya no existen (VMs eliminadas / discos retirados / almacenamientos desmontados) y poda el log <code>events</code> con más de 30 días. El catálogo completo de categorías y la vista del panel que las expone está documentado en <link>Dashboard → Monitor de salud</link>."
"afterIntro": "Los hallazgos usan <code>error_key</code>, categoría y gravedad estables. Las filas de <code>errors</code> se actualizan en el sitio (<code>last_seen</code>, gravedad, motivo), sin duplicarlas. El envío de avisos tiene además sus propias huellas y tiempos de espera.",
"cycleEnd": "La limpieza puede resolver errores obsoletos con la <em>duración de silenciamiento</em> por categoría y reglas de estado, retirar registros huérfanos de recursos eliminados y borrar <code>events</code> de más de 30 días. Las categorías se explican en <link>Panel → Health Monitor</link>."
},
"notifications": {
"heading": "Motor de notificaciones",
"intro": "<code>notification_manager.py</code> es el orquestador. Carga los canales configurados, posee la cola de entrega y expone tanto una API Python (para rutas Flask y el ciclo del Monitor de salud) como un punto de entrada CLI (para los scripts <code>.sh</code> de hooks que vienen con ProxMenux).",
"intro": "<code>notification_manager.py</code> coordina el envío: carga canales, gestiona la cola y ofrece una API Python para Flask y Health Monitor, además de una entrada de consola para los hooks <code>.sh</code> de ProxMenux.",
"items": [
"<strong>Los watchers</strong> empujan eventos: <code>JournalWatcher</code> sigue el journal del sistema, <code>TaskWatcher</code> hace polling de la lista de tareas Proxmox, <code>ProxmoxHookWatcher</code> reacciona a hooks de backup / replicación / snapshot y <code>PollingCollector</code> gestiona fuentes de datos lentas.",
"<strong>Las templates</strong> convierten un evento en un par (título, cuerpo). La misma template puede pasar por el proveedor de IA configurado (OpenAI / Anthropic / Gemini / Groq / Ollama / OpenRouter) para producir una reescritura en lenguaje natural; ambas versiones se guardan en <code>notification_history</code>.",
"<strong>Los canales</strong> entregan los mensajes: Telegram, Discord, Email, Gotify, Pushover y Apprise (multicanal). Cada uno está implementado en <code>notification_channels.py</code> mediante la misma interfaz <code>create_channel()</code> / <code>send()</code>.",
"<strong>Cifrado.</strong> Los ajustes 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>) se cifran con la clave de <code>.notification_key</code> antes de escribirse en la base de datos y aparecen ocultos en la interfaz."
"Los <strong>observadores</strong> generan eventos: <code>JournalWatcher</code> sigue el journal, <code>TaskWatcher</code> consulta tareas Proxmox, <code>ProxmoxHookWatcher</code> recibe hooks de backups, replicación y snapshots, y <code>PollingCollector</code> gestiona fuentes lentas.",
"Las <strong>plantillas</strong> convierten eventos en título y texto. El proveedor de IA configurado (OpenAI / Anthropic / Gemini / Groq / Ollama / OpenRouter) puede reformularlos en lenguaje natural. Ambas versiones se guardan en <code>notification_history</code>.",
"Los <strong>canales</strong> envían por Telegram, Discord, correo, Gotify, Pushover y Apprise, entre otros. Las implementaciones en <code>notification_channels.py</code> comparten <code>create_channel()</code> / <code>send()</code>.",
"<strong>Cifrado.</strong> Los ajustes 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>) se cifran con la clave de <code>.notification_key</code> antes de guardarse en la base de datos y se muestran enmascarados en la interfaz."
],
"linksFooter": "Los toggles por evento, los overrides por canal y la configuración de IA se exponen en <notifLink>Settings → Notifications</notifLink> y <aiLink>Settings → AI Assistant</aiLink>."
"linksFooter": "Los controles por evento, ajustes por canal e IA se explican en <notifLink>Ajustes → Notificaciones</notifLink> y <aiLink>Ajustes → Asistente de IA</aiLink>."
},
"websocket": {
"heading": "Terminal WebSocket",
"intro": "La pestaña <em>Terminal</em> del panel es un cliente fino <code>xterm.js</code> cableado a un PTY del lado servidor a través de un WebSocket. Dos modos de transporte:",
"intro": "La pestaña <em>Terminal</em> conecta un cliente ligero <code>xterm.js</code> a un PTY del servidor por WebSocket. Hay dos modos:",
"items": [
"<strong>Modo HTTP (por defecto):</strong> el servidor de desarrollo de Flask con <code>flask-sock</code> gestiona las peticiones de upgrade. Suficiente para LAN / acceso directo.",
"<strong>Modo HTTPS / WSS:</strong> cuando hay un certificado SSL configurado, el proceso cambia a <code>gevent.pywsgi.WSGIServer</code> con <code>geventwebsocket.handler.WebSocketHandler</code>, para que los WebSockets funcionen sobre TLS sin polyfills."
"<strong>Modo HTTP, predeterminado:</strong> el servidor Flask incluido y <code>flask-sock</code> gestionan el cambio de protocolo a WebSocket.",
"<strong>Modo HTTPS / WSS:</strong> usa <code>gevent.pywsgi.WSGIServer</code> con su gestor predeterminado; <code>flask-sock</code> atiende las conexiones WebSocket sobre TLS."
],
"outro": "El PTY es un hijo del proceso Flask, así que hereda <code>User=root</code> de la unidad. Cada petición de terminal pasa por auth JWT; el usuario debe estar ya logueado en el panel antes de que se asigne un PTY.",
"proxyNote": "Si accedes al Monitor a través de un reverse proxy, asegúrate de habilitar el reenvío de WebSocket (cabeceras <code>Upgrade</code> y <code>Connection</code>). Sin eso, el terminal no funcionará."
"outro": "Los procesos del terminal heredan <code>User=root</code>. Abrir WebSocket exige un ticket breve y de un solo uso, obtenido del endpoint de tickets autenticado con permisos administrativos.",
"proxyNote": "Si usas un proxy inverso, permite el tráfico WebSocket y sus cabeceras <code>Upgrade</code> y <code>Connection</code>. El terminal necesita ese reenvío."
},
"proxy": {
"heading": "Reverse proxy y Fail2Ban",
"intro": "Dos salvaguardas se aseguran de que la seguridad funcione igual tanto si el panel se accede directamente como a través de un reverse proxy:",
"heading": "Proxy inverso y Fail2Ban",
"intro": "La elección de IP del cliente y el bloqueo opcional en la aplicación dependen de estos ajustes y componentes:",
"items": [
"<strong>Recuperación de la IP real del cliente.</strong> Un hook <code>before_request</code> lee <code>X-Forwarded-For</code> y <code>X-Real-IP</code> en ese orden, cayendo a <code>request.remote_addr</code>. La dirección recuperada es la que ven el log de autenticación y el rate limiting. Esto está siempre activo.",
"<strong>Comprobación de Fail2Ban a nivel de aplicación (opcional).</strong> Cuando el panel está detrás de un proxy, el firewall del kernel no puede bloquear la IP real del atacante — la conexión siempre viene del proxy. Para tapar ese hueco, el mismo hook de arriba consulta el jail <code>proxmenux</code> de Fail2Ban cada 30 segundos, cachea el conjunto de IPs baneadas y corta las peticiones desde esas IPs con HTTP 403 dentro de Flask."
"<strong>Elección de IP.</strong> El control <code>before_request</code> y el registro de acceso solo confían en <code>X-Forwarded-For</code> y después <code>X-Real-IP</code> con PROXMENUX_TRUST_PROXY=1. Si no, usan <code>request.remote_addr</code>. Las cabeceras reenviadas no se aceptan automáticamente.",
"<strong>Fail2Ban opcional en la aplicación.</strong> Una conexión por proxy puede mostrar la IP del proxy como origen TCP. Si se obtiene la IP fiable del cliente y está activo el jail <code>proxmenux</code>, Flask rechaza las IP bloqueadas con HTTP 403. La lista se guarda 30 segundos y se renueva al procesar peticiones tras caducar, sin un temporizador de consultas."
],
"calloutTitle": "Fail2Ban no viene incluido",
"calloutBody": "Fail2Ban <strong>no</strong> lo instala ProxMenux Monitor por sí mismo. La comprobación a nivel de aplicación es un no-op hasta que instales Fail2Ban en el host (p. ej. vía <link>Seguridad → Fail2Ban</link> en el menú de ProxMenux). Cuando el binario <code>fail2ban-client</code> o el jail <code>proxmenux</code> está ausente, la llamada falla silenciosamente y las peticiones no se filtran — la autenticación sigue aplicándose, pero no hay baneo a nivel de IP.",
"outro": "Los snippets de reverse proxy (Nginx / Caddy / Traefik) y el walkthrough del jail Fail2Ban están en <accessLink>Access & Authentication</accessLink> y <fail2banLink>Seguridad → Fail2Ban</fail2banLink>."
"calloutBody": "Fail2Ban <strong>no</strong> viene incluido ni se instala automáticamente. Puede instalarse desde Seguridad del Monitor o <link>Seguridad → Fail2Ban</link> en ProxMenux Scripts. Si faltan <code>fail2ban-client</code> o el jail <code>proxmenux</code>, este control no bloquea peticiones. La autenticación sigue la política configurada.",
"outro": "Los ejemplos de proxy inverso Nginx/Caddy/Traefik y la guía del jail están en <accessLink>Acceso y autenticación</accessLink> y <fail2banLink>Seguridad → Fail2Ban</fail2banLink>."
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{
"label": "Access & Authentication",
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tail": " — configuración de primer arranque, contraseña + TOTP 2FA, snippets de reverse proxy, jail Fail2Ban."
"tail": " — primer inicio, contraseña y TOTP 2FA, ejemplos de proxy inverso y jail Fail2Ban."
},
{
"label": "API Reference",
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — cada endpoint, gestión de tokens, mejores prácticas de seguridad."
"tail": " — endpoints de integración, tokens y convenciones de autenticación."
},
{
"label": "Settings → ProxMenux Monitor",
"label": "Ajustes → ProxMenux Monitor",
"href": "/docs/settings/proxmenux-monitor",
"tail": " — el toggle del servicio dentro del menú y el flujo de verificación del estado dentro de la TUI de ProxMenux."
"tail": " — control del servicio y comprobación del estado en el menú de texto de ProxMenux."
}
]
}
@@ -1,7 +1,7 @@
{
"meta": {
"title": "Evaluación e inventario | Auditoría e informes",
"description": "La evaluación de Auditoría e informes: perfiles de informe, clasificación de los resultados, riesgos aceptados, fuentes ilegibles, Lynis e inventario del nodo."
"description": "Evaluación de Auditoría e informes: perfiles de informe, clasificación de resultados, riesgos aceptados, fuentes ilegibles, Lynis e inventario del nodo."
},
"header": {
"title": "Evaluación e inventario",
@@ -19,7 +19,7 @@
}
},
{
"p": "<strong>Ejecutar evaluación</strong> inicia una ejecución con el perfil seleccionado en <strong>Informe</strong>. La vista muestra la fecha de la última ejecución y cuánto tiempo ha pasado."
"p": "<strong>Ejecutar evaluación</strong> inicia una ejecución con el perfil seleccionado en <strong>Informe</strong>. La vista muestra la fecha de la última ejecución y el tiempo transcurrido."
}
]
},
@@ -30,14 +30,35 @@
"blocks": [
{
"table": {
"headers": ["Perfil", "Qué abarca"],
"headers": [
"Perfil",
"Qué abarca"
],
"rows": [
["Auditoría completa", "Todas las comprobaciones y toda la estructura disponible."],
["Diagnóstico rápido", "Todas las comprobaciones; el resultado empieza por los hallazgos críticos, las advertencias y las lecturas que no pudieron verificarse."],
["Inventario", "Una descripción del nodo, sin comprobaciones ni clasificación."],
["Revisión de seguridad", "Exposición, acceso, privilegios, certificados, actualizaciones, repositorios y Lynis."],
["Garantía de backups", "Cobertura, antigüedad, resultados, verificación, retención y recuperación de los backups."],
["Capacidad y desgaste", "Margen de crecimiento, memoria, ocupación y vida útil de los discos."]
[
"Auditoría completa",
"Todas las comprobaciones y toda la estructura disponible."
],
[
"Diagnóstico rápido",
"Todas las comprobaciones; el resultado empieza por los hallazgos críticos, las advertencias y las lecturas que no pudieron verificarse."
],
[
"Inventario",
"Una descripción del nodo, sin comprobaciones ni clasificación."
],
[
"Revisión de seguridad",
"Exposición, acceso, privilegios, certificados, actualizaciones, repositorios y Lynis."
],
[
"Garantía de backups",
"Cobertura, antigüedad, resultados, verificación, retención y recuperación de los backups."
],
[
"Capacidad y desgaste",
"Margen de crecimiento, memoria, ocupación y vida útil de los discos."
]
]
}
},
@@ -52,16 +73,43 @@
"blocks": [
{
"table": {
"headers": ["Clasificación", "Significado"],
"headers": [
"Clasificación",
"Significado"
],
"rows": [
["Crítico", "Una condición fallida con prioridad."],
["Advertencia", "Una condición que requiere revisión, según la evidencia o la política."],
["Observación", "Información sobre el nodo que no se presenta como fallo."],
["Sin verificar", "La fuente que necesita la comprobación no pudo leerse. No significa que el problema no exista."],
["Conforme", "La condición cumple el criterio aplicado."],
["No aplicable", "Dentro del alcance de la comprobación no hay nada a lo que aplicarla."],
["Riesgo aceptado", "El hallazgo existe y hay registrada una decisión sobre él."],
["Excluido por política", "La política declara que el elemento queda fuera del recuento."]
[
"Crítico",
"Una condición fallida con prioridad."
],
[
"Advertencia",
"Una condición que requiere revisión, según la evidencia o la política."
],
[
"Observación",
"Información sobre el nodo que no se presenta como fallo."
],
[
"Sin verificar",
"No se pudo leer la fuente que requiere la comprobación. Esto no significa que el problema no exista."
],
[
"Conforme",
"La condición cumple el criterio aplicado."
],
[
"No aplicable",
"Dentro del alcance de la comprobación no hay nada a lo que aplicarla."
],
[
"Riesgo aceptado",
"El hallazgo existe y hay registrada una decisión sobre él."
],
[
"Excluido por política",
"La política declara que el elemento queda fuera del recuento."
]
]
}
},
@@ -76,11 +124,23 @@
"blocks": [
{
"table": {
"headers": ["Caso", "Comportamiento"],
"headers": [
"Caso",
"Comportamiento"
],
"rows": [
["Sin verificar", "La comprobación conserva su identidad, indica en su evidencia qué fuente falló y no convierte la falta de datos en un resultado conforme."],
["Evidencia incompleta", "El informe nombra la fuente y el momento de la recogida, de modo que un problema real puede distinguirse de una lectura insuficiente."],
["Una nueva ejecución", "Una vez corregido el acceso, el paquete o el servicio, el mismo perfil se ejecuta de nuevo y la comparación muestra si el resultado pudo verificarse."]
[
"Sin verificar",
"La comprobación conserva su identidad, indica qué fuente falló en su evidencia y no convierte datos ausentes en un resultado conforme."
],
[
"Evidencia incompleta",
"El informe indica la fuente y el momento de recogida para distinguir un problema real de una lectura insuficiente."
],
[
"Una nueva ejecución",
"Una vez corregido el acceso, el paquete o el servicio, el mismo perfil se ejecuta de nuevo y la comparación muestra si el resultado pudo verificarse."
]
]
}
}
@@ -91,7 +151,7 @@
"title": "Lynis",
"blocks": [
{
"p": "La revisión de seguridad usa el informe de Lynis del host. Cuando Lynis no se ha ejecutado todavía, o su informe supera el umbral de antigüedad de la política, un diálogo ofrece <strong>Ejecutar con Lynis</strong>, que tarda unos minutos más, o <strong>Ejecutar sin Lynis</strong>, que usa el informe existente."
"p": "La revisión de seguridad usa el informe Lynis del host. Si Lynis nunca se ha ejecutado o el informe supera la antigüedad permitida por la política, un diálogo ofrece <strong>Ejecutar con Lynis</strong>, que tarda unos minutos más, o <strong>Ejecutar sin Lynis</strong>, que usa el informe existente."
},
{
"figure": {
@@ -107,20 +167,32 @@
"title": "Aceptar un riesgo",
"blocks": [
{
"p": "<strong>Aceptar riesgo</strong> registra una decisión sobre un hallazgo. El motivo es obligatorio y se guarda junto al autor y la fecha."
"p": "<strong>Aceptar riesgo</strong> registra una decisión sobre un hallazgo. El motivo es obligatorio y se guarda con el autor y la fecha."
},
{
"table": {
"headers": ["Campo", "Opciones"],
"headers": [
"Campo",
"Opciones"
],
"rows": [
["Motivo", "Texto libre, obligatorio."],
["Deja de aplicarse tras", "90 días, 180 días, 1 año o no caduca. Al cumplirse el plazo, el hallazgo vuelve a estar activo."],
["Recordarme revisarla", "Un recordatorio que devuelve la decisión a la atención mientras sigue en vigor."]
[
"Motivo",
"Texto libre, obligatorio."
],
[
"Deja de aplicarse tras",
"90 días, 180 días, 1 año o no caduca. Al cumplirse el plazo, el hallazgo vuelve a estar activo."
],
[
"Recordarme revisarla",
"Un recordatorio que devuelve la decisión a la atención mientras sigue en vigor."
]
]
}
},
{
"p": "Un hallazgo aceptado sigue visible con su decisión, y <strong>Volver a activo</strong> la revoca. Un riesgo aceptado no es una corrección: la comparación lo presenta como aceptado, no como resuelto."
"p": "El hallazgo aceptado sigue visible con su decisión; <strong>Volver a activo</strong> revoca la aceptación. Aceptar un riesgo no lo corrige: la comparación lo muestra como aceptado y no como resuelto."
}
]
},
@@ -1,11 +1,11 @@
{
"meta": {
"title": "Cambios | Auditoría e informes",
"description": "El registro de cambios de Auditoría e informes: qué ha cambiado ProxMenux en el host, qué había antes, la diferencia y si puede deshacerse."
"description": "Registro de cambios de Auditoría e informes: qué modificó ProxMenux en el host, el estado anterior, las diferencias y si puede deshacerse."
},
"header": {
"title": "Cambios",
"description": "El registro de las operaciones que ProxMenux realiza en el host y, cuando se capturó, el estado antes y después de cada una.",
"description": "Registro de las operaciones realizadas por ProxMenux en el host y, cuando se capturó, el estado anterior y posterior de cada una.",
"section": "Auditoría e informes"
},
"sections": [
@@ -14,25 +14,37 @@
"blocks": [
{
"calloutInfo": {
"title": "Del script que se ejecutó al cambio que hizo",
"body": "Una función extensa puede cambiar solo dos líneas. El registro conserva cada operación concreta con el script, la función y la versión responsables, el recurso afectado, la diferencia y si puede deshacerse."
"title": "Del script ejecutado al cambio realizado",
"body": "Una función extensa puede cambiar solo dos líneas. El registro guarda cada operación concreta con el script, función y versión responsables, el recurso afectado, las diferencias y la posibilidad de deshacerla."
}
},
{
"flow": {
"nodes": [
{ "label": "Script", "detail": "función + versión" },
{ "label": "Captura", "detail": "contenido previo" },
{ "label": "Operación", "detail": "archivo · paquete · servicio" },
{ "label": "Registro", "detail": "atribución + diferencia" }
{
"label": "Script",
"detail": "función + versión"
},
{
"label": "Captura",
"detail": "contenido previo"
},
{
"label": "Operación",
"detail": "archivo · paquete · servicio"
},
{
"label": "Registro",
"detail": "atribución + diferencia"
}
],
"caption": "La captura se toma al ejecutarse la operación y se consolida cuando el Monitor lee el registro."
"caption": "La captura se realiza al ejecutar la operación y se consolida cuando Monitor lee el registro."
}
},
{
"figure": {
"src": "/monitor/audit/changes-view.png",
"alt": "Vista Cambios de Auditoría e informes con las entradas agrupadas por opción de post-install y por script",
"alt": "Vista Cambios de Auditoría e informes con entradas agrupadas por opción de postinstalación y script",
"caption": "La vista Cambios, con la diferencia de un archivo editado por ProxMenux."
}
}
@@ -45,12 +57,27 @@
"blocks": [
{
"table": {
"headers": ["Tipo", "Qué registra"],
"headers": [
"Tipo",
"Qué registra"
],
"rows": [
["Configuración", "ProxMenux escribió, editó o eliminó un archivo, cambió un ajuste o alteró un servicio."],
["Instalaciones", "ProxMenux añadió un paquete o componente, y se registran los paquetes que aparecieron realmente."],
["Ejecuciones", "ProxMenux ejecutó un comando; lo que cambió depende del propio comando."],
["Aplicado", "Una función se aplicó antes de que existiera el registro; el estado previo no se capturó."]
[
"Configuración",
"ProxMenux escribió, editó o eliminó un archivo, cambió un ajuste o alteró un servicio."
],
[
"Instalaciones",
"ProxMenux añadió un paquete o componente, y se registran los paquetes que aparecieron realmente."
],
[
"Ejecuciones",
"ProxMenux ejecutó un comando; sus efectos dependen del propio comando."
],
[
"Aplicado",
"Una función se aplicó antes de que existiera el registro; no se capturó su estado anterior."
]
]
}
}
@@ -62,11 +89,23 @@
"blocks": [
{
"table": {
"headers": ["Sección", "Contenido"],
"headers": [
"Sección",
"Contenido"
],
"rows": [
["Optimizaciones de post-install", "Agrupadas por la opción de post-install que seleccionó el usuario."],
["Scripts de ProxMenux", "GPU, Coral, red, almacenamiento, seguridad, utilidades y el resto de scripts instrumentados, incluidos el instalador de ProxMenux y ProxMenux Monitor."],
["Paquetes y utilidades instalados", "Software que ProxMenux instaló en el host."]
[
"Optimizaciones de post-install",
"Agrupadas por la opción de post-install que seleccionó el usuario."
],
[
"Scripts de ProxMenux",
"GPU, Coral, red, almacenamiento, seguridad, utilidades y el resto de scripts instrumentados, incluidos el instalador de ProxMenux y ProxMenux Monitor."
],
[
"Paquetes y utilidades instalados",
"Software instalado por ProxMenux en el host."
]
]
}
},
@@ -88,7 +127,7 @@
"Las líneas añadidas y eliminadas.",
"Los paquetes que se añadieron realmente.",
"La transición de estado de un servicio.",
"<strong>Deshacer esto</strong>: <em>Restaura exactamente lo que había</em>, <em>Elimina el fichero (no había ninguno antes)</em>, <em>Se puede desinstalar el paquete</em>, un deshacer parcial o <em>No se puede deshacer desde el registro</em>."
"<strong>Deshacer esto</strong>: <em>Restaura exactamente lo que había</em>, <em>Elimina el archivo (no existía antes)</em>, <em>Se puede desinstalar el paquete</em>, una reversión parcial o <em>No puede deshacerse desde el registro</em>."
]
}
}
@@ -96,10 +135,10 @@
},
{
"id": "before",
"title": "Qué significa el estado previo",
"title": "Qué significa el estado anterior",
"blocks": [
{
"p": "El estado previo puede ser contenido capturado, un archivo creado por primera vez o un estado desconocido. Los cambios hechos antes de que existiera el registro no pueden reconstruirse; al volver a ejecutar la función se captura primero el estado encontrado en ese momento."
"p": "El estado anterior puede ser contenido capturado, un archivo creado por primera vez o un estado desconocido. Los cambios anteriores al registro no pueden reconstruirse; al volver a ejecutar la función, primero se captura el estado encontrado en ese momento."
}
]
},
@@ -125,21 +164,42 @@
"blocks": [
{
"table": {
"headers": ["Elemento", "Comportamiento"],
"headers": [
"Elemento",
"Comportamiento"
],
"rows": [
["Entradas", "Se conservan en el host; del registro no se elimina nada automáticamente."],
["Contenido capturado", "Un objeto capturado se conserva mientras alguna entrada lo referencia."],
["Tamaño de una captura", "El contenido de más de 1 MiB no se guarda entero; la entrada registra que la captura se omitió por su tamaño."],
["Lectura", "El Monitor no carga objetos guardados de más de 2 MiB."],
["Diferencia", "Se muestran como máximo 400 líneas, y una diferencia más larga se marca como truncada."],
["Listado", "La API devuelve 200 entradas por petición por defecto y hasta 1000."]
[
"Entradas",
"Se conservan en el host; del registro no se elimina nada automáticamente."
],
[
"Contenido capturado",
"Un objeto capturado se conserva mientras alguna entrada lo referencia."
],
[
"Tamaño de una captura",
"El contenido de más de 1 MiB no se guarda entero; la entrada registra que la captura se omitió por su tamaño."
],
[
"Lectura",
"El Monitor no carga objetos guardados de más de 2 MiB."
],
[
"Diferencia",
"Se muestran como máximo 400 líneas; una diferencia más larga se marca como truncada."
],
[
"Listado",
"La API devuelve por defecto 200 entradas por petición, con un máximo de 1000."
]
]
}
},
{
"calloutWarning": {
"title": "Conservar el contenido no es deshacer automáticamente",
"body": "El contenido previo a un cambio puede consultarse y restaurarse a mano, pero la vista Cambios no revierte operaciones. Una entrada de ejecución registra el comando sin conocer todos los efectos de la herramienta que ejecutó."
"title": "Guardar el contenido no implica deshacer automáticamente",
"body": "El contenido anterior puede consultarse y restaurarse a mano, pero la vista Cambios no revierte operaciones. Una entrada de ejecución registra el comando sin conocer todos los efectos de la herramienta ejecutada."
}
}
]
@@ -1,11 +1,11 @@
{
"meta": {
"title": "Auditoría e informes | ProxMenux Monitor",
"description": "Evaluación de un nodo Proxmox VE, registro de lo que ProxMenux ha cambiado en él y declaración de lo que se espera de sus invitados y almacenamientos, con informes imprimibles."
"description": "Evalúa un nodo Proxmox VE, registra los cambios de ProxMenux y declara qué se espera de sus invitados y almacenamiento, con informes imprimibles."
},
"header": {
"title": "Auditoría e informes",
"description": "Una evaluación del nodo, el registro de lo que ProxMenux ha cambiado en él y la declaración de lo que se espera de él, con documentos que pueden imprimirse o guardarse como PDF.",
"description": "Evaluación del nodo, registro de los cambios realizados por ProxMenux y declaración de expectativas, con documentos imprimibles o guardables en PDF.",
"section": "ProxMenux Monitor"
},
"sections": [
@@ -15,26 +15,47 @@
{
"calloutInfo": {
"title": "Tres vistas, tres preguntas",
"body": "Auditoría e informes separa los hechos del nodo, las intervenciones de ProxMenux y las expectativas declaradas para él. Una configuración que la evaluación no puede contrastar con una finalidad declarada se describe, no se presenta como un fallo."
"body": "Auditoría e informes separa los hechos del nodo, las intervenciones de ProxMenux y las expectativas declaradas. Si una configuración no puede contrastarse con una finalidad declarada, se describe sin considerarla un fallo."
}
},
{
"cards": {
"items": [
{ "icon": "shield", "title": "Evaluación: ¿cómo está el nodo?", "body": "Ejecuta las comprobaciones del perfil elegido, compone el inventario y clasifica lo que requiere atención, con la evidencia de cada resultado." },
{ "icon": "refresh", "title": "Cambios: ¿qué ha hecho ProxMenux?", "body": "Enumera los archivos, paquetes, servicios y comandos que han cambiado los scripts instrumentados de ProxMenux, con lo que había antes cuando se capturó." },
{ "icon": "fileText", "title": "Política: ¿qué se espera?", "body": "Declara qué invitados necesitan backup o deben arrancar con el host, qué almacenamiento es esencial y los umbrales de las comprobaciones." }
{
"icon": "shield",
"title": "Evaluación: ¿cómo está el nodo?",
"body": "Ejecuta las comprobaciones del perfil elegido, compone el inventario y clasifica lo que requiere atención, con la evidencia de cada resultado."
},
{
"icon": "refresh",
"title": "Cambios: ¿qué ha hecho ProxMenux?",
"body": "Enumera los archivos, paquetes, servicios y comandos modificados por los scripts de ProxMenux con instrumentación de auditoría, e incluye el estado anterior cuando se capturó."
},
{
"icon": "fileText",
"title": "Política: ¿qué se espera?",
"body": "Declara qué invitados necesitan backup o deben arrancar con el host, qué almacenamiento es esencial y los umbrales de las comprobaciones."
}
]
}
},
{
"flow": {
"nodes": [
{ "label": "Evaluación", "detail": "hechos" },
{ "label": "Política", "detail": "contexto" },
{ "label": "Cambios", "detail": "intervenciones" }
{
"label": "Evaluación",
"detail": "hechos"
},
{
"label": "Política",
"detail": "contexto"
},
{
"label": "Cambios",
"detail": "intervenciones"
}
],
"caption": "La evaluación aporta los hechos, la política les da contexto y el registro recoge lo que ha hecho ProxMenux."
"caption": "La evaluación aporta los hechos, la política les da contexto y el registro recoge lo que hizo ProxMenux."
}
},
{
@@ -52,11 +73,23 @@
"blocks": [
{
"table": {
"headers": ["Función", "Qué hace"],
"headers": [
"Función",
"Qué hace"
],
"rows": [
["<healthLink>Health Monitor</healthLink>", "Observa métricas y eventos de forma continua y puede generar notificaciones."],
["Auditoría e informes", "Ejecuta una evaluación cuando se pide, documenta el nodo y compara ejecuciones entre sí."],
["Registro de cambios", "Registra las operaciones que ProxMenux realiza a través de sus primitivas de auditoría."]
[
"<healthLink>Monitor de estado</healthLink>",
"Observa métricas y eventos continuamente y puede generar notificaciones."
],
[
"Auditoría e informes",
"Ejecuta una evaluación bajo demanda, documenta el nodo y compara ejecuciones entre sí."
],
[
"Registro de cambios",
"Registra las operaciones realizadas por ProxMenux mediante sus primitivas de auditoría."
]
]
}
}
@@ -69,11 +102,31 @@
{
"next": {
"items": [
{ "label": "Evaluación e inventario", "href": "/docs/monitor/audit-report/assessment", "tail": "perfiles, resultados, riesgos aceptados e inventario." },
{ "label": "Cambios", "href": "/docs/monitor/audit-report/changes", "tail": "el registro de lo que ProxMenux ha cambiado en el host." },
{ "label": "Política", "href": "/docs/monitor/audit-report/policy", "tail": "invitados, almacenamiento y umbrales." },
{ "label": "Informes y comparaciones", "href": "/docs/monitor/audit-report/reports", "tail": "los seis documentos y la ejecución de referencia." },
{ "label": "Alcance y garantías", "href": "/docs/monitor/audit-report/scope", "tail": "fuentes, límites y datos guardados." }
{
"label": "Evaluación e inventario",
"href": "/docs/monitor/audit-report/assessment",
"tail": "perfiles, resultados, riesgos aceptados e inventario."
},
{
"label": "Cambios",
"href": "/docs/monitor/audit-report/changes",
"tail": "el registro de lo que ProxMenux ha cambiado en el host."
},
{
"label": "Política",
"href": "/docs/monitor/audit-report/policy",
"tail": "invitados, almacenamiento y umbrales."
},
{
"label": "Informes y comparaciones",
"href": "/docs/monitor/audit-report/reports",
"tail": "los seis documentos y la ejecución de referencia."
},
{
"label": "Alcance y garantías",
"href": "/docs/monitor/audit-report/scope",
"tail": "fuentes, límites y datos guardados."
}
]
}
}
@@ -1,11 +1,11 @@
{
"meta": {
"title": "Política | Auditoría e informes",
"description": "La política del nodo en Auditoría e informes: backup, arranque y objetivo de recuperación de cada invitado, el papel de cada almacenamiento y los umbrales de las comprobaciones."
"description": "Política del nodo en Auditoría e informes: backups, arranque automático y objetivo de recuperación de cada invitado, función de cada almacenamiento y umbrales de comprobación."
},
"header": {
"title": "Política",
"description": "La política declara lo que ninguna inspección puede deducir: para qué sirve cada invitado y almacenamiento y los umbrales que aplican las comprobaciones.",
"description": "La política declara lo que una inspección no puede deducir: la finalidad de cada invitado y almacenamiento y los umbrales que deben aplicar las comprobaciones.",
"section": "Auditoría e informes"
},
"sections": [
@@ -34,11 +34,27 @@
"blocks": [
{
"table": {
"headers": ["Campo", "Valores", "Efecto en la evaluación"],
"headers": [
"Campo",
"Valores",
"Efecto en la evaluación"
],
"rows": [
["Backup", "Obligatorio, No obligatorio, Sin especificar", "La falta de backup es una advertencia si es obligatorio, una observación si no se especifica, y queda fuera del recuento si no es obligatorio."],
["Arranque", "Obligatorio, No obligatorio, Sin especificar", "Si el invitado debe arrancar con el host."],
["Objetivo de recuperación", "Horas", "La antigüedad máxima aceptable del último backup."]
[
"Backups",
"Obligatorio, No obligatorio, Sin especificar",
"La falta de backup es una advertencia si es obligatorio, una observación si no se especifica, y queda fuera del recuento si no es obligatorio."
],
[
"Arranque automático",
"Obligatorio, No obligatorio, Sin especificar",
"Si el invitado debe arrancar con el host."
],
[
"Objetivo de recuperación",
"Horas",
"La antigüedad máxima aceptable del último backup."
]
]
}
}
@@ -47,30 +63,30 @@
{
"id": "storage",
"title": "Almacenamiento",
"intro": "Cada almacenamiento del nodo se declara Esencial, Opcional o Sin especificar.",
"blocks": [
{
"p": "Un almacenamiento inaccesible se presenta como crítico cuando se declara esencial o sirve a un invitado en marcha, como advertencia cuando su papel no se especifica, y como observación cuando se declara opcional."
}
]
],
"intro": "Cada almacenamiento del nodo se declara Esencial, Opcional o Sin especificar."
},
{
"id": "thresholds",
"title": "Umbrales",
"intro": "Un umbral vacío usa el valor de fábrica, que se muestra como texto de ejemplo.",
"intro": "Un umbral vacío usa el valor incluido por defecto, mostrado como texto de ejemplo.",
"blocks": [
{
"list": {
"items": [
"Revisión de capacidad de almacenamiento (%) y revisión de ocupación de thin pool (%).",
"Ratio de sobreaprovisionamiento thin y ratio de sobreasignación de memoria.",
"Revisión de capacidad de almacenamiento (%) y ocupación del thin pool (%).",
"Ratio de sobreaprovisionamiento thin y de sobreasignación de memoria.",
"Intervalo de scrub de ZFS (días).",
"Plazo de respaldo para la antigüedad (días) y margen sobre el calendario (ratio).",
"Plazo alternativo para la antigüedad del backup (días) y margen sobre el calendario (ratio).",
"Aviso de caducidad de certificado (días).",
"Vida útil del disco (horas) y ventana de errores de disco recientes (días).",
"Antigüedad del informe de Lynis (días) y antigüedad de los índices de paquetes (días).",
"Journal frente a su tope (%).",
"Revisión de espacio del sistema de archivos (%) y revisión de inodos del sistema de archivos (%)."
"Antigüedad del informe de Lynis (días) y del índice de paquetes (días).",
"Uso del journal respecto a su límite (%).",
"Revisión del espacio (%) y de los inodos (%) del sistema de archivos."
]
}
}
@@ -81,12 +97,12 @@
"title": "Cómo se guarda la política",
"blocks": [
{
"p": "La declaración se valida y se guarda de forma atómica en <code>/usr/local/share/proxmenux/audit_policy.json</code>. Cada guardado lleva una revisión: si la declaración cambió en otra sesión, el borrador no se guarda y la vista ofrece recargar la declaración guardada."
"p": "La declaración se valida y guarda de forma atómica en <code>/usr/local/share/proxmenux/audit_policy.json</code>. Cada guardado incluye una revisión: si otra sesión cambió la declaración, el borrador no se guarda y la vista ofrece recargar la versión guardada."
},
{
"calloutWarning": {
"title": "La política nunca se deduce",
"body": "ProxMenux no añade ningún requisito por su cuenta. Un campo vacío conserva el valor de fábrica o queda sin especificar, y una declaración parcial solo afecta a los elementos que nombra."
"body": "ProxMenux no añade requisitos por su cuenta. Un campo vacío conserva el valor incluido por defecto o queda sin especificar; una declaración parcial solo afecta a los elementos que menciona."
}
}
]
@@ -1,11 +1,11 @@
{
"meta": {
"title": "Informes y comparaciones | Auditoría e informes",
"description": "Los seis documentos de Auditoría e informes, cómo se imprimen o guardan como PDF y cómo se comparan las ejecuciones con una ejecución de referencia."
"description": "Los seis documentos de Auditoría e informes, su impresión o guardado en PDF y la comparación de ejecuciones con una referencia."
},
"header": {
"title": "Informes y comparaciones",
"description": "Seis documentos, cada uno compuesto para una pregunta distinta, y la comparación de cada ejecución con una ejecución de referencia.",
"description": "Seis documentos que responden a preguntas distintas y comparación de cada ejecución con una referencia.",
"section": "Auditoría e informes"
},
"sections": [
@@ -29,11 +29,17 @@
"items": [
{
"title": "Auditoría completa",
"body": "Documenta el nodo de extremo a extremo como registro técnico.",
"body": "Documenta todo el nodo como registro técnico.",
"href": "/monitor/audit/sample-audit-full-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "Todas las disponibles." },
{ "label": "Contenido", "value": "Resumen ejecutivo; identidad y clúster; hardware; red y latencia; almacenamiento; invitados; passthrough; aplicaciones; hallazgos con evidencia; fuentes y alcance." }
{
"label": "Comprobaciones",
"value": "Todas las comprobaciones disponibles."
},
{
"label": "Contenido",
"value": "Resumen ejecutivo; identidad y clúster; hardware; red y latencia; almacenamiento; invitados; passthrough; aplicaciones; hallazgos con evidencia; fuentes y alcance."
}
]
},
{
@@ -41,8 +47,14 @@
"body": "Muestra lo que requiere atención sin el inventario completo.",
"href": "/monitor/audit/sample-audit-diagnostic-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "Las mismas que la auditoría completa." },
{ "label": "Contenido", "value": "Identidad mínima; hallazgos críticos; advertencias; observaciones relevantes; lecturas sin verificar y acciones prioritarias. Deja fuera diagramas, inventario y anexos extensos." }
{
"label": "Comprobaciones",
"value": "Las mismas que la auditoría completa."
},
{
"label": "Contenido",
"value": "Identidad mínima; hallazgos críticos; advertencias; observaciones relevantes; lecturas sin verificar y acciones prioritarias. Deja fuera diagramas, inventario y anexos extensos."
}
]
},
{
@@ -50,8 +62,14 @@
"body": "Describe lo que existe en el nodo sin evaluarlo.",
"href": "/monitor/audit/sample-audit-inventory-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "Ninguna; no se clasifica ningún hallazgo." },
{ "label": "Contenido", "value": "Identidad; clúster; CPU y memoria; placa, BIOS y controladoras; red; almacenamiento; VM y LXC; passthrough; aplicaciones y elementos gestionados por ProxMenux." }
{
"label": "Comprobaciones",
"value": "Ninguna; no se clasifica ningún hallazgo."
},
{
"label": "Contenido",
"value": "Identidad; clúster; CPU y memoria; placa, BIOS y controladoras; red; almacenamiento; VM y LXC; passthrough; aplicaciones y elementos gestionados por ProxMenux."
}
]
},
{
@@ -59,8 +77,14 @@
"body": "Abarca la exposición y los controles de acceso al nodo.",
"href": "/monitor/audit/sample-audit-security-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "El área de seguridad, más los privilegios de los contenedores, las actualizaciones, los repositorios y la cadena APT." },
{ "label": "Contenido", "value": "Identidad y clúster; red y latencia; acceso; cortafuegos; 2FA; certificados; privilegios; actualizaciones; repositorios; estado y antigüedad de Lynis." }
{
"label": "Comprobaciones",
"value": "El área de seguridad, más los privilegios de los contenedores, las actualizaciones, los repositorios y la cadena APT."
},
{
"label": "Contenido",
"value": "Identidad y clúster; red y latencia; acceso; cortafuegos; 2FA; certificados; privilegios; actualizaciones; repositorios; estado y antigüedad de Lynis."
}
]
},
{
@@ -68,8 +92,14 @@
"body": "Comprueba que la protección declarada existe y que sus backups son utilizables.",
"href": "/monitor/audit/sample-audit-backup-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "El área de backups, más la conectividad del almacenamiento y la entrega de notificaciones." },
{ "label": "Contenido", "value": "Cobertura por invitado; objetivo de recuperación declarado; antigüedad y resultado; destino; retención; verificación; trabajos fallidos; recuperación y fuentes incompletas." }
{
"label": "Comprobaciones",
"value": "El área de backups, más la conectividad del almacenamiento y la entrega de notificaciones."
},
{
"label": "Contenido",
"value": "Cobertura por invitado; objetivo de recuperación declarado; antigüedad y resultado; destino; retención; verificación; trabajos fallidos; recuperación y fuentes incompletas."
}
]
},
{
@@ -77,8 +107,14 @@
"body": "Mide el margen de crecimiento y las señales de agotamiento o envejecimiento.",
"href": "/monitor/audit/sample-audit-capacity-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "Las áreas de almacenamiento y hardware, más memoria, swap, journal y el sistema de archivos del host." },
{ "label": "Contenido", "value": "Ocupación y umbrales; thin pools; sobreaprovisionamiento; memoria; inodos; ZFS; temperaturas; horas de funcionamiento; errores SMART y vida útil de NVMe/SSD." }
{
"label": "Comprobaciones",
"value": "Las áreas de almacenamiento y hardware, más memoria, swap, journal y el sistema de archivos del host."
},
{
"label": "Contenido",
"value": "Ocupación y umbrales; thin pools; sobreaprovisionamiento; memoria; inodos; ZFS; temperaturas; horas de funcionamiento; errores SMART y vida útil NVMe/SSD."
}
]
}
]
@@ -92,7 +128,7 @@
}
},
{
"p": "Un documento contiene la identidad del nodo y la fecha de la evaluación, el resultado ejecutivo, un resumen por áreas, la estructura de hardware, red y almacenamiento, la protección de los invitados, los hallazgos con su evidencia, las fuentes que no pudieron leerse, y el alcance y la política aplicada, en la medida en que cada perfil los incluye."
"p": "Cada perfil incluye, según corresponda, identidad del nodo y fecha de evaluación, resumen ejecutivo, resumen por áreas, estructura de hardware, red y almacenamiento, protección de invitados, hallazgos con evidencia, fuentes ilegibles y alcance y política aplicados."
}
]
},
@@ -103,10 +139,22 @@
{
"steps": {
"items": [
{ "title": "Ejecutar", "body": "Una evaluación se ejecuta con el perfil seleccionado en <strong>Informe</strong>." },
{ "title": "Revisar", "body": "La ejecución terminada muestra sus hallazgos, las fuentes que no pudo leer y la política que aplicó." },
{ "title": "Generar informe", "body": "<strong>Generar informe</strong> abre la vista preparada como documento." },
{ "title": "Imprimir", "body": "<strong>Imprimir o guardar como PDF</strong> abre el diálogo de impresión del navegador, donde se selecciona una impresora o <em>Guardar como PDF</em>." }
{
"title": "Ejecutar",
"body": "La evaluación usa el perfil seleccionado en <strong>Informe</strong>."
},
{
"title": "Revisar",
"body": "La ejecución terminada muestra sus hallazgos, las fuentes que no pudo leer y la política que aplicó."
},
{
"title": "Generar informe",
"body": "<strong>Generar informe</strong> abre la vista preparada como documento."
},
{
"title": "Imprimir",
"body": "<strong>Imprimir o guardar como PDF</strong> abre el diálogo de impresión del navegador para elegir una impresora o <em>Guardar como PDF</em>."
}
]
}
},
@@ -121,37 +169,76 @@
{
"id": "compare",
"title": "Comparar con una ejecución de referencia",
"intro": "<strong>Usar como referencia</strong> marca una ejecución terminada como referencia. Las ejecuciones posteriores se comparan con ella y sus hallazgos se separan en:",
"intro": "<strong>Usar como referencia</strong> marca una ejecución terminada. Las siguientes se comparan con ella y sus hallazgos se agrupan en:",
"blocks": [
{
"table": {
"headers": ["Grupo", "Significado"],
"headers": [
"Grupo",
"Significado"
],
"rows": [
["Nuevos", "Presentes ahora y no antes."],
["Empeoraron", "Siguen presentes, y son más graves o afectan a más que antes."],
["Mejoraron", "Siguen presentes, pero son menos graves o afectan a menos que antes."],
["Resueltos", "Ya no aparecen, y nadie los aceptó."],
["Aceptados", "Ya no cuentan porque se aceptó un riesgo, no porque haya cambiado el host."],
["Ya no se evalúan", "Estaban antes y no aparecen en esta ejecución; nada ha verificado que hayan dejado de existir."]
[
"Nuevos",
"Presentes ahora y no antes."
],
[
"Empeoraron",
"Siguen apareciendo, pero son más graves o afectan a más que antes."
],
[
"Mejoraron",
"Siguen apareciendo, pero son menos graves o afectan a menos que antes."
],
[
"Resueltos",
"Ya no aparecen y nadie los ha aceptado."
],
[
"Aceptados",
"Ya no cuentan porque se aceptó un riesgo, no porque haya cambiado el host."
],
[
"Ya no se evalúan",
"Aparecían antes pero no en esta ejecución; no se ha verificado que hayan desaparecido."
]
]
}
},
{
"table": {
"headers": ["Ejecución de referencia", "Comportamiento"],
"headers": [
"Ejecución de referencia",
"Comportamiento"
],
"rows": [
["Marcarla", "Puede marcarse cualquier ejecución terminada; ninguna se marca automáticamente."],
["Cambiarla", "Marcar otra ejecución mueve la referencia sin borrar el historial."],
["Comparar", "Si no se seleccionan dos ejecuciones, la comparación usa la referencia y la ejecución seleccionada o la más reciente."],
["Conservar ejecuciones", "Se conservan las 30 ejecuciones más recientes, y la ejecución de referencia nunca se elimina."],
["Sin referencia", "La vista indica que todavía no se ha elegido una ejecución de referencia, así que no hay con qué comparar."]
[
"Marcarla",
"Puede marcarse cualquier ejecución terminada; ninguna se marca automáticamente."
],
[
"Cambiarla",
"Marcar otra ejecución cambia la referencia sin borrar el historial."
],
[
"Comparar",
"Si no se seleccionan dos ejecuciones, la comparación usa la referencia y la ejecución seleccionada o la más reciente."
],
[
"Conservar ejecuciones",
"Se conservan las 30 ejecuciones más recientes; la de referencia nunca se elimina."
],
[
"Sin referencia",
"La vista indica que aún no se ha elegido una ejecución de referencia, así que no hay con qué comparar."
]
]
}
},
{
"calloutWarning": {
"title": "Un informe describe un momento",
"body": "Una evaluación no certifica un periodo completo. Los resultados antiguos dejan de describir el estado actual; la vista muestra la antigüedad de la última ejecución y cada fuente conserva el momento en que se recogió."
"body": "Una evaluación no certifica un periodo completo. Los resultados antiguos dejan de representar el estado actual; la vista muestra la antigüedad de la última ejecución y cada fuente conserva su momento de recogida."
}
}
]
@@ -1,11 +1,11 @@
{
"meta": {
"title": "Alcance y garantías | Auditoría e informes",
"description": "De dónde proceden los datos de Auditoría e informes, qué queda fuera de su alcance, las garantías de su diseño y dónde se guardan sus datos."
"description": "Origen de los datos de Auditoría e informes, límites de su alcance, garantías del diseño y ubicación de sus datos."
},
"header": {
"title": "Alcance y garantías",
"description": "De dónde proceden los datos de una evaluación, qué queda fuera de su alcance y dónde guarda Auditoría e informes sus datos.",
"description": "De dónde proceden los datos de una evaluación, qué queda fuera de su alcance y dónde guarda sus datos Auditoría e informes.",
"section": "Auditoría e informes"
},
"sections": [
@@ -38,7 +38,7 @@
"El equipamiento de red fuera del host.",
"Las dependencias remotas que el nodo no puede observar.",
"El estado físico que el hardware no expone.",
"Las acciones manuales o de otro software, en el registro de cambios."
"El registro de cambios no incluye acciones manuales ni de otros programas."
]
}
},
@@ -62,7 +62,7 @@
"Una política validada y guardada de forma atómica.",
"Riesgos aceptados con motivo y visibles.",
"Atribución de los cambios al script y a la función.",
"Captura del estado anterior y posterior cuando está disponible.",
"Captura del estado anterior y posterior, cuando está disponible.",
"Un resultado explícito cuando algo no puede medirse o capturarse."
]
}
@@ -75,20 +75,38 @@
"blocks": [
{
"table": {
"headers": ["Datos", "Ubicación"],
"headers": [
"Datos",
"Ubicación"
],
"rows": [
["Política", "<code>/usr/local/share/proxmenux/audit_policy.json</code>"],
["Evaluaciones", "La base de datos de auditoría del Monitor"],
["Objetos capturados", "<code>/usr/local/share/proxmenux/changes/objects/</code>"],
["Entradas pendientes", "<code>/usr/local/share/proxmenux/changes/spool/</code>"],
["Registro consolidado", "<code>/usr/local/share/proxmenux/changes.db</code>"]
[
"Política",
"<code>/usr/local/share/proxmenux/audit_policy.json</code>"
],
[
"Evaluaciones",
"La base de datos de auditoría del Monitor"
],
[
"Objetos capturados",
"<code>/usr/local/share/proxmenux/changes/objects/</code>"
],
[
"Entradas pendientes",
"<code>/usr/local/share/proxmenux/changes/spool/</code>"
],
[
"Registro consolidado",
"<code>/usr/local/share/proxmenux/changes.db</code>"
]
]
}
},
{
"calloutInfo": {
"title": "Una herramienta de revisión, no una certificación",
"body": "Auditoría e informes revisa, compara y documenta el nodo. Sus resultados se leen junto con la finalidad del sistema, la política declarada y las fuentes disponibles."
"body": "Auditoría e informes revisa, compara y documenta el nodo. Sus resultados se interpretan según la finalidad del sistema, la política declarada y las fuentes disponibles."
}
}
]
@@ -10,7 +10,7 @@
},
"intro": {
"title": "Un lanzador, no un instalador de aplicaciones",
"body": "La pestaña <strong>Apps</strong> no instala software ni descubre servicios por sí sola. Convierte los enlaces web guardados en una cuadrícula con búsqueda. Los enlaces que pertenecen a un LXC se configuran en la <appTabLink>pestaña App</appTabLink> del contenedor; los enlaces personalizados permiten incluir servicios de VMs, proxies inversos y paneles externos."
"body": "La pestaña <strong>Apps</strong> no instala ni descubre servicios. Convierte enlaces guardados en una cuadrícula con búsqueda. Los enlaces de LXC se configuran en su <appTabLink>pestaña App</appTabLink>; los personalizados permiten incluir servicios VM, proxies inversos y paneles externos."
},
"sources": {
"heading": "Qué aparece en Apps",
@@ -31,12 +31,12 @@
},
{
"source": "Enlace personalizado sin asociación",
"appears": "Cualquier destino HTTP(S), incluido un servicio externo o publicado mediante proxy inverso.",
"appears": "Cualquier destino HTTP(S), incluidos servicios externos o publicados mediante proxy inverso.",
"managedFrom": "Apps → Editar"
}
],
"relationshipTitle": "Apps y la pestaña App del LXC tienen funciones diferentes",
"relationshipBody": "La <appTabLink>pestaña App</appTabLink> del LXC gestiona la identidad de la aplicación, sus enlaces web y el seguimiento opcional de versión. La pestaña principal <strong>Apps</strong> utiliza esos enlaces para ofrecer un acceso rápido. Por eso, al editar una tarjeta que pertenece a un LXC se vuelve a su registro original en lugar de crear una segunda configuración."
"relationshipBody": "La <appTabLink>pestaña App</appTabLink> del LXC gestiona identidad, enlaces web y seguimiento opcional de versión. <strong>Apps</strong> usa esos enlaces para abrirlos rápidamente. Editar una tarjeta LXC vuelve al registro del invitado sin duplicar la configuración."
},
"cards": {
"heading": "Cómo utilizar una tarjeta",
@@ -45,7 +45,7 @@
"Pulsa la tarjeta para abrir su URL en una pestaña nueva del navegador.",
"El logotipo utiliza primero el definido para el enlace web y, cuando corresponde, recurre al logotipo general de la aplicación.",
"La etiqueta de categoría utiliza el mismo color y nombre que el enlace correspondiente en la pestaña App del LXC.",
"La etiqueta del invitado identifica la VM o el LXC asociado. Púlsala para abrir su modal; los enlaces de LXC abren directamente <strong>App</strong> y los de VM abren <strong>Estado</strong>.",
"La etiqueta del invitado identifica la VM o LXC asociado. Púlsala para abrir su ventana: LXC abre <strong>App</strong> y VM abre <strong>Estado</strong>.",
"La flecha morada hacia arriba indica que existe una actualización para esa aplicación o imagen Docker concreta. No representa el total de actualizaciones del invitado."
]
},
@@ -55,8 +55,8 @@
"items": [
"La búsqueda tiene en cuenta el nombre de la aplicación, el nombre del invitado, el VMID y la categoría.",
"El filtro de categoría permite mostrar una categoría concreta o todas las aplicaciones.",
"Se puede ordenar por <strong>Nombre</strong>, <strong>ID</strong> o <strong>Categoría</strong>. Al ordenar por categoría se insertan encabezados entre los grupos de tarjetas.",
"El orden seleccionado se recuerda en este navegador. El texto de búsqueda y el filtro de categoría se restablecen al volver a la página.",
"Ordena por <strong>Nombre</strong>, <strong>ID</strong> o <strong>Categoría</strong>. Ordenar por categoría añade encabezados entre grupos de tarjetas.",
"El orden se recuerda en este navegador. Búsqueda y filtro de categoría se restablecen al volver a la página.",
"La pestaña Apps permanece disponible aunque la cuadrícula esté vacía, de modo que se pueda añadir el primer enlace personalizado sin registrar antes una aplicación LXC."
]
},
@@ -67,21 +67,41 @@
"Pulsa <strong>Añadir enlace</strong> en la barra de herramientas o en el estado vacío.",
"Introduce un nombre y una URL completa que empiece por <code>http://</code> o <code>https://</code>.",
"Opcionalmente, añade un logotipo, elige o crea una categoría y asocia el enlace a una VM o un LXC.",
"Guarda el enlace. La nueva tarjeta se añade a la cuadrícula de inmediato.",
"Para modificar o eliminar un enlace personalizado, pulsa <strong>Editar</strong> y utiliza el lápiz de su tarjeta."
"Guarda el enlace. Su tarjeta aparece inmediatamente en la cuadrícula.",
"Para modificar o eliminar un enlace personalizado, pulsa <strong>Editar</strong> y el lápiz de su tarjeta."
],
"colField": "Campo",
"colRequired": "Obligatorio",
"colPurpose": "Finalidad",
"fields": [
{ "field": "Nombre", "required": "Sí", "purpose": "Título de la tarjeta y término de búsqueda." },
{ "field": "URL", "required": "Sí", "purpose": "Destino HTTP(S) completo que abre la tarjeta." },
{ "field": "URL del logotipo", "required": "No", "purpose": "Imagen remota que se muestra en la tarjeta." },
{ "field": "Categoría", "required": "No", "purpose": "Añade una etiqueta común y permite filtrar por categoría." },
{ "field": "Asociación a invitado", "required": "No", "purpose": "Vincula el enlace a una VM o un LXC y activa su acceso directo." }
{
"field": "Nombre",
"required": "Sí",
"purpose": "Título de la tarjeta y término de búsqueda."
},
{
"field": "URL",
"required": "Sí",
"purpose": "Destino HTTP(S) completo que abre la tarjeta."
},
{
"field": "URL del logotipo",
"required": "No",
"purpose": "Imagen remota que se muestra en la tarjeta."
},
{
"field": "Categoría",
"required": "No",
"purpose": "Añade una etiqueta común y permite filtrar por categoría."
},
{
"field": "Asociación al invitado",
"required": "No",
"purpose": "Vincula el enlace a una VM o un LXC y activa su acceso directo."
}
],
"editTitle": "Edita la fuente original",
"editBody": "El modo de edición solo muestra lápices en los enlaces personalizados. Para cambiar una tarjeta generada desde una aplicación LXC registrada, abre la <appTabLink>pestaña App</appTabLink> de ese contenedor y edita allí el enlace web guardado."
"editBody": "El modo de edición solo muestra lápices en enlaces personalizados. Para una tarjeta de aplicación LXC, abre la <appTabLink>pestaña App</appTabLink> del invitado y cambia allí el enlace guardado."
},
"categories": {
"heading": "Categorías y señales de actualización",
@@ -90,17 +110,17 @@
"El registro asistido por catálogo puede proponer una categoría para una aplicación LXC, pero el usuario siempre puede modificarla.",
"Desde el mismo selector se pueden crear categorías propias y reutilizarlas después en el filtro.",
"Los colores de las categorías son estables y se adaptan al tema claro u oscuro. El morado y el rojo se reservan para actualizaciones y estados de peligro.",
"En los enlaces web de Docker, ProxMenux relaciona la tarjeta con su contenedor o imagen y muestra el estado de actualización de esa imagen. Las actualizaciones de Docker Engine permanecen en la <updatesLink>pestaña Updates</updatesLink> del LXC."
"En Docker, la tarjeta se relaciona con su contenedor o imagen y muestra las actualizaciones de esa imagen. Las de Docker Engine permanecen en la <updatesLink>pestaña Actualizaciones</updatesLink> del LXC."
]
},
"persistence": {
"heading": "Persistencia y comportamiento de la caché",
"intro": "El panel está diseñado para abrirse con los datos ya disponibles en el Monitor, sin volver a analizar todos los invitados.",
"items": [
"Los enlaces personalizados se guardan de forma atómica en <code>/etc/proxmenux/custom_links.json</code> y se cargan en memoria al iniciar el Monitor.",
"Los enlaces personalizados se guardan atómicamente en <code>/etc/proxmenux/custom_links.json</code> y se cargan en memoria al iniciar Monitor.",
"Los enlaces registrados en LXCs siguen formando parte del registro guardado de cada aplicación; el panel Apps no los duplica en el archivo de enlaces personalizados.",
"Al crear, editar o eliminar un enlace personalizado, la lista en memoria se actualiza de inmediato.",
"La preferencia de ordenación se guarda solo en el navegador. No se sincroniza entre dispositivos ni usuarios.",
"La preferencia de orden solo se guarda en este navegador, sin sincronizarse entre dispositivos o usuarios.",
"La posición de Apps en la navegación principal se configura por separado en <settingsLink>Ajustes → Orden de navegación</settingsLink>."
]
},
@@ -109,19 +129,46 @@
"colProblem": "Situación",
"colResolution": "Solución",
"rows": [
{ "problem": "Una aplicación LXC está registrada, pero no aparece ninguna tarjeta", "resolution": "Abre su pestaña App y añade al menos un enlace web. El seguimiento de versión por sí solo no crea una tarjeta en el lanzador." },
{ "problem": "La URL o el logotipo son incorrectos", "resolution": "Edita el enlace personalizado desde Apps o modifica el enlace web en la pestaña App del LXC correspondiente." },
{ "problem": "Falta un servicio Docker", "resolution": "Edita la aplicación Docker registrada y guarda el puerto web publicado por el servicio como enlace web." },
{ "problem": "La flecha morada corresponde a otra actualización Docker", "resolution": "Revisa el nombre y la descripción del enlace web para que se puedan relacionar con el contenedor o la imagen correctos." },
{ "problem": "Apps se abre antes que Resumen del sistema", "resolution": "El primer elemento guardado en Ajustes → Orden de navegación se convierte en la pestaña inicial. Restaura el orden predeterminado o mueve Resumen a la primera posición." }
{
"problem": "Una aplicación LXC está registrada, pero no aparece ninguna tarjeta",
"resolution": "Abre su pestaña App y añade al menos un enlace web. El seguimiento de versión por sí solo no crea una tarjeta en el lanzador."
},
{
"problem": "La URL o el logotipo son incorrectos",
"resolution": "Edita el enlace personalizado desde Apps o modifica el enlace web en la pestaña App del LXC correspondiente."
},
{
"problem": "Falta un servicio Docker",
"resolution": "Edita la aplicación Docker registrada y guarda el puerto web publicado por el servicio como enlace web."
},
{
"problem": "La flecha morada corresponde a otra actualización Docker",
"resolution": "Revisa el nombre y la descripción del enlace web para que se puedan relacionar con el contenedor o la imagen correctos."
},
{
"problem": "Apps se abre antes que Resumen del sistema",
"resolution": "El primer elemento guardado en Ajustes → Orden de navegación se convierte en la pestaña inicial. Restaura el orden predeterminado o mueve Resumen a la primera posición."
}
]
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{ "label": "Pestaña App del LXC", "href": "/docs/monitor/dashboard/vms-lxcs/app", "tail": " — registrar aplicaciones, enlaces web y seguimiento opcional de versión." },
{ "label": "Pestaña Updates del LXC", "href": "/docs/monitor/dashboard/vms-lxcs/updates", "tail": " — configurar y ejecutar actualizaciones de aplicaciones, Docker Engine e imágenes." },
{ "label": "Pestaña Ajustes", "href": "/docs/monitor/dashboard/settings#navigation-order", "tail": " — cambiar el orden de navegación y la pestaña inicial." }
{
"label": "Pestaña App del LXC",
"href": "/docs/monitor/dashboard/vms-lxcs/app",
"tail": " — registrar aplicaciones, enlaces web y seguimiento opcional de versión."
},
{
"label": "Pestaña Updates del LXC",
"href": "/docs/monitor/dashboard/vms-lxcs/updates",
"tail": " — configurar y ejecutar actualizaciones de aplicaciones, Docker Engine e imágenes."
},
{
"label": "Pestaña Ajustes",
"href": "/docs/monitor/dashboard/settings#navigation-order",
"tail": " — cambiar el orden de navegación y la pestaña inicial."
}
]
}
}
@@ -1,6 +1,6 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Hardware | ProxMenux Documentation",
"title": "ProxMenux Monitor — Panel: Hardware | Documentación de ProxMenux",
"description": "La pestaña Hardware inventaría la máquina física: CPU y placa base, módulos de memoria, sensores térmicos, GPUs (con monitorización en tiempo real por slot e instalador de drivers en un clic), aceleradoras Coral TPU, resumen de almacenamiento con comprobaciones de velocidad de enlace, listas completas de dispositivos PCI y USB, consumo de energía, PSUs, ventiladores y estado del UPS."
},
"header": {
@@ -14,29 +14,29 @@
},
"thresholds": {
"title": "Colores de estado y umbrales aplicados aquí",
"intro": "Cada chip de temperatura y lectura de esta pestaña sigue la misma clasificación — <green/> <strong>verde</strong> por debajo de Warning, <amber/> <strong>ámbar</strong> entre Warning y Critical, <red/> <strong>rojo</strong> en Critical y por encima. Valores por defecto recomendados que vienen con ProxMenux:",
"intro": "Cada indicador y lectura de temperatura usa la misma escala: <green/> <strong>verde</strong> por debajo de Advertencia, <amber/> <strong>ámbar</strong> entre Advertencia y Crítico, <red/> <strong>rojo</strong> desde Crítico. Valores recomendados incluidos con ProxMenux:",
"items": [
"<strong>Temperatura de CPU</strong> — Warning 80 °C, Critical 90 °C.",
"<strong>Temperatura de disco</strong> — HDD 60/65 °C · SSD 70/75 °C · NVMe 80/85 °C · SAS 55/65 °C (warning / critical)."
"<strong>Temperatura de CPU</strong>: advertencia 80 °C, crítico 90 °C.",
"<strong>Temperatura de disco</strong>: HDD 60/65 °C · SSD 70/75 °C · NVMe 80/85 °C · SAS 55/65 °C (advertencia / crítico)."
],
"outro": "Cada valor es configurable por host — <link>Settings → Health Monitor Thresholds</link> es la fuente única de verdad y explica cómo ajustarlos."
"outro": "Los valores se configuran por host; <link>Ajustes → Umbrales del monitor de salud</link> documenta y centraliza su ajuste."
},
"sections": {
"heading": "Secciones",
"intro": "La pestaña renderiza de arriba abajo en este orden. Algunas secciones solo aparecen cuando el host tiene el hardware o la herramienta correspondiente instalada — se marcan <em>(condicional)</em> abajo.",
"systemInfoTitle": "System Information",
"intro": "Las secciones aparecen en este orden de arriba abajo. Algunas requieren el hardware o la herramienta correspondiente; se indican como <em>(condicional)</em>.",
"systemInfoTitle": "Información del sistema",
"systemInfoIntro": "Dos bloques uno al lado del otro, siempre presentes:",
"systemInfoItems": [
"<strong>CPU</strong> — nombre del modelo, microarquitectura, sockets / cores / threads, frecuencia base / boost, flags de virtualización (VT-x / AMD-V), topología de caché.",
"<strong>Placa base</strong> — vendor, modelo, versión de BIOS, fecha de BIOS, UUID SMBIOS. Útil para emparejar con páginas de descarga del fabricante al buscar actualizaciones de firmware."
"<strong>CPU</strong>: modelo, microarquitectura, sockets, núcleos, hilos, frecuencias base y turbo, capacidades de virtualización (VT-x / AMD-V) y topología de caché.",
"<strong>Placa base</strong>: fabricante, modelo, versión y fecha de BIOS y UUID SMBIOS. Sirve para localizar la página de descarga correcta del fabricante al buscar firmware."
],
"memoryTitle": "Memory Modules",
"memoryBody": "Una fila por slot poblado desde <code>dmidecode</code>: etiqueta del slot, tamaño del módulo, tipo (DDR4 / DDR5 / variantes ECC), velocidad (configurada y nominal), fabricante, part number y serial. Los slots vacíos se listan atenuados para que veas de un vistazo el margen de ampliación.",
"thermalTitle": "Thermal Monitoring",
"thermalIntro": "Siete sub-bloques alimentados por <code>lm-sensors</code>, <code>sysfs</code> y scrapers específicos por herramienta. Los sensores hwmon de almacenamiento se correlacionan con el dispositivo de bloques físico, por lo que cada unidad detectada incluye su modelo y la ruta <code>/dev/...</code>. Un bloque permanece oculto cuando no hay sensores en esa categoría.",
"memoryTitle": "Módulos de memoria",
"memoryBody": "Una fila por slot ocupado según <code>dmidecode</code>: etiqueta, capacidad del módulo, tipo (DDR4 / DDR5 / variantes ECC), velocidad configurada y nominal, fabricante, referencia y número de serie. Los slots vacíos aparecen atenuados para mostrar el margen de ampliación.",
"thermalTitle": "Monitoreo Térmico",
"thermalIntro": "Siete bloques alimentados por <code>lm-sensors</code>, <code>sysfs</code> y lectores específicos de cada herramienta. Los sensores hwmon de almacenamiento se asocian al dispositivo de bloques físico, con su modelo y ruta <code>/dev/...</code>. Cada bloque se oculta si no hay sensores en su categoría.",
"thermalItems": [
"<strong>CPU</strong> — temperaturas de package y por core.",
"<strong>GPU</strong> — sensores de GPU discreta vía <code>nvidia-smi</code> / <code>amdgpu_top</code> / iGPU Intel. Incluye hot-spot y memory-junction cuando el driver los expone.",
"<strong>CPU</strong>: temperatura del encapsulado y de cada núcleo.",
"<strong>GPU</strong>: sensores de GPU dedicada mediante <code>nvidia-smi</code> / <code>amdgpu_top</code> y de iGPU Intel. Incluye punto caliente y unión de memoria cuando el controlador los ofrece.",
"<strong>NVME</strong> — temperatura composite del controlador asociada a su namespace NVMe exacto.",
"<strong>HDD</strong> — lecturas de <code>drivetemp</code> para dispositivos de bloques rotacionales.",
"<strong>SSD</strong> — lecturas de <code>drivetemp</code> para dispositivos de bloques SATA/SAS no rotacionales.",
@@ -45,16 +45,16 @@
]
},
"graphics": {
"heading": "Graphics Cards",
"intro": "Cada controlador de vídeo detectado renderiza como su propia tarjeta con vendor, modelo, tipo (<em>Integrada</em> / <em>PCI</em> / BMC), slot PCI (BDF), kernel driver y lista de módulos. La tarjeta también expone un control inline <strong>Switch Mode</strong> que alterna la GPU entre compartición LXC (driver nativo) y passthrough a VM (<code>vfio-pci</code>) — mira <link>Switch GPU Mode (VM ↔ LXC)</link> para entender qué pasa en el host cuando lo pulsas.",
"heading": "Tarjetas gráficas",
"intro": "Cada controlador de vídeo aparece en una tarjeta con fabricante, modelo, tipo (<em>Integrada</em> / <em>PCI</em> / BMC), dirección PCI (BDF), controlador del kernel y módulos. <strong>Cambiar modo</strong> alterna entre compartir la GPU con LXC (controlador nativo) y passthrough a VM (<code>vfio-pci</code>). <link>Cambiar modo GPU (VM ↔ LXC)</link> explica sus efectos en el host.",
"vfioImageAlt": "Sección Graphics Cards mostrando una GPU integrada Matrox G200EH atada a mgag200 (Ready for LXC) y una NVIDIA Quadro P400 atada a vfio-pci (Ready for VM passthrough)",
"vfioImageCaption": "Dos GPUs detectadas: el chip BMC Matrox está en el driver nativo y listo para LXC; la NVIDIA Quadro P400 está atada a <code>vfio-pci</code>, lista para passthrough a VM.",
"lxcImageAlt": "Sección Graphics Cards mostrando una iGPU Intel UHD Graphics en i915 y una NVIDIA Quadro P1000 en el driver nvidia, ambas etiquetadas Ready for LXC containers",
"lxcImageAlt": "Tarjetas gráficas: iGPU Intel UHD Graphics con i915 y NVIDIA Quadro P1000 con nvidia, ambas listas para contenedores LXC",
"lxcImageCaption": "Mismo nodo después de devolver la tarjeta NVIDIA al driver nativo — ambas GPUs ahora Ready for LXC containers.",
"realtimeTitle": "Modal de monitorización en tiempo real",
"realtimeBody": "Pulsar una tarjeta de GPU abre una modal de monitorización por slot que sondea la herramienta del vendor adecuada cada tres segundos. La modal expone vendor, tipo, slot PCI, driver, módulo(s) del kernel, utilización en vivo de motores (Render/3D, Video, Blitter, VideoEnhance), clocks de gráficos y memoria, temperatura, consumo de potencia (cuando se reporta), uso de VRAM y una tabla Active Processes con carga de motor por proceso. Los datos se sirven desde <code>/api/gpu/&lt;slot&gt;/realtime</code>.",
"toolsIntro": "La herramienta de vendor usada por GPU:",
"headerVendor": "Vendor",
"realtimeTitle": "Ventana de monitorización en tiempo real",
"realtimeBody": "Pulsa una GPU para abrir su monitorización por slot, que consulta la herramienta del fabricante cada tres segundos. Muestra fabricante, tipo, slot PCI, controlador, módulos del kernel, uso de motores (Render/3D, Video, Blitter, VideoEnhance), frecuencias de gráficos y memoria, temperatura, consumo si está disponible, VRAM y procesos activos con carga por proceso. Datos de <code>/api/gpu/&lt;slot&gt;/realtime</code>.",
"toolsIntro": "Herramienta del fabricante usada para cada GPU:",
"headerVendor": "Proveedor",
"headerTool": "Herramienta",
"headerProject": "Proyecto",
"tools": [
@@ -65,7 +65,7 @@
"projectHref": "https://developer.nvidia.com/nvidia-system-management-interface"
},
{
"vendor": "Intel iGPU",
"vendor": "iGPU Intel",
"tool": "intel_gpu_top (igt-gpu-tools)",
"projectLabel": "gitlab.freedesktop.org",
"projectHref": "https://gitlab.freedesktop.org/drm/igt-gpu-tools"
@@ -78,97 +78,97 @@
},
{
"vendor": "Matrox / ASPEED (BMC)",
"tool": "— (solo display)",
"tool": "— (solo visualización)",
"projectLabel": "Detectado y etiquetado como BMC; sin bloque realtime."
}
],
"nvidiaImageAlt": "Modal de monitorización de GPU para una NVIDIA Quadro P1000: vendor NVIDIA, driver nvidia cargado, clock gráfico 1.26 GHz, clock de memoria 2.50 GHz, temperatura 50 °C, todas las barras de utilización de motor al 0 %, sin procesos activos, memoria total 4096 MiB",
"nvidiaImageCaption": "NVIDIA Quadro P1000 con el driver propietario cargado — clocks, temperatura, barras de motores y procesos activos todos visibles.",
"intelImageAlt": "Modal de monitorización de GPU para una iGPU Intel UHD Graphics en driver i915, mostrando 11.31 W de consumo, 1 % de carga en motor de video y un proceso ffmpeg consumiendo 8 MB",
"nvidiaImageAlt": "Monitorización de NVIDIA Quadro P1000: fabricante NVIDIA, controlador nvidia cargado, frecuencia gráfica 1.26 GHz, memoria 2.50 GHz, temperatura 50 °C, motores al 0 %, sin procesos activos y memoria total 4096 MiB",
"nvidiaImageCaption": "NVIDIA Quadro P1000 con controlador propietario: frecuencias, temperatura, barras de uso de motores y procesos activos.",
"intelImageAlt": "Monitorización de iGPU Intel UHD Graphics con controlador i915: consumo 11.31 W, carga de vídeo 1 % y proceso ffmpeg con 8 MB",
"intelImageCaption": "iGPU Intel con <code>i915</code> activo. La tabla Active Processes recoge un job ffmpeg usando el motor de video.",
"amdImageAlt": "Modal de monitorización de GPU para una GPU integrada AMD Lucienne en driver amdgpu, con barras de utilización de motor al 0 % y amdgpu_top listado como proceso activo",
"amdImageCaption": "iGPU AMD monitorizada a través de <code>amdgpu_top</code> — la propia herramienta aparece como proceso activo porque es el backend de polling en vivo.",
"installTitle": "Instalar el driver NVIDIA desde la modal",
"installBody": "Cuando una GPU NVIDIA está atada a <code>nouveau</code>/<code>nvidiafb</code> (sin driver propietario instalado), el bloque realtime no puede leer clocks, potencia ni carga por proceso. La modal entonces reemplaza las métricas con un botón <strong>Install NVIDIA Drivers</strong> que conecta directamente con el mismo script documentado en <link>Install NVIDIA Drivers (Host)</link>.",
"noDriverAlt": "Modal de monitorización de GPU para una NVIDIA Quadro P620 con módulos de kernel nvidiafb y nouveau cargados, un callout Extended Monitoring Not Available y un botón azul Install NVIDIA Drivers",
"amdImageAlt": "Monitorización de GPU integrada AMD Lucienne con amdgpu: motores al 0 % y amdgpu_top como proceso activo",
"amdImageCaption": "iGPU AMD monitorizada con <code>amdgpu_top</code>. La herramienta aparece como proceso activo porque obtiene los datos en vivo.",
"installTitle": "Instalar el controlador NVIDIA desde la ventana",
"installBody": "Si una GPU NVIDIA usa <code>nouveau</code>/<code>nvidiafb</code> sin controlador propietario, no se pueden leer frecuencias, consumo ni carga por proceso. La ventana muestra <strong>Instalar controladores NVIDIA</strong>, que ejecuta el script de <link>Instalar controladores NVIDIA (Host)</link>.",
"noDriverAlt": "Monitorización de NVIDIA Quadro P620 con nvidiafb y nouveau cargados, aviso Monitorización ampliada no disponible y botón azul Instalar controladores NVIDIA",
"noDriverCaption": "Sin driver propietario instalado todavía — la modal muestra un instalador de un solo clic.",
"promptAlt": "Diálogo de confirmación NVIDIA GPU Driver Installation listando las GPUs detectadas, contenedores LXC con passthrough NVIDIA y un par Yes/Cancel",
"promptAlt": "Confirmación de instalación de controladores NVIDIA, con GPU detectadas, contenedores LXC con passthrough NVIDIA y botones Sí/Cancelar",
"promptCaption": "Resumen pre-instalación: GPUs detectadas, contenedores LXC que ya tienen passthrough NVIDIA y qué hará el script. No se toca nada hasta que confirmas.",
"successAlt": "Salida de terminal mostrando el driver NVIDIA 580.105.08 instalado correctamente y nvidia-smi reportando una Quadro P620",
"successCaption": "Instalación correcta — el <code>.run</code> de NVIDIA construido vía DKMS, el servicio de persistencia en su sitio y <code>nvidia-smi</code> reportando la GPU.",
"warningTitle": "Elige una versión de driver que tu GPU soporte de verdad",
"warningBody": "Las ramas más nuevas de driver NVIDIA dejan de dar soporte a familias de GPU antiguas (p. ej. Maxwell / Kepler). Si la instalación termina pero <code>nvidia-smi</code> reporta <em>\"No devices were found\"</em> o DKMS da error, lo más probable es que la rama elegida no cubra tu GPU — vuelve a lanzar el instalador y elige una rama más antigua (legacy 470.x para tarjetas de era Kepler, etc.). NVIDIA publica la compatibilidad por GPU en la <a>página oficial de búsqueda de drivers</a>.",
"warningBody": "Las ramas nuevas de NVIDIA eliminan soporte para GPU antiguas, como Maxwell o Kepler. Si termina la instalación pero <code>nvidia-smi</code> muestra <em>\"No devices were found\"</em> o falla DKMS, puede que la rama no sea compatible. Repite el instalador con una rama anterior, como legacy 470.x para Kepler. Consulta la compatibilidad en la <a>página oficial de búsqueda de controladores</a>.",
"whereGoIntro": "Por dónde seguir desde aquí:",
"whereGoItems": [
"<link1>Install NVIDIA Drivers (Host)</link1> — recorrido completo del instalador, matriz de compatibilidad de kernel, parche opcional NVENC y propagación a LXC.",
"<link2>Switch GPU Mode (VM ↔ LXC)</link2> — qué hace realmente el control inline <em>Switch Mode</em>.",
"<link3>Add GPU to VM (Passthrough)</link3> y <link4>Add GPU to LXC</link4> — asignación por primera vez de una GPU sin atar."
"<link1>Instalar controladores NVIDIA (Host)</link1>: guía del instalador, matriz de compatibilidad del kernel, parche NVENC opcional y propagación a LXC.",
"<link2>Cambiar modo GPU (VM ↔ LXC)</link2>: efectos del control <em>Cambiar modo</em> de la tarjeta.",
"<link3>Añadir GPU a VM (passthrough)</link3> y <link4>Añadir GPU a LXC</link4>: primera asignación de una GPU sin asociar."
]
},
"coral": {
"heading": "Coral TPU / Aceleradoras de IA",
"subHeading": "(condicional)",
"intro": "Se renderiza cuando el host tiene dispositivos Google Coral u otras aceleradoras de IA conectadas. Cada dispositivo abre una modal con su tipo de conexión (M.2 / mini-PCIe / USB), ancho de enlace PCIe, vendor / product ID, kernel driver (<code>apex</code> para PCIe, <code>libedgetpu</code> para USB), módulos del kernel (<code>gasket</code> + <code>apex</code>), nodos de dispositivo (<code>/dev/apex_*</code>), estado del runtime Edge TPU, temperatura en vivo y los umbrales de aviso de hardware del firmware.",
"intro": "Aparece cuando hay dispositivos Google Coral u otras aceleradoras de IA conectadas. Cada dispositivo abre sus detalles: conexión (M.2 / mini-PCIe / USB), ancho PCIe, ID de fabricante/producto, soporte de software (<code>apex</code> del kernel para PCIe, <code>libedgetpu</code> de usuario para USB), módulos (<code>gasket</code> + <code>apex</code>), nodos (<code>/dev/apex_*</code>), estado del runtime Edge TPU, temperatura en vivo y umbrales de aviso del firmware.",
"imageAlt": "Modal de detalle Coral Edge TPU: conexión PCIe / M.2, enlace PCIe 5.0 GT/s x1, vendor 1ac1:089a, kernel driver apex, módulos gasket y apex cargados, /dev/apex_0 presente, Edge TPU Runtime no instalado, temperatura 53.5 °C con umbrales de aviso de hardware",
"imageCaption": "Coral M.2 con los módulos de kernel del host cargados, el nodo de dispositivo arriba y los avisos de temperatura del firmware expuestos. La línea del runtime se pone verde una vez instalado el runtime Edge TPU correspondiente.",
"pathsIntro": "Existen dos rutas de instalación dependiendo del form factor:",
"pathsIntro": "Hay dos vías de instalación según el formato:",
"pathsItems": [
"<strong>M.2 / Mini-PCIe</strong> — el host necesita los módulos de kernel <code>gasket</code> + <code>apex</code> construidos vía DKMS para que el nodo de dispositivo <code>/dev/apex_0</code> aparezca en el arranque.",
"<strong>USB Accelerator</strong> — el host solo necesita el runtime de espacio de usuario Edge TPU (<code>libedgetpu1-std</code>) desde el repositorio APT de Google."
],
"outro": "Ambas las gestiona una única entrada de ProxMenux — <installLink>Install Coral TPU on the Host</installLink> — que auto-detecta lo que tienes. El contexto y el runtime oficial viven en <a>coral.ai/docs</a>. Una vez listo el lado del host, entrega el dispositivo a un contenedor con <lxcLink>Add Coral TPU to LXC</lxcLink>."
"outro": "Una sola entrada, <installLink>Instalar Coral TPU en el host</installLink>, detecta y gestiona ambos tipos. Consulta el contexto y runtime oficial en <a>coral.ai/docs</a>. Después, asígnalo a un contenedor con <lxcLink>Añadir Coral TPU a LXC</lxcLink>."
},
"storage": {
"heading": "Storage Summary",
"intro": "Cada dispositivo de bloque que conoce el kernel, agrupado por tipo. Para cada disco obtienes el nombre del kernel (<code>sda</code>, <code>nvme0n1</code>, <code>zram0</code> …), la etiqueta de tipo (<em>SSD</em>, <em>HDD</em>, <em>NVMe SSD</em>), la cadena del modelo y la información del enlace negociado. Pulsa cualquier disco para abrir una modal de info de hardware con modelo, serial, capacidad, interfaz y velocidad de enlace actual vs máxima.",
"heading": "Resumen de almacenamiento",
"intro": "Todos los dispositivos de bloques conocidos por el kernel, agrupados por tipo. Cada disco muestra su nombre (<code>sda</code>, <code>nvme0n1</code>, <code>zram0</code>…), tipo (<em>SSD</em>, <em>HDD</em>, <em>NVMe SSD</em>), modelo y enlace negociado. Pulsa para abrir modelo, número de serie, capacidad, interfaz y velocidad actual y máxima.",
"imageAlt": "Tarjeta Storage Summary listando once dispositivos de bloque (SSDs SATA, HDDs SATA, SSDs NVMe y zram) con cadenas de modelo y velocidades de enlace negociadas; los dos discos NVMe muestran 3.0 x4 con la velocidad actual resaltada",
"imageCaption": "Once dispositivos en este nodo. Los enlaces SATA se imprimen como <em>SATA &lt;version&gt;, &lt;Gb/s&gt; (current: ...)</em>; los discos NVMe se imprimen como <em>&lt;PCIe gen&gt; x&lt;width&gt;</em>.",
"nvmeBody": "Para los discos NVMe la línea por tarjeta muestra tanto el enlace negociado como el máximo que soporta el dispositivo. Cuando ambos no coinciden (p. ej. un SSD Gen3 x4 corriendo a <strong>3.0 x1</strong> porque está sentado en un slot del chipset cableado a un solo lane), la velocidad actual se renderiza en ámbar para que el downgrade sea visible de un vistazo — útil al diagnosticar discos inesperadamente lentos o después de que una actualización de BIOS reorganice los lanes.",
"imageCaption": "Once dispositivos en este nodo. Los enlaces SATA aparecen como <em>SATA &lt;version&gt;, &lt;Gb/s&gt; (current: ...)</em>; los NVMe como <em>&lt;PCIe gen&gt; x&lt;width&gt;</em>.",
"nvmeBody": "La línea de cada NVMe compara el enlace negociado con el máximo admitido. Si difieren, como un SSD Gen3 x4 funcionando a <strong>3.0 x1</strong> en un slot de un solo carril, el valor actual aparece en ámbar. Permite detectar enlaces limitados al investigar discos lentos o cambios de carriles tras actualizar BIOS.",
"nvmeModalAlt": "Modal de detalle de disco NVMe para nvme0n1: tipo NVMe SSD, 953.9 GB de capacidad, velocidad actual de enlace 3.0 x1 resaltada en ámbar, velocidad máxima 3.0 x4, modelo WDC CL SN720, número de serie, interfaz PCIe/NVMe",
"nvmeModalCaption": "Modal NVMe mostrando el downgrade de lanes — el disco soporta x4 pero el slot está cableado x1.",
"outro": "Los datos SMART, los self-tests, el historial y el informe PDF de disco viven una pestaña a la derecha, en <storageLink>Panel: pestaña Almacenamiento</storageLink>. Los mismos datos alimentan el script en <smartLink>SMART Disk Health & Test</smartLink> — lanzar un test long desde el script escribe el JSON que el Monitor muestra en <em>Storage → History</em>."
"nvmeModalCaption": "Detalles NVMe con enlace limitado: el disco admite x4, pero el slot está conectado a x1.",
"outro": "Los datos SMART, autopruebas, historial e informe PDF están en <storageLink>Panel: Almacenamiento</storageLink>. Los mismos datos alimentan <smartLink>Salud y pruebas SMART de discos</smartLink>. Una prueba larga desde el script escribe el JSON mostrado por Monitor en <em>Almacenamiento → Historial</em>."
},
"pci": {
"heading": "PCI Devices",
"intro": "Cada dispositivo direccionable por PCI, identificado por su <strong>BDF PCI</strong> (Bus:Device.Function — p. ej. <code>03:00.0</code>) y su clase de dispositivo (<em>Storage Controller</em>, <em>USB Controller</em>, <em>Graphics Card</em>, <em>Network Controller</em>, <em>Audio Controller</em> …). Cada tarjeta muestra el fabricante, el nombre del dispositivo y el <strong>kernel driver actualmente atado</strong> — que es el campo que realmente quieres al diagnosticar passthrough, grupos IOMMU o una tarjeta que el host no esté manejando correctamente.",
"heading": "Dispositivos PCI",
"intro": "Dispositivos PCI identificados por <strong>BDF PCI</strong> (Bus:Device.Function, p. ej. <code>03:00.0</code>) y clase (<em>Controlador de almacenamiento</em>, <em>Controlador USB</em>, <em>Tarjeta gráfica</em>, <em>Controlador de red</em>, <em>Controlador de audio</em>…). Cada tarjeta muestra fabricante, nombre y <strong>controlador del kernel asociado</strong>, útil para diagnosticar passthrough, grupos IOMMU o controladores incorrectos.",
"imageAlt": "Sección PCI Devices listando quince dispositivos agrupados por clase: storage controllers en ahci/nvme, USB controllers, tarjetas gráficas (una en vfio-pci, otra en el driver nativo), network controllers en igb / tg3, un audio controller junto a una GPU pasada por passthrough",
"imageCaption": "Quince dispositivos en este nodo. Fíjate en la GPU y su función de audio compañera, ambas atadas a <code>vfio-pci</code> — esa es una tarjeta preparada para passthrough a VM.",
"bdfTitle": "Leer el BDF",
"bdfBody": "<code>03:00.0</code> significa bus PCI <code>03</code>, dispositivo <code>00</code>, función <code>0</code>. Los dispositivos multifunción como las GPUs discretas suelen reclamar <code>.0</code> para la GPU y <code>.1</code> para la función de audio HDMI — ambos hay que pasarlos por passthrough juntos, por eso <link>Switch GPU Mode</link> también gestiona la limpieza de la función de audio huérfana al salir del modo VM."
"bdfBody": "<code>03:00.0</code> indica bus PCI <code>03</code>, dispositivo <code>00</code> y función <code>0</code>. Las GPU dedicadas suelen usar <code>.0</code> para gráficos y <code>.1</code> para audio HDMI. Ambas funciones se pasan juntas a la VM; por eso <link>Cambiar modo GPU</link> limpia también el audio que quedaría sin asociar al salir del modo VM."
},
"usb": {
"heading": "USB Devices",
"intro": "Cada dispositivo USB que enumera el host, con cadenas de fabricante / producto, versión USB, la dirección <code>bus:device</code>, el par <code>vendor:product</code> y el kernel driver. El renderer también clasifica roles comunes — <em>Communications</em> (sticks Z-Wave / Zigbee), <em>UPS</em>, almacenamiento, HID — para que veas de un vistazo cuál de tus sticks es cuál sin cruzar IDs.",
"imageAlt": "Tarjeta USB Devices listando tres dispositivos: un Z-Stick Z-Wave Aeotec, un coordinador Zigbee ConBee II y un UPS Ellipse ECO, cada uno con versión USB, dirección, vendor:product ID y driver atado",
"heading": "Dispositivos USB",
"intro": "Dispositivos USB con fabricante y producto, versión USB, dirección <code>bus:device</code>, ID <code>vendor:product</code> y controlador del kernel. Se clasifican por función: <em>Comunicaciones</em> (adaptadores Z-Wave / Zigbee), <em>SAI</em>, almacenamiento o HID. Así se identifican sin comparar sus ID.",
"imageAlt": "Dispositivos USB: Aeotec Z-Wave Z-Stick, coordinador Zigbee ConBee II y SAI Ellipse ECO, con versión USB, dirección, ID vendor:product y controlador asociado",
"imageCaption": "Tres dispositivos USB — dos radios de domótica en <code>usbfs</code> y un UPS en <code>usbfs</code> (NUT le habla a través de libusb)."
},
"power": {
"heading": "Power Consumption",
"heading": "Consumo de energía",
"subHeading": "(condicional)",
"intro": "Se renderiza solo cuando el host expone telemetría de energía. Se exponen dos fuentes independientes cuando están disponibles:",
"intro": "Aparece si el host ofrece telemetría de potencia. Muestra dos fuentes independientes cuando están disponibles:",
"items": [
"<strong>Consumo total ACPI / IPMI</strong> — watios de todo el sistema desde un sensor a nivel de placa o el BMC. Típico en placas de servidor.",
"<strong>Consumo de package CPU</strong> — leído de los contadores Intel RAPL (o equivalente AMD). Útil para separar el consumo de CPU del resto del sistema en placas consumer que no exponen una cifra total."
"<strong>Consumo total ACPI / IPMI</strong>: potencia de todo el sistema desde un sensor de la placa o el BMC. Habitual en placas de servidor.",
"<strong>Consumo del encapsulado CPU</strong>: contadores Intel RAPL o equivalente AMD. Distingue el consumo de CPU del resto en placas de consumo sin sensor total."
],
"supplyImageAlt": "Sección Power Consumption mostrando 198 W de consumo total vía interfaz ACPI, más una tarjeta Power Supplies con dos PSUs ambas reportando OK (salida de 185 W y 5 W)",
"supplyImageAlt": "Consumo: 198 W totales por ACPI y dos fuentes de alimentación con estado OK y salida de 185 W y 5 W",
"supplyImageCaption": "Placa de servidor con un único sensor de energía ACPI y PSUs duales reportadas a través de IPMI — la segunda PSU es la redundante, en idle a 5 W.",
"cpuImageAlt": "Sección Power Consumption en una placa consumer mostrando solo CPU Power 8.7 W vía Intel RAPL",
"cpuImageCaption": "Placa consumer sin sensor de todo el sistema — la sección cae a RAPL solo-CPU."
"cpuImageAlt": "Consumo en una placa de uso doméstico: solo 8.7 W de CPU medidos por Intel RAPL",
"cpuImageCaption": "Placa de uso doméstico sin sensor de consumo total: se muestra solo CPU mediante RAPL."
},
"psu": {
"heading": "Power Supplies",
"heading": "Fuentes de alimentación",
"subHeading": "(condicional)",
"body": "Máquinas con placa de servidor / PSU dual vía IPMI: presencia (PSU 1 / PSU 2 / …), voltaje de entrada, watios de salida, flag OK / failed. Lo primero que compruebas tras un parpadeo de luz en un nodo con PSUs redundantes."
"body": "En máquinas con placa de servidor o fuentes dobles, IPMI muestra presencia (PSU 1 / PSU 2 / …), tensión de entrada, potencia de salida y estado correcto/fallo. Compruébalo tras una interrupción eléctrica en nodos con fuentes redundantes."
},
"fans": {
"heading": "System Fans",
"heading": "Ventiladores del sistema",
"subHeading": "(condicional)",
"body": "RPM por ventilador con un pequeño sparkline (cuando se soporta). En placas sin reporte por ventilador la sección cae a una única lectura del ventilador de chasis."
"body": "RPM de cada ventilador con minigráfico de tendencia, si se admite. Sin datos individuales, muestra una sola lectura del ventilador del chasis."
},
"ups": {
"heading": "UPS Status",
"heading": "Estado del SAI",
"subHeading": "(condicional)",
"body": "Se renderiza cuando hay un servidor NUT (Network UPS Tools) configurado y accesible. Muestra: estado (online / on battery / charging / low battery), porcentaje de carga de batería, estimación de runtime, porcentaje de carga, voltaje de entrada, modelo y firmware. Los mismos datos alimentan la categoría <em>Security & Certificates</em> del Monitor de salud — un UPS que pasa a batería sale inmediatamente."
"body": "Aparece si hay un servidor NUT (Network UPS Tools) configurado y accesible. Muestra estado (en línea / batería / cargando / batería baja), carga de batería, autonomía estimada, porcentaje de carga soportada, tensión de entrada, modelo y firmware. Alimenta también <em>Seguridad y certificados</em> del monitor de salud: el paso a batería se señala inmediatamente."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -184,12 +184,12 @@
{
"section": "Valores de sensores en vivo",
"endpoint": "/api/hardware/live",
"source": "<code>sensors</code> (lm-sensors) junto con <code>/sys/class/hwmon</code> y <code>/sys/block</code> para identificar los dispositivos de almacenamiento. Las temperaturas permanecen en vivo; solo la topología hwmon-dispositivo se guarda en caché durante 60 segundos."
"source": "<code>sensors</code> (lm-sensors), <code>/sys/class/hwmon</code> y <code>/sys/block</code> identifican los dispositivos de almacenamiento. Las temperaturas son en vivo; solo se guarda en caché 60 segundos la asociación hwmon-dispositivo."
},
{
"section": "Historial de temperatura de CPU",
"endpoint": "/api/temperature/history",
"source": "Serie temporal muestreada por el Monitor de salud cada 5 min y persistida a SQLite."
"source": "Serie temporal registrada cada 60 segundos por el recolector de temperatura y almacenada en SQLite."
},
{
"section": "Métricas en vivo de GPU",
@@ -197,31 +197,31 @@
"source": "NVIDIA: <code>nvidia-smi --query-gpu=...</code>. Intel: <code>intel_gpu_top</code>. AMD: sysfs <code>/sys/class/drm/cardN</code>."
}
],
"codeComment1": "# Cross-check del inventario contra la vista del SO",
"codeComment1": "# Contrastar el inventario con la información del sistema operativo",
"codeComment2": "# Confirmar la tarjeta GPU que ve el panel"
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{
"label": "Install NVIDIA Drivers (Host)",
"label": "Instalar controladores NVIDIA (Host)",
"href": "/docs/hardware/nvidia-host",
"tail": " — lo que ejecuta el botón de instalación de la modal de GPU."
"tail": " — script que ejecuta el botón de instalación de la ventana de GPU."
},
{
"label": "Switch GPU Mode (VM ↔ LXC)",
"label": "Cambiar modo GPU (VM ↔ LXC)",
"href": "/docs/hardware/switch-gpu-mode",
"tail": " — lo que el conmutador de modo inline en cada tarjeta de GPU le hace al host."
},
{
"label": "Install Coral TPU on the Host",
"label": "Instalar Coral TPU en el host",
"href": "/docs/hardware/install-coral-tpu-host",
"tail": " — la instalación del módulo de kernel / runtime de Coral."
"tail": " — instalación del módulo del kernel y runtime de Coral."
},
{
"label": "SMART Disk Health & Test",
"label": "Prueba de salud de disco SMART",
"href": "/docs/disk-manager/smart-disk-test",
"tail": " — el script detrás de los datos SMART que muestra la vista en detalle de disco de la pestaña Almacenamiento."
"tail": " — script que produce los datos SMART de los detalles de disco en Almacenamiento."
},
{
"label": "Panel: pestaña Almacenamiento",
@@ -231,12 +231,12 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la categoría CPU y Temperatura que consume los mismos sensores."
"tail": " — categoría CPU y Temperatura, que usa los mismos sensores."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints de hardware y GPU."
"tail": " — endpoints de hardware y GPU."
},
{
"label": "Índice del panel",
@@ -1,16 +1,16 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel | ProxMenux Documentation",
"description": "El panel es la interfaz principal de ProxMenux Monitor: diez pestañas de contenido, incluido el lanzador Apps, además de la cabecera global y un orden de navegación configurable."
"title": "ProxMenux Monitor — Panel | Documentación de ProxMenux",
"description": "El panel es la interfaz principal de ProxMenux Monitor: diez pestañas, incluido el lanzador Apps, una cabecera global y un orden de navegación configurable."
},
"header": {
"title": "Panel",
"description": "El panel es la vista diaria de ProxMenux Monitor: diez pestañas de contenido, incluido el lanzador Apps, además de una cabecera global y un orden de navegación configurable.",
"description": "La vista diaria de ProxMenux Monitor: diez pestañas, incluido el lanzador Apps, una cabecera global y un orden de navegación configurable.",
"section": "ProxMenux Monitor"
},
"oneHeader": {
"title": "Una cabecera, diez pestañas",
"body": "La cabecera (logo, nombre del nodo, información de estado, uptime, refresco, conmutador de tema) permanece visible en todo momento. La pestaña activa que hay debajo cambia el área de contenido entera. El color de la información de estado refleja la peor categoría del <link>Monitor de salud</link> — es el mismo dato visto desde el panel."
"body": "La cabecera (logo, nombre del nodo, indicador de estado, tiempo activo, actualización y tema) permanece visible. La pestaña activa cambia toda el área de contenido. El color del indicador refleja la peor categoría del <link>Monitor de estado</link>: el mismo dato mostrado en el panel."
},
"tabs": {
"heading": "Las diez pestañas",
@@ -24,9 +24,9 @@
"owns": "Widgets de CPU, memoria y temperatura; contador de VMs y LXCs activos; gráficas históricas y resúmenes de almacenamiento y red. Es la pestaña inicial mientras no se personalice el orden de navegación."
},
{
"name": "Apps",
"name": "Aplicaciones",
"linksTo": "/docs/monitor/dashboard/apps",
"owns": "Lanzador unificado para enlaces web registrados en LXCs y enlaces personalizados, con categorías, búsqueda, acceso al invitado y señales de actualización por aplicación."
"owns": "Lanzador unificado de enlaces web de LXC registrados y enlaces personalizados, con categorías, búsqueda, accesos al invitado y señales de actualización por aplicación."
},
{
"name": "Almacenamiento",
@@ -34,11 +34,11 @@
},
{
"name": "Red",
"owns": "Cada interfaz (física / bond / bridge / OVS), IP/MAC, gráficas RX/TX, RRD histórica por interfaz."
"owns": "Interfaces físicas, bond, bridge y OVS, direcciones IP/MAC, gráficas RX/TX e histórico RRD por interfaz."
},
{
"name": "VMs y LXCs",
"owns": "Inventario de guests, vista en detalle de config / métricas / logs, acciones start / stop / reboot / shutdown."
"owns": "Inventario de invitados, detalles de configuración, métricas y registros, acciones de iniciar, detener, reiniciar y apagar."
},
{
"name": "Hardware",
@@ -50,7 +50,7 @@
},
{
"name": "Terminal",
"owns": "Shell en el navegador al host o a cualquier VM/CT, sobre <code>xterm.js</code> y WebSockets."
"owns": "Shell del host o de cualquier VM/CT en el navegador, con <code>xterm.js</code> sobre WebSockets."
},
{
"name": "Seguridad",
@@ -58,19 +58,19 @@
},
{
"name": "Ajustes",
"owns": "Idioma del Monitor, orden de navegación, canales de notificación, proveedor de IA, umbrales de salud, exclusiones e inventario de optimizaciones."
"owns": "Idioma de Monitor, orden de navegación, canales de notificación, proveedor IA, umbrales de estado, exclusiones e inventario de optimizaciones posteriores a la instalación."
}
]
},
"headerAnatomy": {
"heading": "Anatomía de la cabecera",
"items": [
"<strong>Logo de ProxMenux.</strong> El logo cambia a la variante \"actualización disponible\" cuando se detecta una nueva release del Monitor.",
"<strong>Identidad del nodo</strong> — el nombre del nodo Proxmox resuelto desde <code>pvesh get /nodes</code>, con fallback a <code>hostname</code>.",
"<strong>Información del estado de salud</strong> — Healthy (verde), Warning (amarillo), Critical (rojo). Pulsa encima para abrir la modal del Monitor de salud. Aparece una insignia azul extra de <em>info</em> cuando hay items descartados que siguen dentro de su ventana de supresión.",
"<strong>Uptime</strong> — tiempo desde el último arranque del host, formateado de forma legible.",
"<strong>Botón de refresco</strong> — relanza todas las llamadas API en vivo sin recargar la página entera.",
"<strong>Conmutador de tema</strong> — claro / oscuro / sistema. Persiste en <code>localStorage</code>."
"<strong>Logo y nombre del producto</strong> a la izquierda. El logo adopta la variante «actualización disponible» cuando se detecta una versión más reciente de Monitor.",
"<strong>Identidad del nodo</strong>: nombre obtenido con <code>pvesh get /nodes</code>, usando <code>hostname</code> como alternativa.",
"<strong>Indicador de estado</strong>: Correcto (verde), Advertencia (amarillo), Crítico (rojo). Abre el Monitor de estado al pulsarlo. Una insignia azul <em>info</em> aparece si hay elementos descartados cuyo periodo de supresión sigue vigente.",
"<strong>Tiempo activo</strong>: tiempo de funcionamiento del host en formato legible.",
"<strong>Botón de actualización</strong>: repite las llamadas API de datos en directo sin recargar toda la página.",
"<strong>Selector de tema</strong>: claro, oscuro o sistema. Se guarda en <code>localStorage</code>."
]
},
"whereNext": {
@@ -79,7 +79,7 @@
{
"label": "Pestaña Apps",
"href": "/docs/monitor/dashboard/apps",
"tail": " — el lanzador unificado de enlaces web y su relación con las aplicaciones registradas en LXCs."
"tail": " — lanzador unificado de enlaces web y relación con las aplicaciones LXC registradas."
},
{
"label": "Pestaña Resumen del sistema",
@@ -89,7 +89,7 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la modal detrás de la información de estado, vista en profundidad de las diez categorías."
"tail": " — ventana del indicador de estado, con detalle de diez categorías."
},
{
"label": "Arquitectura",
@@ -1,16 +1,16 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Red | ProxMenux Documentation",
"description": "La pestaña Red inventaría cada interfaz del host: NICs físicas, bridges, bonds, VLANs y las interfaces virtuales de VM/LXC. La vista en detalle por interfaz muestra IP / MAC / estado / miembros del bond / tráfico desde el arranque y una gráfica RRD histórica."
"title": "ProxMenux Monitor — Panel: pestaña Red | Documentación de ProxMenux",
"description": "La pestaña Red enumera todas las interfaces del host: físicas, puentes, enlaces agrupados, VLAN e interfaces virtuales VM/LXC. El detalle muestra IP, MAC, estado, miembros del enlace agrupado, tráfico desde el arranque e historial RRD."
},
"header": {
"title": "Panel: pestaña Red",
"description": "Cada interfaz que reporta el kernel — NICs físicas, bridges, bonds, VLANs y puertos virtuales de VM/LXC — agrupadas en tres tarjetas. Cada fila es pulsable y abre una vista en detalle con direccionamiento, contadores de tráfico y datos RRD históricos.",
"description": "Todas las interfaces que detecta el kernel —físicas, puentes, enlaces agrupados, VLAN y puertos virtuales VM/LXC— se agrupan en tres tarjetas. Pulsa una fila para ver direcciones, contadores de tráfico e historial RRD.",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "En vivo + histórico, ambos incluidos",
"body": "El estado en vivo viene de <code>psutil.net_if_stats()</code> y <code>ip</code>; el ancho de banda histórico del almacén RRD de Proxmox vía <code>/api/network/&lt;interface&gt;/metrics</code>. La página refresca cada ~5 segundos los contadores en vivo y obtiene datos RRD frescos bajo demanda para la gráfica."
"title": "Datos actuales e históricos",
"body": "El estado actual procede de <code>psutil.net_if_stats()</code> e <code>ip</code>; el historial de ancho de banda, del almacén RRD de Proxmox mediante <code>/api/network/&lt;interface&gt;/metrics</code>. Los contadores se actualizan cada 5 segundos aproximadamente y el gráfico obtiene datos RRD cuando se solicitan."
},
"topRow": {
"heading": "Fila superior: cuatro tarjetas de estadísticas",
@@ -18,122 +18,122 @@
"headerWhat": "Qué muestra",
"rows": [
{
"card": "Network Traffic",
"card": "Tráfico de red",
"what": "Tasa agregada RX / TX a lo largo de todas las interfaces, formateada en la unidad correcta (bps / Kbps / Mbps / Gbps)."
},
{
"card": "Active Interfaces",
"what": "Dos contadores: <em>Physical X / Y</em> y <em>Bridges X / Y</em> (activas sobre total). El primer contador que miras cuando algo deja de funcionar."
"card": "Interfaces activas",
"what": "Dos contadores: <em>Physical X / Y</em> y <em>Bridges X / Y</em>, con interfaces activas respecto al total. Es un primer punto de comprobación cuando algo deja de funcionar."
},
{
"card": "Network Status",
"what": "Veredicto rápido — Healthy / Warning / Critical en función del estado del enlace, alcanzabilidad del gateway e integridad del bridge. Refleja la categoría <em>Network Interfaces</em> del Monitor de salud."
"card": "Estado de la red",
"what": "Estado rápido: Correcto / Aviso / Crítico según el enlace, la accesibilidad de la puerta de enlace y la integridad del puente. Refleja la categoría <em>Interfaces de red</em> de Health Monitor."
},
{
"card": "Network Latency",
"what": "Round-trip time al gateway con un sparkline. Pulsar la tarjeta abre la <strong>modal Network Latency</strong> documentada más abajo — vista histórica + test de ping bajo demanda contra gateway / Cloudflare / Google con un informe PDF descargable."
"card": "Latencia de red",
"what": "Tiempo de ida y vuelta a la puerta de enlace con un minigráfico. Al pulsar, abre el <strong>diálogo Latencia de red</strong> descrito más abajo: historial y prueba de ping a petición contra la puerta de enlace, Cloudflare o Google, con informe PDF descargable."
}
]
},
"flow": {
"heading": "Diagrama Network Flow",
"intro": "Entre la fila superior y las tres tarjetas de grupos, la pestaña renderiza una vista de topología en vivo llamada <strong>Network Flow</strong>. Dibuja cada camino que un paquete puede tomar a través del host — NICs físicas en un extremo, bridges en el medio, VMs y contenedores en el otro — con pulsos animados que muestran el tráfico rx/tx en tiempo real sobre cada enlace.",
"intro": "Entre la fila superior y las tres tarjetas aparece la topología en directo <strong>Network Flow</strong>. Muestra los recorridos de los paquetes: interfaces físicas en un extremo, puentes en medio y máquinas virtuales y contenedores en el otro. Los pulsos animados representan el tráfico rx/tx actual de cada enlace.",
"imageAlt": "Diagrama Network Flow — NICs a la izquierda, host y bridges en el medio, VMs y LXCs a la derecha, con pulsos animados en cada conexión",
"imageCaption": "Network Flow — nodos con código de color más cometas animados cuya dirección y grosor reflejan el tráfico en vivo.",
"elementsTitle": "Qué muestra el diagrama",
"elementsIntro": "Cada nodo es una entidad del mismo inventario que usan las tarjetas de abajo, pero organizadas como topología para que las relaciones se vean de un vistazo:",
"elementsIntro": "Cada nodo representa una entidad del mismo inventario que las tarjetas inferiores. La disposición como topología permite ver sus relaciones de un vistazo:",
"elements": [
"<strong>NICs</strong> (ámbar) — cada interfaz física con enlace activo. Las interfaces reportadas como down se dibujan atenuadas.",
"<strong>Host</strong> (ámbar) — el propio host Proxmox, situado entre las NICs y los bridges. Renderizado como anclaje fijo; no clicable.",
"<strong>Bridges</strong> (cian) — bridges Linux y OVS. Sólo se dibujan los bridges que llevan al menos un guest activo; los bridges sin uso se ocultan para que el diagrama muestre lo que realmente mueve tráfico.",
"<strong>LXCs</strong> (cian) — contenedores en ejecución conectados a un bridge.",
"<strong>VMs</strong> (púrpura) — máquinas virtuales en ejecución conectadas a un bridge.",
"Los guests offline (VMs / contenedores parados) se ocultan."
"<strong>NIC</strong> (ámbar): interfaces físicas con enlace activo; las inactivas aparecen atenuadas.",
"<strong>Host</strong> (ámbar): el host Proxmox entre las interfaces físicas y los puentes. Es un punto fijo y no se puede pulsar.",
"<strong>Puentes</strong> (cian): puentes Linux y OVS con al menos una máquina invitada activa. Los que no se usan se ocultan para centrar el diagrama en el tráfico actual.",
"<strong>LXC</strong> (cian): contenedores en ejecución conectados a un puente.",
"<strong>VM</strong> (morado): máquinas virtuales en ejecución conectadas a un puente.",
"Las máquinas virtuales y los contenedores detenidos se ocultan."
],
"pulsesTitle": "Qué codifica la animación",
"pulsesBody": "Los cometas animados que viajan por cada arista representan tráfico en vivo:",
"pulses": [
"<strong>Dirección</strong> — un pulso que fluye hacia la NIC es <em>tx</em> del guest; hacia el guest es <em>rx</em>.",
"<strong>Grosor de trazo</strong> escala con el rate combinado rx+tx del guest. Un guest inactivo dibuja una línea animada tenue; uno con carga la dibuja gruesa.",
"<strong>Halo de la cabeza del cometa</strong> — templado hacia ~1 MB/s, caliente a ≥30 MB/s. Útil para detectar de un vistazo qué guest está dominando una NIC.",
"<strong>Click</strong> — cada nodo excepto el host es clicable y abre el mismo modal de detalle por interfaz documentado más abajo. Pulsar el host es intencionadamente un no-op — no hay modal a nivel de host en esta vista."
"<strong>Dirección</strong>: hacia la NIC significa <em>tx</em> de la máquina invitada; hacia la máquina, <em>rx</em>.",
"El <strong>grosor del trazo</strong> aumenta con la tasa rx+tx de la máquina invitada. Sin tráfico se mantiene una línea animada tenue; con mucho tráfico, la línea es gruesa.",
"<strong>Brillo de la cabeza del cometa</strong>: tono cálido hacia 1 MB/s e intenso a partir de 30 MB/s. Permite identificar qué máquina invitada concentra el tráfico de una NIC.",
"<strong>Clic</strong>: todos los nodos salvo el host abren el diálogo de detalle por interfaz descrito más abajo. Pulsar el host no tiene efecto; esta vista no incluye un diálogo para él."
],
"useTitle": "Cuándo es útil",
"useBody": "Las tarjetas de grupos de abajo te dicen <em>qué</em> existe; el diagrama te dice <em>cómo está conectado</em> y por dónde fluye el tráfico ahora mismo. Patrones fáciles de ver de un vistazo: un bridge sin ningún guest activo conectado, dos guests pesados usando la misma NIC (candidato a cuello de botella), o una única VM saturando un enlace mientras el resto está tranquilo."
"useBody": "Las tarjetas muestran <em>qué</em> existe; el diagrama, <em>cómo está conectado</em> y por dónde fluye el tráfico. Permite detectar máquinas que comparten un puente, dos máquinas con mucho tráfico en una misma NIC —posible cuello de botella— o una VM que satura un enlace mientras las demás apenas transmiten."
},
"groups": {
"heading": "Tres grupos de interfaces",
"intro": "Bajo la fila superior, tres tarjetas dividen el inventario por rol. Cada tarjeta tiene su propia insignia de recuento de activas en la cabecera. El <strong>tipo</strong> de interfaz se identifica de un vistazo mediante una insignia coloreada en cada fila:",
"intro": "Tres tarjetas agrupan las interfaces por función. La cabecera de cada una indica cuántas están activas. Una etiqueta de color identifica el <strong>tipo</strong> de cada interfaz:",
"badges": [
"Azul <strong>Physical</strong> — NIC real.",
"Verde <strong>Bridge</strong> — bridge Linux o bridge OVS (<code>vmbr*</code>).",
"Morado <strong>Bond</strong> — agregador bond / LACP / active-backup.",
"Cian <strong>VLAN</strong> — sub-interfaz VLAN (<code>vmbr0.10</code>, <code>eno1.42</code>, …)."
"Cian <strong>VLAN</strong>: subinterfaz VLAN (<code>vmbr0.10</code>, <code>eno1.42</code>, …)."
],
"clickable": "<strong>Cada fila es pulsable</strong> — física, virtual, bridge o bond — y abre la vista en detalle por interfaz descrita más abajo (info básica, IPs, contadores de tráfico, gráfica RX/TX histórica del almacén RRD de Proxmox).",
"physicalTitle": "Physical Interfaces",
"physicalBody": "Cada NIC que el kernel ve como un dispositivo real — <code>eno1</code>, <code>enp4s0</code>, <code>eth0</code>, <code>wlp3s0</code>, etc. Una fila por dispositivo con la insignia azul <strong>Physical</strong> y el estado del enlace. Los <em>miembros del bond</em> (NICs esclavizadas a un bond) también se muestran aquí, con una pista que apunta al bond padre.",
"bridgeTitle": "Bridge Interfaces",
"bridgeBody": "Bridges Linux (<code>vmbr0</code>, <code>vmbr1</code>, …) y los bridges OVS que gestiona Proxmox. Cada fila muestra la insignia verde <strong>Bridge</strong>, la interfaz física subyacente (cuando es un bridge de un solo puerto) y el estado del bridge. Los bonds visibles en esta capa reciben la insignia morada <strong>Bond</strong>; las sub-interfaces VLAN reciben la insignia cian <strong>VLAN</strong>.",
"vmTitle": "VM / LXC Interfaces",
"vmBody": "Las interfaces <code>tap*</code> y <code>veth*</code> creadas cuando arrancan los guests — una por NIC virtual. La cabecera de la tarjeta muestra <em>X / Y Active</em>; las filas enlazan con el VM/CT al que pertenecen, así que puedes saltar directamente al guest en la pestaña VMs y LXCs. Las entradas inactivas quedan por un instante después de que un guest se pare; envejecen y se eliminan en el siguiente ciclo de refresco."
"clickable": "<strong>Todas las filas se pueden pulsar</strong>: físicas, virtuales, puentes y bonds. Abren el detalle descrito más abajo: información básica, IP, contadores y gráfico histórico RX/TX del almacén RRD Proxmox.",
"physicalTitle": "Interfaces físicas",
"physicalBody": "Interfaces físicas reconocidas por el kernel: <code>eno1</code>, <code>enp4s0</code>, <code>eth0</code>, <code>wlp3s0</code>, etc. Cada dispositivo tiene una fila con etiqueta azul <strong>Physical</strong> y estado del enlace. Los <em>miembros de un bond</em> también aparecen, con una referencia al bond al que pertenecen.",
"bridgeTitle": "Interfaces de puente",
"bridgeBody": "Puentes Linux (<code>vmbr0</code>, <code>vmbr1</code>, …) y OVS gestionados por Proxmox. Cada fila muestra la etiqueta verde <strong>Bridge</strong>, la interfaz física subyacente si tiene un solo puerto y su estado. Los enlaces agrupados llevan la etiqueta morada <strong>Bond</strong>; las subinterfaces VLAN, la cian <strong>VLAN</strong>.",
"vmTitle": "Interfaces de VM / LXC",
"vmBody": "Interfaces <code>tap*</code> y <code>veth*</code> creadas al arrancar las máquinas invitadas, una por NIC virtual. La cabecera muestra <em>X / Y Active</em> y las filas enlazan a su VM/CT en la pestaña VMs y LXCs. Tras detener una máquina, las entradas inactivas desaparecen en el siguiente ciclo de actualización."
},
"drillIn": {
"heading": "Vista en detalle por interfaz",
"intro": "Pulsar cualquier fila abre una modal con cinco bloques:",
"heading": "Detalle por interfaz",
"intro": "Al pulsar una fila, se abre un diálogo con cinco bloques:",
"headerBlock": "Bloque",
"headerContents": "Contenido",
"rows": [
{
"block": "Basic Information",
"contents": "Nombre de la interfaz, tipo (física / bridge / bond / VLAN / vm), dirección MAC, estado (up / down), MTU y la interfaz física subyacente para los tipos no físicos."
"block": "Información básica",
"contents": "Nombre, tipo (física / puente / bond / VLAN / vm), MAC, estado (activo / inactivo), MTU e interfaz física subyacente para los tipos virtuales."
},
{
"block": "Bond Members",
"contents": "Solo para bonds. Lista cada NIC esclavizada con el flag active / failed, el modo del bond (active-backup / 802.3ad / balance-alb / …) y la interfaz primaria cuando está configurada."
"block": "Miembros del bond",
"contents": "Solo para bonds: cada NIC integrante con estado activo o fallido, modo del bond (active-backup / 802.3ad / balance-alb / …) e interfaz principal si está configurada."
},
{
"block": "IP Addresses",
"block": "Direcciones IP",
"contents": "Cada dirección IPv4 / IPv6 con su longitud de prefijo. Las direcciones link-local autoconfiguradas se listan pero salen atenuadas."
},
{
"block": "Gráfica histórica",
"contents": "Ancho de banda RX / TX sobre el timeframe seleccionado (1 hora / 24 horas / 7 días / 30 días / 1 año), traído de <code>/api/network/&lt;interface&gt;/metrics</code> (RRD de Proxmox)."
"contents": "Ancho de banda RX/TX durante el periodo elegido (1 hora / 24 horas / 7 días / 30 días / 1 año), obtenido de <code>/api/network/&lt;interface&gt;/metrics</code> (RRD Proxmox)."
},
{
"block": "Tráfico desde el último arranque",
"contents": "Bytes y paquetes totales RX / TX desde el último arranque del host, más contadores de errores y descartes."
"contents": "Total de bytes y paquetes RX/TX desde el último arranque del host, con contadores de errores y descartes."
}
],
"inactiveTitle": "Las interfaces inactivas siguen abriendo la vista en detalle",
"inactiveBody": "Para una interfaz <em>down</em>, la modal renderiza un pequeño banner \"Interface Inactive\" y omite los contadores en vivo. La configuración (direcciones, miembros del bond) y los datos históricos siguen mostrándose — útil al diagnosticar por qué falló algo y cuándo."
"inactiveTitle": "También puedes ver el detalle de las interfaces inactivas",
"inactiveBody": "Si la interfaz está <em>inactiva</em>, el diálogo muestra el aviso «Interfaz inactiva» y omite los contadores actuales. Conserva la configuración —direcciones y miembros del bond— y el historial para diagnosticar qué falló y cuándo."
},
"latency": {
"heading": "Modal Network Latency",
"intro": "Pulsar la tarjeta <em>Network Latency</em> de la fila superior abre una modal dedicada. Tiene dos modos (histórico y test bajo demanda), tres opciones de destino y un informe PDF descargable.",
"heading": "Diálogo Latencia de red",
"intro": "Pulsa <em>Latencia de red</em> en la fila superior para abrir su diálogo. Incluye historial, pruebas a petición, tres destinos y un informe PDF descargable.",
"targetsTitle": "Destinos",
"targetsIntro": "Un desplegable de destino en lo alto de la modal selecciona contra qué se hace ping:",
"targetsIntro": "El desplegable de la parte superior selecciona el destino del ping:",
"targets": [
"<strong>Gateway</strong> — tu router de la LAN. Solo testea el tramo de red local; útil cuando sospechas de un problema de switch / cableado y quieres descartar la WAN.",
"<strong>Cloudflare (1.1.1.1)</strong> — resolutor DNS público, red anycast. Testea el tramo WAN.",
"<strong>Google (8.8.8.8)</strong> — destino público alternativo, útil como verificación sanity o cuando Cloudflare está degradado regionalmente."
"<strong>Puerta de enlace</strong>: tu router LAN. Comprueba solo el tramo local para investigar problemas del switch o del cableado sin incluir la WAN.",
"<strong>Cloudflare (1.1.1.1)</strong>: resolutor DNS público en una red anycast. Comprueba el tramo WAN.",
"<strong>Google (8.8.8.8)</strong>: destino público alternativo para contrastar resultados o comprobar incidencias regionales de Cloudflare."
],
"mode1Title": "Modo 1 — Vista histórica",
"mode1Alt": "Modal Network Latency en modo histórico — destino Gateway con un timeframe de 1 hora y las muestras pasadas ploteadas",
"mode1Caption": "Vista histórica — destino Gateway sobre la última hora, alimentada desde la base de datos de historial de latencia que el hilo recolector de temperatura/latencia escribe cada 60 segundos.",
"mode1Body1": "El modo por defecto al abrir la modal. Un segundo desplegable elige el timeframe (<em>1 Hour / 24 Hours / 7 Days / 30 Days / 1 Year</em>); la resolución de los datos baja con la ventana para que la gráfica se mantenga legible. Las estadísticas titulares — Current / Min / Avg / Max — se renderizan encima de la gráfica, con una pastilla de estado (Excellent / Good / Fair / Poor) que refleja el valor actual frente a los umbrales de abajo.",
"mode1Body2": "Fuente: las mismas muestras de latencia que usa el Monitor de salud para detectar ralentizaciones persistentes de red — muestreadas cada 60 segundos contra el gateway por el hilo en background <code>_temperature_collector_loop</code>, escritas a un historial SQLite local.",
"mode1Alt": "Diálogo de latencia en modo histórico, con destino Puerta de enlace, periodo de una hora y muestras anteriores representadas",
"mode1Caption": "Historial de la puerta de enlace durante la última hora. El recolector de temperatura y latencia guarda las muestras en la base de datos cada 60 segundos.",
"mode1Body1": "Es el modo inicial del diálogo. Un segundo desplegable elige el periodo (<em>1 hora / 6 horas / 24 horas / 3 días / 7 días</em>). Encima aparecen Actual / Mínimo / Media / Máximo y un indicador Excelente / Bueno / Regular / Malo según los umbrales siguientes.",
"mode1Body2": "Fuente: las muestras que usa Health Monitor para detectar ralentizaciones persistentes. El hilo <code>_temperature_collector_loop</code> mide la latencia de la puerta de enlace cada 60 segundos y la guarda en un historial SQLite local.",
"mode2Title": "Modo 2 — Test en tiempo real",
"mode2Alt": "Modal Network Latency ejecutando un test de ping en tiempo real contra Cloudflare — barra de progreso al 50%, muestras en vivo acumulándose en la gráfica",
"mode2Caption": "Test en tiempo real contra Cloudflare — ejecución de 2 minutos con una lectura cada 5 segundos, muestras ploteadas según llegan. Pulsa <em>Stop</em> para terminar antes; <em>Test Again</em> añade más muestras al mismo dataset.",
"mode2Alt": "Diálogo de latencia ejecutando un ping a Cloudflare en tiempo real, con progreso al 50 % y nuevas muestras en el gráfico",
"mode2Caption": "Prueba de dos minutos contra Cloudflare, con una lectura cada cinco segundos que se añade al gráfico al llegar. Pulsa <em>Detener</em> para finalizar antes; <em>Repetir prueba</em> añade muestras al mismo conjunto de datos.",
"mode2Intro": "Cambiar el destino a Cloudflare o Google arranca un test de ping bajo demanda. Comportamiento:",
"mode2Items": [
"<strong>Duración</strong> — 2 minutos por ejecución, con barra de progreso y un contador de segundos restantes.",
"<strong>Cadencia</strong> — una lectura cada 5 segundos (24 lecturas por ejecución).",
"<strong>Método</strong> — ICMP Echo Request (<code>ping</code>), 3 pings consecutivos por muestra, latencia promediada.",
"<strong>Duración</strong>: dos minutos por ejecución, con barra de progreso y segundos restantes.",
"<strong>Frecuencia</strong>: una lectura cada cinco segundos, 24 por ejecución.",
"<strong>Método</strong>: ICMP Echo Request (<code>ping</code>), con tres pings seguidos por muestra y su latencia media.",
"<strong>Stop</strong> — termina el test inmediatamente; los datos parciales se preservan.",
"<strong>Test Again</strong> — añade nuevas muestras al dataset existente en lugar de empezar de cero, así puedes construir un registro más largo a lo largo de varias ejecuciones.",
"<strong>Pastilla de estado en vivo</strong> — se reevalúa tras cada muestra con los mismos umbrales Excellent / Good / Fair / Poor."
"<strong>Repetir prueba</strong>: añade muestras a los datos existentes para construir un registro más largo con varias ejecuciones.",
"<strong>Indicador de estado actual</strong>: se recalcula tras cada muestra con los mismos umbrales Excelente / Bueno / Regular / Malo."
],
"thresholdsTitle": "Umbrales de rendimiento",
"headerStatus": "Estado",
@@ -141,47 +141,47 @@
"headerImpact": "Impacto práctico",
"thresholdRows": [
{
"status": "Excellent",
"status": "Excelente",
"range": "< 50 ms",
"impact": "Óptimo para apps en tiempo real, gaming y videollamadas."
},
{
"status": "Good",
"status": "Bueno",
"range": "50 – 100 ms",
"impact": "Aceptable para la mayoría de aplicaciones con impacto mínimo."
},
{
"status": "Fair",
"status": "Regular",
"range": "100 – 200 ms",
"impact": "Retardo perceptible. Puede afectar a VoIP y apps interactivas."
},
{
"status": "Poor",
"status": "Malo",
"range": "> 200 ms",
"impact": "Latencia significativa. Se recomienda investigar."
}
],
"reportTitle": "Network Latency Report (PDF)",
"reportIntro": "Ambos modos tienen un botón <strong>Report</strong> junto al selector de destino. Pulsarlo genera un PDF con todo lo que enviarías a tu ISP si quisieras argumentar un mal servicio.",
"reportPreviewAlt": "Primera página del PDF Network Latency Report — Executive Summary con el gauge, estadísticas de latencia, la gráfica de latencia y la guía de umbrales",
"reportPreviewCaption": "Primera página del Network Latency Report — Executive Summary con el dial del gauge y las estadísticas titulares, la gráfica de latencia por segundo y la guía de umbrales. De la página 2 en adelante está la tabla por muestra y la metodología.",
"downloadLabel": "Descargar informe de ejemplo Network Latency (PDF)",
"reportTitle": "Informe de latencia de red (PDF)",
"reportIntro": "Ambos modos tienen un botón <strong>Informe</strong> junto al selector de destino. Abre un informe imprimible de las mediciones; guárdalo como PDF desde el diálogo de impresión del navegador y adjúntalo a una solicitud de asistencia a tu proveedor de Internet.",
"reportPreviewAlt": "Primera página del informe PDF de latencia: resumen ejecutivo, indicador, estadísticas, gráfico y guía de umbrales",
"reportPreviewCaption": "La primera página contiene resumen ejecutivo, indicador, estadísticas principales, serie temporal de latencia y guía de umbrales. Desde la página 2 aparecen la tabla de muestras y la metodología.",
"downloadLabel": "Descargar informe de ejemplo de latencia (PDF)",
"sectionsIntro": "El informe tiene seis secciones:",
"sections": [
"<strong>Executive Summary</strong> — dial del gauge (0–300+ ms con zonas verde / amarilla / roja), el veredicto de estado (EXCELLENT / GOOD / FAIR / POOR), el destino / modo / recuento de muestras y un resumen de una línea sobre packet loss.",
"<strong>Latency Statistics</strong> — Current / Min / Avg / Max como cuatro tiles grandes, más Sample Count, Packet Loss (avg) y Test Period.",
"<strong>Latency Graph</strong> — gráfica de área de cada muestra a lo largo de la ventana del test con una rejilla en el eje y de min/avg/max.",
"<strong>Performance Thresholds</strong> — la misma escala de cuatro niveles documentada arriba, con un punto coloreado por nivel.",
"<strong>Detailed Test Results</strong> — tabla numerada con timestamp, latencia, packet loss y estado para cada muestra. Útil para detectar micro-ráfagas que esconden los promedios titulares.",
"<strong>Methodology</strong> — método del test (ICMP Echo Request), muestras por test (3 pings consecutivos), nombre del destino, IP del destino y un párrafo final \"Performance Assessment\" derivado del veredicto."
"<strong>Resumen ejecutivo</strong>: indicador de 0 a más de 300 ms con zonas verde, amarilla y roja; estado Excelente / Bueno / Regular / Malo; destino, modo, número de muestras y resumen de pérdida de paquetes.",
"<strong>Estadísticas de latencia</strong>: cuatro indicadores con valor actual, mínimo, media y máximo, además del número de muestras, pérdida media de paquetes y periodo de prueba.",
"<strong>Gráfico de latencia</strong>: gráfico de área de las muestras durante la prueba, con referencias de mínimo, media y máximo en el eje vertical.",
"<strong>Umbrales de rendimiento</strong>: la misma escala de cuatro niveles anterior, con un punto de color por nivel.",
"<strong>Resultados detallados</strong>: tabla numerada con fecha y hora, latencia, pérdida de paquetes y estado de cada muestra. Permite detectar picos breves ocultos por las medias.",
"<strong>Metodología</strong>: ICMP Echo Request, tres pings consecutivos por muestra, nombre e IP del destino y evaluación final derivada del estado."
],
"useCaseTitle": "Caso de uso: reclamaciones a tu ISP",
"useCaseBody": "Ejecuta el test en tiempo real contra Cloudflare durante 2 minutos en un momento de lentitud percibida, después pulsa <em>Test Again</em> unas cuantas veces para extender el dataset y finalmente <em>Report</em>. El PDF lleva la tabla completa por muestra más el bloque de metodología — los ISPs suelen aceptar esto como evidencia, sobre todo si está correlacionado con timestamps de una reclamación aparte."
"useCaseTitle": "Caso de uso: asistencia de tu proveedor de Internet",
"useCaseBody": "Ejecuta dos minutos de prueba contra Cloudflare cuando notes lentitud, usa <em>Repetir prueba</em> para ampliar el registro y selecciona <em>Informe</em>. El PDF incluye todas las muestras y la metodología. Puedes adjuntarlo a una solicitud de asistencia con las horas de la incidencia; tu proveedor decide qué pruebas necesita."
},
"excluding": {
"heading": "Excluir interfaces ruidosas",
"body1": "Igual que los almacenamientos, las interfaces individuales se pueden excluir de la monitorización de salud — útil para bridges deshabilitados a propósito, interfaces de test o NICs físicamente retiradas pero que siguen en la configuración. El flag se guarda en la tabla <code>excluded_interfaces</code> y lo respeta el ciclo del Monitor de salud: sin warnings, sin notificaciones, sin contribución a la pastilla de estado de la cabecera.",
"body2": "Desde el menú contextual de la fila, elige <em>Exclude from monitoring</em>. La interfaz sigue visible en el panel con una insignia morada <strong>excluded</strong>, y puedes reactivar la monitorización desde el mismo menú."
"heading": "Excluir interfaces de la supervisión",
"body1": "Puedes excluir interfaces de la supervisión, por ejemplo puentes desactivados a propósito, interfaces de prueba o NIC retiradas que siguen en la configuración. El ajuste se guarda en <code>excluded_interfaces</code>: Health Monitor no genera avisos ni notificaciones ni incluye esas interfaces en el indicador general.",
"body2": "En el menú contextual de la fila, elige <em>Excluir de la supervisión</em>. La interfaz sigue visible con una etiqueta morada <strong>excluida</strong>. Puedes reactivar la supervisión desde el mismo menú."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -192,31 +192,31 @@
{
"section": "Inventario de interfaces",
"endpoint": "/api/network",
"source": "<code>ip -j addr</code> + <code>ip -j link</code> + introspección de bond / bridge."
"source": "<code>ip -j addr</code> + <code>ip -j link</code> y consulta de bonds y puentes."
},
{
"section": "Tarjetas resumen",
"endpoint": "/api/network/summary",
"source": "Agregación sobre el inventario más recuentos up/down por interfaz."
"source": "Resumen del inventario y recuento de interfaces activas e inactivas."
},
{
"section": "Serie temporal RX/TX por interfaz",
"endpoint": "/api/network/<iface>/metrics",
"source": "<code>/proc/net/dev</code> muestreado por el Monitor de salud con cálculo de byte-rate."
"source": "Los contadores actuales usan <code>/proc/net/dev</code>; el historial del gráfico procede de RRD Proxmox mediante pvesh. Las interfaces VM/LXC usan datos del invitado; las físicas y los puentes, datos del nodo."
},
{
"section": "Latencia: actual",
"endpoint": "/api/network/latency/current",
"source": "Una ráfaga corta de <code>ping</code> contra el gateway / destino configurado."
"source": "Serie corta de <code>ping</code> a la puerta de enlace o al destino configurado."
},
{
"section": "Latencia: histórica",
"endpoint": "/api/network/latency/history",
"source": "Muestras persistidas — cada 5 min por el ciclo del Monitor de salud."
"source": "Muestras guardadas aproximadamente cada 60 segundos por el recolector de temperatura y latencia en segundo plano."
}
],
"codeComment1": "# Cross-check del estado de interfaz que ve el panel",
"codeComment2": "# Verificar una sonda de latencia actual de extremo a extremo"
"codeComment1": "# Contrastar el estado de las interfaces que muestra el panel",
"codeComment2": "# Comprobar una medición actual de latencia de extremo a extremo"
},
"whereNext": {
"heading": "Por dónde seguir",
@@ -224,17 +224,17 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la categoría Red y los umbrales del historial de latencia."
"tail": " — categoría Red y umbrales del historial de latencia."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints de red y latencia."
"tail": " — endpoints de red y latencia."
},
{
"label": "Integraciones",
"href": "/docs/monitor/integrations",
"tail": " — el scrape de Prometheus expone las mismas métricas de red."
"tail": " — la recopilación de Prometheus ofrece las mismas métricas de red."
},
{
"label": "Índice del panel",
@@ -1,174 +1,174 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Seguridad | ProxMenux Documentation",
"description": "La pestaña Seguridad agrupa cada control relacionado con protección en dos columnas: ProxMenux Monitor (Autenticación, SSL/HTTPS, tokens API, Secure Gateway) y Proxmox VE (Firewall, Fail2Ban, auditoría Lynis). Asistente paso a paso de Secure Gateway, recorrido de auditoría Lynis, instalación de Fail2Ban y ajuste de reglas."
"title": "ProxMenux Monitor — Panel: pestaña Seguridad | Documentación de ProxMenux",
"description": "La pestaña Seguridad reúne los controles de protección en dos columnas: ProxMenux Monitor (autenticación, SSL/HTTPS, tokens de API y Secure Gateway) y Proxmox VE (cortafuegos, Fail2Ban y auditoría de Lynis). Incluye el asistente de Secure Gateway, la auditoría de Lynis y la instalación y el ajuste de reglas de Fail2Ban."
},
"header": {
"title": "Panel: pestaña Seguridad",
"description": "Cada control de seguridad del panel, agrupado en dos bloques claramente etiquetados: configuración del propio Monitor (auth, SSL, tokens, Secure Gateway) y configuración del host Proxmox al que vigila (firewall, Fail2Ban, Lynis).",
"description": "Los controles de seguridad del panel se agrupan en dos bloques: la configuración del propio Monitor (autenticación, SSL, tokens y Secure Gateway) y la del host Proxmox que supervisa (cortafuegos, Fail2Ban y Lynis).",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "Dos ámbitos, una pestaña",
"body": "La pestaña Seguridad está dividida en dos secciones claramente separadas: <strong>ProxMenux Monitor</strong> (settings para el propio panel) y <strong>Proxmox VE</strong> (settings para el host de debajo). Las tarjetas se renderizan de forma condicional — Fail2Ban y Lynis solo aparecen una vez instalados."
"body": "La pestaña Seguridad tiene dos secciones: <strong>ProxMenux Monitor</strong> (ajustes del panel) y <strong>Proxmox VE</strong> (ajustes del host). Las tarjetas de Fail2Ban y Lynis ofrecen instalar estas herramientas si faltan y muestran sus controles una vez instaladas."
},
"monitor": {
"heading": "ProxMenux Monitor",
"intro": "Cuatro tarjetas controlan cómo se alcanza y autentica el propio panel."
"intro": "Cuatro tarjetas permiten configurar el acceso al panel y su autenticación."
},
"auth": {
"heading": "Autenticación",
"imageAlt": "Tarjeta Authentication mostrando estado Enabled, Logout, Change Password, info de Two-Factor Authentication, botones Enable Two-Factor Authentication y Disable Authentication",
"imageCaption": "Tarjeta Authentication con auth activa — insignia de estado, Change Password, Enable 2FA y la acción (destructiva) Disable Authentication.",
"intro": "La tarjeta te permite gestionar el login del propio panel. El flujo completo de primer arranque, política de contraseñas, pantallas de alta de TOTP y recuperación de authenticator perdido están documentados en <link>Acceso y autenticación</link> — esta tarjeta es la superficie del día a día para esos settings:",
"imageAlt": "Tarjeta de autenticación con estado Activada, botones Cerrar sesión y Cambiar contraseña, información sobre la autenticación de dos factores y botones para activarla o desactivar la autenticación",
"imageCaption": "Tarjeta con la autenticación activada: indicador de estado, Cambiar contraseña, Activar 2FA y la acción destructiva Desactivar autenticación.",
"intro": "La tarjeta permite gestionar el inicio de sesión del panel. El primer inicio, la política de contraseñas, el alta de TOTP y la recuperación por pérdida del autenticador se explican en <link>Acceso y autenticación</link>. Esta tarjeta permite gestionar esos ajustes a diario:",
"items": [
"<strong>Authentication Status</strong> — insignia mostrando <em>Enabled</em> / <em>Disabled</em> / <em>Declined</em>.",
"<strong>Change Password</strong> — contraseña actual + nueva contraseña + confirmación.",
"<strong>Enable / Disable Two-Factor Authentication</strong> — abre el diálogo de alta con QR al activar, pide la contraseña actual al desactivar.",
"<strong>Disable Authentication</strong> — acción destructiva que vuelve a mostrar el diálogo de primer arranque <em>Protect your dashboard?</em> en la siguiente visita."
"<strong>Estado de autenticación</strong>: indicador con <em>Activada</em> / <em>Desactivada</em> / <em>Rechazada</em>.",
"<strong>Cambiar contraseña</strong>: contraseña actual + nueva contraseña + confirmación.",
"<strong>Activar / Desactivar autenticación de dos factores</strong>: al activarla, abre el diálogo de registro con QR; al desactivarla, solicita la contraseña actual.",
"<strong>Desactivar autenticación</strong>: acción destructiva que vuelve a mostrar el diálogo inicial <em>¿Proteger tu panel?</em> en la siguiente visita."
]
},
"ssl": {
"heading": "SSL / HTTPS",
"imageAlt": "Tarjeta SSL / HTTPS mostrando estado HTTP No SSL, certificado del host Proxmox detectado con Subject, Issuer, Expires, botón Use Proxmox Certificate y opción Use Custom Certificate",
"imageCaption": "Tarjeta SSL / HTTPS con HTTPS apagado. El Monitor detecta el certificado ya instalado en el host Proxmox y lo ofrece como opción de un solo clic, con un fallback a <em>Use Custom Certificate</em> si tienes tus propios archivos en otro sitio.",
"intro": "Sirve el panel sobre HTTPS sin ningún reverse proxy por delante. La tarjeta auto-detecta el certificado que usa el propio Proxmox (bajo <code>/etc/pve/local/</code>) y muestra el subject, issuer y expiración para que lo puedas verificar antes de activar. Dos rutas para activar HTTPS:",
"heading": "SSL/HTTPS",
"imageAlt": "Tarjeta SSL/HTTPS con estado HTTP sin SSL, certificado del host Proxmox detectado con sujeto, emisor y caducidad, botón Usar certificado de Proxmox y opción Usar certificado personalizado",
"imageCaption": "Tarjeta SSL/HTTPS con HTTPS desactivado. Monitor detecta el certificado instalado en el host Proxmox y permite usarlo con un clic. Si tienes otros archivos, puedes elegir <em>Usar certificado personalizado</em>.",
"intro": "Permite servir el panel por HTTPS sin un proxy inverso. La tarjeta detecta el certificado usado por Proxmox en <code>/etc/pve/local/</code> y muestra su sujeto, emisor y caducidad para verificarlo antes de activarlo. Hay dos formas de activar HTTPS:",
"items": [
"<strong>Use Proxmox Certificate</strong> — un clic. El Monitor reutiliza el certificado instalado en el host. Buena opción para usuarios que ya tienen su PVE corriendo en el mismo nombre DNS que el panel.",
"<strong>Use Custom Certificate</strong> — pega rutas absolutas a tus propios archivos <code>.pem</code> de certificado y <code>.key</code> de clave privada. Las rutas se validan antes de reiniciar el servicio; si la carga falla, el panel cae a HTTP automáticamente (sin estado roto)."
"<strong>Usar certificado de Proxmox</strong>: con un clic, Monitor reutiliza el certificado del host. Es adecuado si PVE y el panel ya usan el mismo nombre DNS.",
"<strong>Usar certificado personalizado</strong>: pega las rutas absolutas de tu certificado <code>.pem</code> y clave privada <code>.key</code>. Se validan antes de reiniciar el servicio. Si no pueden cargarse, el panel vuelve automáticamente a HTTP y permanece accesible."
],
"enabledAlt": "Tarjeta SSL/HTTPS con estado HTTPS Enabled, Active Certificate mostrando rutas pve-ssl.pem y pve-ssl.key, y un botón Disable HTTPS",
"enabledCaption": "HTTPS activo — la tarjeta expone el certificado actualmente en uso, las rutas de archivos y una acción <em>Disable HTTPS</em> que vuelve a HTTP en el mismo puerto.",
"enabledAlt": "Tarjeta SSL/HTTPS con HTTPS activado, certificado activo con las rutas de pve-ssl.pem y pve-ssl.key y botón Desactivar HTTPS",
"enabledCaption": "HTTPS activo: la tarjeta muestra el certificado en uso, sus rutas y la acción <em>Desactivar HTTPS</em>, que vuelve a HTTP en el mismo puerto.",
"acmeTitle": "ACME / Let's Encrypt vía Proxmox",
"acmeBody": "Si tu nodo Proxmox ya tiene Let's Encrypt configurado en <em>Datacenter → Certificates → ACME</em>, ese es el certificado que el host sirve a los navegadores — y eso es lo que el panel reutiliza al pulsar <em>Use Proxmox Certificate</em>. No necesitas fontanería ACME separada para el Monitor.",
"walkthroughLink": "Para un recorrido paso a paso — incluyendo cómo el Monitor auto-detecta el certificado subido por ACME, qué se escribe a disco y cómo caer a un par <code>.pem</code> / <code>.key</code> custom — mira <link>HTTPS para ProxMenux Monitor</link>."
"acmeBody": "Si tu nodo Proxmox ya tiene Let’s Encrypt configurado en <em>Datacenter → Certificates → ACME</em>, el panel reutiliza ese mismo certificado al pulsar <em>Usar certificado de Proxmox</em>. No necesitas configurar ACME por separado para Monitor.",
"walkthroughLink": "Consulta <link>HTTPS para ProxMenux Monitor</link> para ver paso a paso cómo se detecta el certificado de ACME, qué se guarda en disco y cómo usar un par <code>.pem</code> / <code>.key</code> propio."
},
"apiTokens": {
"heading": "Tokens de acceso API",
"emptyAlt": "Tarjeta API Access Tokens en estado vacío con caja info About API Tokens y botón Generate New API Token",
"emptyCaption": "Tarjeta API Access Tokens en una instalación recién hecha — la caja <em>About API Tokens</em> resume lifetime, uso y cómo embeber el token en cabeceras <code>Authorization: Bearer</code>.",
"intro": "Tokens de vida larga (1 año) para integraciones desatendidas — widgets Homepage, sensores REST de Home Assistant, scrapers de Grafana, flujos n8n, scripts propios. La tarjeta te lleva por tres estados: vacío → formulario → generado.",
"generateBody": "<strong>Generar un token.</strong> Pulsa <em>Generate New API Token</em>. El formulario pide un <em>Token Name</em> descriptivo (ayuda a identificarlo después en la lista activa) y tu <em>contraseña</em> como confirmación de segundo factor. Si 2FA está activo, el formulario pide adicionalmente el código TOTP actual.",
"generateAlt": "Formulario API Access Tokens generate con input Token Name, input Password, botones Generate Token y Cancel",
"generateCaption": "El formulario Generate API Token — rellena un nombre y confirma con tu contraseña (y TOTP si 2FA está activo).",
"saveBody": "<strong>Guarda el token inmediatamente.</strong> La cadena completa del token se muestra <strong>solo una vez</strong> tras generarlo. La tarjeta lo destaca con un aviso ámbar y un botón de copia. No hay forma de recuperarlo después — solo verás el prefix en la lista Active Tokens.",
"generatedAlt": "Token API generado correctamente con token enmascarado, botón de copia, instrucciones para cabecera Authorization Bearer y lista Active Tokens con prefix",
"generatedCaption": "Token generado — el valor se muestra una vez con un botón de copia y el snippet exacto <code>Authorization: Bearer</code>. Debajo, la lista Active Tokens mantiene nombre + prefix + fecha de creación para que puedas revocar tokens individuales después.",
"outro": "La tarjeta muestra cada token activo con un botón <em>Revoke</em> por fila. Revocar invalida el token inmediatamente; cualquier integración que lo use deja de funcionar desde ese momento. Los cookbooks para Homepage, Home Assistant, n8n y Prometheus están en <link>Integraciones</link>."
"emptyAlt": "Tarjeta de tokens de acceso a la API vacía, con información sobre los tokens y botón Generar nuevo token de API",
"emptyCaption": "Tarjeta de tokens en una instalación nueva. El cuadro <em>Acerca de los tokens de API</em> resume su duración, uso y cómo incluirlos en cabeceras <code>Authorization: Bearer</code>.",
"intro": "Tokens con un año de validez para integraciones desatendidas: widgets de Homepage, sensores REST de Home Assistant, recolectores de Grafana, flujos de n8n y scripts propios. La tarjeta pasa por tres estados: vacío → formulario → generado.",
"generateBody": "<strong>Generar un token.</strong> Pulsa <em>Generar nuevo token de API</em>. Introduce un <em>nombre del token</em> descriptivo para identificarlo después y tu <em>contraseña</em> como confirmación adicional. Si 2FA está activo, también solicita el código TOTP actual.",
"generateAlt": "Formulario de generación de tokens de API con campos Nombre del token y Contraseña y botones Generar token y Cancelar",
"generateCaption": "Formulario Generar token de API: introduce un nombre y confirma con tu contraseña y, si 2FA está activo, el código TOTP.",
"saveBody": "<strong>Guarda el token inmediatamente.</strong> Su valor completo se muestra <strong>solo una vez</strong> tras generarlo. La tarjeta lo señala con un aviso naranja y un botón de copia. No podrás recuperarlo después; la lista de tokens activos solo mostrará su prefijo.",
"generatedAlt": "Token de API generado, con valor oculto, botón de copia, instrucciones para la cabecera Authorization: Bearer y lista de tokens activos con sus prefijos",
"generatedCaption": "Token generado: el valor se muestra una vez, con botón de copia y el fragmento exacto <code>Authorization: Bearer</code>. Debajo, la lista de tokens activos muestra nombre, prefijo y fecha de creación para revocarlos individualmente.",
"outro": "Cada token activo tiene un botón <em>Revocar</em>. La revocación lo invalida inmediatamente y las integraciones que lo usen dejan de funcionar. Encontrarás ejemplos para Homepage, Home Assistant, n8n y Prometheus en <link>Integraciones</link>."
},
"gateway": {
"heading": "Secure Gateway",
"cardAlt": "Tarjeta Secure Gateway con botón Deploy Secure Gateway antes de que se haya desplegado ningún gateway",
"cardCaption": "Tarjeta Secure Gateway en setup recién hecho — un botón arranca el asistente.",
"intro": "Alcanza el panel, la UI web de Proxmox y cualquier guest desde cualquier sitio en tu tailnet de <a>Tailscale</a>, sin exponer ningún puerto a la internet pública. El Monitor despliega un contenedor LXC Alpine en el host corriendo <code>tailscaled</code> como subnet router; una vez aprobado en la consola de admin de Tailscale, tus dispositivos remotos alcanzan la IP de LAN del host desde cualquier sitio.",
"cardAlt": "Tarjeta Secure Gateway con el botón Desplegar Secure Gateway antes de desplegar la primera pasarela",
"cardCaption": "Tarjeta Secure Gateway en una instalación nueva: un botón inicia el asistente.",
"intro": "Accede al panel, a la interfaz web de Proxmox y a cualquier máquina invitada desde tu red <a>Tailscale</a>, sin exponer puertos a Internet. Monitor despliega en el host un contenedor LXC Alpine con <code>tailscaled</code> como router de subred. Tras aprobarlo en la consola de administración de Tailscale, los dispositivos remotos pueden acceder a la IP LAN del host desde cualquier lugar.",
"wizardTitle": "Asistente paso a paso",
"wizardIntro": "Antes de pulsar <em>Deploy Secure Gateway</em>, genera una auth key en tu consola de admin de Tailscale — el asistente la pedirá en el paso 2.",
"step0Title": "0. Generar la auth key de Tailscale",
"step0Body": "Entra en <a>login.tailscale.com/admin/settings/keys</a> y pulsa <em>Generate auth key…</em>. Elige una key <em>pre-autenticada</em> (para que el gateway no necesite un login interactivo de Tailscale) y copia el valor — se muestra solo una vez.",
"step0Alt": "Consola de admin de Tailscale, página Settings Keys con el botón Generate auth key resaltado",
"wizardIntro": "Antes de pulsar <em>Deploy Secure Gateway</em>, genera una clave de autenticación en la consola de Tailscale. El asistente la pedirá en el paso 2.",
"step0Title": "0. Generar la clave de autenticación de Tailscale",
"step0Body": "Entra en <a>login.tailscale.com/admin/settings/keys</a> y pulsa <em>Generate auth key…</em>. Elige una clave <em>preautenticada</em> para que la pasarela no necesite un inicio de sesión interactivo. Copia el valor: solo se muestra una vez.",
"step0Alt": "Página Settings → Keys de la consola de administración de Tailscale, con el botón Generate auth key resaltado",
"step0Caption": "Consola de admin de Tailscale — <em>Settings → Keys → Generate auth key…</em>. Usa una cuenta gratuita de Tailscale si aún no tienes (link dentro del asistente).",
"step1Title": "1. Abrir el asistente",
"step1Body": "De vuelta en la pestaña Seguridad, pulsa <em>Deploy Secure Gateway</em>. El primer paso es una intro con lo que vas a obtener y lo que necesitas.",
"step1Alt": "Paso intro del asistente Secure Gateway Setup explicando qué provee el gateway: acceso VPN, sin port forwarding, cifrado de extremo a extremo",
"step1Body": "Vuelve a la pestaña Seguridad y pulsa <em>Deploy Secure Gateway</em>. El primer paso presenta sus funciones y requisitos.",
"step1Alt": "Introducción del asistente Secure Gateway con acceso VPN, sin redirección de puertos y con cifrado de extremo a extremo",
"step1Caption": "Paso 1 — resumen de lo que provee el Secure Gateway y recordatorio de que necesitarás una cuenta gratuita de Tailscale.",
"step2Title": "2. Tailscale Authentication",
"step2Body": "Pega la auth key del paso 0 y elige un hostname (así es como aparecerá el gateway en la consola de admin de Tailscale — típicamente <code>proxmox-gateway</code> o el nombre de tu nodo).",
"step2Alt": "Paso del asistente Secure Gateway pidiendo Tailscale Auth Key y Device Hostname con link para generar la key",
"step2Caption": "Paso 2 — pega la pre-auth key y elige el hostname del dispositivo. El link debajo del campo abre la página de Tailscale del paso 0 si te lo saltaste.",
"step3Title": "3. Access Scope",
"step2Title": "2. Autenticación de Tailscale",
"step2Body": "Pega la clave de autenticación del paso 0 y elige un nombre de host. Será el nombre de la pasarela en la consola de Tailscale, normalmente <code>proxmox-gateway</code> o el nombre de tu nodo.",
"step2Alt": "Paso del asistente Secure Gateway que solicita la clave de autenticación de Tailscale y el nombre de host del dispositivo, con enlace para generar la clave",
"step2Caption": "Paso 2: pega la clave preautenticada y elige el nombre de host. Si omitiste el paso 0, el enlace bajo el campo abre la página de Tailscale correspondiente.",
"step3Title": "3. Alcance de acceso",
"step3Intro": "Elige a qué puede llegar tu tailnet a través del gateway:",
"step3Items": [
"<strong>Proxmox Only</strong> — solo la UI de Proxmox y el Monitor. La menor superficie de ataque.",
"<strong>Full Local Network</strong> — la subred LAN entera (auto-detectada desde la interfaz primaria del host). Te permite alcanzar NAS, impresoras, VMs y cualquier otro dispositivo de la LAN.",
"<strong>Custom Subnets</strong> — lista CIDRs específicos. Para setups multi-VLAN donde quieres exponer algunos segmentos pero no otros."
"<strong>Subredes personalizadas</strong>: indica los CIDR concretos. Permite dar acceso solo a determinados segmentos en instalaciones con varias VLAN."
],
"step3Alt": "Paso Access Scope del asistente Secure Gateway con tres opciones: Proxmox Only, Full Local Network, Custom Subnets",
"step3Caption": "Paso 3 — elige el access scope. <em>Full Local Network</em> se autorrellena con la subred LAN detectada.",
"step4Title": "4. Advanced Options (opcional)",
"step4Intro": "Dos toggles opcionales. Ambos <strong>off por defecto</strong>:",
"step3Alt": "Paso Ámbito de acceso del asistente Secure Gateway, con las opciones Solo Proxmox, Toda la red local y Subredes personalizadas",
"step3Caption": "Paso 3: elige el ámbito de acceso. <em>Toda la red local</em> rellena automáticamente la subred LAN detectada.",
"step4Title": "4. Opciones avanzadas (opcional)",
"step4Intro": "Dos interruptores opcionales, ambos <strong>desactivados por defecto</strong>:",
"step4Items": [
"<strong>Exit Node</strong> — cuando se activa y se selecciona desde un dispositivo remoto, todo el tráfico de internet de ese dispositivo sale por la WAN del host Proxmox. Útil para escenarios de viaje donde quieres que el tráfico de tu móvil parezca de casa.",
"<strong>Accept Routes</strong> — deja que este gateway alcance redes anunciadas por <em>otros</em> subnet routers del tailnet (para setups multi-sitio)."
"<strong>Exit Node</strong>: al activarlo y seleccionarlo desde un dispositivo remoto, todo el tráfico de Internet de ese dispositivo sale por la WAN del host Proxmox. Es útil al viajar para que el tráfico del móvil salga por tu conexión de casa.",
"<strong>Aceptar rutas</strong>: permite que esta pasarela acceda a redes anunciadas por <em>otros</em> routers de subred de la red Tailscale, para instalaciones en varias ubicaciones."
],
"step4Alt": "Paso Advanced Options del asistente Secure Gateway con checkboxes Exit Node y Accept Routes",
"step4Caption": "Paso 4 — Exit Node y Accept Routes. Salta ambos si lo único que quieres es acceso al panel desde tu móvil o portátil.",
"step5Title": "5. Review & Deploy",
"step5Body": "Resumen final antes de que arranque el deploy. El asistente te recuerda que aún queda un paso manual en el admin de Tailscale tras desplegar: <strong>aprobar la subnet route</strong>.",
"step5Alt": "Paso Review and Deploy del asistente Secure Gateway con Configuration Summary mostrando hostname, access mode, networks, exit node, accept routes y un botón Deploy Gateway",
"step4Alt": "Paso Opciones avanzadas de Secure Gateway con las casillas Exit Node y Accept Routes",
"step4Caption": "Paso 4: Exit Node y Accept Routes. Deja ambas opciones desactivadas si solo necesitas acceder al panel desde el móvil o el portátil.",
"step5Title": "5. Revisar y desplegar",
"step5Body": "Resumen final antes del despliegue. El asistente recuerda que después queda un paso manual en la consola de Tailscale: <strong>aprobar la ruta de subred</strong>.",
"step5Alt": "Paso Revisar y desplegar de Secure Gateway, con el resumen del nombre de host, modo de acceso, redes, Exit Node y Accept Routes y el botón Desplegar pasarela",
"step5Caption": "Paso 5 — revisa la configuración y despliega. El aviso azul al pie señala la aprobación de ruta pendiente.",
"approvalTitle": "Un último paso manual en el admin de Tailscale",
"approvalBody": "Tras desplegar, vuelve a <a>login.tailscale.com/admin/machines</a> y aprueba la subnet route que el gateway está anunciando. Hasta que lo hagas, los dispositivos remotos de tu tailnet no podrán alcanzar realmente IPs de LAN a través del gateway. Tailscale marca las rutas pendientes con un aviso amarillo en la fila del dispositivo — pulsa <em>Edit route settings</em> y marca la casilla de la ruta."
"approvalBody": "Tras el despliegue, vuelve a <a>login.tailscale.com/admin/machines</a> y aprueba la ruta de subred anunciada por la pasarela. Hasta entonces, los dispositivos remotos de tu red Tailscale no podrán acceder a las IP LAN a través de ella. Las rutas pendientes aparecen con un aviso amarillo en la fila del dispositivo: pulsa <em>Edit route settings</em> y marca la casilla de la ruta."
},
"pve": {
"heading": "Proxmox VE",
"intro": "Las protecciones del propio host — firewall, prevención de intrusiones y auditoría de seguridad. Los dos últimos solo se renderizan cuando sus herramientas respectivas están instaladas."
"intro": "Las protecciones del host: cortafuegos, prevención de intrusiones y auditoría de seguridad. Las tarjetas de Fail2Ban y Lynis ofrecen instalarlos si faltan y después muestran sus controles de gestión."
},
"firewall": {
"heading": "Proxmox Firewall",
"imageAlt": "Tarjeta Proxmox Firewall mostrando estado de Cluster Firewall y Host Firewall, Quick Access Rules para ProxMenux Monitor y Proxmox Web UI, contadores Rules Overview y una lista de Firewall Rules con botón Add Rule",
"imageCaption": "Tarjeta Proxmox Firewall — toggles enable / disable a nivel cluster y host, puertos comunes como <em>Quick Access Rules</em>, totales en <em>Rules Overview</em> y la lista completa de reglas con <em>+ Add Rule</em>.",
"intro": "La tarjeta expone el firewall integrado de Proxmox VE (que es independiente de cualquier <code>iptables</code> / <code>nftables</code> a nivel host que puedas correr en paralelo). Tres bloques:",
"imageAlt": "Tarjeta del cortafuegos Proxmox con estado del clúster y del host, reglas de acceso rápido para Monitor y la interfaz web Proxmox, contadores, lista de reglas y botón Añadir regla",
"imageCaption": "Tarjeta del cortafuegos Proxmox: interruptores para el clúster y el host, puertos comunes en <em>Reglas de acceso rápido</em>, contadores en <em>Resumen de reglas</em> y lista completa con <em>+ Añadir regla</em>.",
"intro": "La tarjeta gestiona la configuración del cortafuegos de Proxmox VE. El backend clásico usa <code>iptables</code> y el alternativo usa <code>nftables</code>. No gestiona reglas arbitrarias creadas fuera de Proxmox. Tres bloques:",
"items": [
"<strong>Cluster Firewall + Host Firewall</strong> — toggles globales. El cluster firewall debe estar activo para que cualquier regla a nivel host surta efecto; la tarjeta señala esta dependencia inline.",
"<strong>Quick Access Rules</strong> — filas predefinidas para puertos que importan al propio ProxMenux: <code>8008/TCP</code> (Monitor), <code>8006/TCP</code> (UI web de Proxmox). Cada fila muestra el estado actual allow / deny / unprotected. La UI web de Proxmox se permite vía el macro de firewall <em>integrado</em> de Proxmox y no se puede eliminar por accidente.",
"<strong>Rules Overview</strong> — contadores de reglas totales, reglas accept, reglas drop / reject y puertos distintos protegidos. Los números se leen de <code>/etc/pve/firewall/cluster.fw</code> y <code>/etc/pve/nodes/&lt;node&gt;/host.fw</code>.",
"<strong>Firewall Rules</strong> — lista completa con action / protocolo / puerto / source / level. <em>+ Add Rule</em> abre un editor inline; el icono de papelera en cada fila elimina la regla. Las ediciones escriben a los mismos archivos que usa Proxmox, así que los cambios también aparecen en la UI de Proxmox (Datacenter / Node → Firewall)."
"<strong>Cortafuegos del clúster + cortafuegos del host</strong>: interruptores globales. El del clúster debe estar activado para que se apliquen las reglas del host. La tarjeta indica esta dependencia junto al ajuste.",
"<strong>Reglas de acceso rápido</strong>: filas predefinidas para <code>8008/TCP</code> (Monitor) y <code>8006/TCP</code> (interfaz web Proxmox), con estado permitido, bloqueado o sin protección. La interfaz de Proxmox se permite mediante su macro de cortafuegos <em>integrada</em>, que no puede eliminarse por accidente.",
"<strong>Resumen de reglas</strong>: contadores del total de reglas, reglas accept, reglas drop/reject y puertos distintos protegidos. Los datos se leen de <code>/etc/pve/firewall/cluster.fw</code> y <code>/etc/pve/nodes/&lt;node&gt;/host.fw</code>.",
"<strong>Reglas del cortafuegos</strong>: lista con acción, protocolo, puerto, origen y nivel. <em>+ Añadir regla</em> abre el editor en la tarjeta; la papelera elimina la regla. Los cambios se guardan en los archivos de Proxmox y también aparecen en su interfaz (Datacenter / Node → Firewall)."
]
},
"fail2ban": {
"heading": "Fail2Ban",
"subHeading": "(condicional)",
"whatIs": "<strong>Qué es.</strong> Fail2Ban es un daemon open-source de prevención de intrusiones que vigila archivos de log buscando intentos repetidos fallidos de login y banea la IP ofensora a nivel de firewall. Es la respuesta de facto a los escáneres de fuerza bruta que pegan SSH y formularios de login web 24/7. ProxMenux lo conecta a tres jails por defecto: SSH, el login de la UI web de Proxmox (puerto 8006) y el login del ProxMenux Monitor (puerto 8008).",
"notBundled": "Fail2Ban <strong>no viene de fábrica</strong>. La tarjeta detecta si está instalado y se adapta: cuando falta ofrece una instalación de un clic; una vez instalado muestra estado en vivo de jails, IPs baneadas y te deja ajustar retries / ban time por jail.",
"notInstalledAlt": "Tarjeta Fail2Ban mostrando estado Not Installed con explicación de lo que configuraría: SSH, UI web de Proxmox y protección de ProxMenux Monitor con backend nftables, más un botón Install and Configure Fail2Ban",
"subHeading": "(según el estado)",
"whatIs": "<strong>Qué es.</strong> Fail2Ban es un servicio de código abierto que detecta intentos de inicio de sesión fallidos repetidos en los registros y bloquea la IP en el cortafuegos. Protege frente a ataques de fuerza bruta continuos contra SSH y los formularios web. ProxMenux configura tres jails: SSH, acceso web de Proxmox (puerto 8006) y acceso de ProxMenux Monitor (puerto 8008).",
"notBundled": "Fail2Ban <strong>no viene incluido</strong>. La tarjeta detecta si está instalado y adapta su contenido: si falta, ofrece instalarlo con un clic; una vez instalado, muestra el estado de las jails y las IP bloqueadas, y permite ajustar los reintentos y el tiempo de bloqueo de cada jail.",
"notInstalledAlt": "Tarjeta Fail2Ban sin instalar, con descripción de la protección de SSH, la interfaz web Proxmox y Monitor mediante nftables y botón Instalar y configurar Fail2Ban",
"notInstalledCaption": "Tarjeta Fail2Ban antes de instalar — la caja azul previsualiza lo que configuraría la instalación.",
"clickBody": "Pulsa <em>Install and Configure Fail2Ban</em> y obtienes una modal de confirmación listando cada cambio que hará el script en el host:",
"confirmAlt": "Modal de confirmación Install Fail2Ban listando protección SSH modo agresivo, protección de interfaz web Proxmox puerto 8006, protección ProxMenux Monitor puerto 8008, backend nftables auto-detectado, ajuste del log level de journald y hardening de SSH MaxAuthTries",
"confirmCaption": "Confirmación de instalación — lista explícita de jails, ajustes al log level de journald (para que el jail de auth pueda leer eventos SSH) y un efecto colateral de hardening SSH (<code>MaxAuthTries=3</code>).",
"confirmIntro": "La confirmación dispara un panel de instalación en streaming (apt + config de jails + tests). La misma fontanería que el instalador CLI de ProxMenux.",
"progressAlt": "Panel Fail2Ban Installation mostrando log de instalación en vivo: instalación del paquete, journald MaxLevelStore ajustado para logging de auth, jails configurados, backend nftables detectado, hardening MaxAuthTries, test de comunicación fail2ban-client, mensaje de finalización",
"progressCaption": "Instalación en curso — cada paso se loguea en el panel. Connection-closed al final marca el fin de la sesión de streaming.",
"afterInstall": "Tras instalar la tarjeta pasa a la vista de estado en vivo: jails configurados, contador de IPs baneadas, eventos recientes de ban. Las pestañas grandes separan <em>Jails & Banned IPs</em> de <em>Recent Activity</em> (las últimas N entradas del log de Fail2Ban).",
"activeAlt": "Tarjeta Fail2Ban tras instalar con estado Active, tres jails configurados (proxmenux, proxmox, sshd), contador Banned IPs, Total Bans, Failed Attempts, y filas por jail con retries, ban time, window e icono de rueda dentada",
"activeCaption": "Fail2Ban activo — los tres jails por defecto (<code>proxmenux</code>, <code>proxmox</code>, <code>sshd</code>) con sus settings de retries / ban time / window.",
"tuneBody": "<strong>Ajustar reglas del jail.</strong> Pulsa el icono de rueda dentada en cualquier fila de jail para ajustar <em>Max Retries</em>, <em>Ban Time</em> (usa ban permanente si quieres que los ofensores queden bloqueados hasta que tú los desbanees manualmente) y <em>Find Time</em> (la ventana deslizante para contar retries). Los valores comunes están documentados dentro del formulario.",
"configAlt": "Formulario Configure jail sshd con Max Retries, Ban Time en segundos con opción Permanent Ban, Find Time, recordatorio de valores comunes y botón Save Configuration",
"configCaption": "Editando el jail sshd — elige un <em>Max Retries</em> más estricto para SSH si solo te logueas desde tu propia subred, o extiende el <em>Ban Time</em> para el panel de cara al público.",
"outro": "El recorrido completo <em>Qué instala / cómo se configura / cómo desinstalar</em> — incluyendo la ruta de instalación manual, el efecto colateral de SSH MaxAuthTries y la relación con el journal <code>proxmenux-auth.log</code> — está en <link>ProxMenux → Seguridad → Fail2Ban</link>.",
"calloutTitle": "Sin Fail2Ban, la protección contra fuerza bruta es best-effort",
"calloutBody": "ProxMenux Monitor tiene su propio hook de ban a <em>nivel de aplicación</em> en el pipeline de peticiones de Flask — pero solo surte efecto si Fail2Ban está instalado y escribe a la tabla de bans. Sin Fail2Ban, el Monitor loguea los logins fallidos a <code>proxmenux-auth.log</code> para inspección futura pero no bloquea IPs activamente."
"clickBody": "Pulsa <em>Instalar y configurar Fail2Ban</em> para abrir un diálogo de confirmación que enumera todos los cambios del script en el host:",
"confirmAlt": "Confirmación de Fail2Ban con modo agresivo para SSH, protección de Proxmox en el puerto 8006 y Monitor en el 8008, detección de nftables, ajuste de registros de journald y refuerzo de SSH MaxAuthTries",
"confirmCaption": "Confirmación de instalación: lista de jails, ajuste del nivel de registro de journald para leer eventos SSH y refuerzo adicional de SSH (<code>MaxAuthTries=3</code>).",
"confirmIntro": "Al confirmar, se abre un panel con el registro de instalación en directo: apt, configuración de jails y pruebas. Usa el mismo mecanismo que el instalador CLI de ProxMenux.",
"progressAlt": "Panel con el registro de instalación de Fail2Ban: paquete, journald MaxLevelStore para autenticación, jails, detección de nftables, refuerzo MaxAuthTries, prueba de comunicación fail2ban-client y mensaje de finalización",
"progressCaption": "Instalación en curso: el panel registra cada paso. El mensaje Connection closed al final indica que ha terminado la sesión de transmisión.",
"afterInstall": "Tras instalarse, la tarjeta muestra el estado en directo: jails configurados, IP bloqueadas y bloqueos recientes. Las pestañas separan <em>Jails e IP bloqueadas</em> de <em>Actividad reciente</em>, con las últimas N entradas del registro de Fail2Ban.",
"activeAlt": "Tarjeta Fail2Ban activa con tres jails (proxmenux, proxmox, sshd), contadores de IP bloqueadas, bloqueos totales e intentos fallidos, y filas con intentos, tiempo de bloqueo, intervalo y rueda dentada",
"activeCaption": "Fail2Ban activo: los tres jails predeterminados (<code>proxmenux</code>, <code>proxmox</code> y <code>sshd</code>) con sus ajustes de intentos, duración del bloqueo e intervalo de detección.",
"tuneBody": "<strong>Ajustar las reglas del jail.</strong> Pulsa su rueda dentada para cambiar <em>Max Retries</em>, <em>Ban Time</em> y <em>Find Time</em>, el intervalo móvil en que se cuentan los intentos. Un bloqueo permanente dura hasta que lo retires manualmente. El formulario explica los valores habituales.",
"configAlt": "Formulario del jail sshd con Max Retries, Ban Time en segundos, opción Permanent Ban, Find Time, ayuda con valores habituales y botón Guardar configuración",
"configCaption": "Edición del jail sshd: reduce <em>Max Retries</em> para SSH si solo accedes desde tu subred, o amplía <em>Ban Time</em> para el panel expuesto a Internet.",
"outro": "La guía <em>Qué instala, cómo se configura y cómo desinstalar</em> incluye la instalación manual, el cambio de SSH MaxAuthTries y la relación con el registro <code>proxmenux-auth.log</code>. Consulta <link>ProxMenux → Seguridad → Fail2Ban</link>.",
"calloutTitle": "Sin Fail2Ban, este mecanismo no bloquea las IP",
"calloutBody": "ProxMenux Monitor comprueba las IP bloqueadas en la jaula <code>proxmenux</code> de Fail2Ban a <em>nivel de aplicación</em> antes de procesar las peticiones de Flask, con el resultado en caché durante 30 segundos. Sin Fail2Ban, los intentos fallidos se registran en <code>proxmenux-auth.log</code> y el inicio de sesión se limita a 5 intentos por IP cada 5 minutos, pero no se bloquea ninguna IP."
},
"lynis": {
"heading": "Lynis Security Audit",
"subHeading": "(condicional)",
"whatIs": "<strong>Qué es.</strong> Lynis es una herramienta open-source de auditoría de seguridad que ejecuta ~280 tests en el host (permisos de archivos, hardening del kernel, config SSH, vulnerabilidades de paquetes, política de cripto, tareas programadas, banner grabbing, etc.) y produce una puntuación de hardening 0–100, una lista de warnings y una lista de sugerencias. Es la baseline de facto para \"¿este servidor está en buena forma?\" en servidores basados en Debian.",
"whyUseful": "<strong>Por qué es útil.</strong> Conocer la postura de seguridad de tu servidor es difícil de hacer leyendo archivos de config uno a uno. Lynis captura las cosas que rutinariamente se pasan por alto: flags de hardening del kernel ausentes, cifrados SSH débiles activos, journal no persistente, <code>NOPASSWD</code> en sudoers para cuentas por defecto, y muchas más. Volver a ejecutarlo tras aplicar los ajustes post-instalación de ProxMenux te da un número objetivo de la mejora.",
"notInstalledAlt": "Tarjeta Lynis Security Audit con estado Not Installed y botón Install Lynis, listando features: scoring de hardening, detección de vulnerabilidades, comprobación de compliance y fuente GitHub",
"heading": "Auditoría de seguridad de Lynis",
"subHeading": "(según el estado)",
"whatIs": "<strong>Qué es.</strong> Lynis es una herramienta de auditoría de seguridad de código abierto que realiza unas 280 pruebas del host: permisos, protección del kernel, SSH, vulnerabilidades de paquetes, política criptográfica, tareas programadas e identificación de servicios, entre otras. Genera un índice de seguridad de 0 a 100, avisos y sugerencias. Se usa como referencia para evaluar servidores basados en Debian.",
"whyUseful": "<strong>Por qué es útil.</strong> Evaluar la seguridad leyendo cada archivo de configuración resulta difícil. Lynis detecta fallos habituales: opciones de protección del kernel ausentes, cifrados SSH débiles, registros no persistentes o <code>NOPASSWD</code> en sudoers para cuentas predeterminadas. Repetir el análisis tras los ajustes de ProxMenux permite comparar la mejora con una puntuación.",
"notInstalledAlt": "Tarjeta Lynis sin instalar con botón Instalar Lynis y funciones: puntuación de seguridad, detección de vulnerabilidades, cumplimiento y código en GitHub",
"notInstalledCaption": "Tarjeta Lynis antes de instalar — la caja azul resume lo que hace la herramienta.",
"notBundled": "Lynis tampoco <strong>viene de fábrica</strong>. ProxMenux instala la última release directamente desde la fuente oficial en GitHub (no el paquete Debian, que va varias versiones menores por detrás).",
"confirmAlt": "Modal de confirmación Install Lynis listando lo que hace Lynis: scoring de hardening, detección de vulnerabilidades, análisis de configuración, comprobación de compliance, fuente desde el repositorio oficial de GitHub",
"confirmCaption": "Confirmación de instalación — explícita sobre la fuente GitHub.",
"progressAlt": "Panel en streaming Lynis Installation: instalando la última herramienta de scan, versión 3.1.6 confirmada, mensaje de instalación completada",
"progressCaption": "Instalación en curso — el mismo patrón de panel en streaming que Fail2Ban.",
"afterInstall": "Tras instalar la tarjeta muestra la versión y un historial de auditorías vacío. Pulsa <em>Run Security Audit</em> para arrancar el primer scan.",
"installedAlt": "Tarjeta Lynis Security Audit tras instalar con insignia versión 3.1.6 Installed, timestamp Last Scan, Hardening Index 0, Warnings 0, Suggestions 0, fila de audit report vacía y botón Run Security Audit",
"installedCaption": "Lynis instalado, sin auditoría todavía. La tarjeta prerrellena los tiles de métricas con ceros.",
"runningAlt": "Tarjeta Lynis Security Audit mientras la auditoría está corriendo mostrando mensaje Security audit in progress, duración estimada de 2-5 minutos y un botón Running Audit deshabilitado",
"runningCaption": "Auditoría en curso — el botón de acción muestra un spinner y la tarjeta avisa explícitamente de que el scan puede llevar 2–5 minutos.",
"finishedBody": "Cuando termina, la tarjeta pasa a la vista de resultados: hardening index, warnings, suggestions y una lista <em>Audit Reports</em> con cada scan histórico.",
"resultsAlt": "Tarjeta Lynis Security Audit con resultados: Hardening Index 71 con desglose Lynis 66 PVE 71, 3 warnings, 40 suggestions, barra de progreso Security Hardening Score Proxmox Adjusted 71 de 100 en el rango Good, lista de audit reports con descarga PDF y botón Run Security Audit",
"resultsCaption": "Resultados de auditoría — Hardening Index <strong>71/100 (Good)</strong> en una ejecución de ejemplo. La tarjeta también muestra la \"puntuación raw de Lynis\" (66) frente a la puntuación ajustada para Proxmox (71) que devuelve 11 puntos por hallazgos que el corpus de tests de Lynis marca pero que son comportamiento esperado en Proxmox VE.",
"scoreTitle": "Puntuación raw de Lynis vs puntuación ajustada para Proxmox",
"scoreIntro": "Lynis trae reglas ajustadas para Debian de propósito general. Proxmox diverge legítimamente de algunas (servicios corriendo como root por razones de cluster, tuning custom de <code>journald</code>, etc.). La tarjeta muestra ambos números para que puedas:",
"notBundled": "Lynis tampoco <strong>viene incluido</strong>. ProxMenux lo instala directamente desde el código oficial de GitHub en lugar del paquete de Debian.",
"confirmAlt": "Diálogo de confirmación de Lynis con sus funciones: puntuación de seguridad, detección de vulnerabilidades, análisis de configuración, comprobación de cumplimiento y origen en el repositorio oficial de GitHub",
"confirmCaption": "Confirmación de instalación que indica expresamente el origen en GitHub.",
"progressAlt": "Panel de instalación de Lynis en directo, con instalación de la herramienta más reciente, versión 3.1.6 confirmada y mensaje de finalización",
"progressCaption": "Instalación en curso: el panel muestra el registro en directo, igual que con Fail2Ban.",
"afterInstall": "Tras la instalación, la tarjeta muestra la versión y un historial de auditorías vacío. Pulsa <em>Ejecutar auditoría de seguridad</em> para iniciar el primer análisis.",
"installedAlt": "Tarjeta Lynis tras instalarse con versión 3.1.6, fecha del último análisis, índice de seguridad 0, avisos 0, sugerencias 0, informe vacío y botón Ejecutar auditoría de seguridad",
"installedCaption": "Lynis instalado, aún sin auditorías. Los indicadores muestran ceros inicialmente.",
"runningAlt": "Tarjeta Lynis durante la auditoría con mensaje de análisis en curso, duración estimada de 2 a 5 minutos y botón Auditoría en curso deshabilitado",
"runningCaption": "Auditoría en curso: el botón muestra un indicador de carga y la tarjeta avisa de que el análisis puede tardar de 2 a 5 minutos.",
"finishedBody": "Al terminar, la tarjeta muestra los resultados: índice de seguridad, avisos, sugerencias y la lista de <em>Informes de auditoría</em> con los análisis anteriores.",
"resultsAlt": "Tarjeta Lynis con índice 71, desglose Lynis 66 y PVE 71, 3 avisos, 40 sugerencias, puntuación ajustada a Proxmox 71 de 100 en el rango Bueno, informes con descarga PDF y botón Ejecutar auditoría de seguridad",
"resultsCaption": "Resultados de ejemplo: índice de seguridad <strong>71/100 (Bueno)</strong>. La tarjeta muestra la puntuación original de Lynis (66) y la ajustada para Proxmox (71). El ajuste depende de la puntuación original y de la proporción de hallazgos considerados normales en Proxmox VE; no suma 11 puntos fijos.",
"scoreTitle": "Puntuación original de Lynis y puntuación ajustada para Proxmox",
"scoreIntro": "Las reglas de Lynis están pensadas para Debian de uso general. Proxmox se aparta de algunas por motivos válidos, como servicios de clúster ejecutados como root o ajustes propios de <code>journald</code>. La tarjeta muestra ambas puntuaciones para:",
"scoreItems": [
"Trackear tu <em>puntuación raw de Lynis</em> igual que lo harían auditores externos.",
"Trackear la puntuación <em>ajustada para Proxmox</em> — una baseline más justa si estás comparando nodos dentro del mismo cluster."
"Seguir la evolución de la <em>puntuación original de Lynis</em>, como haría un auditor externo.",
"Seguir la puntuación <em>ajustada para Proxmox</em>, una referencia más adecuada para comparar nodos del mismo clúster."
],
"reportBody": "<strong>El informe completo.</strong> Cada fila de auditoría en la lista tiene un botón <em>PDF</em> que descarga un informe de varias páginas con el resumen ejecutivo, info del sistema, postura de seguridad, cada warning con explicación, cada sugerencia rankeada por impacto y el inventario de paquetes. Es el artefacto que adjuntarías a una revisión de seguridad.",
"reportAlt": "Primera página de ejemplo del PDF Lynis Security Audit Report mostrando resumen ejecutivo con hardening 71 de 100, contadores de warnings y suggestions, bloque de System Information con hostname, kernel, versión de Lynis, fecha del informe, resumen de postura de seguridad",
"reportCaption": "Primera página de un informe descargado — resumen ejecutivo, System Information y resumen de postura de seguridad. El informe completo continúa con warnings detallados, sugerencias y la lista de paquetes instalados. Hay un <a>PDF de ejemplo</a> adjunto como referencia.",
"reportBody": "<strong>Informe completo.</strong> El botón <em>PDF</em> de cada auditoría descarga un informe de varias páginas: resumen ejecutivo, información del sistema, estado de seguridad, avisos explicados, sugerencias ordenadas por impacto e inventario de paquetes. Puedes adjuntarlo a una revisión de seguridad.",
"reportAlt": "Primera página de ejemplo del informe PDF de Lynis con resumen ejecutivo, índice 71 de 100, contadores de avisos y sugerencias, nombre de host, kernel, versión de Lynis, fecha y resumen del estado de seguridad",
"reportCaption": "Primera página del informe descargado: resumen ejecutivo, información del sistema y estado de seguridad. Después incluye avisos detallados, sugerencias y paquetes instalados. Se adjunta un <a>PDF de ejemplo</a> como referencia.",
"runPeriodically": "Ejecuta la auditoría periódicamente (tras grandes upgrades de Proxmox, tras aplicar ajustes post-instalación, antes de abrir una ruta de acceso remoto) y guarda los informes — la tendencia importa más que cualquier número aislado.",
"outro": "El recorrido completo <em>Qué instala / cómo se configura / cómo desinstalar</em> y un análisis escrito del informe de ejemplo están en <link>ProxMenux → Seguridad → Lynis</link>."
"outro": "La guía completa de <em>instalación, configuración y desinstalación</em> y el análisis de un informe de ejemplo están en <link>ProxMenux → Seguridad → Lynis</link>."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -179,22 +179,22 @@
{
"card": "Autenticación, 2FA, cambio de contraseña",
"endpoint": "/api/auth/*",
"source": "SQLite local + JWT emitido por el Monitor."
"source": "Configuración local de autenticación en ~/.config/proxmenux-monitor/auth.json; JWT emitidos por Monitor."
},
{
"card": "SSL / HTTPS",
"card": "SSL/HTTPS",
"endpoint": "/api/auth/ssl/*",
"source": "<code>openssl x509</code> sobre <code>/etc/pve/local/pve-ssl.pem</code> + <code>/etc/proxmenux/ssl_config.json</code>."
},
{
"card": "Listar / generar / revocar tokens API",
"card": "Listar, generar y revocar tokens de API",
"endpoint": "/api/auth/api-tokens",
"source": "Filas de token guardadas localmente; nada sale del host."
},
{
"card": "Secure Gateway (deploy + estado)",
"endpoint": "/api/oci/*",
"source": "Provisiona LXC Alpine + <code>tailscaled</code> vía <code>pct create</code> / <code>pct exec</code>."
"source": "Crea un LXC Alpine y configura <code>tailscaled</code> mediante <code>pct create</code> / <code>pct exec</code>."
},
{
"card": "Estado y reglas de firewall",
@@ -219,27 +219,27 @@
{
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tail": " — flujo completo de primer arranque, selector de app 2FA, recuperación de authenticator perdido, snippets de reverse proxy."
"tail": " — configuración inicial completa, selección de app 2FA, recuperación por pérdida del autenticador y ejemplos de proxy inverso."
},
{
"label": "Integraciones",
"href": "/docs/monitor/integrations",
"tail": " — cookbooks para usar tokens API con Homepage, Home Assistant, Prometheus, n8n y el Secure Gateway de extremo a extremo."
"tail": " — ejemplos de uso de tokens de API con Homepage, Home Assistant, Prometheus y n8n, y configuración completa de Secure Gateway."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tailRich": " — cada endpoint <code>/api/auth</code>, <code>/api/security</code> y <code>/api/oci</code> con método, body y ejemplos curl."
"tailRich": " — endpoints de <code>/api/auth</code>, <code>/api/security</code> y <code>/api/oci</code> con método, cuerpo de petición y ejemplos de curl."
},
{
"label": "ProxMenux → Seguridad → Fail2Ban",
"href": "/docs/security/fail2ban",
"tail": " — recorrido de instalación, jails configurados, ruta de instalación manual."
"tail": " — guía de instalación, jails configurados e instalación manual."
},
{
"label": "ProxMenux → Seguridad → Lynis",
"href": "/docs/security/lynis",
"tail": " — informe de ejemplo, interpretación del score, cuándo volver a ejecutarlo."
"tail": " — informe de ejemplo, interpretación de la puntuación y cuándo repetir la auditoría."
}
]
}
@@ -1,173 +1,173 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Ajustes | Documentación de ProxMenux",
"description": "La pestaña Ajustes controla el idioma del Monitor, el orden de navegación, las preferencias del panel, los umbrales y exclusiones de salud, las notificaciones, la IA y el inventario de optimizaciones."
"description": "La pestaña Ajustes controla idioma, orden de navegación, preferencias del panel, umbrales y exclusiones de supervisión, notificaciones, IA e inventario de optimizaciones posteriores a la instalación."
},
"header": {
"title": "Panel: pestaña Ajustes",
"description": "Idioma del Monitor, orden de navegación, preferencias del panel, exclusiones de monitorización, notificaciones, configuración de IA e inventario de optimizaciones de ProxMenux.",
"description": "Idioma de Monitor, orden de navegación, preferencias del panel, exclusiones, notificaciones, IA e inventario actualizado de optimizaciones de ProxMenux.",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "Dónde vive realmente cada setting",
"body": "La pestaña Ajustes reúne varias funciones distintas: cómo se muestra el panel, qué vigila el Monitor de salud, cómo se envían las alertas y qué cambios ha aplicado ProxMenux en el host. Las tarjetas que tienen su propia página de documentación enlazan a ella en lugar de duplicar el contenido: Ajustes es el punto de entrada."
"title": "Dónde se guarda cada ajuste",
"body": "Ajustes reúne la presentación del panel, la supervisión de Health Monitor, el envío de alertas y los cambios ya aplicados al host por ProxMenux. Las tarjetas con documentación detallada enlazan a ella; aquí encontrarás su punto de acceso."
},
"interfaceLanguage": {
"heading": "Idioma de la interfaz",
"intro": "Selecciona el idioma de la <strong>interfaz web del Monitor</strong>. El cambio se aplica de inmediato; no reinicia el servicio ni modifica el idioma de los menús de ProxMenux ejecutados en la terminal.",
"intro": "Elige el idioma de la <strong>interfaz web del Monitor</strong>. Se aplica de inmediato, sin reiniciar el servicio ni cambiar el idioma de los menús de terminal de ProxMenux.",
"items": [
"ProxMenux Monitor ofrece actualmente inglés, alemán, español, francés, italiano, portugués, eslovaco y sueco.",
"En la primera visita, el Monitor utiliza el idioma del navegador si está disponible; en caso contrario, utiliza inglés.",
"Al cambiar la selección, se actualiza el idioma de la página y también el de otras pestañas abiertas con el mismo perfil del navegador.",
"Si falta una cadena traducida, solo ese texto se muestra en inglés en lugar de presentar una clave rota."
"En la primera visita usa el idioma del navegador si está disponible; en caso contrario, inglés.",
"Cambiar la selección actualiza el idioma de la página y lo sincroniza con las demás pestañas del mismo perfil del navegador.",
"Si falta una traducción, solo ese texto aparece en inglés en lugar de una clave o marcador roto."
],
"scopeTitle": "Preferencia local del navegador",
"scopeBody": "La selección se guarda en <code>localStorage</code> con la clave <code>proxmenux-ui-language</code>. Por tanto, pertenece a este perfil de navegador y dispositivo; no es un ajuste global del nodo. Cada administrador puede utilizar un idioma distinto."
"scopeBody": "La selección se guarda en <code>localStorage</code> con la clave <code>proxmenux-ui-language</code>. Pertenece al perfil y dispositivo actuales, no a todo el nodo. Cada administrador puede elegir su idioma."
},
"navigationOrder": {
"heading": "Orden de navegación",
"intro": "Esta tarjeta permite ordenar los siete elementos principales: <strong>Resumen, Apps, VMs y LXCs, Nodo, Copias, Terminal y Administración</strong>. Pulsa <strong>Editar</strong>, arrastra las filas y guarda el resultado.",
"intro": "Ordena los siete elementos principales: <strong>Resumen, Apps, VMs y LXCs, Nodo, Backup, Terminal y Administración</strong>. Pulsa <strong>Editar</strong>, arrastra las filas y guarda.",
"items": [
"Con el ratón, el arrastre comienza al pulsar. En una pantalla táctil se utiliza una pulsación mantenida de 250 ms para no confundir el desplazamiento normal con una reordenación.",
"Los grupos <strong>Nodo</strong> y <strong>Administración</strong> se mueven como unidades completas; sus páginas internas conservan el orden establecido por ProxMenux.",
"El menú móvil respeta el mismo orden guardado.",
"<strong>Restaurar valores predeterminados</strong> restablece el borrador. Es necesario guardar para aplicar el cambio.",
"Si una versión futura añade una nueva pestaña principal, esta se incorpora al final del orden personalizado sin borrar la organización del usuario."
"Con el ratón, el arrastre empieza al pulsar. En pantallas táctiles requiere mantener la pulsación 250 ms para distinguirlo del desplazamiento.",
"Los grupos <strong>Nodo</strong> y <strong>Administración</strong> se mueven completos; sus páginas internas conservan el orden establecido.",
"El menú móvil respeta el orden guardado.",
"<strong>Restaurar valores predeterminados</strong> restablece el orden en edición. Guarda para aplicar el cambio.",
"Las nuevas pestañas principales de futuras versiones se añaden al final del orden personalizado, conservando tu organización."
],
"landingTitle": "El primer elemento se convierte en la pestaña inicial",
"landingBody": "El primer elemento guardado es la página que abre el Monitor al cargar. Si <strong>Nodo</strong> ocupa la primera posición, se abre Almacenamiento; si la ocupa <strong>Administración</strong>, se abren los Logs del sistema. El orden se guarda solo en este navegador con la clave <code>proxmenux-nav-order</code>, por lo que cada dispositivo puede utilizar una organización distinta."
"landingTitle": "El primer elemento es la pestaña inicial",
"landingBody": "Monitor abre el primer elemento guardado. Si es <strong>Nodo</strong>, abre Almacenamiento; si es <strong>Administración</strong>, abre Registros del sistema. El orden se guarda en este navegador bajo <code>proxmenux-nav-order</code>, por lo que cada dispositivo puede tener su propia organización."
},
"networkUnits": {
"heading": "Network Units",
"imageAlt": "Tarjeta Network Units con desplegable Network Unit Display puesto en Bytes",
"imageCaption": "Elige entre bits por segundo y bytes por segundo para cada rate de red mostrado en el panel.",
"body": "Elige cómo se muestra el throughput de red a lo largo del panel: <strong>bits por segundo</strong> (Mbps / Gbps) o <strong>bytes por segundo</strong> (MB/s / GB/s). Bits es el valor por defecto porque es como los fabricantes de NICs e ISPs etiquetan sus productos; bytes es lo que reportan la mayoría de herramientas de transferencia de archivos. El setting afecta cada gráfica, insignia y tooltip que muestra rate de red — aplicado inmediatamente, sin recargar."
"heading": "Unidades de red",
"imageAlt": "Tarjeta Unidades de red con el selector de visualización en Bytes",
"imageCaption": "Elige bits por segundo o bytes por segundo para todas las velocidades de red del panel.",
"body": "Muestra la velocidad de red en <strong>bits por segundo</strong> (Mbps/Gbps) o <strong>bytes por segundo</strong> (MB/s/GB/s). Por defecto se usan bits, como en las especificaciones de interfaces y proveedores; las transferencias de archivos suelen usar bytes. El cambio se aplica de inmediato a gráficos, etiquetas y ayudas, sin recargar."
},
"health": {
"heading": "Monitor de salud",
"intro": "La tarjeta expone el setting <strong>Suppression Duration</strong> por categoría — una vez se descarta una alerta, cuánto tiene que pasar antes de que se permita al escáner volver a dispararla. Cada una de las diez categorías del Monitor de salud (CPU, Memoria, Almacenamiento, Discos, Red, VMs, Servicios PVE, Logs, Updates, Seguridad) tiene su propio desplegable con estos valores:",
"intro": "La tarjeta configura la <strong>duración del silenciamiento</strong>: cuánto debe esperar el análisis antes de volver a avisar de una alerta descartada. Cada categoría —CPU, memoria, almacenamiento, discos, red, VM, servicios PVE, registros, actualizaciones y seguridad— tiene su desplegable:",
"items": [
"<strong>24 h</strong> — por defecto para la mayoría de categorías transitorias.",
"<strong>72 h</strong> — para eventos sobre los que quieres unos días de silencio.",
"<strong>72 h</strong> — para silenciar estos eventos durante unos días.",
"<strong>168 h</strong> (1 semana) y <strong>720 h</strong> (1 mes) — chequeos periódicos.",
"<strong>8760 h</strong> (1 año) — efectivamente \"silencio en el futuro previsible\".",
"<strong>8760 h</strong> (1 año) — silencio durante un periodo largo.",
"<strong>-1</strong> — silencio permanente hasta que lo reactives manualmente.",
"<strong>Custom hours</strong> — cualquier entero si necesitas un valor intermedio."
"<strong>Horas personalizadas</strong>: cualquier número entero si necesitas un valor intermedio."
],
"imageAlt": "Card Settings → Monitor de salud con los desplegables de supresión por categoría y la sección Active Suppressions",
"imageCaption": "Card Monitor de salud — los desplegables por categoría fijan los valores por defecto para nuevos dismisses; la sección Active Suppressions debajo lista cada alerta actualmente silenciada y permite revertirlas.",
"editTitle": "Modo Edit",
"editBody": "La tarjeta es de solo-lectura por defecto. Pulsa <strong>Edit</strong> en la esquina superior derecha de la card para activar los desplegables y los botones Re-enable. <strong>Save</strong> confirma todos los cambios pendientes (cambios de Suppression Duration y re-enables encolados) en un solo lote; <strong>Cancel</strong> los descarta todos. El botón Save solo se activa cuando hay al menos un cambio pendiente.",
"activeTitle": "Active Suppressions",
"activeIntro": "Debajo de los desplegables de Suppression Duration, la sección <strong>Active Suppressions</strong> lista cada alerta actualmente silenciada — tanto los dismisses time-limited (24 h, 7 días, ventanas custom) como los <em>Permanent</em>. Cada fila muestra:",
"imageAlt": "Ajustes, tarjeta Health Monitor con duración por categoría y sección de silenciamientos activos",
"imageCaption": "Los desplegables definen la duración para futuros descartes. La sección inferior muestra las alertas silenciadas y permite reactivarlas.",
"editTitle": "Modo de edición",
"editBody": "La tarjeta comienza en solo lectura. Pulsa <strong>Editar</strong> arriba a la derecha para activar desplegables y botones de reactivación. <strong>Guardar</strong> aplica en un lote las duraciones y reactivaciones pendientes; <strong>Cancelar</strong> las descarta. Guardar solo se activa cuando hay cambios.",
"activeTitle": "Silenciamientos activos",
"activeIntro": "Bajo las duraciones, <strong>Silenciamientos activos</strong> enumera las alertas silenciadas temporalmente —24 h, 7 días u otro periodo— y las <em>permanentes</em>. Cada fila muestra:",
"activeItems": [
"Un badge coloreado — <strong>Permanent</strong> (ámbar) o una cuenta atrás como <strong>24h remaining</strong> / <strong>7d remaining</strong> (azul).",
"El identificador de la alerta, normalizado para legibilidad (p. ej. <code>pve_storage_full_PBS-Cloud</code> → <em>PVE Storage Full: PBS-Cloud</em>).",
"Categoría, severidad y el timestamp en que se descartó la alerta.",
"Un botón <strong>Re-enable</strong> (activo solo en modo Edit) que encola la alerta para ser un-acknowledged al siguiente Save."
"Una insignia de color: <strong>Permanente</strong> en ámbar o una cuenta atrás, como <strong>24 h restantes</strong> / <strong>7 días restantes</strong>, en azul.",
"El identificador de la alerta, adaptado para facilitar su lectura (p. ej. <code>pve_storage_full_PBS-Cloud</code> → <em>Almacenamiento PVE lleno: PBS-Cloud</em>).",
"Categoría, gravedad y fecha y hora en que se descartó la alerta.",
"Un botón <strong>Reactivar</strong>, disponible al editar, deja pendiente retirar el silenciamiento al guardar."
],
"activeReenableTitle": "Flujo de Re-enable",
"activeReenableBody": "Pulsar <strong>Re-enable</strong> en modo Edit marca la fila en verde y tacha su identificador — está encolada pero todavía no aplicada. Volver a hacer clic en la misma fila la <strong>Undo</strong> (la saca de la cola). Cuando pulsas <strong>Save</strong>, cada re-enable encolado dispara <code>POST /api/health/un-acknowledge</code> en paralelo y las filas afectadas desaparecen de la lista. Si la condición subyacente sigue presente y la categoría soporta re-fire, la alerta reaparece en la lista Active del Monitor de salud en el siguiente ciclo de escaneo.",
"activePermanentNote": "Los dismisses permanentes (alertas descartadas con <em>Permanently</em> desde el modal del Monitor, o aquellas cuya categoría tenga el default puesto a <code>-1</code>) <strong>solo se pueden revertir desde aquí</strong>. El modal del dashboard no expone un botón un-dismiss para ellas — el panel Active Suppressions es el único log de auditoría + UI de revert.",
"activeAutoRefreshTitle": "Auto-refresh",
"activeAutoRefreshBody": "La lista se refresca automáticamente cuando descartas o un-dismiss una alerta desde el modal del Monitor de salud (vía un evento in-browser), cuando la pestaña recupera el foco y al cambio de visibilidad. No necesitas recargar la página tras descartar una alerta desde el dashboard.",
"calloutTitle": "La semántica completa vive en la página del Monitor de salud",
"calloutBody": "Las reglas de escalada (cuándo un re-fire pasa a critical), el comportamiento de auto-resolve para eventos cuyo dispositivo subyacente desaparece y la diferencia entre dismissed y resolved — todo documentado bajo <link>Monitor de salud → Descartar alertas y la Suppression Duration</link>. Esta tarjeta solo expone los desplegables por categoría y el panel Active Suppressions."
"activeReenableTitle": "Cómo reactivar una alerta",
"activeReenableBody": "<strong>Reactivar</strong> al editar marca la fila en verde y tacha su identificador; aún no se aplica. Pulsa de nuevo para <strong>Deshacer</strong>. <strong>Guardar</strong> envía en paralelo <code>POST /api/health/un-acknowledge</code> por cada reactivación y retira sus filas. Si el problema persiste y la categoría permite repetir avisos, la alerta volverá a Activas en el próximo análisis.",
"activePermanentNote": "Los descartes permanentes —mediante <em>Permanente</em> o duración predeterminada <code>-1</code>— <strong>solo se revierten aquí</strong>. El diálogo general no ofrece ese botón; esta sección reúne el registro y la reactivación.",
"activeAutoRefreshTitle": "Actualización automática",
"activeAutoRefreshBody": "La lista se actualiza al descartar o reactivar una alerta desde Health Monitor, al volver a la pestaña y al cambiar su visibilidad. No necesitas recargar la página.",
"calloutTitle": "Detalles en la página de Health Monitor",
"calloutBody": "Las reglas de escalado, la resolución automática cuando desaparece un dispositivo y la diferencia entre descartar y resolver se explican en <link>Health Monitor → Descartar alertas y duración del silenciamiento</link>. Esta tarjeta ofrece los desplegables y los silenciamientos activos."
},
"thresholds": {
"heading": "Health Monitor Thresholds",
"intro": "Donde la tarjeta anterior decide <em>cuánto tiempo quedarse callado tras un dismiss</em>, esta decide <strong>a qué valor se dispara una alerta en primer lugar</strong>. Cada chequeo que ejecuta el Monitor de salud está parametrizado por un par de números — un umbral <strong>Warning</strong> y un umbral <strong>Critical</strong> — y ambos se exponen aquí para que el operador los ajuste.",
"heading": "Umbrales de Health Monitor",
"intro": "La tarjeta anterior define <em>cuánto dura el silencio tras descartar</em>; esta define <strong>el valor que activa una alerta</strong>. La mayoría de controles tienen valores <strong>Aviso</strong> y <strong>Crítico</strong> ajustables. La tabla explica excepciones como la regla combinada de swap.",
"whatForTitle": "Para qué sirve",
"whatForIntro": "Los valores por defecto que vienen con ProxMenux son sensatos para el host Proxmox medio, pero cada entorno tiene su propio sobre operativo:",
"whatForIntro": "Los valores predeterminados sirven como punto de partida, pero cada entorno tiene sus propias condiciones:",
"whatForItems": [
"Un homelab pequeño con un SSD único puede querer avisar antes en capacidad (75 / 90 %) para dejar margen a snapshots.",
"Un host de datacenter con nodos Ceph redundantes puede ser más relajado en avisos de memoria (un working set al 90 % es normal bajo ARC de ZFS).",
"Un mini-PC con refrigeración pasiva necesita umbrales de temperatura más bajos que un servidor con refrigeración forzada por aire — misma clase de drive, sobre físico distinto.",
"Un host muy virtualizado que clava CPU durante builds no debería avisar en cada pico del 80 %, pero sí debe seguir alertando sobre presión sostenida."
"Un homelab con un único SSD puede avisar antes de llenarse, por ejemplo al 75/90 %, para dejar margen a los snapshots.",
"Los umbrales de memoria deben reflejar las mediciones y la carga del host. La redundancia Ceph no justifica por sí sola relajar avisos, y el uso elevado de ARC de ZFS no equivale a memoria de trabajo irrecuperable.",
"Elige umbrales de temperatura según las especificaciones del disco y sus condiciones reales. La refrigeración pasiva o forzada no determina por sí sola un límite seguro universalmente más bajo o más alto.",
"Un host muy virtualizado puede alcanzar picos de CPU durante compilaciones sin necesitar avisos por cada pico del 80 %, pero debe seguir avisando de saturación sostenida."
],
"whatForOutro": "Editar un umbral surte efecto <strong>en el siguiente scan</strong> — el Monitor de salud relee los valores desde <code>/usr/local/share/proxmenux/health_thresholds.json</code> en cada ciclo, sin reinicio de servicio. Los mismos números también alimentan los rangos de color de los widgets del panel (la línea de temperatura en la modal de temperatura de disco, las barras de las tarjetas de almacenamiento) para que la clasificación visual coincida con lo que dispara la alerta.",
"coloursTitle": "Colores de estado: cómo renderizan Warning y Critical en el panel",
"coloursIntro": "Cada umbral de abajo produce la misma clasificación de tres estados a lo largo del panel — los mismos colores para barras de almacenamiento, anillos de CPU/memoria, chips de temperatura y el punto de la modal de disco. Leer un color en cualquier sitio del Monitor mapea a un rango definido relativo al par configurado:",
"whatForOutro": "Los cambios admitidos se aplican <strong>en el siguiente análisis</strong>. Health Monitor lee <code>/usr/local/share/proxmenux/health_thresholds.json</code> cada ciclo sin reinicio. Algunos indicadores, como temperatura de disco, usan estos valores; ciertas barras de capacidad conservan sus propios cortes.",
"coloursTitle": "Colores de estado de Aviso y Crítico",
"coloursIntro": "Los widgets que usan el par Aviso/Crítico siguen los tres estados siguientes. Algunos indicadores, como las barras de capacidad PVE, tienen límites propios; su color no basta para deducir una alerta de Health Monitor.",
"headerColour": "Color",
"headerRange": "Rango",
"headerMeaning": "Significado",
"colourRows": [
{
"colour": "Verde",
"range": "valor < Warning",
"meaning": "Rango operativo normal. No se dispara alerta."
"range": "Valor < Aviso",
"meaning": "Rango normal. No se genera alerta."
},
{
"colour": "Ámbar",
"range": "Warning ≤ valor < Critical",
"meaning": "Estado warning. El Monitor de salud dispara un evento de severidad WARNING; las notificaciones respetan los filtros del canal y las Quiet Hours."
"range": "Aviso ≤ valor < Crítico",
"meaning": "Estado de aviso. Health Monitor genera un evento WARNING; las notificaciones respetan filtros de canal y horario de silencio."
},
{
"colour": "Rojo",
"range": "valor ≥ Critical",
"meaning": "Estado critical. El Monitor de salud dispara un evento CRITICAL; CRITICAL salta las Quiet Hours y siempre alcanza al canal."
"range": "Valor ≥ Crítico",
"meaning": "Estado crítico. Health Monitor genera un evento CRITICAL que omite el horario de silencio. Siguen aplicándose los ajustes de categoría y evento del canal; la entrega también depende de su disponibilidad."
}
],
"sectionsTitle": "Secciones y valores por defecto recomendados",
"sectionsIntro": "Estos son los valores con los que viene ProxMenux — la baseline recomendada. Es lo que ves en un host recién montado hasta que sobreescribes algo. Las secciones están ordenadas de arriba abajo de <em>cómputo</em> → <em>calor</em> → <em>capacidad de almacenamiento</em>, así que leer hacia abajo va de lo concreto (carga actual) al estado acumulado (espacio libre).",
"sectionsTitle": "Secciones y valores predeterminados recomendados",
"sectionsIntro": "Son los valores iniciales de ProxMenux hasta que los cambies. Las secciones van de <em>carga de cómputo</em> a <em>temperatura</em> y <em>capacidad de almacenamiento</em>, desde la carga actual al espacio ocupado.",
"headerSection": "Sección",
"headerWarning": "Warning",
"headerCritical": "Critical",
"headerWarning": "Aviso",
"headerCritical": "Crítico",
"headerGates": "Qué controla",
"thresholdRows": [
{
"section": "Uso de CPU",
"warning": "85 %",
"critical": "95 %",
"gates": "Alerta de carga sostenida cuando la CPU promedia por encima del umbral durante la ventana de scan."
"gates": "Alerta de carga sostenida cuando la CPU media supera el umbral durante el periodo de análisis."
},
{
"section": "Memoria",
"warning": "85 %",
"critical": "95 %",
"gates": "Presión de RAM en el host."
"gates": "Presión de RAM del host."
},
{
"section": "Swap (solo critical)",
"section": "Uso de swap (solo crítico)",
"warning": "—",
"critical": "5 %",
"gates": "Swap realmente en uso. El número es intencionadamente bajo: un host Proxmox sano apenas debería tocar swap, así que incluso un 5 % es una señal significativa de presión de RAM."
"critical": "80 %",
"gates": "El estado CRITICAL de swap exige superar el 80 % de swap y tener menos del 15 % de RAM disponible, sostenido en las muestras. El swap ocupado por sí solo no activa esta regla."
},
{
"section": "Temperatura de CPU",
"warning": "80 °C",
"critical": "90 °C",
"gates": "Lectura de temperatura de package / core de CPU desde <code>lm-sensors</code>."
"gates": "Temperatura del conjunto o de los núcleos de CPU obtenida de <code>lm-sensors</code>."
},
{
"section": "Temp de disco — HDD",
"warning": "60 °C",
"critical": "65 °C",
"gates": "Drives spinning estándar. El sobre del fabricante topa alrededor de 60–65 °C, así que Critical se fija justo en el límite duro."
"gates": "Temperatura HDD. Valores iniciales: aviso a 60 °C y crítico a 65 °C. Son valores de supervisión, no un límite universal del fabricante; consulta las especificaciones del modelo."
},
{
"section": "Temp de disco — SSD",
"warning": "70 °C",
"critical": "75 °C",
"gates": "SSDs SATA 2.5'' / M.2 — corren más frescos que NVMe pero más calientes que HDDs."
"gates": "SSD SATA de 2,5 pulgadas o M.2. Esta clase usa valores iniciales de 70/75 °C; los límites reales dependen del modelo."
},
{
"section": "Temp de disco — NVMe",
"warning": "80 °C",
"critical": "85 °C",
"gates": "Los drives NVMe corren más calientes por diseño; los controladores auto-throttlean por encima de ~85 °C, así que Warning captura la escalada antes de que entre el throttling."
"gates": "Temperatura NVMe. Esta clase usa valores iniciales de 80/85 °C. La temperatura de limitación del controlador varía por modelo y no siempre es 85 °C."
},
{
"section": "Temp de disco — SAS",
"warning": "55 °C",
"critical": "65 °C",
"gates": "Los drives SAS enterprise comparten el mismo límite de fabricante de ~65 °C que los HDDs, pero se despliegan normalmente en chasis rack con refrigeración activa. Una lectura a 55 °C ya señala un problema de refrigeración (ventilador fallando, problema de HVAC) <em>antes</em> de que el propio drive esté en riesgo — de ahí un Warning más bajo que HDD, no porque SAS sea menos tolerante al calor."
"gates": "Temperatura SAS. Esta clase usa aviso a 55 °C y crítico a 65 °C. Son <em>valores de supervisión</em>, no una prueba de fallo de refrigeración a 55 °C ni un límite universal del fabricante."
},
{
"section": "Espacio de disco — host",
"warning": "85 %",
"critical": "95 %",
"gates": "Capacidad de <code>/</code> y cada mountpoint del host (<code>/var/lib/vz</code>, <code>/mnt/*</code>…)."
"gates": "Capacidad de <code>/</code> y de cada punto de montaje del host (<code>/var/lib/vz</code>, <code>/mnt/*</code>…)."
},
{
"section": "Espacio de disco — rootfs LXC",
@@ -176,105 +176,105 @@
"gates": "Disco raíz por contenedor, evaluado contra el tamaño del rootfs según PVE."
},
{
"section": "Mount points LXC",
"section": "Puntos de montaje LXC",
"warning": "85 %",
"critical": "95 %",
"gates": "Capacidad de mountpoints dentro de CTs en ejecución (mp0, mp1, NFS, bind mounts). Excluye rootfs."
"gates": "Capacidad de montajes en CT en ejecución: mp0, mp1, NFS y bind mounts. Excluye rootfs."
},
{
"section": "Almacenamiento PVE",
"warning": "85 %",
"critical": "95 %",
"gates": "Almacenamientos PVE estilo bloque (LVM, LVM-thin, ZFS-pool, RBD/Ceph, PBS)."
"gates": "Solo almacenamientos PVE de tipo LVM, LVM-thin, ZFS-pool, RBD, CephFS y PBS. Los de tipo directorio, NFS y CIFS los cubre la fila de espacio en disco del host."
},
{
"section": "Pool ZFS",
"warning": "85 %",
"critical": "95 %",
"gates": "Pools ZFS a nivel host — independiente del registro PVE."
"gates": "Pools ZFS del host, con independencia de su registro en PVE."
}
],
"defaultsTitle": "Valores por defecto, overrides y reset",
"defaultsBody": "El backend expone una vista fundida: cada sección parte de los valores por defecto de ProxMenux (los que ves cuando el host está recién hecho) y sobreescribes solo los knobs que te importan. La tarjeta muestra el valor <em>efectivo</em> — la sobreescritura si pones una, en otro caso el valor por defecto. Un botón <strong>Reset</strong> limpia cada override y vuelve a los valores por defecto en todas las secciones de una vez.",
"defaultsTitle": "Valores predeterminados, modificaciones y restablecimiento",
"defaultsBody": "Cada sección parte de los valores predeterminados y solo guardas las modificaciones necesarias. La tarjeta muestra el valor <em>efectivo</em>: tu modificación o el valor inicial. <strong>Restablecer</strong> borra todas las modificaciones y restaura los valores de todas las secciones.",
"validationTitle": "Validación",
"validationBody": "Guardar rechaza valores que no tienen sentido (porcentajes fuera de 0–100, critical por debajo de warning, temperaturas negativas). El frontend muestra el error inline; el backend valida otra vez antes de persistir, así que no se puede engañar a la API con un PUT hecho a mano para que acepte un umbral roto."
"validationBody": "Al guardar se comprueban los rangos permitidos y se rechaza Crítico por debajo de Aviso. La interfaz muestra errores y el servidor vuelve a validar las peticiones API antes de guardar."
},
"lxcDetection": {
"heading": "LXC Update Detection",
"imageAlt": "Tarjeta LXC Update Detection con un único switch — cuando está activo, el Monitor escanea periódicamente contenedores LXC Debian/Ubuntu/Alpine en ejecución buscando paquetes con update pendiente.",
"imageCaption": "El toggle para el scan periódico <code>apt list --upgradable</code> / <code>apk list -u</code> a lo largo de cada CT en ejecución. Por defecto ON. El toggle de notificación correspondiente en Notifications → Services solo aparece mientras la detección está activa.",
"intro": "Un toggle dedicado para el scan de actualizaciones LXC, situado entre Health Monitor Thresholds y la tarjeta Notifications. Cuando está ON, ProxMenux recorre cada CT en ejecución del host y consulta al gestor de paquetes dentro del contenedor por updates pendientes; los resultados aterrizan en los contadores de insignias de la pestaña Hardware y alimentan la notificación <code>lxc_updates_available</code>. Cuando está OFF, el scan se detiene por completo (sin llamadas <code>pct exec</code>) y cualquier entrada LXC existente en <code>managed_installs.json</code> se purga inmediatamente, así el panel y el endpoint <code>/api/managed-installs</code> dejan de reportar estado de update LXC sin esperar al siguiente ciclo de 24h.",
"whatRunsTitle": "Qué ejecuta realmente el scan",
"whatRunsIntro": "Para cada CT en estado <code>running</code> con un gestor de paquetes soportado:",
"heading": "Detección de actualización de LXC",
"imageAlt": "Tarjeta de detección de actualizaciones LXC con interruptor para buscar paquetes pendientes en contenedores Debian, Ubuntu y Alpine en ejecución",
"imageCaption": "Interruptor del análisis periódico con <code>apt list --upgradable</code> / <code>apk list -u</code> en los CT en ejecución. Viene activado. El interruptor de aviso en Notificaciones → Servicios aparece mientras la detección está activa.",
"intro": "El interruptor entre Umbrales y Notificaciones controla el análisis LXC. Al activarlo, consulta los gestores de paquetes de CT en ejecución; los resultados aparecen en Hardware y alimentan <code>lxc_updates_available</code>. Al desactivarlo, cesan sus llamadas <code>pct exec</code> y se eliminan las entradas LXC de <code>managed_installs.json</code>, por lo que <code>/api/managed-installs</code> deja de mostrar ese estado sin esperar 24 h.",
"whatRunsTitle": "Qué ejecuta el análisis",
"whatRunsIntro": "Para cada CT en estado <code>running</code> con un gestor de paquetes compatible:",
"whatRunsItems": [
"<strong>Gate de frescura de caché.</strong> Si la caché de metadatos apt/apk dentro del contenedor es más vieja que <strong>24 horas</strong>, primero corre un refresh best-effort (<code>apt-get update -qq</code> en Debian/Ubuntu, <code>apk update</code> en Alpine) con un timeout de 60 s. Cualquier fallo (sin red, repo roto, timeout) se traga en silencio — el listado de abajo sigue corriendo contra la caché que exista, así que un problema transitorio de repo nunca puede empeorar la detección.",
"<strong>Listing.</strong> Después ProxMenux ejecuta <code>apt list --upgradable</code> / <code>apk list -u</code> y parsea la salida en un recuento estructurado más una muestra de los nombres de paquetes top.",
"<strong>Dedup por CT.</strong> Una fingerprint construida a partir del recuento, security-count y los nombres top ordenados se almacena para que un conjunto estable de updates pendientes no re-notifique diariamente, mientras que un conjunto significativamente distinto sí lo haga."
"<strong>Actualización de metadatos.</strong> Si la caché apt/apk supera <strong>24 horas</strong>, intenta renovarla con <code>apt-get update -qq</code> en Debian/Ubuntu o <code>apk update</code> en Alpine, con límite de 60 s. Si falla, el listado usa la caché disponible y puede estar desactualizado.",
"<strong>Listado.</strong> Ejecuta <code>apt list --upgradable</code> / <code>apk list -u</code> y obtiene el número de paquetes y una muestra de sus nombres.",
"<strong>Evitar duplicados por CT.</strong> Guarda una huella del total, las actualizaciones de seguridad y los nombres ordenados para no repetir avisos diarios del mismo conjunto. Un cambio relevante sí vuelve a avisar."
],
"selfUpdateTitle": "Los CTs que se auto-actualizan fuera de apt pueden legítimamente reportar 0",
"selfUpdateBody": "La detección solo ve lo que el gestor de paquetes dentro del contenedor conoce. Un CT cuyo software clave se actualiza fuera de apt (el cron <code>plexupdate</code> de Plex, contenedores Docker actualizados vía <code>docker pull</code>, el actualizador integrado de Frigate, etc.) seguirá reportando updates apt bajos o cero aunque el appliance se mantenga al día activamente — eso es correcto, no es un bug. El sistema base a nivel apt del mismo CT puede aún tener sus propios updates pendientes, que sí saca a la luz el scan.",
"refreshTitle": "Por qué el auto-refresh de 24 h",
"refreshBody": "Los CTs appliance de larga vida con frecuencia acaban con cachés apt meses desactualizadas porque nadie ejecuta rutinariamente <code>apt update</code> dentro de ellos. Sin el refresh, <code>apt list --upgradable</code> reporta 0 updates desde una snapshot congelada y el operador nunca ve el backlog. El umbral coincide con el resto del ciclo de chequeo — si el CT se refrescó en las últimas 24 h, ProxMenux confía en esa señal y se salta el refresh.",
"toggleTitle": "Toggle de notificación condicional",
"toggleBody": "El toggle de notificación por canal <code>lxc_updates_available</code> en <strong>Notifications → Services</strong> solo se renderiza mientras la detección está activa. Cuando pones la detección en OFF, esa fila desaparece de la lista de categorías de cada canal — pero su preferencia almacenada se preserva en la DB, así que reactivar la detección trae el toggle de vuelta al valor que tenía antes.",
"purgeTitle": "Qué se purga al desactivar la detección",
"purgeBody": "Apagar el switch elimina inmediatamente cada entrada <code>type=lxc</code> de <code>/usr/local/share/proxmenux/managed_installs.json</code>. Las insignias de la pestaña Hardware caen a cero en el siguiente refresco del panel. Volver a activarlo repuebla el registro en el siguiente ciclo de detección (o antes si disparas un refresh manual desde la API)."
"selfUpdateTitle": "Los CT con actualizaciones fuera de apt pueden mostrar 0",
"selfUpdateBody": "La detección solo cubre el gestor de paquetes del CT. Software actualizado fuera de apt, como un trabajo <code>plexupdate</code> configurado o imágenes obtenidas con <code>docker pull</code>, queda fuera del recuento. Cero actualizaciones apt no demuestra que todas las aplicaciones estén al día. El sistema base del CT puede tener paquetes pendientes que sí se detectan.",
"refreshTitle": "Por qué renovar los metadatos cada 24 h",
"refreshBody": "Un CT de larga duración puede tener metadatos apt antiguos si nadie ejecuta <code>apt update</code>. Entonces <code>apt list --upgradable</code> puede omitir actualizaciones recientes. ProxMenux intenta renovarlos si tienen más de 24 horas y omite el paso si son más recientes.",
"toggleTitle": "Interruptor de aviso condicionado a la detección",
"toggleBody": "El interruptor por canal <code>lxc_updates_available</code> en <strong>Notificaciones → Servicios</strong> solo aparece con la detección activa. Al desactivarla, la fila se oculta en todos los canales. Su preferencia se conserva en la base de datos y recupera el mismo valor al reactivarla.",
"purgeTitle": "Qué se elimina al desactivar la detección",
"purgeBody": "Desactivarlo elimina de inmediato las entradas <code>type=lxc</code> de <code>/usr/local/share/proxmenux/managed_installs.json</code>. Los contadores de actualizaciones LXC de la pestaña VM y LXC desaparecen en el siguiente refresco. Al reactivarlo, el próximo ciclo de detección repuebla el registro, o antes con una actualización manual de la API."
},
"storageExclusions": {
"heading": "Remote Storage Exclusions",
"imageAlt": "Tarjeta Remote Storage Exclusions listando almacenamientos PBS-Cloud, PBS y PBS2 con toggles Health y Alerts por fila",
"imageCaption": "Toggles <em>Health</em> y <em>Alerts</em> por almacenamiento. Los almacenamientos con ambos toggles en off dejan de contar contra el Monitor de salud y dejan de generar notificaciones — pero siguen renderizándose en la pestaña Almacenamiento marcados como excluidos.",
"intro": "Marca los almacenamientos gestionados por Proxmox (NFS / CIFS / PBS / Ceph / iSCSI / etc.) como excluidos de monitorización. Dos toggles independientes por almacenamiento:",
"heading": "Exclusiones de almacenamiento remoto",
"imageAlt": "Tarjeta de exclusiones de almacenamiento remoto con PBS-Cloud, PBS y PBS2 y controles de Estado y Alertas por fila",
"imageCaption": "Controles <em>Estado</em> y <em>Alertas</em> por almacenamiento. Con ambos desactivados, deja de participar en Health Monitor y de enviar avisos. Sigue visible en Almacenamiento, marcado como excluido.",
"intro": "Puedes excluir almacenamientos gestionados por Proxmox (NFS / CIFS / PBS / Ceph / iSCSI / etc.) con dos controles independientes:",
"items": [
"<strong>Health</strong> — cuando está off, el almacenamiento deja de contribuir a la categoría Almacenamiento del Monitor de salud. Útil para volúmenes de archivo que están intencionadamente offline la mayor parte del tiempo o destinos de backup remotos que solo se encienden a horario.",
"<strong>Alerts</strong> — cuando está off, las alertas sobre este almacenamiento dejan de salir a través de los canales configurados, aunque los chequeos Health sigan activos. Útil cuando quieres la vista del panel pero no las notificaciones."
"<strong>Estado</strong> — al desactivar este control, el almacenamiento deja de contar en la categoría Almacenamiento de Health Monitor. Útil para volúmenes de archivo habitualmente desconectados o destinos remotos de backup que solo se encienden según un horario.",
"<strong>Alertas</strong> — desactivarlo impide enviar avisos de este almacenamiento por los canales configurados, aunque los controles de estado sigan activos. Útil si quieres ver su estado en el panel sin recibir avisos."
],
"outro": "Los almacenamientos excluidos siguen renderizándose en la <link>pestaña Almacenamiento</link> con una insignia morada <em>excluded</em> para que la entrada no desaparezca silenciosamente de tu inventario. El estado se persiste en la tabla SQLite <code>excluded_storages</code>."
"outro": "Los almacenamientos excluidos siguen en la <link>pestaña Almacenamiento</link> con la insignia morada <em>excluido</em>, para mantener visible el inventario. El estado se guarda en la tabla SQLite <code>excluded_storages</code>."
},
"interfaceExclusions": {
"heading": "Network Interface Exclusions",
"imageAlt": "Tarjeta Network Interface Exclusions listando vmbr0, vmbr1, vmbr2, bond0 y eno1 con toggles Health y Alerts por interfaz",
"imageCaption": "La misma forma que Storage Exclusions — toggles <em>Health</em> y <em>Alerts</em> por interfaz. Cada fila muestra la interfaz, insignia de tipo (bridge / bond / física), la IP y la velocidad del enlace.",
"intro": "La misma forma que Storage Exclusions pero para interfaces de red. Por interfaz: excluir de los chequeos Health y/o excluir de las notificaciones. Casos de uso típicos:",
"heading": "Exclusiones de interfaz de red",
"imageAlt": "Tarjeta de exclusiones de interfaces con vmbr0, vmbr1, vmbr2, bond0 y eno1 y controles de Estado y Alertas por interfaz",
"imageCaption": "Igual que las exclusiones de almacenamiento, ofrece <em>Estado</em> y <em>Alertas</em> por interfaz. Cada fila muestra nombre, tipo (bridge / bond / física), IP y velocidad del enlace.",
"intro": "El mismo principio se aplica a las interfaces: excluir cada una de los controles de estado, de los avisos o de ambos. Ejemplos habituales:",
"items": [
"Un bridge spare intencionadamente down.",
"Una NIC que se retiró físicamente pero sigue referenciada en <code>/etc/network/interfaces</code>.",
"Una sub-interfaz VLAN usada solo durante ventanas de mantenimiento.",
"Un bridge de gestión que está up pero no lleva tráfico — flappeando ruidosamente en cada ciclo."
"Un bridge de reserva desactivado intencionadamente.",
"Una NIC retirada físicamente que aún figura en <code>/etc/network/interfaces</code>.",
"Una subinterfaz VLAN usada solo durante tareas de mantenimiento.",
"Un bridge de gestión con cambios de estado del enlace conocidos y repetidos durante el mantenimiento."
],
"outro": "El estado se persiste en la tabla SQLite <code>excluded_interfaces</code>. La misma insignia morada <em>excluded</em> en la <link>pestaña Red</link> para que las interfaces excluidas sigan visibles."
"outro": "El estado se guarda en la tabla SQLite <code>excluded_interfaces</code>. La insignia morada <em>excluida</em> de la <link>pestaña Red</link> mantiene visibles las interfaces excluidas."
},
"notifications": {
"heading": "Notificaciones e IA",
"body1": "Esta sección de la pestaña Settings es donde se activan las notificaciones de ProxMenux Monitor y el reescritor con IA. Pulsar <em>Enable Notifications</em> arranca el hilo de envío en background, registra un target de webhook de Proxmox VE en el host para que los eventos emitidos por PVE fluyan al mismo pipeline y despliega el formulario de canales para que puedas conectar Telegram, Discord, Email, Gotify y el resto. El reescritor con IA vive dentro del mismo panel como una sección avanzada colapsable.",
"body2": "Ambas superficies tienen muchas piezas en movimiento — canales, toggles por evento, mensajes Rich, el Display Name, el pipeline de envío (dedup, cooldown, agregación, quiet hours), la integración del webhook PVE, proveedores de IA, modos de prompt — y viven en sus propias páginas dedicadas en lugar de repetirse aquí:",
"body1": "Aquí se activan las notificaciones de ProxMenux Monitor y la reformulación con IA. <em>Activar notificaciones</em> inicia el proceso de envío en segundo plano, registra un destino webhook de Proxmox VE para incorporar sus eventos y abre el formulario de canales: Telegram, Discord, correo, Gotify y otros. La reformulación con IA está en una sección avanzada desplegable del mismo panel.",
"body2": "Sus opciones se explican en páginas propias: canales, controles por evento, mensajes enriquecidos, nombre visible, envío (duplicados, espera, agrupación y horario de silencio), webhook PVE, proveedores de IA y modos de instrucciones:",
"items": [
"<notifLink>Notificaciones</notifLink> — recorridos por canal (Telegram, Discord, Gotify, Email + app passwords de Gmail / Microsoft, ntfy, Slack, Teams, webhook genérico), categorías por evento, mensajes Rich, Display Name, pipeline de envío, integración del webhook PVE, historial y API.",
"<aiLink>Asistente de IA</aiLink> — proveedores (OpenAI, Anthropic, Gemini, Groq, OpenRouter, Ollama), selección de modelo, modos de prompt (default / custom), idioma de salida, niveles de detalle por canal y sugerencias de IA."
"<notifLink>Notificaciones</notifLink>: configuración de canales (Telegram, Discord, Gotify, correo y contraseñas de aplicación de Gmail / Microsoft, ntfy, Slack, Teams y webhook genérico), categorías por evento, mensajes enriquecidos, nombre visible, envío, webhook PVE, historial y API.",
"<aiLink>Asistente de IA</aiLink>: proveedores (OpenAI, Anthropic, Gemini, Groq, OpenRouter, Ollama), modelos, instrucciones predeterminadas o personalizadas, idioma de salida, detalle por canal y sugerencias de IA."
]
},
"optimizations": {
"heading": "ProxMenux Optimizations",
"intro": "Un inventario en vivo y transparente de cada optimización post-instalación de ProxMenux actualmente activa en el host. Cada vez que aplicas una opción post-instalación desde el lado Scripts — ya sea vía el <autoLink>Automated post-install</autoLink> o vía el <customLink>Customizable post-install</customLink> a la carta — el script correspondiente se registra a sí mismo en <code>/usr/local/share/proxmenux/installed_tools.json</code>. El Monitor lee ese archivo y renderiza esta tarjeta para que veas, de un vistazo, qué se ha cambiado en tu servidor.",
"imageAlt": "Tarjeta ProxMenux Optimizations con rejilla de herramientas instaladas, cada fila mostrando un punto verde, nombre de la herramienta y versión. Ejemplos incluyen 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 con insignia Legacy, Kernel Panic Configuration, Logrotate Optimization, Network Optimizations, Subscription Banner Removal, VFIO IOMMU Passthrough — 14 activas en total",
"imageCaption": "La tarjeta lista cada optimización activa con su nombre, versión, un punto coloreado y un contador naranja <em>14 active</em> arriba a la derecha. Las herramientas cuyo source es alcanzable son pulsables.",
"heading": "Optimizaciones ProxMenux",
"intro": "Inventario de optimizaciones posteriores a la instalación registradas por ProxMenux en el host. Las opciones de <autoLink>Instalación posterior automatizada</autoLink> y <customLink>Instalación posterior personalizable</customLink> registran su aplicación en <code>/usr/local/share/proxmenux/installed_tools.json</code>. Monitor usa ese registro para la tarjeta. Una entrada no comprueba de nuevo que todos los ajustes sigan intactos.",
"imageAlt": "Tarjeta de optimizaciones ProxMenux con 14 entradas: punto de color, nombre y versión. Figuran 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 con Legacy, Kernel Panic Configuration, Logrotate Optimization, Network Optimizations, Subscription Banner Removal y VFIO IOMMU Passthrough.",
"imageCaption": "Cada optimización aparece con nombre, versión y punto de color. Arriba a la derecha hay un contador naranja <em>14 activas</em>. Las herramientas con código fuente disponible se pueden abrir.",
"dotsTitle": "Qué significan los puntos",
"dotsItems": [
"<green/> <strong>Punto verde</strong> — optimización actual, registrada por la versión activa de ProxMenux. El código fuente es alcanzable: pulsa la fila para abrirlo.",
"<amber/> <strong>Punto ámbar + insignia <em>legacy</em></strong> — aplicada por una versión más vieja de ProxMenux cuyo script ha sido renombrado o reemplazado desde entonces. Sigue activa en el host; el source abre en modo \"legacy\" (con un acento ámbar) para que puedas auditar qué se ejecutó realmente."
"<green/> <strong>Punto verde</strong>: optimización registrada sin marca Legacy ni actualización indicada. Pulsa la fila si tiene código fuente disponible.",
"<amber/> <strong>Punto ámbar e insignia <em>legacy</em></strong>: optimización registrada cuyo script cambió de nombre o fue sustituido. Abre su código conservado en modo Legacy con detalles ámbar. No comprueba de nuevo la configuración actual del host."
],
"clickTitle": "Acceso al código fuente",
"clickBody": "Pulsar una herramienta abre una modal con la función bash exacta que aplicó el cambio, más la ruta del archivo de script en el que vive (<code>auto_post_install.sh</code> para el bundle Automated, <code>customizable_post_install.sh</code> para el lado à la carte). Los comentarios y constructos de shell tienen syntax highlighting; un botón Copy pone el source en tu portapapeles. Esta es la superficie \"muestra tu trabajo\" — verifica lo que ProxMenux le hizo a tu host antes de cualquier cambio manual que añadas encima.",
"detailAlt": "Modal de código fuente de herramienta para APT IPv4 Force mostrando la función bash force_apt_ipv4 desde customizable_post_install.sh versión 1.0 con código resaltado que configura /etc/apt/apt.conf.d/99-force-ipv4 con Acquire ForceIPv4 true, registra la herramienta y emite un mensaje translate APT IPv4 configuration completed",
"detailCaption": "Modal de source para <em>APT IPv4 Force</em> — función <code>force_apt_ipv4()</code> exacta de <code>customizable_post_install.sh v1.0</code>, con syntax highlighting y un Copy de un clic.",
"clickTitle": "Abrir el código fuente",
"clickBody": "Pulsar una herramienta abre su función bash asociada y el nombre del script (<code>auto_post_install.sh</code> o <code>customizable_post_install.sh</code>). Para herramientas actuales se extrae del archivo del host; las antiguas pueden usar código conservado. Hay resaltado de sintaxis y Copiar. No garantiza una copia del código exacto ejecutado al instalar.",
"detailAlt": "Ventana de código de APT IPv4 Force con la función bash force_apt_ipv4 de customizable_post_install.sh versión 1.0. El código resaltado configura /etc/apt/apt.conf.d/99-force-ipv4 con Acquire ForceIPv4 true, registra la herramienta y muestra un mensaje traducido de configuración APT IPv4 completada.",
"detailCaption": "Código de <em>APT IPv4 Force</em>: función <code>force_apt_ipv4()</code> de <code>customizable_post_install.sh v1.0</code>, con resaltado de sintaxis y copia con un clic.",
"whyTitle": "Por qué importa esto",
"whyBody": "ProxMenux cambia cosas en tu host: parámetros de kernel, configuración de repositorios, bits de red, rotación de logs, passthrough de GPU, etc. Saber exactamente qué está activo es esencial antes de empezar a añadir customización manual encima — y aún más si un admin distinto opera el host del que lo montó. Esta tarjeta es el registro auditable de cada optimización actualmente en efecto, con el código exacto que la produjo.",
"updatesTitle": "Banner Updates available",
"updatesBody": "Cuando una optimización post-instalación tiene en disco una versión más nueva que la actualmente registrada en el host, la tarjeta muestra un banner \"Updates available\" arriba con el recuento y un botón <strong>Apply</strong>. Pulsar <strong>Apply</strong> abre un selector por optimización (el mismo disponible desde la entrada <em>Apply available updates</em> del menú Post-Install). Elige qué optimizaciones aplicar; ProxMenux relanza la función correspondiente y refresca la versión en el registro. Cuando todo está al día, el banner desaparece.",
"updatesAlt": "Tarjeta ProxMenux Optimizations con un banner Updates available arriba — recuento de updates pendientes más un botón Apply que abre el selector por optimización",
"updatesCaption": "El banner solo se renderiza cuando al menos una optimización tiene una versión más nueva en disco. Mira <link>Apply Available Updates</link> para el flujo completo de update y el equivalente Path-A en el menú de la shell.",
"revertTitle": "Revertir una optimización",
"revertBody": "La tarjeta es de solo lectura — para deshacer una optimización, ejecuta la opción correspondiente <link>Uninstall Optimizations</link> del menú ProxMenux Scripts. El paso de desinstalación elimina la entrada de <code>installed_tools.json</code>, así que desaparece de esta tarjeta en el siguiente refresco."
"whyBody": "ProxMenux puede cambiar parámetros del kernel, repositorios, red, rotación de registros y passthrough de GPU. Revisa las optimizaciones registradas antes de añadir cambios manuales, sobre todo si otro administrador preparó el host. La tarjeta muestra el registro y el código disponible; no audita todos los ajustes actuales ni conserva un historial exacto de ejecución.",
"updatesTitle": "Aviso de actualizaciones disponibles",
"updatesBody": "Si la versión de una optimización disponible en disco supera la registrada en el host, aparece un aviso con el total y <strong>Aplicar</strong>. <strong>Aplicar</strong> abre un selector de optimizaciones, como <em>Aplicar actualizaciones disponibles</em> del menú posterior a la instalación. Elige cuáles actualizar: ProxMenux vuelve a ejecutar sus funciones y actualiza el registro. El aviso desaparece cuando no quedan versiones pendientes.",
"updatesAlt": "Tarjeta de optimizaciones ProxMenux con aviso de actualizaciones disponibles, número pendiente y botón Aplicar para seleccionar optimizaciones",
"updatesCaption": "El aviso aparece si al menos una optimización tiene una versión más reciente en disco. Consulta <link>Aplicar actualizaciones disponibles</link> para el proceso completo y la opción equivalente Path-A del menú de consola.",
"revertTitle": "Deshacer una optimización",
"revertBody": "Para deshacer una optimización, usa la opción correspondiente de <link>Desinstalar optimizaciones</link> en ProxMenux Scripts. Al desinstalar se elimina su entrada de <code>installed_tools.json</code> y desaparece de la tarjeta en el siguiente refresco."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -285,22 +285,22 @@
{
"card": "Idioma de la interfaz",
"endpoint": "localStorage",
"source": "Preferencia del navegador <code>proxmenux-ui-language</code>, obtenida inicialmente del idioma del navegador cuando todavía no existe una selección guardada."
"source": "Preferencia <code>proxmenux-ui-language</code> del navegador; inicialmente usa su idioma si no hay una elección guardada."
},
{
"card": "Orden de navegación",
"endpoint": "localStorage",
"source": "Preferencia del navegador <code>proxmenux-nav-order</code>; también determina la pestaña inicial."
"source": "Preferencia <code>proxmenux-nav-order</code> del navegador; también determina la pestaña inicial."
},
{
"card": "Network Units",
"card": "Unidades de red",
"endpoint": "/api/settings",
"source": "Persistido en la tabla SQLite de settings del panel."
"source": "Guardado en la tabla de ajustes SQLite del panel."
},
{
"card": "Duraciones del Monitor de salud",
"card": "Duraciones de Health Monitor",
"endpoint": "/api/health/settings",
"source": "Duraciones de supresión por categoría en la DB de Health."
"source": "Duración de silenciamiento por categoría en la base de datos de Health Monitor."
},
{
"card": "Exclusiones de almacenamiento / interfaz",
@@ -310,17 +310,17 @@
{
"card": "Panel Notificaciones e IA",
"endpoint": "/api/notifications/*",
"source": "Mira las páginas dedicadas <notifLink>Notificaciones</notifLink> / <aiLink>Asistente de IA</aiLink>."
"source": "Consulta <notifLink>Notificaciones</notifLink> y <aiLink>Asistente de IA</aiLink>."
},
{
"card": "Lista ProxMenux Optimizations",
"card": "Lista de optimizaciones ProxMenux",
"endpoint": "/api/proxmenux/installed-tools",
"source": "Lee <code>/usr/local/share/proxmenux/installed_tools.json</code>, escrito por llamadas <code>register_tool</code> dentro de los scripts post-instalación."
"source": "Lee <code>/usr/local/share/proxmenux/installed_tools.json</code>, escrito mediante llamadas a <code>register_tool</code> en los scripts posteriores a la instalación."
},
{
"card": "Modal de código fuente de optimización",
"card": "Ventana de código de optimización",
"endpoint": "/api/proxmenux/tool-source",
"source": "Extrae la función bash correspondiente de <code>auto_post_install.sh</code> o <code>customizable_post_install.sh</code> en el host."
"source": "Extrae la función bash asociada de <code>auto_post_install.sh</code> o <code>customizable_post_install.sh</code> del host; las antiguas pueden usar código conservado."
}
]
},
@@ -330,37 +330,37 @@
{
"label": "Pestaña Apps",
"href": "/docs/monitor/dashboard/apps",
"tail": " — el lanzador cuya posición se puede cambiar desde Orden de navegación."
"tail": " — el lanzador cuya posición se cambia con Orden de navegación."
},
{
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tail": " — canales, toggles por evento, overrides de canal, historial, test-send."
"tail": " — canales, controles por evento, ajustes particulares por canal, historial y envíos de prueba."
},
{
"label": "Asistente de IA",
"href": "/docs/monitor/ai-assistant",
"tail": " — proveedores, modelos, modos de prompt, idiomas, niveles de detalle por canal."
"tail": " — proveedores, modelos, modos de instrucciones, idiomas y detalle por canal."
},
{
"label": "Monitor de salud → Descartar alertas y la Suppression Duration",
"label": "Health Monitor → Descartar alertas y duración del silenciamiento",
"href": "/docs/monitor/health-monitor#dismissing-alerts-and-the-suppression-duration",
"tail": " — la semántica detrás de los desplegables por categoría de arriba."
"tail": " — cómo funcionan los desplegables de duración por categoría."
},
{
"label": "ProxMenux Scripts → Automated post-install",
"label": "ProxMenux Scripts → Ajustes posteriores a la instalación automatizados",
"href": "/docs/post-install/automated",
"tailRich": " y <customLink>Customizable post-install</customLink> — los scripts reales que se registran en la lista de optimizaciones de arriba."
"tailRich": " y <customLink>Ajustes posteriores a la instalación personalizables</customLink>: los scripts que registran las optimizaciones en la lista anterior."
},
{
"label": "Uninstall Optimizations",
"label": "Desinstalar optimizaciones",
"href": "/docs/post-install/uninstall",
"tail": " — cómo revertir una optimización registrada arriba."
"tail": " — cómo deshacer una optimización de la lista anterior."
},
{
"label": "Índice del panel",
"href": "/docs/monitor/dashboard",
"tail": " — volver al resumen de la pestaña."
"tail": " — volver al resumen de pestañas."
}
]
}
@@ -1,193 +1,193 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Almacenamiento | ProxMenux Documentation",
"description": "La pestaña Almacenamiento consolida cuatro vistas: almacenamientos gestionados por Proxmox con su estado, pools ZFS, discos físicos internos con datos SMART y unidades externas (USB). La vista en detalle de cada disco expone atributos SMART, desgaste y vida útil y el historial permanente de observaciones."
"title": "ProxMenux Monitor — Panel: pestaña Almacenamiento | Documentación de ProxMenux",
"description": "La pestaña Almacenamiento reúne cuatro vistas: almacenamientos Proxmox con su estado, pools ZFS, discos internos con SMART y unidades USB externas. El detalle de cada disco muestra atributos SMART, desgaste, vida útil e historial permanente de observaciones."
},
"header": {
"title": "Panel: pestaña Almacenamiento",
"description": "El estado de almacenamiento del host en una pantalla — pools de Proxmox (NFS / CIFS / LVM / ZFS / dir), salud de pools ZFS, discos internos SATA / NVMe con SMART y unidades USB externas. Pulsa cualquier disco para abrir una vista en detalle con la tabla completa de atributos SMART y el historial de observaciones por disco.",
"description": "Todo el almacenamiento del host en una pantalla: NFS / CIFS / LVM / ZFS / dir de Proxmox, estado de pools ZFS, discos internos SATA/NVMe con SMART y unidades USB externas. Pulsa un disco para abrir sus atributos SMART y su historial de observaciones.",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "Respaldado por tres fuentes",
"body": "Los almacenamientos Proxmox vienen de <code>pvesm status</code>; el estado ZFS de <code>zpool status</code>; los discos físicos de <code>lsblk</code> + <code>smartctl</code> (y <code>nvme</code> para campos específicos de NVMe). La pestaña refresca cada ~60 segundos; la vista en detalle por disco dispara una lectura SMART fresca bajo demanda."
"body": "Los almacenamientos Proxmox proceden de <code>pvesm status</code>; ZFS, de <code>zpool status</code>; los discos físicos, de <code>lsblk</code> + <code>smartctl</code>, y <code>nvme</code> para campos específicos. La pestaña se actualiza aproximadamente cada 60 segundos; abrir el detalle solicita una lectura SMART."
},
"thresholds": {
"title": "Colores de estado y umbrales aplicados aquí",
"intro": "Cada barra, chip y punto de esta pestaña sigue la misma clasificación de tres estados — <green/> <strong>verde</strong> por debajo de Warning, <amber/> <strong>ámbar</strong> entre Warning y Critical, <red/> <strong>rojo</strong> en Critical y por encima. Valores por defecto recomendados que vienen con ProxMenux:",
"intro": "Health Monitor clasifica el estado como <green/> <strong>verde</strong> por debajo de Aviso, <amber/> <strong>ámbar</strong> entre Aviso y Crítico y <red/> <strong>rojo</strong> desde Crítico. Sus valores predeterminados se indican a continuación. Las barras del panel pueden usar otros límites visuales, descritos más abajo.",
"items": [
"<strong>Capacidad</strong> (discos del host, almacenamientos PVE, pools ZFS, mounts de LXC) — Warning 85 %, Critical 95 %.",
"<strong>Capacidad</strong> (discos del host, almacenamientos PVE, pools ZFS y montajes LXC): aviso 85 %, crítico 95 %.",
"<strong>Temperatura de disco</strong> — HDD 60/65 °C · SSD 70/75 °C · NVMe 80/85 °C · SAS 55/65 °C (warning / critical)."
],
"outro": "Cada valor es configurable por host — <link>Settings → Health Monitor Thresholds</link> es la fuente única de verdad y explica cómo ajustarlos."
"outro": "Puedes configurar cada valor por host. <link>Ajustes → Umbrales de Health Monitor</link> recoge los valores y explica cómo ajustarlos."
},
"topRow": {
"heading": "Fila superior: almacenamiento de un vistazo",
"intro": "Al abrir la pestaña Almacenamiento aterrizas en un resumen de cuatro tarjetas del estado de almacenamiento del host — capacidad total, qué se está usando localmente, qué se está usando en almacenamientos remotos y el inventario de discos físicos. Cada tarjeta es una respuesta de una línea a una pregunta común; las tarjetas debajo de la fila son donde profundizas en el detalle.",
"imageAlt": "Pestaña Almacenamiento — fila superior de cuatro tarjetas de estadísticas: Total Storage, Local Used, Remote Used, Physical Disks",
"imageCaption": "Fila superior de la pestaña Almacenamiento — capacidad total y recuento de discos, bytes usados separados en almacenamientos locales vs remotos y un desglose por tipo de discos físicos con su resumen de salud.",
"heading": "Fila superior: resumen del almacenamiento",
"intro": "Al abrir Almacenamiento, cuatro tarjetas resumen capacidad total, uso local, uso remoto e inventario de discos físicos. Ofrecen respuestas rápidas; las tarjetas inferiores contienen los detalles.",
"imageAlt": "Pestaña Almacenamiento, con cuatro tarjetas: capacidad total, uso local, uso remoto y discos físicos",
"imageCaption": "Fila superior: capacidad total y número de discos, bytes usados localmente y en remoto y desglose de discos físicos por tipo con resumen de estado.",
"headerCard": "Tarjeta",
"headerWhat": "Qué muestra",
"totalLabel": "Total Storage",
"totalWhat": "Capacidad bruta combinada de todos los discos físicos. La línea al pie muestra el recuento de discos físicos descubiertos.",
"localLabel": "Local Used",
"localWhat": "Bytes usados en almacenamientos locales (LVM / LVM-thin / ZFS / dir en los discos del propio host). Muestra los bytes usados de forma prominente, con una línea al pie <em>X.XX % de Y TB</em> para que veas el porcentaje de llenado al mismo tiempo.",
"remoteLabel": "Remote Used",
"remoteWhat": "La misma forma que Local Used pero para almacenamientos remotos (NFS / CIFS / PBS / Ceph / iSCSI). Se cuentan por separado porque las caídas remotas no afectan a los datos locales y normalmente los dimensionas y monitorizas de forma diferente.",
"disksLabel": "Physical Disks",
"totalLabel": "Almacenamiento total",
"totalWhat": "Capacidad bruta total de todos los discos físicos. El pie indica cuántos discos se han detectado.",
"localLabel": "Local usado",
"localWhat": "Bytes usados en almacenamientos locales: LVM / LVM-thin / ZFS / dir en los discos del host. El valor principal indica los bytes usados y el pie <em>X.XX % de Y TB</em> muestra también el porcentaje de ocupación.",
"remoteLabel": "Uso remoto",
"remoteWhat": "El mismo formato que Uso local, para almacenamientos remotos NFS / CIFS / PBS / Ceph / iSCSI. Se cuentan por separado porque los fallos remotos y locales tienen un alcance distinto y estos recursos suelen dimensionarse y supervisarse de forma diferente.",
"disksLabel": "Discos físicos",
"disksIntro": "Dos líneas de desglose para el inventario:",
"disksItems": [
"<strong>Por tipo</strong> — recuentos de NVMe (morado), SSD (azul) y HDD (azul) descubiertos. Los hosts con discos mixtos reciben los tres; un host todo-NVMe muestra solo el recuento NVMe.",
"<strong>Por salud</strong> — recuentos de discos <em>normal</em> (verde), <em>warning</em> (amarillo) y <em>critical</em> (rojo). El estado sano normalmente muestra solo \"X normal\"; warnings y critical aparecen solo cuando algo escala."
"<strong>Por tipo</strong>: número de NVMe en morado y de SSD y HDD en azul. Se muestran los tipos detectados; un host solo con NVMe muestra únicamente ese recuento.",
"<strong>Por estado</strong>: número de discos <em>normales</em> en verde, con <em>aviso</em> en amarillo y <em>críticos</em> en rojo. Sin problemas, solo aparece «X normales»; los otros estados aparecen cuando hay incidencias."
]
},
"pveStorage": {
"heading": "Tarjeta Proxmox Storage",
"intro": "Una fila por almacenamiento configurado en <code>/etc/pve/storage.cfg</code>. Cada fila muestra la insignia de tipo (<code>nfs</code> / <code>cifs</code> / <code>zfspool</code> / <code>lvm</code> / <code>lvmthin</code> / <code>dir</code> / <code>pbs</code>), el nombre del almacenamiento, una insignia active / error / not-monitored, el porcentaje de uso y una barra de progreso coloreada:",
"intro": "Una fila por almacenamiento de <code>/etc/pve/storage.cfg</code>, con tipo (<code>nfs</code> / <code>cifs</code> / <code>zfspool</code> / <code>lvm</code> / <code>lvmthin</code> / <code>dir</code> / <code>pbs</code>), nombre, estado activo/error/no supervisado, porcentaje de uso y barra de color:",
"items": [
"<strong>&lt; 75 %</strong> — barra de progreso azul, valor en azul.",
"<strong>75 – 90 %</strong> — barra de progreso amarilla, valor en amarillo (el Monitor de salud avisa en este punto).",
"<strong>> 90 %</strong> — barra de progreso roja, valor en rojo (el Monitor de salud escala).",
"<strong>error</strong> — fila entera con borde rojo, se usa cuando el almacenamiento está configurado pero inalcanzable (servidor NFS caído, credenciales CIFS caducadas).",
"<strong>excluded</strong> — borde morado + la insignia \"not monitored\". Almacenamientos excluidos explícitamente por el usuario de los chequeos de salud (cómodo para volúmenes manuales / de archivo que están intencionadamente offline)."
"<strong>Hasta el 75 %</strong>: barra y valor azules.",
"<strong>Más del 75 % y hasta el 90 %</strong>: barra y valor amarillos. Son límites visuales distintos de los umbrales de Health Monitor.",
"<strong>> 90 %</strong>: barra y valor rojos. Este límite visual es distinto del escalado de Health Monitor.",
"<strong>Error</strong>: borde rojo en toda la fila cuando el almacenamiento está configurado pero no es accesible, por ejemplo por caída de NFS o credenciales CIFS caducadas.",
"<strong>Excluido</strong>: borde morado y etiqueta «no supervisado». Almacenamientos que has excluido de las comprobaciones, como volúmenes de archivo que mantienes desconectados."
],
"calloutTitle": "Excluir un almacenamiento ruidoso",
"calloutBody": "Desde la fila del almacenamiento, el menú por almacenamiento te permite marcarlo como <em>excluded from monitoring</em>. El flag se guarda en la tabla <code>excluded_storages</code> y lo respetan tanto la vista del panel como el ciclo del Monitor de salud — no se disparan notificaciones para almacenamientos excluidos, y no empujan la pastilla de la cabecera."
"calloutTitle": "Excluir un almacenamiento de la supervisión",
"calloutBody": "El menú de cada almacenamiento permite marcarlo como <em>excluido de la supervisión</em>. Se guarda en <code>excluded_storages</code> y lo respetan el panel y Health Monitor: no genera notificaciones ni afecta al indicador general."
},
"zfs": {
"heading": "Tarjeta ZFS Pools",
"intro": "Se renderiza solo cuando ZFS está instalado y existe al menos un pool. Una fila por pool con una insignia de salud, size / allocated / free y un icono que refleja el estado de salud:",
"intro": "Solo aparece si ZFS está instalado y existe al menos un pool. Cada fila muestra un pool con estado, tamaño, espacio asignado y libre e icono de estado:",
"items": [
"<strong>ONLINE</strong> — verde. Todo sano.",
"<strong>DEGRADED</strong> — amarillo. El pool sigue sirviendo datos pero al menos un dispositivo no está disponible; arranca la ventana de reemplazo.",
"<strong>FAULTED</strong> / <strong>UNAVAIL</strong> / <strong>SUSPENDED</strong> — rojo. El pool no sirve datos; se requiere intervención inmediata."
"<strong>DEGRADED</strong>: amarillo. El pool sirve datos, pero al menos un dispositivo no está disponible; hay que gestionar su sustitución.",
"<strong>FAULTED</strong> / <strong>UNAVAIL</strong> / <strong>SUSPENDED</strong>: rojo. El pool no sirve datos y requiere intervención inmediata."
],
"outro": "Tanto el estado ZFS como el estado SMART por disco alimentan la categoría <em>Disks & I/O</em> del <link>Monitor de salud</link>."
"outro": "El estado ZFS y SMART de cada disco contribuyen a la categoría <em>Discos y E/S</em> de <link>Health Monitor</link>."
},
"physical": {
"heading": "Physical Disks & SMART Status",
"heading": "Discos físicos y estado SMART",
"intro": "Discos internos (SATA / NVMe). Cada fila condensa los campos más útiles de un vistazo:",
"items": [
"<strong>Ruta del dispositivo</strong> — <code>/dev/sda</code>, <code>/dev/nvme0n1</code>.",
"<strong>Insignia de tipo</strong> — SATA / NVMe (y el icono correspondiente).",
"<strong>Insignia System</strong> — etiqueta naranja que marca los discos desde los que se está ejecutando el SO del host. El panel lo deriva de los mountpoints de <code>/</code> y <code>/boot</code>: cualquier disco físico que los aloje recibe la etiqueta <em>System</em> para que no lo borres o reasignes por accidente. Los discos sin la etiqueta son unidades puras de datos.",
"<strong>Modelo</strong> — vendor + cadena del modelo de <code>smartctl -i</code>.",
"<strong>Capacidad</strong> — formateada de forma legible.",
"<strong>Temperatura</strong> — °C actuales, coloreada por el umbral de tipo de disco (NVMe corre más caliente que SATA).",
"<strong>Estado SMART</strong> — passed / failed / unknown.",
"<strong>Insignia de observaciones</strong> — cuando el historial permanente <code>disk_observations</code> tiene entradas para este disco, aparece una insignia azul con el recuento (p. ej. <em>3 obs.</em>). Pulsa el disco para entrar y revisarlas.",
"<strong>Insignia de salud</strong> — Healthy / Warning / Critical, derivada del chequeo SMART + observaciones recientes."
"<strong>Etiqueta de tipo</strong>: SATA / NVMe y su icono.",
"<strong>Etiqueta de sistema</strong>: marca naranja para los discos en uso por el host: montajes del sistema (<code>/</code>, <code>/boot</code>, <code>/usr</code>, <code>/var</code>…), swap activa, miembros de pools ZFS, volúmenes físicos LVM, miembros de RAID activos o etiquetas de partición del sistema. La ausencia de etiqueta no demuestra que se puedan borrar o reutilizar sin riesgo.",
"<strong>Modelo</strong>: fabricante y modelo de <code>smartctl -i</code>.",
"<strong>Capacidad</strong>: expresada en unidades legibles.",
"<strong>Temperatura</strong>: °C actuales, con color según el umbral del tipo de disco; NVMe admite umbrales más altos que SATA.",
"<strong>Estado SMART</strong>: correcto / fallido / desconocido.",
"<strong>Etiqueta de observaciones</strong>: si el historial permanente <code>disk_observations</code> contiene entradas del disco, aparece una etiqueta azul con el número, como <em>3 obs.</em>. Pulsa el disco para revisarlas.",
"<strong>Etiqueta de estado</strong>: Correcto / Aviso / Crítico, según SMART y las observaciones recientes."
],
"clickHint": "La fila entera es pulsable y abre la vista en detalle por disco descrita abajo.",
"warningTitle": "No toques los discos con etiqueta System a la ligera",
"warningBody": "Los discos con la insignia naranja <strong>System</strong> alojan el SO en ejecución. El panel expone la etiqueta como guardarraíl — las acciones destructivas lanzadas desde <link>ProxMenux → Disk Manager → Format / Wipe</link> se niegan explícitamente a actuar sobre ellos. Si de verdad necesitas reasignar el disco de arranque, hazlo desde un entorno de rescate, no desde dentro de Proxmox."
"clickHint": "Toda la fila se puede pulsar para abrir el detalle del disco descrito más abajo.",
"warningTitle": "Cuidado con los discos etiquetados como System",
"warningBody": "Los discos con etiqueta naranja <strong>System</strong> alojan el SO activo. La etiqueta ayuda a identificarlos; <link>ProxMenux → Gestor de discos → Formatear / Borrar</link> rechaza las acciones destructivas sobre ellos. Para reutilizar un disco de arranque, usa un entorno de rescate externo al Proxmox en ejecución."
},
"external": {
"heading": "External Storage (USB)",
"body": "Una tarjeta separada para unidades conectadas por USB, solo se renderiza cuando hay al menos una presente. Los mismos campos que los discos internos más una etiqueta naranja <strong>USB</strong>. Las unidades USB suelen aparecer y desaparecer (backups en frío, jobs ocasionales de descarga), así que el Monitor de salud es conservador con ellas — las observaciones se retienen, pero los errores de E/S en una unidad USB desconectada no escalan."
"heading": "Almacenamiento externo (USB)",
"body": "Las unidades USB tienen una tarjeta propia, visible cuando hay alguna conectada. Muestra los mismos campos que los discos internos y una etiqueta naranja <strong>USB</strong>. Como suelen conectarse solo para backups o transferencias ocasionales, se conservan sus observaciones, pero los errores de E/S de una unidad USB desconectada no se escalan."
},
"drillIn": {
"heading": "Modal de vista en detalle de disco",
"intro": "Pulsar cualquier fila de disco abre una modal con cuatro pestañas: <strong>Overview</strong> · <strong>SMART</strong> · <strong>History</strong> · <strong>Schedule</strong>. La cabecera siempre muestra la ruta del dispositivo, el modelo + capacidad y la insignia naranja <em>System</em> si aplica.",
"overviewTitle": "Pestaña 1 — Overview",
"overviewImageAlt": "Modal de vista en detalle de disco — pestaña Overview con estado de salud, anillo Wear & Lifetime y atributos SMART rápidos",
"overviewImageCaption": "Pestaña Overview — identidad, insignia de salud, anillo de vida restante con el desgaste actual y los datos escritos, además de un bloque rápido con los atributos SMART más vigilados.",
"overviewIntro": "La pestaña por defecto al entrar — todo lo que necesitas para responder \"¿este disco está bien?\" sin lanzar un test. Tres bloques:",
"heading": "Diálogo de detalle del disco",
"intro": "Pulsa un disco para abrir cuatro pestañas: <strong>Resumen</strong> · <strong>SMART</strong> · <strong>Historial</strong> · <strong>Programación</strong>. La cabecera muestra ruta, modelo, capacidad y, si corresponde, la etiqueta naranja <em>System</em>.",
"overviewTitle": "Pestaña 1 — Resumen",
"overviewImageAlt": "Detalle de disco, pestaña Resumen con estado, indicador circular de desgaste y vida útil y atributos SMART principales",
"overviewImageCaption": "Resumen: identificación, estado, vida restante con desgaste actual y datos escritos, y atributos SMART principales.",
"overviewIntro": "Pestaña inicial para consultar el estado del disco sin ejecutar una prueba. Tiene tres bloques:",
"overviewItems": [
"<strong>Identity</strong> — modelo, serial, capacidad, insignia Health (Healthy / Warning / Critical).",
"<strong>Wear & Lifetime</strong> — anillo grande de vida restante (97 %, 50 %, …) con el atributo de origen explícito (<em>Media Wearout Indicator</em>, <em>Percentage Used</em>, …), una barra de desgaste (% de consumo actual), una proyección <em>Est. Life</em> en años y los Data Written totales. Los discos NVMe también muestran <em>Available Spare</em>.",
"<strong>SMART Attributes</strong> — seis campos titulares en una rejilla de 2 columnas: Temperature, Power On Hours (con duración humanizada como <em>3y 116d</em>), Rotation Rate (o <em>SSD</em>), Power Cycles, SMART Status, Reallocated Sectors, Pending Sectors, CRC Errors. La tabla de atributos completa vive en la pestaña SMART."
"<strong>Identificación</strong>: modelo, número de serie, capacidad y estado Correcto / Aviso / Crítico.",
"<strong>Desgaste y vida útil</strong>: indicador circular de vida restante (97 %, 50 %, …) con atributo de origen (<em>Media Wearout Indicator</em>, <em>Percentage Used</em>, …), barra del porcentaje consumido, proyección <em>Vida estimada</em> en años y total de datos escritos. NVMe también muestra <em>Available Spare</em>.",
"<strong>Atributos SMART</strong>: los datos principales se muestran en dos columnas: temperatura, horas de encendido (con una duración legible, como <em>3 años y 116 días</em>), velocidad de rotación (o <em>SSD</em>), ciclos de encendido, estado SMART, sectores reasignados, sectores pendientes y errores CRC. La tabla completa de atributos se encuentra en la pestaña SMART."
],
"smartTitle": "Pestaña 2 — SMART",
"smartImageAlt": "Modal de vista en detalle de disco — pestaña SMART con botones Run SMART Test (Short / Extended), resultado del último test y la tabla completa de atributos SMART",
"smartImageCaption": "Pestaña SMART — lanza un test Short o Extended, mira el resultado del último test, scrollea la tabla completa de atributos SMART y genera el informe PDF completo de salud.",
"smartIntro": "Donde viven las acciones. Tres secciones:",
"smartImageAlt": "Detalle del disco, pestaña SMART con pruebas corta y extendida, resultado anterior y tabla completa de atributos",
"smartImageCaption": "Pestaña SMART: ejecuta pruebas cortas o extendidas, consulta el último resultado, revisa todos los atributos y abre el informe completo para imprimirlo o guardarlo como PDF.",
"smartIntro": "Acciones disponibles, en tres secciones:",
"smartItems": [
"<strong>Run SMART Test</strong> — dos botones. <em>Short Test (~2 min)</em> corre síncrono y muestra el resultado inline. <em>Extended Test (background)</em> puede tardar horas en discos grandes, corre en el servidor y dispara una notificación cuando termina.",
"<strong>Last Test</strong> — tipo, insignia de estado (<em>passed</em> / <em>failed</em>) y timestamp de la ejecución más reciente.",
"<strong>SMART Attributes</strong> — la tabla completa de atributos (ID / nombre / valor / worst / estado con iconos OK / warning / critical). Para SATA / SAS, la lista numerada clásica. Para NVMe, los campos estructurados de <code>nvme smart-log</code> (temperatura, available spare, percentage used, data units written / read, host reads / writes, controller busy time, power cycles, unsafe shutdowns, media errors, error-log entries, warning / critical composite temperature time)."
"<strong>Ejecutar prueba SMART</strong>: dos botones. <em>Prueba corta (~2 min)</em> espera al resultado y lo muestra en el diálogo. <em>Prueba extendida (segundo plano)</em> puede tardar horas en discos grandes, continúa en el servidor y avisa al terminar.",
"<strong>Última prueba</strong>: tipo, estado (<em>correcta</em> / <em>fallida</em>) y fecha y hora de la última ejecución.",
"<strong>Atributos SMART</strong>: tabla completa con ID, nombre, valor, peor valor y estado correcto, aviso o crítico. SATA/SAS muestra la lista numerada. NVMe usa <code>nvme smart-log</code>: temperatura, reserva disponible, porcentaje usado, unidades leídas/escritas, lecturas/escrituras del host, tiempo ocupado del controlador, ciclos de encendido, apagados inseguros, errores del medio, entradas del registro de errores y tiempo con temperatura compuesta en aviso/crítico."
],
"pdfTitle": "View Full SMART Report (PDF)",
"pdfIntro": "Al pie de la pestaña SMART, el botón <strong>View Full SMART Report</strong> genera un PDF imprimible y listo para archivo — el mismo informe estructurado que enviarías a un fabricante para un RMA.",
"pdfPreviewAlt": "Primera página del PDF SMART Health Report generado — Executive Summary con el anillo PASSED + bloque Disk Information",
"pdfPreviewCaption": "Primera página del SMART Health Report — Executive Summary con el anillo PASSED y el bloque Disk Information completo. El PDF completo de abajo lleva el anillo de desgaste SSD, cada atributo SMART y el historial de tests.",
"pdfTitle": "Ver informe SMART completo (PDF)",
"pdfIntro": "Al pie de SMART, <strong>Ver informe SMART completo</strong> abre un informe imprimible. Usa el diálogo de impresión del navegador para guardarlo como PDF, archivarlo o compartirlo con el fabricante en un RMA.",
"pdfPreviewAlt": "Primera página del informe SMART: resumen ejecutivo con indicador PASSED e información del disco",
"pdfPreviewCaption": "Primera página: resumen, indicador PASSED e información completa del disco. El PDF de ejemplo incluye desgaste SSD, todos los atributos SMART e historial de pruebas.",
"pdfDownloadLabel": "Descargar informe SMART de ejemplo (PDF)",
"pdfSectionsIntro": "El informe tiene cinco secciones de alto nivel:",
"pdfSectionsIntro": "El informe incluye estas secciones principales:",
"pdfSections": [
"<strong>Executive Summary</strong> — gran veredicto PASSED / FAILED, párrafo de evaluación de salud del disco en lenguaje claro (\"tu disco está sano / muestra signos de desgaste / está fallando\") y cuatro estadísticas rápidas (timestamp del informe, tipo del último test, resultado del test, atributos comprobados).",
"<strong>Disk Information</strong> — modelo, serial, capacidad, tipo (HDD / SSD / NVMe), familia, form factor, interfaz (SATA 3.3 · 6.0 Gb/s, …), soporte de TRIM, temperatura actual con el umbral óptimo, tiempo de power-on, ciclos de encendido, estado SMART, además de los contadores titulares (pending sectors, CRC errors, reallocated sectors).",
"<strong>SSD Wear & Lifetime</strong> (solo SSD / NVMe) — anillo de vida restante, atributo de origen, nivel actual de desgaste, datos escritos, horas de power-on.",
"<strong>SMART Attributes (full)</strong> — cada atributo que reporta el drive, con ID, nombre, valor, worst, threshold, valor raw y una pastilla de estado. Los más relevantes para el usuario (Reallocated Sector Ct, Power On Hours, Reported Uncorrect, UDMA CRC Error Count, Media Wearout Indicator, …) incluyen una explicación de una línea en lenguaje claro bajo la fila.",
"<strong>Last Self-Test Result + Full Self-Test History</strong> — el último test (tipo, resultado, mensaje de finalización, en qué marca de power-on-hours) más una tabla numerada de cada test retenido.",
"<strong>Recommendations</strong> — items de acción basados en el veredicto: <em>Disk is Healthy / Schedule periodic tests / Backup strategy</em> para discos sanos, lenguaje en escalada con guía de reemplazo cuando los atributos se salen de rango."
"<strong>Resumen ejecutivo</strong>: estado PASSED/FAILED, evaluación clara del disco —correcto, con desgaste o fallando— y cuatro datos: fecha del informe, tipo de última prueba, resultado y atributos comprobados.",
"<strong>Información del disco</strong>: modelo, serie, capacidad, tipo HDD/SSD/NVMe, familia, formato, interfaz (SATA 3.3 · 6.0 Gb/s, …), TRIM, temperatura y umbral óptimo, horas y ciclos de encendido, SMART, sectores pendientes y reasignados y errores CRC.",
"<strong>Desgaste y vida útil SSD</strong> (solo SSD/NVMe): indicador de vida restante, atributo de origen, desgaste actual, datos escritos y horas de encendido.",
"<strong>Atributos SMART completos</strong>: ID, nombre, valor, peor valor, umbral, valor bruto y estado de cada atributo. Los principales —Reallocated Sector Ct, Power On Hours, Reported Uncorrect, UDMA CRC Error Count, Media Wearout Indicator, …— incluyen una explicación breve bajo su fila.",
"<strong>Última autoprueba e historial completo</strong>: última prueba con tipo, resultado, mensaje final y horas de encendido en ese momento, más una tabla numerada de todas las pruebas conservadas.",
"<strong>Recomendaciones</strong>: acciones según el resultado. Para discos correctos: <em>disco sano / pruebas periódicas / estrategia de backups</em>. Si los atributos salen de rango, incluye indicaciones de sustitución."
],
"pdfOutro": "El PDF se produce en el servidor y se descarga con un patrón de nombre estable (<code>SMART-&lt;short-id&gt;.pdf</code>) para que múltiples snapshots a lo largo del tiempo puedan convivir en tu archivo. Útil cuando estás rastreando degradación a lo largo de meses o enviando evidencia al soporte del fabricante.",
"historyTitle": "Pestaña 3 — History",
"historyImageAlt": "Modal de vista en detalle de disco — pestaña History listando tests SMART pasados con acciones de descarga y borrado",
"historyImageCaption": "Pestaña History — cada test SMART retenido para este disco. Por fila: tipo, timestamp, etiqueta \"X days ago\", marca latest, descargar (salida raw de <code>smartctl</code>) y acciones de borrado.",
"historyIntro": "El pool retenido de tests SMART para este disco — tanto las ejecuciones short como extended que se completaron. Cada entrada es la salida raw de <code>smartctl</code> capturada en tiempo de ejecución, más los campos estructurados que el Monitor parseó para el panel. Acciones por fila:",
"pdfOutro": "El navegador crea el informe imprimible; Imprimir y Guardar como PDF abren su diálogo de impresión. Elige un nombre como <code>SMART-&lt;short-id&gt;.pdf</code>. Conserva copias fechadas para comparar cambios o compartirlas con el fabricante.",
"historyTitle": "Pestaña 3 — Historial",
"historyImageAlt": "Detalle del disco, pestaña Historial con pruebas SMART anteriores y acciones de descarga y eliminación",
"historyImageCaption": "Historial de pruebas SMART del disco. Cada fila muestra tipo, fecha y hora, antigüedad, marca de última prueba y acciones de descarga de la salida <code>smartctl</code> y eliminación.",
"historyIntro": "Pruebas cortas y extendidas completadas y conservadas para el disco. Cada entrada guarda la salida original de <code>smartctl</code> y los campos que Monitor interpreta para el panel. Acciones por fila:",
"historyItems": [
"<strong>Download</strong> — guarda la salida raw de <code>smartctl -a</code> como un archivo de texto. Idéntico a lo que parsea el informe PDF, útil cuando necesitas la línea exacta que pide un fabricante.",
"<strong>Delete</strong> — elimina el test del historial. El límite de retención fijado en la pestaña Schedule (<em>Last 5 / 10 / 20</em>) borra el más viejo primero automáticamente; esta acción es la sobreescritura manual."
"<strong>Descargar</strong>: guarda el snapshot JSON de esa prueba (salida de <code>smartctl -a --json</code>, o <code>nvme smart-log</code> en NVMe cuando falla smartctl). Útil si el fabricante necesita los campos de diagnóstico originales.",
"<strong>Eliminar</strong>: borra una prueba del historial manualmente. La retención de Programación (<em>últimas 5 / 10 / 20</em>) elimina automáticamente las más antiguas."
],
"scheduleTitle": "Pestaña 4 — Schedule",
"scheduleImageAlt": "Modal de vista en detalle de disco — pestaña Schedule con el toggle Automatic SMART Tests, la lista de schedules configurados y el botón Add Schedule",
"scheduleImageCaption": "Pestaña Schedule — elige tipo de test, frecuencia y retención; el Monitor lo conecta a <code>cron</code> para que los tests corran sin atención.",
"scheduleIntro": "Tests SMART automáticos guiados por cron, sin shell. La página tiene tres áreas:",
"scheduleTitle": "Pestaña 4 — Programación",
"scheduleImageAlt": "Detalle del disco, pestaña Programación con interruptor de pruebas SMART automáticas, lista de horarios y botón Añadir programación",
"scheduleImageCaption": "Programación: elige tipo, frecuencia y retención; Monitor configura <code>cron</code> para ejecutar las pruebas automáticamente.",
"scheduleIntro": "Pruebas SMART automáticas mediante cron, sin usar la terminal. Tres áreas:",
"scheduleItems": [
"<strong>Toggle Automatic SMART Tests</strong> — interruptor global on/off para cada schedule de este disco. Útil cuando quieres pausar todo durante mantenimiento sin perder las definiciones de schedule.",
"<strong>Configured Schedules</strong> — una fila por schedule existente con la insignia de tipo de test (<em>short</em> / <em>long</em>), la expresión cron en forma humana (<em>\"Day 1 of month at 03:00\"</em>, <em>\"Every Sunday at 02:00\"</em>), los discos que cubre y el ajuste de retención.",
"<strong>Add Schedule / Edit Schedule</strong> — formulario con: Test Type (<em>Short ~2 min</em> / <em>Long 1-4 h</em>), Frequency (<em>Daily / Weekly / Monthly</em>), Day of Month / Day of Week, Time, Keep Results (<em>Last 5 / 10 / 20</em>)."
"<strong>Pruebas SMART automáticas</strong>: interruptor general de todos los horarios del disco. Permite pausarlos durante el mantenimiento sin borrar su configuración.",
"<strong>Programaciones configuradas</strong>: una fila por horario con tipo (<em>corto</em> / <em>largo</em>), expresión cron legible (<em>«Día 1 de cada mes a las 03:00»</em>, <em>«Cada domingo a las 02:00»</em>), discos incluidos y retención.",
"<strong>Añadir / Editar programación</strong>: tipo (<em>corta ~2 min</em> / <em>larga 1–4 h</em>), frecuencia (<em>diaria / semanal / mensual</em>), día del mes o semana, hora y resultados guardados (<em>últimos 5 / 10 / 20</em>)."
],
"scheduleOutro": "El schedule se materializa como una entrada cron en el host que llama de vuelta al Monitor; los resultados se guardan en el mismo historial SMART mostrado en la pestaña 3, y el ajuste de retención auto-poda el test más viejo cuando termina uno nuevo.",
"tempTitle": "Modal de historial de temperatura",
"tempIntro": "Cada disco que expone un sensor de temperatura tiene sus lecturas muestreadas de forma continua por el Monitor y persistidas a una serie temporal local. El valor actual aparece como uno de los seis atributos SMART titulares en la pestaña Overview; pulsar ese bloque abre una modal dedicada de historial de temperatura con la imagen completa.",
"tempImageAlt": "Modal de historial de temperatura de disco — cabecera con la ruta y modelo del disco, un selector de timeframe (1 Hour / 24 Hours / 7 Days / 30 Days), una fila de cuatro tarjetas de estadísticas (Current / Min / Avg / Max) y una gráfica de línea de la temperatura sobre el rango seleccionado coloreada por los umbrales por tipo de disco",
"tempImageCaption": "Detalle de temperatura — se abre desde la pestaña Overview en cualquier disco cuyo sensor devuelva una lectura no-cero. La gráfica se colorea contra el umbral de tipo de disco (HDD / SSD / NVMe / SAS).",
"tempShowsTitle": "Lo que muestra la modal",
"scheduleOutro": "El horario crea una entrada cron en el host que llama a Monitor. Los resultados se guardan en el historial SMART de la pestaña 3 y la retención elimina automáticamente los más antiguos al terminar una prueba nueva.",
"tempTitle": "Diálogo de historial de temperatura",
"tempIntro": "Monitor toma periódicamente las lecturas de los discos con sensor de temperatura y las guarda en un historial local. El valor actual aparece en Resumen; al pulsarlo, se abre el detalle del historial de temperatura.",
"tempImageAlt": "Historial de temperatura del disco con ruta y modelo, periodos de 1 hora, 24 horas, 7 días o 30 días, indicadores Actual/Mínimo/Media/Máximo y gráfico de líneas coloreado según los umbrales del tipo de disco",
"tempImageCaption": "El detalle de temperatura se abre desde Resumen si el sensor devuelve un valor distinto de cero. El gráfico usa umbrales de HDD / SSD / NVMe / SAS.",
"tempShowsTitle": "Qué muestra el diálogo",
"tempShowsItems": [
"<strong>Selector de timeframe</strong> con cuatro rangos: <em>1 Hour</em>, <em>24 Hours</em> (por defecto), <em>7 Days</em>, <em>30 Days</em>. Cada uno consulta al mismo backend con un downsampling distinto para que la gráfica siga legible en cada horizonte.",
"<strong>Cuatro tarjetas de estadísticas</strong> en lo alto de la modal: <em>Current</em>, <em>Min</em>, <em>Avg</em>, <em>Max</em> para el rango seleccionado. La tarjeta <em>Current</em> se colorea con los mismos umbrales de estado que usan la pestaña Almacenamiento y las notificaciones, para que veas de un vistazo si el disco está en territorio normal / warm / hot.",
"<strong>Gráfica de línea</strong> de la temperatura a lo largo del tiempo, con la línea y el área sombreada coloreadas por tipo de disco:"
"<strong>Selector de periodo</strong>: <em>1 hora</em>, <em>24 horas</em> por defecto, <em>7 días</em> o <em>30 días</em>. Cada consulta ajusta la resolución para mantener el gráfico legible.",
"<strong>Cuatro indicadores</strong>: <em>Actual</em>, <em>Mínimo</em>, <em>Media</em> y <em>Máximo</em> del periodo. <em>Actual</em> usa los umbrales de la pestaña Almacenamiento y las notificaciones para distinguir temperatura normal, elevada o alta.",
"<strong>Gráfico de líneas</strong> de la temperatura a lo largo del tiempo, con línea y área sombreada coloreadas según el tipo de disco:"
],
"tempDiskTypes": [
"HDD — umbrales típicamente más frescos.",
"SSD — umbrales moderados.",
"NVMe — umbrales más altos (NVMe corre más caliente por diseño).",
"SAS — mismos valores por defecto que HDD."
"SAS: aviso a 55 °C y crítico a 65 °C, con umbral de aviso distinto al HDD."
],
"tempConfigurable": "Los cuatro son configurables desde <em>Settings → Health Monitor Thresholds</em>.",
"tempWhyTitle": "Por qué importa aquí un historial",
"tempConfigurable": "Los cuatro tipos se configuran en <em>Ajustes → Umbrales de Health Monitor</em>.",
"tempWhyTitle": "Por qué importa el historial",
"tempWhyItems": [
"<strong>Detección de drift.</strong> Los discos que se calientan progresivamente a lo largo de semanas (ventilador fallando, acumulación de polvo, disco vecino muriéndose y empujando aire caliente) son invisibles para una lectura única de \"temperatura actual\". Las vistas de 7 días y 30 días sacan el drift a la superficie.",
"<strong>Correlación de picos.</strong> Cuando una ventana de backup o un rebuild empujaron el disco brevemente por encima de su umbral, los rangos de 1 hora y 24 horas muestran si fue puntual o un patrón recurrente.",
"<strong>Ajuste de umbrales.</strong> Antes de subir o bajar un umbral en <em>Settings → Health Monitor Thresholds</em>, la gráfica de 30 días muestra el rango operativo real del disco para que el nuevo valor encaje con lo que el hardware realmente hace en vez de un cálculo a ojo."
"<strong>Detectar tendencias.</strong> Una lectura aislada no revela que un disco lleva semanas calentándose, por ejemplo por fallos de ventilación, polvo o calor cercano. Las vistas de 7 y 30 días permiten ver la evolución.",
"<strong>Relacionar picos.</strong> Si un backup o una reconstrucción elevó brevemente la temperatura por encima del umbral, las vistas de 1 y 24 horas muestran si fue puntual o recurrente.",
"<strong>Ajustar umbrales.</strong> Antes de cambiarlos en <em>Ajustes → Umbrales de Health Monitor</em>, consulta el gráfico de 30 días para conocer el rango real de funcionamiento del disco."
],
"obsTitle": "Historial de observaciones (a lo largo de pestañas)",
"obsIntro": "Los discos modernos fallan de forma gradual. Un disco puede reportar SMART <strong>PASSED</strong> y aún así loguear errores ocasionales de lectura en dmesg, perder enlaces SATA o exponer pending sectors que van y vienen. La UI estándar de Proxmox te muestra el veredicto SMART actual — no mantiene un historial de esas <em>señales</em>. ProxMenux sí, y las expone directamente dentro de la modal de disco.",
"obsImageAlt": "Pestaña Overview de la modal Disk Details mostrando un disco sano con estado SMART Passed, 0 errores reallocated/pending/CRC y una sección Observations listando un evento I/O Error registrado con el mensaje raw del kernel, una traducción humana del código de error ATA, timestamps de primera y última ocurrencia y un contador de ocurrencias",
"obsImageCaption": "Un disco que <strong>SMART dice que está bien</strong> puede aún así tener un historial de observaciones. La tarjeta es la capa de señales histórica bajo el veredicto SMART.",
"obsTitle": "Historial de observaciones en las pestañas",
"obsIntro": "Los fallos de disco pueden desarrollarse gradualmente. Un disco puede indicar SMART <strong>PASSED</strong> y registrar errores de lectura en dmesg, perder enlaces SATA o mostrar sectores pendientes intermitentes. ProxMenux conserva estas <em>señales</em> y las muestra en el diálogo junto al estado SMART actual.",
"obsImageAlt": "Resumen de un disco con SMART correcto y cero sectores reasignados, pendientes y errores CRC, pero una observación de error E/S con mensaje original del kernel, explicación ATA, primera y última fecha y contador",
"obsImageCaption": "Un disco que <strong>supera SMART</strong> puede tener observaciones anteriores. La tarjeta añade el historial de señales al estado actual.",
"obsWhatTitle": "Qué es una observación",
"obsWhatIntro": "Cualquier cosa que ProxMenux capture en el log del kernel, dmesg o salida SMART que parezca un evento a nivel de disco — y que por sí sola sería demasiado granular para una notificación — se registra como una <strong>observación</strong>. Cada fila muestra:",
"obsWhatIntro": "ProxMenux registra como <strong>observación</strong> los eventos de disco detectados en el registro del kernel, dmesg o SMART que por sí solos serían demasiado específicos para una notificación. Cada fila muestra:",
"obsWhatItems": [
"<strong>Insignia de tipo</strong> (I/O Error, SMART Error, Filesystem Error, ZFS Pool Error, Connection Error).",
"<strong>Mensaje raw del kernel</strong> tal cual apareció en dmesg — útil al copiar y pegar en un buscador o en un ticket de soporte.",
"<strong>Una frase humana</strong> bajo el mensaje raw para códigos ATA conocidos (<code>IDNF</code> → \"Sector address not found — posible bad sector o problema de cable\", <code>UNC</code> → \"Uncorrectable read error — bad sector\", y el resto de códigos estándar).",
"<strong>Timestamps de primera y última ocurrencia</strong>, más un <strong>contador de ocurrencias</strong> deduplicado por signature de error."
"<strong>Tipo</strong>: error E/S, SMART, sistema de archivos, pool ZFS o conexión.",
"<strong>Mensaje original del kernel</strong> tal como aparece en dmesg, para copiarlo a un buscador o solicitud de soporte.",
"<strong>Explicación breve</strong> para códigos ATA conocidos: <code>IDNF</code>, dirección de sector no encontrada, posible sector defectuoso o cable; <code>UNC</code>, error de lectura irrecuperable, sector defectuoso; y otros códigos estándar.",
"<strong>Primera y última fecha</strong> y <strong>número de apariciones</strong>, agrupadas por firma del error."
],
"obsWhyTitle": "Por qué ProxMenux las registra y las muestra",
"obsWhyTitle": "Por qué ProxMenux las registra y muestra",
"obsWhyItems": [
"<strong>El fallo de disco rara vez es un evento único.</strong> Normalmente empieza con errores esporádicos de bus ATA, algún sector UNC o un par de errores medium semanas antes de que SMART pase a <em>FAILED</em>. Sin persistencia esos avisos tempranos desaparecen de dmesg en el siguiente arranque.",
"<strong>SMART puede mentir.</strong> Un drive puede mostrar todos los atributos en verde y aún así estar a punto de irse — la capa de observaciones captura los síntomas que SMART no expone (en especial ICRC, IDNF, link resets a velocidades SATA más bajas).",
"<strong>Separa \"está pasando ahora\" de \"pasó recientemente\".</strong> El Monitor de salud auto-resuelve errores transitorios en cuanto dejan de dispararse, lo cual es genial para mantener limpia la lista de alertas activas — pero aún quieres ver, días después, que este disco tuvo tres errores de E/S esa noche. La tabla de observaciones es la respuesta.",
"<strong>Alimenta el modelo de notificación por niveles.</strong> El detector disk_io lee la tasa de observaciones de esta tabla para decidir silent / WARNING / CRITICAL (la ventana deslizante de 24h introducida en 1.2.1.2). El historial es lo que hace posible esa clasificación."
"<strong>Los fallos pueden evolucionar.</strong> Pueden aparecer errores de bus ATA, sectores UNC o errores del medio antes de que SMART indique <em>FAILED</em>. El búfer dmesg no los conserva tras reiniciar; el historial de observaciones sí.",
"<strong>SMART no descarta todos los fallos.</strong> Un disco puede tener atributos verdes y presentar problemas. Las observaciones conservan síntomas adicionales, como ICRC, IDNF, reinicios de enlace SATA o reducción de velocidad.",
"<strong>Distingue lo actual de lo reciente.</strong> Health Monitor resuelve automáticamente errores transitorios que dejan de aparecer. El historial permite comprobar días después que el disco tuvo, por ejemplo, tres errores de E/S esa noche.",
"<strong>Alimenta las notificaciones por niveles.</strong> disk_io usa la frecuencia de observaciones de la tabla para elegir silencio, WARNING o CRITICAL mediante una ventana móvil de 24 horas introducida en 1.2.1.2."
],
"obsDedupTitle": "Cómo funcionan dedup y re-notificación",
"obsDedupBody1": "Las observaciones se deduplican por su <strong>signature</strong> — una huella estable del tipo de error, dispositivo y campos clave de la línea del kernel. El mismo evento repitiéndose sube el <code>occurrence_count</code> de la fila existente en lugar de crear una nueva. Una <strong>signature diferente</strong> en el mismo disco crea una nueva observación y se trata como un evento nuevo para efectos de notificación.",
"obsDedupBody2": "Las notificaciones siguen una regla anti-cascada: la primera ocurrencia de una combinación (disco, signature, severidad) dada avisa al operador, y entonces ProxMenux espera 24 horas antes de volver a pingar sobre la misma combinación — aunque el contador siga subiendo. Una severidad escalando (WARNING → CRITICAL) rompe el cooldown para que se le cuente al operador cuando las cosas empeoran, no solo cuando ocurren.",
"obsDismissTitle": "Historial permanente vs errores activos",
"obsDismissBody1": "Una observación no se puede descartar, ocultar ni eliminar. Cada observación distinta de un disco es una tarjeta; la misma observación vista de nuevo suma a su contador de ocurrencias y actualiza su última fecha en lugar de crear otra tarjeta. El historial pertenece al disco, identificado por su número de serie: un disco conectado donde había otro empieza sin ninguna, y un disco que el kernel renombra conserva las suyas.",
"obsDismissBody2": "Resolver o descartar del lado de error activo (Monitor de salud) es independiente de las observaciones — la observación persiste más allá del auto-resolve del error activo. Ese es justo el punto: sobrevive, para que un warning transitorio de la semana pasada siga visible hoy en la tarjeta del disco. Mira <link>Monitor de salud</link> para el lado de error activo de la misma imagen."
"obsDedupTitle": "Agrupación de duplicados y repetición de avisos",
"obsDedupBody1": "Las observaciones se agrupan por <strong>firma</strong>, una huella estable del tipo de error, dispositivo y campos clave del mensaje. Las repeticiones aumentan <code>occurrence_count</code> en la fila existente. Una <strong>firma distinta</strong> crea otra observación y cuenta como evento nuevo para las notificaciones.",
"obsDedupBody2": "Para evitar avisos en cascada, la primera combinación de disco, firma y gravedad notifica al usuario. La misma combinación no vuelve a avisar hasta pasadas 24 horas, aunque aumente el contador. Un cambio de WARNING a CRITICAL interrumpe esa espera y avisa del empeoramiento.",
"obsDismissTitle": "Historial permanente y errores activos",
"obsDismissBody1": "Las observaciones no se pueden descartar, ocultar ni borrar. Cada firma tiene una tarjeta; si se repite, aumenta el contador y actualiza la última fecha. El historial sigue al número de serie: otro disco empieza vacío aunque use el mismo puerto, y un cambio de nombre del kernel no pierde el historial.",
"obsDismissBody2": "Resolver o descartar un error activo en Health Monitor no modifica sus observaciones. Se conservan después de la resolución automática, de modo que un aviso transitorio de la semana pasada siga visible hoy. Consulta <link>Health Monitor</link> para gestionar los errores activos."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -196,14 +196,14 @@
"headerSource": "Fuente",
"rows": [
{
"section": "Tarjetas resumen superiores",
"section": "Tarjetas de resumen superiores",
"endpoint": "/api/storage/summary",
"source": "Agregado desde <code>lsblk</code>, <code>zpool list</code>, <code>vgs</code> / <code>lvs</code>."
},
{
"section": "Inventario por disco",
"endpoint": "/api/storage",
"source": "<code>lsblk -O</code> + <code>smartctl -i</code> por dispositivo, con caché estable de identidad de disco (limpiado en eventos de hot-plug)."
"source": "<code>lsblk -O</code> + <code>smartctl -i</code> por dispositivo, con caché de identidad que se vacía al conectar o desconectar discos en caliente."
},
{
"section": "Almacenamientos Proxmox",
@@ -213,22 +213,22 @@
{
"section": "Valores SMART actuales",
"endpoint": "/api/storage/smart/<disk>",
"source": "<code>smartctl -A &lt;dev&gt;</code> — refrescado bajo demanda, no cacheado."
"source": "<code>smartctl -A &lt;dev&gt;</code> es una de las consultas disponibles; el endpoint de detalle también usa JSON SMART completo y datos específicos de NVMe."
},
{
"section": "Historial de self-tests SMART",
"section": "Historial de autopruebas SMART",
"endpoint": "/api/storage/smart/<disk>/history",
"source": "Almacenado bajo <code>/var/lib/proxmenux-monitor/smart/&lt;disk&gt;/</code> como snapshots JSON."
"source": "Se guarda en <code>/usr/local/share/proxmenux/smart/&lt;disk&gt;/</code> como snapshots JSON."
},
{
"section": "Observaciones permanentes",
"endpoint": "/api/storage/observations",
"source": "Tabla SQLite alimentada por el Monitor de salud cada ciclo (se mantiene tras auto-resolve)."
"source": "Tabla SQLite actualizada por Health Monitor en cada ciclo, conservada después de resolver errores activos."
}
],
"outro": "Verificar la cadena de recolección en el host:",
"codeComment1": "# Traer la snapshot actual desde un script",
"codeComment2": "# Cross-check de lo que ve el panel contra la vista raw del SO"
"codeComment1": "# Obtener el estado actual desde un script",
"codeComment2": "# Contrastar los datos del panel con el estado directo del sistema operativo"
},
"whereNext": {
"heading": "Por dónde seguir",
@@ -236,17 +236,17 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la categoría discos y E/S y el modelo de supresión."
"tail": " — categoría Discos y E/S y reglas de supresión."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints de storage y SMART."
"tail": " — endpoints de almacenamiento y SMART."
},
{
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tailRich": " — qué disparan aguas abajo <code>disk_io_error</code>, <code>storage_unavailable</code> y <code>smart_test_failed</code>."
"tailRich": " — qué acciones posteriores desencadenan <code>disk_io_error</code>, <code>storage_unavailable</code> y <code>smart_test_failed</code>."
},
{
"label": "Índice del panel",
@@ -254,14 +254,14 @@
"tail": " — el resto de pestañas."
},
{
"label": "ProxMenux → Disk Manager",
"label": "ProxMenux → Gestor de discos",
"href": "/docs/disk-manager",
"tail": " — la cara de las acciones: format / wipe / SMART tests / importar discos a VMs y CTs desde la TUI."
"tail": " — acciones de la TUI: formatear, borrar, pruebas SMART e importar discos a VM y contenedores."
},
{
"label": "ProxMenux → SMART Disk Health & Test",
"label": "ProxMenux → Estado y pruebas SMART del disco",
"href": "/docs/disk-manager/smart-disk-test",
"tail": " — la contraparte CLI de esta pestaña: programar tests SMART, exportar el JSON que renderiza el panel y la referencia más profunda de tipos de test / interpretación."
"tail": " — equivalente CLI: programar pruebas SMART, exportar el JSON mostrado en el panel y consultar los tipos de prueba y su interpretación."
}
]
}
@@ -1,41 +1,41 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Logs del sistema | ProxMenux Documentation",
"title": "ProxMenux Monitor — Panel: Logs del sistema | Documentación de ProxMenux",
"description": "La pestaña Logs del sistema reúne tres fuentes en una sola pantalla: journalctl en vivo con filtros y descarga, historial de tareas de Proxmox (UPIDs) y log de notificaciones — todo buscable, filtrable por severidad / rango temporal y descargable como paquetes de texto."
},
"header": {
"title": "Panel: pestaña Logs del sistema",
"description": "Tres sub-pestañas bajo un mismo techo: el journal del sistema (journalctl con filtros), el historial de tareas de Proxmox y el log de notificaciones. Las tres son buscables, filtrables y descargables como paquetes de texto.",
"description": "Tres subpestañas en una pantalla: journal del sistema (journalctl con filtros), historial de tareas de Proxmox y registro de notificaciones. Las tres permiten buscar, filtrar y descargar los datos como paquetes de texto.",
"section": "ProxMenux Monitor · Panel"
},
"readOnly": {
"title": "Solo lectura por diseño",
"body": "Nada en esta pestaña modifica los archivos de log. Los filtros viven en la URL / estado, las descargas son paquetes generados en el servidor. El panel nunca borra entradas de log — para mantenimiento usa el propio <code>journalctl --vacuum-time=&lt;N&gt;</code> o <code>logrotate</code> del host."
"body": "Esta pestaña no modifica los archivos de log. Los filtros se mantienen en la URL o en el estado de la interfaz y las descargas se generan en el servidor. El panel nunca borra entradas; para su mantenimiento usa <code>journalctl --vacuum-time=&lt;N&gt;</code> o <code>logrotate</code> en el host."
},
"topRow": {
"heading": "Fila superior: cuatro contadores",
"items": [
"<strong>Total Entries</strong> — número de registros dentro de la ventana de filtro activa.",
"<strong>Errors</strong> — recuento de severidad ≤ 3 (<code>err</code> / <code>crit</code> / <code>alert</code> / <code>emerg</code>).",
"<strong>Warnings</strong> — recuento de severidad 4 (<code>warning</code>).",
"<strong>Backups</strong> — recuento de entradas de tareas vzdump / PBS en la misma ventana."
"<strong>Entradas totales</strong>: número de registros dentro del intervalo del filtro activo.",
"<strong>Errores</strong>: número de entradas con severidad ≤ 3 (<code>err</code> / <code>crit</code> / <code>alert</code> / <code>emerg</code>).",
"<strong>Advertencias</strong>: número de entradas con severidad 4 (<code>warning</code>).",
"<strong>Backups</strong>: número de entradas de tareas vzdump / PBS en el mismo intervalo."
]
},
"subtabs": {
"heading": "Tres sub-pestañas",
"logsTitle": "Logs",
"logsIntro": "El journal del sistema, servido por <code>journalctl</code> en el backend. Filtros disponibles en la barra de herramientas:",
"logsTitle": "Registros",
"logsIntro": "El journal del sistema, obtenido en el servidor con <code>journalctl</code>. La barra de herramientas ofrece estos filtros:",
"logsFilters": [
"<strong>Severidad</strong> — emerg / alert / crit / err / warning / notice / info / debug, o cualquier combinación.",
"<strong>Severidad</strong>: emerg / alert / crit / err / warning / notice / info / debug o cualquier combinación.",
"<strong>Rango temporal</strong> — últimos 5 min / 15 min / 1 h / 6 h / 24 h / 7 d / personalizado.",
"<strong>Búsqueda de texto libre</strong> — substring o regex (<code>journalctl --grep</code>).",
"<strong>Filtro por unidad</strong> — restringir a una unidad systemd concreta (<code>pveproxy.service</code>, <code>nginx.service</code>, …)."
"<strong>Búsqueda de texto libre</strong>: subcadena o expresión regular (<code>journalctl --grep</code>).",
"<strong>Filtro de unidad</strong>: restringe a una unidad systemd concreta (<code>pveproxy.service</code>, <code>nginx.service</code>, …)."
],
"logsRowsAfter": "Cada fila muestra timestamp, insignia de severidad, unidad de origen y el mensaje. Los mensajes largos se colapsan con un conmutador \"mostrar más\". La acción <strong>Download</strong> empaqueta el filtro actual en un único archivo <code>.txt</code> vía <code>GET /api/logs/download</code> — útil cuando quieres compartir un trozo del journal con alguien.",
"logDetailsModalTitle": "Modal Log Details",
"logDetailsBody": "Pulsar cualquier fila abre una modal <strong>Log Details</strong> con cada campo estructurado que journald capturó para esa entrada — la misma vista que construirías a mano ejecutando <code>journalctl --output=verbose</code> en el host.",
"logDetailsBody": "Al pulsar una fila se abre <strong>Detalles del log</strong> con todos los campos estructurados que journald capturó para esa entrada, como al ejecutar <code>journalctl --output=verbose</code> en el host.",
"logDetailsImageAlt": "Modal Log Details — una entrada del journal desplegada con Level, Service, Timestamp, Source, Systemd Unit, Process ID, Hostname y el mensaje completo",
"logDetailsImageCaption": "Modal Log Details — cada campo estructurado que journald lleva para esta entrada, con el mensaje íntegro sin truncar al final. Útil para logs de cron y de servicios donde importa la línea de comandos ejecutada.",
"logDetailsImageCaption": "Detalles del log: todos los campos estructurados de journald para la entrada, con el mensaje completo sin truncar al final. Útil para logs de cron y servicios donde importa la línea de comando ejecutada.",
"fieldsIntro": "Campos mostrados:",
"fields": [
"<strong>Level</strong> — insignia de severidad coloreada (INFO / WARNING / ERROR / CRITICAL).",
@@ -45,15 +45,15 @@
"<strong>Systemd Unit</strong> — la unidad <code>.service</code> / <code>.timer</code> / <code>.socket</code> real si la entrada estaba asociada a una.",
"<strong>Process ID</strong> — PID del proceso emisor.",
"<strong>Hostname</strong> — útil cuando los journals se reenvían entre nodos de cluster.",
"<strong>Message</strong> — el mensaje completo sin truncar en un bloque monoespaciado, listo para copiar."
"<strong>Mensaje</strong>: mensaje completo sin truncar, en un bloque monoespaciado listo para copiar."
],
"maxLevelStoreTitle": "MaxLevelStore de journald",
"maxLevelStoreBody": "En una instalación recién hecha de Proxmox, journald usa por defecto <code>MaxLevelStore=warning</code>, lo que descarta en silencio los mensajes de nivel info. El Monitor lo detecta en el arranque y añade un drop-in (<code>/etc/systemd/journald.conf.d/proxmenux-loglevel.conf</code>) que sube el umbral a <code>info</code> para que la pestaña Logs tenga algo que mostrar en todas las severidades.",
"maxLevelStoreBody": "En una instalación nueva de Proxmox, journald usa por defecto <code>MaxLevelStore=warning</code>, que descarta los mensajes info. Monitor lo detecta al arrancar y añade un archivo de configuración complementario (<code>/etc/systemd/journald.conf.d/proxmenux-loglevel.conf</code>) con el umbral <code>info</code> para conservar los mensajes informativos y los de mayor gravedad. Esto no incluye debug.",
"backupsTitle": "Backups",
"backupsBody": "Historial de tareas de Proxmox filtrado a las entradas relacionadas con backup. Una fila por tarea (<code>vzdump</code>, transferencias PBS, Garbage Collect, Verify) con el estado (OK / WARNINGS / ERROR), el guest implicado, el almacenamiento de origen, la duración y el UPID. Pulsa una fila para cargar el log completo de la tarea vía <code>GET /api/task-log/&lt;upid&gt;</code> — los mismos datos que Proxmox expone a través de <em>Datacenter → Tasks</em>, acotado a backups.",
"notificationsTitle": "Notifications",
"notificationsBody1": "Cada notificación enviada por el Monitor — Telegram, Discord, Email, Gotify, ntfy, Slack, Teams, webhook. Cada fila: timestamp, canal, tipo de evento, severidad, el título renderizado, el cuerpo renderizado y (si IA está activa) un conmutador para ver la reescritura con IA junto al original.",
"notificationsBody2": "Usa esta pestaña para verificar que un canal está entregando de verdad y para comparar lo que produjo la reescritura con IA frente a la plantilla base. La configuración de canales vive en la página detallada de <link>Notificaciones</link>."
"notificationsTitle": "Notificaciones",
"notificationsBody1": "Todas las notificaciones enviadas por Monitor: Telegram, Discord, correo electrónico, Gotify, ntfy, Slack, Teams y webhook. Cada fila muestra fecha y hora, canal, tipo de evento, severidad, título y cuerpo generados y, si la IA está activa, un selector para comparar su reescritura con el original.",
"notificationsBody2": "Usa esta pestaña para verificar la entrega de un canal y comparar la reescritura de IA con la plantilla base. Los canales se configuran en la página detallada de <link>Notificaciones</link>."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -64,10 +64,10 @@
{
"subtab": "Logs (filtro en vivo)",
"endpoint": "/api/logs",
"source": "<code>journalctl --output json --since &lt;range&gt;</code> con filtros de severidad / unidad / búsqueda aplicados en el servidor."
"source": "<code>journalctl --output json --since &lt;range&gt;</code> con filtros de severidad, unidad y búsqueda aplicados en el servidor."
},
{
"subtab": "Download",
"subtab": "Descargar",
"endpoint": "/api/logs/download",
"source": "La misma consulta, devuelta como texto plano para grep / less."
},
@@ -77,14 +77,14 @@
"source": "Historial de tareas PVE filtrado por <code>vzdump</code>, transferencias PBS, Garbage Collect, Verify."
},
{
"subtab": "Vista en detalle de una tarea de backup",
"subtab": "Detalles de una tarea de backup",
"endpoint": "/api/task-log/&lt;upid&gt;",
"source": "Log completo de la tarea en texto plano leído de <code>/var/log/pve/tasks/&lt;index&gt;/&lt;upid&gt;</code>."
},
{
"subtab": "Historial de notificaciones",
"endpoint": "/api/notifications/history",
"source": "Tabla SQLite <code>notification_history</code> alimentada por el loop de envío."
"source": "Tabla SQLite <code>notification_history</code>, alimentada por el bucle de envío."
}
],
"apiIntro": "Tanto el filtro en vivo como las descargas también son accesibles vía API:",
@@ -98,17 +98,17 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la categoría Logs del sistema que vigila patrones persistentes / picos / cascadas."
"tail": " — la categoría Logs del sistema, que vigila patrones persistentes, picos y cascadas."
},
{
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tail": " — el watcher del journal lee la misma fuente y convierte coincidencias en notificaciones."
"tail": " — el observador del journal lee la misma fuente y convierte las coincidencias en notificaciones."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints logs y task-log con sus parámetros de consulta."
"tail": " — endpoints logs y task-log y sus parámetros de consulta."
},
{
"label": "Índice del panel",
@@ -1,85 +1,85 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Resumen del sistema | ProxMenux Documentation",
"description": "La pestaña por defecto al abrir ProxMenux Monitor: cuatro tarjetas de métricas (CPU, memoria, VMs y LXCs activos, temperatura) con actualizaciones en vivo y sparkline, la gráfica de métricas históricas y los paneles condensados de Almacenamiento y Red con acceso directo a sus pestañas dedicadas."
"title": "ProxMenux Monitor — Panel: Resumen del sistema | Documentación de ProxMenux",
"description": "La pestaña inicial por defecto de ProxMenux Monitor: cuatro tarjetas (CPU, memoria, VM y LXC activos, temperatura) con actualización en vivo y minigráfico de tendencia, gráfica histórica y resúmenes de almacenamiento y red con enlaces a sus pestañas."
},
"header": {
"title": "Panel: pestaña Resumen del sistema",
"description": "La primera pestaña que abre el panel. Cuatro tarjetas de métricas en vivo arriba, la gráfica de métricas históricas en el medio y paneles condensados de almacenamiento / red abajo — todo derivado de las mismas APIs que alimentan las pestañas dedicadas.",
"description": "La pestaña que el panel abre por defecto. Cuatro tarjetas con métricas en vivo arriba, gráfica histórica en el centro y resúmenes de almacenamiento y red abajo, usando las mismas API que sus pestañas dedicadas.",
"section": "ProxMenux Monitor · Panel"
},
"readOnly": {
"title": "Un vistazo de solo lectura",
"body": "Nada en esta pestaña es una superficie de control — todos los paneles son informativos. Las acciones viven en las pestañas dedicadas a las que enlazan: entra en Almacenamiento para gestionar discos, en VMs y LXCs para arrancar / parar guests, en la pestaña Seguridad para configurar autenticación, y así sucesivamente."
"body": "Todos los paneles de esta pestaña son informativos. Las acciones están en las pestañas enlazadas: Almacenamiento para gestionar discos, VMs y LXCs para iniciar o detener invitados y Seguridad para configurar la autenticación."
},
"captureAlt": "Pestaña Resumen del sistema — cuatro tarjetas de métricas (CPU, Memoria, VMs activos, Temperatura), gráfica de métricas del nodo y tarjetas resumen de Almacenamiento / Red",
"captureCaption": "La pestaña Resumen del sistema — la que abre el panel. Las cuatro tarjetas están en vivo, la gráfica de debajo es histórica y las dos tarjetas de abajo resumen Almacenamiento y Red.",
"captureCaption": "Resumen del sistema, la pestaña inicial por defecto. Las cuatro tarjetas se actualizan en vivo, la gráfica muestra el historial y las dos tarjetas inferiores resumen almacenamiento y red.",
"topRow": {
"heading": "Fila superior: tarjetas de métricas en vivo",
"intro": "Cuatro tarjetas en una rejilla 2×2 en móvil, una sola fila en escritorio. Cada una se actualiza desde <code>/api/system</code> cada pocos segundos.",
"intro": "Cuatro tarjetas en rejilla 2×2 en móvil y una fila en escritorio. Cada una recibe datos de <code>/api/system</code> cada pocos segundos.",
"headerCard": "Tarjeta",
"headerWhat": "Qué muestra",
"headerSource": "Fuente",
"rows": [
{
"card": "CPU Usage",
"card": "Uso de CPU",
"what": "Porcentaje actual con barra de progreso. Se actualiza cada ~1 s vía el sampler de signos vitales.",
"source": "psutil.cpu_percent()"
},
{
"card": "Memory Usage",
"what": "GB usados, porcentaje, GB totales. La barra de progreso sigue al porcentaje.",
"card": "Uso de la memoria",
"what": "GB usados, porcentaje y GB totales. La barra representa el porcentaje.",
"source": "psutil.virtual_memory()"
},
{
"card": "Active VM & LXC",
"what": "Recuento de guests actualmente en ejecución, con una insignia de desglose Running / Stopped y una línea al pie con los totales de VMs y LXCs.",
"card": "VM y LXC activos",
"what": "Número de invitados en ejecución, con desglose En ejecución / Detenidos y totales de VMs y LXCs al pie.",
"source": "/api/vms (consolidado)"
},
{
"card": "Temperature",
"what": "Temperatura de CPU en °C con insignia de estado (cool / warm / hot) y un sparkline de 5 minutos detrás. Muestra <em>N/A</em> cuando no se detecta sensor. Pulsa para abrir la modal de detalle de temperatura.",
"card": "Temperatura",
"what": "Temperatura de CPU en °C, estado (fría / templada / caliente) y minigráfico de los últimos 5 minutos detrás. Muestra <em>N/A</em> si no hay sensor. Pulsa para abrir los detalles.",
"source": "sensors / coretemp"
}
],
"thresholdsTitle": "Colores de estado y umbrales aplicados aquí",
"thresholdsIntro": "Cada anillo, barra y sparkline en las cuatro tarjetas de métricas sigue la misma clasificación — <green/> <strong>verde</strong> por debajo de Warning, <amber/> <strong>ámbar</strong> entre Warning y Critical, <red/> <strong>rojo</strong> en Critical y por encima. Valores por defecto recomendados que vienen con ProxMenux:",
"thresholdsIntro": "Cada anillo, barra y minigráfico usa la misma escala: <green/> <strong>verde</strong> por debajo de Advertencia, <amber/> <strong>ámbar</strong> entre Advertencia y Crítico, <red/> <strong>rojo</strong> desde Crítico. Valores recomendados incluidos con ProxMenux:",
"thresholdsItems": [
"<strong>Uso de CPU</strong> — Warning 85 %, Critical 95 %.",
"<strong>Memoria</strong> — Warning 85 %, Critical 95 % (el swap también dispara Critical al 5 % usado — un host Proxmox sano apenas debería tocar swap).",
"<strong>Temperatura de CPU</strong> — Warning 80 °C, Critical 90 °C."
"<strong>Uso de CPU</strong>: advertencia 85 %, crítico 95 %.",
"<strong>Memoria</strong>: advertencia 85 %, crítico 95 %. Swap también activa Crítico al 5 % de uso; un host Proxmox sano debería usarlo rara vez.",
"<strong>Temperatura de CPU</strong>: advertencia 80 °C, crítico 90 °C."
],
"thresholdsOutro": "Cada valor es configurable por host — <link>Settings → Health Monitor Thresholds</link> es la fuente única de verdad y explica cómo ajustarlos.",
"sparklineTitle": "El sparkline es significativo",
"thresholdsOutro": "Los valores se configuran por host; <link>Ajustes → Umbrales del monitor de salud</link> documenta y centraliza su ajuste.",
"sparklineTitle": "El minigráfico muestra la tendencia",
"sparklineBody": "La tarjeta de temperatura dibuja una traza de 5 minutos bajo el valor, con la línea y el degradado siguiendo el mismo par Warning/Critical documentado arriba. Es la forma más rápida de ver si el host está en escalada térmica sin abrir la modal de detalle."
},
"processes": {
"heading": "Top procesos por CPU / Memoria",
"intro": "Las tarjetas CPU Usage y Memory de la pestaña Resumen son clicables. Al pulsar cualquiera de ellas se abre una lista ordenable con los 25 procesos top — ordenada por uso de CPU si la abriste desde la tarjeta de CPU, o por memoria residente si la abriste desde la de Memory.",
"intro": "Las tarjetas Uso de CPU y Memoria son pulsables. Abren una lista ordenable con los 25 procesos principales, por uso de CPU desde la primera tarjeta o por memoria residente desde la segunda.",
"listTitle": "El diálogo con la lista",
"listItems": [
"<strong>Auto-refresco</strong> — la lista se actualiza cada 5 segundos mientras el diálogo está abierto y deja de pedir datos en cuanto se cierra.",
"<strong>Filtro</strong> — la caja de búsqueda acota la lista por command, user o PID.",
"<strong>Actualización automática</strong>: la lista se actualiza cada 5 segundos mientras está abierta y deja de consultar datos al cerrar.",
"<strong>Filtro</strong>: el buscador acota la lista por comando, usuario o PID.",
"<strong>Barra en línea</strong> — la columna de la métrica principal dibuja una barra pequeña escalada al mayor valor de la lista filtrada, para que el orden siga siendo visible aunque ningún proceso esté cerca del 100 %.",
"<strong>Layout móvil</strong> — por debajo de 640 px las columnas PID y User se ocultan para que Command, CPU % y Memory sigan cabiendo en la pantalla de un teléfono sin scroll horizontal."
],
"captureListAlt": "Modal Top processes by Memory — tabla con columnas PID, USER, COMMAND, CPU %, Memory ordenada por RSS",
"captureListCaption": "La tarjeta Memory abre la lista ordenada por RSS (acento índigo). La tarjeta CPU abre la misma lista ordenada por uso de CPU (acento azul).",
"detailTitle": "Detalle por proceso",
"detailIntro": "Al pulsar cualquier fila de la lista se abre un segundo diálogo con la foto en vivo de ese proceso, organizada en cuatro secciones:",
"detailIntro": "Pulsa una fila para abrir un segundo diálogo con los datos en vivo del proceso, organizados en cuatro secciones:",
"detailItems": [
"<strong>Overview</strong> — estado, proceso padre, número de hilos, descriptores de fichero abiertos, usuario y grupo.",
"<strong>Resources</strong> — CPU %, Memoria %, Resident (RSS), Virtual size, Swap, totales de I/O de lectura y escritura.",
"<strong>Command</strong> — nombre corto, línea de comandos completa, ruta del ejecutable y directorio de trabajo.",
"<strong>Lifetime</strong> — timestamp de arranque y tiempo transcurrido en ejecución."
"<strong>Resumen</strong>: estado, proceso padre, número de hilos, descriptores de archivo abiertos, usuario y grupo.",
"<strong>Recursos</strong>: CPU %, memoria %, memoria residente (RSS), tamaño virtual, swap y totales de E/S leída y escrita.",
"<strong>Comando</strong>: nombre corto, línea de comandos completa, ruta del ejecutable y directorio de trabajo.",
"<strong>Duración</strong>: fecha y hora de inicio y tiempo transcurrido en ejecución."
],
"detailRefresh": "El diálogo de detalle se refresca cada 3 segundos mientras está abierto. Si el proceso termina con el diálogo abierto, el polling se detiene, aparece un banner ámbar <em>This process has finished</em> y el último snapshot capturado se queda en pantalla (atenuado) para que sigas viendo qué estaba pasando justo antes de que terminara.",
"captureDetailAlt": "Modal de detalle de proceso — secciones Overview, Resources, Command y Lifetime para un único PID",
"detailRefresh": "El detalle se actualiza cada 3 segundos mientras está abierto. Al terminar el proceso, cesan las consultas y aparece el aviso ámbar <em>Este proceso ha terminado</em>. La última captura queda atenuada para ver qué ocurría justo antes de finalizar.",
"captureDetailAlt": "Detalle de proceso: secciones Resumen, Recursos, Comando y Duración para un PID",
"captureDetailCaption": "Diálogo de detalle por proceso abierto desde una fila de la lista. El color de acento sigue al de la tarjeta que lo abrió (azul para CPU, índigo para Memory)."
},
"middle": {
"heading": "Medio: gráficas de métricas del nodo",
"body1": "Bajo la fila superior se encuentra el componente <code>NodeMetricsCharts</code> — gráficas históricas de CPU, memoria y E/S de disco tomadas del propio almacén RRD de Proxmox vía <code>/api/node/metrics</code>. Un selector de timeframe alterna entre <em>1 hora / 24 horas / 7 días / 30 días / 1 año</em>; la resolución de los datos baja a medida que crece la ventana para que la gráfica se mantenga fluida.",
"body1": "Bajo las tarjetas está <code>NodeMetricsCharts</code>, con gráficas históricas de CPU, memoria y E/S de disco del almacén RRD de Proxmox mediante <code>/api/node/metrics</code>. El selector permite <em>1 hora / 24 horas / 7 días / 30 días / 1 año</em>; la resolución baja al ampliar el intervalo para mantener la fluidez.",
"body2": "Son las mismas gráficas que la UI web de Proxmox renderiza para un nodo, simplemente consolidadas en el tema oscuro del Monitor y alineadas con el resto de paneles."
},
"bottom": {
@@ -87,25 +87,25 @@
"storageTitle": "Tarjeta Storage Overview",
"storageIntro": "Una vista condensada del estado de almacenamiento del host, dividida en tres bloques:",
"storageItems": [
"<strong>Total Node Capacity</strong> — suma de todos los almacenamientos de VM/LXC más el almacenamiento local de sistema, con una barra de progreso en degradado del reparto total usado / libre.",
"<strong>Capacidad total del nodo</strong>: suma de los almacenamientos de VM/LXC y del almacenamiento local del sistema, con barra degradada de espacio usado y libre.",
"<strong>Total Capacity / Physical Disks</strong> — titular de capacidad bruta y el recuento de discos físicos descubiertos.",
"<strong>VM/LXC Storage</strong> — usado / libre / porcentaje para los almacenamientos donde viven los guests, más un contador cuando hay más de uno configurado.",
"<strong>Local Storage (System)</strong> — el propio mount raíz / sistema del host, separado del pool de guests."
"<strong>Almacenamiento VM/LXC</strong>: espacio usado, libre y porcentaje de los almacenamientos de invitados, con contador si hay más de uno.",
"<strong>Almacenamiento local (sistema)</strong>: montaje raíz o de sistema del host, separado del pool de invitados."
],
"storageDrillIn": "La vista en detalle vive en la <link>pestaña Almacenamiento</link> — SMART por disco, detalles de pool ZFS, historial de observaciones, etc.",
"storageDrillIn": "Los detalles están en la <link>pestaña Almacenamiento</link>: SMART por disco, pools ZFS, historial de observaciones, etc.",
"networkTitle": "Tarjeta Network Overview",
"networkBody1": "La línea superior muestra el recuento de interfaces activas (físicas + bridges combinados). Debajo, dos filas de insignias coloreadas para las interfaces en <code>up</code> — NICs físicas en azul, bridges en un color secundario. Un selector de timeframe arriba a la derecha (1 hora / 24 horas / 7 días / 30 días / 1 año) controla una pequeña gráfica de tráfico RX / TX.",
"networkBody2": "La vista en detalle por interfaz (IP/MAC, gráfica RRD, miembros del bridge, modo del bond, etc.) vive en la <link>pestaña Red</link>."
"networkBody2": "Los detalles por interfaz (IP/MAC, gráfica RRD, miembros del bridge, modo de bond, etc.) están en la <link>pestaña Red</link>."
},
"refresh": {
"heading": "Modelo de refresco",
"intro": "Cada panel gestiona su propio estado de carga (<code>loadingStates.cpu</code>, <code>loadingStates.storage</code>, …) para que una fuente lenta no bloquee al resto. Mientras un panel está obteniendo datos, muestra un skeleton con animación pulse; los fetchs fallidos degradan con elegancia — por ejemplo, un sensor de temperatura ausente renderiza la tarjeta como <em>N/A</em> en vez de un error.",
"heading": "Modelo de actualización",
"intro": "Cada panel tiene su propio estado de carga (<code>loadingStates.cpu</code>, <code>loadingStates.storage</code>, …), de modo que una fuente lenta no bloquea las demás. Mientras carga muestra un marcador pulsante. Los fallos se presentan sin interrumpir el resto; por ejemplo, sin sensor de temperatura muestra <em>N/A</em> en vez de un error.",
"items": [
"<strong>Tarjetas de métricas superiores</strong> — refresco cada ~5 s. Los paneles de CPU y temperatura también reciben un push de 1 s del sampler de signos vitales.",
"<strong>Gráfica de métricas del nodo</strong> — refresco cada 30 s, o al cambiar de timeframe.",
"<strong>Tarjetas superiores</strong>: se actualizan cada ~5 s. CPU y temperatura también reciben datos cada 1 s del muestreador de signos vitales.",
"<strong>Gráfica de métricas del nodo</strong>: carga al abrir y al cambiar de intervalo o idioma. Si hay que reintentar, espera 60 s.",
"<strong>Tarjeta de almacenamiento</strong> — refresco cada 60 s. Los datos SMART se cachean más tiempo (la pestaña Almacenamiento dispara una lectura fresca bajo demanda).",
"<strong>Tarjeta de red</strong> — refresco cada 5 s en el timeframe activo.",
"<strong>Refresco manual</strong> — el botón Refresh en la cabecera fuerza a todos los paneles a recargar inmediatamente."
"<strong>Tarjeta de red</strong>: resumen cada 59 s y gráfica de tráfico cada 60 s en el intervalo activo.",
"<strong>Actualización manual</strong>: el botón Actualizar de la cabecera vuelve a cargar todos los paneles inmediatamente."
]
},
"dataCollected": {
@@ -115,12 +115,12 @@
"headerSource": "Fuente",
"rows": [
{
"card": "Pastilla de estado de la cabecera",
"card": "Indicador de estado de la cabecera",
"endpoint": "/api/health",
"source": "El estado global cacheado que produce el Monitor de salud en cada ciclo."
},
{
"card": "CPU / RAM / Swap / Uptime",
"card": "CPU / RAM / Swap / Tiempo de actividad",
"endpoint": "/api/system",
"source": "<code>/proc/stat</code>, <code>/proc/meminfo</code>, <code>/proc/uptime</code> con muestreo de CPU en ventana corta."
},
@@ -135,13 +135,13 @@
"source": "Mira las pestañas dedicadas para cada una. Las tarjetas de la cabecera muestran una vista compactada de los mismos endpoints."
},
{
"card": "Cadencia de refresco",
"card": "Frecuencia de actualización",
"endpoint": "—",
"source": "CPU / red 5 s; almacenamiento / VMs 30 s; info estática cada 5 min. El botón Refresh de la cabecera fuerza una recarga inmediata en todos los paneles."
"source": "Sistema cada 5 s; almacenamiento, VMs y resumen de red cada 59 s. El botón Actualizar de la cabecera fuerza la recarga inmediata de todos los paneles."
}
],
"codeComment1": "# Llamada única que alimenta la pastilla de la cabecera",
"codeComment2": "# pública, sin token",
"codeComment1": "# Llamada que alimenta el indicador de estado de la cabecera",
"codeComment2": "# público, sin token",
"codeComment3": "# Snapshot autenticada que usan las tarjetas"
},
"whereNext": {
@@ -150,12 +150,12 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la modal detrás de la pastilla de estado de la cabecera (diez categorías, descartes, supresión)."
"tail": " — la ventana del indicador de estado de la cabecera: diez categorías, descartes y supresión de avisos."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints system, info y health."
"tail": " — endpoints system, info y health."
},
{
"label": "Notificaciones",
@@ -165,12 +165,12 @@
{
"label": "Índice del panel",
"href": "/docs/monitor/dashboard",
"tail": " — las otras ocho pestañas de un vistazo."
"tail": " — las demás pestañas del panel de un vistazo."
},
{
"label": "Arquitectura",
"href": "/docs/monitor/architecture",
"tail": " — los hilos en background y las APIs que alimentan esta vista."
"tail": " — los hilos en segundo plano y las API que alimentan esta vista."
}
]
}
@@ -1,16 +1,16 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Terminal | ProxMenux Documentation",
"description": "Shell en el navegador al host Proxmox: hasta 4 terminales a la vez con vista en rejilla, ayudas de teclado para móvil (ESC, TAB, flechas, combinaciones con Ctrl), una chuleta de comandos integrada con cheat.sh, protegida con JWT."
"title": "ProxMenux Monitor — Panel: Terminal | Documentación de ProxMenux",
"description": "Shell del host Proxmox en el navegador: hasta 4 terminales en rejilla, botones de teclado para móviles (ESC, TAB, flechas, combinaciones Ctrl), guía de comandos integrada con cheat.sh y protección JWT."
},
"header": {
"title": "Panel: pestaña Terminal",
"description": "Una sesión real de shell en el navegador, sobre el host Proxmox. Hasta cuatro terminales a la vez, ayudas de teclado para móvil, una chuleta de comandos integrada — todo en el mismo tema que el resto del panel.",
"description": "Una sesión real de shell en el host Proxmox desde el navegador. Hasta cuatro terminales a la vez, botones de teclado para móviles y una guía de comandos integrada, con el mismo tema que el resto del panel.",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "Un PTY real en el navegador",
"body": "El terminal asigna una PTY del lado del servidor a través de <code>flask_terminal_routes</code>, la canaliza por un WebSocket hacia <code>xterm.js</code> en el navegador y se ejecuta como <code>root</code> (el usuario de la unidad systemd). Cualquier cosa que puedas hacer en <code>ssh root@&lt;host&gt;</code> funciona aquí — incluidos <code>vim</code>, <code>tmux</code>, herramientas ncurses y las CLIs de Proxmox (<code>qm</code>, <code>pct</code>, <code>pvesh</code>, <code>pvecm</code>). Cada PTY lanzada desde esta pestaña exporta la variable de entorno <code>PROXMENUX_TERMINAL=monitor</code>, que hereda todo proceso <code>bash</code> hijo — incluida una llamada posterior a <code>menu</code> — para que los flujos de ProxMenux puedan saber si se están ejecutando dentro del terminal del navegador del Monitor."
"body": "El terminal crea una PTY en el servidor mediante <code>flask_terminal_routes</code>, la conecta por WebSocket con <code>xterm.js</code> en el navegador y se ejecuta como <code>root</code>, el usuario de la unidad systemd. Permite lo mismo que <code>ssh root@&lt;host&gt;</code>: <code>vim</code>, <code>tmux</code>, herramientas ncurses y las CLI de Proxmox (<code>qm</code>, <code>pct</code>, <code>pvesh</code>, <code>pvecm</code>). Cada PTY exporta <code>PROXMENUX_TERMINAL=monitor</code>. Sus procesos hijos <code>bash</code>, incluido un lanzamiento posterior de <code>menu</code>, heredan esta variable para reconocer el terminal de Monitor."
},
"singleAlt": "Pestaña Terminal de ProxMenux Monitor — una única sesión de terminal mostrando el resumen del sistema de Fastfetch al hacer login",
"singleCaption": "Un terminal del host abierto — la barra de arriba muestra el recuento (<em>1 / 4 terminals</em>), <em>+ New</em>, <em>Search</em>, <em>Clear</em> y <em>Close</em>. Las ayudas de teclado para móvil aparecen bajo el terminal en dispositivos táctiles.",
@@ -20,24 +20,24 @@
"body2": "Para llegar a un <strong>contenedor LXC</strong> desde el navegador, usa el botón <em>Console</em> dedicado en cada tarjeta de CT en ejecución de la <link>pestaña VMs y LXCs</link>. Abre una modal que ejecuta <code>pct enter &lt;vmid&gt;</code> y reutiliza la misma barra para móvil descrita abajo."
},
"menuGuard": {
"heading": "Guarda de autoactualización cuando menu corre dentro de este terminal",
"body1": "El <code>menu</code> de ProxMenux se autoactualiza en sitio: aceptar el prompt reemplaza su propio árbol de scripts y recarga. Eso funciona bien por SSH o desde la consola de Proxmox, pero el terminal del navegador no puede sobrevivir a ello — la actualización desmonta la propia PTY sobre la que corre la shell y el WebSocket cae a mitad. Para no dejar la sesión colgada, los handlers internos <code>check_updates_stable</code>, <code>check_updates_beta</code> y <code>apply_release_channel</code> leen <code>PROXMENUX_TERMINAL</code> y detectan el contexto Monitor.",
"body2": "Al detectarlo, el diálogo clásico sí / no se sustituye por un msgbox informativo con el instalador canónico de una línea — <code>bash -c \"$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)\"</code> para el canal estable, y la URL equivalente de <code>install_proxmenux_beta.sh</code> para beta. La actualización propiamente dicha se deja para una sesión SSH o la consola del host Proxmox; el terminal del navegador solo se usa para confirmar y leer el comando."
"heading": "Protección de autoactualización de menu en este terminal",
"body1": "<code>menu</code> se autoactualiza sustituyendo su árbol de scripts y recargándose al aceptar. Funciona por SSH o consola Proxmox, pero en el navegador cerraría la PTY de la shell e interrumpiría el WebSocket. Para evitarlo, <code>check_updates_stable</code>, <code>check_updates_beta</code> y <code>apply_release_channel</code> consultan <code>PROXMENUX_TERMINAL</code> y detectan el contexto Monitor.",
"body2": "Al detectarlo, el diálogo sí/no se sustituye por un mensaje informativo con el comando oficial del instalador: <code>bash -c \"$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)\"</code> para estable y la URL equivalente de <code>install_proxmenux_beta.sh</code> para beta. Ejecuta la actualización por SSH o consola del host Proxmox; el terminal del navegador solo permite leer y confirmar el mensaje."
},
"fourTerminals": {
"heading": "Hasta cuatro terminales a la vez",
"intro": "La pestaña te permite abrir hasta cuatro terminales del host simultáneamente. Cada uno obtiene su propia PTY y su propio WebSocket — son sesiones totalmente independientes. Dos layouts se alternan con los iconos junto al botón \"New\":",
"intro": "La pestaña permite abrir hasta cuatro terminales del host simultáneamente, cada uno con su propia PTY y WebSocket: son sesiones independientes. Los iconos junto a «Nuevo» alternan entre dos disposiciones:",
"items": [
"<strong>Vista en pestañas</strong> — un terminal visible a la vez, los demás como pestañas nombradas arriba (<em>Terminal 1</em>, <em>Terminal 2</em>…). Ideal para trabajar en una tarea con el resto en background.",
"<strong>Vista en rejilla</strong> — todos los terminales abiertos visibles a la vez en una rejilla 2×2. Útil para vigilar <code>htop</code> en un panel, <code>iftop</code> en otro y editar en un tercero sin saltar entre ellos."
"<strong>Vista en pestañas</strong>: un terminal visible y los demás como pestañas con nombre arriba (<em>Terminal 1</em>, <em>Terminal 2</em>…). Adecuado para trabajar en una tarea con las otras en segundo plano.",
"<strong>Vista en rejilla</strong>: todos los terminales abiertos en una rejilla 2×2. Permite vigilar <code>htop</code> en uno, <code>iftop</code> en otro y editar en un tercero sin cambiar de pestaña."
],
"outro": "La barra muestra el recuento actual (<em>1/4 terminals</em>, <em>4/4 terminals</em>). Las nuevas pestañas se abren con <strong>+ New</strong> y las individuales se cierran desde la pequeña <code>×</code> en la cabecera de la pestaña. El botón rojo grande <strong>Close</strong> de arriba derriba todos los terminales a la vez."
"outro": "La barra muestra el recuento (<em>1/4 terminales</em>, <em>4/4 terminales</em>). <strong>+ Nuevo</strong> abre una pestaña y la <code>×</code> de su cabecera cierra solo esa. El botón rojo grande <strong>Cerrar</strong> de arriba cierra todos los terminales."
},
"gridAlt": "Pestaña Terminal de ProxMenux Monitor — vista en rejilla con cuatro terminales del host ejecutando ls, configuración de red, iftop y el menú principal de ProxMenux uno al lado del otro",
"gridCaption": "Vista en rejilla (4 / 4 terminals) — cuatro PTYs del host independientes corriendo en paralelo: listado de directorio, <code>/etc/network/interfaces</code> en un lado, <code>iftop</code> en otro y el menú principal de ProxMenux en el cuarto. Alterna entre rejilla y pestañas con el conmutador de layout en la barra.",
"gridCaption": "Vista en rejilla (4 / 4 terminales): cuatro PTY independientes en paralelo, con listado de directorio, <code>/etc/network/interfaces</code>, <code>iftop</code> y el menú principal de ProxMenux. Alterna entre rejilla y pestañas con el selector de disposición de la barra.",
"keyboard": {
"heading": "Ayudas de teclado para móvil",
"intro": "Los teclados de móvil y tablet normalmente no exponen ESC, TAB, las flechas ni combinaciones con modificadores. Sin ellos, navegar por <code>vim</code>, <code>nano</code>, <code>htop</code> o cualquier menú TUI es imposible. La pestaña Terminal lo resuelve renderizando una fila de botones táctiles bajo el terminal siempre que el dispositivo sea suficientemente pequeño o tenga capacidad táctil:",
"heading": "Botones de teclado para dispositivos móviles",
"intro": "Los teclados de móvil y tablet suelen carecer de ESC, TAB, flechas y combinaciones de modificadores. Estas teclas son necesarias para manejar <code>vim</code>, <code>nano</code>, <code>htop</code> o menús TUI. Terminal añade botones táctiles debajo cuando la pantalla es pequeña o el dispositivo admite interacción táctil:",
"headerButton": "Botón",
"headerSends": "Envía",
"headerUse": "Uso típico",
@@ -50,7 +50,7 @@
{
"button": "TAB",
"sends": "\\t",
"use": "Autocompletado de rutas, navegación de campos en dialog/whiptail."
"use": "Autocompletado de rutas y navegación entre campos en dialog/whiptail."
},
{
"button": "↑ ↓ ← →",
@@ -58,9 +58,9 @@
"use": "Historial de la shell, movimiento del cursor, navegación de menús."
},
{
"button": "↵ Enter",
"button": "↵ Intro",
"sends": "\\r",
"use": "Confirmar. Algunos teclados en pantalla cambian Enter por Go/Done — este botón es inequívoco."
"use": "Confirmar. Algunos teclados en pantalla sustituyen Intro por Ir/Hecho; este botón evita ambigüedades."
},
{
"button": "Ctrl ▾",
@@ -71,46 +71,46 @@
"ctrlIntro": "Tres secuencias de control:",
"ctrlItems": [
"<code>Ctrl+C</code> — cancelar / interrumpir el comando en ejecución (<code>\\x03</code>).",
"<code>Ctrl+X</code> — salir de <code>nano</code> (<code>\\x18</code>).",
"<code>Ctrl+R</code> — búsqueda inversa en el historial de bash (<code>\\x12</code>)."
"<code>Ctrl+X</code>: salir de <code>nano</code> (<code>\\x18</code>).",
"<code>Ctrl+R</code>: búsqueda inversa en el historial de bash (<code>\\x12</code>)."
],
"modalTitle": "Misma barra en la modal de consola LXC",
"modalBody": "La consola del contenedor que lanzas desde <link>VMs y LXCs → Console</link> renderiza las mismas ayudas de teclado bajo la modal. La modal además auto-tipea <code>pct enter &lt;vmid&gt;</code> al conectar, para que aterrices directamente dentro del contenedor."
"modalTitle": "La misma barra en la ventana de consola LXC",
"modalBody": "La consola que abres desde <link>VMs y LXCs → Consola</link> muestra los mismos botones de teclado bajo la ventana. Al conectar, introduce automáticamente <code>pct enter &lt;vmid&gt;</code> para entrar directamente en el contenedor."
},
"lxcAlt": "Modal de consola LXC de ProxMenux Monitor — Terminal: ubuntu (ID: 103) con la misma barra para móvil (ESC, TAB, flechas, Enter, Ctrl) bajo el terminal",
"lxcCaption": "La modal de consola LXC — abierta desde <em>VMs y LXCs → Console</em>. La cabecera muestra el contenedor de destino (<em>Terminal: ubuntu (ID: 103)</em>) y la misma barra táctil aparece bajo el terminal.",
"lxcAlt": "Ventana de consola LXC de ProxMenux Monitor — Terminal: ubuntu (ID: 103), con la misma barra para móviles (ESC, TAB, flechas, Intro, Ctrl) debajo",
"lxcCaption": "Consola LXC abierta desde <em>VMs y LXCs → Consola</em>. La cabecera identifica el contenedor (<em>Terminal: ubuntu (ID: 103)</em>) y debajo del terminal aparece la misma barra táctil.",
"search": {
"heading": "Search Commands — chuleta integrada",
"intro": "El botón azul <strong>Search</strong> de la barra abre una modal con búsqueda difusa de comandos. Escribe unas letras de cualquier comando de Linux o Proxmox (<code>ls</code>, <code>tar</code>, <code>qm</code>, <code>pct</code>, <code>zpool</code>, <code>systemctl</code>…) y la modal lista ejemplos de uso con <em>Send to active terminal</em> de un solo toque. Elimina el viaje de ida y vuelta \"espera, ¿qué flag era esa?\" a otra pestaña del navegador.",
"modalAlt": "Modal Search Commands de ProxMenux Monitor — búsqueda difusa de comandos de Linux y Proxmox con cheat.sh, mostrando varios ejemplos de uso de ls",
"modalCaption": "La modal Search Commands consultando <code>ls</code> — cada resultado muestra el comando, su descripción y una pequeña flecha \"send\" que lo canaliza al terminal activo. La esquina inferior derecha indica la fuente de los datos (<em>Powered by cheat.sh</em>).",
"heading": "Buscar comandos: guía de referencia integrada",
"intro": "El botón azul <strong>Buscar</strong> abre una búsqueda aproximada de comandos. Escribe unas letras de un comando Linux o Proxmox (<code>ls</code>, <code>tar</code>, <code>qm</code>, <code>pct</code>, <code>zpool</code>, <code>systemctl</code>…) para ver ejemplos de uso y <em>Enviar al terminal activo</em> con un toque. Así puedes consultar sus opciones sin cambiar de pestaña.",
"modalAlt": "Ventana Buscar comandos de ProxMenux Monitor: búsqueda aproximada de comandos Linux y Proxmox con cheat.sh y varios ejemplos de ls",
"modalCaption": "Buscar comandos con la consulta <code>ls</code>: cada resultado muestra comando, descripción y una flecha de envío al terminal activo. La esquina inferior derecha indica la fuente (<em>Con tecnología de cheat.sh</em>).",
"aboutLabel": "Sobre cheat.sh:",
"aboutBody": "es una chuleta unificada de código abierto y curada por la comunidad que agrega ejemplos cortos y prácticos de uso para cientos de comandos de Linux, herramientas de sysadmin y lenguajes de programación. Diseñada originalmente para consultarse desde un terminal con <code>curl cheat.sh/&lt;command&gt;</code>, también es accesible desde cualquier navegador. ProxMenux Monitor pasa las consultas por un proxy en el servidor para que la modal siga funcionando bajo el mismo origen que el panel.",
"aboutBody": "es una guía de referencia de código abierto mantenida por la comunidad, con ejemplos breves y prácticos de cientos de comandos Linux, herramientas de administración y lenguajes de programación. Diseñada para consultarse con <code>curl cheat.sh/&lt;command&gt;</code>, también funciona en el navegador. ProxMenux Monitor envía las consultas mediante un proxy del servidor para mantener el mismo origen que el panel.",
"headerSource": "Fuente",
"headerWhen": "Cuándo se usa",
"headerWhat": "Lo que ves",
"onlineLabel": "(online)",
"onlineLabel": "(en línea)",
"onlineWhen": "Cuando el host tiene acceso a internet y el proxy de cheat.sh responde.",
"onlineWhat": "Varios ejemplos del mundo real por comando, tipeados con su descripción encima. El punto de estado en la cabecera de la modal es <green>verde</green>.",
"fallbackLabel": "Fallback local",
"onlineWhat": "Varios ejemplos prácticos por comando con su descripción encima. El punto de estado de la cabecera es <green>verde</green>.",
"fallbackLabel": "Alternativa local",
"fallbackWhen": "Cuando cheat.sh no está disponible (host offline, firewall restrictivo, caída de cheat.sh).",
"fallbackWhat": "Una lista empaquetada de comandos comunes de Linux + Proxmox. Catálogo más pequeño pero siempre disponible. El punto de estado es <red>rojo</red>.",
"sendingNote": "<strong>Cómo funciona el envío</strong>: pulsar la pequeña flecha \"send\" junto a un resultado reenvía el texto del comando al terminal que esté activo en ese momento (la pestaña enfocada, o la última en la que pulsaste en la vista en rejilla). La modal se cierra automáticamente para que puedas darle a Enter inmediatamente."
"fallbackWhat": "Una lista incluida de comandos habituales Linux y Proxmox. El catálogo es menor, pero siempre está disponible. El punto de estado es <red>rojo</red>.",
"sendingNote": "<strong>Cómo funciona el envío</strong>: la flecha junto al resultado envía el texto al terminal activo (la pestaña enfocada o el último terminal pulsado en rejilla). La ventana se cierra automáticamente para que puedas pulsar Intro."
},
"auth": {
"heading": "Autenticación",
"items": [
"El upgrade WebSocket lleva el JWT en la cabecera <code>Authorization</code>. Si la autenticación está activa y el token falta o ha caducado, la conexión se rechaza con HTTP 401 antes de asignar una PTY.",
"El navegador primero solicita un ticket de un solo uso mediante <code>POST /api/terminal/ticket</code>, autenticado con JWT en la cabecera <code>Authorization</code>. Después envía ese ticket al abrir el WebSocket. Caduca a los 5 segundos; si la autenticación está activa y falta o no es válido, se cierra la conexión antes de crear una PTY.",
"Si el Monitor está detrás de un reverse proxy, el proxy debe reenviar los upgrades WebSocket. Mira la página <link>Acceso y autenticación</link> para snippets de Nginx / Caddy / Traefik."
]
},
"clipboard": {
"heading": "Portapapeles, scrollback y resize",
"heading": "Portapapeles, historial de pantalla y tamaño",
"items": [
"<strong>Copiar / pegar</strong> — usa el portapapeles nativo del navegador. Selecciona texto con el ratón / trackpad y usa el atajo del SO (<code>Cmd+C</code> en macOS, <code>Ctrl+Shift+C</code> en Linux/Windows). Los escritorios Linux también soportan pegar con el botón central del ratón.",
"<strong>Scrollback</strong> — rueda / scroll con dos dedos. xterm.js mantiene las últimas varios miles de líneas en memoria.",
"<strong>Resize</strong> — el terminal renegocia el tamaño de ventana de la PTY cuando redimensionas el panel del dashboard, así <code>htop</code> y <code>vim</code> renderizan bien.",
"<strong>Reconexión al recuperar foco de la pestaña</strong> — si cambias de app en móvil o tablet (comportamiento habitual en iPad), el WebSocket normalmente caería. La pestaña Terminal detecta el cambio de visibilidad y reconecta automáticamente al volver, con un timeout de 15 segundos para rutas VPN lentas."
"<strong>Copiar y pegar</strong>: usa el portapapeles del navegador. Selecciona texto con ratón o trackpad y usa el atajo del sistema (<code>Cmd+C</code> en macOS, <code>Ctrl+Shift+C</code> en Linux/Windows). Los escritorios Linux también permiten pegar con clic central.",
"<strong>Historial de pantalla</strong>: rueda o desplazamiento con dos dedos. xterm.js conserva en memoria los últimos miles de líneas.",
"<strong>Cambiar tamaño</strong>: al redimensionar el panel se ajusta la ventana PTY para mostrar correctamente <code>htop</code> y <code>vim</code>.",
"<strong>Reconexión al volver a la pestaña</strong>: cambiar de app en móvil o tablet, especialmente iPad, puede cortar el WebSocket. Terminal detecta el cambio de visibilidad y reconecta al volver, con un tiempo de espera de 15 segundos para VPN lentas."
]
},
"disconnect": {
@@ -120,26 +120,26 @@
"headerFix": "Solución",
"rows": [
{
"cause": "JWT de sesión caducado (ventana de 24 h).",
"cause": "JWT de sesión caducado al abrir o reconectar un terminal (ventana de 24 h).",
"fix": "Refresca la página y vuelve a hacer login. El terminal no está pensado para sesiones desatendidas, así que el tiempo de vida del JWT coincide con el del login normal del panel."
},
{
"cause": "Timeout de idle del reverse proxy.",
"fix": "Sube <code>proxy_read_timeout</code> en Nginx o el equivalente en Caddy / Traefik (snippets en Acceso y autenticación)."
"cause": "Tiempo de espera por inactividad del proxy inverso.",
"fix": "Aumenta <code>proxy_read_timeout</code> en Nginx o su equivalente en Caddy / Traefik (ejemplos en Acceso y autenticación)."
},
{
"cause": "Móvil o tablet en sleep.",
"fix": "Cuando el dispositivo despierta, la pestaña auto-reconecta (timeout de 15 s para rutas VPN). Si no lo hace, recarga la pestaña."
"cause": "Móvil o tablet en reposo.",
"fix": "Al reactivarse el dispositivo, la pestaña reconecta automáticamente (15 s de espera para rutas VPN). Si falla, recárgala."
},
{
"cause": "Reinicio del servicio en el host.",
"fix": "Cualquier reinicio de <code>proxmenux-monitor.service</code> tira todas las PTY. Abre nuevos terminales una vez el panel termine de recargar."
"fix": "Reiniciar <code>proxmenux-monitor.service</code> cierra todas las PTY. Abre nuevos terminales cuando el panel termine de recargarse."
}
]
},
"warning": {
"title": "El terminal es una shell de root sobre el host",
"body": "El terminal hereda la identidad de la unidad systemd (<code>root</code>) y por tanto tiene privilegios totales sobre el host Proxmox. Configura un usuario, contraseña y 2FA en <authLink>Acceso y autenticación</authLink> antes de exponer el panel más allá de tu red local: cualquiera que llegue al puerto 8008 sin autenticación aterrizaría directamente en una shell de root — sin prompts adicionales, sin credenciales SSH. Para acceso desde fuera de la LAN, enruta el panel a través de <gatewayLink>Secure Gateway</gatewayLink> (Tailscale) o un reverse proxy con HTTPS, en lugar de abrir el puerto a la internet pública."
"title": "El terminal es una shell de root en el host",
"body": "El terminal hereda el usuario de la unidad systemd (<code>root</code>) y tiene todos los privilegios del host Proxmox. Configura usuario, contraseña y 2FA en <authLink>Acceso y autenticación</authLink> antes de dar acceso fuera de tu red local. Con la autenticación desactivada, quien llegue al puerto 8008 puede abrir una shell de root sin más confirmaciones ni credenciales SSH. Para acceso externo, usa <gatewayLink>Secure Gateway</gatewayLink> (Tailscale) o un proxy inverso HTTPS en lugar de publicar el puerto en Internet."
},
"whereNext": {
"heading": "Por dónde seguir",
@@ -147,17 +147,17 @@
{
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tail": " — snippets de reverse proxy incluyendo las líneas de upgrade WebSocket que requiere el terminal."
"tail": " — ejemplos de proxy inverso con las líneas de cambio de protocolo WebSocket necesarias para el terminal."
},
{
"label": "Arquitectura",
"href": "/docs/monitor/architecture",
"tail": " — el transporte WebSocket (HTTP vía flask-sock vs HTTPS / WSS vía gevent)."
"tail": " — transporte WebSocket (HTTP mediante flask-sock y HTTPS / WSS mediante gevent)."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints WebSocket /ws/terminal y /ws/script/<sid> junto al resto de la API."
"tail": " — endpoints WebSocket /ws/terminal y /ws/script/<sid>, junto al resto de la API."
},
{
"label": "Integraciones → Secure Gateway",
@@ -12,7 +12,7 @@
"p2": "El procedimiento que modifica el software se configura por separado en la <link>pestaña Actualizaciones</link>. Guardar una app nunca ejecuta un instalador ni un actualizador.",
"callout": "El registro, el seguimiento de versiones y la actualización son tres capacidades independientes. Cada una puede utilizarse sin exigir las otras dos.",
"dashboardTitle": "Del registro al lanzador Apps",
"dashboard": "Cada enlace web guardado aquí también se muestra como una tarjeta en la <appsLink>pestaña Apps</appsLink> principal. Esta página del LXC sigue siendo la fuente original para el nombre, el logotipo, los enlaces y el seguimiento de versión de la aplicación."
"dashboard": "Cada enlace web guardado aquí aparece también como tarjeta en la <appsLink>pestaña Apps</appsLink> principal. Esta página del LXC sigue siendo la referencia para nombre, logotipo, enlaces y seguimiento de versiones."
},
"overview": {
"heading": "Qué puede contener un registro",
@@ -31,7 +31,7 @@
"lead": "Las aplicaciones sugeridas forman parte de la caché del modal de cada LXC. El escaneo de arranque las prepara en segundo plano para que la pestaña App pueda mostrar inmediatamente los resultados almacenados.",
"items": [
"Abrir la pestaña App <strong>no</strong> inicia otro escaneo del catálogo ni consulta repetidamente el LXC.",
"<strong>Buscar aplicaciones</strong> ejecuta expresamente una detección nueva solo para ese LXC. Se utiliza después de instalar software mientras ProxMenux ya está en ejecución.",
"<strong>Buscar aplicaciones</strong> ejecuta una detección nueva para ese LXC. Úsalo tras instalar software nuevo mientras ProxMenux ya está en ejecución.",
"La lista anterior permanece visible durante la búsqueda. Las nuevas coincidencias se añaden al finalizar.",
"Si no se encuentra ninguna coincidencia nueva, el resultado aparece junto a las acciones y <strong>Registrar aplicación</strong> continúa disponible para introducirla manualmente.",
"Guardar, eliminar o restaurar una app actualiza la misma caché inmediatamente. El arranque o la restauración de un LXC actualiza únicamente ese sistema mediante su evento de ciclo de vida existente."
@@ -42,10 +42,10 @@
"heading": "Registrar una aplicación",
"lead": "Las sugerencias detectadas y los registros manuales utilizan el mismo editor:",
"steps": [
"Pulsa <strong>Registrar</strong> en una sugerencia o <strong>Registrar aplicación</strong> para elegir una entrada del catálogo o escribir un nombre personalizado.",
"Pulsa <strong>Registrar</strong> en una sugerencia o <strong>Registrar aplicación</strong> para elegir del catálogo o introducir un nombre personalizado.",
"Revisa el nombre y el logotipo propuestos por el catálogo.",
"Añade los enlaces web necesarios. Los puertos en escucha se ofrecen como accesos rápidos, pero ninguno se guarda automáticamente.",
"Deja <strong>Seguir versión disponible</strong> desactivado para un registro de solo enlace o actívalo y revisa el detector instalado y la fuente disponible.",
"Deja <strong>Seguir versión disponible</strong> desactivado para registros de solo enlace, o actívalo y revisa el detector de la versión instalada y la fuente de la versión disponible.",
"Utiliza <strong>Probar detector</strong> cuando el seguimiento esté activado y guarda el registro.",
"Pulsa <strong>Hecho</strong> al terminar la edición. Las pestañas App y Actualizaciones reutilizan el registro actualizado de la caché."
]
@@ -80,7 +80,7 @@
"Cada enlace guarda un esquema, un puerto, una descripción opcional y una URL de logotipo opcional.",
"La URL mostrada utiliza la dirección actual ya detectada para el LXC; esa dirección no se duplica en cada registro.",
"Un enlace sin logotipo propio utiliza el logotipo general de la app.",
"Varios enlaces pueden representar una interfaz de administración, una API, una interfaz secundaria u otro punto final de la misma app.",
"Varios enlaces pueden representar una interfaz de administración, una API, una interfaz secundaria u otro endpoint de la misma app.",
"Una app guardada solo con enlaces también aparece en Actualizaciones, donde se puede configurar posteriormente un actualizador personalizado."
]
},
@@ -90,24 +90,48 @@
"colMethod": "Método de versión instalada",
"colUse": "Uso",
"detectorRows": [
{ "method": "dpkg / apk", "use": "Lee la versión del paquete instalado desde los metadatos de Debian, Ubuntu o Alpine." },
{ "method": "binary", "use": "Ejecuta una ruta binaria absoluta o un nombre de comando con sus parámetros de versión." },
{ "method": "file + regex", "use": "Lee un archivo real y extrae la versión mediante un grupo de captura." },
{ "method": "docker label / docker exec", "use": "Lee una etiqueta de versión OCI o ejecuta un comando de versión dentro de un contenedor Docker." },
{ "method": "python distribution", "use": "Usa importlib.metadata mediante el intérprete de Python seleccionado." },
{ "method": "command", "use": "Ejecuta un comando avanzado en formato argv, sin shell, y extrae la versión de su salida." },
{ "method": "manual", "use": "Guarda una versión introducida manualmente; debe cambiarse después de actualizar la app." },
{ "method": "OCI image", "use": "Para contenedores instalados por OCI manager Apps. Lee las versiones de la aplicación y de la imagen del registro de la instalación y compara el digest instalado con el que publica el registro; no necesita configuración." }
{
"method": "dpkg / apk",
"use": "Lee la versión del paquete instalado desde los metadatos de Debian, Ubuntu o Alpine."
},
{
"method": "binary",
"use": "Ejecuta una ruta binaria absoluta o un nombre de comando con sus parámetros de versión."
},
{
"method": "file + regex",
"use": "Lee un archivo real y extrae la versión mediante un grupo de captura."
},
{
"method": "docker label / docker exec",
"use": "Lee una etiqueta de versión OCI o ejecuta un comando de versión dentro de un contenedor Docker."
},
{
"method": "python distribution",
"use": "Usa importlib.metadata mediante el intérprete de Python seleccionado."
},
{
"method": "command",
"use": "Ejecuta un comando avanzado en formato argv, sin shell, y extrae la versión de su salida."
},
{
"method": "manual",
"use": "Guarda una versión introducida manualmente; debe cambiarse después de actualizar la app."
},
{
"method": "OCI image",
"use": "Para contenedores instalados por OCI manager Apps. Lee las versiones de app e imagen del registro de instalación y compara el digest instalado con el publicado por el registro de imágenes. No necesita configuración."
}
],
"sourcesHeading": "Fuentes para la versión disponible",
"sources": [
"<strong>Repositorio de GitHub</strong>: último lanzamiento o etiqueta de un repositorio público <code>owner/name</code>.",
"<strong>HTTP JSON</strong>: un punto final público y una ruta como <code>data.version</code> o <code>releases[0].tag_name</code>.",
"<strong>HTTP JSON</strong>: un endpoint público y una ruta con puntos, como <code>data.version</code> o <code>releases[0].tag_name</code>.",
"<strong>Docker Hub</strong>: etiquetas versionadas filtradas con una expresión regular. La vista previa muestra etiquetas reales coincidentes antes de guardar.",
"Las etiquetas móviles como <code>latest</code>, <code>stable</code> o <code>lts</code> no contienen una versión. Esas imágenes se siguen por digest desde las actualizaciones de imágenes Docker."
"Etiquetas móviles como <code>latest</code>, <code>stable</code> o <code>lts</code> no contienen una versión. Sigue esas imágenes por digest en las actualizaciones de imágenes Docker."
],
"regexHeading": "Expresión de captura",
"regexLead": "La expresión regular del detector debe devolver la versión en su <strong>primer grupo de captura</strong>.",
"regexLead": "La expresión regular debe devolver la versión en su <strong>primer grupo de captura</strong>.",
"regexRules": [
"Haz coincidir el texto emitido por el binario, archivo, comando o fuente de etiquetas seleccionada; no supongas una ruta genérica.",
"Escapa los puntos literales como <code>\\.</code> para que no coincidan con cualquier carácter.",
@@ -135,11 +159,31 @@
"colDisplay": "Presentación",
"colMeaning": "Significado",
"rows": [
{ "state": "Actualización disponible", "display": "Versión disponible en morado con un icono de flecha ascendente", "meaning": "Las versiones instalada y disponible son diferentes." },
{ "state": "Actualizada", "display": "Versiones instalada y disponible sin la alerta morada", "meaning": "La última comprobación no encontró una versión superior." },
{ "state": "Seguimiento pendiente", "display": "Estado de comprobación o pendiente", "meaning": "El registro está configurado, pero aún no ha completado las dos comprobaciones." },
{ "state": "Seguimiento desactivado", "display": "Solo enlaces web, sin bloque de comparación", "meaning": "El registro sigue siendo válido y puede tener un actualizador." },
{ "state": "Error de comprobación", "display": "Explicación en ámbar dentro de la tarjeta", "meaning": "El estado guardado anterior permanece visible mientras se informa del error del detector o de la fuente." }
{
"state": "Actualización disponible",
"display": "Versión disponible en morado con un icono de flecha ascendente",
"meaning": "Las versiones instalada y disponible son diferentes."
},
{
"state": "Actualizada",
"display": "Versiones instalada y disponible sin la alerta morada",
"meaning": "La última comprobación no encontró una versión superior."
},
{
"state": "Seguimiento pendiente",
"display": "Estado de comprobación o pendiente",
"meaning": "El registro está configurado, pero aún no ha completado las dos comprobaciones."
},
{
"state": "Seguimiento desactivado",
"display": "Solo enlaces web, sin bloque de comparación",
"meaning": "El registro sigue siendo válido y puede tener un actualizador."
},
{
"state": "Error de comprobación",
"display": "Explicación en ámbar dentro de la tarjeta",
"meaning": "El estado guardado anterior permanece visible mientras se informa del error del detector o de la fuente."
}
]
},
"management": {
@@ -158,11 +202,26 @@
"colProblem": "Situación",
"colResolution": "Resolución",
"rows": [
{ "problem": "Se instaló software después de arrancar ProxMenux", "resolution": "Pulsa Buscar aplicaciones. El escaneo explícito actualiza las sugerencias en caché de ese LXC." },
{ "problem": "No se detectó la aplicación", "resolution": "Regístrala manualmente. Un nombre y un enlace web son suficientes; el seguimiento puede añadirse después." },
{ "problem": "El detector sugerido devuelve una versión incorrecta", "resolution": "Abre Editar campos, selecciona el paquete, binario o archivo real y prueba el detector antes de guardar." },
{ "problem": "Una carga Docker no se ofrece como app LXC", "resolution": "Registra Docker y añade la interfaz publicada de la carga como enlace web de Docker. Las actualizaciones de imágenes permanecen en la sección Docker." },
{ "problem": "Una app guardada no tiene botón de actualización", "resolution": "Abre Actualizaciones y configura su método. El seguimiento de versiones no define por sí solo cómo se instala una actualización." }
{
"problem": "Se instaló software después de arrancar ProxMenux",
"resolution": "Pulsa Buscar aplicaciones. El escaneo explícito actualiza las sugerencias en caché de ese LXC."
},
{
"problem": "No se detectó la aplicación",
"resolution": "Regístrala manualmente. Un nombre y un enlace web son suficientes; el seguimiento puede añadirse después."
},
{
"problem": "El detector sugerido devuelve una versión incorrecta",
"resolution": "Abre Editar campos, selecciona el paquete, binario o archivo real y prueba el detector antes de guardar."
},
{
"problem": "Una carga Docker no se ofrece como app LXC",
"resolution": "Registra Docker y añade la interfaz publicada de la carga como enlace web de Docker. Las actualizaciones de imágenes permanecen en la sección Docker."
},
{
"problem": "Una app guardada no tiene botón de actualización",
"resolution": "Abre Actualizaciones y configura su método. El seguimiento de versiones no define por sí solo cómo se instala una actualización."
}
]
},
"figures": {
@@ -19,13 +19,13 @@
"<strong>Paquetes del SO</strong> para contenedores Debian, Ubuntu y Alpine.",
"Una sección por cada <strong>aplicación registrada</strong>, incluidos los registros que solo contienen enlaces.",
"Una sección <strong>Docker</strong> cuando Docker está registrado, con Docker Engine y las imágenes etiquetadas dentro del mismo bloque.",
"Una <strong>Actualización en bloque</strong> configurable, seguida de las opciones de copia, reinicio y programación."
"Una <strong>Actualización en bloque</strong> configurable, seguida de las opciones de backup, reinicio y programación."
]
},
"mechanisms": {
"heading": "Cómo se selecciona el método",
"lead": "La vía integrada de Proxmox VE Helper-Scripts sigue el mecanismo oficial <helper>update-apps</helper>. El resto de instalaciones usa el método de paquetes, Docker o el comando personalizado correspondiente.",
"officialReference": "Referencia oficial: la <helper>documentación de update-apps de Proxmox VE Helper-Scripts</helper> explica los modos interactivo y desatendido, las copias de seguridad, la simulación, los recursos temporales de compilación, los registros y los códigos de salida.",
"officialReference": "Referencia oficial: la <helper>documentación de update-apps de Proxmox VE Helper-Scripts</helper> explica los modos interactivo y desatendido, los backups, la simulación, los recursos temporales de compilación, los registros y los códigos de salida.",
"colSource": "Origen",
"colAction": "Acción mostrada",
"colNotes": "Qué se ejecuta",
@@ -56,7 +56,7 @@
"notes": "Descarga la imagen seleccionada y recrea su grupo de servicios Compose o su contenedor independiente protegido."
}
],
"callout": "El comando personalizado <strong>reemplaza</strong> a Helper-Scripts para esa aplicación. Las ejecuciones manuales, en bloque y programadas respetan la elección guardada. Se conservan los comandos existentes y las selecciones antiguas guardadas en planes o programaciones activadas; una programación antigua nunca activa el actualizador de una app recién registrada."
"callout": "Un comando personalizado <strong>reemplaza</strong> Helper-Scripts para esa app. Las ejecuciones manuales, en bloque y programadas respetan la elección. Se conservan los comandos existentes y las selecciones antiguas guardadas expresamente en planes o programaciones activadas; una programación antigua nunca incorpora una app recién registrada."
},
"docker": {
"heading": "Docker Engine e imágenes Docker",
@@ -84,13 +84,13 @@
"statusColMeaning": "Significado",
"statusRows": [
{
"state": "Actualización verificada",
"state": "Actualización verificada disponible",
"appearance": "Texto morado, icono de flecha ascendente y acción morada",
"meaning": "La versión instalada y la disponible, o los digests de imagen, son diferentes."
},
{
"state": "Actualizado y verificado",
"appearance": "Comprobación verde y acción Actualizado en verde",
"appearance": "Marca de verificación verde y acción Actualizado en verde",
"meaning": "La última comprobación terminada confirma que el objetivo está actualizado."
},
{
@@ -120,16 +120,16 @@
"Los paquetes del SO son obligatorios. Debe seleccionarse al menos una app, Docker Engine o unidad de imagen Docker adicional.",
"Las aplicaciones y unidades Docker se seleccionan individualmente. Un servicio principal de Compose muestra las dependencias que se actualizarán con él.",
"Los objetivos eliminados o no disponibles se marcan como obsoletos y deben retirarse antes de guardar la configuración.",
"El botón <strong>Aplicar actualizaciones</strong> es morado si algún objetivo seleccionado tiene una actualización verificada, verde si todos están verificados como actualizados y neutro cuando el resultado es desconocido.",
"<strong>Aplicar actualizaciones</strong> es morado si algún objetivo tiene una actualización verificada, verde si todos están verificados como actualizados y neutro si el resultado es desconocido.",
"Eliminar la configuración en bloque no borra los métodos individuales ni la programación."
],
"callout": "La actualización en bloque no reemplaza los botones individuales. Es un acceso opcional para una selección que debe ejecutarse junta."
},
"options": {
"heading": "Opciones de copia y reinicio",
"heading": "Opciones de backup y reinicio",
"lead": "Las mismas opciones se aplican a ejecuciones manuales, en bloque y programadas:",
"items": [
"<strong>Instantánea antes de aplicar</strong> crea una copia vzdump en el almacenamiento seleccionado. Si la copia solicitada falla, la actualización no comienza.",
"<strong>Backup antes de aplicar</strong> crea un backup vzdump en el almacenamiento seleccionado. Si el backup solicitado falla, la actualización no comienza.",
"<strong>Reiniciar después de aplicar</strong> reinicia el LXC únicamente tras una ejecución correcta.",
"Las selecciones se guardan por LXC y son independientes de la lista de objetivos."
]
@@ -140,7 +140,7 @@
"items": [
"Selecciona una frecuencia o expresión cron y después objetivos exactos: paquetes del SO, apps individuales, Docker Engine, unidades Docker independientes o grupos de servicios Compose.",
"La espera tras una versión solo se aplica a las apps seleccionadas con seguimiento. Las apps sin seguimiento ejecutan su actualizador cuando vence la programación.",
"El estado de la última ejecución diferencia entre éxito, finalización parcial, error, retención de seguridad y ausencia de elementos pendientes. Después de la primera ejecución programada, <strong>Actualizaciones → Actualizaciones programadas → Ver log</strong> abre la salida completa capturada del actualizador y de los scripts secundarios que haya ejecutado.",
"El estado de la última ejecución distingue éxito, finalización parcial, fallo, retención de seguridad y ausencia de actualizaciones pendientes. Tras la primera ejecución programada, <strong>Actualizaciones → Actualizaciones programadas → Ver registro</strong> abre toda la salida del actualizador y de los scripts secundarios invocados.",
"Después de cada ejecución, ProxMenux comprueba el marcador estándar de Debian que indica si es necesario reiniciar. Cuando hace falta, la pestaña Actualizaciones y la notificación de finalización lo indican; el aviso se elimina cuando ese LXC se inicia o reinicia.",
"En el host Proxmox, los logs de las ejecuciones programadas se guardan en <code>/usr/local/share/proxmenux/logs/lxc-updates/</code> con el nombre <code>&lt;VMID&gt;-scheduled-&lt;run-id&gt;.log</code>. Se conservan los diez últimos logs de cada LXC y los archivos más antiguos se eliminan automáticamente.",
"Este historial corresponde a las actualizaciones programadas. Una actualización manual muestra su salida en tiempo real en la ventana de ejecución del Monitor y no crea un log de ejecución programada en ese directorio.",
@@ -196,8 +196,8 @@
"caption": "La sección del sistema operativo mantiene los paquetes separados de las acciones de aplicaciones y Docker."
},
"options": {
"alt": "Opciones de actualización LXC con copia previa y reinicio posterior",
"caption": "Las preferencias de copia y reinicio se aplican a ejecuciones manuales, en bloque y programadas."
"alt": "Opciones de actualización LXC con backup previo y reinicio posterior",
"caption": "Las preferencias de backup y reinicio se aplican a ejecuciones manuales, en bloque y programadas."
}
}
}
@@ -1,168 +1,168 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña VMs y LXCs | ProxMenux Documentation",
"description": "La pestaña VMs y LXCs inventaría cada guest del host con uso de CPU / memoria / disco en vivo. La vista en detalle por guest muestra configuración, recursos, backups, logs completos del guest, notas y controles Start / Shutdown / Reboot / Stop."
"title": "ProxMenux Monitor — Panel: VMs y LXCs | Documentación de ProxMenux",
"description": "Inventario de todos los invitados con CPU, memoria y disco en vivo. Los detalles incluyen configuración, recursos, backups, el log de consola de los contenedores OCI, notas y controles Iniciar / Apagar / Reiniciar / Forzar parada."
},
"header": {
"title": "Panel: pestaña VMs y LXCs",
"description": "El inventario completo de guests del nodo. Cuatro métricas titulares arriba, una lista ordenable con cada VM y LXC abajo y una vista en detalle por guest con config, recursos, backups, logs y los cuatro controles de ciclo de vida (Start / Shutdown / Reboot / Stop).",
"title": "Panel: VMs y LXCs",
"description": "Inventario completo de invitados del nodo: cuatro métricas arriba, lista ordenable de VM y LXC abajo y detalles por invitado con configuración, recursos, backups, el log de consola de los contenedores OCI y cuatro controles de ciclo de vida (Iniciar / Apagar / Reiniciar / Forzar parada).",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "La superficie de control para guests",
"body": "El resto de pestañas son de solo lectura; esta es desde la que actúas. Todo lo que cambia el estado de un guest pasa por <code>POST /api/vms/&lt;vmid&gt;/control</code> con una confirmación explícita y la respuesta se refleja de vuelta en la fila del guest. No hay force-shutdown sin pasar por el botón Stop dedicado."
"title": "Controles de los invitados",
"body": "Controla el ciclo de vida de los invitados desde esta pestaña. Las acciones pasan por <code>POST /api/vms/&lt;vmid&gt;/control</code>; Reiniciar y Forzar parada piden escribir el VMID para confirmar, y la respuesta se refleja en la fila del invitado. El apagado forzado requiere el botón específico Forzar parada."
},
"topRow": {
"heading": "Fila superior: cuatro tarjetas de estadísticas",
"intro": "Al abrir la pestaña VMs y LXCs aterrizas en un resumen de cuatro tarjetas del estado de los guests — totales, utilización de CPU, compromiso de memoria vs capacidad del host y asignación de disco.",
"intro": "Al abrir VMs y LXCs aparecen cuatro tarjetas: número de invitados, uso CPU, memoria asignada frente a la capacidad del host y espacio de disco asignado.",
"imageAlt": "Pestaña VMs y LXCs — fila superior de cuatro tarjetas de estadísticas: Total VMs & LXCs, Total CPU, Total Memory, Total Disk",
"imageCaption": "Fila superior de la pestaña VMs y LXCs — totales + insignias Running / Stopped, utilización actual de CPU, memoria desglosada en used / running-allocated / total-allocated (con una insignia Within Limits) y espacio de disco asignado.",
"imageCaption": "Fila superior: totales y estados En ejecución / Detenidos, uso actual de CPU, memoria usada / asignada a invitados activos / asignada total (con Dentro de límites) y espacio de disco asignado.",
"headerCard": "Tarjeta",
"headerWhat": "Qué muestra",
"totalLabel": "Total VMs & LXCs",
"totalLabel": "Total de VM y LXC",
"totalWhat": "Recuento total con dos insignias — <em>X Running</em> (verde) y <em>Y Stopped</em> (rojo, solo cuando > 0). El número que miras cuando algo no volvió tras un reinicio.",
"cpuLabel": "Total CPU",
"cpuWhat": "Utilización agregada de CPU en vivo a lo largo de todos los guests como porcentaje de la CPU física del host, con una línea al pie <em>\"Allocated CPU usage\"</em>.",
"memoryLabel": "Total Memory",
"cpuLabel": "CPU total",
"cpuWhat": "Uso CPU total en vivo de todos los invitados como porcentaje de la CPU física del host, con el pie <em>«Uso de CPU asignada»</em>.",
"memoryLabel": "Memoria Total",
"memoryIntro": "Tres lecturas apiladas verticalmente:",
"memoryItems": [
"<strong>Currently used</strong> — valor grande (p. ej. <em>15.4 GB</em>) más <em>X.X % de Y GB</em> contra la RAM total del host. Una barra de progreso azul sigue al porcentaje.",
"<strong>Running allocated</strong> + <strong>Total allocated</strong> — suma de <code>maxmem</code> a lo largo de los guests que están <em>actualmente up</em> junto a la misma suma a lo largo de <em>todos</em> los guests incluyendo los parados. El primero importa hoy; el segundo importa cuando arrancas todo a la vez.",
"<strong>Insignia Within Limits</strong> (verde) — pasa a <em>Over-committed</em> si el total asignado excede la RAM del host. Un over-commit sano de memoria está bien en hosts con KSM, pero la insignia es el aviso temprano cuando ya no es cómodo."
"<strong>Usada actualmente</strong>: valor principal, como <em>15.4 GB</em>, y <em>X.X % de Y GB</em> respecto a la RAM del host. La barra azul indica el porcentaje.",
"<strong>Asignada a activos</strong> + <strong>Asignada total</strong>: suma de <code>maxmem</code> de los invitados <em>en ejecución</em> y de <em>todos</em>, incluidos los detenidos. La primera refleja la situación actual; la segunda, qué pasaría al arrancarlos todos.",
"<strong>Dentro de límites</strong>, en verde, cambia a <em>Sobreasignada</em> si la memoria total asignada supera la RAM del host. Una sobreasignación controlada puede funcionar con KSM; la etiqueta avisa cuando el margen disminuye."
],
"diskLabel": "Total Disk",
"diskWhat": "Suma del espacio de disco asignado a lo largo de todos los guests, en la unidad adecuada (GB / TB), con la línea al pie <em>\"Allocated disk space\"</em>."
"diskLabel": "Disco total",
"diskWhat": "Suma del espacio de disco asignado a todos los invitados, en GB o TB, con el pie <em>«Espacio de disco asignado»</em>."
},
"inventory": {
"heading": "Lista Virtual Machines & Containers",
"heading": "Lista de máquinas virtuales y contenedores",
"intro": "Una fila por guest. La lista se nutre de una única fuente, <code>/api/vms</code>, que consolida <code>qm list</code> + <code>pct list</code> + <code>pvesh /cluster/resources</code> en el host.",
"imageAlt": "Lista Virtual Machines & Containers — una fila por guest con estado, insignia de tipo, nombre, ID y porcentajes inline de CPU / memoria / disco",
"imageCaption": "El layout optimizado para móvil del inventario — los mismos datos que muestra la vista de escritorio, reapilados en una sola columna con los porcentajes e indicadores de estado compactos.",
"rowsIntro": "Cada fila muestra:",
"rows": [
"<strong>Icono de estado</strong> — play verde (running) o cuadrado rojo (stopped). Para guests parados, el resto de la fila se atenúa para que veas al instante qué está offline.",
"<strong>Icono de estado</strong>: triángulo verde (en ejecución) o cuadrado rojo (detenido). Las filas de invitados detenidos se atenúan para identificarlos de inmediato.",
"<strong>Insignia de tipo</strong> — <em>LXC</em> (cian) para contenedores, <em>VM</em> (morado) para máquinas virtuales.",
"<strong>Nombre</strong> — hostname / nombre de display del guest.",
"<strong>Nombre</strong>: nombre de host o nombre visible del invitado.",
"<strong>VMID</strong> — el ID numérico de Proxmox bajo el nombre.",
"<strong>Métricas inline</strong> — tres porcentajes con su icono (CPU %, Memory %, Disk %). Cada icono se pone naranja cuando la métrica cruza un umbral de atención (p. ej. memoria por encima del 90 %), así un vistazo rápido te dice qué guest está bajo presión sin abrirlo."
],
"clickHint": "Pulsar cualquier fila — running o stopped — abre la modal de vista en detalle descrita abajo.",
"mobileTitle": "La lista está construida mobile-first",
"mobileBody": "En móviles y ventanas estrechas el inventario reflowea a una única columna con insignia de tipo, nombre, ID y los tres porcentajes de métricas, uno por línea — exactamente la captura de arriba. En viewports más anchos los mismos datos se reparten horizontalmente con más espacio para los porcentajes. De cualquier modo, cada fila es el mismo target completo: pulsa para entrar."
"clickHint": "Pulsa una fila, esté el invitado en ejecución o detenido, para abrir sus detalles.",
"mobileTitle": "La lista está diseñada para móviles",
"mobileBody": "En móviles y ventanas estrechas, tipo, nombre, ID y tres porcentajes se apilan en una columna, como en la captura. En pantallas anchas se reparten horizontalmente con más espacio. Toda la fila es pulsable para abrir los detalles."
},
"drillIn": {
"heading": "Modal de vista en detalle por guest",
"heading": "Ventana de detalles del invitado",
"intro": "El modal se abre con el nombre, VMID, tipo, estado y tiempo de actividad del sistema. La navegación se adapta al elemento: <strong>Estado</strong>, <strong>App</strong> y <strong>Actualizaciones</strong> para gestionar aplicaciones LXC, <strong>Montajes</strong> cuando existen puntos de montaje, <strong>Logs</strong> en los contenedores instalados por OCI manager Apps, además de <strong>Backups</strong> y <strong>Cortafuegos</strong>. La barra inferior mantiene los controles de ciclo de vida y el terminal LXC disponibles desde cualquier pestaña.",
"statusTitle": "Pestaña 1 — Estado",
"statusImageAlt": "Modal de vista en detalle por guest — pestaña Status con tarjetas en vivo de CPU / Memoria / Disco, totales de E/S de disco y red, el logo de distro del SO y el bloque Resources / IP Addresses",
"statusImageCaption": "Pestaña Status — CPU / Memoria / Disco en vivo con barras de progreso arriba, totales de E/S acumulados (lectura/escritura de disco, descarga/subida de red) abajo, después el bloque estático Resources con expansiones de Notes y + Info y la lista de pastillas IP Addresses.",
"statusIntro": "La pestaña por defecto — la vista \"¿este guest se está portando?\". Tres bloques:",
"statusImageAlt": "Detalles del invitado: Estado con CPU, memoria y disco en vivo, E/S de disco y red, logotipo del SO y Recursos / Direcciones IP",
"statusImageCaption": "Estado: CPU, memoria y disco con barras arriba; totales acumulados de E/S (disco leído/escrito, red recibida/enviada); Recursos con Notas, + Info y lista de direcciones IP.",
"statusIntro": "La pestaña inicial permite comprobar el estado del invitado. Tres bloques:",
"liveTitle": "1. Fila de métricas en vivo",
"liveItems": [
"<strong>CPU Usage (X cores)</strong> — porcentaje actual con barra de progreso. La cabecera muestra el recuento de cores configurado para que sepas qué significaría un 100 %.",
"<strong>Memory</strong> — <em>used / max</em> en GB con barra de progreso.",
"<strong>Disk</strong> — <em>used / max</em> a lo largo de la imagen de disco primaria del guest, misma forma."
"<strong>Uso CPU (X núcleos)</strong>: porcentaje con barra. La cabecera muestra los núcleos configurados para interpretar qué significa 100 %.",
"<strong>Memoria</strong>: <em>usada / máxima</em> en GB con barra.",
"<strong>Disco</strong>: <em>usado / máximo</em> de la imagen principal de disco, con el mismo formato."
],
"ioTitle": "2. Totales de E/S + logo del SO",
"ioItems": [
"<strong>Disk I/O</strong> — totales acumulados de lectura (↓) y escritura (↑) desde el arranque. Útil para detectar un guest que se ha vuelto de repente intensivo en E/S comparado con su baseline.",
"<strong>Network I/O</strong> — descarga (↓) y subida (↑) acumuladas. Misma idea en el lado de red.",
"<strong>Logo de distro del SO</strong> — el icono de Debian / Ubuntu / Alpine / Windows / etc. detectado del tipo de SO del guest. Una pista visual rápida cuando scrolleas varias modales abiertas."
"<strong>E/S de disco</strong>: totales de lectura (↓) y escritura (↑) desde el arranque. Ayuda a detectar aumentos de E/S frente a la actividad habitual del invitado.",
"<strong>E/S de red</strong>: descarga (↓) y subida (↑) acumuladas; el mismo concepto para la red.",
"<strong>Logotipo del SO</strong>: icono Debian / Ubuntu / Alpine / Windows / etc. según el sistema detectado. Ayuda a identificarlo al consultar varias ventanas."
],
"resourcesTitle": "3. Bloque Resources",
"resourcesIntro": "La configuración del guest tal como la ve Proxmox — CPU Cores, Memory (<code>maxmem</code> configurado), Swap. Dos botones colapsables en la cabecera del bloque:",
"resourcesTitle": "3. Bloque Recursos",
"resourcesIntro": "Configuración del invitado según Proxmox: núcleos CPU, memoria (<code>maxmem</code> configurado) y swap. Dos botones despliegan información adicional:",
"resourcesItems": [
"<strong>Notes</strong> — el campo de descripción del guest. Editable: escribir aquí y guardar llama <code>PUT /api/vms/&lt;vmid&gt;/config</code> y escribe de vuelta en <code>/etc/pve/qemu-server/&lt;vmid&gt;.conf</code> o <code>/etc/pve/lxc/&lt;vmid&gt;.conf</code>.",
"<strong>+ Info</strong> — campos extra que son demasiado verbosos para la vista por defecto: bios mode, machine type, agent state, entradas de hostpci passthrough, mount points (CT), boot order."
"<strong>Notas</strong>: descripción editable del invitado. Guardar llama a <code>PUT /api/vms/&lt;vmid&gt;/config</code> y escribe en <code>/etc/pve/qemu-server/&lt;vmid&gt;.conf</code> o <code>/etc/pve/lxc/&lt;vmid&gt;.conf</code>.",
"<strong>+ Info</strong>: modo BIOS, tipo de máquina, estado del agente, asignaciones passthrough hostpci, puntos de montaje CT y orden de arranque."
],
"ipsTitle": "4. IP Addresses",
"ipsBody": "Lista de pastillas con cada dirección IPv4 / IPv6 que el guest expone actualmente — pastilla verde por dirección. Vacía cuando el guest está parado o cuando el QEMU agent no está instalado en una VM (los LXCs siempre reportan direcciones directamente).",
"ipsTitle": "4. Direcciones IP",
"ipsBody": "Cada dirección IPv4 o IPv6 del invitado aparece en una etiqueta verde. La lista queda vacía si está detenido o si una VM carece del agente QEMU; los LXC comunican sus direcciones directamente.",
"appTitle": "Pestaña 2 — App (solo LXC)",
"appIntro": "Registra las aplicaciones que pertenecen al LXC, guarda enlaces web y, opcionalmente, compara las versiones instalada y disponible. Las sugerencias proceden de la caché de arranque; <strong>Buscar aplicaciones</strong> actualiza expresamente la detección de este LXC después de instalar software nuevo.",
"appLinkLead": "Consulta la",
"appLinkLabel": "página específica de App",
"appLinkTail": "para conocer la detección en caché, el registro asistido por catálogo, los enlaces web de Docker y los detectores de versión.",
"updatesTitle": "Pestaña 3 — Actualizaciones (solo LXC)",
"updatesIntro": "Mantiene como objetivos separados los <strong>paquetes del SO</strong>, las aplicaciones registradas, <strong>Docker Engine</strong> y las imágenes Docker. Cada objetivo puede ejecutarse por separado; una acción en bloque y una programación opcionales seleccionan los métodos exactos que deben ejecutarse juntos.",
"updatesIntro": "Mantiene separados <strong>paquetes del SO</strong>, aplicaciones, <strong>Docker Engine</strong> e imágenes Docker. Cada objetivo se ejecuta por separado o se incluye en una selección exacta para actualización en bloque o programada.",
"updatesLinkLead": "Consulta la",
"updatesLinkLabel": "página específica de Actualizaciones",
"updatesLinkTail": "para conocer los actualizadores integrados y personalizados, la recreación Docker, la selección en bloque, las opciones de seguridad y la programación.",
"mountsTitle": "Pestaña 4 — Montajes (solo LXC, cuando existen)",
"mountsImageAlt": "Modal de vista en detalle LXC — pestaña Mounts listando cada mount point que está usando el contenedor: volúmenes PVE, host binds, binds desde almacenamiento PVE y montajes ad-hoc NFS/CIFS que el operador montó desde dentro del CT. Cada tarjeta lleva una insignia de tipo, barra de capacidad, bytes used/total, opciones de montaje y un punto de estado por color (verde sano, ámbar readonly/divergente, rojo stale)",
"updatesLinkTail": "para actualizadores integrados y personalizados, recreación de contenedores Docker, selección en bloque, opciones de seguridad y programación.",
"mountsTitle": "Pestaña 4 — Montajes (solo LXC, si existen)",
"mountsImageAlt": "Detalles LXC, Montajes: volúmenes PVE, bind mounts del host o de almacenamiento PVE y NFS/CIFS montados dentro del CT. Cada tarjeta muestra tipo, capacidad, bytes usados/totales, opciones y estado por color: verde correcto, ámbar solo lectura/divergente, rojo inaccesible.",
"mountsImageCaption": "Pestaña Mounts — solo se renderiza para contenedores LXC, y solo cuando hay al menos un mount point o un montaje remoto ad-hoc presente. Un CT sin mounts no recibe pestaña.",
"mountsIntro": "La propia UI de Proxmox muestra las entradas de mount-point definidas en la config del contenedor (<code>mpX</code>) pero se queda ahí — cualquier cosa que montes desde dentro del CT después (<code>mount.cifs</code>, NFS vía <code>autofs</code>, …) es invisible. Esta pestaña funde <strong>ambas vistas</strong>: los mounts configurados <strong>y</strong> los mounts en runtime que ProxMenux sonda desde dentro del contenedor, con un estado de salud por mount y una barra de capacidad cuando el backend la puede resolver.",
"mountTypesTitle": "Tipos de mount detectados",
"mountsIntro": "Proxmox muestra los montajes configurados como <code>mpX</code>, pero no los añadidos después desde el CT con <code>mount.cifs</code>, NFS mediante <code>autofs</code>, etc. Esta pestaña une <strong>ambas vistas</strong>: montajes configurados <strong>y</strong> detectados dentro del contenedor, con estado por montaje y capacidad cuando el servidor puede obtenerla.",
"mountTypesTitle": "Tipos de montaje detectados",
"mountTypesItems": [
"<strong>PVE volume</strong> — respaldado por un almacenamiento gestionado por Proxmox (un subvol ZFS, una entrada de directorio, un Ceph RBD, …). La capacidad viene de las stats del almacenamiento PVE para que la barra coincida con lo que el propio Proxmox muestra.",
"<strong>Bind from PVE storage</strong> — entrada <code>mpX</code> apuntando a una ruta en un almacenamiento conocido por PVE.",
"<strong>Bind from host</strong> — entrada <code>mpX</code> apuntando a una ruta arbitraria del host (<code>/mnt/something</code>). La capacidad es el <code>df</code> de esa ruta del host.",
"<strong>Volumen PVE</strong>: almacenamiento gestionado por Proxmox (subvolumen ZFS, entrada de directorio, Ceph RBD, etc.). La capacidad usa las estadísticas PVE para coincidir con Proxmox.",
"<strong>Bind de almacenamiento PVE</strong>: entrada <code>mpX</code> que apunta a una ruta de un almacenamiento conocido por PVE.",
"<strong>Bind del host</strong>: entrada <code>mpX</code> con una ruta arbitraria del host (<code>/mnt/something</code>). La capacidad se obtiene con <code>df</code> de esa ruta.",
"<strong>Ad-hoc inside CT</strong> — mount que <em>solo</em> existe en el namespace de mounts del contenedor (p. ej. un share NFS que el CT monta por su cuenta). La capacidad se lee vía <code>pct exec &lt;vmid&gt; df</code>, que es la única forma de verla — <code>/proc/&lt;pid&gt;/root</code> desde el host no expone las stats reales del mount remoto."
],
"mountStateTitle": "Punto de estado por tarjeta y avisos",
"mountStateItems": [
"<green/> <strong>Verde</strong> — mount sano y alcanzable.",
"<amber/> <strong>Ámbar</strong> — divergente (configurado pero no montado en realidad), read-only o <em>zombie bind</em> (el origen en el host fue retirado pero el CT sigue viendo el bind como montado — típico cuando se desconectó una unidad USB o hubo un <code>umount</code> manual en el host).",
"<red/> <strong>Rojo</strong> — stale: la sonda de runtime no pudo alcanzar el mount (común con exports NFS cuyo servidor está caído)."
"<green/> <strong>Verde</strong>: montaje correcto y accesible.",
"<amber/> <strong>Ámbar</strong>: configurado pero no montado, solo lectura o <em>bind zombi</em>. En este último caso se retiró el origen del host, pero el CT aún lo ve montado, por ejemplo tras desconectar un USB o ejecutar <code>umount</code> en el host.",
"<red/> <strong>Rojo</strong>: inaccesible; la comprobación en ejecución no alcanzó el montaje, por ejemplo un recurso NFS con el servidor caído."
],
"mountsCalloutTitle": "Lo que esto te da sobre la UI nativa",
"mountsCalloutTitle": "Información adicional respecto a Proxmox",
"mountsCalloutBody": "Una vista veraz y consciente de la capacidad de cada sitio donde el contenedor lee o escribe. Shares NFS o CIFS montados desde dentro del CT — invisibles para la UI web de Proxmox — aparecen aquí con el mismo aspecto y la misma sonda de salud que cualquier mount point configurado. Mounts remotos stale y zombie binds salen marcados antes de que muerdan durante un backup.",
"logsTitle": "Pestaña 5 — Logs (solo contenedores OCI)",
"logsBody": "Solo aparece en los contenedores instalados por OCI manager Apps. Muestra la salida de consola del proceso principal de la imagen, guardada en el host en <code>/var/log/proxmenux/oci/VMID.console.log</code>: las últimas 100, 500 o 1000 líneas, seguidas en directo con el contenedor en marcha, con un filtro y una descarga. Lee el archivo cada vez que se abre, así que también funciona con el contenedor detenido. Los detalles están en <ociLink>Contenedores OCI en ProxMenux Monitor</ociLink>.",
"logsBody": "Solo para contenedores de OCI manager Apps. Muestra la consola del proceso principal de la imagen, guardada en <code>/var/log/proxmenux/oci/VMID.console.log</code>: últimas 100, 500 o 1000 líneas, seguimiento en vivo mientras está activo, filtro y descarga. Relee el archivo al abrir y funciona detenido. Más en <ociLink>Contenedores OCI en ProxMenux Monitor</ociLink>.",
"backupsTitle": "Pestaña 6 — Backups",
"backupsImageAlt": "Modal de vista en detalle por guest — pestaña Backups con la lista de backups disponibles, etiqueta de destino, tamaños y el botón Create Backup",
"backupsImageCaption": "Pestaña Backups — cada backup almacenado en los almacenamientos Proxmox configurados para este guest, ordenados de más nuevo a más viejo. La cabecera de la pestaña lleva la insignia de recuento.",
"backupsIntro": "Lista cada backup almacenado en los almacenamientos Proxmox configurados para este guest, ordenados de más nuevo a más viejo. El título de la pestaña lleva una insignia de recuento para que veas de un vistazo si el guest está backupeado. Por fila:",
"backupsImageCaption": "Todos los backups del invitado en almacenamientos Proxmox configurados, de más nueva a más antigua. La cabecera muestra su número.",
"backupsIntro": "Lista los backups del invitado en almacenamientos Proxmox, empezando por la más reciente. El contador del título permite comprobar si tiene backups. Cada fila muestra:",
"backupsItems": [
"<strong>Timestamp</strong> — fecha y hora de la ejecución.",
"<strong>Fecha y hora</strong>: momento de la ejecución.",
"<strong>Etiqueta de destino</strong> — el almacenamiento donde vive (PBS-Cloud, PBS-Local, NFS-Backup, …) coloreada por estado.",
"<strong>Size</strong> — tamaño final en disco del backup."
"<strong>Tamaño</strong>: tamaño final en disco del backup."
],
"backupsOutro": "El botón <strong>+ Create Backup</strong> arriba a la derecha arranca una nueva ejecución en el almacenamiento marcado como \"Backup target\" en la config de almacenamiento de Proxmox. El restore vive en la UI web de Proxmox — el Monitor expone la vista \"¿este guest tiene backup reciente?\", no el flujo de recuperación.",
"backupsOutro": "<strong>+ Crear backup</strong> inicia un backup en el almacenamiento marcado «Backup target» en Proxmox. Para restaurar usa la interfaz web de Proxmox; Monitor muestra los backups recientes del invitado y permite crearlos.",
"firewallTitle": "Pestaña 7 — Cortafuegos",
"firewallIntro": "Lee el log de firewall de Proxmox por guest directamente del host (sin servicio extra, sin polling). La pestaña siempre está presente en la barra de navegación; el panel decide qué renderizar dependiendo de si el firewall está activo para ese guest y si alguna regla está logueando realmente:",
"firewallIntro": "Lee el registro del cortafuegos de cada invitado directamente del host, sin servicio extra ni consultas periódicas. La pestaña siempre aparece; el contenido depende de que el cortafuegos esté activado y de que alguna regla registre paquetes.",
"firewallItems": [
"<strong>Firewall disabled</strong> — un aviso ámbar explica exactamente dónde activarlo en la UI de Proxmox (<em>&lt;Container|VM&gt; → Firewall → Options</em>) y te recuerda que al menos una regla necesita <code>log: info</code> (o superior) antes de que aparezcan paquetes.",
"<strong>Firewall enabled, no events yet</strong> — pista de estado vacío con el mismo requisito de logging, útil cuando acabas de activar el firewall.",
"<strong>Events present</strong> — un panel monoespaciado scrolleable con las entradas raw coloreadas por acción: <green>ACCEPT</green> (verde), <orange>REJECT</orange> (naranja), <red>DROP</red> (rojo). Una insignia de recuento en la cabecera muestra cuántas entradas hay cargadas en este momento."
"<strong>Cortafuegos desactivado</strong>: aviso ámbar que indica dónde activarlo en Proxmox (<em>&lt;Container|VM&gt; → Firewall → Options</em>) y que alguna regla requiere <code>log: info</code> o superior para mostrar paquetes.",
"<strong>Cortafuegos activo, sin eventos aún</strong>: el panel vacío recuerda el mismo requisito de registro, útil al activarlo por primera vez.",
"<strong>Hay eventos</strong>: panel monoespaciado con desplazamiento y entradas originales por acción: <green>ACCEPT</green> verde, <orange>REJECT</orange> naranja y <red>DROP</red> rojo. El contador de la cabecera indica las entradas cargadas."
],
"firewallRefresh": "Un botón <em>Refresh</em> arriba a la derecha del panel trae las últimas entradas bajo demanda — no hay auto-refresh dentro de la modal, así que la lista es una snapshot del momento en que abriste la pestaña o pulsaste refresh. Los datos vienen del archivo de log por guest que Proxmox escribe bajo <code>/var/log/pve-firewall.log</code> filtrado por VMID, expuesto vía <code>GET /api/vms/&lt;vmid&gt;/firewall/log</code>.",
"firewallRefresh": "<em>Actualizar</em> carga las entradas más recientes bajo demanda. No hay actualización automática: se muestra el momento de apertura o de la última pulsación. Los datos proceden de <code>/var/log/pve-firewall.log</code>, filtrados por VMID mediante <code>GET /api/vms/&lt;vmid&gt;/firewall/log</code>.",
"firewallCalloutTitle": "¿Por qué tenerlo aquí cuando la UI de Proxmox ya lo muestra?",
"firewallCalloutBody": "Dos razones: elimina el viaje de ida y vuelta a la UI web de Proxmox cuando ya estás inspeccionando un guest desde el panel, y mantiene la misma vista acotada por VMID que usa el resto de la modal — arrancar el guest, comprobar sus mounts, mirar los hits recientes del firewall y pararlo otra vez sin salir del panel. El Monitor nunca edita reglas de firewall; la edición de reglas se queda en la interfaz nativa de Proxmox donde corresponde.",
"firewallCalloutBody": "Evita cambiar a la interfaz Proxmox y mantiene la vista del mismo VMID: inicia el invitado, comprueba montajes y eventos del cortafuegos y vuelve a detenerlo desde el panel. Las reglas se editan en Proxmox; Monitor no las modifica.",
"actionBarTitle": "Barra de acciones del pie",
"actionBarIntro": "Siempre visible al pie de la modal independientemente de qué pestaña esté activa:",
"consoleItem": "<strong>Console</strong> (solo LXC, running) — abre una modal que ejecuta <code>pct enter &lt;vmid&gt;</code> y te deja dentro del contenedor. La misma fontanería xterm.js + WebSocket que la <link>pestaña Terminal</link> independiente, incluyendo la <strong>barra para móvil</strong> con ESC, TAB, flechas, Enter y las combinaciones Ctrl (Ctrl+C / Ctrl+X / Ctrl+R) bajo el terminal — haciendo la modal usable desde el teclado de un móvil o tablet. Las VMs no exponen un botón Console aquí; usa la consola web de Proxmox (noVNC) para acceso al guest.",
"lifecycleIntro": "Debajo, cuatro botones de ciclo de vida en una rejilla 2×2. Cada uno dispara <code>POST /api/vms/&lt;vmid&gt;/control</code> con la <code>action</code> correspondiente; el estado de enabled depende de si el guest está actualmente en ejecución:",
"consoleItem": "<strong>Consola</strong>, solo para LXC en ejecución, abre <code>pct enter &lt;vmid&gt;</code> dentro del contenedor. Usa la misma conexión xterm.js y WebSocket que la <link>pestaña Terminal</link>, incluida la <strong>barra para móviles</strong> con ESC, TAB, flechas, Intro y Ctrl+C / Ctrl+X / Ctrl+R. Permite trabajar con móvil o tablet. Para VM usa la consola Proxmox noVNC.",
"lifecycleIntro": "Debajo hay cuatro botones en rejilla 2×2. Cada uno envía <code>POST /api/vms/&lt;vmid&gt;/control</code> con su <code>action</code>. Se habilitan según el estado actual del invitado.",
"headerButton": "Botón",
"headerEnabled": "Habilitado cuando",
"headerAction": "Acción enviada al host",
"lifecycleRows": [
{
"button": "Start",
"button": "Iniciar",
"color": "green",
"enabled": "El guest está parado.",
"action": "qm start / pct start"
},
{
"button": "Shutdown",
"button": "Apagar",
"color": "blue",
"enabled": "El guest está en ejecución.",
"action": "qm shutdown / pct shutdown — graceful, ACPI"
"enabled": "El invitado está en ejecución.",
"action": "qm shutdown / pct shutdown — apagado ordenado, ACPI"
},
{
"button": "Reboot",
"button": "Reiniciar",
"color": "blue",
"enabled": "El guest está en ejecución.",
"action": "qm reboot / pct reboot — reinicio graceful"
"enabled": "El invitado está en ejecución.",
"action": "qm reboot / pct reboot — reinicio ordenado"
},
{
"button": "Force Stop",
"button": "Forzar parada",
"color": "red",
"enabled": "El guest está en ejecución.",
"action": "qm stop / pct stop — apagado en duro"
"enabled": "El invitado está en ejecución.",
"action": "qm stop / pct stop — apagado forzado"
}
],
"forceStopTitle": "Force Stop es el kill switch, no la opción educada",
"forceStopBody": "<strong>Force Stop</strong> salta la secuencia de apagado del guest — equivalente a tirar del cable de la luz. Usa <strong>Shutdown</strong> cuando el guest responde; recurre a Force Stop solo cuando Shutdown se cuelga y aceptas el riesgo de pérdida de datos de un apagado no coordinado. El botón es rojo y está etiquetado a propósito para que no lo pulses por reflejo."
"forceStopTitle": "Forzar parada corta la ejecución inmediatamente",
"forceStopBody": "<strong>Forzar parada</strong> omite el apagado del invitado, como cortar la alimentación. Usa <strong>Apagar</strong> mientras responda. Fuerza la parada solo si el apagado se bloquea y aceptas el riesgo de perder datos. El botón rojo y su etiqueta ayudan a evitar pulsaciones accidentales."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -186,9 +186,9 @@
"source": "Datos RRD de PVE (<code>pvesh get /nodes/&lt;node&gt;/qemu/&lt;id&gt;/rrddata</code>) condensados a una forma amigable para gráficas."
},
{
"section": "Logs recientes de tareas (modal)",
"endpoint": "/api/vms/<vmid>/logs",
"source": "Tareas para ese <code>vmid</code> desde <code>/var/log/pve/tasks/index</code>."
"section": "Log de consola OCI (pestaña Logs)",
"endpoint": "/api/lxc/<vmid>/console-log",
"source": "Salida de consola del proceso principal de la imagen, leída de <code>/var/log/proxmenux/oci/&lt;vmid&gt;.console.log</code> en el host. Solo para contenedores OCI."
},
{
"section": "Backups disponibles para el guest",
@@ -206,8 +206,8 @@
"source": "<code>qm start|stop|reboot|shutdown</code> o equivalentes <code>pct</code>."
}
],
"codeComment1": "# Cross-check de lo que ve el panel contra PVE",
"codeComment2": "# Inspeccionar la config de un guest concreto tal como la ve la modal",
"codeComment1": "# Contrastar los datos del panel con PVE",
"codeComment2": "# Inspeccionar la configuración de un invitado tal como la muestra la ventana",
"codeComment3": "# VM",
"codeComment4": "# CT"
},
@@ -217,7 +217,7 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tailRich": " — la categoría VMs y Contenedores (boot fallido, timeouts QMP, fallos de shutdown de CT)."
"tailRich": " — categoría VMs y Contenedores: fallos de arranque, tiempos de espera QMP y errores de apagado CT."
},
{
"label": "Notificaciones",
@@ -227,7 +227,7 @@
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tailRich": " — los endpoints de VM y backup."
"tailRich": " — endpoints de VM y backups."
},
{
"label": "Índice del panel",
@@ -235,9 +235,9 @@
"tailRich": " — el resto de pestañas."
},
{
"label": "ProxMenux → Create VM",
"label": "ProxMenux → Crear VM",
"href": "/docs/create-vm",
"tailRich": " — la cara de provisión: plantillas de System NAS (Synology y otros), VMs Linux / Windows, valores por defecto pensados para Proxmox."
"tailRich": " — creación de sistemas: plantillas NAS (Synology y otros), VM Linux/Windows y valores adaptados a Proxmox."
}
]
}
@@ -1,7 +1,7 @@
{
"meta": {
"title": "Monitor de salud de Proxmox — CPU, memoria, almacenamiento, SMART, ZFS, logs | ProxMenux",
"description": "Monitorización proactiva de salud de Proxmox VE: diez categorías escaneadas cada cinco minutos (CPU y temperatura, memoria y swap, almacenamiento, discos/SMART, red, VMs, servicios, logs, actualizaciones, seguridad), cuatro niveles de severidad, duraciones de supresión por categoría, limpieza automática de errores resueltos, un historial permanente de observaciones de disco y el camino desde un evento crudo a una notificación a Telegram, Discord, Gotify o email.",
"description": "Supervisión proactiva de Proxmox VE: diez categorías cada cinco minutos (CPU y temperatura, memoria y swap, almacenamiento, discos/SMART, red, máquinas virtuales, servicios, registros, actualizaciones y seguridad), cuatro niveles de gravedad, silenciamiento por categoría, limpieza automática de errores resueltos, historial permanente de discos y notificaciones por Telegram, Discord, Gotify o correo.",
"ogTitle": "Monitor de salud de Proxmox — CPU, memoria, almacenamiento, SMART, ZFS, logs",
"ogDescription": "Monitorización proactiva de salud de Proxmox VE a través de diez categorías con niveles de severidad, duraciones de supresión y notificaciones dirigidas por eventos.",
"twitterTitle": "Monitor de salud de Proxmox | ProxMenux",
@@ -10,27 +10,27 @@
"header": {
"title": "Monitor de salud",
"description": "El auto-chequeo continuo que escanea diez categorías de estado del host en un ciclo de cinco minutos, muestrea signos vitales continuamente entre ciclos, deduplica hallazgos en un stream de eventos estructurado, y alimenta el panel, el motor de notificaciones y el reescritor opcional de IA desde una única fuente de verdad.",
"section": "ProxMenux Monitor"
"section": "Monitor de ProxMenux"
},
"intro": {
"title": "Un escáner, tres consumidores",
"body": "Un hilo de fondo ejecuta el ciclo completo de salud cada 5 minutos, persiste cada hallazgo en SQLite bajo un <code>error_key</code> estable, y deja que <strong>(1)</strong> el panel renderice el estado actual, <strong>(2)</strong> el motor de notificaciones reparta los eventos nuevos a los canales configurados y <strong>(3)</strong> el asistente opcional de IA reescriba las alertas en lenguaje natural. Configuras el escáner una vez; todo lo de aguas abajo se mantiene en sync."
"body": "Un hilo en segundo plano ejecuta el ciclo completo cada cinco minutos y guarda cada hallazgo en SQLite con un <code>error_key</code> estable. Así, <strong>(1)</strong> el panel muestra el estado actual, <strong>(2)</strong> el sistema de notificaciones distribuye los eventos nuevos a los canales configurados y <strong>(3)</strong> el asistente de IA opcional reformula las alertas en lenguaje sencillo. Configuras el análisis una vez y los componentes utilizan los mismos datos."
},
"howItWorks": {
"heading": "Cómo funciona",
"intro": "El Monitor de salud corre en dos carriles paralelos dentro del proceso del Monitor. Un <strong>muestreador de signos vitales</strong> ligero lee CPU, memoria y temperatura cada pocos segundos para que las condiciones de umbral sostenido se detecten rápido; en paralelo, el <strong>ciclo completo de salud</strong> corre cada cinco minutos y ejercita cada categoría de principio a fin. Ambos carriles convergen en las mismas tablas SQLite — y desde ahí, tres consumidores leen el estado independientemente.",
"intro": "El Monitor de salud usa dos hilos paralelos. Un <strong>muestreador de métricas</strong> ligero llena los historiales de CPU, memoria y temperatura. El <strong>ciclo completo de salud</strong> lee esos datos, evalúa las condiciones sostenidas y realiza las demás comprobaciones aproximadamente cada cinco minutos; después guarda los hallazgos en SQLite para el panel y las notificaciones.",
"scannerTitle": "Del muestreo al hallazgo guardado",
"scannerCaption": "El escáner. Los signos vitales se muestrean rápido para que la presión sostenida de CPU / memoria se detecte antes del siguiente ciclo de 5 min. El ciclo completo lee esos buffers y ejecuta los chequeos más pesados (SMART, estado de pool ZFS, escaneo de journal, salud de servicio, etc.) antes de escribir los hallazgos estructurados a SQLite.",
"scannerCaption": "El muestreador llena los historiales entre ciclos: CPU cada 5 s, memoria cada 30 s y temperatura cada 15 s. No evalúa las alertas. El ciclo completo evalúa esos datos y realiza las comprobaciones más pesadas (SMART, estado ZFS, registros y servicios) antes de guardar los hallazgos en SQLite.",
"scannerArrowLabel": "paso",
"scannerNodes": {
"samplerLabel": "Muestreador de signos vitales",
"samplerDetail": "Uso de CPU 30 s\nMemoria 30 s\nTemperatura 15 s\n→ buffers de historial",
"samplerDetail": "Uso de CPU 5 s\nMemoria 30 s\nTemperatura 15 s\n→ historiales",
"cycleLabel": "Ciclo completo de salud",
"cycleDetail": "Cada 5 min\nLee buffers\n+ probes en vivo\n(SMART, ZFS,\nservicios, journal…)",
"checksLabel": "Chequeos por categoría",
"checksDetail": "Diez categorías\n(CPU, memoria,\nalmacenamiento, discos,\nred, VMs,\nservicios, logs,\nactualizaciones, seguridad)",
"sqliteLabel": "SQLite",
"sqliteDetail": "tabla errors\n(activos +\ndismissed)\n+ disk_observations\n(historial\npermanente por disco)"
"sqliteDetail": "tabla errors\n(activas +\nsilenciadas)\n+ disk_observations\n(historial permanente\npor disco)"
},
"notifTitle": "Del hallazgo guardado al usuario",
"notifCaption": "El camino de la notificación. La misma tabla errors también dirige la vista del panel (listas Active / Dismissed renderizadas en vivo) y la consume la rutina de limpieza al final de cada ciclo para auto-resolver entradas obsoletas — ambas corren desde los mismos datos sin pasar por el dispatcher.",
@@ -43,7 +43,7 @@
"templatesLabel": "Templates + reescritura con IA",
"templatesDetail": "Template\npor evento\n→ reescritura\nopcional con IA\nen lenguaje natural",
"channelsLabel": "Canales",
"channelsDetail": "Telegram\nDiscord\nGotify\nEmail (SMTP)"
"channelsDetail": "Telegram\nDiscord\nGotify\nCorreo electrónico (SMTP)"
}
},
"categories": {
@@ -58,7 +58,7 @@
{
"category": "CPU y Temperatura",
"checks": "Uso de CPU con histéresis, temperatura de sensor",
"events": "Carga sostenida alta; temperatura de CPU cruzando los umbrales warning / critical del fabricante."
"events": "Uso elevado y sostenido de CPU; avisos de temperatura basados en las lecturas muestreadas."
},
{
"category": "Memoria y Swap",
@@ -68,7 +68,7 @@
{
"category": "Almacenamiento",
"checks": "Almacenamientos Proxmox, sistema de archivos raíz",
"events": "Almacenamiento offline (servidor NFS inalcanzable, credenciales CIFS caducadas); montaje raíz > 90 %; pool LVM thin cerca de lleno."
"events": "Uso de espacio por encima de los umbrales configurados en la raíz u otros sistemas de archivos supervisados (85% aviso / 95% crítico por defecto); almacenamientos PVE no disponibles; montajes NFS/CIFS bloqueados o en solo lectura inesperada; LVM-thin y otros almacenamientos de pool que superan los mismos umbrales."
},
{
"category": "Discos y SMART",
@@ -98,7 +98,7 @@
{
"category": "Actualizaciones del sistema",
"checks": "Actualizaciones pendientes, actualizaciones de seguridad, kernel / versión de PVE, antigüedad del sistema",
"events": "Actualizaciones de seguridad disponibles; kernel pinneado varias versiones menores por detrás; uptime del host > 90 días. Cuando hay actualizaciones pendientes, la cabecera de Overview muestra un botón <em>Update Now</em> que ejecuta el flujo completo de actualización de ProxMenux en línea; al cerrar vuelve a golpear el endpoint de health con <code>?refresh=1</code> para que el badge refleje el nuevo estado sin esperar al siguiente ciclo de 5 minutos."
"events": "Actualizaciones pendientes de seguridad o del kernel en uso; sistema sin actualizar desde hace mucho tiempo. Si hay actualizaciones, la categoría Actualizaciones de la ventana de estado de salud muestra <em>Actualizar ahora</em>. Ejecuta todo el proceso de actualización de ProxMenux; al cerrarlo, consulta el estado con <code>?refresh=1</code> para actualizar el indicador sin esperar al próximo ciclo."
},
{
"category": "Seguridad y Certificados",
@@ -141,7 +141,7 @@
],
"infoNote": "Una categoría que está <strong>OK</strong> pero tiene eventos dismissed todavía dentro de su ventana de supresión se renderiza como <strong>INFO</strong> — para recordarte que algo está siendo silenciado en vez de que nunca hubo nada mal.",
"unknownTitle": "UNKNOWN, cuando un chequeo no puede completar",
"unknownBody": "Un chequeo que falla en producir un veredicto durante tres ciclos seguidos (un probe que caduca, un sensor que ha desaparecido, una herramienta que sale con error) se registra internamente como <code>UNKNOWN</code>. El panel lo muestra como un estado amarillo — la vista global capa el <code>UNKNOWN</code> a <strong>WARNING</strong> para que nunca escale un host sano a CRITICAL por sí solo."
"unknownBody": "Una comprobación no disponible devuelve <code>UNKNOWN</code>; tras tres ciclos consecutivos así, se registra un hallazgo persistente. El panel muestra la comprobación en amarillo. El estado general limita <code>UNKNOWN</code> a <strong>WARNING</strong>: por sí sola, una comprobación no disponible no vuelve crítico al host."
},
"dashboardView": {
"heading": "La vista del panel",
@@ -150,7 +150,7 @@
"<strong>Active</strong> — cada categoría con un hallazgo sin resolver. Cada fila expande para mostrar los chequeos individuales que produjeron el estado, la cadena <code>reason</code> cruda, el dispositivo o VM ID involucrado, y (para categorías que enlazan a una pestaña) un click-through a Almacenamiento / Red / VMs / Logs / Hardware para investigar.",
"<strong>Dismissed</strong> — items previamente reconocidos por el usuario que aún están dentro de su ventana de supresión. Cada fila muestra cuánto queda de la supresión y la duración configurada. Cuando la ventana caduca, el item desaparece de esta lista; si la condición subyacente sigue presente y la categoría soporta re-firing, reaparece en <em>Active</em>."
],
"pillTitle": "La pildora refleja la peor categoría",
"pillTitle": "El indicador refleja la categoría más grave",
"pillBody": "El color de la cabecera del panel es la severidad más alta entre las diez categorías: cualquier CRITICAL → rojo, si no cualquier WARNING → amarillo, si no cualquier INFO → azul, si no verde. La misma lógica dirige el punto del favicon y el badge del PWA.",
"updateNowTitle": "Botón Update Now en la cabecera de Overview",
"updateNowBody1": "Cuando la categoría <em>Actualizaciones del sistema</em> reporta una o más actualizaciones pendientes, la cabecera de Overview renderiza un botón <strong>Update Now</strong> al lado de la pildora de salud. El botón abre una modal que ejecuta el mismo flujo del lado del host que <em>ProxMenux → Settings post-install Proxmox → Proxmox System Update</em>: higiene de repos, <code>apt full-upgrade</code> vía el worker seguro <code>update-pve-safe.sh</code>, recompilación DKMS automática de los drivers gestionados por ProxMenux cuando aterriza un kernel nuevo, autoremove / autoclean y prompt de reinicio si el kernel cambió. Las líneas de progreso van llegando a la modal según las va imprimiendo el worker.",
@@ -158,55 +158,55 @@
},
"dismiss": {
"heading": "Hacer dismiss de alertas y la Suppression Duration",
"intro": "Algunos eventos son ruidosos por naturaleza — un <em>System Updates: actualizaciones pendientes disponibles</em> permanece cierto hasta que parches el host, y no quieres una notificación cada cinco minutos durante una semana. El botón <em>Update Now</em> de la cabecera de Overview es el atajo directo para resolver ese caso concreto en sitio; para todo lo demás, o cuando el parche se aplaza, el Monitor de salud ofrece además dos mecanismos de silenciamiento acoplados:",
"step1": "<strong>Acción Dismiss por evento</strong> en el modal. El botón Dismiss abre un dropdown con tres opciones — <strong>24 horas</strong>, <strong>7 días</strong> o <strong>Permanently</strong> — que te permite elegir cuánto tiempo se silencia esta alerta concreta independientemente del valor por defecto de la categoría. Elegir una llama a <code>POST /api/health/acknowledge</code> con el <code>error_key</code> y el <code>suppression_hours</code> escogido (<code>-1</code> para permanente). El evento se mueve a la lista Dismissed con un <code>acknowledged_at</code> con timestamp.",
"dropdownImageAlt": "Dropdown de Dismiss sobre una alerta del Monitor de salud — 24 horas, 7 días o Permanently",
"dropdownImageCaption": "Dropdown Dismiss por evento. La ventana elegida aplica solo a esta alerta; si no eliges ninguna por evento se usa el valor por defecto de la categoría. Los dismisses permanentes se marcan con un badge ámbar distinto <em>Permanent</em> en la lista Dismissed y no se re-disparan.",
"intro": "Algunos eventos son ruidosos por naturaleza: <em>System Updates: actualizaciones pendientes disponibles</em> sigue activo hasta que actualices el host, y no quieres una notificación cada cinco minutos durante una semana. El botón <em>Actualizar ahora</em> de la categoría Actualizaciones de la ventana de estado de salud resuelve ese caso en el sitio; para todo lo demás, o si aplazas la actualización, el Monitor de salud ofrece además dos mecanismos de silenciado relacionados:",
"step1": "<strong>Descartar un evento</strong> desde su ventana. El botón ofrece <strong>24 horas</strong>, <strong>7 días</strong> o <strong>Permanentemente</strong>, independientemente del valor de la categoría. Envía <code>POST /api/health/acknowledge</code> con el <code>error_key</code> y las <code>suppression_hours</code> elegidas (<code>-1</code> para permanente). El evento pasa a Descartados con su fecha <code>acknowledged_at</code>.",
"dropdownImageAlt": "Menú para descartar una alerta: 24 horas, 7 días o permanentemente",
"dropdownImageCaption": "La duración elegida se aplica solo a esta alerta; sin una elección individual, se usa el valor de la categoría. Los descartes permanentes llevan una etiqueta ámbar <em>Permanente</em> y normalmente no reaparecen. La excepción de temperatura crítica de CPU se explica más abajo.",
"step2": "<strong>Ajuste de Suppression Duration por categoría</strong>. Desde la card Settings → Health Monitor (o <code>POST /api/health/settings</code>), cada una de las diez categorías tiene su propia ventana por defecto, aplicada cuando se hace un Dismiss sin elegir ventana por evento:",
"imageAlt": "Card Settings → Health Monitor con los dropdowns de supresión por categoría y la sección Active Suppressions",
"imageCaption": "Card Health Monitor — un dropdown por categoría fija los valores por defecto para nuevos dismisses; la sección Active Suppressions debajo lista todas las alertas actualmente silenciadas (ver más abajo).",
"imageCaption": "Un selector de duración por categoría. Elige una ventana mayor para eventos ruidosos, como actualizaciones pendientes, y menor para los que quieras reevaluar pronto. Debajo se muestran los silenciamientos activos.",
"outro": "Mientras un evento está suprimido, el escáner sigue corriendo y actualiza el timestamp <code>last_seen</code> de la fila, pero no se despacha ninguna notificación nueva y el panel se mantiene calmado. Cuando la ventana caduca, el siguiente ciclo reevalúa la condición y o bien re-dispara fresco o, si la condición se ha aclarado por sí sola, retira la fila de las listas.",
"activeSuppressionsTitle": "Revisar y revertir dismisses — el panel Active Suppressions",
"activeSuppressionsBody": "Cada alerta actualmente silenciada (time-limited y permanente) aparece en <strong>Settings → Health Monitor → Active Suppressions</strong>. Cada fila muestra el identificador de la alerta, categoría, severidad, cuándo se descartó y cuánto tiempo le queda, más un botón <strong>Re-enable</strong> que limpia el reconocimiento para que la alerta pueda volver a disparar en el próximo escaneo. Los dismisses permanentes solo se pueden revertir desde aquí; los time-limited también se pueden revivir a la fuerza sin esperar a la cuenta atrás. La acción Re-enable está protegida por el modo <em>Edit</em> del Health Monitor arriba de la card — pulsa Edit, haz clic en Re-enable en cada fila que quieras revivir (las filas en cola muestran un borde verde y el identificador tachado) y luego pulsa Save para confirmar. Cancel descarta la cola.",
"autoTitle": "Auto-supresión cuando cambias la Duration",
"activeSuppressionsBody": "Las alertas silenciadas, temporales o permanentes, aparecen en <strong>Ajustes → Monitor de salud → Silenciamientos activos</strong>. Cada fila muestra identificador, categoría, gravedad, fecha y tiempo restante. <strong>Reactivar</strong> quita la confirmación para permitir otra alerta en el próximo análisis. Los descartes permanentes se revierten desde aquí; los temporales también pueden reactivarse antes de tiempo. Activa el modo <em>Editar</em> de la tarjeta, pulsa Reactivar en las filas deseadas (quedan con borde verde y tachadas) y Guarda para aplicar. Cancelar vacía la selección.",
"autoTitle": "Silenciamiento automático al cambiar la duración",
"autoBody": "Poner una Suppression Duration de categoría a cualquier cosa distinta del valor por defecto de 24 h tiene un segundo efecto más allá de los dismissals iniciados por el usuario: <strong>los futuros hallazgos en esa categoría entran en la tabla ya reconocidos</strong> con esa duración. Esto es por diseño — si le has dicho al Monitor que quieres los eventos de disco silenciados durante una semana, los hallazgos de disco nuevos honran esa intención sin que tengas que hacer dismiss de cada uno a mano. Aparecen directamente en la lista Dismissed con el tiempo restante configurado. Las categorías dejadas en 24 h no se ven afectadas y se comportan de la forma clásica (los hallazgos nuevos aterrizan en Active hasta que actúes).",
"tempTitle": "La temperatura de CPU CRITICAL es el override de seguridad",
"tempBody": "Un hallazgo específico saltea la supresión por completo: <strong>temperatura de CPU CRITICAL</strong>. Si el sensor cruza el umbral crítico, la alerta re-dispara independientemente de cualquier dismissal previo — una CPU achicharrada es una CPU achicharrada. Este es el único override integrado del modelo de dismiss.",
"nonDismissableTitle": "Hallazgos a los que no se les puede hacer dismiss",
"nonDismissableBody": "Un puñado de hallazgos están marcados como no-descartables a propósito — señalan una condición donde silenciar la alerta podría costar datos, hardware o conectividad. El botón Dismiss está oculto para estas filas; la alerta se aclara solo cuando la condición subyacente se recupera y la limpieza auto-resolve la coge. Otros hallazgos (eventos I/O transitorios en un disco sano, estados recuperados) también están marcados no-descartables pero por la razón opuesta: no hay nada que silenciar porque la fila ya es informativa y se auto-aclara.",
"tempBody": "La persistencia incluye una regla especial para un registro <strong>Temperatura de CPU CRITICAL</strong>: si lo recibe, ignora la confirmación previa y el silenciamiento automático. Esto no significa que todos los comprobadores de temperatura emitan un registro crítico al superar un umbral configurado.",
"nonDismissableTitle": "¿Qué hallazgos pueden descartarse?",
"nonDismissableBody": "La ventana muestra Descartar solo si la comprobación devuelve explícitamente dismissable = true. Si el valor es falso o falta, oculta el botón. La gravedad no determina este permiso: varias comprobaciones críticas permiten la confirmación. Los ejemplos describen los datos actuales; silenciar una alerta no corrige su causa.",
"headerFinding": "Hallazgo",
"headerWhy": "Por qué no se puede hacer dismiss",
"headerWhy": "Comportamiento al descartar",
"rows": [
{
"finding": "Advertencia / crítico de temperatura de CPU",
"why": "Riesgo hardware — sobre-temperatura sostenida daña el silicio. Silenciar dejaría a una CPU achicharrándose pasar desapercibida."
"why": "El aviso de temperatura basado en muestras permite descartarse explícitamente. Una regla separada ignora la confirmación si llega un registro de temperatura de CPU con gravedad CRITICAL."
},
{
"finding": "Espacio crítico de filesystem (montaje raíz)",
"why": "Riesgo de pérdida de datos — un raíz lleno impide escrituras y corrompe estado. La alerta debe permanecer visible hasta que liberes espacio."
"why": "Las comprobaciones de espacio permiten descartarse, incluso con uso crítico. Confirmar la alerta no libera espacio ni elimina el riesgo de fallos de escritura."
},
{
"finding": "Pool ZFS DEGRADED / FAULTED",
"why": "Riesgo de integridad de datos — el fallo del pool amenaza cada dataset en él. Silenciar mientras el pool está enfermo nunca es la respuesta correcta."
"why": "Los hallazgos de estado del pool ZFS (DEGRADED, FAULTED, UNAVAIL) permiten descartarse, igual que las comprobaciones de capacidad del pool. Confirmar no repara un pool degradado o averiado."
},
{
"finding": "Errores I/O de disco con SMART FAILED",
"why": "Fallo de unidad confirmado por SMART — enmascarar oculta hardware real muriendo. La alerta se queda hasta que el dispositivo sea reemplazado (o eliminado del host)."
"why": "Los hallazgos de disco persistidos desde el journal pueden permitir descartarse. SMART FAILED sigue necesitando investigación; el botón depende del indicador de la comprobación, no solo del texto de la alerta."
},
{
"finding": "Interfaz de red DOWN",
"why": "Pérdida de conectividad — bridges, bonds e interfaces físicas con tráfico activo deben permanecer visibles. Silenciarlos enmascararía una pérdida de acceso remoto."
"why": "Las comprobaciones persistidas de interfaz DOWN permiten descartarse. Esto no restaura un bridge, un bond o un enlace físico, ni recupera el acceso remoto."
},
{
"finding": "Eventos I/O en discos sanos (INFO)",
"why": "Eventos ATA / dmesg transitorios en un disco cuyo SMART dice OK — marcado INFO y auto-aclarándose. Nada que descartar porque el siguiente ciclo ya los retira."
"why": "Los eventos ATA o dmesg transitorios con SMART sano pueden ser informativos y resolverse solos. Las filas informativas pueden no ofrecer Descartar; el comprobador decide cuándo se resuelve la condición."
}
],
"principle": "Todo lo demás se puede descartar. El principio es: alertas que indican \"daño real en progreso\" o que ya se han auto-resuelto se mantienen fuera del camino de dismiss; las alertas sobre condiciones sostenidas que puede que quieras reconocer y revisar más tarde (uso alto de CPU, actualizaciones pendientes, certificado cerca de caducar, warnings de log, hipos de arranque de VM, etc.) todas exponen el botón Dismiss."
"principle": "Usa el botón que muestre el hallazgo concreto; no deduzcas su disponibilidad por la categoría o gravedad. La confirmación controla la presentación y las notificaciones. Las comprobaciones de recuperación y el historial del disco son independientes."
},
"autoresolve": {
"heading": "Auto-resolución y limpieza",
"intro": "Muchas alertas deberían aclararse solas cuando la condición desaparece — una VM que estaba fallando al arrancar y ahora está corriendo, un disco que ya no está en el sistema, una temperatura que ha bajado a la normalidad. Una rutina de limpieza corre al final de cada ciclo de cinco minutos y aplica estas reglas:",
"intro": "Muchas alertas deben desaparecer cuando cesa la causa: una VM que ya arranca, un disco retirado o una temperatura que vuelve a la normalidad. La limpieza al final de cada ciclo de cinco minutos aplica estas reglas:",
"headerTrigger": "Disparador",
"headerAction": "Acción",
"rows": [
@@ -228,7 +228,7 @@
},
{
"trigger": "Hallazgos provenientes del journal (categoría <code>logs</code>, entradas SMART, errores ATA / I/O) cuando su ventana de supresión caduca.",
"action": "Retirados limpiamente. Cada scan inspecciona entradas frescas del journal desde ese punto en adelante; la misma línea histórica en el journal no se re-emite."
"action": "Se retiran. Cada análisis examina nuevas entradas del journal a partir de ese punto; la misma línea histórica no vuelve a emitirse."
},
{
"trigger": "Errores resueltos con más de siete días.",
@@ -236,27 +236,27 @@
}
],
"permanentTitle": "La supresión permanente no es lo mismo que resuelto",
"permanentBody": "Poner una Suppression Duration de categoría a <code>-1</code> (<em>permanente</em>) silencia alertas futuras para items que descartas en esa categoría — pero no salta el chequeo de auto-resolve de arriba. Si la condición subyacente desaparece (recurso borrado, umbral ya no rebasado), el item igualmente se limpia automáticamente."
"permanentBody": "Una duración por categoría de <code>-1</code> (<em>permanente</em>) silencia futuras alertas de los elementos descartados, pero no evita la comprobación automática anterior. Si desaparece la causa —recurso eliminado o umbral ya no superado—, el elemento sigue limpiándose automáticamente."
},
"observations": {
"heading": "Observaciones de disco — el historial permanente",
"intro": "Los eventos de disco son especiales. Un warning SMART en <code>/dev/sdh</code> a las 02:14 AM es algo que quieres recordar incluso después de que la tormenta I/O se calmase y el error se auto-resolviese — el disco tiene ahora un track record. Para ese propósito, el Monitor de salud guarda una tabla <strong>permanente</strong> aparte: <code>disk_observations</code>.",
"intro": "Los eventos de disco merecen conservarse. Un aviso SMART en <code>/dev/sdh</code> a las 02:14 sigue siendo relevante cuando termina la ráfaga de E/S y el error se resuelve solo: el disco ya tiene antecedentes. Por eso el Monitor de salud mantiene otra tabla <strong>permanente</strong>: <code>disk_observations</code>.",
"headerProperty": "Propiedad",
"headerErrors": "tabla <code>errors</code> (Active)",
"headerErrors": "Tabla <code>errors</code> (Activos)",
"headerObs": "tabla <code>disk_observations</code>",
"rows": [
{
"property": "Propósito",
"errors": "Dirige la vista <em>actual</em> de salud + despacho de notificaciones.",
"obs": "Audit trail permanente por disco."
"obs": "Registro de auditoría permanente por disco."
},
{
"property": "Auto-resolve",
"errors": "Sí — las filas se aclaran cuando la condición desaparece.",
"property": "Resolución automática",
"errors": "Sí: las filas se retiran cuando desaparece la causa.",
"obs": "No — las entradas persisten para siempre salvo que el usuario las descarte explícitamente."
},
{
"property": "Clave de dedup",
"property": "Clave de deduplicación",
"errors": "<code>error_key</code> (p. ej. <code>smart_sdh</code>).",
"obs": "<code>(disk_registry_id, error_type, error_signature)</code> con firmas estables despojadas de datos volátiles."
},
@@ -268,10 +268,10 @@
{
"property": "Qué registra",
"errors": "Lo que esté fallando actualmente.",
"obs": "Warnings SMART (problemas de sector / temperatura / CRC / self-tests fallidos), errores I/O (ATA / NVMe / dm), errores de filesystem, eventos de pool ZFS."
"obs": "Avisos SMART (sectores, temperatura, CRC o autopruebas fallidas), errores de E/S (ATA / NVMe / dm), errores del sistema de archivos y eventos de pools ZFS."
}
],
"outro": "Consecuencia práctica: una alerta puede aclararse del panel mientras el mismo incidente sigue registrado en el historial del disco. Cuando entras a un disco bajo Almacenamiento, la tarjeta muestra el conteo de observaciones pendientes y una lista con timestamps, severidad y el mensaje crudo original — útil cuando estás decidiendo si una unidad necesita reemplazo.",
"outro": "Una alerta puede desaparecer del panel mientras el incidente sigue registrado en el historial del disco. Al abrir el disco en Almacenamiento, su tarjeta muestra las observaciones pendientes con fecha, gravedad y mensaje original sin procesar. Esto ayuda a decidir si hay que sustituirlo.",
"renameTitle": "Los renombres entre dispositivos se fusionan automáticamente",
"renameBody": "Los discos a veces aparecen bajo nombres transitorios (<code>ata8</code>, <code>nvme0n1p3</code>) antes de conseguir un nombre estable de block-device. La capa de observaciones consolida entradas por número de serie cuando se conoce: si un evento se registró primero como <code>ata8</code> y el mismo disco se identifica más tarde como <code>sdh</code>, las observaciones históricas se reasocian a <code>sdh</code> en el siguiente ciclo para que el historial no se fragmente."
},
@@ -283,13 +283,13 @@
"Si el tipo de evento está <strong>activado</strong> en los ajustes globales de notificación, y el canal no ha silenciado esta categoría, se encola un evento.",
"El motor de templates renderiza un par (título, cuerpo) desde los detalles estructurados. Si el reescritor de IA está activado, el mismo par también pasa por el proveedor configurado para una versión en lenguaje natural.",
"La implementación del canal lo envía: mensaje de Telegram, embed de Discord, push de Gotify o email. El resultado del despacho se guarda en <code>notification_history</code>.",
"Si un dismiss llega más tarde, la ventana de supresión entra en juego y cualquier re-firing posterior del mismo <code>error_key</code> se queda en la cola hasta que la ventana cierre."
"Descartar una alerta inicia su ventana de silenciamiento. Durante ella, las nuevas detecciones del mismo <code>error_key</code> normalmente no generan notificaciones ni quedan en cola para enviarse al terminar. La regla de temperatura crítica de CPU sigue siendo una excepción."
],
"outro": "La configuración de canales (token de bot de Telegram, URLs de webhook, keys de proveedor de IA, toggles por evento, overrides por canal) está documentada en <notifLink>Notifications</notifLink> y <aiLink>Asistente de IA</aiLink>."
"outro": "La configuración de canales —token del bot Telegram, URLs de webhook, claves de IA, opciones por evento y ajustes por canal— se explica en <notifLink>Notificaciones</notifLink> y <aiLink>Asistente de IA</aiLink>."
},
"rest": {
"heading": "Endpoints REST",
"intro": "Todo lo que hace el modal se puede llamar desde la API — útil para scripts, paneles propios o tu propia integración de chat-bot. Cada llamada necesita un token de API; las que modifican algo — descartar una alerta, guardar los ajustes de supresión o limpiar huérfanos — requieren uno con scope full_admin, y un token read_only recibe 403.",
"intro": "Las acciones de la ventana están disponibles por API para scripts, paneles o bots. Las llamadas necesitan un token Bearer válido, obtenido al iniciar sesión o en la pantalla de tokens API. Los cambios, como confirmar alertas, guardar ajustes o limpiar errores huérfanos, exigen full_admin; read_only recibe 403.",
"headerEndpoint": "Endpoint",
"headerMethod": "Método",
"headerUse": "Uso",
@@ -297,7 +297,7 @@
{
"endpoint": "/api/health",
"method": "GET",
"use": "Probe pequeño de salud — devuelve JSON con <code>status</code>, <code>timestamp</code> y <code>version</code>. Adecuado para keyword checks de Uptime Kuma; el receptor debe enviar la cabecera bearer."
"use": "Comprobación ligera que devuelve JSON con <code>status</code>, <code>timestamp</code> y <code>version</code>. Sirve para comprobar palabras clave con Uptime Kuma; el cliente debe enviar una cabecera Bearer."
},
{
"endpoint": "/api/health/status",
@@ -312,27 +312,27 @@
{
"endpoint": "/api/health/full",
"method": "GET",
"use": "Snapshot completo — categorías + errores activos + lista de dismissed + ajustes de supresión personalizados. Alimenta el modal en un round-trip y usa una caché de fondo de 6 min para respuesta instantánea."
"use": "Vista completa: categorías, errores activos, descartados y ajustes de silenciamiento. Alimenta la ventana con una sola petición y usa una caché en segundo plano de seis minutos para responder rápidamente."
},
{
"endpoint": "/api/health/active-errors",
"method": "GET",
"use": "Solo la lista Active. Filtrable por <code>?category=&lt;name&gt;</code>."
"use": "Solo la lista Activos. Admite el filtro <code>?category=&lt;name&gt;</code>."
},
{
"endpoint": "/api/health/dismissed",
"method": "GET",
"use": "Solo la lista Dismissed, con las horas de supresión restantes."
"use": "Solo la lista Descartados, con las horas restantes de silenciamiento."
},
{
"endpoint": "/api/health/acknowledge",
"method": "POST",
"use": "Body: <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Descarta una alerta con la ventana configurada de la categoría."
"use": "Cuerpo: <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Descarta una alerta durante el plazo configurado para su categoría."
},
{
"endpoint": "/api/health/settings",
"method": "GET / POST",
"use": "Lee o escribe los valores de Suppression Duration por categoría."
"use": "Lee o guarda la duración del silenciamiento por categoría."
},
{
"endpoint": "/api/health/cleanup-orphans",
@@ -348,14 +348,14 @@
"heading": "Por dónde seguir",
"items": [
{
"label": "Dashboard",
"label": "Panel",
"href": "/docs/monitor/dashboard",
"tail": " — desde donde se abre el modal del Monitor de salud en la UI."
},
{
"label": "Notifications",
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tail": " — canales, toggles por evento, el hook de reescritura con IA, historial."
"tail": " — canales, opciones por evento, integración de la reformulación IA e historial."
},
{
"label": "Asistente de IA",
+23 -23
View File
@@ -27,7 +27,7 @@
"tableWhat": "Qué muestra",
"sections": [
{
"name": "Health Monitor",
"name": "Monitor de salud",
"description": "Alertas activas y descartadas para CPU, memoria, almacenamiento, discos, red, servicios, logs, VMs, actualizaciones y seguridad. Alimenta el motor de notificaciones."
},
{
@@ -40,7 +40,7 @@
},
{
"name": "VMs y contenedores",
"description": "Inventario de todas las VMs y LXCs con estado, recursos y uptime. El detalle muestra config, métricas históricas, logs completos del guest y acciones de start/stop/reboot/shutdown."
"description": "Inventario de VM y LXC con estado, recursos y tiempo de actividad. El detalle muestra configuración, métricas históricas, descarga de registros de Proxmox y acciones de iniciar/parar/reiniciar/apagar. Los registros dependen del endpoint de Proxmox; no es un archivo completo del sistema invitado."
},
{
"name": "Hardware",
@@ -52,37 +52,37 @@
},
{
"name": "Terminal",
"description": "Shell en el navegador hacia el host o cualquier VM/CT, mediante <code>xterm.js</code> sobre WebSockets. Autenticado y auditado igual que el resto de la API."
"description": "Shell del host y acceso a consolas VM/CT compatibles en el navegador mediante <code>xterm.js</code> y WebSockets. Las sesiones no se auditan comando a comando."
},
{
"name": "Seguridad",
"description": "Fallos de autenticación, estado de jails de Fail2Ban, eventos de bloqueo recientes, integración con el jail <code>[proxmenux]</code> del host."
"description": "Fallos de autenticación, estado de las jails de Fail2Ban, bloqueos recientes e integración con la jail <code>[proxmenux]</code> del host."
}
],
"footer": "Cada sección tiene su propia página de documentación bajo <link>Dashboard</link> en la barra lateral."
"footer": "Cada sección tiene documentación propia bajo <link>Panel</link> en la barra lateral."
},
"howItRuns": {
"heading": "Cómo se ejecuta",
"intro": "ProxMenux Monitor se distribuye como un AppImage autocontenido. Una única unidad systemd (<code>proxmenux-monitor.service</code>) arranca un proceso Flask que:",
"intro": "ProxMenux Monitor se distribuye como una AppImage autónoma. Una única unidad de systemd (<code>proxmenux-monitor.service</code>) inicia un proceso de Flask que:",
"bullets": [
"Escucha en <strong>TCP 8008</strong> en el host (HTTP).",
"Sirve el panel Next.js como activos estáticos bajo <code>/</code> y la API bajo <code>/api/*</code> desde el mismo proceso.",
"Obtiene datos en vivo con herramientas estándar del host: <code>psutil</code>, <code>pvesh</code>, <code>smartctl</code>, <code>journalctl</code>, <code>zpool</code>, <code>ip</code>, <code>nvidia-smi</code>, etc.",
"Persiste su propio estado en una base de datos SQLite local (<code>/usr/local/share/proxmenux/health_monitor.db</code>): alertas descartadas, observaciones de discos, configuración de notificaciones, configuración de IA. El estado de autenticación vive aparte en <code>/root/.config/proxmenux-monitor/auth.json</code>."
],
"footer": "El flujo completo de petición, la disposición de archivos y la integración systemd se describen en <link>Architecture</link>."
"footer": "El flujo de peticiones, la estructura de archivos y la integración systemd se describen en <link>Arquitectura</link>."
},
"noAgent": {
"title": "Sin agente en los guests",
"body": "El Monitor lee todo desde el host. Las VMs y CTs no necesitan ningún agente instalado — los datos del guest provienen de la API de Proxmox y de la visibilidad a nivel de kernel del propio host sobre los guests en ejecución."
"body": "El Monitor obtiene los datos desde el host. No hace falta instalar un agente en las VM ni en los CT: los datos proceden de la API de Proxmox y de la información que el kernel del host ofrece sobre los invitados en ejecución."
},
"access": {
"heading": "Acceder al panel",
"intro": "Se soportan dos patrones de acceso y la aplicación detecta cuál está en uso:",
"codeComment1": "# 1) Acceso directo al host",
"codeComment2": "# 2) Mediante proxy inverso (Nginx / Caddy / Traefik)",
"afterCode": "Cuando hay un proxy inverso por delante, el Monitor respeta <code>X-Forwarded-For</code>, <code>X-Forwarded-Proto</code> y <code>X-Forwarded-Host</code> para que las URLs y CORS funcionen correctamente sin configuración manual.",
"footer": "La configuración inicial, contraseña + TOTP 2FA y snippets de proxy inverso se cubren en <link>Access & Authentication</link>."
"afterCode": "El proxy inverso debe configurar <code>X-Forwarded-For</code>, <code>X-Forwarded-Proto</code> y <code>X-Forwarded-Host</code> correctamente y permitir WebSockets. En puertos estándar el navegador usa su origen actual. El backend solo confía en direcciones reenviadas con PROXMENUX_TRUST_PROXY=1 explícito; restringe su acceso directo si activas esa confianza.",
"footer": "La configuración inicial, contraseña + TOTP 2FA y ejemplos de proxy inverso se explican en <link>Acceso y autenticación</link>."
},
"mobile": {
"heading": "Uso móvil e instalación en la pantalla de inicio",
@@ -95,8 +95,8 @@
"androidLabel": "Android Chrome / Edge:",
"androidBody": "menú de tres puntos → <em>Instalar app</em> (o <em>Añadir a pantalla de inicio</em> en versiones antiguas).",
"afterInstall": "Una vez instalado, abrir el icono lanza el panel en modo standalone con su propia entrada en el conmutador de tareas.",
"onlineOnlyTitle": "Solo online",
"onlineOnlyBody": "La PWA es instalable pero <strong>no</strong> funciona sin conexión — no hay service worker. El lanzador se comporta como una app nativa, pero el dispositivo necesita poder llegar al host en TCP 8008 (LAN, VPN o HTTPS tras proxy inverso) para que el panel cargue."
"onlineOnlyTitle": "Requiere conexión",
"onlineOnlyBody": "La PWA se puede instalar, pero <strong>no</strong> funciona sin conexión: no incluye un service worker. El acceso directo se comporta como una aplicación nativa, pero el dispositivo debe poder conectar con el host por TCP 8008 (mediante LAN, VPN o HTTPS a través de un proxy inverso) para cargar el panel."
},
"health": {
"heading": "El Health Monitor y las notificaciones",
@@ -112,38 +112,38 @@
},
"api": {
"heading": "API REST e integraciones",
"intro": "Todo lo que muestra la interfaz está disponible como JSON sobre HTTP/HTTPS. Los mismos endpoints alimentan widgets de Homepage, sensores de Home Assistant, dashboards de Grafana (vía el exporter Prometheus en <code>/api/prometheus</code>), pruebas de Uptime Kuma y cualquier script personalizado que hable <code>curl</code>.",
"tokens": "Los tokens API de larga duración (365 días) se generan desde <strong>Settings → API Access Tokens</strong> o vía <code>POST /api/auth/generate-api-token</code>.",
"bearer": "Los tokens viajan como <code>Authorization: Bearer …</code>. Los endpoints públicos (<code>/api/health</code>, <code>/api/auth/*</code>) funcionan sin token para que las pruebas externas de uptime puedan llegar al host sin entregar credenciales.",
"catalog": "El catálogo completo de endpoints, la guía de rotación de tokens y las buenas prácticas de seguridad viven en <linkApi>API Reference</linkApi>; los ejemplos listos para Homepage, Home Assistant, Grafana, Uptime Kuma y un patrón genérico de cURL están en <linkIntegrations>Integrations</linkIntegrations>."
"intro": "Los endpoints REST ofrecen datos de monitorización JSON por HTTP/HTTPS para widgets Homepage, sensores Home Assistant, pruebas Uptime Kuma y scripts. Grafana puede usar el exportador de texto Prometheus en <code>/api/prometheus</code>. Las peticiones se pueden hacer con <code>curl</code>.",
"tokens": "Los tokens API de larga duración (365 días) se generan en <strong>Configuración → Tokens de acceso API</strong> o mediante <code>POST /api/auth/generate-api-token</code>.",
"bearer": "Envía tokens con <code>Authorization: Bearer …</code>. <code>/api/health</code> también espera la cabecera Bearer, así que las pruebas de disponibilidad necesitan un token read_only. Bajo <code>/api/auth/*</code> hay rutas públicas de configuración/inicio/estado y rutas protegidas de cuentas y tokens; no todas son anónimas.",
"catalog": "El catálogo de endpoints, rotación de tokens y prácticas de seguridad están en <linkApi>Referencia de la API</linkApi>. Los ejemplos para Homepage, Home Assistant, Grafana, Uptime Kuma y cURL están en <linkIntegrations>Integraciones</linkIntegrations>."
},
"serviceControl": {
"heading": "Control del servicio",
"intro": "Día a día, el Monitor se gestiona exactamente como cualquier otro servicio systemd. También está expuesto como dos entradas dentro del TUI de ProxMenux bajo <em>Settings</em>:",
"intro": "Monitor se gestiona como cualquier servicio systemd. También tiene dos entradas en la interfaz de texto ProxMenux bajo <em>Configuración</em>:",
"codeComment": "# Control manual",
"footer": "Mira <link>Settings → ProxMenux Monitor</link> para el conmutador del menú y el flujo de verificación de estado."
"footer": "Consulta <link>Configuración → ProxMenux Monitor</link> para activar/desactivar el servicio y verificar su estado."
},
"nextSteps": {
"heading": "A dónde ir ahora",
"items": [
{
"label": "Architecture",
"label": "Arquitectura",
"description": "— backend Flask, unidad systemd, esquema SQLite, proveedores IA, canales de notificación."
},
{
"label": "Access & Authentication",
"label": "Acceso y autenticación",
"description": "— primer arranque, configuración de contraseña, TOTP 2FA, configuración de proxy inverso, integración con Fail2Ban."
},
{
"label": "Dashboard",
"label": "Panel",
"description": "— cada sección de la interfaz, una página por cada una."
},
{
"label": "API Reference",
"label": "Referencia de la API",
"description": "— cada endpoint, forma de petición / respuesta y gestión de tokens."
},
{
"label": "Integrations",
"label": "Integraciones",
"description": "— Homepage, Home Assistant, Grafana / Prometheus, Uptime Kuma, patrón genérico de cURL."
}
]
+40 -40
View File
@@ -10,21 +10,21 @@
"header": {
"title": "Integraciones",
"description": "Guías copia-pega para conectar ProxMenux Monitor en los paneles y herramientas que tu homelab ya usa — Homepage, Home Assistant, Grafana vía Prometheus, Uptime Kuma. Cada guía muestra la configuración exacta que espera la herramienta receptora, el endpoint del Monitor con el que habla y el patrón de cabecera de auth que lo une todo.",
"section": "ProxMenux Monitor"
"section": "Monitor de ProxMenux"
},
"intro": {
"title": "Qué puedes construir desde esta página",
"body": "Cada guía de abajo está lista para copiar a tu herramienta elegida. Los endpoints de la API usados aquí están documentados en la <link>API Reference</link> — esta página es el compañero \"cómo usarlos realmente en Homepage / Home Assistant / Grafana\". Las capturas muestran la salida real que verás una vez la guía esté en su sitio."
"body": "Copia cada ejemplo en la herramienta correspondiente. Los endpoints están documentados en la <link>Referencia de la API</link>; esta página explica cómo utilizarlos en Homepage, Home Assistant y Grafana. Las capturas muestran el resultado de esas configuraciones."
},
"auth": {
"heading": "Autenticación: lo único que cada guía necesita",
"intro": "La mayoría de los endpoints usados por estas integraciones están autenticados. Tienes dos formas de satisfacer ese requisito.",
"optAtitle": "Opción A — API token (recomendado para integraciones)",
"optAbody1": "Abre el panel y ve a <strong>Settings → Security → API Tokens</strong>. Pulsa <em>Generate token</em>, dale un nombre (p. ej. <em>homepage</em>, <em>home-assistant</em>, <em>prometheus</em>), y copia el token — se muestra <em>una vez</em>. De larga duración (un año de expiración por defecto), revocable individualmente, y lo que deberías usar para cualquier cliente no-navegador.",
"optAbody1": "Entra en <strong>Ajustes → Seguridad → Tokens API</strong>. Pulsa <em>Generar token</em>, ponle un nombre, como <em>homepage</em>, <em>home-assistant</em> o <em>prometheus</em>, y cópialo: se muestra <em>una sola vez</em>. Caduca al año por defecto y puede revocarse individualmente. Úsalo para los clientes externos al navegador.",
"optAbody2": "A partir de ahí cada petición es simplemente:",
"optBtitle": "Opción B — flujo de login (usuario + contraseña)",
"optBbody": "Útil para scripts que se autentican como un usuario humano. El token devuelto es de corta duración; la mayoría de integraciones deberían preferir la Opción A.",
"outro": "El campo TOTP solo es requerido cuando el 2FA está activado en la cuenta. La rotación de tokens, la revocación, la política de contraseñas y el log de auditoría viven en <link>Access & Authentication</link>.",
"outro": "El campo TOTP solo hace falta con la autenticación en dos pasos activada. La rotación y revocación de tokens, la política de contraseñas y el registro de auditoría se explican en <link>Acceso y autenticación</link>.",
"httpsTitle": "Usando HTTPS en lugar de HTTP",
"httpsIntro": "Cada guía de abajo usa <code>http://</code> en las URLs para mantener los ejemplos cortos. Si has activado TLS en el Monitor (<strong>Settings → Security → SSL/HTTPS</strong>), cambia <code>http://</code> por <code>https://</code> en cada URL — ese es el único cambio. Dos notas específicas para ciertas herramientas:",
"httpsItems": [
@@ -48,16 +48,16 @@
"multiTitle": "Setup multi-widget — sistema, almacenamiento, red",
"multiIntro": "Para una vista más rica, renderiza tres tarjetas separadas respaldadas por distintos endpoints — una para métricas del sistema, una para almacenamiento, una para red. Usa el mismo token en cada tarjeta; es la misma instancia del Monitor.",
"multiCalloutTitle": "Múltiples hosts Proxmox",
"multiCalloutBody": "Repite el bloque de entrada por host para obtener el layout multi-tarjeta de la captura de arriba — cada entrada apunta a la URL <code>http://&lt;host&gt;:8008</code> de su propia instancia de ProxMenux Monitor. El token puede ser distinto por host (una entrada secret por host) o compartido, según cómo los generes."
"multiCalloutBody": "Repite el bloque para cada host y obtendrás las tarjetas de la captura. Cada entrada usa la URL <code>http://&lt;host&gt;:8008</code> de su propia instancia. Genera y guarda un token por host: cada instalación tiene su clave de firma y no debes asumir que el token de otra funcione."
},
"homeAssistant": {
"heading": "Home Assistant",
"headingHref": "https://www.home-assistant.io",
"intro": "No hay una integración HACS nativa para ProxMenux Monitor (todavía) — pero no la necesitas. La integración <code>rest</code> integrada en Home Assistant puede consumir cada endpoint documentado en la <link>API Reference</link> y convertir las respuestas en sensores, atributos y triggers. El build de referencia completo de abajo expone ~25 sensores cubriendo recursos del sistema, el Monitor de salud, VMs / CTs, almacenamiento, red, latencia al gateway y estado de actualización de ProxMenux — pega el YAML en <code>configuration.yaml</code>, reinicia y tienes una capa completa de observabilidad de Proxmox dentro de HA.",
"intro": "Estos ejemplos usan la integración <code>rest</code> de Home Assistant y no necesitan un componente HACS propio. Leen endpoints del Monitor descritos en la <link>Referencia de la API</link> y convierten sus respuestas en sensores y atributos para automatizaciones. La configuración ofrece unos 25 sensores de recursos, salud, VMs/CTs, almacenamiento, red y actualizaciones. Añádela a <code>configuration.yaml</code> y recarga o reinicia HA.",
"imageAlt": "Panel Home Assistant mostrando entidades de ProxMenux Monitor — badge de estado de salud, gauges de CPU / RAM / Temp, contador de VMs, uso de almacenamiento y contador de errores activos",
"imageCaption": "ProxMenux Monitor como integración de primera clase en Home Assistant — sensores construidos desde la guía YAML de abajo.",
"step1Title": "1 · Guarda el API token",
"step1Body": "Mete el token en el <code>secrets.yaml</code> de Home Assistant para que nunca se filtre en un volcado de config. El prefijo bearer entero va en una línea — eso permite al YAML referenciarlo directamente como valor de cabecera. El nombre y ubicación del archivo depende de tu instalación de HA (típicamente <code>/config/secrets.yaml</code> para HA OS / Container).",
"step1Body": "Guarda el token en <code>secrets.yaml</code> para separarlo de la configuración principal. Incluye el prefijo Bearer y el token en un único valor para usarlo como cabecera. El archivo no está cifrado y también debe mantenerse privado. Su ubicación depende de la instalación; normalmente es <code>/config/secrets.yaml</code> en HA OS o Container.",
"step2Title": "2 · Añade la configuración REST",
"step2Body": "Seis bloques REST cubren toda la superficie — uno por área principal del Monitor. Cada bloque tiene un <code>scan_interval</code> sensato ajustado a cuán a menudo cambian los datos subyacentes (recursos del sistema cada 30 s, salud cada 60 s, inventarios que cambian despacio cada 5-10 min). Pega en <code>configuration.yaml</code>:",
"step3Title": "3 · Añade sensores binarios y helpers de template",
@@ -65,21 +65,21 @@
"step4Title": "4 · Recarga y verifica",
"step4Body": "Desde la UI de HA: <em>Developer Tools → YAML → Check Configuration</em> primero para validar la sintaxis, luego recarga <em>All YAML configuration</em> (o reinicia completo). Después de que vuelva, filtra <em>Settings → Devices & Services → Entities</em> por <em>proxmenux</em> — deberías ver las ~25 entidades llenándose dentro de un intervalo de scan.",
"replaceTitle": "¿Reemplazando una versión anterior de esta guía?",
"replaceBody": "Si probaste una versión previa de estos bloques YAML, el registro de entidades de Home Assistant puede haber cacheado los IDs de entidad viejos y entidades obsoletas seguirán apareciendo (con warnings <em>Entidad no encontrada</em> en tus tarjetas Lovelace). Estado limpio en dos pasos: borra los bloques <code>rest:</code> y <code>template:</code> previos de <code>configuration.yaml</code>, recarga, y luego bajo <em>Settings → Devices & Services → Entities</em> filtra por <em>proxmenux</em> y quita cualquier entrada marcada como \"Restored\" o mostrada como indisponible. Luego pega el YAML actual y recarga de nuevo — las entidades nuevas se registran limpiamente.",
"replaceBody": "Si usaste una versión anterior, el registro de entidades puede conservar IDs obsoletos y las tarjetas mostrar <em>Entidad no encontrada</em>. Quita los bloques anteriores <code>rest:</code> y <code>template:</code> de <code>configuration.yaml</code> y recarga. En <em>Ajustes → Dispositivos y servicios → Entidades</em>, filtra por <em>proxmenux</em> y elimina las entradas antiguas restauradas o no disponibles. Añade después el YAML actual y recarga para registrar las nuevas.",
"step5Title": "5 · Panel Lovelace",
"step5Body": "El YAML de abajo es una única tarjeta <strong>vertical-stack</strong> que combina todas las sub-tarjetas en un bloque — cabecera con logo, KPIs rápidos, detalle del sistema, VMs, almacenamiento, red y una tarjeta condicional de problemas de salud. Para usarla: abre tu panel, pulsa el lápiz (editar), pulsa <em>Add card</em>, baja al final y elige <em>Manual</em>, luego pega:",
"viewTipTitle": "¿Lo quieres como vista completa de panel en lugar de una sola tarjeta?",
"viewTipBody": "Abre el menú de 3 puntos del panel → <em>Raw configuration editor</em> y añade una vista nueva con esta cabecera (encima de la lista <code>cards:</code> del YAML de arriba):",
"viewTipOutro": "Eso te da una pestaña/vista dedicada en tu panel con su propio icono y título, en vez de una tarjeta larga en una vista existente.",
"altViewTitle": "Alternativa — una vista de panel dedicada",
"altViewIntro": "Si prefieres tener una página dedicada completa (su propia pestaña en la barra lateral del panel) en vez de una tarjeta dentro de una vista existente, Home Assistant te deja crear una vista nueva directamente con YAML. Pasos:",
"altViewIntro": "Para crear una pestaña propia dentro de un panel existente, añade una vista con el YAML de abajo. Una vista es una pestaña del panel; no crea una entrada nueva en la barra lateral. Pasos:",
"altViewSteps": [
"Abre el panel donde quieres la nueva pestaña.",
"Pulsa el lápiz (editar panel) arriba a la derecha.",
"Pulsa la pestaña <em>+</em> al final de las pestañas existentes para crear una vista nueva.",
"En el diálogo que se abre, cambia a la pestaña <em>Code editor</em> (arriba a la derecha del diálogo — alterna entre editor visual y YAML).",
"Pega el YAML de abajo.",
"Guarda. La nueva pestaña <em>ProxMenux Monitor</em> aparece en la barra lateral con todas las tarjetas renderizadas."
"Guarda. La vista <em>ProxMenux Monitor</em> aparece como pestaña dentro del panel con sus tarjetas."
],
"twoEditorsTitle": "Dos editores YAML en HA — elige el correcto",
"twoEditorsIntro": "Home Assistant tiene dos editores YAML que parecen similares pero esperan formatos distintos:",
@@ -89,7 +89,7 @@
],
"twoEditorsOutro": "Pegar YAML de cuerpo de vista en el editor de panel entero (o viceversa) te deja con una <em>Vista sin nombre</em> y <code>cards: []</code>. El YAML de abajo es para el editor de una sola vista — pega exactamente como se muestra.",
"viewImageAlt": "Vista dedicada de Home Assistant renderizando ProxMenux Monitor — cabecera picture-entity, KPIs glance y tarjetas de entidad Sistema / VMs / Almacenamiento / Red distribuidas automáticamente por HA en múltiples columnas",
"viewImageCaption": "La vista dedicada <em>ProxMenux Monitor</em> como la renderiza Home Assistant en una pantalla ancha — el layout por defecto de HA divide las tarjetas en múltiples columnas automáticamente.",
"viewImageCaption": "La vista <em>ProxMenux Monitor</em> en pantalla ancha. La disposición Masonry distribuye las tarjetas automáticamente en columnas; el resultado depende del tipo de vista configurado.",
"twoColTipTitle": "¿Quieres un layout fijo de dos columnas en lugar del auto layout?",
"twoColTipBody": "Reemplaza cualquier par de tarjetas (p. ej. <em>Sistema</em> + <em>VMs</em>, o <em>Almacenamiento</em> + <em>Red</em>) con un único <code>horizontal-stack</code> envolviendo ambas, para que siempre se rendericen lado a lado independientemente del ancho de pantalla:",
"twoColTipOutro": "En móvil la fila se mantiene comprimida; el auto layout de HA (sin horizontal-stack) refluye mejor a anchos estrechos.",
@@ -105,28 +105,28 @@
"En el YAML Lovelace, reemplaza la URL <code>image:</code> por <code>/local/icons/proxmenux.svg</code>. Guarda y recarga — la imagen se renderiza desde el archivo local, sin internet necesaria."
],
"scanTipTitle": "Regla práctica para scan_interval",
"scanTipBody": "<code>/api/system</code> es barato de llamar — 30 s está bien. <code>/api/health/full</code> usa una caché interna de 6 min, así que hacer polling más a menudo de ~60 s no te aporta nada. <code>/api/storage/summary</code> cambia despacio — cada 5 min sobra. <code>/api/proxmenux/update-status</code> solo importa una vez por hora. Ajusta a tu presupuesto de hardware si tienes muchos sensores en muchos hosts."
"scanTipBody": "Un punto de partida razonable es consultar <code>/api/system</code> cada 30 s. <code>/api/health/full</code> suele leer datos en caché válidos hasta seis minutos; consultarlo cada 60 s no evita esa caché. Prueba cinco minutos para <code>/api/storage/summary</code> y una hora para <code>/api/proxmenux/update-status</code>. Ajusta los intervalos a tu hardware y número de hosts."
},
"grafana": {
"heading": "Prometheus + Grafana",
"promHref": "https://prometheus.io",
"grafanaHref": "https://grafana.com",
"intro": "ProxMenux Monitor expone un endpoint de scrape formato Prometheus en <code>GET /api/prometheus</code> (autenticado) devolviendo texto OpenMetrics. Cabléalo a Prometheus, luego construye un panel Grafana encima — los mismos datos que muestra la UI del panel, en el formato que tu TSDB espera.",
"intro": "ProxMenux Monitor expone <code>GET /api/prometheus</code> con formato de exposición de texto Prometheus 0.0.4. Necesita un token Bearer si la autenticación está activada. Configura Prometheus para recoger las métricas y Grafana para visualizar la base de datos de series temporales.",
"imageAlt": "Panel Grafana renderizando métricas de ProxMenux Monitor — gauge de uso de CPU, timeseries de uso de memoria, contador de VMs en ejecución, throughput de red",
"imageCaption": "Un panel Grafana básico construido desde el scrape Prometheus de ProxMenux — CPU, memoria, VMs en ejecución, throughput de red. El catálogo completo de métricas vive en la <link>API Reference → Métricas Prometheus</link>.",
"step1Title": "1 · Añade el job de scrape a Prometheus",
"step1Body": "Pasa el API token vía el bloque nativo <code>authorization</code> de Prometheus (más limpio que cabeceras personalizadas y funciona con secret stores):",
"step1After": "Recarga Prometheus (<code>kill -HUP</code> o <code>systemctl reload prometheus</code>, o <code>docker compose restart prometheus</code> si lo corres como contenedor) y comprueba <em>Status → Targets</em> — el job proxmenux debería ponerse verde dentro de un intervalo de scrape. Cada métrica lleva una etiqueta <code>node=\"&lt;hostname&gt;\"</code> para que puedas distinguir hosts en las queries.",
"tokenTipTitle": "Token vía archivo o env, no inline",
"step1After": "Recarga Prometheus con <code>kill -HUP &lt;PID&gt;</code> (sustituye PID por su ID de proceso), <code>systemctl reload prometheus</code> si el servicio lo permite o <code>docker compose restart prometheus</code> para el contenedor. Revisa <em>Status → Targets</em>: el job proxmenux debería pasar a UP en un intervalo de recogida. Las métricas llevan <code>node=\"&lt;hostname&gt;\"</code> para distinguir los hosts.",
"tokenTipTitle": "Guarda el token en un archivo separado",
"tokenTipBody": "Para despliegues en producción evita poner el token inline. Prometheus soporta <code>credentials_file: /etc/prometheus/secrets/proxmenux.token</code> como alternativa — guarda el token en un archivo 0600 y deja que Prometheus lo lea.",
"step2Title": "2 · Verifica el scrape con un par de queries",
"step2Body": "Antes de configurar Grafana, confirma que Prometheus realmente tiene los datos. Abre la propia UI de Prometheus en <code>http://&lt;prometheus-host&gt;:9090</code>, pulsa <em>Query</em> y ejecuta cualquiera de estas — deberías obtener números en vivo de tu host Proxmox:",
"headerQuery": "Query",
"headerQuery": "Consulta",
"headerConfirms": "Qué confirma",
"verifyRows": [
{
"query": "up{job=\"proxmenux\"}",
"confirms": "Devuelve <code>1</code> si Prometheus está haciendo scrape del Monitor con éxito, <code>0</code> si no. La comprobación de cordura más rápida."
"confirms": "Devuelve <code>1</code> si Prometheus recoge datos del Monitor correctamente y <code>0</code> si falla. Es la comprobación inicial más rápida."
},
{
"query": "proxmox_cpu_usage",
@@ -134,7 +134,7 @@
},
{
"query": "proxmox_vms_running",
"confirms": "Número de guests en ejecución. Compara con lo que ves en la UI de Proxmox."
"confirms": "Número de máquinas invitadas en ejecución. Compáralo con la interfaz de Proxmox."
},
{
"query": "proxmox_uptime_seconds / 86400",
@@ -142,13 +142,13 @@
}
],
"calloutTitle": "El 401 que puedes ver al pulsar la URL del endpoint es normal",
"calloutBody": "En la página <em>Status → Targets</em>, pulsar el enlace del endpoint (<code>/api/prometheus</code>) hace que tu navegador lo descargue directamente — sin la cabecera bearer que Prometheus usa para sus propios scrapes. Así que verás <code>'{'\"error\":\"Authentication required\"'}'</code>. Eso confirma que la API está correctamente protegida; el propio Prometheus se autentica correctamente porque tiene el token de la configuración de scrape. Confía en el verde <em>State: UP</em>, no en el click-through.",
"calloutBody": "Con la autenticación activa, al pulsar el enlace en <em>Status → Targets</em> el navegador consulta <code>/api/prometheus</code> sin la cabecera Bearer de Prometheus. Puede responder <code>'{'\"error\":\"Authentication required\"'}'</code>. Comprueba el <em>State: UP</em> del destino para confirmar que Prometheus recoge los datos con su token.",
"step3Title": "3 · Añade Prometheus como fuente de datos en Grafana",
"step3Body": "En Grafana: <em>Connections → Data sources → Add new → Prometheus</em>. Configura la URL a tu instancia de Prometheus (p. ej. <code>http://prometheus.lan:9090</code>), guarda y prueba. No se necesita auth extra en esta capa — Prometheus ya se ha autenticado a ProxMenux.",
"step3Body": "En Grafana, abre <em>Connections → Data sources → Add new → Prometheus</em>. Indica la URL de Prometheus, por ejemplo <code>http://prometheus.lan:9090</code>, guarda y prueba. Si tu servidor Prometheus exige autenticación, configúrala aquí por separado. El token del Monitor pertenece al job de recogida de Prometheus.",
"step4Title": "4 · Construye paneles con estas queries PromQL",
"step4Body": "Un set inicial que mapea directamente a lo que los usuarios típicamente vigilan en un host Proxmox:",
"headerPanel": "Idea de panel",
"headerPromql": "Query PromQL",
"headerPromql": "Consulta PromQL",
"panelRows": [
{
"panel": "Gauge de uso de CPU por host",
@@ -179,11 +179,11 @@
"promql": "rate(proxmox_interface_bytes_sent_total[5m])"
},
{
"panel": "Load average (1m)",
"panel": "Promedio de carga (1m)",
"promql": "proxmox_load_average{period=\"1m\"}"
},
{
"panel": "% espacio en disco usado por mountpoint",
"panel": "Porcentaje de espacio usado por punto de montaje",
"promql": "proxmox_disk_usage_percent"
},
{
@@ -198,55 +198,55 @@
"outro": "Añade cada query como un panel Grafana, configura la visualización adecuada (<em>Stat</em> para gauges, <em>Time series</em> para tendencias) y agrupa paneles en filas por categoría. Usa la etiqueta <code>node</code> como variable de panel (<em>Settings → Variables → New → Query → label_values(proxmox_cpu_usage, node)</em>) para filtrar todos los paneles por host."
},
"uptimeKuma": {
"heading": "Uptime Kuma y otros status checkers",
"heading": "Uptime Kuma y otras herramientas de comprobación de estado",
"href": "https://github.com/louislam/uptime-kuma",
"intro": "Para probes externos, usa <code>GET /api/system-info</code> — es el único endpoint que funciona sin token, devolviendo un payload JSON pequeño con hostname, uptime y el estado global de salud (mapeado a <code>healthy</code> / <code>warning</code> / <code>critical</code>). Eso es exactamente lo que necesita un monitor basado en keyword.",
"kumaTitle": "Uptime Kuma — HTTP keyword monitor",
"intro": "Para comprobar una palabra clave, usa <code>GET /api/system-info</code>. Esta ruta no exige token y devuelve nombre del host, tiempo de actividad y salud como <code>healthy</code>, <code>warning</code> o <code>critical</code>. Es una comprobación pública, a diferencia de los endpoints detallados protegidos.",
"kumaTitle": "Uptime Kuma — Monitor HTTP de palabras clave",
"kumaSteps": [
"En Uptime Kuma, pulsa <em>+ Add New Monitor</em>.",
"Monitor Type: <em>HTTP(s) - Keyword</em>.",
"Friendly Name: <em>ProxMenux Monitor — pve01</em>.",
"Tipo de monitor: <em>HTTP(s) - Palabras clave</em>.",
"Nombre descriptivo: <em>ProxMenux Monitor — pve01</em>.",
"URL: <code>http://pve01.lan:8008/api/system-info</code>.",
"Keyword: <code>healthy</code> (el valor de <code>health.status</code> cuando el host está OK).",
"Heartbeat Interval: 60 segundos basta.",
"Guarda. Sin cabeceras necesarias — el endpoint es público."
"Intervalo de comprobación: 60 segundos es suficiente.",
"Guarda. La ruta system-info no necesita una cabecera Bearer."
],
"healthchecksTitle": "healthchecks.io / pings tipo cron",
"healthchecksBody": "Mismo endpoint, misma forma — apunta tu ping tipo cron a <code>/api/system-info</code> y comprueba <code>.health.status == \"healthy\"</code>. La mayoría de estos servicios aceptan un estado HTTP 2xx como señal de \"up\" también, en cuyo caso incluso un curl sin parsing basta.",
"healthchecksBody": "Un trabajo cron puede consultar <code>/api/system-info</code> y comprobar <code>.health.status == \"healthy\"</code>. Solo si supera la prueba debe enviar un ping de éxito a la URL única de Healthchecks.io. Ese servicio recibe pings de los trabajos; no consulta el Monitor. Un HTTP 2xx por sí solo no demuestra buena salud del host.",
"richTitle": "¿Quieres datos de salud más ricos?",
"richBody": "Para el estado completo (las diez categorías del Monitor de salud + errores activos + lista dismissed), usa <code>GET /api/health/full</code> en su lugar — ese requiere un API token pero te da todo lo que el modal del panel renderiza en una sola respuesta."
"richBody": "Para el estado completo —diez categorías de salud, errores activos y descartados— usa <code>GET /api/health/full</code>. Devuelve los datos de la ventana del panel en una respuesta y necesita un token Bearer si la autenticación está activada."
},
"workflows": {
"heading": "n8n, Zapier y scripts propios",
"intro": "Para herramientas de workflow y scripts ad-hoc que necesitan <em>levantar</em> notificaciones a través del Monitor (un fallo de CI, un sensor de smart-home, un cron job que tardó demasiado), la guía es un POST a <code>/api/notifications/send</code>. El evento fluye por la misma pipeline de despacho que cualquier cosa emitida internamente — dedup, cooldown, reescritura con IA opcional, fan-out a los canales configurados.",
"n8nBody": "En n8n, el equivalente es un nodo <em>HTTP Request</em> con método POST, la URL de arriba, una cabecera <em>Authorization</em> configurada a <code>Bearer '{''{'$credentials.proxmenux.token'}''}'</code> (usando credentials de n8n) y un body JSON coincidiendo con el payload de curl. Cabléa cualquier nodo precedente como el trigger (cron, webhook, condición).",
"severityBody": "Los valores de severidad son <code>INFO</code>, <code>WARNING</code> o <code>CRITICAL</code> (en mayúsculas). El payload <code>data</code> es JSON libre — el reescritor de IA, cuando está activado, sacará cualquier cosa útil de ahí para el cuerpo renderizado. La semántica completa de tipos de evento vive en <link>Notifications → Catálogo de eventos</link>."
"intro": "Las herramientas de workflow y scripts pueden <em>enviar</em> notificaciones con un POST a <code>/api/notifications/send</code>, por ejemplo por un fallo de CI o un trabajo cron demasiado largo. Es un envío directo: omite la cola y la espera entre huellas de eventos. Conserva el formato por canal, la IA opcional y la entrega a los canales configurados. Controla los duplicados desde quien llama.",
"n8nBody": "En n8n, usa un nodo <em>HTTP Request</em> con POST, la URL anterior y el mismo JSON que curl. Elige credenciales genéricas Header Auth: nombre <em>Authorization</em> y valor <code>Bearer YOUR_API_TOKEN</code>, sustituyendo el marcador. Conecta una programación, webhook u otro nodo para disparar la petición.",
"severityBody": "La gravedad usa <code>INFO</code>, <code>WARNING</code> o <code>CRITICAL</code> en mayúsculas. El objeto <code>data</code> aporta contexto del evento y campos de plantilla. En este endpoint, la IA solo recibe el título y el mensaje; los campos de <code>data</code> no se envían al proveedor. Consulta <link>Notificaciones → Catálogo de eventos</link>."
},
"pveWebhook": {
"heading": "Webhook nativo de Proxmox VE (entrante)",
"intro1": "Proxmox VE 8.1+ tiene su propio sistema de notificaciones. ProxMenux Monitor se registra como destino webhook para que todo lo que PVE emite por sí mismo (fencing HA, replicación, vzdump desde la GUI, renovación de certificado) aterrice en la misma pipeline de despacho que los propios eventos del Monitor. Esto ocurre automáticamente cuando pulsas <em>Enable Notifications</em> en la pestaña Settings — sin trabajo de integración requerido por parte del usuario.",
"intro1": "El sistema de notificaciones llegó en PVE 8.1; los destinos webhook nativos requieren Proxmox VE 8.3 o posterior. <em>Activar notificaciones</em> en Ajustes intenta registrar el Monitor como destino. Los avisos que PVE enruta allí, como informes de backups o replicación, entran en su flujo de envío. El alta depende de que la configuración esté disponible y permita escritura.",
"intro2": "La mecánica, la plantilla de body que PVE envía, las entradas escritas en <code>/etc/pve/notifications.cfg</code> y el comportamiento en clusters están documentados en <link>Notifications → Integración del webhook de PVE</link>."
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{
"label": "API Reference",
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — cada endpoint con método, path y el catálogo completo de métricas Prometheus."
},
{
"label": "Notifications",
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tail": " — fuentes de eventos, canales, la pipeline de despacho, la integración del webhook de PVE en detalle."
},
{
"label": "Asistente de IA",
"href": "/docs/monitor/ai-assistant",
"tail": " — el reescritor opcional que convierte cuerpos templated en lenguaje natural antes de llegar a Telegram / Discord / email / Gotify."
"tail": " — reformulación opcional de las plantillas en lenguaje sencillo antes de enviarlas a Telegram, Discord, correo o Gotify."
},
{
"label": "Access & Authentication",
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tail": " — emitir y revocar los API tokens que consumen estas guías, log de auditoría, configuración TLS."
}
+150 -150
View File
@@ -1,54 +1,54 @@
{
"meta": {
"title": "Notificaciones de Proxmox — Telegram, Discord, Email, Gotify, Pushover, Apprise | ProxMenux Monitor",
"description": "Envía notificaciones de Proxmox VE a Telegram, Discord, Email, Gotify, Pushover y unos 80 servicios adicionales mediante Apprise. ProxMenux Monitor convierte los eventos del monitor de salud, el journal watcher y el webhook de Proxmox VE en mensajes enriquecidos con deduplicación, cooldown, agregación de ráfagas, una reescritura opcional con IA y un historial completo.",
"ogTitle": "Notificaciones de Proxmox — Telegram, Discord, Email, Gotify, Pushover, Apprise",
"ogDescription": "Envía alertas de Proxmox VE a Telegram, Discord, Email, Gotify, Pushover y unos 80 servicios adicionales mediante Apprise.",
"title": "Notificaciones de Proxmox — Telegram, Discord, correo, Gotify, Pushover, Apprise | ProxMenux Monitor",
"description": "Envía notificaciones de Proxmox VE a Telegram, Discord, correo, Gotify, Pushover y unos 80 servicios mediante Apprise. Los eventos del monitor de salud, los registros y el webhook de PVE se convierten en mensajes con deduplicación, intervalos de repetición, agrupación de ráfagas, reescritura opcional con IA e historial.",
"ogTitle": "Notificaciones de Proxmox — Telegram, Discord, correo, Gotify, Pushover, Apprise",
"ogDescription": "Alertas a Telegram, Discord, correo, Gotify, Pushover y unos 80 servicios mediante Apprise, con deduplicación, intervalos de repetición, agrupación de ráfagas e IA opcional.",
"twitterTitle": "Notificaciones de Proxmox | ProxMenux Monitor",
"twitterDescription": "Envía alertas de Proxmox VE a Telegram, Discord, Email, Gotify, Pushover y unos 80 servicios adicionales mediante Apprise."
},
"header": {
"title": "Notifications",
"description": "El motor de distribución que recibe eventos de todos los colectores del Monitor y los entrega a Telegram, Discord, Email, Gotify, Pushover y unos 80 servicios adicionales mediante Apprise, con deduplicación, cooldown, agregación de ráfagas, controles por evento y por canal, reescritura opcional con IA e historial consultable.",
"section": "ProxMenux Monitor"
"title": "Notificaciones",
"description": "Distribuye eventos de los colectores del Monitor a Telegram, Discord, correo, Gotify, Pushover y unos 80 servicios mediante Apprise. Incluye deduplicación, límites de repetición, agrupación de ráfagas, controles por evento y canal, IA opcional e historial consultable.",
"section": "Monitor de ProxMenux"
},
"intro": {
"title": "De dónde vienen los mensajes",
"body": "Las notificaciones no son un escáner aparte. Son el lado de salida de cada colector que ya está corriendo dentro del Monitor — el <link>Monitor de salud</link>, el journal watcher, el task watcher de Proxmox, el hook del webhook de PVE, el polling collector y los eventos in-process emitidos por scripts de ProxMenux. Cada evento corre por la misma pipeline de despacho antes de llegar a un móvil o a un buzón de correo."
"body": "Las notificaciones distribuyen los eventos de los colectores del Monitor: <link>Monitor de salud</link>, vigilancia del registro y de tareas Proxmox, webhook de PVE, consultas periódicas y emisores internos de los scripts. Cada evento pasa por el mismo proceso de envío antes de llegar al móvil o al correo."
},
"howItWorks": {
"heading": "Cómo funciona",
"intro": "Cada notificación sigue el mismo camino por el proceso del Monitor. Los eventos los producen un puñado de colectores independientes, se normalizan en un payload estructurado, pasan por una pipeline de despacho que decide si enviar y en qué forma, opcionalmente se reescriben por un LLM, y finalmente se reparten a los canales que el usuario haya configurado.",
"intro": "Cada notificación sigue el mismo recorrido: los colectores producen eventos estructurados, el proceso de distribución decide si enviarlos y con qué formato, la IA puede reescribirlos y finalmente se entregan a los canales configurados.",
"arrowLabel": "evento",
"caption": "Flujo de alto nivel. Cada intento real de despacho — exitoso, agregado o fallido — se registra en la tabla de historial SQLite para inspección retrospectiva. Los eventos suprimidos por la etapa de cooldown no se loguean.",
"caption": "Esquema general. Cada intento de envío realizado, correcto, agrupado o fallido, se registra en SQLite. Los eventos suprimidos por el intervalo de repetición no se registran.",
"nodes": {
"sourcesLabel": "Fuentes",
"sourcesDetail": "Monitor de salud\nJournal watcher\nTask watcher\nPVE webhook hook\nPolling collector\nEmisores in-process",
"dispatchLabel": "Pipeline de despacho",
"dispatchDetail": "Toggle por evento\nDedup fingerprint\nCooldown\nAgregación de ráfaga",
"sourcesDetail": "Monitor de salud\nVigilancia del registro\nVigilancia de tareas\nWebhook de PVE\nConsultas periódicas\nEmisores internos",
"dispatchLabel": "Proceso de envío",
"dispatchDetail": "Agrupación de ráfagas\nHuella e intervalo de repetición\nLímites por grupo\nControles por canal",
"aiLabel": "Reescritura IA (opc.)",
"aiDetail": "OpenAI / Anthropic\nGemini / Groq\nOpenRouter / Ollama\n(off por defecto)",
"aiDetail": "OpenAI / Anthropic\nGemini / Groq\nOpenRouter / Ollama\n(desactivado por defecto)",
"channelsLabel": "Canales",
"channelsDetail": "Telegram\nDiscord\nEmail (SMTP)\nGotify\nPushover\nApprise (~80 servicios)"
}
},
"enabling": {
"heading": "Activar el panel",
"intro": "En una instalación recién hecha la tarjeta Notifications en la pestaña Settings muestra un badge <em>Disabled</em> y un único botón <em>Enable Notifications</em>. Nada se despacha y ninguna config de PVE se toca hasta que lo pulsas.",
"disabledAlt": "Tarjeta Notifications en una instalación recién hecha mostrando badge Disabled y un único botón Enable Notifications",
"intro": "En una instalación nueva, la tarjeta Notificaciones de Ajustes muestra <em>Desactivado</em> y el botón <em>Activar notificaciones</em>. Hasta pulsarlo no se envía nada ni se modifica la configuración de PVE.",
"disabledAlt": "Tarjeta de notificaciones inicial con estado Desactivado y botón Activar notificaciones",
"disabledCaption": "El primer estado — un clic para activar.",
"stepsIntro": "Pulsar el botón hace tres cosas en secuencia:",
"steps": [
"Cambia el panel a su estado <em>Active</em> y despliega el formulario de canal debajo.",
"Registra un destino webhook de Proxmox VE en <code>/etc/pve/notifications.cfg</code> apuntando a <code>POST http://127.0.0.1:8008/api/notifications/webhook</code>. Desde este momento, todo lo que Proxmox VE emite por sí mismo (HA, replicación, vzdump desde la GUI) fluye a la misma pipeline que los eventos propios del Monitor. Mira <pvelink>Integración del webhook de PVE</pvelink> más abajo para la mecánica completa.",
"Arranca el hilo de fondo de despacho. El hilo hace polling de la cola de eventos y camina cada evento por la pipeline diagramada arriba."
"Activa el estado <em>Activo</em> y muestra el formulario de canales.",
"Registra un destino webhook de Proxmox en <code>/etc/pve/notifications.cfg</code>. Sin HTTPS usa <code>POST http://127.0.0.1:8008/api/notifications/webhook</code>; con HTTPS usa el receptor HTTP local del puerto 8009. Las notificaciones PVE entran en el proceso de envío del Monitor. Consulta <pvelink>Integración del webhook de PVE</pvelink>.",
"Inicia el hilo de envío en segundo plano, que consulta la cola y procesa cada evento según el esquema anterior."
],
"activeAlt": "Tarjeta de notificaciones activada con pestañas de canales, nombre visible y opciones avanzadas de IA",
"activeCaption": "Estado activo: pestañas de canales en la parte superior (Telegram / Gotify / Discord / correo electrónico / Pushover / Apprise), campo Nombre para mostrar, lista de categorías de cada canal y sección desplegable <em>Avanzado: mejora con IA</em>."
},
"sources": {
"heading": "Fuentes de eventos",
"intro": "Seis colectores independientes alimentan el motor de notificaciones. Corren como hilos de fondo dentro del proceso del Monitor y emiten un <code>NotificationEvent</code> estructurado cada vez que algo pasa.",
"intro": "Seis tipos de fuentes alimentan el motor: colectores en segundo plano, receptor webhook y emisores internos. Producen objetos <code>NotificationEvent</code> estructurados.",
"headerCollector": "Colector",
"headerWatches": "Vigila",
"headerEvents": "Eventos típicos",
@@ -59,51 +59,51 @@
"events": "<code>new_error</code>, <code>error_resolved</code>, <code>error_escalated</code>, <code>health_degraded</code>, <code>health_persistent</code>."
},
{
"collector": "Journal watcher",
"watches": "<code>journalctl --follow</code> con pattern matching para fallos de autenticación SSH / web, bans de Fail2Ban (cuando el jail opcional está instalado), errores I/O del kernel, OOM, eventos de smartd.",
"collector": "Monitor del registro del sistema",
"watches": "<code>journalctl --follow</code> con patrones para fallos de acceso SSH/web, bloqueos Fail2Ban cuando está instalado el jail, errores de E/S del núcleo, OOM y eventos smartd.",
"events": "<code>auth_fail</code>, <code>ip_block</code>, <code>oom_kill</code>, <code>disk_io_error</code>, <code>service_fail</code>."
},
{
"collector": "Task watcher",
"watches": "Hace polling de <code>/var/log/pve/tasks/index</code> para nuevos UPIDs de tareas y sigue sus logs por archivo.",
"collector": "Monitor de tareas",
"watches": "Consulta <code>/var/log/pve/tasks/index</code> para detectar nuevos UPID y sigue sus archivos de registro.",
"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": "Hook de webhook Proxmox",
"watches": "Escucha en <code>POST /api/notifications/webhook</code>. Proxmox VE 8.1+ empuja sus propias notificaciones aquí una vez configurada la integración (mira <pvelink>abajo</pvelink>).",
"collector": "Receptor webhook de Proxmox",
"watches": "Recibe <code>POST /api/notifications/webhook</code>. Las versiones de PVE con destinos webhook pueden reenviar sus avisos tras configurarlo; consulta <pvelink>más abajo</pvelink>.",
"events": "Cualquier cosa que PVE emita — incluyendo eventos que el Monitor de otro modo perdería (HA, replicación, vzdump desde la GUI)."
},
{
"collector": "Polling collector",
"collector": "Colector de consultas periódicas",
"watches": "Comparaciones periódicas (nodos del cluster online, caducidad de certificado, estado de passthrough de GPU, disponibilidad de actualización 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": "Emisores in-process",
"collector": "Emisores internos",
"watches": "Llamadas directas desde scripts de ProxMenux y desde el propio 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>, eventos de prueba personalizados."
}
],
"after1": "Cada evento lleva un <code>event_type</code> estable (el catálogo está abajo), una <code>severity</code> (<code>INFO</code>, <code>WARNING</code>, <code>CRITICAL</code>), una <code>category</code> (usada para enriquecimiento de emoji y filtros por grupo) y un payload <code>data</code> con lo que la template necesite (<code>vmid</code>, <code>device</code>, <code>source_ip</code>, <code>reason</code>…).",
"after2": "Cada <code>event_type</code> tiene una template coincidente en <code>notification_templates.py</code> que renderiza el evento estructurado en un cuerpo de texto plano antes de que cualquier otra cosa pase. Ese cuerpo templated es lo que viaja por la pipeline de despacho, y lo que la capa opcional de IA reescribe si está activada. Mira la <ailink>página del Asistente de IA</ailink> para cómo la capa de reescritura interactúa con este cuerpo templated."
"after1": "Cada evento incluye un <code>event_type</code> estable, una <code>severity</code> (<code>INFO</code>, <code>WARNING</code>, <code>CRITICAL</code>), una <code>category</code> para emojis y filtros, y los valores <code>data</code> que necesita la plantilla (<code>vmid</code>, <code>device</code>, <code>source_ip</code>, <code>reason</code>…).",
"after2": "Cada <code>event_type</code> tiene una plantilla en <code>notification_templates.py</code> que convierte el evento en texto. Ese texto pasa por el proceso de envío y puede ser reescrito por la IA. La <ailink>página del Asistente de IA</ailink> explica esa interacción."
},
"channels": {
"heading": "Walkthroughs de canales",
"heading": "Configuración de los canales",
"intro": "Actualmente se admiten seis canales: Telegram, Discord, Gotify, Email (SMTP), Pushover y Apprise. Los cinco primeros son integraciones nativas con sus propios campos de configuración. Apprise funciona como un concentrador genérico que añade unos 80 servicios adicionales (ntfy, Matrix, Slack, Teams, Pushbullet, AWS SNS, Mattermost…) mediante una única URL. Todos están documentados paso a paso a continuación.",
"credsTitle": "Dónde viven las credenciales",
"credsBody": "Los tokens, las claves, las URL de webhook y las contraseñas SMTP se guardan localmente en la base de datos SQLite del Monitor dentro de <code>/usr/local/share/proxmenux/</code>. Los valores sensibles están protegidos y se ocultan en la interfaz. Solo salen del host para comunicarse con el servicio correspondiente. Una copia de ese directorio permite recuperar los canales configurados."
"credsTitle": "Dónde se guardan las credenciales",
"credsBody": "Los tokens, las claves, las URL de webhook y las contraseñas SMTP se guardan localmente en la base de datos SQLite del Monitor dentro de <code>/usr/local/share/proxmenux/</code>. Los valores sensibles están protegidos y se ocultan en la interfaz. Solo salen del host para comunicarse con el servicio correspondiente. Un backup de ese directorio permite recuperar los canales configurados."
},
"telegram": {
"heading": "Telegram",
"intro": "Se requieren dos piezas de información: un <strong>Bot Token</strong> (uno por bot, reutilizable entre chats) y un <strong>Chat ID</strong> (donde el bot debe publicar — tu chat privado, un grupo o un tema dentro de un supergrupo). La guía in-app de abajo contiene el paso a paso completo; el resto de esta sección lo repite como texto más las dos formas que puede tomar el Chat ID.",
"guideAlt": "Modal Telegram Bot Setup Guide con cuatro secciones numeradas: Crear un Bot con BotFather, Obtener el Bot Token, Obtener tu Chat ID y Para Grupos o Canales",
"guideCaption": "El enlace <em>+ setup guide</em> dentro de la pestaña Telegram abre este modal — los cuatro pasos numerados van de sin bot a un canal funcionando en unos dos minutos.",
"intro": "Necesitas un <strong>Token del bot</strong>, reutilizable entre chats, y un <strong>ID del chat</strong> de destino: privado, grupo o tema de un supergrupo. La guía integrada muestra el procedimiento; aquí se explica también el formato de cada ID.",
"guideAlt": "Guía de configuración de Telegram con cuatro secciones: crear bot con BotFather, obtener token, obtener ID del chat y configurar grupos o canales",
"guideCaption": "El enlace <em>+ guía de configuración</em> de Telegram abre estos cuatro pasos para crear el bot y configurar el canal en unos dos minutos.",
"step1Title": "1 · Crea un bot con BotFather",
"step1Items": [
"Abre Telegram y empieza un chat con <a>@BotFather</a> (el que tiene el tick azul de verificación — las copias son comunes).",
"Envía <code>/newbot</code>.",
"Elige un nombre visible (p. ej. <em>ProxMenux Lab</em>). Se puede cambiar después.",
"Elige un username terminado en <code>bot</code> (p. ej. <em>proxmenux_lab_bot</em>). Debe ser único en Telegram.",
"Elige un nombre de usuario terminado en <code>bot</code>, como <em>proxmenux_lab_bot</em>. Debe ser único en Telegram.",
"BotFather responde con un token de la forma <code>123456789:ABCdef…</code> — ese es el Bot Token. Trátalo como una contraseña."
],
"step2Title": "2 · Obtén el Chat ID",
@@ -120,61 +120,61 @@
"Añade el bot al grupo como miembro (y hazlo admin si el grupo lo requiere para publicar).",
"Envía cualquier mensaje en el grupo.",
"Abre <code>https://api.telegram.org/bot&lt;YOUR_TOKEN&gt;/getUpdates</code> en un navegador. Busca <code>chat.id</code> en la respuesta JSON — para grupos es un número negativo, para supergrupos empieza con <code>-100</code>.",
"Para supergrupos con <em>Topics</em> activado, anota también el <code>message_thread_id</code> del tema al que quieres apuntar — eso va en el campo opcional <em>Topic ID</em>."
"En supergrupos con <em>Temas</em>, anota el <code>message_thread_id</code> de destino e introdúcelo en el campo opcional <em>ID de tema</em>."
],
"groupAlt": "Formulario de canal Telegram con Bot Token (enmascarado), Chat ID negativo prefijado con -100 indicando un supergrupo, y Topic ID 3 configurado para entregar a un tema específico",
"groupCaption": "Supergrupo — el Chat ID empieza con <code>-100…</code> y el <em>Topic ID</em> opcional apunta a un hilo específico.",
"step3Title": "3 · Guarda y prueba",
"step3Body": "Pega el Bot Token y el Chat ID en la pestaña Telegram, guarda y pulsa <em>Send Test</em> al final del panel. Un mensaje de prueba debería llegar en un segundo; si no llega, la sección History registra el fallo con el motivo exacto (token inválido, bot no en el grupo, bloqueado por el usuario, etc.)."
"step3Body": "Pega el token del bot y el ID del chat en Telegram, guarda y pulsa <em>Enviar prueba</em>. El mensaje debería llegar en un segundo; si no, el Historial muestra el motivo del fallo, como token inválido, bot fuera del grupo o bloqueo por el usuario."
},
"discord": {
"heading": "Discord",
"intro": "Los canales de Discord aceptan mensajes entrantes a través de una <em>Webhook URL</em> ligada a un único canal. El Monitor necesita esa URL y nada más.",
"intro": "Discord recibe mensajes mediante una <em>URL de webhook</em> asociada a un canal. Monitor necesita esa URL.",
"items": [
"En Discord, abre el servidor donde quieres que aterricen las notificaciones y ve a <em>Server Settings → Integrations → Webhooks</em>.",
"Pulsa <em>New Webhook</em>. Dale un nombre (p. ej. <em>ProxMenux</em>) y elige el canal donde debe publicar. Un avatar es opcional.",
"Pulsa <em>Copy Webhook URL</em> — tiene aspecto de <code>https://discord.com/api/webhooks/&lt;id&gt;/&lt;token&gt;</code>.",
"Abre el servidor Discord y ve a <em>Ajustes del servidor → Integraciones → Webhooks</em>.",
"Pulsa <em>Nuevo webhook</em>, ponle un nombre como <em>ProxMenux</em> y elige el canal de destino. El avatar es opcional.",
"Pulsa <em>Copiar URL del webhook</em>. Su formato es <code>https://discord.com/api/webhooks/&lt;id&gt;/&lt;token&gt;</code>.",
"Pégalo en el campo Webhook URL de la pestaña Discord en el panel Notifications y guarda."
],
"imageAlt": "Formulario de canal Discord con campo Webhook URL empezando por https://discord.com/api/webhooks/",
"imageCaption": "Discord — pega la Webhook URL de <em>Server Settings → Integrations → Webhooks</em>."
"imageCaption": "Discord: pega la URL obtenida en <em>Ajustes del servidor → Integraciones → Webhooks</em>."
},
"gotify": {
"heading": "Gotify",
"intro": "Gotify es un servidor push autoalojado. Necesitas su URL base y un <em>Application Token</em> generado desde la UI de admin de Gotify.",
"intro": "Gotify es un servidor de notificaciones que puedes alojar. Necesitas su URL base y un <em>Token de aplicación</em> generado en su interfaz de administración.",
"items": [
"Si aún no tienes una instancia de Gotify, instala una — mira la <a>guía oficial de instalación</a>.",
"Abre la UI web de Gotify, loguéate como admin, ve a <em>Apps</em> → <em>Create Application</em>. Dale un nombre (p. ej. <em>ProxMenux</em>). Gotify genera un token — cópialo.",
"En la pestaña Gotify del panel Notifications, configura <em>Server URL</em> a la URL base de tu instancia (p. ej. <code>https://gotify.example.com</code>) y pega el App Token.",
"Guarda y pulsa <em>Send Test</em>."
"Entra como administrador en Gotify y abre <em>Aplicaciones</em> → <em>Crear aplicación</em>. Ponle un nombre como <em>ProxMenux</em> y copia el token generado.",
"En Gotify, establece <em>URL del servidor</em> en la URL base, por ejemplo <code>https://gotify.example.com</code>, y pega el token.",
"Guarda y pulsa <em>Enviar prueba</em>."
],
"imageAlt": "Formulario de canal Gotify con campo Server URL configurado a https://gotify.example.com y un campo App Token con placeholder A_valid_gotify_token",
"imageCaption": "Gotify — URL del servidor de tu instancia autoalojada más el App Token de la UI de admin de Gotify."
},
"email": {
"heading": "Email (SMTP)",
"heading": "Correo electrónico (SMTP)",
"intro": "Email es el canal más flexible — y el que tiene más campos. Necesitas un servidor SMTP, un puerto, un modo TLS, opcionalmente un usuario y contraseña, una dirección de remitente y al menos un destinatario.",
"imageAlt": "Formulario de canal Email con SMTP Host, Port, dropdown TLS Mode, Username, Password, From Address, To Addresses separadas por coma y campos Subject Prefix",
"imageCaption": "Email — host / puerto / modo TLS de SMTP, usuario + contraseña opcionales, dirección de remitente, destinatarios separados por coma y un prefijo de asunto para hacer las alertas fáciles de filtrar en el lado del inbox.",
"appNote": "Si usas una cuenta personal de Gmail o Microsoft 365, el campo password no puede ser tu contraseña normal de cuenta — ambos proveedores requieren una <strong>app password</strong> generada específicamente para clientes de terceros. Los dos flujos están abajo.",
"gmailTitle": "App password de Gmail",
"imageAlt": "Formulario SMTP con servidor, puerto, modo TLS, usuario, contraseña, remitente, destinatarios separados por comas y prefijo del asunto",
"imageCaption": "Correo: servidor, puerto y TLS de SMTP; usuario y contraseña opcionales; remitente, destinatarios separados por comas y prefijo de asunto para filtrar avisos.",
"appNote": "Monitor usa autenticación SMTP con contraseña. Gmail puede requerir una <strong>contraseña de aplicación</strong>. En Microsoft depende del servicio y de las políticas del tenant: una contraseña de aplicación no permite saltarse el bloqueo de autenticación básica. Comprueba que el servicio admita este método.",
"gmailTitle": "Contraseña de aplicación de Gmail",
"gmailIntro": "Las app passwords de Gmail requieren que la <strong>verificación en 2 pasos</strong> esté activa en la cuenta de Google. Si no lo está, la página <em>App passwords</em> no existirá.",
"gmailItems": [
"Abre <a>myaccount.google.com/security</a> y activa <em>Verificación en 2 pasos</em> si no está activada.",
"Ve a <a>myaccount.google.com/apppasswords</a>.",
"Escribe un nombre (p. ej. <em>ProxMenux</em>) y pulsa <em>Create</em>. Google muestra una contraseña de 16 caracteres — cópiala.",
"Rellena la pestaña Email con: <em>Host</em> <code>smtp.gmail.com</code>, <em>Port</em> <code>587</code>, <em>TLS Mode</em> <code>STARTTLS</code>, <em>Username</em> tu dirección de Gmail, <em>Password</em> la app password de 16 caracteres."
"Escribe un nombre como <em>ProxMenux</em> y pulsa <em>Crear</em>. Copia la contraseña de 16 caracteres.",
"Configura: <em>Servidor</em> <code>smtp.gmail.com</code>, <em>Puerto</em> <code>587</code>, <em>Modo TLS</em> <code>STARTTLS</code>, <em>Usuario</em> tu dirección Gmail y <em>Contraseña</em> la de aplicación de 16 caracteres."
],
"outlookTitle": "App password de Microsoft / Outlook",
"outlookIntro": "Microsoft ahora requiere <strong>verificación en dos pasos</strong> en la cuenta personal antes de que se pueda crear una app password. Los tenants empresariales donde el admin ha deshabilitado SMTP basic auth necesitan un camino distinto (OAuth2) que el Monitor no soporta actualmente — apunta esos a un relay SMTP que controles en su lugar.",
"outlookTitle": "Contraseña de aplicación de Microsoft / Outlook",
"outlookIntro": "Las contraseñas de aplicación de Microsoft exigen <strong>verificación en dos pasos</strong>, pero disponer de una no garantiza compatibilidad SMTP. Si el servicio o tenant exige OAuth2, el cliente SMTP de Monitor no puede autenticarse. Usa un relay que admita la autenticación del proveedor.",
"outlookItems": [
"Abre <a>account.microsoft.com/security</a> y activa la verificación en dos pasos.",
"Abre <em>Advanced security options</em>, baja a <em>App passwords</em> y pulsa <em>Create a new app password</em>.",
"Microsoft muestra una contraseña aleatoria larga — cópiala.",
"Rellena la pestaña Email con: <em>Host</em> <code>smtp-mail.outlook.com</code>, <em>Port</em> <code>587</code>, <em>TLS Mode</em> <code>STARTTLS</code>, <em>Username</em> tu dirección de Outlook / Microsoft 365, <em>Password</em> la app password generada."
"Si tu cuenta ofrece <em>Opciones avanzadas de seguridad</em> → <em>Contraseñas de aplicación</em>, elige <em>Crear una contraseña de aplicación</em>. Eso no garantiza que el correo admita autenticación SMTP con contraseña.",
"Si Microsoft genera la contraseña, cópiala y comprueba que tu servicio SMTP la acepte.",
"Solo si el proveedor admite SMTP con contraseña, usa sus ajustes autorizados: <em>servidor SMTP</em> <code>smtp.office365.com</code> para Exchange Online, <em>Puerto</em> <code>587</code>, <em>modo TLS</em> <code>STARTTLS</code>, <em>Nombre de usuario</em> tu dirección y <em>Contraseña</em> la credencial permitida. Outlook.com personal usa requisitos y ajustes distintos; no presupongas que estas credenciales funcionen."
],
"relayTitle": "Relay SMTP autoalojado",
"relayBody": "Si corres tu propio relay SMTP (Postfix, msmtp, etc.) en la LAN, apunta el Monitor a él y saltea el baile de app-password por completo. El relay maneja la auth upstream y el Monitor envía en cleartext sobre una red de confianza."
"relayBody": "Usa un relay SMTP que controles, como Postfix. El relay gestiona la autenticación hacia el proveedor. Configura la autenticación y TLS de Monitor según lo que exija el relay; que sea local no desactiva el cifrado."
},
"pushover": {
"heading": "Pushover",
@@ -182,8 +182,8 @@
"stepsTitle": "Configuración",
"steps": [
"Crea una <a>cuenta de Pushover</a>, instala la aplicación oficial en los dispositivos que recibirán las alertas e inicia sesión.",
"Copia la <em>User Key</em> que aparece en el panel de Pushover. También puedes usar una clave de grupo si varias personas o dispositivos deben recibir la misma alerta.",
"Abre <a>Create an Application/API Token</a>, crea una aplicación llamada <em>ProxMenux</em> y copia su token API de 30 caracteres.",
"Copia la <em>Clave de usuario</em> del panel Pushover. Puedes usar una clave de grupo si varias personas o dispositivos deben recibir la alerta.",
"Abre <a>Crear aplicación/token API</a>, crea una aplicación llamada <em>ProxMenux</em> y copia su token API de 30 caracteres.",
"En <em>Ajustes → Notificaciones → Pushover</em>, pega la clave de usuario o grupo y el token API de la aplicación. Los campos de dispositivo y sonido son opcionales.",
"Guarda los ajustes y pulsa <em>Enviar prueba</em>. La aplicación Pushover debería recibir el mensaje inmediatamente."
],
@@ -198,160 +198,160 @@
"listIntro": "La lista completa de servicios compatibles y el formato exacto de cada URL están disponibles en la documentación oficial de Apprise:",
"listItems": [
"<a>Documentación de servicios de Apprise</a> — índice completo de servicios compatibles.",
"<a>URL basics</a> — cómo se estructuran las URLs de Apprise."
"<a>Conceptos básicos de las URL</a>: estructura de las URL de Apprise."
],
"stepsTitle": "Pasos",
"steps": [
"Elige el servicio destino en la <a>wiki de Apprise</a> y copia la plantilla de URL para él. Cada página de servicio muestra el esquema exacto a usar (<code>ntfy://</code>, <code>matrix://</code>, <code>pover://</code>, <code>slack://</code>…) más cualquier token, canal u hostname requerido.",
"Sustituye los marcadores por tus credenciales. Ejemplos: ntfy.sh <code>ntfy://ntfy.sh/my-topic</code>; Pushover <code>pover://user@token</code>; Matrix <code>matrix://user:pass@host:port/#room</code>.",
"Pega la URL final en el campo <em>Apprise URL</em> en la pestaña Apprise del panel Notifications y guarda.",
"Pulsa <em>Send Test</em> para verificar que la URL es alcanzable y las credenciales se aceptan."
"Pulsa <em>Enviar prueba</em> para comprobar el acceso y las credenciales."
],
"deliveredTitle": "Qué se entrega",
"deliveredBody": "Apprise recibe el mismo payload que los otros canales — título, cuerpo y una severidad (info / success / warning / failure). La severidad se mapea a lo que el servicio destino exponga (icono, prioridad, color). El formato de mensajes ricos y la capa de reescritura con IA corren todos antes de que se invoque la URL, exactamente como para Telegram o Email.",
"fanoutTitle": "Una URL por canal Apprise",
"fanoutBody": "El Monitor expone un único slot de URL por canal Apprise. Si necesitas hacer fan-out a varios servicios Apprise a la vez (p. ej. ntfy.sh más una sala de Matrix), el enfoque más limpio es alojar un pequeño <a>servidor Apprise API</a> con una config etiquetada y apuntar el Monitor a su endpoint — el servidor luego difunde a cada URL detrás de esa etiqueta."
"fanoutBody": "Monitor ofrece una URL por canal Apprise. Para enviar a varios servicios, como ntfy.sh y Matrix, aloja un <a>servidor Apprise API</a> con una configuración etiquetada. Monitor llama a ese destino y el servidor distribuye a las URL de la etiqueta."
},
"rich": {
"heading": "Mensajes ricos, categorías y filtrado por canal",
"intro": "Bajo el formulario del canal cada canal expone los mismos tres controles: un toggle <em>Rich messages</em> arriba (destacado con la flecha en la captura), once <em>Notification Categories</em> colapsables con toggles por evento y un botón <em>Send Test</em> abajo.",
"imageAlt": "Panel Notification Categories con toggle maestro Rich messages destacado arriba, secciones colapsables para VM/CT, Backups, Resources, Storage, Network, Security, Cluster, Services, Health Monitor, Updates cada una con toggle y contador de eventos, y un botón Send Test",
"imageCaption": "Flecha de arriba — el toggle <em>Rich messages</em> por canal. Abajo — las once categorías colapsables con toggles por evento. <em>Send Test</em> está al final del canal.",
"richTitle": "Mensajes ricos",
"richIntro": "Con <em>Rich messages</em> activado, la cabecera de cada evento se prefija con un emoji de categoría y el cuerpo se renderiza usando el formato nativo del canal (HTML de Telegram, embed de Discord con color de severidad). Con él desactivado, el Monitor envía una versión de texto plano con la misma información menos las pistas visuales. Mismo contenido, distinta presentación:",
"plainHeader": "Plano — Rich messages off",
"richHeader": "Rico — Rich messages on",
"richOutro": "El toggle es por canal: deja Email plano para legibilidad de reglas de inbox dejando que Telegram y Discord rendericen la versión rica. Los canales que no soportan formato inline (email texto plano, Gotify) ignoran el formato y caen a texto de todas formas.",
"heading": "Mensajes enriquecidos, categorías y filtros por canal",
"intro": "Cada canal tiene tres controles: <em>Mensajes enriquecidos</em> arriba, once secciones de <em>Categorías de notificación</em> con interruptores por evento y <em>Enviar prueba</em> abajo.",
"imageAlt": "Categorías con Mensajes enriquecidos destacado, secciones de VM/CT, backups, recursos, almacenamiento, red, seguridad, clúster, servicios, salud y actualizaciones, con interruptores y contadores, y botón Enviar prueba",
"imageCaption": "La flecha señala <em>Mensajes enriquecidos</em>. Debajo están las once categorías desplegables con controles por evento. <em>Enviar prueba</em> está al final.",
"richTitle": "Mensajes enriquecidos",
"richIntro": "Con <em>Mensajes enriquecidos</em>, cada aviso lleva un emoji de categoría y formato nativo del canal, como HTML en Telegram o tarjetas coloreadas en Discord. Desactivado, se envía el mismo contenido en texto simple:",
"plainHeader": "Texto simple: formato enriquecido desactivado",
"richHeader": "Texto enriquecido: formato activado",
"richOutro": "El control es independiente por canal. Puedes dejar el correo en texto simple y usar formato en Telegram y Discord. Los canales sin ese formato, como correo de texto o Gotify, reciben texto.",
"togglesTitle": "Categorías por evento",
"togglesIntro": "Unos setenta tipos de evento están agrupados en once categorías de UI. Cada evento tiene un toggle maestro y un override por canal — dos capas que deciden si un evento dado llega a un canal dado:",
"togglesIntro": "Cada canal controla sus categorías y tipos de evento de forma independiente. Desactivar una categoría suprime sus eventos en ese canal. Los controles individuales se aplican dentro de las categorías activas; el distribuidor no tiene un control maestro global por evento.",
"togglesItems": [
"<strong>Toggle maestro por evento.</strong> Si <code>vm_start</code> está off en todas partes, ningún canal ve nunca un <code>vm_start</code>. Los toggles persisten como <code>event_toggles[event_type] = true | false</code>.",
"<strong>Overrides por canal.</strong> Un tipo de evento también se puede silenciar para un canal específico (<em>\"enviar <code>backup_complete</code> a Discord pero no a Telegram\"</em>). Estos viven en <code>channel_overrides[channel_name][event_type]</code> y solo aplican si el evento pasó el toggle maestro."
"<strong>Control de categoría por canal.</strong> Por ejemplo, desactivar VM/CT suprime <code>vm_start</code> y sus equivalentes para ese canal. Se guarda como <code>&lt;channel&gt;.events.&lt;group&gt;</code>.",
"<strong>Control de evento por canal.</strong> En una categoría activa puedes elegir <em>enviar <code>backup_complete</code> a Discord pero no a Telegram</em>. Se guarda como <code>&lt;channel&gt;.event.&lt;event_type&gt;</code>."
],
"togglesOutro": "Cada cabecera de categoría en la captura también muestra el conteo de eventos <em>actualmente activados</em> / <em>total</em> para ese grupo, y un toggle a nivel de categoría que pone cada evento dentro a on o off en un clic — el atajo para silenciar un grupo entero (p. ej. todos los backups <code>info</code>, todos los eventos relacionados con actualizaciones) sin expandir la sección."
"togglesOutro": "Cada categoría indica los eventos <em>activados</em> frente al <em>total</em> y permite activar o desactivar el grupo completo con un clic, por ejemplo backups <code>info</code> o avisos de actualización, sin abrirlo."
},
"quiet": {
"heading": "Quiet Hours",
"intro": "Quiet Hours es una ventana temporal por canal durante la cual el dispatcher solo deja pasar eventos <strong>CRITICAL</strong>. Todo lo demás — INFO, WARNING, eventos de acción — se retiene, se persiste a disco y se entrega como un único resumen agrupado en el momento en que la ventana cierra. El canal sigue recibiendo las cosas urgentes en tiempo real; el ruido espera hasta que probablemente lo quieras.",
"imageAlt": "Ajustes de canal mostrando ambos knobs lado a lado: tarjeta Quiet Hours con toggle activado, Start 22:00 y End 07:00 más una preview en vivo de la siguiente transición, y justo debajo la tarjeta Daily digest con su propio toggle, un selector de hora de entrega configurado a 09:00 y la nota de que CRITICAL y WARNING nunca se retrasan",
"imageCaption": "Ambos knobs viven lado a lado dentro de la tarjeta de ajustes de cada canal — Quiet Hours arriba, Daily digest debajo. Independientes por canal.",
"heading": "Horas de silencio",
"intro": "Durante las horas de silencio de cada canal solo pasan los eventos <strong>CRITICAL</strong>. INFO, WARNING y las acciones se guardan en disco y se entregan en un resumen al terminar el intervalo.",
"imageAlt": "Ajustes de canal con Horas de silencio de 22:00 a 07:00 y vista del próximo cambio; debajo, Resumen diario a 09:00 con aviso de que este resumen no retrasa CRITICAL ni WARNING",
"imageCaption": "Cada canal tiene ambos ajustes independientes: Horas de silencio arriba y Resumen diario debajo.",
"purposeTitle": "Para qué sirve",
"purposeItems": [
"<strong>No me despiertes a las 03:00 por un aviso de actualización.</strong> Backups, actualizaciones de apps, optimizaciones post-instalación y otros eventos de nivel INFO dejan de avisar a tu móvil por la noche.",
"<strong>Pero aun así despiértame por un fuego.</strong> Fallos de disco, OOM kills, shutdowns del host, bans de fail2ban — cualquier cosa clasificada como CRITICAL — saltea la ventana y llega inmediatamente.",
"<strong>Tampoco pierdas nada.</strong> Los eventos suprimidos durante la ventana no se descartan silenciosamente — se sientan en un buffer SQLite hasta que vuelves al reloj."
"<strong>Los eventos críticos siguen llegando.</strong> Solo los clasificados como CRITICAL evitan el silencio. El nombre no determina la severidad: el monitor del registro emite los bloqueos Fail2Ban y los avisos de apagado/reinicio del host como INFO, por lo que pueden retenerse.",
"<strong>Conserva los avisos aplazados.</strong> Los eventos retenidos se guardan en un búfer SQLite hasta que termine el intervalo."
],
"howTitle": "Cómo funciona",
"howItems": [
"<strong>Toggle por canal.</strong> Cada canal tiene su propia configuración de Quiet Hours — Telegram puede estar silencioso 22:00-07:00 mientras email sigue recibiendo todo 24/7.",
"<strong>Control por canal.</strong> Por ejemplo, Telegram puede guardar silencio de 22:00 a 07:00 mientras el correo recibe avisos todo el día.",
"<strong>Hora de inicio y fin</strong> en tu zona horaria local, intervalo semi-abierto (inicio inclusivo, fin exclusivo). La ventana puede cruzar medianoche (p. ej. 22:00-07:00 significa esta noche hasta mañana por la mañana).",
"<strong>Línea de preview en vivo</strong> justo debajo de los inputs muestra si la ventana está actualmente activa y cuándo ocurre la siguiente transición. Ahorra abrir un reloj.",
"<strong>Durante la ventana:</strong> los eventos CRITICAL siguen disparando por la pipeline de despacho normal. Los eventos INFO y WARNING se enrutan a un buffer persistente (tabla <code>quiet_pending</code> en la DB SQLite del Monitor).",
"<strong>Cuando la ventana cierra:</strong> se envía una única notificación agrupada con todo lo que se acumuló — una línea por evento bufferizado, en orden cronológico. El buffer se limpia solo después de que el canal confirme la entrega, para que un fallo transitorio de Telegram / SMTP no pierda el contexto de la noche.",
"<strong>A través de reinicios.</strong> Si el Monitor reinicia a mitad de ventana, el buffer está intacto en disco. Si el reinicio ocurre justo después de que la ventana cierre, el siguiente ciclo de despacho detecta las filas pendientes y las descarga con un único resumen \"recovery\" — no se pierden notificaciones por un deploy o un reboot."
"<strong>Vista previa en directo.</strong> Bajo los campos se indica si el intervalo está activo y cuándo cambiará.",
"<strong>Durante el intervalo:</strong> CRITICAL sigue por el proceso de envío; INFO y WARNING se guardan en la tabla SQLite <code>quiet_pending</code>.",
"<strong>Al terminar:</strong> se envía un resumen cronológico con una línea por evento guardado. El búfer se borra tras confirmar la entrega, para resistir fallos transitorios de Telegram o SMTP.",
"<strong>Resiste reinicios.</strong> El búfer permanece en disco. Tras reiniciar, el siguiente ciclo detecta las filas pendientes y envía un resumen de recuperación cuando corresponde."
],
"criticalTitle": "Qué cuenta como CRITICAL",
"criticalBody": "La severidad se fija en la creación del evento, no en el momento del despacho. Los fallos de disco, OOM kills, split-brain de cluster, shutdowns del host y el nivel \"duro\" de errores I/O de disco se envían como CRITICAL por diseño. Todo lo demás (backups OK, actualizaciones disponibles, logs INFO, hits de rate-limit) cae por defecto a INFO o WARNING y por tanto es silenciable. Puedes verificar la severidad por defecto de un evento dado en el <link>Catálogo de eventos</link> más abajo en esta página."
"criticalBody": "El productor fija la severidad al crear el evento. Que trate de disco, apagado o seguridad no lo convierte en CRITICAL. El monitor del registro emite ip_block, system_shutdown y system_reboot como INFO. El <link>Catálogo de eventos</link> enumera los tipos; consulta el productor y el evento recibido para conocer su severidad real."
},
"digest": {
"heading": "Resumen diario de eventos INFO",
"intro1": "El Daily Digest es el knob opuesto: un ajuste <strong>opt-in</strong> que dice \"no me envíes cada backup exitoso o aviso de actualización según ocurre — recoléctalos y envíame un resumen al día a las 09:00 (o la hora que elija)\". Mismo objetivo que Quiet Hours (menos ruido) pero un mecanismo distinto (resumen basado en tiempo en vez de una ventana diaria).",
"intro2": "Vive en la misma tarjeta de ajustes de canal que Quiet Hours (mira la figura bajo <link>Quiet Hours</link>), justo debajo. Cada uno se activa independientemente.",
"intro1": "El resumen diario es una opción <strong>que activas expresamente</strong>: agrupa avisos INFO aptos, como actualizaciones disponibles, a las 09:00 o a la hora elegida. Los resultados de backups y replicación y las acciones en directo están excluidos. Las horas de silencio aplazan los avisos no críticos durante un intervalo.",
"intro2": "Está debajo de las horas de silencio en la misma tarjeta; consulta la figura en <link>Horas de silencio</link>. Ambos se activan por separado.",
"purposeTitle": "Para qué sirve",
"purposeItems": [
"<strong>El recap matutino de \"todo lo que pasó\".</strong> Si chequeas el host una vez al día con un café, un digest a las 09:00 lleva la misma información que 20 pings individuales a lo largo del día anterior, sin que leas 20 burbujas de Telegram.",
"<strong>Separa ruido de señal.</strong> Los eventos INFO responden a \"qué pasó\"; CRITICAL y WARNING responden a \"qué necesito hacer ahora mismo\". El digest maneja el primero; todo lo demás mantiene su entrega en vivo."
"<strong>Un repaso matutino de lo ocurrido.</strong> Un resumen a las 09:00 reúne la información de 20 avisos individuales del día anterior y evita leer 20 mensajes de Telegram.",
"<strong>Separa actividad y urgencias.</strong> INFO explica qué pasó; CRITICAL y WARNING indican qué requiere atención. El resumen agrupa los INFO aptos; los demás conservan el envío directo."
],
"howTitle": "Cómo funciona",
"howItems": [
"<strong>Opt-in por canal.</strong> Off por defecto — Telegram no batcheaiza silenciosamente tus alertas. Lo activas en los canales donde quieres un digest, dejando otros en entrega en vivo.",
"<strong>Activación por canal.</strong> Desactivado por defecto. Actívalo solo donde quieras resúmenes y deja los otros canales con avisos directos.",
"<strong>Hora de entrega</strong> en tu zona horaria local. Por defecto 09:00 pero puedes elegir cualquier hora; el dispatcher dispara el digest dentro de ~60 s de ese minuto.",
"<strong>Qué entra en el digest:</strong> cualquier evento que el canal habría recibido en vivo cuya severidad es <strong>INFO</strong>. Ejemplos — <em>vzdump complete</em>, <em>Tailscale update available</em>, <em>ProxMenux optimisation update available</em>, <em>APT security updates pending</em>, <em>rate-limit hit</em>.",
"<strong>Incluye:</strong> eventos generales aptos de nivel <strong>INFO</strong>, como <em>actualización de aplicación disponible</em>, <em>actualización de Tailscale disponible</em>, <em>actualización de optimización de ProxMenux disponible</em> y <em>actualizaciones de seguridad APT pendientes</em>. Los resultados de backups y otras acciones excluidas siguen en directo.",
"<strong>Qué nunca se retrasa:</strong>",
"<strong>Persistencia.</strong> Los eventos pendientes se sientan en una tabla SQLite (<code>digest_pending</code>) hasta la hora configurada. El Monitor puede reiniciar libremente sin perder lo que el digest eventualmente contendrá.",
"<strong>Los días vacíos son silenciosos.</strong> Si nada de nivel INFO pasó, no se envía digest — el canal se mantiene quieto en vez de recibir un mensaje \"no hay eventos para reportar\"."
"<strong>Persistencia.</strong> Los pendientes se guardan en SQLite, tabla <code>digest_pending</code>, hasta la hora elegida y sobreviven a reinicios.",
"<strong>Sin eventos, sin resumen.</strong> Si no hay avisos INFO pendientes, no se envía ningún resumen vacío."
],
"neverDelayedSub": [
"Los eventos <strong>CRITICAL</strong> siempre pasan inmediatamente.",
"Los eventos <strong>WARNING</strong> siempre pasan inmediatamente.",
"Eventos de acción en vivo (VM/CT start / stop / shutdown / restart, vm_fail / ct_fail, backup start / fail, replication start / fail, host shutdown / reboot) saltean el digest incluso con severidad INFO — has hecho opt-in a verlos en vivo, el digest derrotaría ese opt-in."
"Las acciones de VM/CT, sus fallos, inicio y resultados de backups, resultados de replicación y apagado o reinicio del host evitan el resumen incluso con nivel INFO. Las horas de silencio sí pueden retrasarlas si no son críticas."
],
"comboTitle": "Combinar Quiet Hours y Daily Digest",
"comboBody": "Los dos funcionan juntos. Un canal puede tener <em>ambos</em> activos — Quiet Hours de 22:00 a 07:00 más un Daily Digest a las 09:00. Los eventos INFO durante la ventana quiet van al buffer quiet y llegan a las 07:00 como el resumen de cierre de ventana; los eventos INFO durante el día van al buffer digest y llegan a las 09:00 a la mañana siguiente. CRITICAL y WARNING siempre atraviesan ambos. Elige Quiet Hours cuando el objetivo es una <em>ventana de silencio</em>, el Daily Digest cuando el objetivo es un <em>resumen a hora fija</em>; muchos setups quieren ambos."
"comboTitle": "Combinar horas de silencio y resumen diario",
"comboBody": "Puedes activar <em>ambos</em>: silencio de 22:00 a 07:00 y resumen a 09:00. Los avisos no críticos del intervalo se liberan en el resumen de 07:00; los INFO aptos de fuera van al resumen diario. CRITICAL evita ambos; WARNING evita el diario, pero espera durante el silencio. Elige un <em>intervalo sin avisos</em>, un <em>resumen a hora fija</em> o ambos."
},
"displayName": {
"heading": "Display Name",
"intro": "Cada notificación lleva un <em>Display Name</em> — la etiqueta que identifica qué host produjo la alerta. Es el valor que ves al final del ejemplo de mensajes ricos arriba (<code>🏠 home-lab</code>) y dentro del prefijo de asunto del email.",
"imageAlt": "Campo Display Name con el valor amd mostrado como ejemplo, etiqueta Name shown in notifications - edit to customize or leave empty to use the system hostname",
"imageCaption": "El campo Display Name — déjalo vacío para usar el hostname del sistema, o sobreescríbelo con lo que quieras.",
"heading": "Nombre visible",
"intro": "Cada aviso lleva un <em>Nombre visible</em> para identificar el host, como <code>🏠 home-lab</code> al pie del ejemplo y en el prefijo del asunto del correo.",
"imageAlt": "Campo Nombre visible con amd como ejemplo; permite un nombre propio o usar el del sistema si queda vacío",
"imageCaption": "Nombre visible: déjalo vacío para usar el nombre del host o escribe uno propio.",
"outro": "Si el campo está vacío, el Monitor cae al hostname del sistema. El override es sobre todo útil cuando corres varios hosts ProxMenux que envían al mismo chat de Telegram o buzón — una etiqueta más amigable (<em>home-lab</em>, <em>office-pve</em>) es más fácil de leer que <code>pve01.lan</code> o <code>pmx-prod-01</code>."
},
"dispatch": {
"heading": "Pipeline de despacho",
"intro": "Entre que un evento se levanta y un mensaje sale del host, corren tres etapas en este orden:",
"heading": "Proceso de envío",
"intro": "La tabla describe tres mecanismos relacionados. El proceso real empieza con la agrupación de ráfagas, sigue con reserva de entrega, intervalos de repetición y límites por grupo, y termina con formato y controles de cada canal:",
"headerStage": "Etapa",
"headerWhat": "Qué hace",
"headerTunable": "¿Ajustable?",
"rows": [
{
"stage": "1. Deduplicación por huella",
"stage": "Deduplicación por huella",
"what": "Cada evento genera una huella (<code>event_type + key fields from data</code>). Las huellas idénticas dentro de una ventana corta se consideran duplicados del primero.",
"tunable": "No — lógica interna del dispatcher."
},
{
"stage": "2. Cooldown",
"what": "Cuando una huella ya se ha enviado, esa misma huella se silencia durante el cooldown propio de cada severidad. El estado se guarda en la tabla SQLite <code>notification_last_sent</code> para que sobreviva a reinicios. Valores por defecto: <code>CRITICAL</code> 60 s, <code>WARNING</code> 300 s, <code>INFO</code> 900 s, con posibilidad de override por categoría (por ejemplo <code>resources</code> 900 s, <code>updates</code> 86 400 s).",
"tunable": "No — valores por defecto integrados en el dispatcher."
"stage": "Intervalo de repetición",
"what": "Tras un envío correcto se suprimen huellas repetidas y se guarda el estado en <code>notification_last_sent</code>. Las bases de <code>CRITICAL</code>, <code>WARNING</code> e <code>INFO</code> son 86400 s, igual que <code>resources</code> y <code>updates</code>. Excepciones: 5 s para acciones VM/CT y apagado/reinicio, 10 s para resultados de backups/replicación y 1800–3600 s para varias categorías de salud. Los ajustes explícitos por evento o grupo prevalecen.",
"tunable": "Solo mediante la API de ajustes: una clave <code>cooldown.&lt;event_type&gt;</code> o <code>cooldown.&lt;group&gt;</code> sustituye los valores predeterminados; no hay control en la interfaz."
},
{
"stage": "3. Agregación de ráfagas",
"stage": "Agrupación de ráfagas",
"what": "Cuando llegan N eventos del mismo tipo dentro de una ventana corta (por ejemplo un aluvión de intentos de fuerza bruta SSH), se agrupan en un único mensaje <code>burst_*</code> con un contador y una muestra.",
"tunable": "No — ventana y umbral están fijados por tipo de evento."
}
],
"calloutTitle": "El despacho ocurre en un hilo de fondo",
"calloutBody": "El bucle de despacho corre en su propio hilo. La petición HTTP que emite un evento devuelve en cuanto el evento se encola — no espera al RTT de Telegram, SMTP o el webhook. Cada resultado de envío se registra en la tabla de historial para revisarlo después."
"calloutTitle": "El envío se ejecuta en segundo plano",
"calloutBody": "La petición HTTP termina al poner el evento en cola; el hilo de envío espera las respuestas de Telegram, SMTP o webhook y guarda los resultados en el historial."
},
"aiRewrite": {
"heading": "Reescritura con IA opcional",
"body1": "Cualquier evento se puede pasar por un LLM que reescribe su cuerpo en lenguaje natural y (opcionalmente) en el idioma del usuario destino antes del fan-out. El reescritor de IA está off por defecto. Cuando se activa corre en el hilo de despacho; si la llamada al proveedor falla o caduca, se usa el cuerpo templated original en su lugar.",
"body2": "Se soportan seis proveedores (OpenAI, Anthropic, Google Gemini, Groq, OpenRouter y Ollama local), con nivel de detalle por canal (<code>brief</code>, <code>standard</code>, <code>detailed</code>), idioma de salida, modo de prompt (<code>default</code> o <code>custom</code>) y un prompt personalizado opcional. El walkthrough de configuración completo, capturas y ejemplos de prompt viven en la página dedicada <link>Asistente de IA</link>.",
"body1": "Los eventos aptos pueden reescribirse con un LLM. Los resultados backup_complete y backup_fail lo omiten. La IA está desactivada por defecto y se ejecuta en el hilo de envío. Si falla o agota el tiempo, se usa la plantilla original.",
"body2": "Admite OpenAI, Anthropic, Google Gemini, Groq, OpenRouter y Ollama local, con detalle por canal (<code>brief</code>, <code>standard</code>, <code>detailed</code>), idioma, modo de instrucciones (<code>default</code> o <code>custom</code>) e instrucciones propias. Guía y ejemplos en <link>Asistente de IA</link>.",
"privacyTitle": "Nota de privacidad",
"privacyBody": "La reescritura con IA envía el cuerpo del evento — que puede incluir hostnames, direcciones IP, usernames, mensajes de error y líneas de journal — al proveedor configurado. Ollama mantiene todo en el host; los otros cinco proveedores transmiten datos a sus respectivos endpoints. Desactiva el reescritor, o usa Ollama, si el host corre en un entorno donde el contenido de los eventos no puede salir de la red."
"privacyBody": "La petición de IA puede incluir título, severidad, texto, instrucciones del sistema o propias y contexto, con nombres de host, IP, usuarios, errores y registros. Se envía al destino elegido. Ollama solo procesa localmente con servidor y modelo locales; un servidor remoto o modelo en la nube envía datos fuera del host. Desactiva la reescritura o usa un servidor y modelo locales controlados si el contenido debe permanecer en la red."
},
"pveWebhook": {
"heading": "Integración del webhook de PVE",
"intro1": "Proxmox VE 8.1+ tiene su propio sistema de notificaciones con <em>endpoints</em> integrados (sendmail, gotify, SMTP, webhook). Cuando activas Notifications en el Monitor, se registra como uno de esos endpoints — un destino <code>webhook</code> que apunta de vuelta a la propia API del Monitor. Desde ese momento, todo lo que Proxmox mismo emite (fencing HA, replicación, vzdump desde la GUI, renovación de certificado, etc.) fluye por la misma pipeline de despacho que los eventos propios del Monitor.",
"intro2": "El destino es visible desde la GUI de Proxmox en <em>Datacenter → Notifications → Notification Targets</em>:",
"intro1": "El sistema de notificaciones Proxmox tiene <em>destinos</em> sendmail, Gotify, SMTP y, en versiones compatibles, webhook. Monitor registra un destino <code>webhook</code> al activarse. Los avisos de PVE, como HA, replicación y backups desde la interfaz, entran así en el mismo proceso de envío.",
"intro2": "Puedes verlo en <em>Datacenter → Notificaciones → Destinos de notificación</em>.",
"imageAlt": "Diálogo Proxmox VE Edit Webhook mostrando el destino proxmenux-webhook autocreado con método POST, URL http://127.0.0.1:8008/api/notifications/webhook y una plantilla JSON usando escape title, escape message, escape severity, escape timestamp y campos json",
"imageCaption": "El destino webhook del lado PVE como Proxmox lo ve (la GUI está en el locale configurado del host — español en este ejemplo). Los mismos campos aplican en cualquier idioma.",
"registeredIntro": "Qué se registra:",
"registeredItems": [
"<strong>Método y URL.</strong> <code>POST http://127.0.0.1:8008/api/notifications/webhook</code>. Solo loopback — PVE habla con el proceso del Monitor corriendo en el mismo host.",
"<strong>Plantilla de body.</strong> Un body JSON usando los helpers Handlebars nativos de PVE — guardado base64-encoded en el archivo de config por PVE, pero se expande a:",
"<strong>Método y URL.</strong> <code>POST http://127.0.0.1:8008/api/notifications/webhook</code> sin HTTPS en Monitor. Con HTTPS, usa el receptor HTTP local del puerto 8009. Ambos permanecen en el mismo host.",
"<strong>Plantilla del cuerpo.</strong> JSON con funciones Handlebars de PVE, guardado como base64 en la configuración. Al expandirse resulta:",
"<strong>Matcher.</strong> Un bloque compañero <code>matcher: proxmenux-matcher</code> con <code>mode all</code> para que cada notificación de PVE llegue al destino.",
"<strong>Bloque priv compañero.</strong> Una entrada vacía <code>webhook: proxmenux-webhook</code> se añade a <code>/etc/pve/priv/notifications.cfg</code>. PVE se niega a instanciar cualquier endpoint webhook sin un bloque privado coincidente, incluso cuando no se necesitan secrets — así que el Monitor escribe un stub solo de cabecera ahí. No se configuran tokens, cabeceras ni HMAC en el lado PVE."
"<strong>Configuración privada.</strong> Se escribe el bloque <code>webhook: proxmenux-webhook</code> en <code>/etc/pve/priv/notifications.cfg</code> con una entrada <code>secret</code> llamada X-Webhook-Secret, codificada en base64. El bloque del destino público solo contiene la plantilla del cuerpo, el método y la URL. El bloque privado no está vacío."
],
"securityTitle": "Cómo se asegura el receptor",
"securityIntro": "El receptor webhook en <code>POST /api/notifications/webhook</code> aplica distintas capas de seguridad según de dónde venga la petición:",
"securityItems": [
"<strong>Loopback (<code>127.0.0.1</code> / <code>::1</code>).</strong> Solo rate-limit. El endpoint confía en la interfaz loopback — solo procesos corriendo en el host pueden alcanzarlo, y PVE mismo no puede enviar cabeceras de auth personalizadas en el body que genera. Este es el camino que viaja cada notificación emitida por PVE.",
"<strong>Llamadores remotos.</strong> Cinco capas se apilan encima del rate-limiting: un shared secret en la cabecera <code>X-Webhook-Secret</code>, un timestamp de frescura en <code>X-ProxMenux-Timestamp</code> (rechazado si se desvía más allá de la ventana configurada), una búsqueda de caché de replay y una allowlist de IP opcional. El shared secret vive en la tabla de ajustes SQLite del Monitor — no en <code>/etc/pve/priv/notifications.cfg</code> — y se genera en el primer setup. Este camino existe para integraciones personalizadas que hacen POST desde fuera del host; el destino configurado por PVE nunca lo ejercita."
"<strong>Orígenes locales (<code>127.0.0.1</code> / <code>::1</code>).</strong> Se aplica límite de peticiones, pero se omiten las comprobaciones remotas de secreto, tiempo y repetición. También se consideran locales las IP asignadas a las interfaces del host. El destino automático de PVE usa loopback.",
"<strong>Peticiones remotas.</strong> Además del límite de envíos, se comprueban el secreto de <code>X-Webhook-Secret</code>, la fecha en <code>X-ProxMenux-Timestamp</code> o el JSON, las repeticiones y la lista opcional de IP. El secreto está en SQLite y también se copia en base64 a <code>/etc/pve/priv/notifications.cfg</code> para que PVE envíe la cabecera."
],
"practiceTitle": "En la práctica",
"practiceBody": "El setup de PVE escribe el destino como <code>http://127.0.0.1:8008</code>, así que las notificaciones emitidas por PVE siempre pasan por el camino loopback con seguridad solo rate-limit. El camino de llamador remoto con shared secret es opt-in para integraciones personalizadas — apunta un servicio externo a <code>https://&lt;monitor-host&gt;:&lt;port&gt;/api/notifications/webhook</code> y suministra la cabecera <code>X-Webhook-Secret</code> para usarlo.",
"practiceBody": "PVE usa <code>http://127.0.0.1:8008</code> sin HTTPS, o HTTP en 8009 con HTTPS. Las integraciones externas en <code>https://&lt;monitor-host&gt;:&lt;port&gt;/api/notifications/webhook</code> deben enviar <code>X-Webhook-Secret</code> y una fecha actual, y superar las comprobaciones de repetición e IP. El secreto solo no basta.",
"actionsIntro": "El Monitor gestiona este destino a través de tres acciones en la pestaña Settings:",
"actionsItems": [
"<strong>Setup</strong> — corre automáticamente cuando activas Notifications. Crea la entrada en <code>/etc/pve/notifications.cfg</code>. El archivo solo se escribe cuando su contenido tiene que cambiar, y se guarda un backup del anterior en <code>/usr/local/share/proxmenux/backups/pve-notifications/</code> (los tres más recientes). No se escribe nada mientras <code>/etc/pve</code> no está montado: un Monitor que arranca durante un reinicio de <code>pve-cluster</code> registra la entrada cuando vuelve.",
"<strong>Cleanup</strong> — elimina la entrada. El backup previo del archivo se conserva.",
"<strong>Read config</strong> — muestra los destinos y matchers actuales como PVE los ve. Así es como confirmas que la entrada del Monitor es la que dispara cuando PVE tiene múltiples rutas de notificación configuradas."
"<strong>Configurar</strong>: al activar las notificaciones crea la entrada en <code>/etc/pve/notifications.cfg</code>. Solo escribe cambios y conserva las tres copias anteriores más recientes en <code>/usr/local/share/proxmenux/backups/pve-notifications/</code>. Mientras <code>/etc/pve</code> no está montado no escribe; registra la entrada cuando <code>pve-cluster</code> vuelve a estar disponible.",
"<strong>Limpiar</strong>: elimina la entrada y conserva la copia anterior.",
"<strong>Leer configuración</strong>: muestra destinos y reglas para comprobar qué ruta de notificación usa PVE."
],
"clusterTitle": "Nodos de cluster",
"clusterBody": "<code>/etc/pve/</code> se replica entre miembros del cluster, así que el destino webhook es visible en cada nodo. Cada nodo, sin embargo, hace POST a su <em>propio</em> <code>127.0.0.1:8008</code> — lo que significa que el Monitor corriendo en ese nodo recibe los eventos que PVE generó localmente. Ejecuta el Monitor en cada nodo que quieras ver en el historial de Notifications."
"clusterBody": "<code>/etc/pve/</code> se comparte en el clúster, incluida URL y secreto. Cada nodo llama a su receptor <em>local</em>: <code>127.0.0.1:8008</code> sin HTTPS, o HTTP 8009 con HTTPS. Ejecuta Monitor en cada nodo necesario y mantén el destino compartido compatible con sus receptores."
},
"catalogue": {
"heading": "Catálogo de eventos",
"intro": "Unos setenta tipos de evento están agrupados en once categorías de UI. El panel Notifications renderiza una sección colapsable por grupo con un toggle por cada evento dentro. Cada evento está on por defecto salvo que se marque explícitamente lo contrario.",
"intro": "Unos setenta tipos se agrupan en once categorías. Cada sección desplegable permite activar eventos. Están activos por defecto salvo indicación contraria.",
"headerGroup": "Grupo",
"headerEvents": "Eventos",
"rows": [
@@ -380,7 +380,7 @@
"events": "<code>auth_fail</code>, <code>ip_block</code>, <code>firewall_issue</code>, <code>user_permission_change</code>."
},
{
"group": "Cluster",
"group": "Clúster",
"events": "<code>split_brain</code>, <code>node_disconnect</code>, <code>node_reconnect</code>."
},
{
@@ -400,52 +400,52 @@
"events": "<code>gpu_mode_switch</code>, <code>gpu_passthrough_blocked</code>, <code>pci_passthrough_conflict</code>, <code>ai_model_migrated</code>."
}
],
"burstNote": "Un puñado de tipos de agregación <code>burst_*</code> (<code>burst_auth_fail</code>, <code>burst_ip_block</code>, <code>burst_disk_io</code>, etc.) existen solo en el dispatcher — reemplazan ráfagas de eventos individuales con un único mensaje de resumen y no se exponen como toggles en la UI. Heredan el estado on/off de su tipo de evento padre.",
"burstNote": "Los tipos agrupados <code>burst_*</code> (<code>burst_auth_fail</code>, <code>burst_ip_block</code>, <code>burst_disk_io</code>, etc.) sustituyen ráfagas por un resumen. No tienen controles propios en la interfaz y heredan los del evento de origen.",
"backupResults": {
"heading": "Resultados de backup",
"intro": "Una notificación sobre un trabajo de backup de Proxmox indica cómo terminó el trabajo. El resultado se lee del informe que envía Proxmox, y determina el título, el icono que se muestra con <em>Rich messages</em> activado y la fila de estado del email.",
"headerIcon": "Icono",
"intro": "El informe de cada trabajo de backup determina su resultado, título, icono con <em>Mensajes enriquecidos</em> y fila de estado del correo.",
"headerIcon": "Icon",
"headerResult": "Resultado",
"headerWhen": "Cuándo",
"rows": [
{
"icon": "💾✅",
"result": "Backup completado",
"when": "Todos los guests del trabajo terminaron y el informe no contiene advertencias."
"when": "Todos los sistemas invitados terminaron sin advertencias en el informe."
},
{
"icon": "💾⚠️",
"result": "Backup completado con advertencias",
"when": "Todos los guests terminaron y el informe contiene al menos una línea de advertencia."
"when": "Todos los sistemas invitados terminaron y el informe contiene alguna advertencia."
},
{
"icon": "💾❌",
"result": "Backup fallido",
"when": "Un guest falló, o el trabajo se detuvo con un error."
"when": "Falló un sistema invitado o el trabajo terminó con un error."
},
{
"icon": "💾❔",
"result": "Resultado del backup sin confirmar",
"when": "El informe está incompleto o no indica un resultado para cada guest."
"when": "El informe está incompleto o no indica el resultado de cada sistema invitado."
}
],
"items": [
"<strong>El título indica sobre qué era el trabajo.</strong> Incluye el almacenamiento y, en un trabajo con un solo guest, su tipo, nombre e ID. Un trabajo fallido nombra el guest que falló.",
"<strong>El cuerpo lista cada guest</strong> con su propio resultado, tamaño, duración y archivo, seguido de una línea con los totales del trabajo.",
"<strong>El título identifica el trabajo.</strong> Incluye almacenamiento y, si solo hay un invitado, su tipo, nombre e ID. Si falla, identifica el invitado afectado.",
"<strong>El cuerpo detalla cada sistema invitado</strong>, con resultado, tamaño, duración y archivo, seguido de los totales.",
"<strong>Las advertencias y los errores se listan una vez.</strong> Las líneas repetidas se muestran una sola vez con la causa principal primero; a partir de ocho líneas, el resto se cuenta en una línea de cierre y permanece en el log de la tarea de Proxmox.",
"<strong>Un trabajo que falla antes de su primer guest</strong> muestra la causa que dio Proxmox, por ejemplo un almacenamiento que no existe.",
"<strong>Los resúmenes conservan el resultado.</strong> Un backup listado en el resumen de Quiet Hours o en el Daily Digest lleva el icono de su propio resultado."
"<strong>Un trabajo que falla antes del primer invitado</strong> muestra la causa indicada por Proxmox, por ejemplo un almacenamiento inexistente.",
"<strong>Los resúmenes conservan el resultado.</strong> Un backup en el resumen de horas de silencio conserva su icono. Los resultados de backups evitan el resumen diario."
]
}
},
"history": {
"heading": "Historial",
"body1": "Cada <em>intento</em> de despacho que el dispatcher realmente ejecuta se registra en la tabla SQLite <code>notification_history</code>. Cada fila guarda el timestamp (<code>sent_at</code>), canal, tipo de evento, severidad, título, cuerpo de mensaje renderizado, un flag <code>success</code> y — cuando el envío falló — el error devuelto por el proveedor en <code>error_message</code>. Los eventos agregados en ráfaga aparecen como una única fila con el tipo de evento <code>burst_*</code>. Los eventos suprimidos por la etapa de cooldown no se loguean: nunca se convierten en un intento de despacho.",
"body1": "Cada <em>intento</em> de envío realizado se guarda en <code>notification_history</code>: fecha <code>sent_at</code>, canal, evento, severidad, título, cuerpo, indicador <code>success</code> y, si falla, <code>error_message</code>. Las ráfagas usan una fila de tipo <code>burst_*</code>. Los eventos suprimidos por el intervalo de repetición no se registran.",
"body2": "Settings → Notifications tiene una sección <em>Historial de notificaciones</em>, cerrada por defecto, con las últimas 20 entradas: el resultado de cada envío, su canal y su fecha, el error cuando falló y, en cada ejecución del resumen diario, si tenía algo que enviar. La página no ofrece borrarlo: Audit & Report lee ese mismo historial para comprobar la entrega de cada canal.",
"body3": "Los mismos datos se exponen en <code>GET /api/notifications/history</code> con parámetros opcionales <code>limit</code>, <code>offset</code>, <code>severity</code> y <code>channel</code>, y se pueden borrar con <code>DELETE /api/notifications/history</code>."
},
"api": {
"heading": "Endpoints de API",
"heading": "Endpoints de la API",
"headerEndpoint": "Endpoint",
"headerMethod": "Método",
"headerUse": "Uso",
@@ -453,7 +453,7 @@
{
"endpoint": "/api/notifications/settings",
"method": "GET / POST",
"use": "Lee o escribe la configuración completa (canales, toggles por evento, reescritor de IA, Display Name)."
"use": "Lee o escribe la configuración: canales, controles por evento, IA y nombre visible."
},
{
"endpoint": "/api/notifications/test",
@@ -483,7 +483,7 @@
{
"endpoint": "/api/notifications/webhook",
"method": "POST",
"use": "Recibe las notificaciones propias de Proxmox VE. Los llamadores loopback están solo rate-limited; los llamadores remotos deben pasar adicionalmente la cabecera <code>X-Webhook-Secret</code>, comprobación de frescura <code>X-ProxMenux-Timestamp</code>, caché de replay y allowlist de IP opcional."
"use": "Recibe avisos de Proxmox. Los orígenes locales omiten las comprobaciones remotas, pero tienen límite de peticiones. Los remotos se comprueban con <code>X-Webhook-Secret</code>, fecha en <code>X-ProxMenux-Timestamp</code> o JSON, detección de repeticiones y lista de IP configurada."
},
{
"endpoint": "/api/notifications/proxmox/setup-webhook",
@@ -508,7 +508,7 @@
{
"label": "Asistente de IA",
"href": "/docs/monitor/ai-assistant",
"tail": " — proveedores, modelos, modos de prompt, idiomas, niveles de detalle por canal."
"tail": " — proveedores, modelos, modos de instrucciones, idiomas y detalle por canal."
},
{
"label": "Monitor de salud",
@@ -521,14 +521,14 @@
"tailRich": " — dónde encajan las tablas SQLite (<code>notification_last_sent</code>, <code>notification_history</code>) y el hilo de despacho en el proceso más amplio del Monitor."
},
{
"label": "Access & Authentication",
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tailRich": " — cómo se emiten API tokens para scripts que llaman a <code>/api/notifications/send</code>."
},
{
"label": "Dashboard → Logs del sistema",
"href": "/docs/monitor/dashboard/system-logs",
"tail": " — la vista en vivo del mismo journal que alimenta el journal watcher."
"tail": " — vista en directo del registro del sistema que alimenta su monitor de eventos."
}
]
}
@@ -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. La confiance accordée aux IP clientes de <code>X-Forwarded-For</code> nécessite PROXMENUX_TRUST_PROXY=1 et un proxy que vous contrôlez. La seule présence de <code>X-Forwarded-Proto</code> ou <code>X-Forwarded-Host</code> n’active pas la confiance envers le proxy. Sur les ports 80/443, le frontend utilise des URL relatives <code>/api/*</code> ; sur tout autre port, il appelle le port 8008 du même nom d’hôte."
},
"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": "Points d’accès publics (sans jeton)",
"publicIntro": "La connexion, l’état de l’authentification, la configuration initiale et le point d’accès léger <code>/api/system-info</code> sont publics :",
"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 secours 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 d’authentification, utilisez un code de secours conservé ou restaurez l’application depuis une sauvegarde préparée auparavant. Synchronisation cloud et exports locaux 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 de configuration 2FA montre un QR code, un secret Base32 pour la saisie manuelle et, après la vérification, huit codes de secours à usage unique. Copiez les codes avant de fermer le dialogue : 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> dans la barre latérale du tableau de bord, puis cliquez sur <strong>Activer 2FA</strong> et <strong>Démarrer la configuration</strong>. Le dialogue montre le QR code et la clé manuelle ; les huit codes de secours apparaissent après la vérification du code.",
"<strong>Ajouter l'entrée à l'application authentificateur:</strong>",
"<strong>Confirmez avec le code actuel à six chiffres</strong> de l’application dans le champ « Code de vérification » du dialogue de configuration, puis validez. Le code change toutes les 30 secondes ; s’il expire pendant la saisie, utilisez le suivant.",
"<strong>Conservez les codes de secours.</strong> Après la vérification, gardez les huit en lieu sûr dans un gestionnaire de mots de passe, une note chiffrée ou une copie papier sécurisée. Chacun sert une fois si votre application d’authentification est indisponible.",
"<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 est refusé, vérifiez les horloges du serveur et du téléphone avant de vous déconnecter de la session fonctionnelle. Si l’accès est déjà perdu, utilisez un code de secours 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 secours.</strong> Saisissez un des huit codes enregistrés dans le champ TOTP. Il sert une fois ; les codes inutilisés restent valides. Après connexion, ouvrez Sécurité, choisissez <strong>Désactiver 2FA</strong> puis <strong>Activer 2FA</strong> 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 secours valide. Le secret TOTP et les codes de secours sont effacés. Retirez aussi l’ancienne entrée de votre application d’authentification.",
"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 répartiteur envoie le modèle original. Les reformulations de la file d’envoi des événements ont un délai maximal de 25 secondes ; une fois ce délai atteint, le modèle est envoyé au lieu d’attendre."
},
"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 avec IA × tokens d’entrée et de sortie par appel. Exemple : 50 événements × un canal × (2 000 en entrée + 300 en sortie) font environ 115 000 tokens par jour, car l’invite système par défaut compte à elle seule environ 1 500 tokens. La consommation et les coûts réels dépendent du modèle, du contexte, du cache et des limites du fournisseur. La section <link>Détail par canal</link> explique comment utiliser <code>brief</code> pour le chat au lieu de <code>standard</code>, tout en gardant des rapports e-mail 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>, un instantané figé plutôt qu’un alias évolutif."
]
},
"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 d’une VM ou d’un LXC. Champs du corps, tous facultatifs sauf si les valeurs par défaut ne correspondent pas à l’organisation du stockage : <code>storage</code> (un stockage 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> 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>'{'\"test_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>Paquets Python fournis.</strong> Les paquets Python sont livrés dans l’AppImage et s’exécutent avec l’interpréteur Python de l’hôte lui-même, 3.11 (PVE 8) ou 3.13 (PVE 9), sans rien installer dans le Python système de l’hôte. 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 des origines CORS restreintes, enregistre directement dix blueprints et initialise les routes du terminal. Le tableau montre les modules principaux ; les blueprints PBS, liens du Monitor, audit et sauvegarde VM sont aussi enregistrés. Les préchargements propres à 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.",
"CPU : utilisation et température CPU comparées aux seuils configurables ; 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 enregistrements existants d’<code>errors</code> sont mis à jour sur place (<code>last_seen</code>, gravité, motif), sans duplication. L’envoi des notifications a aussi ses propres règles d’empreinte et de temporisation.",
"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> le serveur TLS utilise <code>gevent.pywsgi.WSGIServer</code> avec son gestionnaire par défaut ; <code>flask-sock</code> gère les connexions WebSocket sur TLS."
],
"outro": "Les processus enfants du terminal héritent de <code>User=root</code> du service. L’ouverture d’un WebSocket exige un ticket bref à usage unique obtenu par le point d’accès authentifié des tickets de terminal avec droits administratifs.",
"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 ouvre un rapport imprimable des mesures ; enregistrez-le en PDF depuis la boîte de dialogue d’impression du navigateur et joignez-le à 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 dans la jail <code>proxmenux</code> de Fail2Ban au <em>niveau applicatif</em> avant de traiter les requêtes Flask, en gardant le résultat en cache pendant 30 secondes. Sans Fail2Ban, les échecs de connexion sont consignés dans <code>proxmenux-auth.log</code> et le point d’accès de connexion est limité à 5 tentatives par IP toutes les 5 minutes, mais aucune IP n’est bloquée."
},
"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 à seuil ont des valeurs <strong>Avertissement</strong> et <strong>Critique</strong> réglables. Le tableau ci-dessous explique les exceptions, comme la règle combinée du swap.",
"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 de seuils 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, dont la température des disques, utilisent ces valeurs ; certaines barres de capacité gardent leurs propres limites visuelles.",
"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."
},
{
"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": "Uniquement les stockages PVE de type LVM, LVM-thin, ZFS-pool, RBD, CephFS et PBS. Les stockages répertoire, NFS et CIFS relèvent de la ligne d’espace disque de l’hôte."
},
{
"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 toutes les entrées <code>type=lxc</code> de <code>/usr/local/share/proxmenux/managed_installs.json</code>. Les compteurs de mises à jour LXC de l’onglet VM et LXC disparaissent à l’actualisation suivante du tableau de bord. La réactivation remplit le registre au prochain cycle de détection, 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 utilisés par l’hôte : points de montage système (<code>/</code>, <code>/boot</code>, <code>/usr</code>, <code>/var</code>…), swap actif, membres de pools ZFS, volumes physiques LVM, membres RAID actifs ou étiquettes de partitions système. 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 ces 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 de ce test (sortie de <code>smartctl -a --json</code>, ou <code>nvme smart-log</code> sur NVMe si smartctl échoue). Utile si le support du fabricant 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": "L’onglet VM et LXC inventorie tous les invités de l’hôte avec l’utilisation CPU, mémoire et disque en direct. Les détails de chaque invité montrent configuration, ressources, sauvegardes, journal de console des conteneurs OCI, notes et commandes Démarrer / Éteindre / Redémarrer / Forcer l'arrêt."
},
"header": {
"title": "Tableau de bord : VM et LXC",
"description": "Inventaire complet des invités du nœud : quatre mesures en haut, une liste triable de chaque VM et LXC en dessous et les détails par invité avec configuration, ressources, sauvegardes, journal de console des conteneurs OCI et les quatre commandes de cycle de vie (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 de cycle de vie passent par <code>POST /api/vms/&lt;vmid&gt;/control</code> ; Redémarrer et Forcer l'arrêt demandent de saisir le VMID pour confirmer, et la réponse est reflétée dans 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": "Journal de console OCI (onglet Logs)",
"endpoint": "/api/lxc/<vmid>/console-log",
"source": "Sortie console du processus principal de l’image, lue depuis <code>/var/log/proxmenux/oci/&lt;vmid&gt;.console.log</code> sur l’hôte. Affiché uniquement pour les conteneurs OCI."
},
{
"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) ; stockages PVE indisponibles ; montages NFS/CIFS figés ou passés en lecture seule de façon inattendue ; stockages LVM-thin et autres pools dépassant les mêmes seuils."
},
{
"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. La catégorie Mises à jour de la fenêtre État de santé affiche un bouton <em>Mettre à jour maintenant</em> lorsque des mises à jour sont en attente. Il lance la procédure complète de mise à jour ProxMenux dans la fenêtre ; sa fermeture actualise l’état avec <code>?refresh=1</code> afin que l’indicateur reflète le nouvel état 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 par nature, comme <em>Mises à jour système : mises à jour disponibles</em> tant que l’hôte n’est pas mis à jour, et une notification toutes les cinq minutes pendant une semaine serait inutile. Le bouton <em>Mettre à jour maintenant</em> de la catégorie Mises à jour de la fenêtre État de santé permet de résoudre ce cas directement. Pour les autres cas ou les mises à jour reportées, la surveillance offre aussi deux mécanismes liés pour 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 constats d’état des pools ZFS (DEGRADED, FAULTED, UNAVAIL) autorisent explicitement l’acquittement, tout comme les contrôles de capacité des pools. 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 aussi accessibles par API pour scripts, tableaux de bord personnalisés ou bots. Les appels exigent un jeton Bearer valide, issu de la connexion ou de l’écran des jetons API. Les modifications, comme acquitter des alertes, enregistrer les réglages de suppression ou nettoyer les erreurs orphelines, exigent la portée full_admin ; read_only reçoit 403.",
"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 ; 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. Les sessions ne sont pas auditées commande par 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>. <code>/api/health</code> attend aussi l’en-tête Bearer : les sondes de disponibilité ont donc besoin d’un jeton read_only. Sous <code>/api/auth/*</code> se trouvent à la fois des routes publiques de configuration/connexion/état et des routes protégées de gestion du compte et des jetons ; elles ne sont pas toutes anonymes.",
"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 le contexte de l’événement et les champs du modèle. Sur ce point d’accès, la reformulation IA ne reçoit que le titre et le message ; les champs de <code>data</code> ne sont pas envoyés au fournisseur. Voir <link>Notifications → Catalogue des événements</link> pour la signification des événements."
},
"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."
}
]
}
}

Some files were not shown because too many files have changed in this diff Show More