From 652b9688d3fdf3c06e7e52a3235e27dcf54904bc Mon Sep 17 00:00:00 2001 From: holger krekel Date: Fri, 8 Dec 2023 20:34:27 +0100 Subject: [PATCH] deploy chatmaild in a virtualenv to make it easier to add dependencies --- .../{doveauth.service => doveauth.service.f} | 2 +- ...iltermail.service => filtermail.service.f} | 2 +- .../src/deploy_chatmail/__init__.py | 137 +++++++++++------- scripts/deploy.sh | 7 - 4 files changed, 84 insertions(+), 64 deletions(-) rename chatmaild/src/chatmaild/{doveauth.service => doveauth.service.f} (58%) rename chatmaild/src/chatmaild/{filtermail.service => filtermail.service.f} (76%) diff --git a/chatmaild/src/chatmaild/doveauth.service b/chatmaild/src/chatmaild/doveauth.service.f similarity index 58% rename from chatmaild/src/chatmaild/doveauth.service rename to chatmaild/src/chatmaild/doveauth.service.f index 1792fba7..89926038 100644 --- a/chatmaild/src/chatmaild/doveauth.service +++ b/chatmaild/src/chatmaild/doveauth.service.f @@ -2,7 +2,7 @@ Description=Dict authentication proxy for dovecot [Service] -ExecStart=/usr/local/bin/doveauth /run/dovecot/doveauth.socket vmail /home/vmail/passdb.sqlite +ExecStart={execpath} /run/dovecot/doveauth.socket vmail /home/vmail/passdb.sqlite Restart=always RestartSec=30 diff --git a/chatmaild/src/chatmaild/filtermail.service b/chatmaild/src/chatmaild/filtermail.service.f similarity index 76% rename from chatmaild/src/chatmaild/filtermail.service rename to chatmaild/src/chatmaild/filtermail.service.f index fec5ba4f..dd9d1290 100644 --- a/chatmaild/src/chatmaild/filtermail.service +++ b/chatmaild/src/chatmaild/filtermail.service.f @@ -2,7 +2,7 @@ Description=Chatmail Postfix BeforeQeue filter [Service] -ExecStart=/usr/local/bin/filtermail 10080 +ExecStart={execpath} 10080 Restart=always RestartSec=30 diff --git a/deploy-chatmail/src/deploy_chatmail/__init__.py b/deploy-chatmail/src/deploy_chatmail/__init__.py index 20dc0dfd..ab42a275 100644 --- a/deploy-chatmail/src/deploy_chatmail/__init__.py +++ b/deploy-chatmail/src/deploy_chatmail/__init__.py @@ -1,75 +1,102 @@ """ Chat Mail pyinfra deploy. """ +import sys import importlib.resources +import subprocess +import shutil +import io import configparser from pathlib import Path from pyinfra import host -from pyinfra.operations import apt, files, server, systemd +from pyinfra.operations import apt, files, server, systemd, pip from pyinfra.facts.files import File from pyinfra.facts.systemd import SystemdEnabled from .acmetool import deploy_acmetool -def _install_chatmaild() -> None: - chatmaild_filename = "chatmaild-0.1.tar.gz" - chatmaild_path = importlib.resources.files(__package__).joinpath( - f"../../../dist/{chatmaild_filename}" +def _build_chatmaild(dist_dir) -> None: + dist_dir = Path(dist_dir).resolve() + if dist_dir.exists(): + shutil.rmtree(dist_dir) + dist_dir.mkdir() + subprocess.check_output( + [sys.executable, "-m", "build", "-n"] + + ["--sdist", "chatmaild", "--outdir", str(dist_dir)] ) - remote_path = f"/tmp/{chatmaild_filename}" - if Path(str(chatmaild_path)).exists(): + entries = list(dist_dir.iterdir()) + assert len(entries) == 1 + return entries[0] + + +def _install_remote_venv_with_chatmaild() -> None: + dist_file = _build_chatmaild(dist_dir=Path("chatmaild/dist")) + remote_base_dir = "/usr/local/lib/chatmaild" + remote_dist_file = f"{remote_base_dir}/dist/{dist_file.name}" + remote_venv_dir = f"{remote_base_dir}/venv" + root_owned = dict(user="root", group="root", mode="644") + + apt.packages( + name="apt install python3-virtualenv", + packages=["python3-virtualenv"], + ) + + files.put( + name="Upload chatmaild source package", + src=dist_file.open("rb"), + dest=remote_dist_file, + create_remote_dir=True, + **root_owned, + ) + + pip.virtualenv( + name=f"chatmaild virtualenv {remote_venv_dir}", + path=remote_venv_dir, + always_copy=True, + ) + + server.shell( + name=f"forced pip-install {dist_file.name}", + commands=[ + f"{remote_venv_dir}/bin/pip install --force-reinstall {remote_dist_file}" + ], + ) + + # disable legacy doveauth-dictproxy.service + if host.get_fact(SystemdEnabled).get("doveauth-dictproxy.service"): + systemd.service( + name="Disable legacy doveauth-dictproxy.service", + service="doveauth-dictproxy.service", + running=False, + enabled=False, + ) + + # install systemd units + + for fn in ( + "doveauth", + "filtermail", + ): + execpath = f"{remote_venv_dir}/bin/{fn}" + source_path = importlib.resources.files("chatmaild").joinpath(f"{fn}.service.f") + content = source_path.read_text().format(execpath=execpath).encode() + files.put( - name="Upload chatmaild source package", - src=chatmaild_path.open("rb"), - dest=remote_path, + name=f"Upload {fn}.service", + src=io.BytesIO(content), + dest=f"/etc/systemd/system/{fn}.service", + **root_owned, ) - - apt.packages( - name="apt install python3-aiosmtpd python3-pip python3-venv", - packages=["python3-aiosmtpd", "python3-pip", "python3-venv"], + systemd.service( + name=f"Setup {fn} service", + service=f"{fn}.service", + running=True, + enabled=True, + restarted=True, + daemon_reload=True, ) - # --no-deps because aiosmtplib is installed with `apt`. - server.shell( - name="install chatmaild with pip", - commands=[f"pip install --break-system-packages {remote_path}"], - ) - - # disable legacy doveauth-dictproxy.service - if host.get_fact(SystemdEnabled).get("doveauth-dictproxy.service"): - systemd.service( - name="Disable legacy doveauth-dictproxy.service", - service="doveauth-dictproxy.service", - running=False, - enabled=False, - ) - - # install systemd units - - for fn in ( - "doveauth", - "filtermail", - ): - files.put( - name=f"Upload {fn}.service", - src=importlib.resources.files("chatmaild") - .joinpath(f"{fn}.service") - .open("rb"), - dest=f"/etc/systemd/system/{fn}.service", - user="root", - group="root", - mode="644", - ) - systemd.service( - name=f"Setup {fn} service", - service=f"{fn}.service", - running=True, - enabled=True, - restarted=True, - daemon_reload=True, - ) - def _configure_opendkim(domain: str, dkim_selector: str) -> bool: """Configures OpenDKIM""" @@ -381,7 +408,7 @@ def deploy_chatmail(mail_domain: str, mail_server: str, dkim_selector: str) -> N build_webpages(src_dir, build_dir, config) files.rsync(f"{build_dir}/", "/var/www/html", flags=["-avz"]) - _install_chatmaild() + _install_remote_venv_with_chatmaild() debug = False dovecot_need_restart = _configure_dovecot(mail_server, debug=debug) postfix_need_restart = _configure_postfix(mail_domain, debug=debug) diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 88be8b9d..0bcef825 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -4,12 +4,5 @@ echo ----------------------------------------- echo deploying to $CHATMAIL_DOMAIN echo ----------------------------------------- -echo WARNING: in five seconds deploy to $CHATMAIL_DOMAIN starts -sleep 5 - -venv/bin/python3 -m build -n --sdist chatmaild --outdir dist - venv/bin/pyinfra --ssh-user root "$CHATMAIL_DOMAIN" \ deploy-chatmail/src/deploy_chatmail/deploy.py - -rm -r dist/