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
+107 -8
View File
@@ -1163,7 +1163,15 @@
"targetBoth": "Système d'exploitation + application",
"lastRun": "Dernière exécution : {date}",
"runSuccess": "✓ succès",
"runPartial": "partiellement terminée",
"runFailed": "✗ échoué",
"runDeferred": "reportée par sécurité",
"runSkipped": "rien en attente",
"releaseDelaySummary": "délai de {days} jour(s)",
"releaseDelayLabel": "Attendre après une nouvelle version d’application",
"releaseDelayNone": "Aucun délai d’attente",
"releaseDelayDays": "Attendre {days} jour(s)",
"releaseDelayHelp": "S’applique uniquement aux applications sélectionnées dont les versions sont suivies. Leurs versions en attente doivent avoir cet âge ; les applications sans suivi exécutent leur programme de mise à jour à chaque programmation.",
"notScheduled": "Non programmé",
"frequency": "Fréquence",
"cronExpression": "Expression Cron",
@@ -1172,6 +1180,11 @@
"targetOptionOs": "Packages de système d'exploitation uniquement",
"targetOptionApp": "Candidature uniquement",
"targetOptionBoth": "Système d'exploitation + application",
"dockerComposeTarget": "Docker Compose · {project}",
"dockerContainerTarget": "Conteneur Docker · {container}",
"dockerEngineTarget": "Moteur Docker",
"noTargets": "Aucune cible sélectionnée",
"selectAtLeastOne": "Sélectionnez au moins une cible de mise à jour.",
"deleteButton": "Supprimer le planning",
"deleteConfirm": "Supprimer les mises à jour planifiées pour ce conteneur ? Les valeurs par défaut appliquées (sauvegarde + redémarrage) sont conservées."
},
@@ -1217,7 +1230,7 @@
"osPlusApp": "Mises à jour du système d'exploitation + {appName}",
"osPlusApps": "Mises à jour du système d'exploitation et des applications",
"noUpdateMethodTitle": "Aucune méthode de mise à jour disponible",
"noUpdateMethodBody": "Aucune méthode de mise à jour disponible. Mettez à jour depuis l'application elle-même ou définissez une commande personnalisée dans l'onglet Application.",
"noUpdateMethodBody": "Aucune méthode de mise à jour n’a été identifiée pour cette application. Ajoutez une commande de mise à jour personnalisée.",
"ociImmutableTitle": "Conteneur d'images OCI",
"ociImmutableBody": "Les packages du système d'exploitation sont intégrés au moment de la création de l'image et ne peuvent pas être mis à jour sur place. Appliquez les mises à jour manuellement ou réinstallez avec une image plus récente.",
"hideNoticeButton": "Masquer cet avis pour cette application",
@@ -1230,6 +1243,7 @@
"applicationDefaultName": "Application",
"installedLabel": "installé",
"upToDateAtLabel": "À jour à",
"versionLabel": "version {version}",
"versionTrackingPending": "Suivi des versions en attente : la prochaine vérification programmée indiquera les versions installée et disponible.",
"customCommandTitle": "Commande de mise à jour personnalisée",
"customCommandBody": "Exécutez une commande shell définie par l'utilisateur pour mettre à jour cette application dans le conteneur.",
@@ -1238,6 +1252,7 @@
"hideNoticeAction": "Masquer cet avis pour {appName}",
"detectedByPrefix": "Détecté par",
"editApp": "Modifier",
"configureUpdater": "Configurer",
"alsoDetectedTitle": "Également détecté dans ce conteneur :",
"detectedInline": "· détecté par {method}",
"customCommandLabel": "Commande de mise à jour personnalisée",
@@ -1245,9 +1260,9 @@
"removeButton": "Retirer",
"cancelButton": "Annuler",
"saveButton": "Sauvegarder",
"editCommandButton": "Modifier la commande",
"wireUpCommandButton": "Ajouter une commande de mise à jour personnalisée",
"versionTrackingPendingShort": "Suivi de version en attente.",
"versionTrackingNotConfigured": "Le suivi des versions n’est pas configuré.",
"managedByOsPackages": "Cette application est mise à jour par l’action sur les paquets du système.",
"noMethodBody": "Aucune méthode de mise à jour disponible. Mettez à jour à partir de l'application elle-même ou connectez une commande personnalisée que ProxMenux exécutera à l'intérieur du conteneur.",
"noMethodHideBody": "Cette application n'a aucune méthode de mise à jour enregistrée. Définissez-en un dans l’onglet Application ou ignorez cet avis.",
"hideForApp": "Masquer l'avis pour {appName}",
@@ -1266,15 +1281,59 @@
"noManagedUpdateInfo": "Aucune information de mise à jour pour l'instant - vérifiez depuis Sécurité → Secure Gateway.",
"ociTitle": "Conteneur d'images OCI",
"ociBody": "Ce conteneur a été créé à partir d'une image OCI (Docker). La gestion des mises à jour pour les conteneurs OCI est fournie avec la prochaine fonctionnalité d'installation OCI : les mises à jour reconstruiront le conteneur à partir d'une balise d'image plus récente plutôt que de corriger les packages à l'intérieur.",
"helperNotUpdateable": "Le registre des scripts de communauté marque cette application comme non modifiable.",
"helperDetectedTitle": "Détection d'un programme de mise à jour des scripts d'assistance",
"helperDetectedBody": "L’application manuelle est la plus sûre.",
"dockerImagesTitle": "Images Docker",
"dockerAppTitle": "Docker",
"dockerImagesSubheading": "Images",
"dockerImagesReadOnly": "Les tags sont comparés par digest de registre. Les services Compose peuvent télécharger l’image et être recréés depuis leur projet déclaré.",
"dockerEngineManagedByOs": "Docker Engine {version} est géré par paquets et mis à jour par l’action des paquets du SE ci-dessus.",
"dockerEngineSubheading": "Moteur",
"dockerEngineDetected": "Docker Engine {version} détecté",
"dockerEngineUpdateHelp": "Met à jour uniquement les paquets Docker installés et les dépendances nécessaires. Les autres paquets du système et les conteneurs ne sont pas modifiés.",
"updateDockerEngineOnly": "Mettre à jour Docker Engine",
"adguardWebUpdateOnly": "Cette installation d’AdGuard Home se met à jour depuis sa propre interface web.",
"openAdguard": "Ouvrir AdGuard Home",
"updateDockerImage": "Mettre à jour l’image",
"recreateStandaloneContainer": "Mettre à jour {container}",
"standaloneRecreatePending": "Les conteneurs autonomes nécessitent une recréation protégée : {names}",
"noDockerImages": "Docker est installé, mais aucune image taguée n’a été trouvée.",
"dockerInventoryStarting": "En attente de la fin du démarrage de Docker…",
"dockerInventoryUnavailable": "L’inventaire Docker n’a pas pu être lu. Vérifiez à nouveau lorsque Docker sera disponible.",
"usedByContainers": "Utilisée par : {names}",
"imageUpdateAvailable": "Nouvelle image disponible",
"imageUpToDate": "À jour",
"imageInstalledTag": "tag installé",
"imageDigestUnknown": "Digest indisponible",
"dockerPendingSummary": "{count} mise(s) à jour d’image Docker détectée(s). Utilisez le flux Docker ou Compose correspondant.",
"postApplyChecking": "Vérification du résultat de la mise à jour…",
"postApplyAllOk": "{count} package(s) appliqué(s) avec succès – rien en attente.",
"postApplyNothingPending": "Rien en attente – tout est à jour.",
"postApplyPartial": "{pending} package(s) toujours en attente après l'exécution.",
"postApplyPartialSubline": "{applied} appliqué.Certaines mises à jour n'ont pas été terminées – consultez la sortie du terminal ci-dessus."
},
"bulkUpdate": {
"title": "Mise à jour groupée",
"description": "Configurez une seule action pour mettre à jour le système et les méthodes sélectionnées dans ce conteneur.",
"loading": "Chargement de la configuration…",
"notConfigured": "Non configurée.",
"configure": "Configurer",
"edit": "Modifier",
"apply": "Appliquer les mises à jour",
"osTarget": "Système",
"osRequired": "Obligatoire pour une mise à jour groupée.",
"includesDependencies": "Inclut aussi les dépendances déclarées : {names}",
"noMethod": "Aucune méthode de mise à jour exécutable n’est disponible.",
"staleTarget": "Cette sélection n’est plus disponible. Retirez-la avant d’enregistrer.",
"dockerInventoryPending": "En attente de l’inventaire des images Docker…",
"missingDockerTarget": "Image Docker indisponible",
"selectAtLeastOne": "Sélectionnez au moins une cible de mise à jour en plus du système.",
"cancel": "Annuler",
"save": "Enregistrer",
"delete": "Supprimer la configuration",
"deleteConfirm": "Supprimer cette configuration de mise à jour groupée ?",
"saveFailed": "Impossible d’enregistrer la configuration de mise à jour groupée.",
"deleteFailed": "Impossible de supprimer la configuration de mise à jour groupée.",
"planFailed": "Impossible de préparer la mise à jour groupée. Vérifiez les méthodes indisponibles."
},
"appEditor": {
"closePanel": "Fermer le panneau",
"cancelButton": "Annuler",
@@ -1284,6 +1343,17 @@
"hiddenBadge": "Actuellement masqué — réapparaîtra dans la liste de détection",
"registerDifferent": "Enregistrez une autre application",
"detectedInContainer": "Détecté sur ce conteneur",
"versionDetected": "Version {version} détectée dans ce conteneur",
"legacyDetectorUsed": "Détectée avec une solution de compatibilité ancienne",
"dockerImagesTitle": "Mises à jour des images Docker",
"dockerImagesHelp": "Suit chaque image locale séparément du moteur Docker en comparant les digests immuables du registre.",
"refreshDockerImages": "Vérifier maintenant",
"noDockerImages": "Aucune image Docker taguée trouvée",
"usedByContainers": "Utilisée par : {names}",
"imageUpdateAvailable": "Nouvelle image disponible",
"imageUpToDate": "À jour",
"imageDigestUnknown": "Digest indisponible",
"dockerReadOnlyNote": "Vérification en lecture seule : aucune image téléchargée et aucun conteneur redémarré.",
"installedManaged": "Installé et géré par ProxMenux",
"nameLabel": "Nom",
"installedViaLabel": "Installé via",
@@ -1340,6 +1410,17 @@
"jsonPathPlaceholder": "par exemple, data.version ou releases[0].tag_name",
"dockerImageLabel": "Image DockerHub",
"dockerImagePlaceholder": "par exemple, linuxserver/plex ou nginx",
"dockerVersionedTagsHelp": "À utiliser uniquement pour les tags versionnés. Pour latest, stable ou lts, utilisez les mises à jour d’images Docker par digest.",
"dockerPresetSemver": "SemVer uniquement",
"dockerPresetSemverSuffix": "SemVer + suffixe",
"dockerTagFilterHelp": "Filtre les tags réels avant que ProxMenux choisisse la version la plus élevée.",
"dockerTagPreviewLabel": "Aperçu des tags réels",
"dockerTagPreviewCount": "{matched} correspondances sur {scanned}",
"dockerTagPreviewLoading": "Interrogation de Docker Hub…",
"dockerTagPreviewFailed": "Impossible d’afficher les tags Docker Hub",
"dockerTagPreviewEmpty": "Aucun tag réel ne correspond à ce filtre.",
"dockerMovingTag": "tag mobile",
"dockerMovingTagHelp": "Les tags mobiles ne contiennent pas de version. Suivez-les plutôt par digest dans les mises à jour d’images Docker.",
"tagRegexLabel": "Tag regex (avec groupe de capture)",
"tagRegexPlaceholder": "par exemple, v?(\\d+\\.\\d+\\.\\d+)",
"tagRegexBare": "v?(\\d+\\.\\d+\\.\\d+)",
@@ -1372,7 +1453,14 @@
"registerCustom": "Enregistrez une application personnalisée",
"noAppsTitle": "Aucune candidature enregistrée",
"noAppsBody": "Enregistrez les applications exécutées dans ce conteneur pour obtenir des liens web et, si vous le souhaitez, le suivi des versions disponibles avec des notifications de nouvelles versions.",
"registerApplication": "Enregistrer une demande",
"registerApplication": "Enregistrer l’application",
"searchApplications": "Rechercher des applications",
"searchingApplications": "Recherche d’applications…",
"noApplicationsDetected": "Aucune application détectée.",
"noNewApplicationsDetected": "Aucune nouvelle application détectée.",
"oneNewApplicationDetected": "Une nouvelle application détectée.",
"newApplicationsDetected": "{count} nouvelles applications détectées.",
"detectionFailed": "Échec de la détection des applications",
"hiddenSuffix": "{count} masqué",
"confirmHide": "Masquer définitivement la détection « {name} » sur ce conteneur ?\n\nPour la récupérer plus tard, cliquez sur « Enregistrer une autre application » : la liste masquée y apparaît avec une option de restauration.",
"saveFailed": "Échec de l'enregistrement",
@@ -1383,6 +1471,13 @@
"binaryArgsHintGrafana": "Grafana a besoin",
"loadFailed": "Impossible de charger la configuration de l'application",
"checkFailed": "La vérification a échoué",
"testDetectorButton": "Tester le détecteur",
"testingDetectorButton": "Test du détecteur…",
"detectorTestTitle": "Résultat du test du détecteur",
"detectorTestNotSaved": "Brouillon uniquement · non enregistré",
"detectorTestNoVersion": "Aucune version détectée",
"detectorTestNoUpstream": "Aucune source amont configurée",
"detectorTestFailed": "Échec du test du détecteur",
"deleteFailed": "Échec de la suppression",
"dismissFailed": "Impossible d'ignorer la détection",
"restoreFailed": "Impossible de restaurer la détection",
@@ -1399,6 +1494,10 @@
"webLinks": "Liens Internet",
"addPort": "Ajouter un port",
"detectedPorts": "Ports détectés dans le conteneur — cliquez pour ajouter :",
"dockerPublishedServicesTitle": "Services Docker avec des ports publiés",
"dockerPublishedServicesHelp": "Sélectionnez uniquement les ports qui fournissent une interface web. ProxMenux n’enregistre pas ces conteneurs comme des applications LXC indépendantes.",
"dockerPublishedAdd": "Ajouter le lien",
"dockerPublishedPort": "port {containerPort} du conteneur → {hostPort} dans le LXC",
"noWebPorts": "Aucun port Web n'écoute. Utilisez Ajouter un port si vous souhaitez toujours créer un lien manuellement.",
"trackUpstream": "Suivre la version disponible (facultatif)",
"trackOff": "Désactivé : lien uniquement",
@@ -1416,7 +1515,7 @@
"checkButton": "Vérifier",
"editFieldsButton": "Modifier les champs",
"alsoDetectedContainer": "Également détecté sur ce conteneur",
"addAnotherApplication": "Ajouter une autre application",
"addAnotherApplication": "Enregistrer une autre application",
"doneButton": "Fait",
"editButton": "Modifier",
"upstreamErrorTimeout": "expiration du délai d'attente du réseau lors du contact en amont",