Sunil Mohan Adapa 858d4a4337
nextcloud: Connect to redis using Unix socket
- Connecting using Unix socket allows us to drop having to make redis listen on
the containers IP address.

- Instead configure redis to listen on unix socket.

- Keep the configuration file separate and include it the main configuration
file. This allows easier configuration changes in the future.

- Ensure that the drop-in configuration is available during setup.

- Ensure that redis is running during setup. This is important when app is
upgraded while it is disabled. Or when setup is re-run.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2024-04-19 06:41:33 -04:00

156 lines
5.9 KiB
Python

# SPDX-License-Identifier: AGPL-3.0-or-later
"""FreedomBox app to configure Nextcloud."""
from django.utils.translation import gettext_lazy as _
from plinth import app as app_module
from plinth import frontpage, menu
from plinth.config import DropinConfigs
from plinth.daemon import Daemon, SharedDaemon
from plinth.modules.apache.components import Webserver, diagnose_url
from plinth.modules.backups.components import BackupRestore
from plinth.modules.firewall.components import (Firewall,
FirewallLocalProtection)
from plinth.package import Packages
from . import manifest, privileged
_description = [
_('Nextcloud is a self-hosted productivity platform which provides '
'private and secure functions for file sharing, collaborative work, '
'and more. Nextcloud includes the Nextcloud server, client applications '
'for desktop computers, and mobile clients. The Nextcloud server '
'provides a well integrated web interface.'),
_('All users of FreedomBox can use Nextcloud.'),
_('To perform administrative actions, use the '
f'<strong>"{privileged.GUI_ADMIN}"</strong> user.'),
_('You can set a new password in the "Configuration" section below.'),
_('Please note, that Nextcloud isn\'t maintained by Debian, which means '
'security and feature updates are applied independently.')
]
class NextcloudApp(app_module.App):
"""FreedomBox app for Nextcloud."""
app_id = 'nextcloud'
_version = 1
configure_when_disabled = False
def __init__(self):
"""Create components for the app."""
super().__init__()
info = app_module.Info(
app_id=self.app_id, version=self._version, name=_('Nextcloud'),
icon_filename='nextcloud',
short_description=_('File Storage & Collaboration'),
description=_description, manual_page='Nextcloud',
clients=manifest.clients)
self.add(info)
menu_item = menu.Menu('menu-nextcloud', info.name,
info.short_description, info.icon_filename,
'nextcloud:index', parent_url_name='apps')
self.add(menu_item)
shortcut = frontpage.Shortcut('shortcut-nextcloud', info.name,
short_description=info.short_description,
icon=info.icon_filename,
url='/nextcloud/', clients=info.clients,
login_required=True)
self.add(shortcut)
packages = Packages('packages-nextcloud', [
'podman', 'default-mysql-server', 'python3-iso3166',
'redis-server', 'php-redis'
], conflicts=['libpam-tmpdir'],
conflicts_action=Packages.ConflictsAction.REMOVE)
self.add(packages)
dropin_configs = DropinConfigs('dropin-configs-nextcloud', [
'/etc/apache2/conf-available/nextcloud-freedombox.conf',
'/etc/fail2ban/jail.d/nextcloud-freedombox.conf',
'/etc/fail2ban/filter.d/nextcloud-freedombox.conf',
'/etc/redis/conf.d/freedombox.conf',
])
self.add(dropin_configs)
firewall = Firewall('firewall-nextcloud', info.name,
ports=['http', 'https'], is_external=True)
self.add(firewall)
firewall_local_protection = FirewallLocalProtection(
'firewall-local-protection-nextcloud', ['8181'])
self.add(firewall_local_protection)
webserver = Webserver('webserver-nextcloud', 'nextcloud-freedombox',
urls=['https://{host}/nextcloud/login'])
self.add(webserver)
daemon = SharedDaemon('shared-daemon-podman-auto-update',
'podman-auto-update.timer')
self.add(daemon)
daemon = SharedDaemon('shared-daemon-nextcloud-redis', 'redis-server',
listen_ports=[(6379, 'tcp4')])
self.add(daemon)
daemon = SharedDaemon('shared-daemon-nextcloud-mysql', 'mysql')
self.add(daemon)
daemon = Daemon('daemon-nextcloud', 'nextcloud-freedombox')
self.add(daemon)
daemon = Daemon('daemon-nextcloud-timer',
'nextcloud-cron-freedombox.timer')
self.add(daemon)
backup_restore = NextcloudBackupRestore('backup-restore-nextcloud',
**manifest.backup)
self.add(backup_restore)
def setup(self, old_version):
"""Install and configure the app."""
super().setup(old_version)
with self.get_component(
'shared-daemon-nextcloud-redis').ensure_running():
with self.get_component(
'shared-daemon-nextcloud-mysql').ensure_running():
# Database needs to be running for successful initialization or
# upgrade of Nextcloud database.
# Drop-in configs need to be enabled for setup to succeed
self.get_component('dropin-configs-nextcloud').enable()
privileged.setup()
if not old_version:
self.enable()
def uninstall(self):
"""De-configure and uninstall the app."""
privileged.uninstall()
super().uninstall()
def diagnose(self):
"""Run diagnostics and return the results."""
results = super().diagnose()
results.append(diagnose_url('docker.com'))
return results
class NextcloudBackupRestore(BackupRestore):
"""Component to backup/restore Nextcloud."""
def backup_pre(self, packet):
"""Save database contents."""
super().backup_pre(packet)
privileged.dump_database()
def restore_post(self, packet):
"""Restore database contents."""
super().restore_post(packet)
privileged.restore_database()