diff --git a/actions/radicale b/actions/radicale index ad54de786..4c745e5d8 100755 --- a/actions/radicale +++ b/actions/radicale @@ -6,21 +6,13 @@ Configuration helper for Radicale. import argparse import os -import shutil -import subprocess -import tempfile import augeas from plinth import action_utils -from plinth.modules import radicale - -COLLECTIONS_PATH = '/var/lib/radicale/collections' -LOG_PATH = '/var/log/radicale' CONFIG_FILE = '/etc/radicale/config' - -DEFAULT_FILE = '/etc/default/radicale' +LOG_PATH = '/var/log/radicale' def parse_arguments(): @@ -28,89 +20,32 @@ def parse_arguments(): parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - subparsers.add_parser('setup', help='Setup Radicale configuration') - subparsers.add_parser('migrate', help='Migrate config to radicale 2.x') - subparsers.add_parser('fix-collections', - help='Ensure collections path exists') configure = subparsers.add_parser('configure', help='Configure various options') configure.add_argument('--rights_type', help='Set the rights type for radicale') + subparsers.add_parser('fix-paths', help='Ensure paths exists') subparsers.required = True return parser.parse_args() -def subcommand_setup(_): - """Setup Radicale configuration.""" - current_version = radicale.get_package_version() - if not current_version: - print('Warning: Unable to get radicale version.') - - aug = load_augeas() - - if current_version and current_version < radicale.VERSION_2: - aug.set('/files' + DEFAULT_FILE + '/ENABLE_RADICALE', 'yes') - aug.set('/files' + CONFIG_FILE + '/server/hosts', - '127.0.0.1:5232, [::1]:5232') - aug.set('/files' + CONFIG_FILE + '/server/base_prefix', '/radicale/') - aug.set('/files' + CONFIG_FILE + '/well-known/caldav', - '/radicale/%(user)s/caldav/') - aug.set('/files' + CONFIG_FILE + '/well-known/carddav', - '/radicale/%(user)s/carddav/') - aug.set('/files' + CONFIG_FILE + '/auth/type', 'remote_user') - aug.set('/files' + CONFIG_FILE + '/rights/type', 'owner_only') - - aug.save() - - -def subcommand_migrate(_): - """Migrate from radicale 1.x to 2.x.""" - current_version = radicale.get_package_version() - - # Migrate data from radicale 1.x to radicale 2.x format. - if current_version and current_version < radicale.VERSION_2: - with tempfile.TemporaryDirectory() as temp_directory: - export_location = os.path.join(temp_directory, 'radicale-export') - subprocess.run(['radicale', '--export-storage', export_location], - check=True) - collection_root = os.path.join(export_location, 'collection-root') - shutil.copytree(collection_root, - os.path.join(COLLECTIONS_PATH, 'collection-root')) - subprocess.run( - ['chown', '-R', 'radicale:radicale', COLLECTIONS_PATH], - check=True) - - action_utils.webserver_disable('radicale-plinth') - - def subcommand_configure(arguments): """Sets the radicale rights type to a particular value""" - current_version = radicale.get_package_version() - if not current_version: - print('Warning: Unable to get radicale version.') - - if current_version and current_version >= radicale.VERSION_2: - if arguments.rights_type == 'owner_only': - # Radicale 2.x default rights file is equivalent to owner_only. - arguments.rights_type = 'from_file' + if arguments.rights_type == 'owner_only': + # Default rights file is equivalent to owner_only. + arguments.rights_type = 'from_file' aug = load_augeas() aug.set('/files' + CONFIG_FILE + '/rights/type', arguments.rights_type) aug.save() - if current_version and current_version >= radicale.VERSION_2: - action_utils.service_try_restart('uwsgi') - else: - action_utils.service_try_restart('radicale') + action_utils.service_try_restart('uwsgi') -def subcommand_fix_collections(_): - """Fix collections path to work around a bug.""" - # Workaround for bug in radicale's uwsgi script (#919339) - if not os.path.exists(COLLECTIONS_PATH): - os.makedirs(COLLECTIONS_PATH) - +def subcommand_fix_paths(_): + """Fix log path to work around a bug.""" + # Workaround for bug in radicale's uwsgi script (#931201) if not os.path.exists(LOG_PATH): os.makedirs(LOG_PATH) @@ -120,10 +55,6 @@ def load_augeas(): aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) - # shell-script config file lens - aug.set('/augeas/load/Shellvars/lens', 'Shellvars.lns') - aug.set('/augeas/load/Shellvars/incl[last() + 1]', DEFAULT_FILE) - # INI file lens aug.set('/augeas/load/Puppet/lens', 'Puppet.lns') aug.set('/augeas/load/Puppet/incl[last() + 1]', CONFIG_FILE) diff --git a/plinth/modules/radicale/__init__.py b/plinth/modules/radicale/__init__.py index d94838a3a..10c52968b 100644 --- a/plinth/modules/radicale/__init__.py +++ b/plinth/modules/radicale/__init__.py @@ -4,28 +4,22 @@ FreedomBox app for radicale. """ import logging -import subprocess -from distutils.version import LooseVersion as LV import augeas -from apt.cache import Cache from django.utils.translation import ugettext_lazy as _ from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu -from plinth.daemon import Daemon from plinth.modules.apache.components import Uwsgi, Webserver from plinth.modules.firewall.components import Firewall from plinth.modules.users.components import UsersAndGroups -from plinth.utils import format_lazy, Version +from plinth.utils import Version, format_lazy from .manifest import backup, clients # noqa, pylint: disable=unused-import version = 2 -managed_services = ['radicale'] - managed_packages = ['radicale', 'uwsgi', 'uwsgi-plugin-python3'] _description = [ @@ -45,8 +39,6 @@ logger = logging.getLogger(__name__) CONFIG_FILE = '/etc/radicale/config' -VERSION_2 = LV('2') - app = None @@ -81,125 +73,26 @@ class RadicaleApp(app_module.App): ports=['http', 'https'], is_external=True) self.add(firewall) - webserver = RadicaleWebserver('webserver-radicale', None, - urls=['https://{host}/radicale']) + webserver = Webserver('webserver-radicale', 'radicale2-freedombox', + urls=['https://{host}/radicale']) self.add(webserver) - uwsgi = RadicaleUwsgi('uwsgi-radicale', 'radicale') + uwsgi = Uwsgi('uwsgi-radicale', 'radicale') self.add(uwsgi) - daemon = RadicaleDaemon('daemon-radicale', managed_services[0]) - self.add(daemon) - users_and_groups = UsersAndGroups('users-and-groups-radicale', reserved_usernames=['radicale']) self.add(users_and_groups) - -class RadicaleWebserver(Webserver): - """Webserver enable/disable behavior specific for radicale.""" - - @property - def web_name(self): - """Return web configuration name based on radicale version.""" - current_version = get_package_version() - if current_version and current_version < VERSION_2: - return 'radicale-plinth' - - return 'radicale2-freedombox' - - @web_name.setter - def web_name(self, web_name): - """Set the web name""" - - -class RadicaleUwsgi(Uwsgi): - """uWSGI enable/disable behavior specific for radicale.""" - - def is_enabled(self): - """Return whether the uWSGI configuration is enabled if version>=2.""" - package_version = get_package_version() - if package_version and package_version >= VERSION_2: - return super().is_enabled() - - return True - def enable(self): - """Enable the uWSGI configuration if version >=2.""" - package_version = get_package_version() - if package_version and package_version >= VERSION_2: - actions.superuser_run('radicale', ['fix-collections']) - super().enable() - - def disable(self): - """Disable the uWSGI configuration if version >=2.""" - package_version = get_package_version() - if package_version and package_version >= VERSION_2: - super().disable() - - -class RadicaleDaemon(Daemon): - """Daemon enable/disable behavior specific for radicale.""" - - @staticmethod - def _is_old_radicale(): - """Return whether radicale is less than version 2.""" - package_version = get_package_version() - return package_version and package_version < VERSION_2 - - def is_enabled(self): - """Return whether daemon is enabled if version < 2.""" - if self._is_old_radicale(): - return super().is_enabled() - - return True - - def enable(self): - """Enable the daemon if version < 2.""" - if self._is_old_radicale(): - super().enable() - else: - super().disable() - - def disable(self): - """Disable the daemon if version < 2.""" - if self._is_old_radicale(): - super().disable() - - def is_running(self): - """Return whether daemon is enabled if version < 2.""" - if self._is_old_radicale(): - return super().is_running() - - return True + """Fix missing directories before enabling radicale.""" + actions.superuser_run('radicale', ['fix-paths']) + super().enable() def setup(helper, old_version=None): """Install and configure the module.""" - if old_version == 1: - # Check that radicale 2.x is available for install. - cache = Cache() - candidate = cache['radicale'].candidate - if candidate < '2': - logger.error('Radicale 2.x is not available to install.') - - # Try to upgrade radicale 1.x to 2.x. - helper.call('pre', actions.superuser_run, 'radicale', ['migrate']) - helper.install(managed_packages, force_configuration='new') - - # Check that radicale 2.x is installed. - current_version = get_package_version() - if not current_version: - logger.error('Could not determine installed version of radicale.') - elif current_version < VERSION_2: - logger.error('Could not install radicale 2.x.') - - # Enable radicale. - helper.call('post', actions.superuser_run, 'radicale', ['setup']) - else: - helper.install(managed_packages) - helper.call('post', actions.superuser_run, 'radicale', ['setup']) - + helper.install(managed_packages) helper.call('post', app.enable) @@ -209,10 +102,6 @@ def force_upgrade(helper, packages): return False # Allow upgrade from 2.* to newer 2.* - current_version = get_package_version() - if not current_version or current_version < VERSION_2: - return False - package = packages['radicale'] if Version(package['new_version']) > Version('3~'): return False @@ -224,30 +113,6 @@ def force_upgrade(helper, packages): return True -def get_package_version(): - try: - proc = subprocess.run(['radicale', '--version'], - stdout=subprocess.PIPE, check=True) - output = proc.stdout.decode('utf-8') - except subprocess.CalledProcessError: - return None - - package_version = str(output.strip()) - return LV(package_version) - - -def enable(): - """Enable the module.""" - actions.superuser_run('radicale', ['enable']) - app.enable() - - -def disable(): - """Disable the module.""" - actions.superuser_run('radicale', ['disable']) - app.disable() - - def load_augeas(): """Prepares the augeas.""" aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + @@ -266,10 +131,8 @@ def get_rights_value(): aug = load_augeas() value = aug.get('/files' + CONFIG_FILE + '/rights/type') - current_version = get_package_version() - if current_version and current_version >= VERSION_2: - if value == 'from_file': - # Radicale 2.x default rights file is equivalent to owner_only. - value = 'owner_only' + if value == 'from_file': + # Default rights file is equivalent to owner_only. + value = 'owner_only' return value diff --git a/plinth/modules/radicale/data/etc/apache2/conf-available/radicale-plinth.conf b/plinth/modules/radicale/data/etc/apache2/conf-available/radicale-plinth.conf deleted file mode 100644 index ed6ba9f59..000000000 --- a/plinth/modules/radicale/data/etc/apache2/conf-available/radicale-plinth.conf +++ /dev/null @@ -1,13 +0,0 @@ -## -## On all sites, provide Radicale on a path: /radicale -## Allow all valid users. -## -Redirect 301 /.well-known/carddav /radicale/.well-known/carddav -Redirect 301 /.well-known/caldav /radicale/.well-known/caldav - - - ProxyPass http://localhost:5232 - - Include includes/freedombox-auth-ldap.conf - Require valid-user - diff --git a/plinth/modules/radicale/manifest.py b/plinth/modules/radicale/manifest.py index 965b491fd..56c16452f 100644 --- a/plinth/modules/radicale/manifest.py +++ b/plinth/modules/radicale/manifest.py @@ -79,9 +79,4 @@ clients = validate([{ }] }]) -backup = validate_backup({ - 'data': { - 'directories': ['/var/lib/radicale/'] - }, - 'services': ['radicale'] -}) +backup = validate_backup({'data': {'directories': ['/var/lib/radicale/']}})