From 0b0e2a4e6aabb17ef52135c3ef5a1f13c0a57a65 Mon Sep 17 00:00:00 2001 From: Spitap Date: Tue, 25 Apr 2023 17:57:47 +0200 Subject: [PATCH] Updated for 2.2 --- modoboa_installer/python.py | 23 ++++++++++++++ modoboa_installer/scripts/dovecot.py | 16 +++++++++- .../dovecot/dovecot-sql-mysql.conf.ext.tpl | 6 ++-- .../dovecot/dovecot-sql-postgres.conf.ext.tpl | 6 ++-- .../scripts/files/modoboa/crontab.tpl | 2 +- .../scripts/files/modoboa/supervisor-rq.tpl | 9 ++++++ .../scripts/files/modoboa/supervisor.tpl | 1 + modoboa_installer/scripts/modoboa.py | 30 ++++++++++++++++++- 8 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 modoboa_installer/scripts/files/modoboa/supervisor-rq.tpl diff --git a/modoboa_installer/python.py b/modoboa_installer/python.py index 04788ca..f7f00c1 100644 --- a/modoboa_installer/python.py +++ b/modoboa_installer/python.py @@ -45,6 +45,29 @@ def install_packages(names, venv=None, upgrade=False, **kwargs): utils.exec_cmd(cmd, **kwargs) +def get_package_version(name, venv=None, **kwargs): + """Returns the version of an installed package.""" + cmd = "{} show {}".format( + get_pip_path(venv), + name + ) + status, output = utils.exec_cmd(cmd, **kwargs) + + output_list = output.split("\n") + version_item_list = output_list[1].split(":") + version_list = version_item_list[1].split(".") + version_list_clean = [] + for element in version_list: + try: + version_list_clean.append(int(version_list[i])) + except ValueError: + utils.printcolor( + f"Failed to decode some part of the version of {name}", + utils.YELLOW) + version_list_clean.append(element) + return version_list_clean + + def install_package_from_repository(name, url, vcs="git", venv=None, **kwargs): """Install a Python package from its repository.""" if vcs == "git": diff --git a/modoboa_installer/scripts/dovecot.py b/modoboa_installer/scripts/dovecot.py index ce4fa0f..3224de3 100644 --- a/modoboa_installer/scripts/dovecot.py +++ b/modoboa_installer/scripts/dovecot.py @@ -30,6 +30,17 @@ class Dovecot(base.Installer): "conf.d/10-master.conf", "conf.d/20-lmtp.conf", "conf.d/10-ssl-keys.try"] with_user = True + def __init__(self, *args, **kwargs): + super.__init__(*args, **kwargs) + # Check if modoboa version > 2.2 + self.modoboa_2_2_or_greater = False + condition = ( + (modoboa_version[0] == 2 and modoboa_version[1] >= 2) or + modoboa_version[0] > 2 + ) + if condition: + self.modoboa_2_2_or_greater = True + def setup_user(self): """Setup mailbox user.""" super().setup_user() @@ -83,6 +94,7 @@ class Dovecot(base.Installer): else: # Protocols are automatically guessed on debian/ubuntu protocols = "" + context.update({ "db_driver": self.db_driver, "mailboxes_owner_uid": pw_mailbox[2], @@ -97,7 +109,9 @@ class Dovecot(base.Installer): "ssl_protocol_parameter": ssl_protocol_parameter, "radicale_user": self.config.get("radicale", "user"), "radicale_auth_socket_path": os.path.basename( - self.config.get("dovecot", "radicale_auth_socket_path")) + self.config.get("dovecot", "radicale_auth_socket_path")), + "modoboa_2_2_or_greater": "" if self.modoboa_2_2_or_greater else "#", + "not_modoboa_2_2_or_greater": "" if not self.modoboa_2_2_or_greater else "#" }) return context diff --git a/modoboa_installer/scripts/files/dovecot/dovecot-sql-mysql.conf.ext.tpl b/modoboa_installer/scripts/files/dovecot/dovecot-sql-mysql.conf.ext.tpl index 4538b9a..1a0434f 100644 --- a/modoboa_installer/scripts/files/dovecot/dovecot-sql-mysql.conf.ext.tpl +++ b/modoboa_installer/scripts/files/dovecot/dovecot-sql-mysql.conf.ext.tpl @@ -123,7 +123,8 @@ connect = host=%dbhost port=%dbport dbname=%modoboa_dbname user=%modoboa_dbuser #user_query = \ # SELECT home, uid, gid \ # FROM users WHERE username = '%%n' AND domain = '%%d' -user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, %mailboxes_owner_gid as gid, CONCAT('*:bytes=', mb.quota, 'M') AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user u ON u.id=mb.user_id WHERE mb.address='%%n' AND dom.name='%%d' +%{not_modoboa_2_2_or_greater}user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, %mailboxes_owner_gid as gid, CONCAT('*:bytes=', mb.quota, 'M') AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user u ON u.id=mb.user_id WHERE mb.address='%%n' AND dom.name='%%d' +%{modoboa_2_2_or_greater}user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, %mailboxes_owner_gid as gid, CONCAT('*:bytes=', mb.quota, 'M') AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user u ON u.id=mb.user_id WHERE (mb.is_send_only=0 OR '%s' NOT IN ('imap', 'pop3', 'lmtp')) AND mb.address='%%n' AND dom.name='%%d' # If you wish to avoid two SQL lookups (passdb + userdb), you can use # userdb prefetch instead of userdb sql in dovecot.conf. In that case you'll @@ -133,7 +134,8 @@ user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, # SELECT userid AS user, password, \ # home AS userdb_home, uid AS userdb_uid, gid AS userdb_gid \ # FROM users WHERE userid = '%%u' -password_query = SELECT email AS user, password, '%{home_dir}/%%d/%%n' AS userdb_home, %mailboxes_owner_uid AS userdb_uid, %mailboxes_owner_gid AS userdb_gid, CONCAT('*:bytes=', mb.quota, 'M') AS userdb_quota_rule FROM core_user u INNER JOIN admin_mailbox mb ON u.id=mb.user_id INNER JOIN admin_domain dom ON mb.domain_id=dom.id WHERE u.email='%%u' AND u.is_active=1 AND dom.enabled=1 +%{not_modoboa_2_2_or_greater}password_query = SELECT email AS user, password, '%{home_dir}/%%d/%%n' AS userdb_home, %mailboxes_owner_uid AS userdb_uid, %mailboxes_owner_gid AS userdb_gid, CONCAT('*:bytes=', mb.quota, 'M') AS userdb_quota_rule FROM core_user u INNER JOIN admin_mailbox mb ON u.id=mb.user_id INNER JOIN admin_domain dom ON mb.domain_id=dom.id WHERE u.email='%%u' AND u.is_active=1 AND dom.enabled=1 +%{modoboa_2_2_or_greater}password_query = SELECT email AS user, password, '%{home_dir}/%%d/%%n' AS userdb_home, %mailboxes_owner_uid AS userdb_uid, %mailboxes_owner_gid AS userdb_gid, CONCAT('*:bytes=', mb.quota, 'M') AS userdb_quota_rule FROM core_user u INNER JOIN admin_mailbox mb ON u.id=mb.user_id INNER JOIN admin_domain dom ON mb.domain_id=dom.id WHERE (mb.is_send_only=0 OR '%s' NOT IN ('imap', 'pop3')) AND u.email='%%u' AND u.is_active=1 AND dom.enabled=1 # Query to get a list of all usernames. #iterate_query = SELECT username AS user FROM users diff --git a/modoboa_installer/scripts/files/dovecot/dovecot-sql-postgres.conf.ext.tpl b/modoboa_installer/scripts/files/dovecot/dovecot-sql-postgres.conf.ext.tpl index abb5379..811e0f0 100644 --- a/modoboa_installer/scripts/files/dovecot/dovecot-sql-postgres.conf.ext.tpl +++ b/modoboa_installer/scripts/files/dovecot/dovecot-sql-postgres.conf.ext.tpl @@ -123,7 +123,8 @@ connect = host=%dbhost port=%dbport dbname=%modoboa_dbname user=%modoboa_dbuser #user_query = \ # SELECT home, uid, gid \ # FROM users WHERE username = '%%n' AND domain = '%%d' -user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, %mailboxes_owner_gid as gid, '*:bytes=' || mb.quota || 'M' AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user u ON u.id=mb.user_id WHERE mb.address='%%n' AND dom.name='%%d' +%{not_modoboa_2_2_or_greater}user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, %mailboxes_owner_gid as gid, '*:bytes=' || mb.quota || 'M' AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user u ON u.id=mb.user_id WHERE mb.address='%%n' AND dom.name='%%d' +%{modoboa_2_2_or_greater}user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, %mailboxes_owner_gid as gid, '*:bytes=' || mb.quota || 'M' AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user u ON u.id=mb.user_id WHERE (mb.is_send_only IS NOT TRUE OR '%s' NOT IN ('imap', 'pop3', 'lmtp')) AND mb.address='%%n' AND dom.name='%%d' # If you wish to avoid two SQL lookups (passdb + userdb), you can use # userdb prefetch instead of userdb sql in dovecot.conf. In that case you'll @@ -133,7 +134,8 @@ user_query = SELECT '%{home_dir}/%%d/%%n' AS home, %mailboxes_owner_uid as uid, # SELECT userid AS user, password, \ # home AS userdb_home, uid AS userdb_uid, gid AS userdb_gid \ # FROM users WHERE userid = '%%u' -password_query = SELECT email AS user, password, '%{home_dir}/%%d/%%n' AS userdb_home, %mailboxes_owner_uid AS userdb_uid, %mailboxes_owner_gid AS userdb_gid, CONCAT('*:bytes=', mb.quota, 'M') AS userdb_quota_rule FROM core_user u INNER JOIN admin_mailbox mb ON u.id=mb.user_id INNER JOIN admin_domain dom ON mb.domain_id=dom.id WHERE email='%%u' AND is_active AND dom.enabled +%{not_modoboa_2_2_or_greater}password_query = SELECT email AS user, password, '%{home_dir}/%%d/%%n' AS userdb_home, %mailboxes_owner_uid AS userdb_uid, %mailboxes_owner_gid AS userdb_gid, CONCAT('*:bytes=', mb.quota, 'M') AS userdb_quota_rule FROM core_user u INNER JOIN admin_mailbox mb ON u.id=mb.user_id INNER JOIN admin_domain dom ON mb.domain_id=dom.id WHERE email='%%u' AND is_active AND dom.enabled +%{modoboa_2_2_or_greater}password_query = SELECT email AS user, password, '%{home_dir}/%%d/%%n' AS userdb_home, %mailboxes_owner_uid AS userdb_uid, %mailboxes_owner_gid AS userdb_gid, CONCAT('*:bytes=', mb.quota, 'M') AS userdb_quota_rule FROM core_user u INNER JOIN admin_mailbox mb ON u.id=mb.user_id INNER JOIN admin_domain dom ON mb.domain_id=dom.id WHERE (mb.is_send_only IS NOT TRUE OR '%s' NOT IN ('imap', 'pop3')) AND email='%%u' AND is_active AND dom.enabled # Query to get a list of all usernames. #iterate_query = SELECT username AS user FROM users diff --git a/modoboa_installer/scripts/files/modoboa/crontab.tpl b/modoboa_installer/scripts/files/modoboa/crontab.tpl index 28bde36..84d9427 100644 --- a/modoboa_installer/scripts/files/modoboa/crontab.tpl +++ b/modoboa_installer/scripts/files/modoboa/crontab.tpl @@ -33,4 +33,4 @@ INSTANCE=%{instance_path} %{minutes} %{hours} * * * root $PYTHON $INSTANCE/manage.py communicate_with_public_api # Generate DKIM keys (they will belong to the user running this job) -%{opendkim_enabled}* * * * * %{opendkim_user} umask 077 && $PYTHON $INSTANCE/manage.py modo manage_dkim_keys +%{dkim_cron_enabled}* * * * * %{opendkim_user} umask 077 && $PYTHON $INSTANCE/manage.py modo manage_dkim_keys diff --git a/modoboa_installer/scripts/files/modoboa/supervisor-rq.tpl b/modoboa_installer/scripts/files/modoboa/supervisor-rq.tpl new file mode 100644 index 0000000..531650e --- /dev/null +++ b/modoboa_installer/scripts/files/modoboa/supervisor-rq.tpl @@ -0,0 +1,9 @@ +[program:modoboa-dkim-worker] +autostart=true +autorestart=true +command=%{venv_path}/bin/python %{home_dir}/instance/manage.py rqworker dkim +directory=%{home_dir} +user=%{dkim_user} +redirect_stderr=true +numprocs=1 +stopsignal=TERM diff --git a/modoboa_installer/scripts/files/modoboa/supervisor.tpl b/modoboa_installer/scripts/files/modoboa/supervisor.tpl index 0303a04..46e22fe 100644 --- a/modoboa_installer/scripts/files/modoboa/supervisor.tpl +++ b/modoboa_installer/scripts/files/modoboa/supervisor.tpl @@ -6,3 +6,4 @@ directory=%{home_dir} redirect_stderr=true user=%{user} numprocs=1 + diff --git a/modoboa_installer/scripts/modoboa.py b/modoboa_installer/scripts/modoboa.py index 838d1b5..1496fb6 100644 --- a/modoboa_installer/scripts/modoboa.py +++ b/modoboa_installer/scripts/modoboa.py @@ -45,6 +45,15 @@ class Modoboa(base.Installer): def __init__(self, *args, **kwargs): """Get configuration.""" super(Modoboa, self).__init__(*args, **kwargs) + # Check if modoboa version > 2.2 + self.modoboa_2_2_or_greater = False + condition = ( + (modoboa_version[0] == 2 and modoboa_version[1] >= 2) or + modoboa_version[0] > 2 + ) + if condition: + self.modoboa_2_2_or_greater = True + self.venv_path = self.config.get("modoboa", "venv_path") self.instance_path = self.config.get("modoboa", "instance_path") self.extensions = self.config.get("modoboa", "extensions").split() @@ -61,6 +70,9 @@ class Modoboa(base.Installer): self.extensions.remove("modoboa-radicale") self.dovecot_enabled = self.config.getboolean("dovecot", "enabled") self.opendkim_enabled = self.config.getboolean("opendkim", "enabled") + self.dkim_cron_enabled = False + if not self.modoboa_2_2_or_greater and self.opendkim_enabled: + self.dkim_cron_enabled = True def is_extension_ok_for_version(self, extension, version): """Check if extension can be installed with this modo version.""" @@ -214,6 +226,20 @@ class Modoboa(base.Installer): else: path = "supervisor=/etc/supervisord.d/policyd.ini" config_files.append(path) + + # Add worker for dkim if needed + modoboa_version = python.get_package_version( + "modoboa", + self.venv_path, + sudo_user=self.user + ) + condition = ( + (modoboa_version[0] == 2 and modoboa_version[1] >= 2) or + modoboa_version[0] > 2 + ) + if condition: + config_files.append( + "supervisor-rq=/etc/supervisor/conf.d/modoboa-worker.conf") return config_files def get_template_context(self): @@ -232,7 +258,9 @@ class Modoboa(base.Installer): "" if "modoboa-radicale" in extensions else "#"), "opendkim_user": self.config.get("opendkim", "user"), "minutes": random.randint(1, 59), - "hours" : f"{random_hour},{random_hour+12}" + "hours": f"{random_hour},{random_hour+12}", + "modoboa_2_2_or_greater": "" if self.modoboa_2_2_or_greater else "#", + "dkim_cron_enabled": "" if self.dkim_cron_enabled else "#" }) return context