mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-04 20:02:07 +00:00
fix(oci): apply the llama.cpp context size and stable Vulkan settings for integrated GPUs
This commit is contained in:
@@ -256,6 +256,7 @@
|
||||
"Acceleration for llama.cpp": "Beschleunigung für llama.cpp",
|
||||
"Accept routes from other nodes?": "Routen von anderen Knoten akzeptieren?",
|
||||
"Accept this host monitoring profile?": "Akzeptieren Sie dieses Host Monitoring Profil?",
|
||||
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Zugriff auf die Movistar- und O2-Cloud über WebDAV-Clients und Backup-Werkzeuge.",
|
||||
"Access Scope:": "Zugriffsbereich:",
|
||||
"Access bridge": "Zugangsbrücke",
|
||||
"Access bridge for Immich": "Access Bridge für Immich",
|
||||
@@ -4897,6 +4898,7 @@
|
||||
"Open the page of an application in the menu": "Die Seite einer Anwendung im Menü öffnen",
|
||||
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Öffne die Webadresse und erstelle das erste Konto: Der Daemon registriert sich selbst und startet den ersten Scan.",
|
||||
"Open the web address and create the password of the akadmin user in the first-run setup.": "Öffnen Sie die Webadresse und erstellen Sie im ersten Setup das Passwort des akadmin-Benutzers.",
|
||||
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Öffnen Sie das Web-Dashboard und verknüpfen Sie Ihr Movistar/O2-Konto über die SMS-Bestätigung.",
|
||||
"Open-source AI-powered coding assistant": "Open-Source AI-powered Coding Assistant",
|
||||
"Open-source UI for building and debugging multi-agent and RAG applications": "Open-Source-Benutzeroberfläche zum Erstellen und Debuggen von Multi-Agenten- und RAG-Anwendungen",
|
||||
"Open-source in-memory data store.": "Open-Source-Datenspeicher im Arbeitsspeicher.",
|
||||
@@ -8202,12 +8204,17 @@
|
||||
"Web access": "Webzugang",
|
||||
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Webadresse des AdGuard Home, der die Einstellungen erhält (z. B. http://192.168.1.3)",
|
||||
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Webadresse des AdGuard Home, dessen Einstellungen kopiert sind (z. B. http://192.168.1.2)",
|
||||
"Web dashboard": "Web-Dashboard",
|
||||
"Web dashboard and WebDAV": "Web-Dashboard und WebDAV",
|
||||
"Web interface": "Weboberfläche",
|
||||
"Web interface for Borg Backup repositories and jobs.": "Weboberfläche für Borg-Backup-Repositories und -Jobs.",
|
||||
"Web interface for managing 3D printers.": "Weboberfläche zur Verwaltung von 3D-Druckern.",
|
||||
"Web interface to manage devices running Tasmota firmware.": "Web-Schnittstelle zur Verwaltung von Geräten mit Tasmota-Firmware.",
|
||||
"Web reverse proxy with an administration interface.": "Web-Reverse-Proxy mit Administrationsoberfläche.",
|
||||
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord kann als ein Paket von Sicherheits- und Datenschutz-Härtungen, Discord-Features-Reimplementierungen, Electron / Chromium / Discord-Bugs-Workarounds, Stylesheets, interne Seiten und verpackte https://discord.com-Seite zusammengefasst werden, die so weit wie möglich mit ToS konform sind (oder die Änderungen, die es verletzen könnten, vor Discords Augen verbergen).",
|
||||
"WebDAV": "WebDAV",
|
||||
"WebDAV and dashboard password (leave empty to generate)": "Passwort für WebDAV und Dashboard (leer = generiert)",
|
||||
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV ist auf Port 8080 des Containers verfügbar. Vor Dateioperationen in der Cloud muss das Konto verknüpft werden.",
|
||||
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus ist ein multi-site inkrementeller xmltv epg grabber. Es sammelt tv-programm-guide-daten von ausgewählten tvguide-seiten für ihre lieblingskanäle.",
|
||||
"Webservers & Proxies": "Webserver und Proxys",
|
||||
"Website": "Webseite",
|
||||
|
||||
@@ -255,6 +255,7 @@
|
||||
"Acceleration for llama.cpp": "Aceleración para llama.cpp",
|
||||
"Accept routes from other nodes?": "¿Aceptar rutas de otros nodos?",
|
||||
"Accept this host monitoring profile?": "¿Aceptar este perfil de monitorización del host?",
|
||||
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Accede a la nube de Movistar y O2 desde clientes WebDAV y herramientas de backup.",
|
||||
"Access Scope:": "Ámbito de acceso:",
|
||||
"Access bridge": "Puente de acceso",
|
||||
"Access bridge for Immich": "Puente de acceso para Immich",
|
||||
@@ -4888,6 +4889,7 @@
|
||||
"Open the page of an application in the menu": "Abrir la página de una aplicación en el menú",
|
||||
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Abre la dirección web y crea la primera cuenta: el daemon se registra solo y empieza el primer escaneo.",
|
||||
"Open the web address and create the password of the akadmin user in the first-run setup.": "abra la dirección web y cree la contraseña del usuario akaadmin en la configuración de primera ejecución.",
|
||||
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Abre el panel web y vincula tu cuenta de Movistar/O2 con su verificación por SMS.",
|
||||
"Open-source AI-powered coding assistant": "Asistente de programación con IA de código abierto",
|
||||
"Open-source UI for building and debugging multi-agent and RAG applications": "Interfaz de código abierto para crear y depurar aplicaciones multiagente y RAG",
|
||||
"Open-source in-memory data store.": "Almacén de datos en memoria de código abierto.",
|
||||
@@ -8175,12 +8177,17 @@
|
||||
"Web access": "Acceso web",
|
||||
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Dirección web del AdGuard Home que recibe los ajustes (por ejemplo, http://192.168.1.3)",
|
||||
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Dirección web del AdGuard Home principal, cuyos ajustes se copian (por ejemplo, http://192.168.1.2)",
|
||||
"Web dashboard": "Panel web",
|
||||
"Web dashboard and WebDAV": "Panel web y WebDAV",
|
||||
"Web interface": "interfaz web",
|
||||
"Web interface for Borg Backup repositories and jobs.": "Interfaz web para gestionar repositorios y tareas de Borg Backup.",
|
||||
"Web interface for managing 3D printers.": "Interfaz web para gestionar impresoras 3D.",
|
||||
"Web interface to manage devices running Tasmota firmware.": "Interfaz web para gestionar dispositivos con firmware Tasmota.",
|
||||
"Web reverse proxy with an administration interface.": "Proxy inverso web con interfaz de administración.",
|
||||
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord puede resumirse como un conjunto de medidas de hardening de seguridad y privacidad, reimplementaciones de funciones de Discord, soluciones a fallos de Electron / Chromium / Discord, hojas de estilo, páginas internas y la página https://discord.com encapsulada, diseñado para cumplir los ToS en lo posible (u ocultar a Discord los cambios que podrían incumplirlos).",
|
||||
"WebDAV": "WebDAV",
|
||||
"WebDAV and dashboard password (leave empty to generate)": "Contraseña de WebDAV y del panel (vacío = generada)",
|
||||
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV está disponible en el puerto 8080 del contenedor. Hay que vincular la cuenta antes de trabajar con los archivos de la nube.",
|
||||
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus es un capturador incremental de EPG xmltv para múltiples sitios. Recoge los datos de la guía de programación de los sitios de guías de TV seleccionados para tus canales favoritos.",
|
||||
"Webservers & Proxies": "Webservers & Proxies",
|
||||
"Website": "Sitio web",
|
||||
|
||||
@@ -256,6 +256,7 @@
|
||||
"Acceleration for llama.cpp": "Accélération pour llama.cpp",
|
||||
"Accept routes from other nodes?": "Accepter les routes d'autres nœuds ?",
|
||||
"Accept this host monitoring profile?": "Accepter ce profil de surveillance de l'hôte?",
|
||||
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Accédez au cloud Movistar et O2 depuis des clients WebDAV et des outils de sauvegarde.",
|
||||
"Access Scope:": "Portée d'accès :",
|
||||
"Access bridge": "Pont d'accès",
|
||||
"Access bridge for Immich": "Pont d'accès pour Immich",
|
||||
@@ -4897,6 +4898,7 @@
|
||||
"Open the page of an application in the menu": "Ouvrir la page d'une application dans le menu",
|
||||
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Ouvrez l'adresse web et créez le premier compte : le daemon s'enregistre tout seul et lance la première analyse.",
|
||||
"Open the web address and create the password of the akadmin user in the first-run setup.": "ouvrez l'adresse Web et créez le mot de passe de l'utilisateur akadmin lors de la configuration de première exécution.",
|
||||
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Ouvrez le tableau de bord web et liez votre compte Movistar/O2 avec sa vérification par SMS.",
|
||||
"Open-source AI-powered coding assistant": "Assistant de codage à source ouverte",
|
||||
"Open-source UI for building and debugging multi-agent and RAG applications": "UI open-source pour la construction et le débogage d'applications multi-agents et RAG",
|
||||
"Open-source in-memory data store.": "Magasin de données en mémoire libre.",
|
||||
@@ -8201,12 +8203,17 @@
|
||||
"Web access": "Accès au Web",
|
||||
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Adresse Web du AdGuard Home qui reçoit les paramètres (p. ex. http://192.168.1.3)",
|
||||
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Adresse Web du principal AdGuard Home, dont les paramètres sont copiés (par exemple http://192.168.1.2)",
|
||||
"Web dashboard": "Tableau de bord web",
|
||||
"Web dashboard and WebDAV": "Tableau de bord web et WebDAV",
|
||||
"Web interface": "interface Web",
|
||||
"Web interface for Borg Backup repositories and jobs.": "Interface web pour les dépôts et tâches Borg Backup.",
|
||||
"Web interface for managing 3D printers.": "Interface web de gestion des imprimantes 3D.",
|
||||
"Web interface to manage devices running Tasmota firmware.": "Interface Web pour gérer les appareils utilisant le firmware Tasmota.",
|
||||
"Web reverse proxy with an administration interface.": "Proxy inverse web doté d’une interface d’administration.",
|
||||
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord peut être résumé comme un paquet de durcissements de sécurité et de confidentialité, les fonctionnalités Discord réimplémentations, Electron / Chromium / Discord bugs workarounds, les feuilles de style, les pages internes et la page https://discord.com enveloppée, conçue pour se conformer à ToS autant qu'il est possible (ou cacher les changements qui pourraient la violer des yeux de Discord).",
|
||||
"WebDAV": "WebDAV",
|
||||
"WebDAV and dashboard password (leave empty to generate)": "Mot de passe WebDAV et du tableau de bord (vide = généré)",
|
||||
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV est disponible sur le port 8080 du conteneur. Le compte doit être lié avant toute opération sur les fichiers du cloud.",
|
||||
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus est un accrocheur différentiel multisite xmltv egg. Il recueille les données du guide TV-programme à partir de sites sélectionnés pour vos chaînes préférées.",
|
||||
"Webservers & Proxies": "Serveurs web et proxys",
|
||||
"Website": "Site web",
|
||||
|
||||
@@ -256,6 +256,7 @@
|
||||
"Acceleration for llama.cpp": "Accelerazione per llama.cpp",
|
||||
"Accept routes from other nodes?": "Accettare rotte da altri nodi?",
|
||||
"Accept this host monitoring profile?": "Accettare questo profilo di monitoraggio host?",
|
||||
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Accedi al cloud di Movistar e O2 da client WebDAV e strumenti di backup.",
|
||||
"Access Scope:": "Ambito di accesso:",
|
||||
"Access bridge": "Bridge di accesso",
|
||||
"Access bridge for Immich": "Bridge di accesso per Immich",
|
||||
@@ -4897,6 +4898,7 @@
|
||||
"Open the page of an application in the menu": "Apri la pagina di un'applicazione nel menu",
|
||||
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Apri l'indirizzo web e crea il primo account: il daemon si registra da solo e avvia la prima scansione.",
|
||||
"Open the web address and create the password of the akadmin user in the first-run setup.": "Apri l'indirizzo web e imposta la password dell'utente akadmin durante la configurazione iniziale.",
|
||||
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Apri la dashboard web e collega il tuo account Movistar/O2 con la verifica tramite SMS.",
|
||||
"Open-source AI-powered coding assistant": "Assistente open source per la programmazione basato sull'IA",
|
||||
"Open-source UI for building and debugging multi-agent and RAG applications": "Interfaccia open source per creare ed eseguire il debug di applicazioni multiagente e RAG",
|
||||
"Open-source in-memory data store.": "Archivio dati in memoria open source.",
|
||||
@@ -8202,12 +8204,17 @@
|
||||
"Web access": "Accesso web",
|
||||
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Indirizzo web dell'istanza AdGuard Home che riceve le impostazioni (ad es. http://192.168.1.3)",
|
||||
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Indirizzo web dell'istanza AdGuard Home principale, da cui vengono copiate le impostazioni (ad es. http://192.168.1.2)",
|
||||
"Web dashboard": "Dashboard web",
|
||||
"Web dashboard and WebDAV": "Dashboard web e WebDAV",
|
||||
"Web interface": "Interfaccia web",
|
||||
"Web interface for Borg Backup repositories and jobs.": "Interfaccia web per repository e job di Borg Backup.",
|
||||
"Web interface for managing 3D printers.": "Interfaccia web per gestire stampanti 3D.",
|
||||
"Web interface to manage devices running Tasmota firmware.": "Interfaccia web per gestire dispositivi con firmware Tasmota.",
|
||||
"Web reverse proxy with an administration interface.": "Proxy inverso web con interfaccia di amministrazione.",
|
||||
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord comprende miglioramenti alla sicurezza e alla privacy, reimplementazioni di funzioni di Discord, soluzioni alternative ai bug di Electron, Chromium e Discord, fogli di stile, pagine interne e la pagina https://discord.com incapsulata. È progettato per rispettare i termini di servizio per quanto possibile (o nascondere a Discord le modifiche che potrebbero violarli).",
|
||||
"WebDAV": "WebDAV",
|
||||
"WebDAV and dashboard password (leave empty to generate)": "Password di WebDAV e della dashboard (campo vuoto = generata)",
|
||||
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV è disponibile sulla porta 8080 del container. Prima di operare sui file del cloud bisogna collegare l'account.",
|
||||
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus acquisisce dati EPG XMLTV incrementalmente da più siti. Raccoglie le guide TV dai siti selezionati per i canali preferiti.",
|
||||
"Webservers & Proxies": "Server web e proxy",
|
||||
"Website": "Sito web",
|
||||
|
||||
@@ -256,6 +256,7 @@
|
||||
"Acceleration for llama.cpp": "Aceleração para llama.cpp",
|
||||
"Accept routes from other nodes?": "Aceita rotas de outros nós?",
|
||||
"Accept this host monitoring profile?": "Aceita este perfil de monitorização da máquina?",
|
||||
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Acesse a nuvem da Movistar e da O2 a partir de clientes WebDAV e ferramentas de backup.",
|
||||
"Access Scope:": "Escopo de acesso:",
|
||||
"Access bridge": "Ponte de acesso",
|
||||
"Access bridge for Immich": "Ponte de acesso para Immich",
|
||||
@@ -4897,6 +4898,7 @@
|
||||
"Open the page of an application in the menu": "Abrir a página de uma aplicação no menu",
|
||||
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Abra o endereço web e crie a primeira conta: o daemon regista-se sozinho e inicia a primeira análise.",
|
||||
"Open the web address and create the password of the akadmin user in the first-run setup.": "Abra o endereço da web e crie a senha do usuário akadmin na configuração inicial.",
|
||||
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Abra o painel web e vincule sua conta Movistar/O2 com a verificação por SMS.",
|
||||
"Open-source AI-powered coding assistant": "Assistente de codificação com código aberto",
|
||||
"Open-source UI for building and debugging multi-agent and RAG applications": "UI de código aberto para a construção e depuração de aplicações multi-agente e RAG",
|
||||
"Open-source in-memory data store.": "Armazenamento de dados em memória de código aberto.",
|
||||
@@ -8202,12 +8204,17 @@
|
||||
"Web access": "Acesso à Internet",
|
||||
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Endereço Web do AdGuard Home que recebe as definições (por exemplo, http://192.168.1.3)",
|
||||
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Endereço Web do AdGuard Home principal, cujas configurações são copiadas (por exemplo, http://192.168.1.2)",
|
||||
"Web dashboard": "Painel web",
|
||||
"Web dashboard and WebDAV": "Painel web e WebDAV",
|
||||
"Web interface": "Interface da Web",
|
||||
"Web interface for Borg Backup repositories and jobs.": "Interface web para gerenciar repositórios e tarefas do Borg Backup.",
|
||||
"Web interface for managing 3D printers.": "Interface web para gerenciar impressoras 3D.",
|
||||
"Web interface to manage devices running Tasmota firmware.": "Interface Web para gerenciar dispositivos rodando firmware Tasmota.",
|
||||
"Web reverse proxy with an administration interface.": "Proxy reverso web com interface de administração.",
|
||||
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord pode ser resumido como um pacote de endurecimentos de segurança e privacidade, recursos de discórdia reimplementações, Electron / Chromium / Erros de discórdia workarounds, stylesheets, páginas internas e página envolto https://discord.com, projetado para se conformar com ToS tanto quanto possível (ou ocultar as alterações que podem violá-lo dos olhos da Discord).",
|
||||
"WebDAV": "WebDAV",
|
||||
"WebDAV and dashboard password (leave empty to generate)": "Senha do WebDAV e do painel (vazio = gerada)",
|
||||
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "O WebDAV está disponível na porta 8080 do contêiner. É preciso vincular a conta antes de operar com os arquivos da nuvem.",
|
||||
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus é um multi-site incremental xmltv epg grabber. Ele coleta dados de guias de tv-programa de sites selecionados para seus canais favoritos.",
|
||||
"Webservers & Proxies": "Servidores web e proxies",
|
||||
"Website": "Site",
|
||||
|
||||
@@ -256,6 +256,7 @@
|
||||
"Acceleration for llama.cpp": "Zrýchlenie pre llama.cpp",
|
||||
"Accept routes from other nodes?": "Prijímať trasy z iných uzlov?",
|
||||
"Accept this host monitoring profile?": "Prijať tento profil monitorovania hostiteľa?",
|
||||
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Prístup ku cloudu Movistar a O2 z klientov WebDAV a nástrojov na zálohovanie.",
|
||||
"Access Scope:": "Rozsah prístupu:",
|
||||
"Access bridge": "Sieťový most (bridge)",
|
||||
"Access bridge for Immich": "Sieťový most (bridge) pre Immich",
|
||||
@@ -4899,6 +4900,7 @@
|
||||
"Open the page of an application in the menu": "Otvoriť stránku aplikácie v ponuke",
|
||||
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Otvorte webovú adresu a vytvorte prvé konto: daemon sa zaregistruje sám a spustí prvé skenovanie.",
|
||||
"Open the web address and create the password of the akadmin user in the first-run setup.": "Otvorte webovú adresu a v prvotnom nastavení vytvorte heslo používateľa akadmin.",
|
||||
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Otvorte webový panel a prepojte svoj účet Movistar/O2 pomocou overenia cez SMS.",
|
||||
"Open-source AI-powered coding assistant": "Programátorský asistent využívajúci AI s otvoreným zdrojovým kódom",
|
||||
"Open-source UI for building and debugging multi-agent and RAG applications": "Rozhranie s otvoreným zdrojovým kódom na tvorbu a ladenie aplikácií s viacerými agentmi a RAG",
|
||||
"Open-source in-memory data store.": "Úložisko údajov v pamäti s otvoreným zdrojovým kódom.",
|
||||
@@ -8202,12 +8204,17 @@
|
||||
"Web access": "Adresa webového rozhrania",
|
||||
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Webová adresa AdGuard Home, ktorá prijíma nastavenia (napr. http://192.168.1.3)",
|
||||
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Webová adresa hlavného AdGuard Home, ktorého nastavenia sú kopírované (napr. http://192.168.1.2)",
|
||||
"Web dashboard": "Webový panel",
|
||||
"Web dashboard and WebDAV": "Webový panel a WebDAV",
|
||||
"Web interface": "Webové rozhranie",
|
||||
"Web interface for Borg Backup repositories and jobs.": "Webové rozhranie na správu úložísk a úloh Borg Backup.",
|
||||
"Web interface for managing 3D printers.": "Webové rozhranie na správu 3D tlačiarní.",
|
||||
"Web interface to manage devices running Tasmota firmware.": "Webové rozhranie pre správu zariadení bežiacich na Tasmota firmware.",
|
||||
"Web reverse proxy with an administration interface.": "Webový reverzný proxy server s administračným rozhraním.",
|
||||
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord je klient obklopujúci stránku https://discord.com, ktorý zlepšuje bezpečnosť a súkromie, upravuje funkcie Discordu, obchádza chyby Electronu, Chromia a Discordu a pridáva štýly aj interné stránky. Snaží sa čo najviac dodržiavať podmienky používania alebo skryť pred Discordom úpravy, ktoré by ich mohli porušovať.",
|
||||
"WebDAV": "WebDAV",
|
||||
"WebDAV and dashboard password (leave empty to generate)": "Heslo pre WebDAV a panel (prázdne = generované)",
|
||||
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV je dostupný na porte 8080 kontajnera. Pred prácou so súbormi v cloude je potrebné prepojiť účet.",
|
||||
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "WebGrab+Plus priebežne získava elektronický programový sprievodca (EPG) vo formáte XMLTV z viacerých webov. Zhromažďuje televízny program vybraných staníc z podporovaných stránok.",
|
||||
"Webservers & Proxies": "Webové servery a proxy",
|
||||
"Website": "Webová stránka",
|
||||
|
||||
@@ -256,6 +256,7 @@
|
||||
"Acceleration for llama.cpp": "Acceleration för llama.cpp",
|
||||
"Accept routes from other nodes?": "Acceptera rutter från andra noder?",
|
||||
"Accept this host monitoring profile?": "Acceptera denna värdövervakningsprofil?",
|
||||
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Kom åt Movistar- och O2-molnet från WebDAV-klienter och säkerhetskopieringsverktyg.",
|
||||
"Access Scope:": "Åtkomstomfång:",
|
||||
"Access bridge": "Tillgång bridge",
|
||||
"Access bridge for Immich": "Tillgångsbro för Immich",
|
||||
@@ -4897,6 +4898,7 @@
|
||||
"Open the page of an application in the menu": "Öppna en applikations sida i menyn",
|
||||
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Öppna webbadressen och skapa det första kontot: daemonen registrerar sig själv och startar den första skanningen.",
|
||||
"Open the web address and create the password of the akadmin user in the first-run setup.": "Öppna webbadressen och skapa lösenordet för akadmin-användaren i den första körningen.",
|
||||
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Öppna webbpanelen och koppla ditt Movistar/O2-konto med SMS-verifieringen.",
|
||||
"Open-source AI-powered coding assistant": "Open-source AI-driven kodningsassistent",
|
||||
"Open-source UI for building and debugging multi-agent and RAG applications": "Open-source UI för att bygga och debugga multi-agent- och RAG-applikationer",
|
||||
"Open-source in-memory data store.": "Öppen datalagring i minnet.",
|
||||
@@ -8202,12 +8204,17 @@
|
||||
"Web access": "Web access",
|
||||
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Webbadress för AdGuard Home som tar emot inställningarna (t.ex. http://192.168.1.3)",
|
||||
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Webbadressen för AdGuard Home, vars inställningar kopieras (t.ex. http://192.168.1.2)",
|
||||
"Web dashboard": "Webbpanel",
|
||||
"Web dashboard and WebDAV": "Webbpanel och WebDAV",
|
||||
"Web interface": "Webbgränssnitt",
|
||||
"Web interface for Borg Backup repositories and jobs.": "Webbgränssnitt för Borg Backup-arkiv och jobb.",
|
||||
"Web interface for managing 3D printers.": "Webbgränssnitt för hantering av 3D-skrivare.",
|
||||
"Web interface to manage devices running Tasmota firmware.": "Webbgränssnitt för att hantera enheter som kör Tasmota firmware.",
|
||||
"Web reverse proxy with an administration interface.": "Omvänd proxy för webben med administrationsgränssnitt.",
|
||||
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord kan sammanfattas som ett paket av säkerhets- och sekretesshärdningar, Discord-funktioner reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, interna sidor och wrapped https://discord.com sida, utformad för att överensstämma med ToS så mycket som möjligt (eller dölja de förändringar som kan bryta mot det från Discords ögon).",
|
||||
"WebDAV": "WebDAV",
|
||||
"WebDAV and dashboard password (leave empty to generate)": "Lösenord för WebDAV och panelen (tom = genererat)",
|
||||
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV är tillgängligt på containerns port 8080. Kontot måste kopplas innan du arbetar med filerna i molnet.",
|
||||
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus är en multi-site inkrementell xmltv epg grabber. Det samlar in tv-programguide data från utvalda tvguide webbplatser för dina favoritkanaler.",
|
||||
"Webservers & Proxies": "Webbservrar och proxyservrar",
|
||||
"Website": "Webbplats",
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
<!-- Generated from oci/catalog/verification.json by .github/scripts/oci_validation.py. Do not edit by hand. -->
|
||||
|
||||
52 of 533 applications in the OCI catalog have been tested for real: 49 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists.
|
||||
52 of 534 applications in the OCI catalog have been tested for real: 49 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists.
|
||||
|
||||
Each test describes the scenario that was run and names the image it ran on. It does not cover every possible configuration of the application, and a newer image has not been tested until someone reports it.
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "LLAMA_ARG_CONTEXT_SIZE",
|
||||
"name": "LLAMA_ARG_CTX_SIZE",
|
||||
"example": "8192",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
@@ -142,7 +142,7 @@
|
||||
],
|
||||
"environment": [
|
||||
"LLAMA_ARG_N_GPU_LAYERS=999",
|
||||
"LLAMA_ARG_CONTEXT_SIZE=8192",
|
||||
"LLAMA_ARG_CTX_SIZE=8192",
|
||||
"LLAMA_ARG_MODELS_DIR=/models"
|
||||
],
|
||||
"devices": [
|
||||
@@ -342,6 +342,28 @@
|
||||
"0x1002"
|
||||
]
|
||||
}
|
||||
],
|
||||
"environment": [
|
||||
{
|
||||
"name": "LLAMA_ARG_FLASH_ATTN",
|
||||
"value": "off"
|
||||
},
|
||||
{
|
||||
"name": "LLAMA_ARG_UBATCH",
|
||||
"value": "32"
|
||||
},
|
||||
{
|
||||
"name": "LLAMA_ARG_BATCH",
|
||||
"value": "128"
|
||||
},
|
||||
{
|
||||
"name": "GGML_VK_DISABLE_F16",
|
||||
"value": "1"
|
||||
},
|
||||
{
|
||||
"name": "GGML_VK_DISABLE_ASYNC",
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,609 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-movistar-webdav-proxy",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Movistar / O2 Cloud WebDAV Proxy"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Access Movistar and O2 Cloud from WebDAV clients and backup tools."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Official uniextra image with a web dashboard for Movistar/O2 Cloud account linking. Persistent OAuth credentials, authenticated WebDAV and disk-backed temporary uploads."
|
||||
},
|
||||
"category": "backup",
|
||||
"category_label": "Backup & Recovery",
|
||||
"author": "uniextra",
|
||||
"developer": "uniextra",
|
||||
"icon": "https://raw.githubusercontent.com/uniextra/MovistarWebDAVProxy/main/static/favicon.svg",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 5000,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://github.com/uniextra/MovistarWebDAVProxy",
|
||||
"documentation": "https://github.com/uniextra/MovistarWebDAVProxy#readme",
|
||||
"repository": "https://github.com/uniextra/MovistarWebDAVProxy",
|
||||
"tips": [
|
||||
"Link your Movistar or O2 account from the dashboard after installation.",
|
||||
"Use the container IP and port 8080 for WebDAV. Docker's published port 5050 is not used by native OCI LXC.",
|
||||
"Temporary uploads use a separate disk volume, excluded from backups, to avoid filling RAM."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "uniextra",
|
||||
"repository": "https://github.com/uniextra/MovistarWebDAVProxy",
|
||||
"revision": "e48485bc8bdf9745caa6249fdc92db6d28214549",
|
||||
"image_repository_url": "https://hub.docker.com/r/uniextra/movistar-webdav-proxy",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "e51607e979c1a776ececda038caeffb4195f443ebc017eba753a4b4ff8fd5c28",
|
||||
"generated_at": "2026-11-02T23:42:04+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/uniextra/MovistarWebDAVProxy/e48485bc8bdf9745caa6249fdc92db6d28214549/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "movistar-webdav-proxy",
|
||||
"container_name": "movistar-webdav-proxy",
|
||||
"image": {
|
||||
"reference": "uniextra/movistar-webdav-proxy:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "uniextra/movistar-webdav-proxy",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "WEBDAV_USER",
|
||||
"example": "admin",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "WEBDAV_PASSWORD",
|
||||
"example": "",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "docker-compose",
|
||||
"prompt": "WebDAV and dashboard password (leave empty to generate)"
|
||||
},
|
||||
{
|
||||
"name": "REQUIRE_AUTH",
|
||||
"example": "true",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "TOKENS_ENCRYPTION_KEY",
|
||||
"example": "",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "MAX_UPLOAD_MB",
|
||||
"example": "4096",
|
||||
"required": false,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "tokens",
|
||||
"container_path": "/app/tokens",
|
||||
"compose_source_example": "./tokens",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 16
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "uploads",
|
||||
"container_path": "/tmp",
|
||||
"compose_source_example": "./tmp",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 16
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 5000,
|
||||
"published_example": 5000,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
},
|
||||
{
|
||||
"container_port": 8080,
|
||||
"published_example": 8080,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "services:\n movistar-webdav-proxy:\n image: uniextra/movistar-webdav-proxy:v2.1.0\n container_name: movistar-webdav-proxy\n restart: unless-stopped\n read_only: true\n tmpfs:\n - /tmp\n security_opt:\n - no-new-privileges:true\n environment:\n - WEBDAV_USER=${WEBDAV_USER:-}\n - WEBDAV_PASSWORD=${WEBDAV_PASSWORD:-}\n - WEBUI_USER=${WEBUI_USER:-}\n - WEBUI_PASSWORD=${WEBUI_PASSWORD:-}\n ports:\n - \"${BIND_IP:-0.0.0.0}:${WEB_PORT:-5000}:5000\" # Panel Web de gestión y logs (usa BIND_IP=127.0.0.1 para acceso solo local)\n - \"${BIND_IP:-0.0.0.0}:${WEBDAV_PORT:-5050}:8080\" # Endpoint WebDAV (Duplicati / Synology HyperBackup)\n volumes:\n - movistar_tokens:/app/tokens\n\nvolumes:\n movistar_tokens:\n name: movistar_webdav_tokens\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "movistar-webdav-proxy",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "movistar-webdav-proxy",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "movistar-webdav-proxy",
|
||||
"image": "uniextra/movistar-webdav-proxy:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"environment": {
|
||||
"MAX_UPLOAD_MB": "4096",
|
||||
"REQUIRE_AUTH": "true",
|
||||
"TOKENS_ENCRYPTION_KEY": "${GENERATED_TOKENS_ENCRYPTION_KEY}",
|
||||
"WEBDAV_PASSWORD": "${GENERATED_WEBDAV_PASSWORD}",
|
||||
"WEBDAV_USER": "admin"
|
||||
},
|
||||
"image": "uniextra/movistar-webdav-proxy:latest",
|
||||
"ports": [
|
||||
"5000:5000",
|
||||
"8080:8080"
|
||||
],
|
||||
"volumes": [
|
||||
"./tokens:/app/tokens",
|
||||
"./tmp:/tmp"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "movistar-webdav-proxy"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "movistar-webdav-proxy-volume-0",
|
||||
"service": "movistar-webdav-proxy",
|
||||
"container_path": "/app/tokens",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": false,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "movistar-webdav-proxy-volume-1",
|
||||
"service": "movistar-webdav-proxy",
|
||||
"container_path": "/tmp",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": false,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"movistar-webdav-proxy"
|
||||
],
|
||||
"stop_order": [
|
||||
"movistar-webdav-proxy"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "tokens-encryption-key",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "movistar-webdav-proxy",
|
||||
"environment_variable": "TOKENS_ENCRYPTION_KEY"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "webdav-password",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "movistar-webdav-proxy",
|
||||
"environment_variable": "WEBDAV_PASSWORD"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Web dashboard",
|
||||
"scheme": "http",
|
||||
"port": 5000,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"label": "WebDAV",
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/",
|
||||
"source": "native-container-port"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "Web dashboard and WebDAV",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "admin",
|
||||
"username_environment": "WEBDAV_USER",
|
||||
"password": null,
|
||||
"password_environment": "WEBDAV_PASSWORD",
|
||||
"change_required": false,
|
||||
"source": "installer-generated",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 1,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "disk-backed-upload-scratch",
|
||||
"upstream_behavior": "Compose mounts /tmp as a tmpfs.",
|
||||
"native_lxc_behavior": "A separate managed disk volume provides /tmp and is excluded from backups.",
|
||||
"reason": "Uploads can reach 4096 MB; a disk-backed scratch volume avoids consuming the LXC RAM limit.",
|
||||
"behavioral_impact": "Scratch data uses disk and can survive a restart; the application removes completed temporary uploads.",
|
||||
"validation": "passed-in-lab"
|
||||
},
|
||||
{
|
||||
"id": "native-rootfs-permissions",
|
||||
"upstream_behavior": "Docker Compose requests read_only for the root filesystem.",
|
||||
"native_lxc_behavior": "Proxmox uses a writable native root disk; /app is owned by root, while the upstream entrypoint drops to UID 10001. Tokens and upload scratch have separate writable volumes.",
|
||||
"reason": "The Proxmox pre-start setup requires a writable root disk. Protect application code through root ownership instead of declaring unsupported read-only startup.",
|
||||
"behavioral_impact": "This is not a fully read-only root filesystem; the application user cannot replace the root-owned application directory or binaries.",
|
||||
"validation": "passed-in-lab"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/app",
|
||||
"remove_lost_found": false,
|
||||
"owner_strategy": "mapped-root",
|
||||
"mode": "0755"
|
||||
},
|
||||
{
|
||||
"container_path": "/app/tokens",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-application-user",
|
||||
"mode": "0700"
|
||||
},
|
||||
{
|
||||
"container_path": "/tmp",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-application-user",
|
||||
"mode": "1777"
|
||||
}
|
||||
],
|
||||
"volume_owner": {
|
||||
"uid": 10001,
|
||||
"gid": 10001
|
||||
},
|
||||
"generated_sensitive_environment": {
|
||||
"WEBDAV_PASSWORD": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 16,
|
||||
"prompt": true
|
||||
},
|
||||
"TOKENS_ENCRYPTION_KEY": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32,
|
||||
"prompt": false
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"options": {
|
||||
"no_new_privileges": true
|
||||
}
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 5000,
|
||||
"path": "/health",
|
||||
"timeout_seconds": 90,
|
||||
"request_timeout_seconds": 5,
|
||||
"stability_seconds": 4,
|
||||
"verify_tls": false
|
||||
},
|
||||
"completion_notes": [
|
||||
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.",
|
||||
"WebDAV is available on container port 8080. Account linking is required before cloud file operations."
|
||||
]
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"stop_signal",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "passed",
|
||||
"service_health": "passed",
|
||||
"restart_persistence": "passed",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -82,22 +82,6 @@
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "volume-1",
|
||||
"container_path": "/dev/net/tun",
|
||||
"compose_source_example": "/dev/net/tun",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [],
|
||||
@@ -180,17 +164,6 @@
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "tailscale-volume-1",
|
||||
"service": "tailscale",
|
||||
"container_path": "/dev/net/tun",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": false,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
@@ -288,6 +261,23 @@
|
||||
"owner_strategy": "mapped-root",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"device_requests": [
|
||||
{
|
||||
"id": "dev-net-tun",
|
||||
"kind": "character-device",
|
||||
"purpose": "tun",
|
||||
"enable_prompt": "Pass /dev/net/tun to the LXC",
|
||||
"enabled_default": true,
|
||||
"required_by_compose": true,
|
||||
"path_prompt": "Host device for /dev/net/tun",
|
||||
"host_path_default": "/dev/net/tun",
|
||||
"container_path": "/dev/net/tun",
|
||||
"mode": "preserve-host",
|
||||
"deny_write": false,
|
||||
"gid_strategy": "host-device-gid",
|
||||
"source_mapping": "/dev/net/tun:/dev/net/tun"
|
||||
}
|
||||
]
|
||||
},
|
||||
"adaptations": [
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "LLAMA_ARG_CONTEXT_SIZE",
|
||||
"name": "LLAMA_ARG_CTX_SIZE",
|
||||
"example": "8192",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
@@ -142,7 +142,7 @@
|
||||
],
|
||||
"environment": [
|
||||
"LLAMA_ARG_N_GPU_LAYERS=999",
|
||||
"LLAMA_ARG_CONTEXT_SIZE=8192",
|
||||
"LLAMA_ARG_CTX_SIZE=8192",
|
||||
"LLAMA_ARG_MODELS_DIR=/models"
|
||||
],
|
||||
"devices": [
|
||||
@@ -342,6 +342,28 @@
|
||||
"0x1002"
|
||||
]
|
||||
}
|
||||
],
|
||||
"environment": [
|
||||
{
|
||||
"name": "LLAMA_ARG_FLASH_ATTN",
|
||||
"value": "off"
|
||||
},
|
||||
{
|
||||
"name": "LLAMA_ARG_UBATCH",
|
||||
"value": "32"
|
||||
},
|
||||
{
|
||||
"name": "LLAMA_ARG_BATCH",
|
||||
"value": "128"
|
||||
},
|
||||
{
|
||||
"name": "GGML_VK_DISABLE_F16",
|
||||
"value": "1"
|
||||
},
|
||||
{
|
||||
"name": "GGML_VK_DISABLE_ASYNC",
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,609 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-movistar-webdav-proxy",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Movistar / O2 Cloud WebDAV Proxy"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Access Movistar and O2 Cloud from WebDAV clients and backup tools."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Official uniextra image with a web dashboard for Movistar/O2 Cloud account linking. Persistent OAuth credentials, authenticated WebDAV and disk-backed temporary uploads."
|
||||
},
|
||||
"category": "backup",
|
||||
"category_label": "Backup & Recovery",
|
||||
"author": "uniextra",
|
||||
"developer": "uniextra",
|
||||
"icon": "https://raw.githubusercontent.com/uniextra/MovistarWebDAVProxy/main/static/favicon.svg",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 5000,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://github.com/uniextra/MovistarWebDAVProxy",
|
||||
"documentation": "https://github.com/uniextra/MovistarWebDAVProxy#readme",
|
||||
"repository": "https://github.com/uniextra/MovistarWebDAVProxy",
|
||||
"tips": [
|
||||
"Link your Movistar or O2 account from the dashboard after installation.",
|
||||
"Use the container IP and port 8080 for WebDAV. Docker's published port 5050 is not used by native OCI LXC.",
|
||||
"Temporary uploads use a separate disk volume, excluded from backups, to avoid filling RAM."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "uniextra",
|
||||
"repository": "https://github.com/uniextra/MovistarWebDAVProxy",
|
||||
"revision": "e48485bc8bdf9745caa6249fdc92db6d28214549",
|
||||
"image_repository_url": "https://hub.docker.com/r/uniextra/movistar-webdav-proxy",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "e51607e979c1a776ececda038caeffb4195f443ebc017eba753a4b4ff8fd5c28",
|
||||
"generated_at": "2026-11-02T23:42:04+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/uniextra/MovistarWebDAVProxy/e48485bc8bdf9745caa6249fdc92db6d28214549/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "movistar-webdav-proxy",
|
||||
"container_name": "movistar-webdav-proxy",
|
||||
"image": {
|
||||
"reference": "uniextra/movistar-webdav-proxy:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "uniextra/movistar-webdav-proxy",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "WEBDAV_USER",
|
||||
"example": "admin",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "WEBDAV_PASSWORD",
|
||||
"example": "",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "docker-compose",
|
||||
"prompt": "WebDAV and dashboard password (leave empty to generate)"
|
||||
},
|
||||
{
|
||||
"name": "REQUIRE_AUTH",
|
||||
"example": "true",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "TOKENS_ENCRYPTION_KEY",
|
||||
"example": "",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "MAX_UPLOAD_MB",
|
||||
"example": "4096",
|
||||
"required": false,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "tokens",
|
||||
"container_path": "/app/tokens",
|
||||
"compose_source_example": "./tokens",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 16
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "uploads",
|
||||
"container_path": "/tmp",
|
||||
"compose_source_example": "./tmp",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 16
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 5000,
|
||||
"published_example": 5000,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
},
|
||||
{
|
||||
"container_port": 8080,
|
||||
"published_example": 8080,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "services:\n movistar-webdav-proxy:\n image: uniextra/movistar-webdav-proxy:v2.1.0\n container_name: movistar-webdav-proxy\n restart: unless-stopped\n read_only: true\n tmpfs:\n - /tmp\n security_opt:\n - no-new-privileges:true\n environment:\n - WEBDAV_USER=${WEBDAV_USER:-}\n - WEBDAV_PASSWORD=${WEBDAV_PASSWORD:-}\n - WEBUI_USER=${WEBUI_USER:-}\n - WEBUI_PASSWORD=${WEBUI_PASSWORD:-}\n ports:\n - \"${BIND_IP:-0.0.0.0}:${WEB_PORT:-5000}:5000\" # Panel Web de gestión y logs (usa BIND_IP=127.0.0.1 para acceso solo local)\n - \"${BIND_IP:-0.0.0.0}:${WEBDAV_PORT:-5050}:8080\" # Endpoint WebDAV (Duplicati / Synology HyperBackup)\n volumes:\n - movistar_tokens:/app/tokens\n\nvolumes:\n movistar_tokens:\n name: movistar_webdav_tokens\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "movistar-webdav-proxy",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "movistar-webdav-proxy",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "movistar-webdav-proxy",
|
||||
"image": "uniextra/movistar-webdav-proxy:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"environment": {
|
||||
"MAX_UPLOAD_MB": "4096",
|
||||
"REQUIRE_AUTH": "true",
|
||||
"TOKENS_ENCRYPTION_KEY": "${GENERATED_TOKENS_ENCRYPTION_KEY}",
|
||||
"WEBDAV_PASSWORD": "${GENERATED_WEBDAV_PASSWORD}",
|
||||
"WEBDAV_USER": "admin"
|
||||
},
|
||||
"image": "uniextra/movistar-webdav-proxy:latest",
|
||||
"ports": [
|
||||
"5000:5000",
|
||||
"8080:8080"
|
||||
],
|
||||
"volumes": [
|
||||
"./tokens:/app/tokens",
|
||||
"./tmp:/tmp"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "movistar-webdav-proxy"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "movistar-webdav-proxy-volume-0",
|
||||
"service": "movistar-webdav-proxy",
|
||||
"container_path": "/app/tokens",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": false,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "movistar-webdav-proxy-volume-1",
|
||||
"service": "movistar-webdav-proxy",
|
||||
"container_path": "/tmp",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": false,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"movistar-webdav-proxy"
|
||||
],
|
||||
"stop_order": [
|
||||
"movistar-webdav-proxy"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "tokens-encryption-key",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "movistar-webdav-proxy",
|
||||
"environment_variable": "TOKENS_ENCRYPTION_KEY"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "webdav-password",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "movistar-webdav-proxy",
|
||||
"environment_variable": "WEBDAV_PASSWORD"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Web dashboard",
|
||||
"scheme": "http",
|
||||
"port": 5000,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"label": "WebDAV",
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/",
|
||||
"source": "native-container-port"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "Web dashboard and WebDAV",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "admin",
|
||||
"username_environment": "WEBDAV_USER",
|
||||
"password": null,
|
||||
"password_environment": "WEBDAV_PASSWORD",
|
||||
"change_required": false,
|
||||
"source": "installer-generated",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 1,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "disk-backed-upload-scratch",
|
||||
"upstream_behavior": "Compose mounts /tmp as a tmpfs.",
|
||||
"native_lxc_behavior": "A separate managed disk volume provides /tmp and is excluded from backups.",
|
||||
"reason": "Uploads can reach 4096 MB; a disk-backed scratch volume avoids consuming the LXC RAM limit.",
|
||||
"behavioral_impact": "Scratch data uses disk and can survive a restart; the application removes completed temporary uploads.",
|
||||
"validation": "passed-in-lab"
|
||||
},
|
||||
{
|
||||
"id": "native-rootfs-permissions",
|
||||
"upstream_behavior": "Docker Compose requests read_only for the root filesystem.",
|
||||
"native_lxc_behavior": "Proxmox uses a writable native root disk; /app is owned by root, while the upstream entrypoint drops to UID 10001. Tokens and upload scratch have separate writable volumes.",
|
||||
"reason": "The Proxmox pre-start setup requires a writable root disk. Protect application code through root ownership instead of declaring unsupported read-only startup.",
|
||||
"behavioral_impact": "This is not a fully read-only root filesystem; the application user cannot replace the root-owned application directory or binaries.",
|
||||
"validation": "passed-in-lab"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/app",
|
||||
"remove_lost_found": false,
|
||||
"owner_strategy": "mapped-root",
|
||||
"mode": "0755"
|
||||
},
|
||||
{
|
||||
"container_path": "/app/tokens",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-application-user",
|
||||
"mode": "0700"
|
||||
},
|
||||
{
|
||||
"container_path": "/tmp",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-application-user",
|
||||
"mode": "1777"
|
||||
}
|
||||
],
|
||||
"volume_owner": {
|
||||
"uid": 10001,
|
||||
"gid": 10001
|
||||
},
|
||||
"generated_sensitive_environment": {
|
||||
"WEBDAV_PASSWORD": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 16,
|
||||
"prompt": true
|
||||
},
|
||||
"TOKENS_ENCRYPTION_KEY": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32,
|
||||
"prompt": false
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"options": {
|
||||
"no_new_privileges": true
|
||||
}
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 5000,
|
||||
"path": "/health",
|
||||
"timeout_seconds": 90,
|
||||
"request_timeout_seconds": 5,
|
||||
"stability_seconds": 4,
|
||||
"verify_tls": false
|
||||
},
|
||||
"completion_notes": [
|
||||
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.",
|
||||
"WebDAV is available on container port 8080. Account linking is required before cloud file operations."
|
||||
]
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"stop_signal",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "passed",
|
||||
"service_health": "passed",
|
||||
"restart_persistence": "passed",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -9980,6 +9980,39 @@
|
||||
"hidden": false,
|
||||
"template_id": "image-motioneye"
|
||||
},
|
||||
{
|
||||
"id": "movistar-webdav-proxy",
|
||||
"provider": "uniextra",
|
||||
"template_family": "curated-profile",
|
||||
"title": "Movistar / O2 Cloud WebDAV Proxy",
|
||||
"repository": "https://github.com/uniextra/MovistarWebDAVProxy",
|
||||
"description": "Official uniextra image with a web dashboard for Movistar/O2 Cloud account linking. Persistent OAuth credentials, authenticated WebDAV and disk-backed temporary uploads.",
|
||||
"website": "https://github.com/uniextra/MovistarWebDAVProxy",
|
||||
"icon": "https://raw.githubusercontent.com/uniextra/MovistarWebDAVProxy/main/static/favicon.svg",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "uniextra/movistar-webdav-proxy:latest",
|
||||
"category": "backup",
|
||||
"category_label": "Backup & Recovery",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/movistar-webdav-proxy.json",
|
||||
"template_id": "image-movistar-webdav-proxy",
|
||||
"template": "apps/movistar-webdav-proxy.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"hidden": false,
|
||||
"automatic_install_candidate": true,
|
||||
"untranslated_blockers": [],
|
||||
"requires_privileged_lxc": false,
|
||||
"optional_privileged_lxc": false,
|
||||
"requires_host_pid_namespace": false,
|
||||
"requires_relaxed_confinement": false,
|
||||
"optional_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"multi_container": false
|
||||
},
|
||||
{
|
||||
"id": "msedge",
|
||||
"provider": "linuxserver.io",
|
||||
|
||||
@@ -187,6 +187,24 @@ def _split_short_mount(value: str) -> tuple[str | None, str, str | None]:
|
||||
return ":".join(parts[:-2]), parts[-2], parts[-1]
|
||||
|
||||
|
||||
# Host device nodes a Compose file may bind as a volume. They are passed to
|
||||
# the LXC as devices: a mount at that path would hide the device.
|
||||
DEVICE_NODE_BINDS = ("/dev/net/tun", "/dev/fuse", "/dev/kvm")
|
||||
|
||||
|
||||
def _device_bind(item: Any) -> str | None:
|
||||
"""The `source:target` of a volume that binds a host device node."""
|
||||
if isinstance(item, dict):
|
||||
if item.get("type", "bind") != "bind":
|
||||
return None
|
||||
source, target = item.get("source"), item.get("target")
|
||||
else:
|
||||
source, target, _ = _split_short_mount(str(item))
|
||||
if str(source or "") in DEVICE_NODE_BINDS and str(target or "") == str(source):
|
||||
return f"{source}:{target}"
|
||||
return None
|
||||
|
||||
|
||||
def _mount_contract(value: Any, optional: set[str]) -> list[dict[str, Any]]:
|
||||
if value is None:
|
||||
return []
|
||||
@@ -194,6 +212,8 @@ def _mount_contract(value: Any, optional: set[str]) -> list[dict[str, Any]]:
|
||||
raise ConversionError("volumes must be a list")
|
||||
result: list[dict[str, Any]] = []
|
||||
for index, item in enumerate(value):
|
||||
if _device_bind(item):
|
||||
continue
|
||||
if isinstance(item, dict):
|
||||
source = item.get("source")
|
||||
target = item.get("target")
|
||||
@@ -606,6 +626,10 @@ def _device_installer_profile(
|
||||
) -> tuple[dict[str, Any], list[str]]:
|
||||
optional = optional or set()
|
||||
raw_devices = service.get("devices")
|
||||
volumes = service.get("volumes")
|
||||
device_binds = [bind for bind in map(_device_bind, volumes) if bind] if isinstance(volumes, list) else []
|
||||
if device_binds and (raw_devices is None or isinstance(raw_devices, list)):
|
||||
raw_devices = [*(raw_devices or []), *device_binds]
|
||||
requests: list[dict[str, Any]] = []
|
||||
blockers: list[str] = []
|
||||
nvidia_requested = _nvidia_requested(service)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
"""A Compose volume that binds a host device node, such as /dev/net/tun for
|
||||
Tailscale, is passed to the LXC as a device: a mount there hides the device."""
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
||||
from proxmenux_oci import converter
|
||||
|
||||
|
||||
class DeviceNodeBindTests(unittest.TestCase):
|
||||
service = {"image": "tailscale/tailscale:latest", "volumes": [
|
||||
{"type": "bind", "source": "/DATA/AppData/tailscale", "target": "/var/lib/tailscale"},
|
||||
{"type": "bind", "source": "/dev/net/tun", "target": "/dev/net/tun"},
|
||||
"/dev/fuse:/dev/fuse"]}
|
||||
|
||||
def test_device_nodes_are_not_volumes(self):
|
||||
mounts = converter._mount_contract(self.service["volumes"], set())
|
||||
self.assertEqual([m["container_path"] for m in mounts], ["/var/lib/tailscale"])
|
||||
|
||||
def test_device_nodes_become_device_requests(self):
|
||||
profile, blockers = converter._device_installer_profile(self.service)
|
||||
self.assertEqual(blockers, [])
|
||||
self.assertEqual([(r["id"], r["container_path"]) for r in profile["device_requests"]],
|
||||
[("dev-net-tun", "/dev/net/tun"), ("dev-fuse", "/dev/fuse")])
|
||||
|
||||
def test_a_device_directory_is_left_to_its_own_handling(self):
|
||||
self.assertIsNone(converter._device_bind("/dev/dri:/dev/dri"))
|
||||
self.assertIsNone(converter._device_bind({"type": "volume", "source": "/dev/net/tun", "target": "/dev/net/tun"}))
|
||||
|
||||
def test_the_tailscale_recipe_passes_the_tun_device(self):
|
||||
import json
|
||||
recipe = json.loads((Path(__file__).resolve().parents[1] / "catalog/apps/tailscale.json").read_text())
|
||||
self.assertNotIn("/dev/net/tun", [v["container_path"] for v in recipe["container_contract"]["volumes"]])
|
||||
self.assertIn("dev-net-tun", [r["id"] for r in recipe["proxmox"]["installer_profile"]["device_requests"]])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user