mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-05 20:32:15 +00:00
Merge pull request #590 from jcastro/feature/oci-nextcloud-mariadb
feat(oci): add LinuxServer Nextcloud with MariaDB and Redis
This commit is contained in:
@@ -1644,6 +1644,7 @@
|
||||
"Create scheduled backup job": "Erstellen Sie einen geplanten Sicherungsauftrag",
|
||||
"Create share directory:": "Freigabeverzeichnis erstellen:",
|
||||
"Create shared directory:": "Freigegebenes Verzeichnis erstellen:",
|
||||
"ProxMenux generates the administrator password and shows it at the end of the installation. Change it after the first login.": "ProxMenux erzeugt das Administratorpasswort und zeigt es am Ende der Installation an. Ändern Sie es nach der ersten Anmeldung.",
|
||||
"Create this LXC in privileged mode?": "Erstellen Sie diese LXC im privilegierten Modus?",
|
||||
"Create with create_user in the container console": "Erstellen Sie den Benutzer mit create_user in der Container-Konsole",
|
||||
"Create, send and sign documents with a self-hosted web app.": "Erstelle, versende und signiere Dokumente mit einer selbst gehosteten Web-App.",
|
||||
@@ -3904,6 +3905,7 @@
|
||||
"Linux/Mac path:": "Linux/Mac-Pfad:",
|
||||
"LinuxServer Jellyfin with optional GPU passthrough": "LinuxServer Jellyfin mit optionalem GPU-Passthrough",
|
||||
"LinuxServer MariaDB requires a user, database and password": "LinuxServer MariaDB requires ein Benutzer, Datenbank und Passwort",
|
||||
"LinuxServer Nextcloud with MariaDB and Redis": "LinuxServer Nextcloud mit MariaDB und Redis",
|
||||
"List Available Disks": "Verfügbare Festplatten auflisten",
|
||||
"List IOMMU group mapping": "IOMMU-Gruppenzuordnung auflisten",
|
||||
"List NVMe devices": "NVMe-Geräte auflisten",
|
||||
@@ -4484,6 +4486,7 @@
|
||||
"Next Step Required": "Nächster Schritt erforderlich",
|
||||
"Next Steps:": "Nächste Schritte:",
|
||||
"Next step: stop that VM first, then run": "Nächster Schritt: Stoppen Sie zuerst die VM und führen Sie sie dann aus",
|
||||
"Nextcloud Web UI": "Nextcloud-Weboberfläche",
|
||||
"Nextcloud configuration cancelled": "Nextcloud-Konfiguration gestrichen",
|
||||
"Nextcloud gives you access to all your files wherever you are.": "Nextcloud bietet Ihnen Zugriff auf alle Ihre Dateien, wo immer Sie sind.",
|
||||
"Nextcloud volume size in GB": "Nextcloud Volumengröße in GB",
|
||||
@@ -5605,6 +5608,7 @@
|
||||
"Recreation prepared": "Erholung vorbereitet",
|
||||
"Recursive DNS resolver.": "Rekursiver DNS-Resolver.",
|
||||
"Recursive and authoritative DNS server.": "Rekursiver und autoritativer DNS-Server.",
|
||||
"Redis locking is configured automatically. Existing Nextcloud configuration files are preserved.": "Die Dateisperre mit Redis wird automatisch eingerichtet. Vorhandene Nextcloud-Konfigurationsdateien bleiben erhalten.",
|
||||
"Redmine": "Redmine",
|
||||
"Refresh APT index and verify repositories:": "APT-Index aktualisieren und Repositorys überprüfen:",
|
||||
"Refresh catalog": "Katalog aktualisieren",
|
||||
@@ -7995,6 +7999,7 @@
|
||||
"Use a privileged LXC for NFS server/client workflows.": "Verwenden Sie einen privilegierten LXC für NFS-Server-/Client-Workflows.",
|
||||
"Use a privileged LXC for Samba client/server workflows.": "Verwenden Sie einen privilegierten LXC für Samba-Client/Server-Workflows.",
|
||||
"Use a registry hostname, for example ghcr.io or registry.example.com:5000.": "Verwenden Sie einen Registrierungs-Hostnamen, zum Beispiel ghcr.io oder registry.example.com:5000.",
|
||||
"Use a trusted HTTPS reverse proxy. Upgrade Nextcloud one major version at a time.": "Verwenden Sie einen HTTPS-Reverse-Proxy mit einem vertrauenswürdigen Zertifikat. Aktualisieren Sie Nextcloud jeweils auf die nächste Hauptversion, ohne eine zu überspringen.",
|
||||
"Use an existing SSH private key file on this host": "Verwenden Sie eine vorhandene private SSH-Schlüsseldatei auf diesem Host",
|
||||
"Use an existing keyfile": "Verwenden Sie eine vorhandene Schlüsseldatei",
|
||||
"Use an image reference, for example ghcr.io/owner/app:latest.": "Verwenden Sie eine Bildreferenz, zum Beispiel ghcr.io/owner/app:latest.",
|
||||
@@ -8008,6 +8013,7 @@
|
||||
"Use existing filesystem": "Vorhandenes Dateisystem verwenden",
|
||||
"Use existing: mount without formatting": "Vorhandenes verwenden: mounten ohne Formatierung",
|
||||
"Use images only if the directory is on suitable storage.": "Verwenden Sie Bilder nur, wenn sich das Verzeichnis auf einem geeigneten Speicher befindet.",
|
||||
"Use managed storage for /config and MariaDB. A host/NAS directory can be selected for /data and needs a separate backup.": "Verwenden Sie verwalteten Speicher für /config und MariaDB. Für /data können Sie ein Verzeichnis auf dem Host/NAS auswählen, das eine eigene Sicherung benötigt.",
|
||||
"Use mp1/mp2/... for extra mount points.": "Verwenden Sie mp1/mp2/... für zusätzliche Mount-Punkte.",
|
||||
"Use only when unprivileged containers cannot meet your needs": "Verwenden Sie es nur, wenn nicht privilegierte Container Ihre Anforderungen nicht erfüllen können",
|
||||
"Use option 1 to add a local disk (as Proxmox storage and/or as a host mount).": "Verwenden Sie Option 1, um eine lokale Festplatte hinzuzufügen (als Proxmox-Speicher und/oder als Host-Mount).",
|
||||
|
||||
@@ -1642,6 +1642,7 @@
|
||||
"Create scheduled backup job": "Crear trabajo de backup programado",
|
||||
"Create share directory:": "Crear directorio compartido:",
|
||||
"Create shared directory:": "Crear directorio compartido:",
|
||||
"ProxMenux generates the administrator password and shows it at the end of the installation. Change it after the first login.": "ProxMenux genera la contraseña del administrador y la muestra al final de la instalación. Cámbiala después del primer inicio de sesión.",
|
||||
"Create this LXC in privileged mode?": "¿Crear este LXC en modo privilegiado?",
|
||||
"Create with create_user in the container console": "Crea el usuario con create_user desde la consola del contenedor",
|
||||
"Create, send and sign documents with a self-hosted web app.": "Crea, envía y firma documentos con una aplicación web autoalojada.",
|
||||
@@ -3899,6 +3900,7 @@
|
||||
"Linux/Mac path:": "Ruta Linux/Mac:",
|
||||
"LinuxServer Jellyfin with optional GPU passthrough": "Jellyfin de LinuxServer con passthrough de GPU opcional",
|
||||
"LinuxServer MariaDB requires a user, database and password": "LinuxServer MariaDB requiere un usuario, base de datos y contraseña",
|
||||
"LinuxServer Nextcloud with MariaDB and Redis": "Nextcloud de LinuxServer con MariaDB y Redis",
|
||||
"List Available Disks": "Listar discos disponibles",
|
||||
"List IOMMU group mapping": "Listar el mapeo del grupo IOMMU",
|
||||
"List NVMe devices": "Listar dispositivos NVMe",
|
||||
@@ -4479,6 +4481,7 @@
|
||||
"Next Step Required": "Se requiere el siguiente paso",
|
||||
"Next Steps:": "Próximos pasos:",
|
||||
"Next step: stop that VM first, then run": "Siguiente paso: detén esa VM primero y luego ejecuta",
|
||||
"Nextcloud Web UI": "Interfaz web de Nextcloud",
|
||||
"Nextcloud configuration cancelled": "Configuración Nextcloud cancelada",
|
||||
"Nextcloud gives you access to all your files wherever you are.": "Nextcloud te da acceso a todos tus archivos estés donde estés.",
|
||||
"Nextcloud volume size in GB": "Tamaño del volumen de Nextcloud en GB",
|
||||
@@ -5588,6 +5591,7 @@
|
||||
"Recreating the container:": "Recreando el contenedor:",
|
||||
"Recursive DNS resolver.": "Resolvedor DNS recursivo.",
|
||||
"Recursive and authoritative DNS server.": "Servidor DNS recursivo y autoritativo.",
|
||||
"Redis locking is configured automatically. Existing Nextcloud configuration files are preserved.": "El bloqueo con Redis se configura automáticamente. Se conservan los archivos de configuración existentes de Nextcloud.",
|
||||
"Redmine": "Redmine",
|
||||
"Refresh APT index and verify repositories:": "Actualizar el índice APT y verificar los repositorios:",
|
||||
"Refresh catalog": "Actualizar catálogo",
|
||||
@@ -7966,6 +7970,7 @@
|
||||
"Use a privileged LXC for NFS server/client workflows.": "Utiliza un LXC privilegiado para flujos de trabajo de servidor/cliente NFS.",
|
||||
"Use a privileged LXC for Samba client/server workflows.": "Utiliza un LXC privilegiado para flujos de trabajo de cliente/servidor Samba.",
|
||||
"Use a registry hostname, for example ghcr.io or registry.example.com:5000.": "Escribe el nombre de un registro, por ejemplo ghcr.io o registry.example.com:5000.",
|
||||
"Use a trusted HTTPS reverse proxy. Upgrade Nextcloud one major version at a time.": "Usa un proxy inverso HTTPS con un certificado de confianza. Actualiza Nextcloud de una versión principal a la siguiente, sin saltarte ninguna.",
|
||||
"Use an existing SSH private key file on this host": "Usar un archivo de clave privada SSH existente en este host",
|
||||
"Use an existing keyfile": "Usar un archivo de claves existente",
|
||||
"Use an image reference, for example ghcr.io/owner/app:latest.": "Escribe una referencia de imagen, por ejemplo ghcr.io/owner/app:latest.",
|
||||
@@ -7979,6 +7984,7 @@
|
||||
"Use existing filesystem": "Usar el sistema de archivos existente",
|
||||
"Use existing: mount without formatting": "Usar existente: montar sin formatear",
|
||||
"Use images only if the directory is on suitable storage.": "Utiliza imágenes solo si el directorio está en un almacenamiento adecuado.",
|
||||
"Use managed storage for /config and MariaDB. A host/NAS directory can be selected for /data and needs a separate backup.": "Usa almacenamiento gestionado para /config y MariaDB. Para /data puedes elegir un directorio del host/NAS, que necesita su propia copia de seguridad.",
|
||||
"Use mp1/mp2/... for extra mount points.": "Utiliza mp1/mp2/... para puntos de montaje adicionales.",
|
||||
"Use only when unprivileged containers cannot meet your needs": "Úselo solo cuando los contenedores sin privilegios no puedan satisfacer sus necesidades",
|
||||
"Use option 1 to add a local disk (as Proxmox storage and/or as a host mount).": "Utiliza la opción 1 para añadir un disco local (como almacenamiento Proxmox y/o como montaje de host).",
|
||||
|
||||
@@ -1644,6 +1644,7 @@
|
||||
"Create scheduled backup job": "Créer une tâche de sauvegarde planifiée",
|
||||
"Create share directory:": "Créer un répertoire de partage :",
|
||||
"Create shared directory:": "Créer un répertoire partagé :",
|
||||
"ProxMenux generates the administrator password and shows it at the end of the installation. Change it after the first login.": "ProxMenux génère le mot de passe de l'administrateur et l'affiche à la fin de l'installation. Modifiez-le après la première connexion.",
|
||||
"Create this LXC in privileged mode?": "Créer ce LXC en mode privilégié ?",
|
||||
"Create with create_user in the container console": "Créez l’utilisateur avec create_user dans la console du conteneur",
|
||||
"Create, send and sign documents with a self-hosted web app.": "Créez, envoyez et signez des documents avec une application web auto-hébergée.",
|
||||
@@ -3904,6 +3905,7 @@
|
||||
"Linux/Mac path:": "Chemin Linux/Mac :",
|
||||
"LinuxServer Jellyfin with optional GPU passthrough": "LinuxServer Jellyfin avec passage GPU optionnel",
|
||||
"LinuxServer MariaDB requires a user, database and password": "LinuxServer MariaDB requires un utilisateur, une base de données et un mot de passe",
|
||||
"LinuxServer Nextcloud with MariaDB and Redis": "Nextcloud de LinuxServer avec MariaDB et Redis",
|
||||
"List Available Disks": "Liste des disques disponibles",
|
||||
"List IOMMU group mapping": "Répertorier le mappage de groupe IOMMU",
|
||||
"List NVMe devices": "Répertorier les appareils NVMe",
|
||||
@@ -4484,6 +4486,7 @@
|
||||
"Next Step Required": "Prochaine étape requise",
|
||||
"Next Steps:": "Prochaines étapes :",
|
||||
"Next step: stop that VM first, then run": "Étape suivante : arrêtez d'abord cette VM, puis exécutez",
|
||||
"Nextcloud Web UI": "Interface web de Nextcloud",
|
||||
"Nextcloud configuration cancelled": "Configuration Nextcloud annulée",
|
||||
"Nextcloud gives you access to all your files wherever you are.": "Nextcloud vous donne accès à tous vos fichiers où que vous soyez.",
|
||||
"Nextcloud volume size in GB": "Taille du volume Nextcloud en GB",
|
||||
@@ -5605,6 +5608,7 @@
|
||||
"Recreation prepared": "Loisirs préparés",
|
||||
"Recursive DNS resolver.": "Résolveur DNS récursif.",
|
||||
"Recursive and authoritative DNS server.": "Serveur DNS récursif et faisant autorité.",
|
||||
"Redis locking is configured automatically. Existing Nextcloud configuration files are preserved.": "Le verrouillage avec Redis est configuré automatiquement. Les fichiers de configuration existants de Nextcloud sont conservés.",
|
||||
"Redmine": "Redmine",
|
||||
"Refresh APT index and verify repositories:": "Actualisez l'index APT et vérifiez les référentiels :",
|
||||
"Refresh catalog": "Actualiser le catalogue",
|
||||
@@ -7994,6 +7998,7 @@
|
||||
"Use a privileged LXC for NFS server/client workflows.": "Utilisez un LXC privilégié pour les workflows serveur/client NFS.",
|
||||
"Use a privileged LXC for Samba client/server workflows.": "Utilisez un LXC privilégié pour les workflows client/serveur Samba.",
|
||||
"Use a registry hostname, for example ghcr.io or registry.example.com:5000.": "Utilisez un nom d'hôte de registre, par exemple ghcr.io ou registry.example.com:5000.",
|
||||
"Use a trusted HTTPS reverse proxy. Upgrade Nextcloud one major version at a time.": "Utilisez un proxy inverse HTTPS avec un certificat de confiance. Mettez Nextcloud à niveau vers la version majeure suivante, sans en sauter.",
|
||||
"Use an existing SSH private key file on this host": "Utiliser un fichier de clé privée SSH existant sur cet hôte",
|
||||
"Use an existing keyfile": "utiliser un fichier de clés existant",
|
||||
"Use an image reference, for example ghcr.io/owner/app:latest.": "Utilisez une référence d'image, par exemple ghcr.io/owner/app:latest.",
|
||||
@@ -8007,6 +8012,7 @@
|
||||
"Use existing filesystem": "Utiliser le système de fichiers existant",
|
||||
"Use existing: mount without formatting": "Utiliser existant : monter sans formatage",
|
||||
"Use images only if the directory is on suitable storage.": "Utilisez des images uniquement si le répertoire se trouve sur un stockage approprié.",
|
||||
"Use managed storage for /config and MariaDB. A host/NAS directory can be selected for /data and needs a separate backup.": "Utilisez un stockage géré pour /config et MariaDB. Pour /data, vous pouvez choisir un répertoire de l’hôte/NAS, qui nécessite sa propre sauvegarde.",
|
||||
"Use mp1/mp2/... for extra mount points.": "Utilisez mp1/mp2/... pour des points de montage supplémentaires.",
|
||||
"Use only when unprivileged containers cannot meet your needs": "À utiliser uniquement lorsque les conteneurs non privilégiés ne peuvent pas répondre à vos besoins",
|
||||
"Use option 1 to add a local disk (as Proxmox storage and/or as a host mount).": "Utilisez l'option 1 pour ajouter un disque local (comme stockage Proxmox et/ou comme montage hôte).",
|
||||
|
||||
@@ -1644,6 +1644,7 @@
|
||||
"Create scheduled backup job": "Crea attività di backup pianificata",
|
||||
"Create share directory:": "Crea directory condivisa:",
|
||||
"Create shared directory:": "Crea directory condivisa:",
|
||||
"ProxMenux generates the administrator password and shows it at the end of the installation. Change it after the first login.": "ProxMenux genera la password dell'amministratore e la mostra alla fine dell'installazione. Cambiala dopo il primo accesso.",
|
||||
"Create this LXC in privileged mode?": "Creare questo LXC in modalità privilegiata?",
|
||||
"Create with create_user in the container console": "Crea l’utente con create_user nella console del container",
|
||||
"Create, send and sign documents with a self-hosted web app.": "Crea, invia e firma documenti con un'app web self-hosted.",
|
||||
@@ -3904,6 +3905,7 @@
|
||||
"Linux/Mac path:": "Percorso Linux/Mac:",
|
||||
"LinuxServer Jellyfin with optional GPU passthrough": "LinuxServer Jellyfin con passthrough GPU opzionale",
|
||||
"LinuxServer MariaDB requires a user, database and password": "LinuxServer MariaDB richiede un utente, un database e una password",
|
||||
"LinuxServer Nextcloud with MariaDB and Redis": "Nextcloud di LinuxServer con MariaDB e Redis",
|
||||
"List Available Disks": "Elenca i dischi disponibili",
|
||||
"List IOMMU group mapping": "Elenca la mappatura dei gruppi IOMMU",
|
||||
"List NVMe devices": "Elenca i dispositivi NVMe",
|
||||
@@ -4484,6 +4486,7 @@
|
||||
"Next Step Required": "Passaggio successivo obbligatorio",
|
||||
"Next Steps:": "Passaggi successivi:",
|
||||
"Next step: stop that VM first, then run": "Passaggio successivo: arresta prima la VM, quindi esegui",
|
||||
"Nextcloud Web UI": "Interfaccia web di Nextcloud",
|
||||
"Nextcloud configuration cancelled": "Configurazione di Nextcloud annullata",
|
||||
"Nextcloud gives you access to all your files wherever you are.": "Nextcloud ti dà accesso a tutti i tuoi file, ovunque ti trovi.",
|
||||
"Nextcloud volume size in GB": "Dimensione volume Nextcloud in GB",
|
||||
@@ -5605,6 +5608,7 @@
|
||||
"Recreation prepared": "Ricreazione preparata",
|
||||
"Recursive DNS resolver.": "Resolver DNS ricorsivo.",
|
||||
"Recursive and authoritative DNS server.": "Server DNS ricorsivo e autorevole.",
|
||||
"Redis locking is configured automatically. Existing Nextcloud configuration files are preserved.": "Il blocco dei file con Redis viene configurato automaticamente. I file di configurazione esistenti di Nextcloud vengono conservati.",
|
||||
"Redmine": "Redmine",
|
||||
"Refresh APT index and verify repositories:": "Aggiorna l'indice APT e verifica i repository:",
|
||||
"Refresh catalog": "Aggiorna catalogo",
|
||||
@@ -7995,6 +7999,7 @@
|
||||
"Use a privileged LXC for NFS server/client workflows.": "Usare un LXC privilegiato per le operazioni server/client NFS.",
|
||||
"Use a privileged LXC for Samba client/server workflows.": "Usare un LXC privilegiato per le operazioni client/server Samba.",
|
||||
"Use a registry hostname, for example ghcr.io or registry.example.com:5000.": "Utilizza un nome host del registro, ad esempio ghcr.io o registry.example.com:5000.",
|
||||
"Use a trusted HTTPS reverse proxy. Upgrade Nextcloud one major version at a time.": "Usa un proxy inverso HTTPS con un certificato attendibile. Aggiorna Nextcloud alla versione principale successiva, senza saltarne nessuna.",
|
||||
"Use an existing SSH private key file on this host": "Usa un file di chiave privata SSH esistente su questo host",
|
||||
"Use an existing keyfile": "Usa file di chiavi esistente",
|
||||
"Use an image reference, for example ghcr.io/owner/app:latest.": "Utilizza un riferimento a un'immagine, ad esempio ghcr.io/owner/app:latest.",
|
||||
@@ -8008,6 +8013,7 @@
|
||||
"Use existing filesystem": "Usa file system esistente",
|
||||
"Use existing: mount without formatting": "Usa esistente: monta senza formattare",
|
||||
"Use images only if the directory is on suitable storage.": "Usare images solo se la directory è su uno storage adatto.",
|
||||
"Use managed storage for /config and MariaDB. A host/NAS directory can be selected for /data and needs a separate backup.": "Usa lo storage gestito per /config e MariaDB. Per /data puoi scegliere una directory dell’host/NAS, che richiede un backup separato.",
|
||||
"Use mp1/mp2/... for extra mount points.": "Usare mp1/mp2/... per mount aggiuntivi.",
|
||||
"Use only when unprivileged containers cannot meet your needs": "Usare solo se i container non privilegiati non soddisfano le esigenze",
|
||||
"Use option 1 to add a local disk (as Proxmox storage and/or as a host mount).": "Usare l’opzione 1 per aggiungere un disco locale (come storage Proxmox e/o mount host).",
|
||||
|
||||
@@ -1644,6 +1644,7 @@
|
||||
"Create scheduled backup job": "Criar tarefa de backup agendada",
|
||||
"Create share directory:": "Crie um diretório de compartilhamento:",
|
||||
"Create shared directory:": "Crie um diretório compartilhado:",
|
||||
"ProxMenux generates the administrator password and shows it at the end of the installation. Change it after the first login.": "O ProxMenux gera a senha do administrador e mostra-a no fim da instalação. Altere-a após o primeiro login.",
|
||||
"Create this LXC in privileged mode?": "Criar este LXC em modo privilegiado?",
|
||||
"Create with create_user in the container console": "Crie o utilizador com create_user na consola do contentor",
|
||||
"Create, send and sign documents with a self-hosted web app.": "Crie, envie e assine documentos com uma aplicação web autoalojada.",
|
||||
@@ -3904,6 +3905,7 @@
|
||||
"Linux/Mac path:": "Caminho Linux/Mac:",
|
||||
"LinuxServer Jellyfin with optional GPU passthrough": "LinuxServer Jellyfin com passagem opcional de GPU",
|
||||
"LinuxServer MariaDB requires a user, database and password": "LinuxServer MariaDB requires um usuário, banco de dados e senha",
|
||||
"LinuxServer Nextcloud with MariaDB and Redis": "Nextcloud da LinuxServer com MariaDB e Redis",
|
||||
"List Available Disks": "Listar discos disponíveis",
|
||||
"List IOMMU group mapping": "Listar mapeamento de grupo IOMMU",
|
||||
"List NVMe devices": "Listar dispositivos NVMe",
|
||||
@@ -4484,6 +4486,7 @@
|
||||
"Next Step Required": "Próxima etapa obrigatória",
|
||||
"Next Steps:": "Próximas etapas:",
|
||||
"Next step: stop that VM first, then run": "Próxima etapa: pare a VM primeiro e depois execute",
|
||||
"Nextcloud Web UI": "Interface web do Nextcloud",
|
||||
"Nextcloud configuration cancelled": "Configuração do Nextcloud cancelada",
|
||||
"Nextcloud gives you access to all your files wherever you are.": "O Nextcloud dá-lhe acesso a todos os seus ficheiros onde quer que esteja.",
|
||||
"Nextcloud volume size in GB": "Tamanho do volume Nextcloud em GB",
|
||||
@@ -5605,6 +5608,7 @@
|
||||
"Recreation prepared": "Recreação preparada",
|
||||
"Recursive DNS resolver.": "Resolvedor DNS recursivo.",
|
||||
"Recursive and authoritative DNS server.": "Servidor DNS recursivo e autoritativo.",
|
||||
"Redis locking is configured automatically. Existing Nextcloud configuration files are preserved.": "O bloqueio de ficheiros com Redis é configurado automaticamente. Os ficheiros de configuração existentes do Nextcloud são preservados.",
|
||||
"Redmine": "Redmine",
|
||||
"Refresh APT index and verify repositories:": "Atualize o índice APT e verifique os repositórios:",
|
||||
"Refresh catalog": "Atualizar catálogo",
|
||||
@@ -7995,6 +7999,7 @@
|
||||
"Use a privileged LXC for NFS server/client workflows.": "Use um LXC privilegiado para fluxos de trabalho de servidor/cliente NFS.",
|
||||
"Use a privileged LXC for Samba client/server workflows.": "Use um LXC privilegiado para fluxos de trabalho cliente/servidor Samba.",
|
||||
"Use a registry hostname, for example ghcr.io or registry.example.com:5000.": "Use um nome de host de registro, por exemplo ghcr.io ou registry.example.com:5000.",
|
||||
"Use a trusted HTTPS reverse proxy. Upgrade Nextcloud one major version at a time.": "Use um proxy inverso HTTPS com um certificado de confiança. Atualize o Nextcloud para a versão principal seguinte, sem saltar nenhuma.",
|
||||
"Use an existing SSH private key file on this host": "Use um arquivo de chave privada SSH existente neste host",
|
||||
"Use an existing keyfile": "Use um arquivo-chave existente",
|
||||
"Use an image reference, for example ghcr.io/owner/app:latest.": "Use uma referência de imagem, por exemplo ghcr.io/owner/app:latest.",
|
||||
@@ -8008,6 +8013,7 @@
|
||||
"Use existing filesystem": "Use o sistema de arquivos existente",
|
||||
"Use existing: mount without formatting": "Use existente: monte sem formatação",
|
||||
"Use images only if the directory is on suitable storage.": "Use imagens somente se o diretório estiver em um armazenamento adequado.",
|
||||
"Use managed storage for /config and MariaDB. A host/NAS directory can be selected for /data and needs a separate backup.": "Use armazenamento gerido para /config e MariaDB. Para /data pode escolher um diretório do host/NAS, que precisa de uma cópia de segurança separada.",
|
||||
"Use mp1/mp2/... for extra mount points.": "Use mp1/mp2/... para pontos de montagem extras.",
|
||||
"Use only when unprivileged containers cannot meet your needs": "Use somente quando contêineres sem privilégios não atenderem às suas necessidades",
|
||||
"Use option 1 to add a local disk (as Proxmox storage and/or as a host mount).": "Use a opção 1 para adicionar um disco local (como armazenamento Proxmox e/ou como montagem de host).",
|
||||
|
||||
@@ -1644,6 +1644,7 @@
|
||||
"Create scheduled backup job": "Vytvoriť naplánovanú úlohu zálohy",
|
||||
"Create share directory:": "Vytvoriť zdieľaný priečinok:",
|
||||
"Create shared directory:": "Vytvoriť zdieľaný priečinok:",
|
||||
"ProxMenux generates the administrator password and shows it at the end of the installation. Change it after the first login.": "ProxMenux vygeneruje heslo správcu a zobrazí ho na konci inštalácie. Po prvom prihlásení ho zmeňte.",
|
||||
"Create this LXC in privileged mode?": "Vytvoriť tento LXC v privilegovanom režime?",
|
||||
"Create with create_user in the container console": "Používateľa vytvorte príkazom create_user v konzole kontajnera",
|
||||
"Create, send and sign documents with a self-hosted web app.": "Vytvárajte, posielajte a podpisujte dokumenty vo webovej aplikácii prevádzkovanej vo vlastnej réžii.",
|
||||
@@ -3904,6 +3905,7 @@
|
||||
"Linux/Mac path:": "Cesta pre Linux/Mac:",
|
||||
"LinuxServer Jellyfin with optional GPU passthrough": "LinuxServer Jellyfin s voliteľným GPU priechodom",
|
||||
"LinuxServer MariaDB requires a user, database and password": "LinuxServer MariaDB vyžaduje používateľa, databázu a heslo",
|
||||
"LinuxServer Nextcloud with MariaDB and Redis": "Nextcloud od LinuxServer s MariaDB a Redis",
|
||||
"List Available Disks": "Zobraziť dostupné disky",
|
||||
"List IOMMU group mapping": "Zobraziť mapovanie IOMMU skupín",
|
||||
"List NVMe devices": "Zobraziť NVMe zariadenia",
|
||||
@@ -4484,6 +4486,7 @@
|
||||
"Next Step Required": "Je potrebný ďalší krok",
|
||||
"Next Steps:": "Ďalšie kroky:",
|
||||
"Next step: stop that VM first, then run": "Ďalší krok: najprv zastavte tú VM, potom spustite",
|
||||
"Nextcloud Web UI": "Webové rozhranie Nextcloud",
|
||||
"Nextcloud configuration cancelled": "Konfigurácia Nextcloud zrušená",
|
||||
"Nextcloud gives you access to all your files wherever you are.": "Nextcloud vám umožní prístup ku všetkým súborom kdekoľvek ste.",
|
||||
"Nextcloud volume size in GB": "Veľkosť dátového zväzku Nextcloud v GB",
|
||||
@@ -5607,6 +5610,7 @@
|
||||
"Recreation prepared": "Pripravené rekreácie",
|
||||
"Recursive DNS resolver.": "Rekurzívny DNS resolver.",
|
||||
"Recursive and authoritative DNS server.": "Rekurzívny a autoritatívny DNS server.",
|
||||
"Redis locking is configured automatically. Existing Nextcloud configuration files are preserved.": "Zamykanie súborov pomocou Redis sa nastaví automaticky. Existujúce konfiguračné súbory Nextcloud sa zachovajú.",
|
||||
"Redmine": "Redmine",
|
||||
"Refresh APT index and verify repositories:": "Obnovte APT index a overte repozitáre:",
|
||||
"Refresh catalog": "Aktualizovať katalóg",
|
||||
@@ -7995,6 +7999,7 @@
|
||||
"Use a privileged LXC for NFS server/client workflows.": "Pre NFS server/klient používajte privilegovaný LXC.",
|
||||
"Use a privileged LXC for Samba client/server workflows.": "Pre Samba klient/server používajte privilegovaný LXC.",
|
||||
"Use a registry hostname, for example ghcr.io or registry.example.com:5000.": "Použite názov hostiteľa registra, napríklad ghcr.io alebo registry.example.com:5000.",
|
||||
"Use a trusted HTTPS reverse proxy. Upgrade Nextcloud one major version at a time.": "Použite reverzný proxy server HTTPS s dôveryhodným certifikátom. Nextcloud aktualizujte vždy na nasledujúcu hlavnú verziu, žiadnu nepreskakujte.",
|
||||
"Use an existing SSH private key file on this host": "Použiť existujúci súbor súkromného SSH kľúča na tomto hostovi",
|
||||
"Use an existing keyfile": "Použiť existujúci keyfile",
|
||||
"Use an image reference, for example ghcr.io/owner/app:latest.": "Použite odkaz na obraz, napríklad ghcr.io/owner/app:latest.",
|
||||
@@ -8008,6 +8013,7 @@
|
||||
"Use existing filesystem": "Použiť existujúci súborový systém",
|
||||
"Use existing: mount without formatting": "Použiť existujúci: pripojiť bez formátovania",
|
||||
"Use images only if the directory is on suitable storage.": "Typ images používajte iba vtedy, ak je priečinok na vhodnom úložisku.",
|
||||
"Use managed storage for /config and MariaDB. A host/NAS directory can be selected for /data and needs a separate backup.": "Pre /config a MariaDB použite spravované úložisko. Pre /data môžete vybrať adresár hostiteľa/NAS, ktorý vyžaduje samostatné zálohovanie.",
|
||||
"Use mp1/mp2/... for extra mount points.": "Pre ďalšie mount pointy použite mp1/mp2/...",
|
||||
"Use only when unprivileged containers cannot meet your needs": "Použite iba vtedy, keď neprivilegované kontajnery nestačia vašim potrebám",
|
||||
"Use option 1 to add a local disk (as Proxmox storage and/or as a host mount).": "Použite možnosť 1 na pridanie lokálneho disku (ako úložisko Proxmoxu a/alebo ako mount na hostovi).",
|
||||
|
||||
@@ -1644,6 +1644,7 @@
|
||||
"Create scheduled backup job": "Skapa schemalagt säkerhetskopieringsjobb",
|
||||
"Create share directory:": "Skapa delningskatalog:",
|
||||
"Create shared directory:": "Skapa delad katalog:",
|
||||
"ProxMenux generates the administrator password and shows it at the end of the installation. Change it after the first login.": "ProxMenux genererar administratörslösenordet och visar det i slutet av installationen. Ändra det efter första inloggningen.",
|
||||
"Create this LXC in privileged mode?": "Skapa denna LXC i privilegierat läge?",
|
||||
"Create with create_user in the container console": "Skapa användaren med create_user i containerns konsol",
|
||||
"Create, send and sign documents with a self-hosted web app.": "Skapa, skicka och signera dokument med en webbapp som du driftar själv.",
|
||||
@@ -3904,6 +3905,7 @@
|
||||
"Linux/Mac path:": "Linux/Mac sökväg:",
|
||||
"LinuxServer Jellyfin with optional GPU passthrough": "LinuxServer Jellyfin med valfri GPU genomgång",
|
||||
"LinuxServer MariaDB requires a user, database and password": "LinuxServer MariaDB requires en användare, databas och lösenord",
|
||||
"LinuxServer Nextcloud with MariaDB and Redis": "LinuxServer Nextcloud med MariaDB och Redis",
|
||||
"List Available Disks": "Lista tillgängliga diskar",
|
||||
"List IOMMU group mapping": "Lista IOMMU-gruppkartläggning",
|
||||
"List NVMe devices": "Lista NVMe-enheter",
|
||||
@@ -4484,6 +4486,7 @@
|
||||
"Next Step Required": "Nästa steg krävs",
|
||||
"Next Steps:": "Nästa steg:",
|
||||
"Next step: stop that VM first, then run": "Nästa steg: stoppa den virtuella datorn först och kör sedan",
|
||||
"Nextcloud Web UI": "Nextclouds webbgränssnitt",
|
||||
"Nextcloud configuration cancelled": "Nextcloud konfiguration annullerad",
|
||||
"Nextcloud gives you access to all your files wherever you are.": "Nextcloud ger dig tillgång till alla dina filer var du än är.",
|
||||
"Nextcloud volume size in GB": "Nextcloud volymstorlek i GB",
|
||||
@@ -5605,6 +5608,7 @@
|
||||
"Recreation prepared": "Rekreation förberedd",
|
||||
"Recursive DNS resolver.": "Rekursiv DNS-resolver.",
|
||||
"Recursive and authoritative DNS server.": "Rekursiv och auktoritativ DNS-server.",
|
||||
"Redis locking is configured automatically. Existing Nextcloud configuration files are preserved.": "Fillåsning med Redis konfigureras automatiskt. Befintliga konfigurationsfiler för Nextcloud bevaras.",
|
||||
"Redmine": "Redmine",
|
||||
"Refresh APT index and verify repositories:": "Uppdatera APT-index och verifiera förråd:",
|
||||
"Refresh catalog": "Uppdatera katalogen",
|
||||
@@ -7995,6 +7999,7 @@
|
||||
"Use a privileged LXC for NFS server/client workflows.": "Använd en privilegierad LXC för NFS-server/klient-arbetsflöden.",
|
||||
"Use a privileged LXC for Samba client/server workflows.": "Använd en privilegierad LXC för Samba klient/server arbetsflöden.",
|
||||
"Use a registry hostname, for example ghcr.io or registry.example.com:5000.": "Använd ett registervärdnamn, till exempel ghcr.io eller registry.example.com:5000.",
|
||||
"Use a trusted HTTPS reverse proxy. Upgrade Nextcloud one major version at a time.": "Använd en omvänd HTTPS-proxy med ett betrott certifikat. Uppgradera Nextcloud till nästa huvudversion utan att hoppa över någon.",
|
||||
"Use an existing SSH private key file on this host": "Använd en befintlig privat SSH-nyckelfil på denna värd",
|
||||
"Use an existing keyfile": "Använd en befintlig nyckelfil",
|
||||
"Use an image reference, for example ghcr.io/owner/app:latest.": "Använd en bildreferens, till exempel ghcr.io/owner/app:latest.",
|
||||
@@ -8008,6 +8013,7 @@
|
||||
"Use existing filesystem": "Använd befintligt filsystem",
|
||||
"Use existing: mount without formatting": "Använd befintlig: montera utan formatering",
|
||||
"Use images only if the directory is on suitable storage.": "Använd endast bilder om katalogen finns på lämplig lagring.",
|
||||
"Use managed storage for /config and MariaDB. A host/NAS directory can be selected for /data and needs a separate backup.": "Använd hanterad lagring för /config och MariaDB. För /data kan du välja en katalog på värden/NAS som behöver säkerhetskopieras separat.",
|
||||
"Use mp1/mp2/... for extra mount points.": "Använd mp1/mp2/... för extra monteringspunkter.",
|
||||
"Use only when unprivileged containers cannot meet your needs": "Använd endast när oprivilegierade behållare inte kan uppfylla dina behov",
|
||||
"Use option 1 to add a local disk (as Proxmox storage and/or as a host mount).": "Använd alternativ 1 för att lägga till en lokal disk (som Proxmox-lagring och/eller som värdmontering).",
|
||||
|
||||
+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 554 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 555 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.
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -19414,6 +19414,38 @@
|
||||
"optional_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"hidden": false
|
||||
},
|
||||
{
|
||||
"id": "nextcloud-mariadb",
|
||||
"provider": "linuxserver",
|
||||
"template_family": "curated-profile",
|
||||
"title": "Nextcloud MariaDB",
|
||||
"repository": "https://github.com/linuxserver/docker-nextcloud",
|
||||
"description": "LinuxServer Nextcloud, MariaDB 10.11 and Redis 7 in three native OCI LXC containers. /config and /data are separate; user files can use a host/NAS directory while database state stays in local managed storage.",
|
||||
"website": "https://nextcloud.com/",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/nextcloud.webp",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "lscr.io/linuxserver/nextcloud:latest",
|
||||
"category": "productivity",
|
||||
"category_label": "Productivity & Workflows",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/nextcloud-mariadb.json",
|
||||
"template_id": "image-nextcloud-mariadb",
|
||||
"template": "apps/nextcloud-mariadb.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"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,
|
||||
"hidden": false
|
||||
}
|
||||
],
|
||||
"discovery": {
|
||||
|
||||
@@ -161,6 +161,9 @@
|
||||
],
|
||||
"wordcraft": [
|
||||
"/storage"
|
||||
],
|
||||
"nextcloud-mariadb": [
|
||||
"/data"
|
||||
]
|
||||
},
|
||||
"sizes": {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// Prepare a fresh LinuxServer Nextcloud without replacing persistent user settings.
|
||||
$dir = '/config/www/nextcloud/config';
|
||||
umask(0077);
|
||||
if (!is_dir($dir) && !mkdir($dir, 0770, true)) { throw new RuntimeException('Cannot create the Nextcloud config directory'); }
|
||||
// The directory belongs to the application user. Create each file without
|
||||
// following a link placed there, and give it to that user without following one.
|
||||
function create_private($path, $content, $owner) {
|
||||
$handle = @fopen($path, 'x');
|
||||
if ($handle === false || fwrite($handle, $content) !== strlen($content) || !fclose($handle)) { throw new RuntimeException('Cannot write ' . basename($path)); }
|
||||
if ($owner && (!lchown($path, fileowner($owner)) || !lchgrp($path, filegroup($owner)))) { throw new RuntimeException('Cannot set Nextcloud configuration ownership'); }
|
||||
}
|
||||
if (!is_file($dir . '/config.php') && !is_file($dir . '/autoconfig.php')) {
|
||||
foreach (['MYSQL_HOST', 'MYSQL_DATABASE', 'MYSQL_USER', 'MYSQL_PASSWORD', 'NEXTCLOUD_ADMIN_PASSWORD'] as $name) {
|
||||
if (getenv($name) === false || getenv($name) === '') { throw new RuntimeException('Missing Nextcloud setting: ' . $name); }
|
||||
}
|
||||
// Keep the defaults that LinuxServer copies only into an empty config directory.
|
||||
$defaults = '/app/www/src/config';
|
||||
if (is_dir($defaults)) {
|
||||
foreach (new DirectoryIterator($defaults) as $file) {
|
||||
if ($file->isDot() || !$file->isFile()) { continue; }
|
||||
$target = $dir . '/' . $file->getFilename();
|
||||
if (!file_exists($target) && !is_link($target)) { create_private($target, file_get_contents($file->getPathname()), null); }
|
||||
}
|
||||
}
|
||||
// With the administrator included, Nextcloud installs itself on the first
|
||||
// request, so nobody else on the network can claim the setup page.
|
||||
$settings = ['dbtype' => 'mysql', 'dbhost' => getenv('MYSQL_HOST'), 'dbname' => getenv('MYSQL_DATABASE'), 'dbuser' => getenv('MYSQL_USER'), 'dbpass' => getenv('MYSQL_PASSWORD'), 'directory' => '/data', 'adminlogin' => 'admin', 'adminpass' => getenv('NEXTCLOUD_ADMIN_PASSWORD')];
|
||||
// Existing installations skip LinuxServer's first-run ownership setup.
|
||||
create_private($dir . '/autoconfig.php', "<?php\n\$AUTOCONFIG = " . var_export($settings, true) . ";\n", $dir);
|
||||
}
|
||||
$path = $dir . '/proxmenux-redis.config.php';
|
||||
// Installed instances keep their existing cache configuration unchanged.
|
||||
if (!is_file($path) && !is_link($path) && !is_file($dir . '/config.php')) {
|
||||
$settings = ['filelocking.enabled' => true, 'memcache.local' => '\OC\Memcache\APCu', 'memcache.locking' => '\OC\Memcache\Redis', 'redis' => ['host' => 'redis', 'port' => 6379, 'timeout' => 0.0]];
|
||||
create_private($path, "<?php\n\$CONFIG = " . var_export($settings, true) . ";\n", $dir);
|
||||
}
|
||||
@@ -247,12 +247,19 @@ def relay_child_output(stream):
|
||||
return result
|
||||
|
||||
|
||||
def http_url(scheme, host, port, path):
|
||||
"""Without the default port of its scheme: an application that records its
|
||||
first request, like Nextcloud's trusted domain, sees the host a browser sends."""
|
||||
default = (scheme, int(port)) in (('https', 443), ('http', 80))
|
||||
return f"{scheme}://{host}{'' if default else f':{port}'}{path}"
|
||||
|
||||
|
||||
def assign_health_address(service):
|
||||
"""Bind a generated dependency probe to its allocated private address."""
|
||||
check = service['healthcheck']
|
||||
if check['type'] == 'http':
|
||||
endpoint = check['endpoint']
|
||||
check['url'] = f"{endpoint['scheme']}://{service['ip']}:{endpoint['port']}{endpoint['path']}"
|
||||
check['url'] = http_url(endpoint['scheme'], service['ip'], endpoint['port'], endpoint['path'])
|
||||
elif check['type'] == 'tcp':
|
||||
check['host'] = service['ip']
|
||||
|
||||
@@ -383,7 +390,7 @@ def lan_access_urls(services, subnet, strict=True):
|
||||
if not candidates:
|
||||
raise RuntimeError(f"{translate('No LAN address was obtained for the service:')} {service['name']}")
|
||||
urls.append({'label':service['name'],
|
||||
'url':f"{endpoint['scheme']}://{candidates[0]}:{endpoint['port']}{endpoint['path']}"})
|
||||
'url':http_url(endpoint['scheme'], candidates[0], endpoint['port'], endpoint['path'])})
|
||||
except Exception:
|
||||
if strict:
|
||||
raise
|
||||
|
||||
@@ -373,6 +373,18 @@ healthcheck_probe_url() {
|
||||
&& (( status == 1 || status == 8 || status == 52 || status == 56 ))
|
||||
}
|
||||
|
||||
# The address of the check, without the default port of its scheme: an
|
||||
# application that records its first request, like Nextcloud's trusted domain,
|
||||
# then sees the same host a browser sends.
|
||||
healthcheck_url() {
|
||||
local port=$1
|
||||
if [[ ( $HC_SCHEME == https && $port == 443 ) || ( $HC_SCHEME == http && $port == 80 ) ]]; then
|
||||
printf '%s://%s%s' "$HC_SCHEME" "$IP" "$HC_PATH"
|
||||
else
|
||||
printf '%s://%s:%s%s' "$HC_SCHEME" "$IP" "$port" "$HC_PATH"
|
||||
fi
|
||||
}
|
||||
|
||||
# Any of the addresses answering means the application is up; HC_URL keeps the
|
||||
# one that answered.
|
||||
healthcheck_probe() {
|
||||
@@ -2351,12 +2363,12 @@ if [[ $START_AFTER == 1 && $HAS_STARTUP_HEALTHCHECK == 1 ]]; then
|
||||
(( HC_STABILITY < HC_TIMEOUT )) \
|
||||
|| die "$(translate "The stability period must be shorter than the healthcheck timeout")"
|
||||
[[ -n $IP ]] || die "$(translate "The healthcheck cannot run without an IP address")"
|
||||
HC_URL="${HC_SCHEME}://${IP}:${HC_PORT}${HC_PATH}"
|
||||
HC_URL=$(healthcheck_url "$HC_PORT")
|
||||
HC_URLS=("$HC_URL")
|
||||
while IFS= read -r HC_ALT_PORT; do
|
||||
[[ $HC_ALT_PORT =~ ^[0-9]+$ && $HC_ALT_PORT -ge 1 && $HC_ALT_PORT -le 65535 ]] \
|
||||
|| die "$(translate "Invalid healthcheck port")"
|
||||
HC_URLS+=("${HC_SCHEME}://${IP}:${HC_ALT_PORT}${HC_PATH}")
|
||||
HC_URLS+=("$(healthcheck_url "$HC_ALT_PORT")")
|
||||
done < <(jq -r '.alternative_ports[]? | tostring' <<<"$STARTUP_HEALTHCHECK")
|
||||
HC_ANY_STATUS=$(jq -r '.accept_any_status // false' <<<"$STARTUP_HEALTHCHECK")
|
||||
HC_ACCEPT_NON_HTTP=$(jq -r '.accept_non_http // false' <<<"$STARTUP_HEALTHCHECK")
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
"""The startup check asks for the address a browser would use: without the
|
||||
default port of its scheme. Nextcloud trusts the host of its first request."""
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
import unittest
|
||||
|
||||
SCRIPT = (Path(__file__).resolve().parents[1] / 'remote/install_oci.sh').read_text()
|
||||
|
||||
|
||||
def url(scheme, port, path='/'):
|
||||
function = re.search(r'^healthcheck_url\(\) \{\n.*?^\}\n', SCRIPT, re.M | re.S).group(0)
|
||||
done = subprocess.run(['bash', '-c', function + f'HC_SCHEME={scheme} IP=192.0.2.10 HC_PATH={path}; healthcheck_url {port}'],
|
||||
capture_output=True, text=True, check=True)
|
||||
return done.stdout
|
||||
|
||||
|
||||
class HealthcheckUrlTests(unittest.TestCase):
|
||||
def test_default_ports_are_left_out(self):
|
||||
self.assertEqual(url('https', 443), 'https://192.0.2.10/')
|
||||
self.assertEqual(url('http', 80, '/status'), 'http://192.0.2.10/status')
|
||||
|
||||
def test_other_ports_are_kept(self):
|
||||
self.assertEqual(url('http', 443), 'http://192.0.2.10:443/')
|
||||
self.assertEqual(url('https', 8443), 'https://192.0.2.10:8443/')
|
||||
self.assertEqual(url('http', 3000), 'http://192.0.2.10:3000/')
|
||||
|
||||
def test_every_probe_address_uses_it(self):
|
||||
self.assertIn('HC_URL=$(healthcheck_url "$HC_PORT")', SCRIPT)
|
||||
self.assertIn('HC_URLS+=("$(healthcheck_url "$HC_ALT_PORT")")', SCRIPT)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -18,7 +18,8 @@ class MainFrontendReadiness(unittest.TestCase):
|
||||
with patch.object(installer,'run',return_value='10.77.6.30\n172.30.249.70\n'), \
|
||||
patch.object(installer,'wait_web') as web:
|
||||
url=installer.wait_main_web(service,ipaddress.ip_network('10.77.6.0/24'))
|
||||
self.assertEqual(url,'http://172.30.249.70:80/')
|
||||
# Without the default port: the host a browser sends.
|
||||
self.assertEqual(url,'http://172.30.249.70/')
|
||||
self.assertEqual(service['healthcheck']['url'],url)
|
||||
self.assertEqual(service['ip'],'10.77.6.30')
|
||||
web.assert_called_once_with(service,url)
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
"""The LinuxServer/MariaDB variant keeps its complete private stack and safe bootstrap."""
|
||||
import json
|
||||
import base64
|
||||
import re
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from contextlib import ExitStack
|
||||
from unittest.mock import patch
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path[:0] = [str(ROOT / 'src'), str(Path(__file__).parent)]
|
||||
from proxmenux_oci.catalog import Catalog
|
||||
from proxmenux_oci.custom import template_from_oci_compose
|
||||
from proxmenux_oci.installer import ADVANCED_MODE, DEFAULT_MODE, build_deployment
|
||||
from proxmenux_oci.stack import assess
|
||||
from test_advanced_flow_order import RecordingUI, storages, addresses
|
||||
|
||||
|
||||
class NextcloudMariaDBTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.catalog = Catalog(ROOT)
|
||||
self.template = self.catalog.compose('nextcloud-mariadb')
|
||||
|
||||
def test_catalog_roundtrip_preserves_the_original_image_families_and_tls(self):
|
||||
t = template_from_oci_compose(json.dumps(self.template))
|
||||
self.catalog.validate(t)
|
||||
self.assertEqual(assess(t), [])
|
||||
services = {s['name']: s for s in t['compose_stack']['services']}
|
||||
self.assertEqual({k: v['image'] for k, v in services.items()}, {
|
||||
'nextcloud': 'lscr.io/linuxserver/nextcloud:latest',
|
||||
'db': 'mariadb:10.11', 'redis': 'redis:7-alpine'})
|
||||
self.assertEqual(t['first_run']['endpoints'][0]['scheme'], 'https')
|
||||
self.assertEqual(t['first_run']['endpoints'][0]['port'], 443)
|
||||
self.assertEqual(t['first_run']['credentials'][0]['password_environment'], 'NEXTCLOUD_ADMIN_PASSWORD')
|
||||
self.assertEqual(t['first_run']['credentials'][0]['username'], 'admin')
|
||||
self.assertTrue(t['catalog_ui']['icon'].startswith('https://'))
|
||||
self.assertEqual(set(services['nextcloud']['depends_on']), {'db', 'redis'})
|
||||
for name in ('db', 'redis'):
|
||||
self.assertFalse(services[name]['compose'].get('ports'))
|
||||
self.assertFalse(services[name]['frontend_network'])
|
||||
|
||||
def plan(self, mode, answers=None):
|
||||
with ExitStack() as stack:
|
||||
for target, value in [
|
||||
('proxmenux_oci.installer.host.storages', storages),
|
||||
('proxmenux_oci.installer.access.ask_addresses', addresses)]:
|
||||
stack.enter_context(patch(target, side_effect=value))
|
||||
for target, value in [
|
||||
('proxmenux_oci.i18n.language', 'en'),
|
||||
('proxmenux_oci.installer.host.bridges', [{'iface': 'vmbr0', 'cidr': '192.0.2.1/24'}]),
|
||||
('proxmenux_oci.installer.host.timezone', 'Europe/Madrid')]:
|
||||
stack.enter_context(patch(target, return_value=value))
|
||||
return build_deployment(self.template, RecordingUI(answers), mode)
|
||||
|
||||
def test_default_and_advanced_plans_keep_shared_secrets_private_dependencies_and_persistence(self):
|
||||
for mode in (DEFAULT_MODE, ADVANCED_MODE):
|
||||
with self.subTest(mode=mode):
|
||||
plan = self.plan(mode)
|
||||
services = {s['name']: s for s in plan['services']}
|
||||
env = {name: {e['name']: e['value'] for e in s['deployment']['environment']}
|
||||
for name, s in services.items()}
|
||||
self.assertEqual(env['nextcloud']['MYSQL_PASSWORD'], env['db']['MYSQL_PASSWORD'])
|
||||
self.assertNotEqual(env['db']['MYSQL_PASSWORD'], env['db']['MYSQL_ROOT_PASSWORD'])
|
||||
# The administrator is created by ProxMenux, not by whoever opens the page first.
|
||||
self.assertEqual(len(env['nextcloud']['NEXTCLOUD_ADMIN_PASSWORD']), 64)
|
||||
self.assertNotIn(env['nextcloud']['NEXTCLOUD_ADMIN_PASSWORD'],
|
||||
(env['db']['MYSQL_PASSWORD'], env['db']['MYSQL_ROOT_PASSWORD']))
|
||||
self.assertNotIn('NEXTCLOUD_ADMIN_PASSWORD', env['db'])
|
||||
self.assertEqual(env['nextcloud']['MYSQL_HOST'], 'db')
|
||||
self.assertEqual([s['name'] for s in plan['services']], ['db', 'redis', 'nextcloud'])
|
||||
self.assertEqual([s['name'] for s in plan['services'] if s.get('frontend')], ['nextcloud'])
|
||||
self.assertEqual(services['db']['healthcheck']['argv'][0], 'healthcheck.sh')
|
||||
self.assertEqual(services['nextcloud']['healthcheck']['endpoint']['scheme'], 'https')
|
||||
self.assertEqual({k: s['deployment']['hostname'] for k, s in services.items()},
|
||||
{'nextcloud': 'nextcloud', 'db': 'nextcloud-db', 'redis': 'nextcloud-redis'})
|
||||
for service in services.values():
|
||||
self.assertTrue(service['deployment']['security']['unprivileged'])
|
||||
self.assertTrue(all(m['backup'] for m in service['deployment']['mounts']))
|
||||
self.assertEqual({k: v['deployment']['resources']['memory_mb'] for k, v in services.items()},
|
||||
{'nextcloud': 2048, 'db': 1024, 'redis': 512})
|
||||
runtime = services['nextcloud']['template']['proxmox']['installer_profile']['runtime']
|
||||
self.assertIn('exec /init', runtime['compose_entrypoint'][2])
|
||||
# The private umask of the bootstrap does not reach the application.
|
||||
self.assertTrue(runtime['compose_entrypoint'][2].startswith('(umask 077; '))
|
||||
self.assertTrue(runtime['compose_entrypoint'][2].endswith('| php); exec /init'))
|
||||
self.assertNotIn('\n', runtime['compose_entrypoint'][2])
|
||||
self.assertNotIn('\r', runtime['compose_entrypoint'][2])
|
||||
|
||||
def test_nas_mount_is_separate_from_configuration_database_and_cache(self):
|
||||
plan = self.plan(DEFAULT_MODE, {'Where to store nextcloud: /data': 'host-bind',
|
||||
'Host path for nextcloud: /data': '/mnt/pve/media/Nextcloud'})
|
||||
services = {s['name']: s for s in plan['services']}
|
||||
mounts = {m['container_path']: m for m in services['nextcloud']['deployment']['mounts']}
|
||||
self.assertEqual(mounts['/data']['source'], '/mnt/pve/media/Nextcloud')
|
||||
self.assertEqual(mounts['/data']['type'], 'host-bind')
|
||||
self.assertFalse(mounts['/data']['backup'])
|
||||
self.assertEqual(mounts['/config']['type'], 'managed-volume')
|
||||
for name in ('db', 'redis'):
|
||||
self.assertTrue(all(m['type'] == 'managed-volume' and m['backup']
|
||||
for m in services[name]['deployment']['mounts']))
|
||||
|
||||
@unittest.skipUnless(shutil.which('php'), 'PHP CLI is needed to execute the bootstrap contract')
|
||||
def test_bootstrap_prefills_mysql_with_escaped_secrets_and_preserves_existing_files(self):
|
||||
entry = next(s for s in self.template['compose_stack']['services'] if s['name'] == 'nextcloud')['compose']['entrypoint']
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
folder = Path(temp) / 'config'
|
||||
image_config = Path(temp) / 'image-config'
|
||||
image_config.mkdir()
|
||||
defaults = {'CAN_INSTALL': '', '.htaccess': 'deny all', 'config.sample.php': '<?php // sample'}
|
||||
for name, content in defaults.items(): (image_config / name).write_text(content)
|
||||
payload = re.search(r'printf %s ([A-Za-z0-9+/=]+) \| base64 -d \| php', entry[2]).group(1)
|
||||
source = base64.b64decode(payload).decode()
|
||||
self.assertEqual(source, (ROOT / 'examples/nextcloud-mariadb-bootstrap.php').read_text())
|
||||
test_source = source.replace('/config/www/nextcloud/config', str(folder)).replace('/app/www/src/config', str(image_config))
|
||||
script = entry[2].replace(payload, base64.b64encode(test_source.encode()).decode()).replace('exec /init', 'exit 0')
|
||||
password = "test-'quote\\backslash$not-a-real-secret\nline"
|
||||
env = dict(os.environ, MYSQL_HOST='db', MYSQL_DATABASE='nextcloud', MYSQL_USER='nextcloud', MYSQL_PASSWORD=password,
|
||||
NEXTCLOUD_ADMIN_PASSWORD='admin-' + password)
|
||||
subprocess.run(['/bin/sh', '-ec', script], env=env, check=True, capture_output=True)
|
||||
for name, content in defaults.items(): self.assertEqual((folder / name).read_text(), content)
|
||||
autoconfig = folder / 'autoconfig.php'
|
||||
redis = folder / 'proxmenux-redis.config.php'
|
||||
for path in (autoconfig, redis):
|
||||
subprocess.run(['php', '-l', str(path)], check=True, capture_output=True)
|
||||
self.assertEqual(path.stat().st_mode & 0o777, 0o600)
|
||||
code = 'require $argv[1]; echo json_encode($AUTOCONFIG);'
|
||||
values = json.loads(subprocess.check_output(['php', '-r', code, str(autoconfig)], env=env))
|
||||
self.assertEqual(values['dbpass'], password)
|
||||
self.assertEqual(values['dbhost'], 'db')
|
||||
self.assertEqual(values['directory'], '/data')
|
||||
self.assertEqual((values['adminlogin'], values['adminpass']), ('admin', 'admin-' + password))
|
||||
cache = json.loads(subprocess.check_output(['php', '-r', 'require $argv[1]; echo json_encode($CONFIG);', str(redis)]))
|
||||
self.assertEqual(cache['redis']['host'], 'redis')
|
||||
self.assertEqual(cache['memcache.locking'], '\\OC\\Memcache\\Redis')
|
||||
# A retry/update must not replace user edits or a completed installation.
|
||||
saved = {p: p.read_bytes() for p in (autoconfig, redis)}
|
||||
subprocess.run(['/bin/sh', '-ec', script], env=dict(env, MYSQL_PASSWORD='changed'), check=True, capture_output=True)
|
||||
for path, content in saved.items(): self.assertEqual(path.read_bytes(), content)
|
||||
autoconfig.unlink()
|
||||
(folder / 'CAN_INSTALL').unlink()
|
||||
(folder / 'config.php').write_text('<?php $CONFIG = ["installed" => true];')
|
||||
subprocess.run(['/bin/sh', '-ec', script], env=env, check=True, capture_output=True)
|
||||
self.assertFalse(autoconfig.exists())
|
||||
self.assertFalse((folder / 'CAN_INSTALL').exists())
|
||||
|
||||
@unittest.skipUnless(shutil.which('php'), 'PHP CLI is needed to execute the bootstrap contract')
|
||||
def test_bootstrap_refuses_links_and_needs_the_administrator_password(self):
|
||||
source = (ROOT / 'examples/nextcloud-mariadb-bootstrap.php').read_text()
|
||||
base = dict(os.environ, MYSQL_HOST='db', MYSQL_DATABASE='nextcloud', MYSQL_USER='nextcloud', MYSQL_PASSWORD='x')
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
folder = Path(temp) / 'config'
|
||||
folder.mkdir()
|
||||
target = Path(temp) / 'outside'
|
||||
(folder / 'autoconfig.php').symlink_to(target)
|
||||
script = source.replace('/config/www/nextcloud/config', str(folder)).replace('/app/www/src/config', str(Path(temp) / 'none'))
|
||||
done = subprocess.run(['php'], input=script.encode(), env=dict(base, NEXTCLOUD_ADMIN_PASSWORD='y'), capture_output=True)
|
||||
self.assertNotEqual(done.returncode, 0)
|
||||
self.assertFalse(target.exists())
|
||||
(folder / 'autoconfig.php').unlink()
|
||||
done = subprocess.run(['php'], input=script.encode(), env=base, capture_output=True)
|
||||
self.assertNotEqual(done.returncode, 0)
|
||||
self.assertFalse((folder / 'autoconfig.php').exists())
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith('linux') and os.geteuid() == 0 and shutil.which('php'),
|
||||
'Linux root is needed to reproduce existing-volume ownership')
|
||||
def test_existing_config_volume_can_read_new_redis_configuration_as_its_app_user(self):
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
root = Path(temp)
|
||||
root.chmod(0o755)
|
||||
folder = root / 'config'
|
||||
folder.mkdir(mode=0o755)
|
||||
os.chown(folder, 1001, 1001)
|
||||
installed = folder / 'autoconfig.php'
|
||||
installed.write_text('<?php $CONFIG = ["installed" => true];')
|
||||
installed.chmod(0o640)
|
||||
os.chown(installed, 1001, 1001)
|
||||
source = (ROOT / 'examples/nextcloud-mariadb-bootstrap.php').read_text()
|
||||
source = source.replace('/config/www/nextcloud/config', str(folder))
|
||||
subprocess.run(['php'], input=source.encode(), check=True, capture_output=True)
|
||||
redis = folder / 'proxmenux-redis.config.php'
|
||||
self.assertEqual((redis.stat().st_uid, redis.stat().st_gid), (1001, 1001))
|
||||
self.assertEqual(redis.stat().st_mode & 0o777, 0o600)
|
||||
def app_user():
|
||||
os.setgroups([])
|
||||
os.setgid(1001)
|
||||
os.setuid(1001)
|
||||
result = subprocess.check_output(['php', '-r',
|
||||
'require $argv[1]; echo json_encode($CONFIG);', str(redis)], preexec_fn=app_user)
|
||||
self.assertEqual(json.loads(result)['redis']['host'], 'redis')
|
||||
self.assertEqual(installed.read_text(), '<?php $CONFIG = ["installed" => true];')
|
||||
self.assertFalse((folder / 'config.php').exists())
|
||||
|
||||
@unittest.skipUnless(shutil.which('php'), 'PHP CLI needed for the installed-instance contract')
|
||||
def test_existing_installation_does_not_override_user_cache_settings(self):
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
folder = Path(temp) / 'config'
|
||||
folder.mkdir()
|
||||
config = folder / 'config.php'
|
||||
content = '<?php $CONFIG = ["installed" => true, "redis" => ["host" => "user-cache", "timeout" => 3]];'
|
||||
config.write_text(content)
|
||||
source = (ROOT / 'examples/nextcloud-mariadb-bootstrap.php').read_text()
|
||||
source = source.replace('/config/www/nextcloud/config', str(folder))
|
||||
subprocess.run(['php'], input=source.encode(), check=True, capture_output=True)
|
||||
self.assertEqual(config.read_text(), content)
|
||||
self.assertFalse((folder / 'proxmenux-redis.config.php').exists())
|
||||
self.assertFalse((folder / 'autoconfig.php').exists())
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user