142 lines
5.1 KiB
Python
142 lines
5.1 KiB
Python
"""Modoboa related tasks."""
|
|
|
|
import os
|
|
import pwd
|
|
import shutil
|
|
import stat
|
|
|
|
from .. import python
|
|
from .. import utils
|
|
|
|
from . import base
|
|
from . import install
|
|
|
|
|
|
class Modoboa(base.Installer):
|
|
|
|
"""Modoboa installation."""
|
|
|
|
appname = "modoboa"
|
|
no_daemon = True
|
|
packages = [
|
|
"build-essential", "python-dev", "libxml2-dev", "libxslt-dev",
|
|
"libjpeg-dev", "librrd-dev", "rrdtool", "libffi-dev", "cron"]
|
|
config_files = [
|
|
"crontab=/etc/cron.d/modoboa",
|
|
"sudoers=/etc/sudoers.d/modoboa",
|
|
]
|
|
with_db = True
|
|
with_user = True
|
|
|
|
def __init__(self, config):
|
|
"""Get configuration."""
|
|
super(Modoboa, self).__init__(config)
|
|
self.venv_path = config.get("modoboa", "venv_path")
|
|
self.instance_path = config.get("modoboa", "instance_path")
|
|
self.extensions = config.get("modoboa", "extensions").split()
|
|
self.devmode = config.getboolean("modoboa", "devmode")
|
|
|
|
def _setup_venv(self):
|
|
"""Prepare a dedicated virtuelenv."""
|
|
python.setup_virtualenv(self.venv_path, sudo_user=self.user)
|
|
packages = ["modoboa", "rrdtool"]
|
|
if self.dbengine == "postgres":
|
|
packages.append("psycopg2")
|
|
else:
|
|
packages.append("MYSQL-Python")
|
|
python.install_packages(packages, self.venv_path, sudo_user=self.user)
|
|
if self.devmode:
|
|
# FIXME: use dev-requirements instead
|
|
python.install_packages(
|
|
["django-bower", "django-debug-toolbar"], self.venv_path,
|
|
sudo_user=self.user)
|
|
|
|
def _deploy_instance(self):
|
|
"""Deploy Modoboa."""
|
|
target = os.path.join(self.home_dir, "instance")
|
|
if os.path.exists(target):
|
|
utils.printcolor(
|
|
"Target directory for Modoboa deployment ({}) already exists."
|
|
" If you choose to continue, it will be removed.".format(
|
|
target),
|
|
utils.YELLOW
|
|
)
|
|
answer = utils.user_input("Do you confirm? (Y/n) ")
|
|
if answer.lower().startswith("n"):
|
|
return
|
|
shutil.rmtree(target)
|
|
|
|
prefix = ". {}; ".format(
|
|
os.path.join(self.venv_path, "bin", "activate"))
|
|
args = [
|
|
"--collectstatic",
|
|
"--timezone", self.config.get("modoboa", "timezone"),
|
|
"--domain", self.config.get("general", "hostname"),
|
|
"--extensions", " ".join(self.extensions),
|
|
"--dburl", "'default:{0}://{1}:{2}@{3}/{1}'".format(
|
|
self.config.get("database", "engine"), self.dbname,
|
|
self.dbpasswd, self.dbhost)
|
|
]
|
|
if self.devmode:
|
|
args = ["--devel"] + args
|
|
if self.config.getboolean("amavis", "enabled"):
|
|
args += [
|
|
"'amavis:{}://{}:{}@{}/{}'".format(
|
|
self.config.get("database", "engine"),
|
|
self.config.get("amavis", "dbuser"),
|
|
self.config.get("amavis", "dbpassword"),
|
|
self.dbhost,
|
|
self.config.get("amavis", "dbname")
|
|
)
|
|
]
|
|
utils.exec_cmd(
|
|
"bash -c '{} modoboa-admin.py deploy instance {}'".format(
|
|
prefix, " ".join(args)),
|
|
sudo_user=self.user, cwd=self.home_dir)
|
|
|
|
def get_template_context(self):
|
|
"""Additional variables."""
|
|
context = super(Modoboa, self).get_template_context()
|
|
extensions = self.config.get("modoboa", "extensions")
|
|
extensions = extensions.split()
|
|
context.update({
|
|
"dovecot_mailboxes_owner": (
|
|
self.config.get("dovecot", "mailboxes_owner")),
|
|
"radicale_enabled": "#" if "modoboa-radicale" in extensions else ""
|
|
})
|
|
return context
|
|
|
|
def apply_settings(self):
|
|
"""Configure modoboa."""
|
|
rrd_root_dir = os.path.join(self.home_dir, "rrdfiles")
|
|
pdf_storage_dir = os.path.join(self.home_dir, "pdfcredentials")
|
|
webmail_media_dir = os.path.join(
|
|
self.instance_path, "media", "webmail")
|
|
pw = pwd.getpwnam(self.user)
|
|
for d in [rrd_root_dir, pdf_storage_dir, webmail_media_dir]:
|
|
utils.mkdir(d, stat.S_IRWXU | stat.S_IRWXG, pw[2], pw[3])
|
|
settings = {
|
|
"admin.HANDLE_MAILBOXES": "yes",
|
|
"admin.AUTO_ACCOUNT_REMOVAL": "yes",
|
|
"modoboa_amavis.AM_PDP_MODE": "inet",
|
|
"modoboa_stats.RRD_ROOTDIR": rrd_root_dir,
|
|
"modoboa_pdfcredentials.STORAGE_DIR": pdf_storage_dir,
|
|
}
|
|
|
|
for name, value in settings.items():
|
|
query = (
|
|
"DELETE FROM lib_parameter WHERE name='{0}';"
|
|
"INSERT INTO lib_parameter (name, value) VALUES ('{0}', '{1}')"
|
|
.format(name, value)
|
|
)
|
|
self.backend._exec_query(
|
|
query, self.dbname, self.dbuser, self.dbpasswd)
|
|
|
|
def post_run(self):
|
|
"""Additional tasks."""
|
|
self._setup_venv()
|
|
self._deploy_instance()
|
|
self.apply_settings()
|
|
install("uwsgi", self.config)
|
|
install("nginx", self.config)
|