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
+106 -7
View File
@@ -1162,7 +1162,15 @@
"targetBoth": "OS + application",
"lastRun": "Last run: {date}",
"runSuccess": "✓ success",
"runPartial": "completed partially",
"runFailed": "✗ failed",
"runDeferred": "held for safety",
"runSkipped": "nothing pending",
"releaseDelaySummary": "{days}-day release hold",
"releaseDelayLabel": "Wait after a new app release",
"releaseDelayNone": "No waiting period",
"releaseDelayDays": "Wait {days} day(s)",
"releaseDelayHelp": "Applies only to selected apps with version tracking. Their pending releases must be this old; apps without version tracking still run their updater on every scheduled occurrence.",
"notScheduled": "Not scheduled",
"frequency": "Frequency",
"cronExpression": "Cron expression",
@@ -1171,6 +1179,11 @@
"targetOptionOs": "OS packages only",
"targetOptionApp": "Application only",
"targetOptionBoth": "OS + application",
"dockerComposeTarget": "Docker Compose · {project}",
"dockerContainerTarget": "Docker container · {container}",
"dockerEngineTarget": "Docker Engine",
"noTargets": "No targets selected",
"selectAtLeastOne": "Select at least one update target.",
"deleteButton": "Delete schedule",
"deleteConfirm": "Remove the scheduled updates for this container? Apply defaults (backup + restart) are kept."
},
@@ -1216,7 +1229,7 @@
"osPlusApp": "OS + {appName} updates",
"osPlusApps": "OS + Apps updates",
"noUpdateMethodTitle": "No update method available",
"noUpdateMethodBody": "No update method available. Update from the app itself, or set a custom command in the App tab.",
"noUpdateMethodBody": "No update method has been identified for this application. Add a custom update command.",
"ociImmutableTitle": "OCI image container",
"ociImmutableBody": "OS packages are baked in at image build time and cannot be updated in place. Apply updates manually or reinstall with a newer image.",
"hideNoticeButton": "Hide this notice for this app",
@@ -1229,6 +1242,7 @@
"applicationDefaultName": "Application",
"installedLabel": "installed",
"upToDateAtLabel": "Up to date at",
"versionLabel": "version {version}",
"versionTrackingPending": "Version tracking pending — the next scheduled check will populate installed and upstream numbers.",
"customCommandTitle": "Custom update command",
"customCommandBody": "Run a user-defined shell command to update this app inside the container.",
@@ -1237,6 +1251,7 @@
"hideNoticeAction": "Hide this notice for {appName}",
"detectedByPrefix": "Detected by",
"editApp": "Edit",
"configureUpdater": "Configure",
"alsoDetectedTitle": "Also detected in this container:",
"detectedInline": "· detected by {method}",
"customCommandLabel": "Custom update command",
@@ -1244,9 +1259,9 @@
"removeButton": "Remove",
"cancelButton": "Cancel",
"saveButton": "Save",
"editCommandButton": "Edit command",
"wireUpCommandButton": "Add custom update command",
"versionTrackingPendingShort": "Version tracking pending.",
"versionTrackingNotConfigured": "Version tracking is not configured.",
"managedByOsPackages": "This application is updated by the OS packages action.",
"noMethodBody": "No update method available. Update from the app itself, or wire up a custom command that ProxMenux will run inside the container.",
"noMethodHideBody": "This app has no update method registered. Set one from the App tab or dismiss this notice.",
"hideForApp": "Hide notice for {appName}",
@@ -1265,15 +1280,59 @@
"noManagedUpdateInfo": "No update information yet — check from Security → Secure Gateway.",
"ociTitle": "OCI image container",
"ociBody": "This container was created from an OCI (Docker) image. Update management for OCI containers is coming with the upcoming OCI install feature — updates will rebuild the container from a newer image tag rather than patching packages inside.",
"helperNotUpdateable": "The community-scripts registry marks this app as not updateable.",
"helperDetectedTitle": "Detected a helper-scripts updater",
"helperDetectedBody": "Applying manually is safest.",
"dockerImagesTitle": "Docker images",
"dockerAppTitle": "Docker",
"dockerImagesSubheading": "Images",
"dockerImagesReadOnly": "Image tags are compared by registry digest. Compose services can be pulled and recreated from their declared project.",
"dockerEngineManagedByOs": "Docker Engine {version} is package-managed and is updated by the OS packages action above.",
"dockerEngineSubheading": "Engine",
"dockerEngineDetected": "Docker Engine {version} detected",
"dockerEngineUpdateHelp": "Updates only the installed Docker packages and required dependencies. It does not upgrade other OS packages or recreate containers.",
"updateDockerEngineOnly": "Update Docker Engine",
"adguardWebUpdateOnly": "This AdGuard Home installation is updated from its own web interface.",
"openAdguard": "Open AdGuard Home",
"updateDockerImage": "Update image",
"recreateStandaloneContainer": "Update {container}",
"standaloneRecreatePending": "Standalone container(s) require protected recreation: {names}",
"noDockerImages": "Docker is installed, but no tagged images were found.",
"dockerInventoryStarting": "Waiting for Docker to finish starting…",
"dockerInventoryUnavailable": "The Docker inventory could not be read. Check again when Docker is available.",
"usedByContainers": "Used by: {names}",
"imageUpdateAvailable": "New image available",
"imageUpToDate": "Up to date",
"imageInstalledTag": "installed tag",
"imageDigestUnknown": "Digest unavailable",
"dockerPendingSummary": "{count} Docker image update(s) detected. Update with the owning Docker or Compose workflow.",
"postApplyChecking": "Verifying update result…",
"postApplyAllOk": "{count} package(s) applied successfully — nothing pending.",
"postApplyNothingPending": "Nothing pending — everything is up to date.",
"postApplyPartial": "{pending} package(s) still pending after the run.",
"postApplyPartialSubline": "{applied} applied. Some updates did not complete — review the terminal output above."
},
"bulkUpdate": {
"title": "Bulk update",
"description": "Configure one action to update the OS and the methods you select in this container.",
"loading": "Loading configuration…",
"notConfigured": "Not configured.",
"configure": "Configure",
"edit": "Edit",
"apply": "Apply updates",
"osTarget": "OS",
"osRequired": "Required for a bulk update.",
"includesDependencies": "Also includes declared dependencies: {names}",
"noMethod": "No executable update method is available.",
"staleTarget": "This selection is no longer available. Remove it before saving.",
"dockerInventoryPending": "Waiting for the Docker image inventory…",
"missingDockerTarget": "Docker image unavailable",
"selectAtLeastOne": "Select at least one update target in addition to the OS.",
"cancel": "Cancel",
"save": "Save",
"delete": "Remove configuration",
"deleteConfirm": "Remove this bulk update configuration?",
"saveFailed": "Could not save the bulk update configuration.",
"deleteFailed": "Could not remove the bulk update configuration.",
"planFailed": "Could not prepare the bulk update. Edit the configuration and review unavailable methods."
},
"appEditor": {
"closePanel": "Close panel",
"cancelButton": "Cancel",
@@ -1283,6 +1342,17 @@
"hiddenBadge": "Currently hidden — will re-appear in the detection list",
"registerDifferent": "Register a different app",
"detectedInContainer": "Detected on this container",
"versionDetected": "Version {version} detected in this container",
"legacyDetectorUsed": "Detected with a legacy compatibility fallback",
"dockerImagesTitle": "Docker image updates",
"dockerImagesHelp": "Tracks each local image separately from the Docker engine by comparing immutable registry digests.",
"refreshDockerImages": "Check now",
"noDockerImages": "No tagged Docker images found",
"usedByContainers": "Used by: {names}",
"imageUpdateAvailable": "New image available",
"imageUpToDate": "Up to date",
"imageDigestUnknown": "Digest unavailable",
"dockerReadOnlyNote": "Read-only check: no image is pulled and no container is restarted.",
"installedManaged": "Installed and managed by ProxMenux",
"nameLabel": "Name",
"installedViaLabel": "Installed via",
@@ -1339,6 +1409,17 @@
"jsonPathPlaceholder": "e.g., data.version or releases[0].tag_name",
"dockerImageLabel": "Docker Hub image",
"dockerImagePlaceholder": "e.g., linuxserver/plex or nginx",
"dockerVersionedTagsHelp": "Use this only for versioned tags. For latest, stable, or lts, use Docker image updates, which compares digests.",
"dockerPresetSemver": "SemVer only",
"dockerPresetSemverSuffix": "SemVer + suffix",
"dockerTagFilterHelp": "Filters real tags before ProxMenux selects the highest version.",
"dockerTagPreviewLabel": "Live tag preview",
"dockerTagPreviewCount": "{matched} matched of {scanned}",
"dockerTagPreviewLoading": "Checking Docker Hub…",
"dockerTagPreviewFailed": "Could not preview Docker Hub tags",
"dockerTagPreviewEmpty": "No real tags match this filter.",
"dockerMovingTag": "moving tag",
"dockerMovingTagHelp": "Moving tags do not contain a version. Track them in Docker image updates by digest instead.",
"tagRegexLabel": "Tag regex (with capture group)",
"tagRegexPlaceholder": "e.g., v?(\\d+\\.\\d+\\.\\d+)",
"tagRegexBare": "v?(\\d+\\.\\d+\\.\\d+)",
@@ -1375,6 +1456,13 @@
"noAppsTitle": "No applications registered",
"noAppsBody": "Register each application running in this container. Get clickable web links, and — optionally — upstream version tracking + notifications for new releases.",
"registerApplication": "Register application",
"searchApplications": "Find applications",
"searchingApplications": "Searching applications…",
"noApplicationsDetected": "No applications were detected.",
"noNewApplicationsDetected": "No new applications were detected.",
"oneNewApplicationDetected": "One new application was detected.",
"newApplicationsDetected": "{count} new applications were detected.",
"detectionFailed": "Application detection failed",
"hiddenSuffix": "{count} hidden",
"confirmHide": "Hide the \"{name}\" detection permanently on this container?\n\nTo bring it back later, click \"Register a different app\" — the hidden list appears there with a Restore option.",
"saveFailed": "Save failed",
@@ -1385,6 +1473,13 @@
"binaryArgsHintGrafana": "Grafana needs",
"loadFailed": "Could not load app configuration",
"checkFailed": "Check failed",
"testDetectorButton": "Test detector",
"testingDetectorButton": "Testing detector…",
"detectorTestTitle": "Detector test result",
"detectorTestNotSaved": "Draft only · not saved",
"detectorTestNoVersion": "No version was detected",
"detectorTestNoUpstream": "No upstream source configured",
"detectorTestFailed": "Detector test failed",
"deleteFailed": "Delete failed",
"dismissFailed": "Could not dismiss detection",
"restoreFailed": "Could not restore detection",
@@ -1401,6 +1496,10 @@
"webLinks": "Web links",
"addPort": "Add port",
"detectedPorts": "Ports detected in the container — click to add:",
"dockerPublishedServicesTitle": "Docker services with published ports",
"dockerPublishedServicesHelp": "Choose only ports that provide a web interface. ProxMenux does not register these containers as independent LXC applications.",
"dockerPublishedAdd": "Add link",
"dockerPublishedPort": "container port {containerPort} → {hostPort} on the LXC",
"noWebPorts": "No web ports listening. Use Add port if you still want to create a link manually.",
"trackUpstream": "Track upstream version (optional)",
"trackOff": "Off — link only",
@@ -1418,7 +1517,7 @@
"checkButton": "Check",
"editFieldsButton": "Edit fields",
"alsoDetectedContainer": "Also detected on this container",
"addAnotherApplication": "Add another application",
"addAnotherApplication": "Register another application",
"doneButton": "Done",
"editButton": "Edit",
"notificationsEnabled": "Upstream update notifications ON — click to mute",