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": "SO + aplicativo",
"lastRun": "Última execução: {date}",
"runSuccess": "✓ sucesso",
"runPartial": "concluída parcialmente",
"runFailed": "✗ falhou",
"runDeferred": "adiada por segurança",
"runSkipped": "nada pendente",
"releaseDelaySummary": "espera de {days} dia(s)",
"releaseDelayLabel": "Esperar após uma nova versão da app",
"releaseDelayNone": "Sem período de espera",
"releaseDelayDays": "Esperar {days} dia(s)",
"releaseDelayHelp": "Aplica-se apenas às apps selecionadas com acompanhamento de versões. As versões pendentes devem ter esta idade; as apps sem acompanhamento executam o atualizador em cada agendamento.",
"notScheduled": "Não agendado",
"frequency": "Freqüência",
"cronExpression": "Expressão Cron",
@@ -1172,6 +1180,11 @@
"targetOptionOs": "Somente pacotes de sistema operacional",
"targetOptionApp": "Somente aplicativo",
"targetOptionBoth": "SO + aplicativo",
"dockerComposeTarget": "Docker Compose · {project}",
"dockerContainerTarget": "Contentor Docker · {container}",
"dockerEngineTarget": "Motor Docker",
"noTargets": "Nenhum alvo selecionado",
"selectAtLeastOne": "Selecione pelo menos um alvo de atualização.",
"deleteButton": "Excluir programação",
"deleteConfirm": "Remover as atualizações agendadas para este contêiner? Os padrões de aplicação (backup + reinicialização) são mantidos."
},
@@ -1217,7 +1230,7 @@
"osPlusApp": "SO + atualizações de {appName}",
"osPlusApps": "Atualizações do sistema operacional + aplicativos",
"noUpdateMethodTitle": "Nenhum método de atualização disponível",
"noUpdateMethodBody": "Nenhum método de atualização disponível. Atualize a partir do próprio aplicativo ou defina um comando personalizado na guia Aplicativo.",
"noUpdateMethodBody": "Não foi identificado nenhum método de atualização para esta aplicação. Adicione um comando de atualização personalizado.",
"ociImmutableTitle": "Contêiner de imagem OCI",
"ociImmutableBody": "Os pacotes do sistema operacional são incorporados no momento da criação da imagem e não podem ser atualizados no local. Aplique as atualizações manualmente ou reinstale com uma imagem mais recente.",
"hideNoticeButton": "Ocultar este aviso para este app",
@@ -1230,6 +1243,7 @@
"applicationDefaultName": "Aplicativo",
"installedLabel": "instalado",
"upToDateAtLabel": "Atualizado em",
"versionLabel": "versão {version}",
"versionTrackingPending": "Rastreamento de versões pendente — a próxima verificação agendada mostrará as versões instalada e disponível.",
"customCommandTitle": "Comando de atualização personalizado",
"customCommandBody": "Execute um comando shell definido pelo usuário para atualizar este aplicativo dentro do contêiner.",
@@ -1238,6 +1252,7 @@
"hideNoticeAction": "Ocultar este aviso para {appName}",
"detectedByPrefix": "Detectado por",
"editApp": "Editar",
"configureUpdater": "Configurar",
"alsoDetectedTitle": "Também detectado neste contêiner:",
"detectedInline": "· detectado por {method}",
"customCommandLabel": "Comando de atualização personalizado",
@@ -1245,9 +1260,9 @@
"removeButton": "Remover",
"cancelButton": "Cancelar",
"saveButton": "Salvar",
"editCommandButton": "Editar comando",
"wireUpCommandButton": "Adicionar comando de atualização personalizado",
"versionTrackingPendingShort": "Rastreamento de versão pendente.",
"versionTrackingNotConfigured": "O acompanhamento de versões não está configurado.",
"managedByOsPackages": "Esta aplicação é atualizada através da ação de pacotes do SO.",
"noMethodBody": "Nenhum método de atualização disponível. Atualize a partir do próprio aplicativo ou conecte um comando personalizado que o ProxMenux executará dentro do contêiner.",
"noMethodHideBody": "Este aplicativo não possui nenhum método de atualização registrado. Defina um na guia Aplicativo ou ignore este aviso.",
"hideForApp": "Ocultar aviso para {appName}",
@@ -1266,15 +1281,59 @@
"noManagedUpdateInfo": "Nenhuma informação de atualização ainda — verifique em Segurança → Secure Gateway.",
"ociTitle": "Contêiner de imagem OCI",
"ociBody": "Este contêiner foi criado a partir de uma imagem OCI (Docker). O gerenciamento de atualizações para contêineres OCI vem com o próximo recurso de instalação do OCI – as atualizações reconstruirão o contêiner a partir de uma tag de imagem mais recente, em vez de corrigir os pacotes internos.",
"helperNotUpdateable": "O registro de scripts da comunidade marca este aplicativo como não atualizável.",
"helperDetectedTitle": "Detectou um atualizador de scripts auxiliares",
"helperDetectedBody": "Aplicar manualmente é mais seguro.",
"dockerImagesTitle": "Imagens Docker",
"dockerAppTitle": "Docker",
"dockerImagesSubheading": "Imagens",
"dockerImagesReadOnly": "As tags são comparadas pelo digest do registo. Os serviços Compose podem descarregar a imagem e ser recriados a partir do projeto declarado.",
"dockerEngineManagedByOs": "O Docker Engine {version} é gerido por pacotes e atualizado pela ação de pacotes do SO acima.",
"dockerEngineSubheading": "Motor",
"dockerEngineDetected": "Docker Engine {version} detetado",
"dockerEngineUpdateHelp": "Atualiza apenas os pacotes Docker instalados e as dependências necessárias. Não atualiza outros pacotes do SO nem recria contentores.",
"updateDockerEngineOnly": "Atualizar Docker Engine",
"adguardWebUpdateOnly": "Esta instalação do AdGuard Home é atualizada na sua própria interface web.",
"openAdguard": "Abrir AdGuard Home",
"updateDockerImage": "Atualizar imagem",
"recreateStandaloneContainer": "Atualizar {container}",
"standaloneRecreatePending": "Os contentores independentes requerem uma recriação protegida: {names}",
"noDockerImages": "O Docker está instalado, mas não foram encontradas imagens com tag.",
"dockerInventoryStarting": "A aguardar que o Docker termine de iniciar…",
"dockerInventoryUnavailable": "Não foi possível ler o inventário do Docker. Verifique novamente quando o Docker estiver disponível.",
"usedByContainers": "Usada por: {names}",
"imageUpdateAvailable": "Nova imagem disponível",
"imageUpToDate": "Atualizada",
"imageInstalledTag": "etiqueta instalada",
"imageDigestUnknown": "Digest indisponível",
"dockerPendingSummary": "Foram detetadas {count} atualizações de imagens Docker. Use o respetivo fluxo Docker ou Compose.",
"postApplyChecking": "Verificando o resultado da atualização…",
"postApplyAllOk": "{count} pacote(s) aplicado(s) com sucesso — nada pendente.",
"postApplyNothingPending": "Nada pendente — tudo está atualizado.",
"postApplyPartial": "{pending} pacote(s) ainda pendente(s) após a execução.",
"postApplyPartialSubline": "{applied} aplicado.Algumas atualizações não foram concluídas – revise a saída do terminal acima."
},
"bulkUpdate": {
"title": "Atualização em bloco",
"description": "Configure uma única ação para atualizar o sistema operativo e os métodos selecionados neste contentor.",
"loading": "A carregar configuração…",
"notConfigured": "Não configurada.",
"configure": "Configurar",
"edit": "Editar",
"apply": "Aplicar atualizações",
"osTarget": "Sistema operativo",
"osRequired": "Obrigatório numa atualização em bloco.",
"includesDependencies": "Inclui também as dependências declaradas: {names}",
"noMethod": "Não está disponível nenhum método de atualização executável.",
"staleTarget": "Esta seleção já não está disponível. Remova-a antes de guardar.",
"dockerInventoryPending": "A aguardar o inventário de imagens Docker…",
"missingDockerTarget": "Imagem Docker indisponível",
"selectAtLeastOne": "Selecione pelo menos um destino de atualização além do sistema operativo.",
"cancel": "Cancelar",
"save": "Guardar",
"delete": "Remover configuração",
"deleteConfirm": "Remover esta configuração de atualização em bloco?",
"saveFailed": "Não foi possível guardar a configuração de atualização em bloco.",
"deleteFailed": "Não foi possível remover a configuração de atualização em bloco.",
"planFailed": "Não foi possível preparar a atualização em bloco. Reveja os métodos indisponíveis."
},
"appEditor": {
"closePanel": "Fechar painel",
"cancelButton": "Cancelar",
@@ -1284,6 +1343,17 @@
"hiddenBadge": "Atualmente oculto — reaparecerá na lista de detecção",
"registerDifferent": "Registre um aplicativo diferente",
"detectedInContainer": "Detectado neste contêiner",
"versionDetected": "Versão {version} detetada neste contentor",
"legacyDetectorUsed": "Detetada com um fallback de compatibilidade antigo",
"dockerImagesTitle": "Atualizações de imagens Docker",
"dockerImagesHelp": "Verifica cada imagem local separadamente do motor Docker comparando digests imutáveis do registo.",
"refreshDockerImages": "Verificar agora",
"noDockerImages": "Não foram encontradas imagens Docker com tag",
"usedByContainers": "Usada por: {names}",
"imageUpdateAvailable": "Nova imagem disponível",
"imageUpToDate": "Atualizada",
"imageDigestUnknown": "Digest indisponível",
"dockerReadOnlyNote": "Verificação só de leitura: nenhuma imagem é descarregada e nenhum contentor é reiniciado.",
"installedManaged": "Instalado e gerenciado por ProxMenux",
"nameLabel": "Nome",
"installedViaLabel": "Instalado via",
@@ -1340,6 +1410,17 @@
"jsonPathPlaceholder": "por exemplo, data.version ou releases[0].tag_name",
"dockerImageLabel": "Imagem do DockerHub",
"dockerImagePlaceholder": "por exemplo, linuxserver/plex ou nginx",
"dockerVersionedTagsHelp": "Utilize apenas com tags versionadas. Para latest, stable ou lts, use as atualizações de imagens Docker por digest.",
"dockerPresetSemver": "Apenas SemVer",
"dockerPresetSemverSuffix": "SemVer + sufixo",
"dockerTagFilterHelp": "Filtra as tags reais antes de o ProxMenux escolher a versão mais alta.",
"dockerTagPreviewLabel": "Pré-visualização de tags reais",
"dockerTagPreviewCount": "{matched} correspondências de {scanned}",
"dockerTagPreviewLoading": "A consultar o Docker Hub…",
"dockerTagPreviewFailed": "Não foi possível mostrar as tags do Docker Hub",
"dockerTagPreviewEmpty": "Nenhuma tag real corresponde a este filtro.",
"dockerMovingTag": "tag móvel",
"dockerMovingTagHelp": "As tags móveis não contêm uma versão. Acompanhe-as pelo digest nas atualizações de imagens Docker.",
"tagRegexLabel": "Tag regex (com grupo de captura)",
"tagRegexPlaceholder": "por exemplo, v?(\\d+\\.\\d+\\.\\d+)",
"tagRegexBare": "v?(\\d+\\.\\d+\\.\\d+)",
@@ -1372,7 +1453,14 @@
"registerCustom": "Registre um aplicativo personalizado",
"noAppsTitle": "Nenhum aplicativo cadastrado",
"noAppsBody": "Registre os aplicativos executados neste contêiner para obter links da web e, opcionalmente, rastrear versões disponíveis com notificações de novos lançamentos.",
"registerApplication": "Registrar aplicativo",
"registerApplication": "Registar aplicação",
"searchApplications": "Procurar aplicações",
"searchingApplications": "A procurar aplicações…",
"noApplicationsDetected": "Nenhuma aplicação detetada.",
"noNewApplicationsDetected": "Nenhuma aplicação nova detetada.",
"oneNewApplicationDetected": "Foi detetada uma nova aplicação.",
"newApplicationsDetected": "Foram detetadas {count} aplicações novas.",
"detectionFailed": "Falha ao detetar aplicações",
"hiddenSuffix": "{count} oculto",
"confirmHide": "Ocultar permanentemente a detecção \"{name}\" neste contêiner?\n\nPara recuperá-lo mais tarde, clique em “Registrar um aplicativo diferente” – a lista oculta aparece com a opção Restaurar.",
"saveFailed": "Falha ao salvar",
@@ -1383,6 +1471,13 @@
"binaryArgsHintGrafana": "Necessidades de grafana",
"loadFailed": "Não foi possível carregar a configuração do aplicativo",
"checkFailed": "Falha na verificação",
"testDetectorButton": "Testar detetor",
"testingDetectorButton": "A testar o detetor…",
"detectorTestTitle": "Resultado do teste do detetor",
"detectorTestNotSaved": "Apenas rascunho · não guardado",
"detectorTestNoVersion": "Nenhuma versão detetada",
"detectorTestNoUpstream": "Nenhuma fonte upstream configurada",
"detectorTestFailed": "Falha no teste do detetor",
"deleteFailed": "Falha na exclusão",
"dismissFailed": "Não foi possível descartar a detecção",
"restoreFailed": "Não foi possível restaurar a detecção",
@@ -1399,6 +1494,10 @@
"webLinks": "Links da web",
"addPort": "Adicionar porta",
"detectedPorts": "Portas detectadas no contêiner — clique para adicionar:",
"dockerPublishedServicesTitle": "Serviços Docker com portas publicadas",
"dockerPublishedServicesHelp": "Selecione apenas as portas que fornecem uma interface Web. O ProxMenux não regista estes contentores como aplicações LXC independentes.",
"dockerPublishedAdd": "Adicionar ligação",
"dockerPublishedPort": "porta {containerPort} do contentor → {hostPort} no LXC",
"noWebPorts": "Nenhuma porta da web escutando. Use Adicionar porta se ainda quiser criar um link manualmente.",
"trackUpstream": "Rastrear versão disponível (opcional)",
"trackOff": "Desativado – apenas link",
@@ -1416,7 +1515,7 @@
"checkButton": "Verificar",
"editFieldsButton": "Editar campos",
"alsoDetectedContainer": "Também detectado neste contêiner",
"addAnotherApplication": "Adicione outro aplicativo",
"addAnotherApplication": "Registar outra aplicação",
"doneButton": "Feito",
"editButton": "Editar",
"upstreamErrorTimeout": "Tempo limite da rede ao entrar em contato com o upstream",