radicale: Remove code to handle 1.x

Since radicale 1.x is only in Stretch (oldstable), remove code that
was added to support that version and migration from 1.x to newer
versions.

Keep the fix for missing log path as the fix is not available in Buster yet.

Tests:

- Ran functional tests in testing container. Manually tested logging
  in to web interface and creating a calendar.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
[sunil: Add back the fix for missing log path]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
James Valleroy 2020-07-25 20:20:02 -04:00 committed by Sunil Mohan Adapa
parent c629191aa8
commit 880e3dc10e
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
4 changed files with 21 additions and 245 deletions

View File

@ -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)

View File

@ -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

View File

@ -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
<Location /radicale>
ProxyPass http://localhost:5232
Include includes/freedombox-auth-ldap.conf
Require valid-user
</Location>

View File

@ -79,9 +79,4 @@ clients = validate([{
}]
}])
backup = validate_backup({
'data': {
'directories': ['/var/lib/radicale/']
},
'services': ['radicale']
})
backup = validate_backup({'data': {'directories': ['/var/lib/radicale/']}})