mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2025-12-21 13:51:29 +00:00
Use config.json to render multiple Jinja2 templates
This commit is contained in:
@@ -30,30 +30,53 @@ class BootstrapBase:
|
||||
self.mysql_conn = None
|
||||
self.redis_conn = None
|
||||
|
||||
def render_config(self, template_name, output_path, clean_blank_lines=False):
|
||||
def render_config(self, config_file):
|
||||
"""
|
||||
Renders a Jinja2 template and writes it to the specified output path.
|
||||
Renders multiple Jinja2 templates based on a JSON config file.
|
||||
|
||||
Args:
|
||||
template_name (str): Name of the template file.
|
||||
output_path (str or Path): Path to write the rendered output file.
|
||||
clean_blank_lines (bool): If True, removes empty/whitespace-only lines from rendered output.
|
||||
Each config entry must include:
|
||||
- template (str): the template filename
|
||||
- output (str): absolute path to the output file
|
||||
|
||||
Optional:
|
||||
- clean_blank_lines (bool): remove empty lines from output
|
||||
- if_not_exists (bool): skip rendering if output file already exists
|
||||
"""
|
||||
|
||||
output_path = Path(output_path)
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
from pathlib import Path
|
||||
import json
|
||||
|
||||
template = self.env.get_template(template_name)
|
||||
rendered = template.render(self.env_vars)
|
||||
config_path = Path(config_file)
|
||||
if not config_path.exists():
|
||||
print(f"Template config file not found: {config_path}")
|
||||
return
|
||||
|
||||
if clean_blank_lines:
|
||||
rendered = "\n".join(line for line in rendered.splitlines() if line.strip())
|
||||
with config_path.open("r") as f:
|
||||
entries = json.load(f)
|
||||
|
||||
# converts output to Unix-style line endings
|
||||
rendered = rendered.replace('\r\n', '\n').replace('\r', '\n')
|
||||
for entry in entries:
|
||||
template_name = entry["template"]
|
||||
output_path = Path(entry["output"])
|
||||
clean_blank_lines = entry.get("clean_blank_lines", False)
|
||||
if_not_exists = entry.get("if_not_exists", False)
|
||||
|
||||
with open(output_path, "w") as f:
|
||||
f.write(rendered)
|
||||
if if_not_exists and output_path.exists():
|
||||
print(f"Skipping {output_path} (already exists)")
|
||||
continue
|
||||
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
template = self.env.get_template(template_name)
|
||||
rendered = template.render(self.env_vars)
|
||||
|
||||
if clean_blank_lines:
|
||||
rendered = "\n".join(line for line in rendered.splitlines() if line.strip())
|
||||
|
||||
rendered = rendered.replace('\r\n', '\n').replace('\r', '\n')
|
||||
|
||||
with output_path.open("w") as f:
|
||||
f.write(rendered)
|
||||
|
||||
print(f"Rendered {template_name} to {output_path}")
|
||||
|
||||
def prepare_template_vars(self, overwrite_path, extra_vars = None):
|
||||
"""
|
||||
|
||||
@@ -47,7 +47,7 @@ class Bootstrap(BootstrapBase):
|
||||
self.set_timezone()
|
||||
|
||||
print("Render config")
|
||||
self.render_config("whitelist.ign2.j2", "/var/lib/clamav/whitelist.ign2", clean_blank_lines=True)
|
||||
self.render_config("/etc/clamav/config.json")
|
||||
|
||||
# Fix permissions
|
||||
self.set_owner("/var/lib/clamav", "clamav", "clamav", recursive=True)
|
||||
|
||||
@@ -55,23 +55,7 @@ class Bootstrap(BootstrapBase):
|
||||
self.set_timezone()
|
||||
|
||||
print("Render config")
|
||||
self.render_config("dovecot-dict-sql-quota.conf.j2", "/etc/dovecot/sql/dovecot-dict-sql-quota.conf")
|
||||
self.render_config("dovecot-dict-sql-userdb.conf.j2", "/etc/dovecot/sql/dovecot-dict-sql-userdb.conf")
|
||||
self.render_config("dovecot-dict-sql-sieve_before.conf.j2", "/etc/dovecot/sql/dovecot-dict-sql-sieve_before.conf")
|
||||
self.render_config("dovecot-dict-sql-sieve_after.conf.j2", "/etc/dovecot/sql/dovecot-dict-sql-sieve_after.conf")
|
||||
self.render_config("mail_plugins.j2", "/etc/dovecot/mail_plugins")
|
||||
self.render_config("mail_plugins_imap.j2", "/etc/dovecot/mail_plugins_imap")
|
||||
self.render_config("mail_plugins_lmtp.j2", "/etc/dovecot/mail_plugins_lmtp")
|
||||
self.render_config("global_sieve_after.sieve.j2", "/var/vmail/sieve/global_sieve_after.sieve")
|
||||
self.render_config("global_sieve_before.sieve.j2", "/var/vmail/sieve/global_sieve_before.sieve")
|
||||
self.render_config("dovecot-master.passwd.j2", "/etc/dovecot/dovecot-master.passwd")
|
||||
self.render_config("dovecot-master.userdb.j2", "/etc/dovecot/dovecot-master.userdb")
|
||||
self.render_config("sieve.creds.j2", "/etc/sogo/sieve.creds")
|
||||
self.render_config("sogo-sso.pass.j2", "/etc/phpfpm/sogo-sso.pass")
|
||||
self.render_config("cron.creds.j2", "/etc/sogo/cron.creds")
|
||||
self.render_config("source_env.sh.j2", "/source_env.sh")
|
||||
self.render_config("maildir_gc.sh.j2", "/usr/local/bin/maildir_gc.sh")
|
||||
self.render_config("dovecot.conf.j2", "/etc/dovecot/dovecot.conf")
|
||||
self.render_config("/etc/dovecot/config.json")
|
||||
|
||||
files = [
|
||||
"/etc/dovecot/mail_plugins",
|
||||
|
||||
@@ -46,7 +46,7 @@ class Bootstrap(BootstrapBase):
|
||||
self.set_timezone()
|
||||
|
||||
print("Render config")
|
||||
self.render_config("my.cnf.j2", "/etc/mysql/conf.d/my.cnf")
|
||||
self.render_config("/etc/mysql/conf.d/config.json")
|
||||
|
||||
def start_temporary(self, socket):
|
||||
"""
|
||||
|
||||
@@ -41,11 +41,7 @@ class Bootstrap(BootstrapBase):
|
||||
self.set_timezone()
|
||||
|
||||
print("Render config")
|
||||
self.render_config("nginx.conf.j2", "/etc/nginx/nginx.conf")
|
||||
self.render_config("sites-default.conf.j2", "/etc/nginx/includes/sites-default.conf")
|
||||
self.render_config("server_name.active.j2", "/etc/nginx/conf.d/server_name.active")
|
||||
self.render_config("listen_plain.active.j2", "/etc/nginx/conf.d/listen_plain.active")
|
||||
self.render_config("listen_ssl.active.j2", "/etc/nginx/conf.d/listen_ssl.active")
|
||||
self.render_config("/etc/nginx/conf.d/config.json")
|
||||
|
||||
def get_valid_cert_dirs(self):
|
||||
ssl_dir = '/etc/ssl/mail/'
|
||||
|
||||
@@ -44,12 +44,7 @@ class Bootstrap(BootstrapBase):
|
||||
|
||||
|
||||
print("Render config")
|
||||
self.render_config("opcache-recommended.ini.j2", "/usr/local/etc/php/conf.d/opcache-recommended.ini")
|
||||
self.render_config("pools.conf.j2", "/usr/local/etc/php-fpm.d/z-pools.conf")
|
||||
self.render_config("other.ini.j2", "/usr/local/etc/php/conf.d/zzz-other.ini")
|
||||
self.render_config("upload.ini.j2", "/usr/local/etc/php/conf.d/upload.ini")
|
||||
self.render_config("session_store.ini.j2", "/usr/local/etc/php/conf.d/session_store.ini")
|
||||
self.render_config("0081-custom-mailcow.css.j2", "/web/css/build/0081-custom-mailcow.css")
|
||||
self.render_config("/php-conf/config.json")
|
||||
|
||||
self.copy_file("/usr/local/etc/php/conf.d/opcache-recommended.ini", "/php-conf/opcache-recommended.ini")
|
||||
self.copy_file("/usr/local/etc/php-fpm.d/z-pools.conf", "/php-conf/pools.conf")
|
||||
|
||||
@@ -40,39 +40,7 @@ class Bootstrap(BootstrapBase):
|
||||
self.set_syslog_redis()
|
||||
|
||||
print("Render config")
|
||||
self.render_config("aliases.j2", "/etc/aliases")
|
||||
self.render_config("mysql_relay_ne.cf.j2", "/opt/postfix/conf/sql/mysql_relay_ne.cf")
|
||||
self.render_config("mysql_relay_recipient_maps.cf.j2", "/opt/postfix/conf/sql/mysql_relay_recipient_maps.cf")
|
||||
self.render_config("mysql_tls_policy_override_maps.cf.j2", "/opt/postfix/conf/sql/mysql_tls_policy_override_maps.cf")
|
||||
self.render_config("mysql_tls_enforce_in_policy.cf.j2", "/opt/postfix/conf/sql/mysql_tls_enforce_in_policy.cf")
|
||||
self.render_config("mysql_sender_dependent_default_transport_maps.cf.j2", "/opt/postfix/conf/sql/mysql_sender_dependent_default_transport_maps.cf")
|
||||
self.render_config("mysql_transport_maps.cf.j2", "/opt/postfix/conf/sql/mysql_transport_maps.cf")
|
||||
self.render_config("mysql_virtual_resource_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_resource_maps.cf")
|
||||
self.render_config("mysql_sasl_passwd_maps_sender_dependent.cf.j2", "/opt/postfix/conf/sql/mysql_sasl_passwd_maps_sender_dependent.cf")
|
||||
self.render_config("mysql_sasl_passwd_maps_transport_maps.cf.j2", "/opt/postfix/conf/sql/mysql_sasl_passwd_maps_transport_maps.cf")
|
||||
self.render_config("mysql_virtual_alias_domain_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_alias_domain_maps.cf")
|
||||
self.render_config("mysql_virtual_alias_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_alias_maps.cf")
|
||||
self.render_config("mysql_recipient_bcc_maps.cf.j2", "/opt/postfix/conf/sql/mysql_recipient_bcc_maps.cf")
|
||||
self.render_config("mysql_sender_bcc_maps.cf.j2", "/opt/postfix/conf/sql/mysql_sender_bcc_maps.cf")
|
||||
self.render_config("mysql_recipient_canonical_maps.cf.j2", "/opt/postfix/conf/sql/mysql_recipient_canonical_maps.cf")
|
||||
self.render_config("mysql_virtual_domains_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_domains_maps.cf")
|
||||
self.render_config("mysql_virtual_mailbox_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_mailbox_maps.cf")
|
||||
self.render_config("mysql_virtual_relay_domain_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_relay_domain_maps.cf")
|
||||
self.render_config("mysql_virtual_sender_acl.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_sender_acl.cf")
|
||||
self.render_config("mysql_mbr_access_maps.cf.j2", "/opt/postfix/conf/sql/mysql_mbr_access_maps.cf")
|
||||
self.render_config("mysql_virtual_spamalias_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_spamalias_maps.cf")
|
||||
self.render_config("sni.map.j2", "/opt/postfix/conf/sni.map")
|
||||
self.render_config("main.cf.j2", "/opt/postfix/conf/main.cf")
|
||||
|
||||
# Conditional render
|
||||
if not Path("/opt/postfix/conf/dns_blocklists.cf").exists():
|
||||
self.render_config("dns_blocklists.cf.j2", "/opt/postfix/conf/dns_blocklists.cf")
|
||||
if not Path("/opt/postfix/conf/dns_reply.map").exists():
|
||||
self.render_config("dns_reply.map.j2", "/opt/postfix/conf/dns_reply.map")
|
||||
if not Path("/opt/postfix/conf/custom_postscreen_whitelist.cidr").exists():
|
||||
self.render_config("custom_postscreen_whitelist.cidr.j2", "/opt/postfix/conf/custom_postscreen_whitelist.cidr")
|
||||
if not Path("/opt/postfix/conf/custom_transport.pcre").exists():
|
||||
self.render_config("custom_transport.pcre.j2", "/opt/postfix/conf/custom_transport.pcre")
|
||||
self.render_config("/opt/postfix/conf/config.json")
|
||||
|
||||
# Create SNI Config
|
||||
self.run_command(["postmap", "-F", "hash:/opt/postfix/conf/sni.map"])
|
||||
|
||||
@@ -80,13 +80,7 @@ class Bootstrap(BootstrapBase):
|
||||
self.set_timezone()
|
||||
|
||||
print("Render config")
|
||||
self.render_config("mailcow_networks.map.j2", "/etc/rspamd/custom/mailcow_networks.map")
|
||||
self.render_config("dovecot_trusted.map.j2", "/etc/rspamd/custom/dovecot_trusted.map")
|
||||
self.render_config("rspamd_trusted.map.j2", "/etc/rspamd/custom/rspamd_trusted.map")
|
||||
self.render_config("external_services.conf.j2", "/etc/rspamd/local.d/external_services.conf")
|
||||
self.render_config("redis.conf.j2", "/etc/rspamd/local.d/redis.conf")
|
||||
self.render_config("dqs-rbl.conf.j2", "/etc/rspamd/custom/dqs-rbl.conf")
|
||||
self.render_config("worker-controller-password.inc.j2", "/etc/rspamd/override.d/worker-controller-password.inc")
|
||||
self.render_config("/etc/rspamd/config.json")
|
||||
|
||||
# Fix missing default global maps, if any
|
||||
# These exists in mailcow UI and should not be removed
|
||||
|
||||
@@ -48,8 +48,7 @@ class Bootstrap(BootstrapBase):
|
||||
self.set_syslog_redis()
|
||||
|
||||
print("Render config")
|
||||
self.render_config("sogod.plist.j2", "/var/lib/sogo/GNUstep/Defaults/sogod.plist")
|
||||
self.render_config("UIxTopnavToolbar.wox.j2", "/usr/lib/GNUstep/SOGo/Templates/UIxTopnavToolbar.wox")
|
||||
self.render_config("/etc/sogo/config.json")
|
||||
|
||||
print("Fix permissions")
|
||||
self.set_owner("/var/lib/sogo", "sogo", "sogo", recursive=True)
|
||||
|
||||
Reference in New Issue
Block a user