overhaul app tracking and update orchestration

- Generate and ship a verified 389-app tracking catalog with 23 runtime overrides, fallback detectors, ports, logos, and Docker Hub tag previews.
- Support modern Proxmox VE Helper-Scripts markers, historical installations, and official or manual app deployments.
- Rework the LXC App and Updates tabs with cached suggestions, explicit discovery, version tracking, web links, custom updaters, and complete i18n.
- Add independent OS, app, Docker Engine, Docker image, bulk, and scheduled update targets.
- Add digest-based Docker inventory, Compose dependency grouping, safe standalone-container recreation with rollback, and package-scoped Docker Engine updates.
- Refresh per-LXC caches after lifecycle and update tasks, then emit idempotent notifications based on the verified final state.
- Harden Coral USB recovery by removing orphaned gasket DKMS registrations and validating that dpkg is healthy before reporting success.
This commit is contained in:
MacRimi
2026-08-23 12:43:03 +02:00
parent 7244201810
commit 0251f77331
27 changed files with 11631 additions and 893 deletions
+108 -9
View File
@@ -1163,7 +1163,15 @@
"targetBoth": "SO + aplicación",
"lastRun": "Última ejecución: {date}",
"runSuccess": "✓ éxito",
"runPartial": "completada parcialmente",
"runFailed": "✗ falló",
"runDeferred": "retenida por seguridad",
"runSkipped": "nada pendiente",
"releaseDelaySummary": "espera de {days} día(s)",
"releaseDelayLabel": "Esperar tras una nueva versión de app",
"releaseDelayNone": "Sin periodo de espera",
"releaseDelayDays": "Esperar {days} día(s)",
"releaseDelayHelp": "Solo se aplica a las apps seleccionadas con seguimiento de versión. Sus versiones pendientes deben tener esta antigüedad; las apps sin seguimiento ejecutan su actualizador en cada programación.",
"notScheduled": "No programado",
"frequency": "Frecuencia",
"cronExpression": "expresión cron",
@@ -1172,6 +1180,11 @@
"targetOptionOs": "Solo paquetes de sistema operativo",
"targetOptionApp": "Sólo aplicación",
"targetOptionBoth": "SO + aplicación",
"dockerComposeTarget": "Docker Compose · {project}",
"dockerContainerTarget": "Contenedor Docker · {container}",
"dockerEngineTarget": "Motor de Docker",
"noTargets": "Ningún objetivo seleccionado",
"selectAtLeastOne": "Seleccione al menos un objetivo de actualización.",
"deleteButton": "Eliminar horario",
"deleteConfirm": "¿Eliminar las actualizaciones programadas para este contenedor? Se mantienen los valores predeterminados de aplicación (copia de seguridad + reinicio)."
},
@@ -1217,7 +1230,7 @@
"osPlusApp": "SO + actualizaciones {appName}",
"osPlusApps": "Actualizaciones de SO y aplicaciones",
"noUpdateMethodTitle": "No hay ningún método de actualización disponible",
"noUpdateMethodBody": "No hay ningún método de actualización disponible. Actualice desde la propia aplicación o configure un comando personalizado en la pestaña Aplicación.",
"noUpdateMethodBody": "No se ha identificado un método de actualización para esta aplicación. Añada un comando de actualización personalizado.",
"ociImmutableTitle": "Contenedor de imágenes OCI",
"ociImmutableBody": "Los paquetes del sistema operativo se integran en el momento de crear la imagen y no se pueden actualizar en el lugar. Aplique las actualizaciones manualmente o reinstálelas con una imagen más nueva.",
"hideNoticeButton": "Ocultar este aviso para esta aplicación",
@@ -1229,7 +1242,8 @@
"securityUpdatesLabel": "actualizaciones de seguridad",
"applicationDefaultName": "Solicitud",
"installedLabel": "instalado",
"upToDateAtLabel": "Al día en",
"upToDateAtLabel": "Actualizada en la versión",
"versionLabel": "versión {version}",
"versionTrackingPending": "Seguimiento de versiones pendiente: la próxima comprobación programada mostrará las versiones instalada y disponible.",
"customCommandTitle": "Comando de actualización personalizado",
"customCommandBody": "Ejecute un comando de shell definido por el usuario para actualizar esta aplicación dentro del contenedor.",
@@ -1238,6 +1252,7 @@
"hideNoticeAction": "Ocultar este aviso para {appName}",
"detectedByPrefix": "Detectado por",
"editApp": "Editar",
"configureUpdater": "Configurar",
"alsoDetectedTitle": "También detectado en este contenedor:",
"detectedInline": "· detectado por {method}",
"customCommandLabel": "Comando de actualización personalizado",
@@ -1245,9 +1260,9 @@
"removeButton": "Eliminar",
"cancelButton": "Cancelar",
"saveButton": "Guardar",
"editCommandButton": "Editar comando",
"wireUpCommandButton": "Agregar comando de actualización personalizado",
"versionTrackingPendingShort": "Seguimiento de versión pendiente.",
"versionTrackingNotConfigured": "El seguimiento de versión no está configurado.",
"managedByOsPackages": "Esta aplicación se actualiza mediante la acción de paquetes del SO.",
"noMethodBody": "No hay ningún método de actualización disponible. Actualice desde la propia aplicación o conecte un comando personalizado que ProxMenux ejecutará dentro del contenedor.",
"noMethodHideBody": "Esta aplicación no tiene ningún método de actualización registrado. Configure uno desde la pestaña Aplicación o ignore este aviso.",
"hideForApp": "Ocultar aviso para {appName}",
@@ -1266,15 +1281,59 @@
"noManagedUpdateInfo": "Aún no hay información de actualización: verifique desde Seguridad → Secure Gateway.",
"ociTitle": "Contenedor de imágenes OCI",
"ociBody": "Este contenedor se creó a partir de una imagen OCI (Docker). La gestión de actualizaciones para contenedores OCI viene con la próxima función de instalación de OCI: las actualizaciones reconstruirán el contenedor a partir de una etiqueta de imagen más nueva en lugar de aplicar parches a los paquetes internos.",
"helperNotUpdateable": "El registro de scripts comunitarios marca esta aplicación como no actualizable.",
"helperDetectedTitle": "Detectado un actualizador de scripts auxiliares",
"helperDetectedBody": "La aplicación manual es la más segura.",
"dockerImagesTitle": "Imágenes Docker",
"dockerAppTitle": "Docker",
"dockerImagesSubheading": "Imágenes",
"dockerImagesReadOnly": "Las etiquetas se comparan mediante el digest del registro. Los servicios Compose pueden descargar la imagen y recrearse desde su proyecto declarado.",
"dockerEngineManagedByOs": "Docker Engine {version} está gestionado por paquetes y se actualiza mediante la acción de paquetes del SO anterior.",
"dockerEngineSubheading": "Motor",
"dockerEngineDetected": "Docker Engine {version} detectado",
"dockerEngineUpdateHelp": "Actualiza únicamente los paquetes Docker instalados y sus dependencias necesarias. No actualiza otros paquetes del SO ni recrea contenedores.",
"updateDockerEngineOnly": "Actualizar Docker Engine",
"adguardWebUpdateOnly": "Esta instalación de AdGuard Home se actualiza desde su propia interfaz web.",
"openAdguard": "Abrir AdGuard Home",
"updateDockerImage": "Actualizar imagen",
"recreateStandaloneContainer": "Actualizar {container}",
"standaloneRecreatePending": "Estos contenedores independientes requieren una recreación protegida: {names}",
"noDockerImages": "Docker está instalado, pero no se encontraron imágenes con etiqueta.",
"dockerInventoryStarting": "Esperando a que Docker termine de arrancar…",
"dockerInventoryUnavailable": "No se pudo leer el inventario de Docker. Vuelva a comprobarlo cuando Docker esté disponible.",
"usedByContainers": "Usada por: {names}",
"imageUpdateAvailable": "Nueva imagen disponible",
"imageUpToDate": "Actualizada",
"imageInstalledTag": "etiqueta instalada",
"imageDigestUnknown": "Digest no disponible",
"dockerPendingSummary": "Se detectaron {count} actualización(es) de imágenes Docker. Actualízalas con su flujo de Docker o Compose.",
"postApplyChecking": "Comprobando resultado de la actualización…",
"postApplyAllOk": "{count} paquete(s) aplicados correctamente — nada pendiente.",
"postApplyNothingPending": "Nada pendiente — todo actualizado.",
"postApplyPartial": "{pending} paquete(s) siguen pendientes tras la ejecución.",
"postApplyPartialSubline": "{applied} aplicados. Algunas actualizaciones no finalizaron — revisa la salida del terminal."
},
"bulkUpdate": {
"title": "Actualización en bloque",
"description": "Configure una sola acción para actualizar el SO y los métodos que seleccione en este contenedor.",
"loading": "Cargando configuración…",
"notConfigured": "No configurada.",
"configure": "Configurar",
"edit": "Editar",
"apply": "Aplicar actualizaciones",
"osTarget": "SO",
"osRequired": "Obligatorio en una actualización en bloque.",
"includesDependencies": "Incluye también las dependencias declaradas: {names}",
"noMethod": "No hay ningún método de actualización ejecutable disponible.",
"staleTarget": "Esta selección ya no está disponible. Elimínela antes de guardar.",
"dockerInventoryPending": "Esperando al inventario de imágenes Docker…",
"missingDockerTarget": "Imagen Docker no disponible",
"selectAtLeastOne": "Seleccione al menos un método de actualización además del SO.",
"cancel": "Cancelar",
"save": "Guardar",
"delete": "Eliminar configuración",
"deleteConfirm": "¿Eliminar esta configuración de actualización en bloque?",
"saveFailed": "No se pudo guardar la configuración de actualización en bloque.",
"deleteFailed": "No se pudo eliminar la configuración de actualización en bloque.",
"planFailed": "No se pudo preparar la actualización en bloque. Edite la configuración y revise los métodos no disponibles."
},
"appEditor": {
"closePanel": "Cerrar panel",
"cancelButton": "Cancelar",
@@ -1284,6 +1343,17 @@
"hiddenBadge": "Actualmente oculto: volverá a aparecer en la lista de detección",
"registerDifferent": "Registrar una aplicación diferente",
"detectedInContainer": "Detectado en este contenedor",
"versionDetected": "Versión {version} detectada en este contenedor",
"legacyDetectorUsed": "Detectada mediante un fallback de compatibilidad antiguo",
"dockerImagesTitle": "Actualizaciones de imágenes Docker",
"dockerImagesHelp": "Comprueba cada imagen local por separado del motor Docker comparando digests inmutables del registro.",
"refreshDockerImages": "Comprobar ahora",
"noDockerImages": "No se encontraron imágenes Docker con etiqueta",
"usedByContainers": "Usada por: {names}",
"imageUpdateAvailable": "Nueva imagen disponible",
"imageUpToDate": "Actualizada",
"imageDigestUnknown": "Digest no disponible",
"dockerReadOnlyNote": "Comprobación de solo lectura: no descarga imágenes ni reinicia contenedores.",
"installedManaged": "Instalado y administrado por ProxMenux",
"nameLabel": "Nombre",
"installedViaLabel": "Instalado a través de",
@@ -1340,6 +1410,17 @@
"jsonPathPlaceholder": "por ejemplo, data.version o lanzamientos[0].tag_name",
"dockerImageLabel": "Imagen de Docker Hub",
"dockerImagePlaceholder": "por ejemplo, linuxserver/plex o nginx",
"dockerVersionedTagsHelp": "Úsalo solo con etiquetas versionadas. Para latest, stable o lts, usa Actualizaciones de imágenes Docker, que compara digests.",
"dockerPresetSemver": "Solo SemVer",
"dockerPresetSemverSuffix": "SemVer + sufijo",
"dockerTagFilterHelp": "Filtra las etiquetas reales antes de que ProxMenux elija la versión más alta.",
"dockerTagPreviewLabel": "Vista previa de etiquetas reales",
"dockerTagPreviewCount": "{matched} coinciden de {scanned}",
"dockerTagPreviewLoading": "Consultando Docker Hub…",
"dockerTagPreviewFailed": "No se pudieron consultar las etiquetas de Docker Hub",
"dockerTagPreviewEmpty": "Ninguna etiqueta real coincide con este filtro.",
"dockerMovingTag": "etiqueta móvil",
"dockerMovingTagHelp": "Las etiquetas móviles no contienen una versión. Contrólalas por digest en Actualizaciones de imágenes Docker.",
"tagRegexLabel": "Etiquetar expresiones regulares (con grupo de captura)",
"tagRegexPlaceholder": "por ejemplo, v?(\\d+\\.\\d+\\.\\d+)",
"tagRegexBare": "v?(\\d+\\.\\d+\\.\\d+)",
@@ -1375,7 +1456,14 @@
"registerCustom": "Registrar una aplicación personalizada",
"noAppsTitle": "No hay aplicaciones registradas",
"noAppsBody": "Registre las aplicaciones que se ejecutan en este contenedor. Obtendrá enlaces web y, opcionalmente, seguimiento de versiones disponibles y notificaciones de nuevos lanzamientos.",
"registerApplication": "Solicitud de registro",
"registerApplication": "Registrar aplicación",
"searchApplications": "Buscar aplicaciones",
"searchingApplications": "Buscando aplicaciones…",
"noApplicationsDetected": "No se han detectado aplicaciones.",
"noNewApplicationsDetected": "No se han detectado aplicaciones nuevas.",
"oneNewApplicationDetected": "Se ha detectado una aplicación nueva.",
"newApplicationsDetected": "Se han detectado {count} aplicaciones nuevas.",
"detectionFailed": "No se pudo completar la búsqueda de aplicaciones",
"hiddenSuffix": "{count} oculto",
"confirmHide": "¿Ocultar la detección \"{name}\" permanentemente en este contenedor?\n\nPara recuperarlo más tarde, haga clic en \"Registrar una aplicación diferente\"; la lista oculta aparece allí con una opción de Restaurar.",
"saveFailed": "Error al guardar",
@@ -1386,6 +1474,13 @@
"binaryArgsHintGrafana": "Grafana necesita",
"loadFailed": "No se pudo cargar la configuración de la aplicación",
"checkFailed": "Verificación fallida",
"testDetectorButton": "Probar detector",
"testingDetectorButton": "Probando detector…",
"detectorTestTitle": "Resultado de la prueba del detector",
"detectorTestNotSaved": "Solo borrador · sin guardar",
"detectorTestNoVersion": "No se detectó ninguna versión",
"detectorTestNoUpstream": "No hay una fuente upstream configurada",
"detectorTestFailed": "La prueba del detector ha fallado",
"deleteFailed": "Error al eliminar",
"dismissFailed": "No se pudo descartar la detección",
"restoreFailed": "No se pudo restaurar la detección",
@@ -1402,6 +1497,10 @@
"webLinks": "Enlaces web",
"addPort": "Agregar puerto",
"detectedPorts": "Puertos detectados en el contenedor: haga clic para agregar:",
"dockerPublishedServicesTitle": "Servicios Docker con puertos publicados",
"dockerPublishedServicesHelp": "Elige únicamente los puertos que ofrecen una interfaz web. ProxMenux no registra estos contenedores como aplicaciones LXC independientes.",
"dockerPublishedAdd": "Agregar enlace",
"dockerPublishedPort": "puerto {containerPort} del contenedor → {hostPort} en el LXC",
"noWebPorts": "No hay puertos web escuchando. Utilice Agregar puerto si aún desea crear un enlace manualmente.",
"trackUpstream": "Seguir versión disponible (opcional)",
"trackOff": "Desactivado: solo enlace",
@@ -1419,7 +1518,7 @@
"checkButton": "Controlar",
"editFieldsButton": "Editar campos",
"alsoDetectedContainer": "También detectado en este contenedor.",
"addAnotherApplication": "Agregar otra aplicación",
"addAnotherApplication": "Registrar otra aplicación",
"doneButton": "Hecho",
"editButton": "Editar",
"notificationsEnabled": "Notificaciones de actualización activas — clic para silenciar",