mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-08-26 12:46:08 +00:00
email: rspamd: Simplify installing configuration
Existing implementation expects configuration files installed by FreedomBox to be edited at the top and the bottom. When re-installing, it tries to keep the edited parts while reinstalling the FreedomBox managed section in the middle to be overwritten with (new) FreedomBox defaults. Instead, simply ship the two files to rspamd configuration directories. These can be easily overridden by the user if they desire due to flexible configuration file priorities by rspamd. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
3b5091cbc3
commit
6e2c24c9e4
@ -3,14 +3,12 @@
|
||||
|
||||
import glob
|
||||
import logging
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from plinth import actions
|
||||
from plinth.modules.email import interproc, lock, postconf
|
||||
from plinth.modules.email.modconf import ConfigInjector
|
||||
|
||||
from . import models
|
||||
|
||||
@ -73,12 +71,6 @@ egress_filter_cleanup_options = {
|
||||
'nested_header_checks': ''
|
||||
}
|
||||
|
||||
# Rspamd config
|
||||
|
||||
rspamd_re = re.compile('#[ ]*--[ ]*([A-Z]{3,5})[ ]+FREEDOMBOX CONFIG$')
|
||||
rspamd_format = '#-- {} FREEDOMBOX CONFIG'
|
||||
|
||||
rspamd_mutex = lock.Mutex('rspamd-config')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -116,20 +108,6 @@ def action_set_filter():
|
||||
with postconf.mutex.lock_all():
|
||||
fix_filter(check_filter())
|
||||
|
||||
injector = ConfigInjector(rspamd_re, rspamd_format)
|
||||
with rspamd_mutex.lock_all():
|
||||
# XXX Maybe use globbing?
|
||||
_inject_rspamd_config(injector, 'override', 'options.inc')
|
||||
_inject_rspamd_config(injector, 'local', 'milter_headers.conf')
|
||||
|
||||
|
||||
def _inject_rspamd_config(injector, type, name):
|
||||
template_path = '/etc/plinth/rspamd-config/%s_%s' % (type, name)
|
||||
config_path = '/etc/rspamd/%s.d/%s' % (type, name)
|
||||
|
||||
logger.info('Opening Rspamd config file %s', config_path)
|
||||
injector.do_template_file(template_path, config_path)
|
||||
|
||||
|
||||
def _compile_sieve():
|
||||
sieve_list = glob.glob('/etc/dovecot/freedombox-sieve-after/*.sieve')
|
||||
|
||||
@ -1,78 +0,0 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""Generic config modifying utilities"""
|
||||
|
||||
import contextlib
|
||||
import io
|
||||
import re
|
||||
|
||||
from . import interproc
|
||||
|
||||
|
||||
class ConfigInjector:
|
||||
def __init__(self, match, generate):
|
||||
self.re_pattern = re.compile(match)
|
||||
self.boundary_fmt = generate + '\n'
|
||||
|
||||
def do_file_des(self, template, config, scratch):
|
||||
"""Write modified config to the `scratch` stream"""
|
||||
if not isinstance(template, io.TextIOBase):
|
||||
raise TypeError('Not a text IO stream: template')
|
||||
self._inject_config3(template, config, scratch)
|
||||
|
||||
def _inject_config3(self, template, config, scratch):
|
||||
# Copy the original config up to header line
|
||||
for line in config:
|
||||
match = self.re_pattern.match(line.strip())
|
||||
if match and match.group(1) == 'BEGIN':
|
||||
break
|
||||
scratch.write(line)
|
||||
if not line.endswith('\n'): # in case no new line was at the eof
|
||||
scratch.write('\n')
|
||||
|
||||
# Write header line
|
||||
scratch.write(self.boundary_fmt.format('BEGIN'))
|
||||
# Write template to scratch
|
||||
for line in template:
|
||||
scratch.write(line)
|
||||
# in case no new line was at the eof
|
||||
if not line.endswith('\n'):
|
||||
scratch.write('\n')
|
||||
# Write footer line
|
||||
scratch.write(self.boundary_fmt.format('END'))
|
||||
|
||||
# Find the trailer line in config
|
||||
for line in config:
|
||||
match = self.re_pattern.match(line.strip())
|
||||
if match and match.group(1) == 'END':
|
||||
break
|
||||
|
||||
# Copy the original
|
||||
for line in config:
|
||||
scratch.write(line) # keep original file ending style
|
||||
|
||||
def do_template_file(self, template_path, config_path):
|
||||
with open(template_path, 'r') as template:
|
||||
with self._open_config(config_path) as (config, scratch):
|
||||
self._inject_config3(template, config, scratch)
|
||||
|
||||
def do_template_string(self, template_string, config_path):
|
||||
with self._open_config(config_path) as (config, scratch):
|
||||
self._inject_config3([template_string], config, scratch)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _open_config(self, config_path):
|
||||
with open(config_path, 'a+') as config:
|
||||
with interproc.atomically_rewrite(config_path) as scratch:
|
||||
config.seek(0)
|
||||
yield config, scratch
|
||||
|
||||
def has_header_line(self, config_path):
|
||||
with open(config_path, 'r') as config_fd:
|
||||
return self._has_header_line(config_fd)
|
||||
|
||||
def _has_header_line(self, config_fd):
|
||||
for line in config_fd:
|
||||
match = self.re_pattern.match(line.strip())
|
||||
if match and match.group(1) == 'BEGIN':
|
||||
return True
|
||||
return False
|
||||
Loading…
x
Reference in New Issue
Block a user