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

This commit is contained in:
MacRimi
2026-10-18 13:19:12 +02:00
146 changed files with 10388 additions and 628 deletions
+21 -1
View File
@@ -5,7 +5,12 @@ serves every published page under locale-prefixed URLs:
- `/en/<path>` — English, the source of truth
- `/es/<path>` — Spanish
- `/de/<path>` — German
- `/fr/<path>` — French
- `/it/<path>` — Italian
- `/pt/<path>` — Portuguese
- `/sk/<path>` — Slovak, with English fallback where needed
- `/sv/<path>` — Swedish
We use [`next-intl`](https://next-intl.dev) for the i18n plumbing. Anyone
can translate the docs without writing TypeScript: most of the work is
@@ -148,6 +153,18 @@ Example:
### 4. Test locally
From the repository root, check the available catalogs without using a
translation provider:
```bash
python3 .github/scripts/check_web_docs_catalogs.py
```
For a full locale-completion change, add `--require-complete` to also require
every English file and leaf. This validates schema, placeholders, rich-text
tags, literal code and rendering metadata; it does not replace linguistic
review. Partial translations can continue to use the English fallback.
```bash
cd web
npm run dev
@@ -311,7 +328,10 @@ registers a renderer for them.
If you want to add a language that isn't in the project yet:
1. Create `messages/<locale>/common.json` and the page catalogs. The automated
builder can provide the initial baseline.
builder can provide the initial baseline when explicitly dispatched. It
does not run on merge: changing English and its translations together must
not trigger machine retranslation of the reviewed text. Offline validation
still runs automatically for website changes.
2. Review the shared navigation and a representative set of documentation
pages with a native speaker.
3. Add the locale code to `routing.ts` only when the locale is ready to be
@@ -89,10 +89,12 @@ export default async function PostInstallPage({
docs: { postInstall: {
routes: Route[]
related: { items: RelatedItem[] }
pbs?: { items: string[] }
} }
}
const routes = messages.docs.postInstall.routes
const relatedItems = messages.docs.postInstall.related.items
const pbsItems = messages.docs.postInstall.pbs?.items ?? []
const code = (chunks: React.ReactNode) => <code>{chunks}</code>
const strong = (chunks: React.ReactNode) => <strong>{chunks}</strong>
@@ -210,6 +212,14 @@ export default async function PostInstallPage({
{t.rich("community.body", { em, code, a: communityAnchor, link: externalRepoLink })}
</p>
<h2 className="text-2xl font-semibold mt-10 mb-4 text-gray-900">{t("pbs.heading")}</h2>
<p className="mb-4 text-gray-800 leading-relaxed">{t.rich("pbs.body", { strong })}</p>
<ul className="list-disc pl-6 mb-4 text-gray-800 leading-relaxed space-y-2">
{pbsItems.map((_, i) => (
<li key={i}>{t.rich(`pbs.items.${i}`, { strong, em })}</li>
))}
</ul>
<h2 className="text-2xl font-semibold mt-10 mb-4 text-gray-900">{t("related.heading")}</h2>
<ul className="list-disc pl-6 text-gray-800 leading-relaxed space-y-1">
{relatedItems.map((item) => (
+5 -4
View File
@@ -8,13 +8,14 @@ const inter = Inter({ subsets: ["latin"] })
* Minimal root layout — the localized layout under [locale]/ does the
* real work (provider, navbar, etc.) but cannot own <html>/<body> tags
* because Next.js requires those at the root level. Lang is set to the
* default locale here and refined client-side from inside the locale
* layout so the page still renders correctly with JS disabled (defaults
* to English) and switches to the active locale once hydrated.
* default locale here; scripts/localize-export.mjs sets the exported
* document's language before search indexing, and LocaleHtmlSync keeps
* it in sync during client navigation. The root-only hydration suppression
* allows that intentional lang attribute change in the static export.
*/
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className="dark">
<html lang="en" className="dark" suppressHydrationWarning>
<body className={`${inter.className} bg-background text-foreground antialiased`}>
{children}
</body>
+5
View File
@@ -29,7 +29,12 @@ export function LanguageSwitcher() {
const labels: Record<string, string> = {
en: t("en"),
es: t("es"),
de: t("de"),
fr: t("fr"),
it: t("it"),
pt: t("pt"),
sk: t("sk"),
sv: t("sv"),
}
return (
+1 -1
View File
@@ -19,7 +19,7 @@ import { defineRouting } from "next-intl/routing"
* `CONTRIBUTING-TRANSLATIONS.md`.
*/
export const routing = defineRouting({
locales: ["en", "es", "sk"],
locales: ["en", "es", "de", "fr", "it", "pt", "sk", "sv"],
defaultLocale: "en",
localePrefix: "always",
})
+254
View File
@@ -0,0 +1,254 @@
{
"site": {
"name": "ProxMenux",
"tagline": "Interaktives Menü und Web-Dashboard für Proxmox VE"
},
"nav": {
"home": "Startseite",
"docs": "Dokumentation",
"documentation": "Dokumentation",
"guides": "Anleitungen",
"changelog": "Änderungsprotokoll",
"github": "GitHub",
"rss": "RSS",
"rssTitle": "RSS-Feed",
"menuOpen": "Menü öffnen"
},
"footer": {
"sponsorHeading": "Projekt unterstützen",
"sponsorBody": "Wenn Sie das Projekt unterstützen möchten.",
"sponsorAlt": "Auf Ko-fi unterstützen",
"connectHeading": "Community",
"connectBody": "Beteiligen Sie sich an den Community-Diskussionen auf GitHub, um Hilfe zu erhalten, Ideen auszutauschen und zum Projekt beizutragen. Jede Idee ist willkommen!",
"joinDiscussion": "An der Diskussion teilnehmen",
"copyrightPrefix": "ProxMenux, ein gemeinschaftliches Open-Source-Projekt von",
"copyrightSuffix": "."
},
"language": {
"switcher": "Sprache",
"en": "English",
"es": "Español",
"sk": "Slovenčina",
"de": "Deutsch",
"fr": "Français",
"it": "Italiano",
"pt": "Português",
"sv": "Svenska"
},
"resources": {
"documentation": {
"title": "Dokumentation",
"description": "Systembeschreibung und Benutzeranleitungen"
},
"changelog": {
"title": "Änderungsprotokoll",
"description": "Informationen zu den neuesten Aktualisierungen"
},
"guides": {
"title": "Anleitungen",
"description": "Schrittweise Anleitungen für häufige Aufgaben"
},
"github": {
"title": "GitHub-Repository",
"description": "Sehen Sie sich den Quellcode an."
}
},
"docSidebar": {
"documentation": "Dokumentation",
"items": {
"introduction": "Einführung",
"installation": "Installation",
"proxmenuxMonitor": "ProxMenux Monitor",
"monitorOverview": "Übersicht",
"architecture": "Architektur",
"accessAuth": "Zugriff und Authentifizierung",
"dashboard": "Dashboard",
"dashboardSystemOverview": "Registerkarte Systemübersicht",
"dashboardApps": "Registerkarte Apps",
"dashboardStorage": "Registerkarte Speicher",
"dashboardNetwork": "Registerkarte Netzwerk",
"dashboardVmsLxcs": "Registerkarte VMs und LXCs",
"dashboardVmsLxcsApp": "App",
"dashboardVmsLxcsUpdates": "Aktualisierungen",
"dashboardHardware": "Registerkarte Hardware",
"dashboardSystemLogs": "Registerkarte Systemprotokolle",
"dashboardTerminal": "Registerkarte Terminal",
"dashboardSecurity": "Registerkarte Sicherheit",
"dashboardSettings": "Registerkarte Einstellungen",
"healthMonitor": "Zustandsüberwachung",
"auditReport": "Prüfung und Berichte",
"auditReportOverview": "Übersicht",
"auditReportAssessment": "Bewertung und Inventar",
"auditReportPolicy": "Richtlinie",
"auditReportChanges": "Änderungen",
"auditReportReports": "Berichte und Vergleiche",
"auditReportScope": "Umfang und Garantien",
"notifications": "Benachrichtigungen",
"aiAssistant": "KI-Assistent",
"apiReference": "API-Referenz",
"integrations": "Integrationen",
"ociManager": "OCI manager Apps",
"ociOverview": "Übersicht",
"ociArchitecture": "So wird ein OCI-Image umgesetzt",
"ociCustomImage": "Image außerhalb des Katalogs",
"ociStorageNetwork": "Daten, Pfade und Netzwerk",
"ociHardware": "Geräte und Beschleunigung",
"ociStacks": "Anwendungen mit mehreren Containern",
"ociLifecycle": "Installieren, aktualisieren und ändern",
"ociMonitor": "In ProxMenux Monitor",
"proxmenuxScripts": "ProxMenux Scripts",
"postInstallScript": "Skript zur Nachinstallation",
"postInstallOverview": "Übersicht",
"postInstallAutomated": "Automatisch",
"postInstallCustomizable": "Anpassbar",
"postInstallBasicSettings": "Grundeinstellungen",
"postInstallSystem": "System",
"postInstallVirtualization": "Virtualisierung",
"postInstallNetwork": "Netzwerk",
"postInstallStorage": "Speicher",
"postInstallSecurity": "Sicherheit",
"postInstallCustomization": "Anpassung",
"postInstallMonitoring": "Überwachung",
"postInstallPerformance": "Leistung",
"postInstallOptional": "Optional",
"postInstallUpdates": "Verfügbare Aktualisierungen installieren",
"postInstallUninstall": "Optimierungen entfernen",
"gpusCoralTpu": "GPUs und Coral TPU",
"nvidiaHost": "NVIDIA-Treiber auf dem Host installieren",
"coralHost": "Coral TPU auf dem Host installieren",
"addGpuLxc": "GPU für einen LXC freigeben",
"addCoralLxc": "Coral TPU für einen LXC freigeben",
"addGpuVm": "GPU einer VM zuweisen (Passthrough)",
"switchGpuMode": "GPU-Modus wechseln (VM ↔ LXC)",
"createVm": "VM erstellen",
"createVmOverview": "Übersicht",
"createVmSystemNas": "NAS-Systeme",
"createVmSynology": "Synology-VM",
"createVmNasOthers": "Weitere NAS-Systeme",
"createVmSystemWindows": "Windows-Systeme",
"createVmSystemLinux": "Linux-Systeme",
"diskManager": "Datenträgerverwaltung",
"diskManagerOverview": "Übersicht",
"diskImportVm": "Datenträger in eine VM importieren",
"diskImportImageVm": "Datenträgerabbild in eine VM importieren",
"diskAddController": "Controller oder NVMe-Gerät zu einer VM hinzufügen",
"diskImportLxc": "Datenträger in einen LXC importieren",
"diskFormat": "Physischen Datenträger formatieren oder löschen",
"diskSmart": "SMART-Zustand und Datenträgertests",
"storageShareManager": "Speicher und Freigaben verwalten",
"storageShareOverview": "Übersicht",
"hostStorage": "Speicher in den Host einbinden",
"hostNfs": "NFS-Freigabe als Proxmox-Speicher hinzufügen",
"hostSamba": "Samba-Freigabe als Proxmox-Speicher hinzufügen",
"hostIscsi": "iSCSI-Ziel als Proxmox-Speicher hinzufügen",
"hostLocalDisk": "Lokalen Datenträger als Proxmox-Speicher hinzufügen",
"hostLocalShared": "Freigegebenes Verzeichnis auf dem Host anlegen",
"lxcMountPoints": "LXC-Mountpoints (Host ↔ CT)",
"lxcNetworkSharing": "Netzwerkfreigaben in LXC",
"lxcNfsClient": "NFS-Client in LXC",
"lxcSambaClient": "Samba-Client in LXC",
"lxcNfsServer": "NFS-Server in LXC",
"lxcSambaServer": "Samba-Server in LXC",
"network": "Netzwerk",
"networkOverview": "Übersicht",
"networkDiagnostics": "Diagnose",
"networkMonitoring": "Werkzeuge zur Echtzeitüberwachung",
"networkBridge": "Netzwerk-Bridges prüfen und reparieren",
"networkConfig": "Konfiguration prüfen und bereinigen",
"networkPersistent": "Dauerhafte Schnittstellennamen",
"networkBackup": "Schnittstellen sichern und neu starten",
"security": "Sicherheit",
"securityOverview": "Übersicht",
"securityFail2ban": "Fail2Ban",
"securityLynis": "Lynis",
"utilities": "Dienstprogramme",
"utilsOverview": "Übersicht",
"utilsUupDump": "ISO-Erstellung mit UUP Dump",
"utilsSystemUtils": "Systemwerkzeuge installieren",
"utilsSystemUpdate": "Proxmox-System aktualisieren",
"utilsUpgradePve": "Von PVE 8 auf PVE 9 aktualisieren",
"utilsExportVm": "VM als OVA/OVF exportieren",
"utilsImportVm": "VM aus OVA/OVF importieren",
"settingsProxmenux": "ProxMenux-Einstellungen",
"settingsOverview": "Übersicht",
"settingsMonitor": "ProxMenux Monitor",
"settingsBeta": "Release-Kanal wechseln",
"settingsVersion": "Versionsinformationen anzeigen",
"settingsUninstall": "ProxMenux deinstallieren",
"commandsReference": "Befehlsreferenz",
"commandsOverview": "Übersicht",
"commandsSystem": "Nützliche Systembefehle",
"commandsVmCt": "VMs und CTs verwalten",
"commandsStorage": "Speicher und Datenträger",
"commandsNetwork": "Netzwerkbefehle",
"commandsUpdates": "Aktualisierungen und Pakete",
"commandsGpu": "GPU-Passthrough",
"commandsZfs": "ZFS verwalten",
"commandsBackup": "Sichern und Wiederherstellen",
"commandsTools": "Systemwerkzeuge für die Befehlszeile",
"glossary": "Glossar",
"about": "Über das Projekt",
"aboutOverview": "Übersicht",
"aboutFaq": "FAQ",
"aboutContributors": "Mitwirkende",
"aboutContributing": "Mitwirken",
"aboutCodeOfConduct": "Verhaltenskodex",
"externalRepositories": "Externe Repositorys",
"backupRestore": "Sichern und Wiederherstellen",
"backupRestoreOverview": "Übersicht",
"backupRestoreHowItWorks": "Funktionsweise",
"backupRestoreDestinations": "Ziele",
"backupRestoreDestOverview": "Übersicht",
"backupRestoreDestLocal": "Lokales Archiv",
"backupRestoreDestPbs": "Proxmox Backup Server",
"backupRestoreDestBorg": "Borg",
"backupRestoreCreating": "Sicherungen erstellen",
"backupRestoreJobs": "Geplante Aufträge",
"backupRestoreRestoring": "Wiederherstellen",
"backupRestoreCrossKernel": "Wiederherstellung mit anderer Kernel-Version",
"backupRestoreGlossary": "Glossar"
}
},
"hero": {
"title": "ProxMenux",
"tagline": "Ein interaktives Menü und Web-Dashboard für Proxmox VE",
"description": "ProxMenux verbindet ein interaktives Menü mit einem Web-Dashboard für Proxmox VE. Führen Sie Befehle, Skripte und geführte Assistenten über das Terminalmenü aus oder verfolgen Sie Host-Zustand, Messwerte und Benachrichtigungen im Browser.",
"installButton": "Jetzt installieren",
"whatIsButton": "Was ist ProxMenux?",
"logoAlt": "ProxMenux-Logo"
},
"docNav": {
"previous": "Zurück",
"next": "Weiter"
},
"tocPanel": {
"onThisPage": "Auf dieser Seite"
},
"supportProject": {
"heading": "Unterstützen Sie das Projekt!",
"body": "Wenn Sie <strong>ProxMenux</strong> hilfreich finden, geben Sie dem Projekt eine ⭐ auf GitHub, damit auch andere darauf aufmerksam werden.",
"button": "Stern auf GitHub vergeben"
},
"rssLink": {
"heading": "Bleiben Sie auf dem Laufenden!",
"body": "Abonnieren Sie unseren RSS-Feed, um über neue Änderungen informiert zu werden.",
"copy": "Kopieren",
"copied": "Kopiert!",
"copyTitle": "RSS-URL kopieren",
"openFeed": "RSS-Feed öffnen",
"openTitle": "RSS-Feed öffnen"
},
"changelog": {
"pageTitle": "Änderungsprotokoll",
"meta": {
"title": "ProxMenux-Änderungsprotokoll",
"titleSuffix": "Versionshinweise",
"latest": "Aktuell",
"mostRecent": "Neueste Version",
"description": "Versionshinweise und Aktualisierungsverlauf für ProxMenux, das menügesteuerte Skript zur Verwaltung von Proxmox VE.",
"descriptionTail": "Neue Funktionen, Fehlerbehebungen, Sicherheitsupdates, Verbesserungen an ProxMenux Monitor, Kompatibilität mit KI-Anbietern, zusätzliche Absicherung beim GPU-Passthrough und mehr.",
"ogDescription": "Versionshinweise für ProxMenux.",
"ogTail": "Abonnieren Sie den RSS-Feed oder besuchen Sie diese Seite erneut, um neue Versionen zu finden."
}
}
}
+6 -1
View File
@@ -28,7 +28,12 @@
"switcher": "Language",
"en": "English",
"es": "Español",
"sk": "Slovenčina"
"sk": "Slovenčina",
"de": "Deutsch",
"fr": "Français",
"it": "Italiano",
"pt": "Português",
"sv": "Svenska"
},
"resources": {
"documentation": {
@@ -78,6 +78,17 @@
"heading": "Community scripts",
"body": "The menu also exposes two third-party scripts from the <a>community-scripts</a> project: <em>Proxmox VE Post Install</em> and <em>Proxmox VE Microcode</em>. These are wrappers that <code>wget | bash</code> the original authors' scripts. They are not maintained by ProxMenux. See <link>External Repositories</link> for details and trust considerations before running them."
},
"pbs": {
"heading": "On Proxmox Backup Server",
"body": "On a Proxmox Backup Server host, the same menu opens from <strong>Settings post-install Proxmox</strong> in the PBS menu. Automated, Customizable, Apply Available Updates and Uninstall Optimizations work as on Proxmox VE, with these differences:",
"items": [
"<strong>Repositories and upgrade:</strong> when the server has no subscription and only the Enterprise PBS repository is active, ProxMenux asks before switching to the PBS no-subscription repository. The switch goes through the server's own repository API, the same one behind <em>Administration > Repositories</em>. With an active subscription, or with a no-subscription or test repository already configured, the sources stay as they are.",
"<strong>Customizable list:</strong> the options that only apply to Proxmox VE are not listed: guest agent, VFIO IOMMU, Open vSwitch, vzdump backup speed, pigz, Appliance Manager, Ceph, High Availability and OVH Real Time Monitoring.",
"<strong>Subscription banner:</strong> the patch applies to the Proxmox Backup Server web interface, and Uninstall Optimizations restores it.",
"<strong>Figurine:</strong> installs without the Proxmox VE aliases.",
"<strong>Community scripts:</strong> the section offers <em>Proxmox Backup Server Post Install</em> and <em>Proxmox Backup Server Microcode</em> in place of the Proxmox VE scripts."
]
},
"related": {
"heading": "Related",
"items": [
+6 -1
View File
@@ -28,7 +28,12 @@
"switcher": "Idioma",
"en": "English",
"es": "Español",
"sk": "Slovenčina"
"sk": "Slovenčina",
"de": "Deutsch",
"fr": "Français",
"it": "Italiano",
"pt": "Português",
"sv": "Svenska"
},
"resources": {
"documentation": {
@@ -157,7 +157,7 @@
"<strong>Filesystems runtime del kernel y sistema</strong> — <code>/proc</code>, <code>/sys</code>, <code>/dev</code> y <code>/run</code> son pseudo-filesystems que produce el kernel y udev; no se persisten en ningún sitio.",
"<strong>Binarios de paquetes bajo <code>/usr/bin</code>, <code>/usr/lib</code>, <code>/lib</code>, <code>/sbin</code></strong> — los reinstala el APT del destino a partir de <code>packages.manual.list</code>.",
"<strong><code>/var/log/</code>, <code>/var/tmp/</code>, <code>/var/cache/</code></strong> — estado runtime por host, no se restaura.",
"<strong><code>/home/USUARIO</code></strong> — no está en el perfil por defecto. Añadirlo como ruta custom cuando un sistema tenga directorios home de usuario que deban sobrevivir a una restauración."
"<strong><code>/home/USER</code></strong> — no está en el perfil por defecto. Añadirlo como ruta custom cuando un sistema tenga directorios home de usuario que deban sobrevivir a una restauración."
],
"customPathsTitle": "Cómo se tratan las rutas custom",
"customPathsBody": "Una ruta custom añadida en línea en modo Custom o persistida en <code>backup-extra-paths.txt</code> pasa por el mismo pipeline de <code>rsync</code> que las rutas del perfil por defecto. Se aplican las exclusiones globales. Si la ruta custom está bajo <code>/root/</code> o <code>/usr/local/share/proxmenux/</code>, siguen aplicando las exclusiones específicas de arriba. Cada ruta archivada — default o custom — queda registrada en <code>metadata/paths_archived.txt</code>. Las rutas que no existen en el origen se registran en <code>metadata/missing_paths.txt</code> sin detener la copia."
@@ -14,7 +14,7 @@
},
"intro": {
"title": "Cada salto de kernel se maneja de forma distinta",
"body": "Cuando la restauración detecta que la copia y el destino tienen versiones mayores distintas de kernel, el flujo se ramifica en función de la dirección del salto — si la copia es más antigua o más reciente que el destino — porque los dos casos tienen modos de fallo opuestos. Las copias más recientes que el destino se restauran limpiamente tal cual (verificado empíricamente en múltiples pruebas de banco). Las copias más antiguas que el destino necesitan un filtro para evitar romper el arranque del destino con configuración escrita para un kernel que desde entonces ha cambiado."
"body": "El kernel de un host Proxmox se identifica mediante una versión como <code>6.17.13-2-pve</code>. Los dos primeros números (<strong>6.17</strong> en este ejemplo) definen la versión principal: cuando cambian, algunos archivos de configuración del kernel anterior podrían no ser válidos para el nuevo. Si la restauración detecta versiones principales distintas en la copia y en el destino, el proceso toma un camino u otro según la dirección del salto: si el kernel de la copia es anterior o posterior al del destino. Los dos casos presentan riesgos opuestos. Las copias con un kernel más reciente que el del destino se restauran tal cual, sin problemas según las pruebas realizadas con varios saltos de kernel. Las copias con un kernel anterior al del destino necesitan un filtro para evitar que una configuración del kernel antiguo impida arrancar el sistema de destino."
},
"directionCheck": {
"heading": "La comprobación de dirección",
@@ -78,7 +78,7 @@
"intro": "Para desarrolladores que quieran trazar o extender el comportamiento cross-kernel:",
"rows": [
{ "component": "Detección de dirección", "location": "<code>hb_compat_check</code> en <code>lib_host_backup_common.sh</code>. Fija <code>HB_COMPAT_KERNEL_DIRECTION</code>." },
{ "component": "Lista de rutas del subconjunto seguro", "location": "<code>hb_unsafe_paths_cross_version</code> en <code>lib_host_backup_common.sh</code>. Emite líneas <code>path\\tmotivo</code> usadas tanto por el filtro CLI como por el endpoint Web <code>/api/host-backups/restore/prepare</code>." },
{ "component": "Lista de rutas del subconjunto seguro", "location": "<code>hb_unsafe_paths_cross_version</code> en <code>lib_host_backup_common.sh</code>. Emite líneas <code>path\\treason</code> usadas tanto por el filtro CLI como por el endpoint Web <code>/api/host-backups/restore/prepare</code>." },
{ "component": "Fases de hidratación", "location": "<code>_rs_hyd_grub</code>, <code>_rs_hyd_kernel_cmdline</code>, <code>_rs_hyd_modules</code>, <code>_rs_hyd_files</code> en <code>backup_host.sh</code>. Orquestados por <code>_rs_apply_bk_older_hydration</code>." },
{ "component": "Forzado de reflow post-arranque", "location": "<code>apply_pending_restore.sh</code> lee <code>HB_HYDRATION_APPLIED</code> de <code>plan.env</code> y fuerza <code>NEEDS_INITRAMFS=1</code>/<code>NEEDS_GRUB=1</code>." },
{ "component": "Preview Web", "location": "<code>/api/host-backups/restore/prepare</code> en <code>flask_server.py</code>. Fuentea la librería helper, ejecuta <code>_rs_apply_bk_older_hydration</code> en modo plan, devuelve las acciones al modal Web." }
@@ -76,7 +76,7 @@
},
"sameArchive": {
"heading": "El contenido interno de la copia es el mismo en cualquier destino",
"body": "Con independencia de dónde se guarde la copia, dentro siempre están los mismos tres bloques descritos en <em>Cómo funciona</em>: el sistema de ficheros (<code>rootfs/</code>), los metadatos (<code>metadata/</code>) y el manifiesto (<code>manifest.json</code>). Al extraer una copia local <code>.tar.zst</code>, restaurar un archivo <code>.pxar</code> desde PBS o descomprimir un archivo Borg, el árbol de directorios resultante es idéntico en los tres casos. Esto significa que el proceso de restauración lee siempre los mismos ficheros y no le importa desde qué destino provenga la copia."
"body": "Los tres destinos contienen la misma estructura <code>rootfs/</code> + <code>metadata/</code> + <code>manifest.json</code> descrita en <em>Cómo funciona</em>. Extraer un <code>.tar.zst</code> de un archivo local, restaurar un <code>.pxar</code> desde PBS o extraer un archivo de Borg con <code>borg extract</code> produce el mismo árbol de directorios. El proceso de restauración (<code>_rs_check_layout</code>, <code>_rs_apply</code>, <code>_rs_prepare_pending_restore</code>) lee los mismos tres componentes sin necesitar saber de qué destino proceden."
},
"extractStandalone": {
"heading": "Extraer una copia fuera de ProxMenux",
@@ -23,7 +23,7 @@
},
"repoSelection": {
"heading": "Selección del repositorio",
"intro": "ProxMenux descubre repositorios PBS desde dos fuentes en cada copia. El usuario elige uno desde un menú unificado; esa elección determina, para esa ejecución concreta, contra qué servidor y datastore se envía la copia, con qué contraseña se autentica y con qué huella (<em>fingerprint</em>) valida el certificado.",
"intro": "ProxMenux descubre los repositorios de PBS a partir de dos fuentes en cada copia de seguridad. El usuario elige uno en un menú unificado; esa elección determina los valores de <code>HB_PBS_REPOSITORY</code>, <code>HB_PBS_SECRET</code> y <code>HB_PBS_FINGERPRINT</code> para esa ejecución.",
"sourceRows": [
{
"source": "storage.cfg de Proxmox (auto-descubierto)",
@@ -46,7 +46,7 @@
"backupIdTitle": "Nombrado del backup ID",
"backupIdBody": "El backup ID por defecto es <code>hostcfg-HOSTNAME</code>. Se pide al usuario que lo confirme o edite antes de la subida; cualquier carácter fuera de <code>[A-Za-z0-9_-]</code> se elimina y los guiones finales se recortan. Reutilizar el mismo ID entre ejecuciones es intencional — PBS trata el ID como un <em>grupo</em>, y cada copia posterior aparece como un nuevo backup dentro de ese grupo, compartiendo dedup con las ejecuciones previas.",
"pxarTitle": "Qué se incluye dentro del archivo .pxar",
"pxarBody": "Al construir el archivo <code>.pxar</code> se empaqueta el directorio de trabajo completo: el sistema de ficheros del host (<code>rootfs/</code>), los metadatos (<code>metadata/</code>) y el manifiesto (<code>manifest.json</code>). Al restaurar, ProxMenux compara la información del manifiesto con la del host destino para detectar si son equivalentes, si cambia el hardware o si se trata de un equipo distinto, y ajustar el proceso en consecuencia. Las copias antiguas —hechas con versiones anteriores de ProxMenux que empaquetaban solo el sistema de ficheros— siguen restaurándose sin problema: el flujo de restauración detecta ese formato heredado y lo reorganiza automáticamente."
"pxarBody": "El origen del <code>.pxar</code> es todo el directorio <code>staging_root</code>, con <code>rootfs/</code>, <code>metadata/</code> y <code>manifest.json</code> juntos. Las versiones anteriores utilizaban <code>$staging_root/rootfs</code> como origen; esto dejaba <code>metadata/</code> fuera del archivo y la comprobación de compatibilidad de la restauración no tenía datos que leer, por lo que mostraba advertencias de restauración entre hosts incluso al restaurar en el mismo host. Las copias antiguas creadas solo a partir de rootfs siguen restaurándose correctamente mediante la rama del caso 3 de <code>_rs_check_layout</code>, que vuelve a colocar el árbol plano <code>etc/var/root/usr</code> dentro de una estructura <code>rootfs/</code>."
},
"encryption": {
"heading": "Cifrado del lado del cliente",
@@ -61,9 +61,9 @@
"modesSharedTitle": "Clave compartida (importar la misma en cada host)",
"modesSharedBody": "Se genera una única clave y se importa en todos los hosts mediante la opción <em>Usar una clave existente</em>. La gestión es más sencilla: hay un solo secreto que proteger, y cualquier host puede leer las copias de cualquier otro (útil para verificación centralizada, ejercicios de restauración cruzada o consolidación). A cambio, si la clave compartida se filtra queda expuesto todo el conjunto de hosts a la vez. Recomendado para laboratorios personales y entornos donde todos los hosts pertenecen al mismo responsable y comparten el mismo nivel de confianza.",
"recoveryTitle": "¿Subir la clave a PBS? — el usuario decide",
"recoveryBody": "Justo después de elegir la clave, ProxMenux pregunta si se quiere subir una copia de esa clave a PBS como red de seguridad, con dos opciones. <strong>No</strong> (por defecto) mantiene la clave solo en el host; ProxMenux no toca PBS con nada relacionado con la recuperación y el usuario gestiona por su cuenta la copia externa (desde el Monitor, la acción <em>Descargar</em> en la fila del destino PBS la exporta en el acto). <strong>Sí</strong> pide una passphrase de recuperación —dos veces, para comprobar que coincidan—; con esa passphrase, la clave se envuelve localmente con AES-256-CBC y PBKDF2 (600 000 iteraciones, sal aleatoria) en un fichero <code>pbs-key.recovery.enc</code>. A partir de ese momento, cada copia cifrada sube también ese fichero envuelto a PBS. Ni la passphrase ni la clave en claro salen del host. La respuesta se puede cambiar después desde el Monitor en cualquier momento; el interruptor está inline en la fila del destino PBS y el botón que aparece se adapta al estado (empezar a subir, dejar de subir, o cambiar la passphrase).",
"recoveryBody": "Justo después de elegir la clave, ProxMenux hace una única pregunta explícita — <em>¿Subir clave a PBS?</em> — con dos respuestas. <strong>No se sube nada a PBS hasta que el usuario responde Sí.</strong> La opción por defecto es <em>No, mantener solo local</em>: la clave se queda solo en su ruta local, ProxMenux no toca PBS con nada relacionado con la recuperación y el usuario gestiona por su cuenta la copia externa (desde el Monitor, el botón <em>Descargar archivo clave</em> de la fila del destino PBS la exporta en el acto). Al elegir <em>Sí, subir</em> se pide una passphrase de recuperación —dos veces, para comprobar que coincidan— y ProxMenux envuelve la clave con esa passphrase usando AES-256-CBC y PBKDF2 (600 000 iteraciones, sal aleatoria) en un fichero <code>pbs-key.recovery.enc</code>. A partir de ese momento, cada backup cifrado sube también ese fichero envuelto a PBS como un grupo de backup asociado. Ni la passphrase ni la clave en claro salen del host. La respuesta se puede cambiar después desde el Monitor en cualquier momento: el interruptor de la fila del destino PBS cambia entre Sí y No y se aplica al momento (empezar a subir, dejar de subir o cambiar la passphrase, según el estado).",
"blobUploadTitle": "Grupo emparejado en PBS",
"blobUploadBody1": "Cuando el usuario ha respondido Sí, ProxMenux sube el sobre de recuperación a PBS después de cada copia cifrada como un segundo grupo emparejado, con el mismo nombre que el del host pero terminado en <code>-keyrecovery</code>. Los dos grupos aparecen juntos en el listado del datastore: uno con las copias del host, otro con los sobres. <strong>El sobre nunca sale del host en claro</strong>: se cifra en el host con AES-256-CBC y PBKDF2 antes de enviar un solo byte (<code>openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -salt</code>). PBS solo recibe el sobre ya cifrado.",
"blobUploadBody1": "Cuando la custodia está configurada como <em>Sí, subir</em>, ProxMenux sube el archivo de recuperación protegido a PBS después de cada copia cifrada. Lo guarda en un segundo grupo de copia asociado, con el mismo nombre que el grupo del host y el sufijo <code>-keyrecovery</code>. Los dos grupos aparecen juntos en la lista del almacén de datos: uno para las copias del host y otro para los archivos de recuperación. <strong>El archivo de recuperación nunca sale del host en texto plano</strong>: se cifra en el propio host con AES-256-CBC y PBKDF2 antes de enviar ningún dato (<code>openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -salt</code>). PBS solo recibe el archivo ya cifrado.",
"envelopeSecurityTitle": "¿No es un riesgo subir el archivo keyrecovery a PBS?",
"envelopeSecurityBody": "El sobre viaja y se guarda cifrado en todo momento. La passphrase de recuperación no sale nunca del host: el cifrado ocurre en local antes de la subida y PBS solo recibe el resultado ya cifrado. Un administrador de PBS —o cualquiera con acceso al datastore— puede descargar el sobre, pero sin la passphrase no puede leer la clave que contiene: son solo bytes cifrados. Para reconstruir la clave hacen falta las dos cosas a la vez, el sobre y la passphrase, y solo el usuario tiene ambas.",
"blobUploadConstraintTitle": "Por qué dos grupos y no uno solo cifrado",
@@ -73,7 +73,7 @@
"recoverTitle": "Recuperación en un equipo recién instalado",
"recoverBody": "Cuando la clave no está en su sitio —tras reinstalar el host desde cero o después de eliminarla a propósito— el flujo de restauración prueba tres fuentes en orden y se queda con la primera que produce una clave usable. Primero, si el repositorio PBS elegido tiene una clave gestionada por PVE en <code>/etc/pve/priv/storage/&lt;NAME&gt;.enc</code>, se copia sola a la ruta canónica. Segundo, si en PBS hay un grupo <code>-keyrecovery</code>, se descarga la copia más reciente y se pide la passphrase de recuperación para abrirla. Tercero, si ninguna de las dos anteriores funciona o el usuario las descarta, el diálogo pide la ruta absoluta donde ha dejado la clave en este host, y se copia a la ruta canónica. El Monitor expone el mismo flujo dentro del modal de la copia. Si al Restaurar, Descargar o Ver contenido falta la clave, aparece un panel ámbar arriba del modal con las mismas tres vías de importación. Si la clave está instalada pero no es la correcta para esa copia, PBS devuelve un error de tipo <code>wrong key — manifest's key XX does not match provided key YY</code> y el modal muestra un panel estructurado con el fingerprint que PBS espera (el que quedó grabado en el manifest de la copia), para que el usuario sepa qué clave concreta necesita importar.",
"monitorManagementTitle": "Gestionar la clave desde el Monitor",
"monitorManagementBody": "En la página de configuración de copias, la fila de cada destino PBS incluye los controles de la clave. Tres acciones directas: <em>Descargar</em> exporta la clave actual al navegador. <em>Subir</em> reemplaza la clave instalada por otra que aporta el usuario (la anterior solo se sobrescribe cuando la nueva ha llegado correctamente a su sitio). <em>Eliminar</em> retira la clave del host. Justo al lado está el interruptor del sobre de recuperación: un Sí/No para subir o no la clave a PBS, un campo de passphrase que aparece al elegir Sí, y un botón que se adapta al estado actual (empezar a subir, dejar de subir, o cambiar la passphrase). Los controles del Monitor y el diálogo del shell hacen lo mismo por dentro, así que el resultado en disco y en PBS es idéntico se use la que se use."
"monitorManagementBody": "El Monitor muestra los controles del archivo de clave en cada fila de destino PBS de la página de configuración de copias. Hay tres acciones: <em>Descargar</em> envía el archivo de clave actual al navegador del usuario; <em>Subir</em> sustituye el archivo de clave instalado por uno proporcionado por el usuario (el anterior solo se sobrescribe cuando el nuevo se ha guardado correctamente en la ruta canónica); y <em>Eliminar</em> borra el archivo de clave del host. Junto a estas acciones hay un único control de custodia para la recuperación: las opciones Sí y No de <em>¿Subir la clave a PBS?</em>, un campo para la frase de contraseña al elegir Sí y un botón contextual para aplicar el cambio, con el texto <em>Iniciar subida</em>, <em>Detener subida</em> o <em>Actualizar frase de contraseña</em> según el estado actual. Todas las acciones utilizan los mismos endpoints de Flask que el menú de terminal, por lo que el resultado en disco y el estado en PBS son idénticos desde ambas interfaces."
},
"restoreAccess": {
"heading": "Recuperación del lado de la restauración",
@@ -112,7 +112,7 @@
{
"id": "repositorio-pbs",
"term": "Repositorio PBS",
"def": "Combinación de servidor Proxmox Backup Server + <a href=\"#datastore\">datastore</a> + usuario al que se suben las copias. Se identifica con el formato <code>usuario@realm@host:datastore</code>. Un mismo servidor PBS puede alojar varios repositorios."
"def": "Combinación de servidor Proxmox Backup Server + <a href=\"#datastore\">datastore</a> + usuario al que se suben las copias. Se identifica con el formato <code>user@realm@host:datastore</code>. Un mismo servidor PBS puede alojar varios repositorios."
},
{
"id": "datastore",
@@ -121,7 +121,7 @@
}
],
"schemaTitle": "Validación por esquema",
"schemaBody": "ProxMenux incluye una plantilla que describe qué campos debe contener el manifiesto y qué forma tiene cada uno. Cuando se genera una copia se puede comprobar automáticamente que el manifiesto respeta esa plantilla, de modo que si un colector produjera un JSON malformado o con un campo mal escrito se detectaría en el momento. Es una comprobación destinada al desarrollo del propio ProxMenux: si el sistema no la tiene instalada, la copia sigue funcionando con normalidad y el manifiesto se genera igual."
"schemaBody": "El manifiesto se valida con <code>scripts/backup_restore/schema/manifest.schema.json</code>. Ejecutar <code>build_manifest.sh --validate</code> activa una validación JSON Schema en Python (requiere <code>python3</code> y <code>jsonschema</code>). Si el módulo no está instalado, se omite la comprobación sin mostrar ningún aviso: esta validación es principalmente una ayuda para el desarrollo, no una dependencia necesaria durante la ejecución."
},
"applications": {
"heading": "El inventario de aplicaciones",
@@ -26,7 +26,7 @@
},
{
"action": "Descargar",
"detail": "Exporta el archivo como un fichero portable <code>.tar.zst</code> (tar comprimido con zstd). Se puede extraer en cualquier sistema Linux con <code>tar --zstd -xf FICHERO.tar.zst</code>, o desde macOS/Windows con herramientas que soporten zstd (7-Zip, PeaZip, Keka…). El árbol extraído contiene <code>manifest.json</code>, <code>metadata/</code> y <code>rootfs/</code>, exactamente el mismo layout que consume la restauración. Es útil para inspección offline o para restaurar en un host que no tiene acceso al destino original (PBS, Borg)."
"detail": "Exporta el archivo como un fichero portable <code>.tar.zst</code> (tar comprimido con zstd). Se puede extraer en cualquier sistema Linux con <code>tar --zstd -xf FILE.tar.zst</code>, o desde macOS/Windows con herramientas que soporten zstd (7-Zip, PeaZip, Keka…). El árbol extraído contiene <code>manifest.json</code>, <code>metadata/</code> y <code>rootfs/</code>, exactamente el mismo layout que consume la restauración. Es útil para inspección offline o para restaurar en un host que no tiene acceso al destino original (PBS, Borg)."
},
{
"action": "Restaurar",
@@ -110,7 +110,7 @@
},
"apply": {
"title": "Aplicar cambios del host + workloads",
"body": "Una vez confirmas, el script escribe los cambios del lado del host — <code>vfio.conf</code>, blacklist, módulos y (para NVIDIA) la regla udev por BDF en <code>/etc/udev/rules.d/10-proxmenux-vfio-bind.rules</code> más el estado BDF en <code>/etc/proxmenux/vfio-bind.bdfs</code>. También aplica la política de conflicto elegida a cada VM/LXC afectada. Si la config del host realmente cambió, ejecuta <code>update-initramfs -u -k all</code> — si no, salta ese paso."
"body": "Tras confirmar, el script escribe los cambios en el host: <code>vfio.conf</code>, la lista de módulos bloqueados, los módulos y, para NVIDIA, la regla udev por BDF en <code>/etc/udev/rules.d/10-proxmenux-vfio-bind.rules</code> y el estado BDF en <code>/etc/proxmenux/vfio-bind.bdfs</code>. También aplica la política de conflictos elegida a cada VM/LXC afectado. Si la configuración del host ha cambiado, ejecuta <code>update-initramfs -u -k all</code> y después <code>proxmox-boot-tool refresh</code>; si no ha cambiado, omite ambos comandos."
},
"reboot": {
"title": "Reiniciar",
@@ -257,7 +257,7 @@
"<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 (tu-usuario)</code>) y empieza a mostrar un código de 6 dígitos que se refresca cada 30 segundos.",
"<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",
@@ -319,7 +319,7 @@
"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.",
"calloutTitle": "Por qué esto es cómodo",
"calloutBody": "La URL se mantiene igual que en la LAN — <code>http://&lt;ip-lan-proxmox&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": "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.",
"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."
},
@@ -55,7 +55,7 @@
"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\": \"'<'motivo'>'\"'}'</code>.",
"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."
]
@@ -174,7 +174,7 @@
"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:",
"curlCode": "TOKEN=<tu token full_admin>\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 \"estado final: $state\"",
"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\""
@@ -101,7 +101,7 @@
],
"sourcesHeading": "Fuentes para la versión disponible",
"sources": [
"<strong>Repositorio de GitHub</strong>: último lanzamiento o etiqueta de un repositorio público <code>propietario/nombre</code>.",
"<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>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."
@@ -110,8 +110,8 @@
"No incluyas <code>pct exec</code>; ProxMenux ya entra en el contenedor y ejecuta el comando como root."
],
"exampleLead": "Ejemplo de procedimiento completo dentro del contenedor:",
"example": "cd /opt/mi-app && ./update.sh",
"callout": "Un comando de versión como <code>miapp --version</code> solo lee una versión; no instala nada. Los comandos se ejecutan con privilegios administrativos y deben revisarse con el mismo cuidado que un comando de shell como root."
"example": "cd /opt/my-app && ./update.sh",
"callout": "Un comando de versión como <code>myapp --version</code> solo lee una versión; no instala nada. Los comandos se ejecutan con privilegios administrativos y deben revisarse con el mismo cuidado que un comando de shell como root."
},
"bulk": {
"heading": "Actualización en bloque",
@@ -142,7 +142,7 @@
"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.",
"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;id-de-ejecución&gt;.log</code>. Se conservan los diez últimos logs de cada LXC y los archivos más antiguos se eliminan automáticamente.",
"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.",
"Las programaciones externas detectadas de Proxmox VE Helper-Scripts se muestran aparte para hacer visible cualquier automatización coincidente."
],
@@ -186,7 +186,7 @@
},
{
"problem": "Una actualización programada indica que es necesario reiniciar",
"resolution": "Abre <strong>Ver log</strong> para revisar la ejecución completada y reinicia ese LXC. ProxMenux elimina el aviso mediante el evento de ciclo de vida existente cuando el contenedor vuelve a arrancar."
"resolution": "Abre Ver registro para revisar la ejecución completada y después reinicia ese LXC. ProxMenux borra el aviso cuando el evento de ciclo de vida detecta el nuevo arranque."
}
]
},
@@ -37,7 +37,7 @@
"headingHref": "https://gethomepage.dev",
"intro": "Homepage es un panel de aplicaciones totalmente estático y personalizable. ProxMenux Monitor se enchufa vía el widget <code>customapi</code> integrado — pega una entrada de servicio en <code>services.yaml</code>, reinicia Homepage y la tarjeta aparece con números en vivo.",
"iconCalloutTitle": "El logo oficial de ProxMenux está en dashboardicons.com",
"iconCalloutBody": "Las guías de abajo usan <code>icon: proxmenux.png</code>. Homepage resuelve automáticamente los nombres de archivo simples contra <a1>dashboardicons.com</a1> — una librería de iconos curada para paneles autoalojados. La entrada de ProxMenux vive en <a2>dashboardicons.com/icons/external/proxmenux</a2> y Homepage la descarga en el primer render. La misma búsqueda funciona para miles de otras herramientas (Telegram, Discord, Grafana, Tailscale, etc.) — basta con escribir <code>icon: &lt;nombre&gt;.png</code> en cualquier entrada de servicio.",
"iconCalloutBody": "Las guías de abajo usan <code>icon: proxmenux.png</code>. Homepage resuelve automáticamente los nombres de archivo simples contra <a1>dashboardicons.com</a1> — una librería de iconos curada para paneles autoalojados. La entrada de ProxMenux vive en <a2>dashboardicons.com/icons/external/proxmenux</a2> y Homepage la descarga en el primer render. La misma búsqueda funciona para miles de otras herramientas (Telegram, Discord, Grafana, Tailscale, etc.) — basta con escribir <code>icon: &lt;name&gt;.png</code> en cualquier entrada de servicio.",
"imageAlt": "Panel Homepage mostrando tres tarjetas de ProxMenux Monitor (EDGE, VOID, DREAM) con uptime, CPU, RAM y temperatura para cada host Proxmox",
"imageCaption": "Tres instancias de ProxMenux Monitor renderizadas como tarjetas Homepage — uptime, CPU, RAM y temperatura de CPU leídas en vivo desde <code>/api/system</code> en cada host cada 10 s.",
"basicTitle": "Widget básico — sin autenticación",
@@ -94,7 +94,7 @@
"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.",
"step6Title": "6 · Automatizaciones",
"step6Body": "Tres automatizaciones que cubren los escenarios reactivos más comunes — reemplaza <code>notify.mobile_app_&lt;tu_movil&gt;</code> por el servicio notify que uses:",
"step6Body": "Tres automatizaciones que cubren los escenarios reactivos más comunes — reemplaza <code>notify.mobile_app_&lt;your_phone&gt;</code> por el servicio notify que uses:",
"logoTitle": "Sobre el logo de ProxMenux",
"logoBody": "La tarjeta picture-entity en la parte superior del YAML Lovelace descarga el logo oficial de ProxMenux desde <a1>dashboardicons.com</a1> — una librería de iconos gratuita curada para paneles autoalojados. La entrada de ProxMenux vive en <a2>dashboardicons.com/icons/external/proxmenux</a2>. Home Assistant descarga el SVG sobre HTTPS en el primer render y lo cachea.",
"logoBrokenTitle": "Si la tarjeta del logo muestra una imagen rota",
@@ -120,7 +120,7 @@
"tokenTipTitle": "Token vía archivo o env, no inline",
"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;host-prometheus&gt;:9090</code>, pulsa <em>Query</em> y ejecuta cualquiera de estas — deberías obtener números en vivo de tu host Proxmox:",
"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",
"headerConfirms": "Qué confirma",
"verifyRows": [
@@ -44,7 +44,7 @@
"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."
],
"activeAlt": "Tarjeta de notificaciones activada con pestañas de canales, nombre visible y opciones avanzadas de IA",
"activeCaption": "Estado activo: pestañas Telegram, Gotify, Discord, Email, Pushover y Apprise, nombre visible, categorías por canal 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",
@@ -119,7 +119,7 @@
"groupItems": [
"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;TU_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>.",
"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>."
],
"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",
@@ -203,7 +203,7 @@
"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.",
"Rellena los placeholders con tus propias credenciales. Por ejemplo, un topic de ntfy.sh tiene aspecto de <code>ntfy://ntfy.sh/mi-topic</code>; una URL de Pushover tiene aspecto de <code>pover://user@token</code>; una URL de Matrix tiene aspecto de <code>matrix://user:pass@host:port/#room</code>.",
"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."
],
@@ -295,7 +295,7 @@
"rows": [
{
"stage": "1. Deduplicación por huella",
"what": "Cada evento genera una huella (<code>event_type + campos clave de data</code>). Las huellas idénticas dentro de una ventana corta se consideran duplicados del primero.",
"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."
},
{
@@ -339,7 +339,7 @@
"<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."
],
"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;host-monitor&gt;:&lt;port&gt;/api/notifications/webhook</code> y suministra la cabecera <code>X-Webhook-Secret</code> para usarlo.",
"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.",
"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.",
@@ -59,7 +59,7 @@
"table": {
"headers": ["Tipo", "Identificación", "Validación"],
"rows": [
["Intel/AMD DRM", "<code>/dev/dri/renderD*</code> y <code>/sys/class/drm/NODO/device/vendor</code>", "Un dispositivo de caracteres con fabricante <code>0x8086</code> (Intel) o <code>0x1002</code> (AMD)"],
["Intel/AMD DRM", "<code>/dev/dri/renderD*</code> y <code>/sys/class/drm/NODE/device/vendor</code>", "Un dispositivo de caracteres con fabricante <code>0x8086</code> (Intel) o <code>0x1002</code> (AMD)"],
["OpenCL AMD", "El render node, más <code>/dev/kfd</code> cuando el perfil lo necesita", "Existencia, tipo, fabricante, permisos y compatibilidad declarada"],
["AMD ROCm", "El nodo de render, <code>/dev/kfd</code> y la generación que declara el driver de cómputo en <code>/sys/class/kfd/kfd/topology/nodes/*/properties</code>", "Una generación para la que la imagen ROCm de la aplicación trae kernels, las GPU RDNA2 que incluye y las posteriores, se ofrece tal cual. Las demás GPU de esas familias, como las Radeon 680M y 780M, se ofrecen como experimentales y nunca son la opción propuesta: ROCm no las soporta oficialmente, la aplicación las presenta como la generación de su familia (<code>HSA_OVERRIDE_GFX_VERSION</code>) y el instalador pide confirmación antes de descargar la imagen, que es más grande. Una GPU anterior, como los gráficos integrados de un Ryzen 5000U, no se ofrece e Immich deja el reconocimiento en la CPU"],
["NVIDIA", "<code>nvidia-smi</code> y <code>nvidia-container-cli</code>", "GPU, UUID, bus PCI, versión del driver, Toolkit, nodos <code>/dev/nvidia*</code>, binarios y librerías"],
@@ -112,7 +112,7 @@
"items": [
{ "title": "Contenedor y remoto", "body": "El VMID del contenedor Rclone, el nombre exacto del remoto y, opcionalmente, una ruta dentro de él." },
{ "title": "Nombre y caché", "body": "El nombre del montaje y el modo de caché VFS: <code>off</code>, <code>minimal</code>, <code>writes</code> o <code>full</code> (por defecto)." },
{ "title": "Vistas publicadas", "body": "Una raíz común, <code>/mnt/oci-shared</code> por defecto, contiene una vista de lectura y escritura en <code>/mnt/oci-shared/remotes/NOMBRE</code> y una de solo lectura en <code>/mnt/oci-shared/remotes-ro/NOMBRE</code>." },
{ "title": "Vistas publicadas", "body": "Una raíz común, <code>/mnt/oci-shared</code> de forma predeterminada, contiene una vista de lectura y escritura en <code>/mnt/oci-shared/remotes/NAME</code> y otra de solo lectura en <code>/mnt/oci-shared/remotes-ro/NAME</code>." },
{ "title": "Activación", "body": "Tras una confirmación, el CT se detiene, se configuran su orden de arranque y un hookscript de Proxmox VE, y se vuelve a iniciar. La operación espera hasta que las dos vistas están montadas en el host." }
]
}
@@ -78,6 +78,17 @@
"heading": "Community scripts",
"body": "El menú también expone dos scripts de terceros del proyecto <a>community-scripts</a>: <em>Proxmox VE Post Install</em> y <em>Proxmox VE Microcode</em>. Son wrappers que hacen <code>wget | bash</code> de los scripts de los autores originales. No los mantiene ProxMenux. Mira <link>External Repositories</link> para detalles y consideraciones de confianza antes de ejecutarlos."
},
"pbs": {
"heading": "En Proxmox Backup Server",
"body": "En un host Proxmox Backup Server, el mismo menú se abre desde <strong>Settings post-install Proxmox</strong> en el menú de PBS. Automatizado, Personalizable, Apply Available Updates y Uninstall Optimizations funcionan igual que en Proxmox VE, con estas diferencias:",
"items": [
"<strong>Repositorios y actualización:</strong> cuando el servidor no tiene suscripción y solo está activo el repositorio Enterprise de PBS, ProxMenux pregunta antes de cambiar al repositorio sin suscripción de PBS. El cambio se hace con la API de repositorios del propio servidor, la misma que usa <em>Administration > Repositories</em>. Con una suscripción activa, o con un repositorio sin suscripción o de pruebas ya configurado, las fuentes se mantienen como están.",
"<strong>Lista personalizable:</strong> no aparecen las opciones que solo se aplican a Proxmox VE: agente de invitado, VFIO IOMMU, Open vSwitch, velocidad de backups vzdump, pigz, Appliance Manager, Ceph, alta disponibilidad y OVH Real Time Monitoring.",
"<strong>Banner de suscripción:</strong> el parche se aplica a la interfaz web de Proxmox Backup Server, y Uninstall Optimizations lo restaura.",
"<strong>Figurine:</strong> se instala sin los alias de Proxmox VE.",
"<strong>Scripts de la comunidad:</strong> la sección ofrece <em>Proxmox Backup Server Post Install</em> y <em>Proxmox Backup Server Microcode</em> en lugar de los scripts de Proxmox VE."
]
},
"related": {
"heading": "Relacionado",
"items": [
@@ -20,7 +20,7 @@
"<code>SystemMaxUse=64M</code> / <code>RuntimeMaxUse=60M</code> — caps duros sobre el uso de disco/memoria del journal.",
"<code>Compress=yes</code>, <code>Seal=no</code> — comprimir logs, saltar el forward-secure sealing (ahorra CPU).",
"<code>MaxLevelStore=info</code> — almacenar info y superiores (requerido para el visor de logs del ProxMenux Monitor y para que Fail2Ban detecte fallos de autenticación SSH/Proxmox desde el journal).",
"Rate-limits: <code>1000 eventos / 30 s</code> para prevenir flooding de logs.",
"Límite de frecuencia: <code>1000 events / 30 s</code> para evitar una avalancha de registros.",
"<code>ForwardToSyslog=no</code>, <code>ForwardToWall=no</code> — no duplicar mensajes a syslog ni broadcastear a consolas."
],
"tipTitle": "Por qué importa MaxLevelStore=info",
@@ -56,7 +56,7 @@
"<strong>Entrada del portal</strong> — escribe la IP o hostname del servidor del target iSCSI. Se asume el puerto <code>3260</code> a menos que escribas <code>host:port</code>.",
"<strong>Descubrimiento de targets</strong> — ProxMenux llama a <code>iscsiadm --mode discovery --type sendtargets --portal &lt;ip:port&gt;</code>. El servidor responde con cada IQN que permite ver a este initiator. Si el descubrimiento falla, el script muestra el error exacto de <code>iscsiadm</code> y lista las causas comunes (IP incorrecta, firewall, IQN del initiator no autorizado).",
"<strong>Selección del target</strong> — si hay un solo target se selecciona automáticamente; con varios targets se muestra un menú.",
"<strong>Storage ID</strong> — por defecto es <code>iscsi-&lt;último segmento del IQN, máx. 20 caracteres&gt;</code>. Solo letras, dígitos, <code>-</code> y <code>_</code>.",
"<strong>Storage ID</strong> — por defecto es <code>iscsi-&lt;last IQN segment, 20 chars max&gt;</code>. Solo letras, dígitos, <code>-</code> y <code>_</code>.",
"<strong>Content type</strong> — a diferencia de NFS / Samba, el contenido iSCSI está <strong>fijado a <code>images</code></strong>. iSCSI expone dispositivos de bloque raw, no un sistema de archivos, así que Proxmox solo te deja alojar discos de VM ahí."
],
"authTitle": "Autorizar el initiator de Proxmox en el target",
@@ -129,7 +129,7 @@
},
"troubleshoot": {
"heading": "Solución de problemas",
"noMountTitle": "El montaje aparece en la config del pct pero no dentro del contenedor",
"noMountTitle": "El montaje aparece en pct config, pero no dentro del contenedor",
"noMountBody": "Los bind mounts solo se adjuntan cuando el contenedor arranca. Si añadiste el montaje mientras el CT estaba corriendo, reinícialo (<code>pct reboot &lt;ctid&gt;</code>). Si ya está reiniciado y sigue faltando, comprueba <code>pct config &lt;ctid&gt;</code> para confirmar que la entrada existe y que la ruta del host realmente contiene un directorio.",
"noWriteTitle": "El contenedor puede ver el directorio pero no puede escribir",
"noWriteBody": "Casi siempre un problema de permisos. Para contenedores unprivileged, ejecuta de nuevo el fix de permisos del script — las ACLs del directorio del host pueden haber sido reseteadas por otra herramienta (rsync, restore desde backup, <code>chmod</code> manual). Para CIFS, revisa las opciones de montaje en el host: <code>findmnt /mnt/pve/cifs-…</code>, busca valores <code>uid=</code> / <code>gid=</code> / <code>file_mode=</code>.",
+254
View File
@@ -0,0 +1,254 @@
{
"site": {
"name": "ProxMenux",
"tagline": "Menu interactif et tableau de bord web pour Proxmox VE"
},
"nav": {
"home": "Accueil",
"docs": "Documentation",
"documentation": "Documentation",
"guides": "Guides",
"changelog": "Journal des modifications",
"github": "GitHub",
"rss": "RSS",
"rssTitle": "Flux RSS",
"menuOpen": "Ouvrir le menu"
},
"footer": {
"sponsorHeading": "Soutenir le projet",
"sponsorBody": "Si vous souhaitez soutenir le projet.",
"sponsorAlt": "Soutenez-moi sur Ko-fi",
"connectHeading": "Communauté",
"connectBody": "Rejoignez les discussions de la communauté sur GitHub pour obtenir de l’aide, partager vos idées et contribuer au projet. Toutes les idées sont les bienvenues !",
"joinDiscussion": "Participer à la discussion",
"copyrightPrefix": "ProxMenux, un projet collaboratif et open source créé par",
"copyrightSuffix": "."
},
"language": {
"switcher": "Langue",
"en": "English",
"es": "Español",
"sk": "Slovenčina",
"de": "Deutsch",
"fr": "Français",
"it": "Italiano",
"pt": "Português",
"sv": "Svenska"
},
"resources": {
"documentation": {
"title": "Documentation",
"description": "Présentation du système et guides d’utilisation"
},
"changelog": {
"title": "Journal des modifications",
"description": "Informations sur les dernières mises à jour"
},
"guides": {
"title": "Guides",
"description": "Tutoriels et guides pas à pas pour les tâches courantes"
},
"github": {
"title": "Dépôt GitHub",
"description": "Consultez le code source."
}
},
"docSidebar": {
"documentation": "Documentation",
"items": {
"introduction": "Introduction",
"installation": "Installation",
"proxmenuxMonitor": "ProxMenux Monitor",
"monitorOverview": "Vue d’ensemble",
"architecture": "Architecture",
"accessAuth": "Accès et authentification",
"dashboard": "Tableau de bord",
"dashboardSystemOverview": "Onglet Vue d’ensemble du système",
"dashboardApps": "Onglet Applications",
"dashboardStorage": "Onglet Stockage",
"dashboardNetwork": "Onglet Réseau",
"dashboardVmsLxcs": "Onglet VM et LXC",
"dashboardVmsLxcsApp": "Application",
"dashboardVmsLxcsUpdates": "Mises à jour",
"dashboardHardware": "Onglet Matériel",
"dashboardSystemLogs": "Onglet Journaux système",
"dashboardTerminal": "Onglet Terminal",
"dashboardSecurity": "Onglet Sécurité",
"dashboardSettings": "Onglet Paramètres",
"healthMonitor": "Surveillance de l’état du système",
"auditReport": "Audit et rapports",
"auditReportOverview": "Vue d’ensemble",
"auditReportAssessment": "Évaluation et inventaire",
"auditReportPolicy": "Politique",
"auditReportChanges": "Modifications",
"auditReportReports": "Rapports et comparaisons",
"auditReportScope": "Périmètre et garanties",
"notifications": "Notifications",
"aiAssistant": "Assistant IA",
"apiReference": "Référence de l’API",
"integrations": "Intégrations",
"ociManager": "OCI manager Apps",
"ociOverview": "Vue d’ensemble",
"ociArchitecture": "Comment une image OCI est adaptée",
"ociCustomImage": "Image absente du catalogue",
"ociStorageNetwork": "Données, chemins et réseau",
"ociHardware": "Périphériques et accélération",
"ociStacks": "Applications à plusieurs conteneurs",
"ociLifecycle": "Installer, mettre à jour et modifier",
"ociMonitor": "Dans ProxMenux Monitor",
"proxmenuxScripts": "ProxMenux Scripts",
"postInstallScript": "Script de post-installation",
"postInstallOverview": "Vue d’ensemble",
"postInstallAutomated": "Automatique",
"postInstallCustomizable": "Personnalisable",
"postInstallBasicSettings": "Paramètres de base",
"postInstallSystem": "Système",
"postInstallVirtualization": "Virtualisation",
"postInstallNetwork": "Réseau",
"postInstallStorage": "Stockage",
"postInstallSecurity": "Sécurité",
"postInstallCustomization": "Personnalisation",
"postInstallMonitoring": "Surveillance",
"postInstallPerformance": "Performances",
"postInstallOptional": "Facultatif",
"postInstallUpdates": "Appliquer les mises à jour disponibles",
"postInstallUninstall": "Supprimer les optimisations",
"gpusCoralTpu": "GPU et Coral TPU",
"nvidiaHost": "Installer les pilotes NVIDIA sur l’hôte",
"coralHost": "Installer Coral TPU sur l’hôte",
"addGpuLxc": "Donner accès à un GPU dans un LXC",
"addCoralLxc": "Donner accès à Coral TPU dans un LXC",
"addGpuVm": "Attribuer un GPU à une VM (passthrough)",
"switchGpuMode": "Changer le mode du GPU (VM ↔ LXC)",
"createVm": "Créer une VM",
"createVmOverview": "Vue d’ensemble",
"createVmSystemNas": "Systèmes NAS",
"createVmSynology": "VM Synology",
"createVmNasOthers": "Autres systèmes NAS",
"createVmSystemWindows": "Systèmes Windows",
"createVmSystemLinux": "Systèmes Linux",
"diskManager": "Gestionnaire de disques",
"diskManagerOverview": "Vue d’ensemble",
"diskImportVm": "Importer un disque dans une VM",
"diskImportImageVm": "Importer une image disque dans une VM",
"diskAddController": "Ajouter un contrôleur ou un périphérique NVMe à une VM",
"diskImportLxc": "Importer un disque dans un LXC",
"diskFormat": "Formater ou effacer un disque physique",
"diskSmart": "État SMART et tests du disque",
"storageShareManager": "Gestion du stockage et des partages",
"storageShareOverview": "Vue d’ensemble",
"hostStorage": "Intégration du stockage à l’hôte",
"hostNfs": "Ajouter un partage NFS comme stockage Proxmox",
"hostSamba": "Ajouter un partage Samba comme stockage Proxmox",
"hostIscsi": "Ajouter une cible iSCSI comme stockage Proxmox",
"hostLocalDisk": "Ajouter un disque local comme stockage Proxmox",
"hostLocalShared": "Créer un répertoire partagé sur l’hôte",
"lxcMountPoints": "Points de montage LXC (hôte ↔ CT)",
"lxcNetworkSharing": "Partages réseau dans LXC",
"lxcNfsClient": "Client NFS dans LXC",
"lxcSambaClient": "Client Samba dans LXC",
"lxcNfsServer": "Serveur NFS dans LXC",
"lxcSambaServer": "Serveur Samba dans LXC",
"network": "Réseau",
"networkOverview": "Vue d’ensemble",
"networkDiagnostics": "Diagnostic",
"networkMonitoring": "Outils de surveillance en temps réel",
"networkBridge": "Analyse et réparation des ponts réseau",
"networkConfig": "Analyse et nettoyage de la configuration",
"networkPersistent": "Noms persistants des interfaces",
"networkBackup": "Sauvegarde et redémarrage des interfaces",
"security": "Sécurité",
"securityOverview": "Vue d’ensemble",
"securityFail2ban": "Fail2Ban",
"securityLynis": "Lynis",
"utilities": "Utilitaires",
"utilsOverview": "Vue d’ensemble",
"utilsUupDump": "Création d’ISO avec UUP Dump",
"utilsSystemUtils": "Installation d’utilitaires système",
"utilsSystemUpdate": "Mise à jour du système Proxmox",
"utilsUpgradePve": "Passer de PVE 8 à PVE 9",
"utilsExportVm": "Exporter une VM au format OVA/OVF",
"utilsImportVm": "Importer une VM depuis OVA/OVF",
"settingsProxmenux": "Paramètres de ProxMenux",
"settingsOverview": "Vue d’ensemble",
"settingsMonitor": "ProxMenux Monitor",
"settingsBeta": "Changer de canal de publication",
"settingsVersion": "Afficher les informations de version",
"settingsUninstall": "Désinstaller ProxMenux",
"commandsReference": "Référence des commandes",
"commandsOverview": "Vue d’ensemble",
"commandsSystem": "Commandes système utiles",
"commandsVmCt": "Gestion des VM et CT",
"commandsStorage": "Stockage et disques",
"commandsNetwork": "Commandes réseau",
"commandsUpdates": "Mises à jour et paquets",
"commandsGpu": "Passthrough GPU",
"commandsZfs": "Gestion de ZFS",
"commandsBackup": "Sauvegarde et restauration",
"commandsTools": "Outils système en ligne de commande",
"glossary": "Glossaire",
"about": "À propos",
"aboutOverview": "Vue d’ensemble",
"aboutFaq": "FAQ",
"aboutContributors": "Contributeurs",
"aboutContributing": "Contribuer",
"aboutCodeOfConduct": "Code de conduite",
"externalRepositories": "Dépôts externes",
"backupRestore": "Sauvegarde et restauration",
"backupRestoreOverview": "Vue d’ensemble",
"backupRestoreHowItWorks": "Fonctionnement",
"backupRestoreDestinations": "Destinations",
"backupRestoreDestOverview": "Vue d’ensemble",
"backupRestoreDestLocal": "Archive locale",
"backupRestoreDestPbs": "Proxmox Backup Server",
"backupRestoreDestBorg": "Borg",
"backupRestoreCreating": "Créer des sauvegardes",
"backupRestoreJobs": "Tâches planifiées",
"backupRestoreRestoring": "Restaurer",
"backupRestoreCrossKernel": "Restauration entre versions du noyau",
"backupRestoreGlossary": "Glossaire"
}
},
"hero": {
"title": "ProxMenux",
"tagline": "Un menu interactif et un tableau de bord web pour Proxmox VE",
"description": "ProxMenux réunit un menu interactif et un tableau de bord web pour Proxmox VE. Exécutez des commandes, des scripts et des assistants depuis le terminal, ou consultez l’état de l’hôte, ses métriques et ses notifications dans un navigateur.",
"installButton": "Installer maintenant",
"whatIsButton": "Qu’est-ce que ProxMenux ?",
"logoAlt": "Logo ProxMenux"
},
"docNav": {
"previous": "Précédent",
"next": "Suivant"
},
"tocPanel": {
"onThisPage": "Sur cette page"
},
"supportProject": {
"heading": "Soutenez le projet !",
"body": "Si <strong>ProxMenux</strong> vous est utile, donnez-lui une ⭐ sur GitHub pour aider d’autres personnes à le découvrir.",
"button": "Ajouter une étoile sur GitHub"
},
"rssLink": {
"heading": "Suivez les nouveautés !",
"body": "Abonnez-vous à notre flux RSS pour être informé des nouveautés.",
"copy": "Copier",
"copied": "Copié !",
"copyTitle": "Copier l’URL du flux RSS",
"openFeed": "Ouvrir le flux RSS",
"openTitle": "Ouvrir le flux RSS"
},
"changelog": {
"pageTitle": "Journal des modifications",
"meta": {
"title": "Journal des modifications de ProxMenux",
"titleSuffix": "Notes de version",
"latest": "Dernière version",
"mostRecent": "Version la plus récente",
"description": "Notes de version et historique des mises à jour de ProxMenux, le script à menus pour administrer Proxmox VE.",
"descriptionTail": "Nouvelles fonctionnalités, corrections de bugs, mises à jour de sécurité, améliorations de ProxMenux Monitor, compatibilité avec les fournisseurs d’IA, sécurisation du passthrough GPU et bien plus.",
"ogDescription": "Notes de version de ProxMenux.",
"ogTail": "Abonnez-vous au flux RSS ou revenez consulter les nouvelles versions."
}
}
}
+254
View File
@@ -0,0 +1,254 @@
{
"site": {
"name": "ProxMenux",
"tagline": "Menu interattivo e dashboard web per Proxmox VE"
},
"nav": {
"home": "Home",
"docs": "Documentazione",
"documentation": "Documentazione",
"guides": "Guide",
"changelog": "Registro delle modifiche",
"github": "GitHub",
"rss": "RSS",
"rssTitle": "Feed RSS",
"menuOpen": "Apri menu"
},
"footer": {
"sponsorHeading": "Sostieni il progetto",
"sponsorBody": "Se desideri sostenere il progetto.",
"sponsorAlt": "Sostienimi su Ko-fi",
"connectHeading": "Community",
"connectBody": "Partecipa alle discussioni della community su GitHub per ricevere aiuto, condividere idee e contribuire al progetto. Ogni idea è benvenuta!",
"joinDiscussion": "Partecipa alla discussione",
"copyrightPrefix": "ProxMenux, un progetto collaborativo e open source di",
"copyrightSuffix": "."
},
"language": {
"switcher": "Lingua",
"en": "English",
"es": "Español",
"sk": "Slovenčina",
"de": "Deutsch",
"fr": "Français",
"it": "Italiano",
"pt": "Português",
"sv": "Svenska"
},
"resources": {
"documentation": {
"title": "Documentazione",
"description": "Descrizione del sistema e guide per l’utente"
},
"changelog": {
"title": "Registro delle modifiche",
"description": "Informazioni sugli ultimi aggiornamenti"
},
"guides": {
"title": "Guide",
"description": "Tutorial e guide passo passo per le attività più comuni"
},
"github": {
"title": "Repository GitHub",
"description": "Esplora il codice sorgente."
}
},
"docSidebar": {
"documentation": "Documentazione",
"items": {
"introduction": "Introduzione",
"installation": "Installazione",
"proxmenuxMonitor": "ProxMenux Monitor",
"monitorOverview": "Panoramica",
"architecture": "Architettura",
"accessAuth": "Accesso e autenticazione",
"dashboard": "Dashboard",
"dashboardSystemOverview": "Scheda Panoramica del sistema",
"dashboardApps": "Scheda App",
"dashboardStorage": "Scheda Archiviazione",
"dashboardNetwork": "Scheda Rete",
"dashboardVmsLxcs": "Scheda VM e LXC",
"dashboardVmsLxcsApp": "App",
"dashboardVmsLxcsUpdates": "Aggiornamenti",
"dashboardHardware": "Scheda Hardware",
"dashboardSystemLogs": "Scheda Log di sistema",
"dashboardTerminal": "Scheda Terminale",
"dashboardSecurity": "Scheda Sicurezza",
"dashboardSettings": "Scheda Impostazioni",
"healthMonitor": "Monitoraggio dello stato",
"auditReport": "Verifica e report",
"auditReportOverview": "Panoramica",
"auditReportAssessment": "Valutazione e inventario",
"auditReportPolicy": "Criteri",
"auditReportChanges": "Modifiche",
"auditReportReports": "Report e confronti",
"auditReportScope": "Ambito e garanzie",
"notifications": "Notifiche",
"aiAssistant": "Assistente IA",
"apiReference": "Riferimento API",
"integrations": "Integrazioni",
"ociManager": "OCI manager Apps",
"ociOverview": "Panoramica",
"ociArchitecture": "Come viene adattata un’immagine OCI",
"ociCustomImage": "Immagine non presente nel catalogo",
"ociStorageNetwork": "Dati, percorsi e rete",
"ociHardware": "Dispositivi e accelerazione",
"ociStacks": "Applicazioni con più container",
"ociLifecycle": "Installazione, aggiornamento e modifica",
"ociMonitor": "In ProxMenux Monitor",
"proxmenuxScripts": "ProxMenux Scripts",
"postInstallScript": "Script di post-installazione",
"postInstallOverview": "Panoramica",
"postInstallAutomated": "Automatico",
"postInstallCustomizable": "Personalizzabile",
"postInstallBasicSettings": "Impostazioni di base",
"postInstallSystem": "Sistema",
"postInstallVirtualization": "Virtualizzazione",
"postInstallNetwork": "Rete",
"postInstallStorage": "Archiviazione",
"postInstallSecurity": "Sicurezza",
"postInstallCustomization": "Personalizzazione",
"postInstallMonitoring": "Monitoraggio",
"postInstallPerformance": "Prestazioni",
"postInstallOptional": "Facoltativo",
"postInstallUpdates": "Applica gli aggiornamenti disponibili",
"postInstallUninstall": "Rimuovi le ottimizzazioni",
"gpusCoralTpu": "GPU e Coral TPU",
"nvidiaHost": "Installa i driver NVIDIA sull’host",
"coralHost": "Installa Coral TPU sull’host",
"addGpuLxc": "Abilita una GPU in un LXC",
"addCoralLxc": "Abilita Coral TPU in un LXC",
"addGpuVm": "Assegna una GPU a una VM (passthrough)",
"switchGpuMode": "Cambia modalità GPU (VM ↔ LXC)",
"createVm": "Crea una VM",
"createVmOverview": "Panoramica",
"createVmSystemNas": "Sistemi NAS",
"createVmSynology": "VM Synology",
"createVmNasOthers": "Altri sistemi NAS",
"createVmSystemWindows": "Sistemi Windows",
"createVmSystemLinux": "Sistemi Linux",
"diskManager": "Gestione dischi",
"diskManagerOverview": "Panoramica",
"diskImportVm": "Importa un disco in una VM",
"diskImportImageVm": "Importa un’immagine disco in una VM",
"diskAddController": "Aggiungi un controller o un dispositivo NVMe a una VM",
"diskImportLxc": "Importa un disco in un LXC",
"diskFormat": "Formatta o cancella un disco fisico",
"diskSmart": "Stato SMART e test del disco",
"storageShareManager": "Gestione archiviazione e condivisioni",
"storageShareOverview": "Panoramica",
"hostStorage": "Integrazione dell’archiviazione nell’host",
"hostNfs": "Aggiungi una condivisione NFS come storage Proxmox",
"hostSamba": "Aggiungi una condivisione Samba come storage Proxmox",
"hostIscsi": "Aggiungi una destinazione iSCSI come storage Proxmox",
"hostLocalDisk": "Aggiungi un disco locale come storage Proxmox",
"hostLocalShared": "Crea una directory condivisa sull’host",
"lxcMountPoints": "Punti di montaggio LXC (host ↔ CT)",
"lxcNetworkSharing": "Condivisioni di rete in LXC",
"lxcNfsClient": "Client NFS in LXC",
"lxcSambaClient": "Client Samba in LXC",
"lxcNfsServer": "Server NFS in LXC",
"lxcSambaServer": "Server Samba in LXC",
"network": "Rete",
"networkOverview": "Panoramica",
"networkDiagnostics": "Diagnostica",
"networkMonitoring": "Strumenti di monitoraggio in tempo reale",
"networkBridge": "Analisi e riparazione dei bridge di rete",
"networkConfig": "Analisi e pulizia della configurazione",
"networkPersistent": "Nomi persistenti delle interfacce",
"networkBackup": "Backup e riavvio delle interfacce",
"security": "Sicurezza",
"securityOverview": "Panoramica",
"securityFail2ban": "Fail2Ban",
"securityLynis": "Lynis",
"utilities": "Utilità",
"utilsOverview": "Panoramica",
"utilsUupDump": "Creazione di ISO con UUP Dump",
"utilsSystemUtils": "Installazione di utilità di sistema",
"utilsSystemUpdate": "Aggiornamento del sistema Proxmox",
"utilsUpgradePve": "Passaggio da PVE 8 a PVE 9",
"utilsExportVm": "Esporta una VM in OVA/OVF",
"utilsImportVm": "Importa una VM da OVA/OVF",
"settingsProxmenux": "Impostazioni di ProxMenux",
"settingsOverview": "Panoramica",
"settingsMonitor": "ProxMenux Monitor",
"settingsBeta": "Cambia canale di rilascio",
"settingsVersion": "Mostra informazioni sulla versione",
"settingsUninstall": "Disinstalla ProxMenux",
"commandsReference": "Riferimento dei comandi",
"commandsOverview": "Panoramica",
"commandsSystem": "Comandi di sistema utili",
"commandsVmCt": "Gestione di VM e CT",
"commandsStorage": "Archiviazione e dischi",
"commandsNetwork": "Comandi di rete",
"commandsUpdates": "Aggiornamenti e pacchetti",
"commandsGpu": "Passthrough GPU",
"commandsZfs": "Gestione di ZFS",
"commandsBackup": "Backup e ripristino",
"commandsTools": "Strumenti di sistema da riga di comando",
"glossary": "Glossario",
"about": "Informazioni sul progetto",
"aboutOverview": "Panoramica",
"aboutFaq": "FAQ",
"aboutContributors": "Collaboratori",
"aboutContributing": "Come contribuire",
"aboutCodeOfConduct": "Codice di condotta",
"externalRepositories": "Repository esterni",
"backupRestore": "Backup e ripristino",
"backupRestoreOverview": "Panoramica",
"backupRestoreHowItWorks": "Come funziona",
"backupRestoreDestinations": "Destinazioni",
"backupRestoreDestOverview": "Panoramica",
"backupRestoreDestLocal": "Archivio locale",
"backupRestoreDestPbs": "Proxmox Backup Server",
"backupRestoreDestBorg": "Borg",
"backupRestoreCreating": "Creare backup",
"backupRestoreJobs": "Attività pianificate",
"backupRestoreRestoring": "Ripristino",
"backupRestoreCrossKernel": "Ripristino tra versioni del kernel",
"backupRestoreGlossary": "Glossario"
}
},
"hero": {
"title": "ProxMenux",
"tagline": "Un menu interattivo e una dashboard web per Proxmox VE",
"description": "ProxMenux unisce un menu interattivo e una dashboard web per Proxmox VE. Esegui comandi, script e procedure guidate dal terminale oppure controlla lo stato dell’host, le metriche e le notifiche dal browser.",
"installButton": "Installa ora",
"whatIsButton": "Che cos’è ProxMenux?",
"logoAlt": "Logo di ProxMenux"
},
"docNav": {
"previous": "Precedente",
"next": "Successivo"
},
"tocPanel": {
"onThisPage": "In questa pagina"
},
"supportProject": {
"heading": "Sostieni il progetto!",
"body": "Se <strong>ProxMenux</strong> ti è utile, lascia una ⭐ su GitHub per aiutare altre persone a scoprirlo.",
"button": "Lascia una stella su GitHub"
},
"rssLink": {
"heading": "Resta aggiornato!",
"body": "Iscriviti al feed RSS per ricevere le novità.",
"copy": "Copia",
"copied": "Copiato!",
"copyTitle": "Copia l’URL del feed RSS",
"openFeed": "Apri il feed RSS",
"openTitle": "Apri il feed RSS"
},
"changelog": {
"pageTitle": "Registro delle modifiche",
"meta": {
"title": "Registro delle modifiche di ProxMenux",
"titleSuffix": "Note di rilascio",
"latest": "Ultima versione",
"mostRecent": "Versione più recente",
"description": "Note di rilascio e cronologia degli aggiornamenti di ProxMenux, lo script a menu per gestire Proxmox VE.",
"descriptionTail": "Nuove funzionalità, correzioni di bug, aggiornamenti di sicurezza, miglioramenti di ProxMenux Monitor, compatibilità con i fornitori IA, maggiore sicurezza del passthrough GPU e altro.",
"ogDescription": "Note di rilascio di ProxMenux.",
"ogTail": "Iscriviti al feed RSS o torna su questa pagina per le nuove versioni."
}
}
}
+254
View File
@@ -0,0 +1,254 @@
{
"site": {
"name": "ProxMenux",
"tagline": "Menu interativo e painel web para o Proxmox VE"
},
"nav": {
"home": "Início",
"docs": "Documentação",
"documentation": "Documentação",
"guides": "Guias",
"changelog": "Histórico de alterações",
"github": "GitHub",
"rss": "RSS",
"rssTitle": "Feed RSS",
"menuOpen": "Abrir menu"
},
"footer": {
"sponsorHeading": "Apoiar o projeto",
"sponsorBody": "Se quiser apoiar o projeto.",
"sponsorAlt": "Apoie-me no Ko-fi",
"connectHeading": "Comunidade",
"connectBody": "Participe nas discussões da comunidade no GitHub para obter ajuda, partilhar ideias e contribuir para o projeto. Todas as ideias são bem-vindas!",
"joinDiscussion": "Participar na discussão",
"copyrightPrefix": "ProxMenux, um projeto colaborativo e de código aberto criado por",
"copyrightSuffix": "."
},
"language": {
"switcher": "Idioma",
"en": "English",
"es": "Español",
"sk": "Slovenčina",
"de": "Deutsch",
"fr": "Français",
"it": "Italiano",
"pt": "Português",
"sv": "Svenska"
},
"resources": {
"documentation": {
"title": "Documentação",
"description": "Descrição do sistema e guias de utilização"
},
"changelog": {
"title": "Histórico de alterações",
"description": "Informações sobre as últimas atualizações"
},
"guides": {
"title": "Guias",
"description": "Tutoriais e guias passo a passo para tarefas comuns"
},
"github": {
"title": "Repositório do GitHub",
"description": "Explore o código-fonte."
}
},
"docSidebar": {
"documentation": "Documentação",
"items": {
"introduction": "Introdução",
"installation": "Instalação",
"proxmenuxMonitor": "ProxMenux Monitor",
"monitorOverview": "Visão geral",
"architecture": "Arquitetura",
"accessAuth": "Acesso e autenticação",
"dashboard": "Painel",
"dashboardSystemOverview": "Separador Visão geral do sistema",
"dashboardApps": "Separador Aplicações",
"dashboardStorage": "Separador Armazenamento",
"dashboardNetwork": "Separador Rede",
"dashboardVmsLxcs": "Separador VM e LXC",
"dashboardVmsLxcsApp": "Aplicação",
"dashboardVmsLxcsUpdates": "Atualizações",
"dashboardHardware": "Separador Hardware",
"dashboardSystemLogs": "Separador Registos do sistema",
"dashboardTerminal": "Separador Terminal",
"dashboardSecurity": "Separador Segurança",
"dashboardSettings": "Separador Definições",
"healthMonitor": "Monitor de estado",
"auditReport": "Auditoria e relatórios",
"auditReportOverview": "Visão geral",
"auditReportAssessment": "Avaliação e inventário",
"auditReportPolicy": "Política",
"auditReportChanges": "Alterações",
"auditReportReports": "Relatórios e comparações",
"auditReportScope": "Âmbito e garantias",
"notifications": "Notificações",
"aiAssistant": "Assistente de IA",
"apiReference": "Referência da API",
"integrations": "Integrações",
"ociManager": "OCI manager Apps",
"ociOverview": "Visão geral",
"ociArchitecture": "Como é adaptada uma imagem OCI",
"ociCustomImage": "Imagem fora do catálogo",
"ociStorageNetwork": "Dados, caminhos e rede",
"ociHardware": "Dispositivos e aceleração",
"ociStacks": "Aplicações com vários contentores",
"ociLifecycle": "Instalar, atualizar e modificar",
"ociMonitor": "No ProxMenux Monitor",
"proxmenuxScripts": "ProxMenux Scripts",
"postInstallScript": "Script de pós-instalação",
"postInstallOverview": "Visão geral",
"postInstallAutomated": "Automático",
"postInstallCustomizable": "Personalizável",
"postInstallBasicSettings": "Definições básicas",
"postInstallSystem": "Sistema",
"postInstallVirtualization": "Virtualização",
"postInstallNetwork": "Rede",
"postInstallStorage": "Armazenamento",
"postInstallSecurity": "Segurança",
"postInstallCustomization": "Personalização",
"postInstallMonitoring": "Monitorização",
"postInstallPerformance": "Desempenho",
"postInstallOptional": "Opcional",
"postInstallUpdates": "Aplicar as atualizações disponíveis",
"postInstallUninstall": "Remover otimizações",
"gpusCoralTpu": "GPU e Coral TPU",
"nvidiaHost": "Instalar controladores NVIDIA no host",
"coralHost": "Instalar Coral TPU no host",
"addGpuLxc": "Disponibilizar uma GPU num LXC",
"addCoralLxc": "Disponibilizar Coral TPU num LXC",
"addGpuVm": "Atribuir uma GPU a uma VM (passthrough)",
"switchGpuMode": "Alterar o modo da GPU (VM ↔ LXC)",
"createVm": "Criar uma VM",
"createVmOverview": "Visão geral",
"createVmSystemNas": "Sistemas NAS",
"createVmSynology": "VM Synology",
"createVmNasOthers": "Outros sistemas NAS",
"createVmSystemWindows": "Sistemas Windows",
"createVmSystemLinux": "Sistemas Linux",
"diskManager": "Gestor de discos",
"diskManagerOverview": "Visão geral",
"diskImportVm": "Importar um disco para uma VM",
"diskImportImageVm": "Importar uma imagem de disco para uma VM",
"diskAddController": "Adicionar um controlador ou dispositivo NVMe a uma VM",
"diskImportLxc": "Importar um disco para um LXC",
"diskFormat": "Formatar ou apagar um disco físico",
"diskSmart": "Estado SMART e testes do disco",
"storageShareManager": "Gestor de armazenamento e partilhas",
"storageShareOverview": "Visão geral",
"hostStorage": "Integração de armazenamento no host",
"hostNfs": "Adicionar uma partilha NFS como armazenamento do Proxmox",
"hostSamba": "Adicionar uma partilha Samba como armazenamento do Proxmox",
"hostIscsi": "Adicionar um destino iSCSI como armazenamento do Proxmox",
"hostLocalDisk": "Adicionar um disco local como armazenamento do Proxmox",
"hostLocalShared": "Criar um diretório partilhado no host",
"lxcMountPoints": "Pontos de montagem LXC (host ↔ CT)",
"lxcNetworkSharing": "Partilhas de rede em LXC",
"lxcNfsClient": "Cliente NFS em LXC",
"lxcSambaClient": "Cliente Samba em LXC",
"lxcNfsServer": "Servidor NFS em LXC",
"lxcSambaServer": "Servidor Samba em LXC",
"network": "Rede",
"networkOverview": "Visão geral",
"networkDiagnostics": "Diagnóstico",
"networkMonitoring": "Ferramentas de monitorização em tempo real",
"networkBridge": "Análise e reparação de bridges de rede",
"networkConfig": "Análise e limpeza da configuração",
"networkPersistent": "Nomes persistentes das interfaces",
"networkBackup": "Cópia de segurança e reinício das interfaces",
"security": "Segurança",
"securityOverview": "Visão geral",
"securityFail2ban": "Fail2Ban",
"securityLynis": "Lynis",
"utilities": "Utilitários",
"utilsOverview": "Visão geral",
"utilsUupDump": "Criação de ISO com UUP Dump",
"utilsSystemUtils": "Instalação de utilitários do sistema",
"utilsSystemUpdate": "Atualização do sistema Proxmox",
"utilsUpgradePve": "Atualizar do PVE 8 para o PVE 9",
"utilsExportVm": "Exportar uma VM para OVA/OVF",
"utilsImportVm": "Importar uma VM a partir de OVA/OVF",
"settingsProxmenux": "Definições do ProxMenux",
"settingsOverview": "Visão geral",
"settingsMonitor": "ProxMenux Monitor",
"settingsBeta": "Alterar o canal de versões",
"settingsVersion": "Mostrar informações da versão",
"settingsUninstall": "Desinstalar o ProxMenux",
"commandsReference": "Referência de comandos",
"commandsOverview": "Visão geral",
"commandsSystem": "Comandos úteis do sistema",
"commandsVmCt": "Gestão de VM e CT",
"commandsStorage": "Armazenamento e discos",
"commandsNetwork": "Comandos de rede",
"commandsUpdates": "Atualizações e pacotes",
"commandsGpu": "Passthrough de GPU",
"commandsZfs": "Gestão do ZFS",
"commandsBackup": "Cópia de segurança e restauro",
"commandsTools": "Ferramentas de sistema para a linha de comandos",
"glossary": "Glossário",
"about": "Sobre o projeto",
"aboutOverview": "Visão geral",
"aboutFaq": "FAQ",
"aboutContributors": "Colaboradores",
"aboutContributing": "Como contribuir",
"aboutCodeOfConduct": "Código de conduta",
"externalRepositories": "Repositórios externos",
"backupRestore": "Cópia de segurança e restauro",
"backupRestoreOverview": "Visão geral",
"backupRestoreHowItWorks": "Como funciona",
"backupRestoreDestinations": "Destinos",
"backupRestoreDestOverview": "Visão geral",
"backupRestoreDestLocal": "Arquivo local",
"backupRestoreDestPbs": "Proxmox Backup Server",
"backupRestoreDestBorg": "Borg",
"backupRestoreCreating": "Criar cópias de segurança",
"backupRestoreJobs": "Tarefas agendadas",
"backupRestoreRestoring": "Restaurar",
"backupRestoreCrossKernel": "Restauro entre versões do kernel",
"backupRestoreGlossary": "Glossário"
}
},
"hero": {
"title": "ProxMenux",
"tagline": "Um menu interativo e um painel web para o Proxmox VE",
"description": "O ProxMenux reúne um menu interativo e um painel web para o Proxmox VE. Execute comandos, scripts e assistentes a partir do terminal ou consulte o estado do host, as métricas e as notificações no navegador.",
"installButton": "Instalar agora",
"whatIsButton": "O que é o ProxMenux?",
"logoAlt": "Logótipo do ProxMenux"
},
"docNav": {
"previous": "Anterior",
"next": "Seguinte"
},
"tocPanel": {
"onThisPage": "Nesta página"
},
"supportProject": {
"heading": "Apoie o projeto!",
"body": "Se o <strong>ProxMenux</strong> lhe é útil, dê-lhe uma ⭐ no GitHub para ajudar outras pessoas a descobri-lo.",
"button": "Dar uma estrela no GitHub"
},
"rssLink": {
"heading": "Acompanhe as novidades!",
"body": "Subscreva o feed RSS para receber as novidades.",
"copy": "Copiar",
"copied": "Copiado!",
"copyTitle": "Copiar o URL do feed RSS",
"openFeed": "Abrir o feed RSS",
"openTitle": "Abrir o feed RSS"
},
"changelog": {
"pageTitle": "Histórico de alterações",
"meta": {
"title": "Histórico de alterações do ProxMenux",
"titleSuffix": "Notas da versão",
"latest": "Última versão",
"mostRecent": "Versão mais recente",
"description": "Notas de versão e histórico de atualizações do ProxMenux, o script com menus para gerir o Proxmox VE.",
"descriptionTail": "Novas funcionalidades, correções de erros, atualizações de segurança, melhorias do ProxMenux Monitor, compatibilidade com fornecedores de IA, reforço de segurança do passthrough de GPU e muito mais.",
"ogDescription": "Notas de versão do ProxMenux.",
"ogTail": "Subscreva o feed RSS ou volte a esta página para consultar novas versões."
}
}
}
+15 -2
View File
@@ -28,7 +28,12 @@
"switcher": "Jazyk",
"en": "English",
"es": "Español",
"sk": "Slovenčina"
"sk": "Slovenčina",
"de": "Deutsch",
"fr": "Français",
"it": "Italiano",
"pt": "Português",
"sv": "Svenska"
},
"resources": {
"documentation": {
@@ -193,7 +198,15 @@
"backupRestoreJobs": "Plánované úlohy",
"backupRestoreRestoring": "Obnova",
"backupRestoreCrossKernel": "Obnova medzi kernelmi",
"backupRestoreGlossary": "Slovník pojmov"
"backupRestoreGlossary": "Slovník pojmov",
"dashboardApps": "Karta Aplikácie",
"auditReport": "Audit a správy",
"auditReportOverview": "Prehľad",
"auditReportAssessment": "Hodnotenie a inventár",
"auditReportPolicy": "Pravidlá",
"auditReportChanges": "Zmeny",
"auditReportReports": "Správy a porovnania",
"auditReportScope": "Rozsah a záruky"
}
},
"hero": {
@@ -98,7 +98,7 @@
],
"sourcesHeading": "Zdroje dostupnej verzie",
"sources": [
"<strong>GitHub repozitár</strong>: najnovšie vydanie alebo značka verejného repozitára <code>vlastník/názov</code>.",
"<strong>GitHub repozitár</strong>: najnovšie vydanie alebo značka verejného repozitára <code>owner/name</code>.",
"<strong>HTTP JSON</strong>: verejný koncový bod a cesta ako <code>data.version</code> alebo <code>releases[0].tag_name</code>.",
"<strong>Docker Hub</strong>: verzované značky filtrované regulárnym výrazom. Živý náhľad pred uložením ukáže skutočné zodpovedajúce značky.",
"Pohyblivé značky ako <code>latest</code>, <code>stable</code> alebo <code>lts</code> neobsahujú verziu. Tieto obrazy sledujte podľa digestu v aktualizáciách Docker obrazov."
@@ -110,7 +110,7 @@
"Nepridávajte <code>pct exec</code>; ProxMenux už vstupuje do kontajnera a príkaz spúšťa ako root."
],
"exampleLead": "Príklad úplného postupu v kontajneri:",
"example": "cd /opt/moja-aplikacia && ./update.sh",
"example": "cd /opt/my-app && ./update.sh",
"callout": "Príkaz ako <code>myapp --version</code> iba číta verziu a nič neaktualizuje. Príkazy sa spúšťajú s oprávneniami správcu a musia sa kontrolovať ako príkazy shellu root."
},
"bulk": {
@@ -140,7 +140,7 @@
"items": [
"Vyberte predvoľbu alebo cron výraz a potom presné ciele: balíky OS, jednotlivé aplikácie, Docker Engine, samostatné jednotky Dockeru alebo skupiny služieb Compose.",
"Oneskorenie po vydaní platí iba pre vybrané aplikácie so sledovaním verzie. Aplikácie bez sledovania spustia aktualizátor pri každom termíne.",
"Stav posledného behu rozlišuje úspech, čiastočné dokončenie, zlyhanie, bezpečnostné pozdržanie a stav bez čakajúcich aktualizácií.",
"Stav posledného behu rozlišuje úspech, čiastočné dokončenie, zlyhanie, bezpečnostné pozastavenie a žiadne čakajúce aktualizácie. Po prvom plánovanom behu otvorí <strong>Aktualizácie → Plánované aktualizácie → Zobraziť záznam</strong> celý výstup aktualizátora a podradených skriptov.",
"Zistené externé plány Proxmox VE Helper-Scripts sa zobrazia samostatne, aby bola viditeľná prekrývajúca sa automatizácia."
],
"callout": "Pred zapnutím plánu otestujte každú vybranú metódu manuálne. Plánovaný príkaz nemôže odpovedať na interaktívne otázky."
+254
View File
@@ -0,0 +1,254 @@
{
"site": {
"name": "ProxMenux",
"tagline": "Interaktiv meny och webbaserad instrumentpanel för Proxmox VE"
},
"nav": {
"home": "Start",
"docs": "Dokumentation",
"documentation": "Dokumentation",
"guides": "Guider",
"changelog": "Ändringslogg",
"github": "GitHub",
"rss": "RSS",
"rssTitle": "RSS-flöde",
"menuOpen": "Öppna meny"
},
"footer": {
"sponsorHeading": "Stöd projektet",
"sponsorBody": "Om du vill stödja projektet.",
"sponsorAlt": "Stöd mig på Ko-fi",
"connectHeading": "Gemenskap",
"connectBody": "Delta i diskussionerna på GitHub för att få hjälp, dela idéer och bidra till projektet. Alla idéer är välkomna!",
"joinDiscussion": "Delta i diskussionen",
"copyrightPrefix": "ProxMenux, ett samarbetsprojekt med öppen källkod av",
"copyrightSuffix": "."
},
"language": {
"switcher": "Språk",
"en": "English",
"es": "Español",
"sk": "Slovenčina",
"de": "Deutsch",
"fr": "Français",
"it": "Italiano",
"pt": "Português",
"sv": "Svenska"
},
"resources": {
"documentation": {
"title": "Dokumentation",
"description": "Systembeskrivning och användarguider"
},
"changelog": {
"title": "Ändringslogg",
"description": "Information om de senaste uppdateringarna"
},
"guides": {
"title": "Guider",
"description": "Stegvisa instruktioner och guider för vanliga uppgifter"
},
"github": {
"title": "GitHub-arkiv",
"description": "Utforska källkoden."
}
},
"docSidebar": {
"documentation": "Dokumentation",
"items": {
"introduction": "Introduktion",
"installation": "Installation",
"proxmenuxMonitor": "ProxMenux Monitor",
"monitorOverview": "Översikt",
"architecture": "Arkitektur",
"accessAuth": "Åtkomst och autentisering",
"dashboard": "Instrumentpanel",
"dashboardSystemOverview": "Fliken Systemöversikt",
"dashboardApps": "Fliken Program",
"dashboardStorage": "Fliken Lagring",
"dashboardNetwork": "Fliken Nätverk",
"dashboardVmsLxcs": "Fliken VM och LXC",
"dashboardVmsLxcsApp": "Program",
"dashboardVmsLxcsUpdates": "Uppdateringar",
"dashboardHardware": "Fliken Maskinvara",
"dashboardSystemLogs": "Fliken Systemloggar",
"dashboardTerminal": "Fliken Terminal",
"dashboardSecurity": "Fliken Säkerhet",
"dashboardSettings": "Fliken Inställningar",
"healthMonitor": "Systemövervakning",
"auditReport": "Granskning och rapporter",
"auditReportOverview": "Översikt",
"auditReportAssessment": "Bedömning och inventering",
"auditReportPolicy": "Policy",
"auditReportChanges": "Ändringar",
"auditReportReports": "Rapporter och jämförelser",
"auditReportScope": "Omfattning och garantier",
"notifications": "Aviseringar",
"aiAssistant": "AI-assistent",
"apiReference": "API-referens",
"integrations": "Integrationer",
"ociManager": "OCI manager Apps",
"ociOverview": "Översikt",
"ociArchitecture": "Så anpassas en OCI-avbildning",
"ociCustomImage": "Avbildning utanför katalogen",
"ociStorageNetwork": "Data, sökvägar och nätverk",
"ociHardware": "Enheter och acceleration",
"ociStacks": "Program med flera containrar",
"ociLifecycle": "Installera, uppdatera och ändra",
"ociMonitor": "I ProxMenux Monitor",
"proxmenuxScripts": "ProxMenux Scripts",
"postInstallScript": "Skript efter installationen",
"postInstallOverview": "Översikt",
"postInstallAutomated": "Automatiskt",
"postInstallCustomizable": "Anpassningsbart",
"postInstallBasicSettings": "Grundinställningar",
"postInstallSystem": "System",
"postInstallVirtualization": "Virtualisering",
"postInstallNetwork": "Nätverk",
"postInstallStorage": "Lagring",
"postInstallSecurity": "Säkerhet",
"postInstallCustomization": "Anpassning",
"postInstallMonitoring": "Övervakning",
"postInstallPerformance": "Prestanda",
"postInstallOptional": "Valfritt",
"postInstallUpdates": "Installera tillgängliga uppdateringar",
"postInstallUninstall": "Ta bort optimeringar",
"gpusCoralTpu": "GPU och Coral TPU",
"nvidiaHost": "Installera NVIDIA-drivrutiner på värden",
"coralHost": "Installera Coral TPU på värden",
"addGpuLxc": "Gör en GPU tillgänglig i en LXC",
"addCoralLxc": "Gör Coral TPU tillgänglig i en LXC",
"addGpuVm": "Tilldela en GPU till en VM (passthrough)",
"switchGpuMode": "Byt GPU-läge (VM ↔ LXC)",
"createVm": "Skapa en VM",
"createVmOverview": "Översikt",
"createVmSystemNas": "NAS-system",
"createVmSynology": "Synology-VM",
"createVmNasOthers": "Andra NAS-system",
"createVmSystemWindows": "Windows-system",
"createVmSystemLinux": "Linux-system",
"diskManager": "Diskhantering",
"diskManagerOverview": "Översikt",
"diskImportVm": "Importera en disk till en VM",
"diskImportImageVm": "Importera en diskavbildning till en VM",
"diskAddController": "Lägg till en styrenhet eller NVMe-enhet i en VM",
"diskImportLxc": "Importera en disk till en LXC",
"diskFormat": "Formatera eller radera en fysisk disk",
"diskSmart": "SMART-status och disktester",
"storageShareManager": "Hantering av lagring och delningar",
"storageShareOverview": "Översikt",
"hostStorage": "Anslut lagring till värden",
"hostNfs": "Lägg till en NFS-delning som Proxmox-lagring",
"hostSamba": "Lägg till en Samba-delning som Proxmox-lagring",
"hostIscsi": "Lägg till ett iSCSI-mål som Proxmox-lagring",
"hostLocalDisk": "Lägg till en lokal disk som Proxmox-lagring",
"hostLocalShared": "Skapa en delad katalog på värden",
"lxcMountPoints": "LXC-monteringspunkter (värd ↔ CT)",
"lxcNetworkSharing": "Nätverksdelning i LXC",
"lxcNfsClient": "NFS-klient i LXC",
"lxcSambaClient": "Samba-klient i LXC",
"lxcNfsServer": "NFS-server i LXC",
"lxcSambaServer": "Samba-server i LXC",
"network": "Nätverk",
"networkOverview": "Översikt",
"networkDiagnostics": "Diagnostik",
"networkMonitoring": "Verktyg för övervakning i realtid",
"networkBridge": "Analysera och reparera nätverksbryggor",
"networkConfig": "Analysera och rensa konfigurationen",
"networkPersistent": "Beständiga gränssnittsnamn",
"networkBackup": "Säkerhetskopiera och starta om gränssnitt",
"security": "Säkerhet",
"securityOverview": "Översikt",
"securityFail2ban": "Fail2Ban",
"securityLynis": "Lynis",
"utilities": "Verktyg",
"utilsOverview": "Översikt",
"utilsUupDump": "Skapa ISO med UUP Dump",
"utilsSystemUtils": "Installera systemverktyg",
"utilsSystemUpdate": "Uppdatera Proxmox-systemet",
"utilsUpgradePve": "Uppgradera från PVE 8 till PVE 9",
"utilsExportVm": "Exportera en VM till OVA/OVF",
"utilsImportVm": "Importera en VM från OVA/OVF",
"settingsProxmenux": "ProxMenux-inställningar",
"settingsOverview": "Översikt",
"settingsMonitor": "ProxMenux Monitor",
"settingsBeta": "Byt versionskanal",
"settingsVersion": "Visa versionsinformation",
"settingsUninstall": "Avinstallera ProxMenux",
"commandsReference": "Kommandoreferens",
"commandsOverview": "Översikt",
"commandsSystem": "Användbara systemkommandon",
"commandsVmCt": "Hantera VM och CT",
"commandsStorage": "Lagring och diskar",
"commandsNetwork": "Nätverkskommandon",
"commandsUpdates": "Uppdateringar och paket",
"commandsGpu": "GPU-passthrough",
"commandsZfs": "Hantera ZFS",
"commandsBackup": "Säkerhetskopiering och återställning",
"commandsTools": "Systemverktyg för kommandoraden",
"glossary": "Ordlista",
"about": "Om projektet",
"aboutOverview": "Översikt",
"aboutFaq": "FAQ",
"aboutContributors": "Medverkande",
"aboutContributing": "Bidra",
"aboutCodeOfConduct": "Uppförandekod",
"externalRepositories": "Externa arkiv",
"backupRestore": "Säkerhetskopiering och återställning",
"backupRestoreOverview": "Översikt",
"backupRestoreHowItWorks": "Så fungerar det",
"backupRestoreDestinations": "Mål",
"backupRestoreDestOverview": "Översikt",
"backupRestoreDestLocal": "Lokalt arkiv",
"backupRestoreDestPbs": "Proxmox Backup Server",
"backupRestoreDestBorg": "Borg",
"backupRestoreCreating": "Skapa säkerhetskopior",
"backupRestoreJobs": "Schemalagda jobb",
"backupRestoreRestoring": "Återställning",
"backupRestoreCrossKernel": "Återställning mellan kärnversioner",
"backupRestoreGlossary": "Ordlista"
}
},
"hero": {
"title": "ProxMenux",
"tagline": "En interaktiv meny och webbaserad instrumentpanel för Proxmox VE",
"description": "ProxMenux kombinerar en interaktiv meny med en webbaserad instrumentpanel för Proxmox VE. Kör kommandon, skript och guidade steg från terminalmenyn, eller följ värdens status, mätvärden och aviseringar i webbläsaren.",
"installButton": "Installera nu",
"whatIsButton": "Vad är ProxMenux?",
"logoAlt": "ProxMenux-logotyp"
},
"docNav": {
"previous": "Föregående",
"next": "Nästa"
},
"tocPanel": {
"onThisPage": "På den här sidan"
},
"supportProject": {
"heading": "Stöd projektet!",
"body": "Om du har nytta av <strong>ProxMenux</strong> kan du ge projektet en ⭐ på GitHub så att fler upptäcker det.",
"button": "Ge en stjärna på GitHub"
},
"rssLink": {
"heading": "Följ uppdateringarna!",
"body": "Prenumerera på vårt RSS-flöde för att få information om nyheter.",
"copy": "Kopiera",
"copied": "Kopierat!",
"copyTitle": "Kopiera RSS-adressen",
"openFeed": "Öppna RSS-flödet",
"openTitle": "Öppna RSS-flödet"
},
"changelog": {
"pageTitle": "Ändringslogg",
"meta": {
"title": "Ändringslogg för ProxMenux",
"titleSuffix": "Versionsinformation",
"latest": "Senaste",
"mostRecent": "Senaste versionen",
"description": "Versionsinformation och uppdateringshistorik för ProxMenux, det menystyrda skriptet för administration av Proxmox VE.",
"descriptionTail": "Nya funktioner, felrättningar, säkerhetsuppdateringar, förbättringar i ProxMenux Monitor, stöd för AI-leverantörer, säkrare GPU-passthrough och mer.",
"ogDescription": "Versionsinformation för ProxMenux.",
"ogTail": "Prenumerera via RSS eller besök sidan igen för att se nya versioner."
}
}
}
+2 -2
View File
@@ -4,10 +4,10 @@
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build && pagefind --site out --output-path public/pagefind && cp -r public/pagefind out/pagefind",
"build": "next build && node scripts/localize-export.mjs && pagefind --site out --output-path public/pagefind && cp -r public/pagefind out/pagefind",
"start": "next start",
"lint": "next lint",
"index": "pagefind --site out --output-path public/pagefind && cp -r public/pagefind out/pagefind"
"index": "node scripts/localize-export.mjs && pagefind --site out --output-path public/pagefind && cp -r public/pagefind out/pagefind"
},
"dependencies": {
"@hookform/resolvers": "^3.9.1",
+32
View File
@@ -0,0 +1,32 @@
// Next's shared root layout cannot read its nested [locale] parameter.
// Set the static document language before Pagefind indexes the export, so
// search and no-JavaScript readers see the same locale as the hydrated app.
import { readdir, readFile, writeFile } from 'node:fs/promises'
import { join } from 'node:path'
async function htmlFiles(directory) {
const entries = await readdir(directory, { withFileTypes: true })
const files = await Promise.all(entries.map(entry => {
const path = join(directory, entry.name)
return entry.isDirectory() ? htmlFiles(path) : entry.isFile() && entry.name.endsWith('.html') ? [path] : []
}))
return files.flat()
}
let count = 0
for (const entry of await readdir('out', { withFileTypes: true })) {
if (!entry.isDirectory() || !/^[a-z]{2}(?:-[a-z0-9]+)?$/.test(entry.name)) continue
const locale = entry.name
for (const file of await htmlFiles(join('out', locale))) {
const original = await readFile(file, 'utf8')
const updated = original.replace(/<html\b([^>]*)>/i, (tag, attributes) => {
const next = /\blang\s*=\s*["'][^"']*["']/i.test(attributes)
? attributes.replace(/\blang\s*=\s*["'][^"']*["']/i, `lang="${locale}"`)
: `${attributes} lang="${locale}"`
return `<html${next}>`
})
if (updated !== original) await writeFile(file, updated, 'utf8')
count += 1
}
}
console.log(`Static document language verified for ${count} localized pages.`)