From 4cdccee63b7f7d8d9429b6d3dd0d87cea829377c Mon Sep 17 00:00:00 2001 From: j4n Date: Tue, 11 Aug 2026 11:05:17 +0200 Subject: [PATCH] feat(mtail): deploy filtermail.mtail and gate mtail rule copy on mtail_address Deploy filtermail.mtail program along delivered_mail.mtail, fetched from upstream; for this, refactor download_executable to accept mode, so we can use it to upload non-binaries. refactor: make hashes (for uniformity) and mtail version (for use by mtail deployer) module constants. Additionally, gate both mtail programs on mtail_address being set. --- cmdeploy/src/cmdeploy/basedeploy.py | 4 ++-- cmdeploy/src/cmdeploy/filtermail/deployer.py | 15 +++++++++------ cmdeploy/src/cmdeploy/mtail/deployer.py | 17 ++++++++++++++--- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/cmdeploy/src/cmdeploy/basedeploy.py b/cmdeploy/src/cmdeploy/basedeploy.py index ef0740fa..5831f218 100644 --- a/cmdeploy/src/cmdeploy/basedeploy.py +++ b/cmdeploy/src/cmdeploy/basedeploy.py @@ -227,7 +227,7 @@ class Deployer: res = files.directory(name=name, path=path, present=False, **kwargs) return self._update_restart_signals(path, res) - def download_executable(self, url, dest, sha256sum, extract=None): + def download_executable(self, url, dest, sha256sum, extract=None, mode="755"): existing = host.get_fact(Sha256File, dest) if existing == sha256sum: return @@ -244,7 +244,7 @@ class Deployer: f"({dl_cmd}" f" && echo '{sha256sum} {tmp}' | sha256sum -c" f" && mv {tmp} {dest})", - f"chmod 755 {dest}", + f"chmod {mode} {dest}", ], ) self.need_restart = True diff --git a/cmdeploy/src/cmdeploy/filtermail/deployer.py b/cmdeploy/src/cmdeploy/filtermail/deployer.py index 6c88b2df..3ba588f3 100644 --- a/cmdeploy/src/cmdeploy/filtermail/deployer.py +++ b/cmdeploy/src/cmdeploy/filtermail/deployer.py @@ -4,6 +4,13 @@ from pyinfra import facts, host from cmdeploy.basedeploy import Deployer +VERSION = "v0.7.4" # also gets used by mtail deployer +SHA256SUMS = { + "x86_64": "484cb8dff083134aefba9fce4a6b7ef4784a0f0e28e5108ecf8bb9e58a44fd2c", + "aarch64": "66aa0ca2ca9add7a12d92883d76f8786384092adfde24a3d3a1d0b1f30d23a9e", +} +MTAIL_PROGRAM_SHA256 = "948f688bb89ad47e6eb0fc8fa107e201a689f5adc264ff926be487a2a8562b51" + class FiltermailDeployer(Deployer): services = ["filtermail", "filtermail-incoming", "filtermail-transport"] @@ -20,12 +27,8 @@ class FiltermailDeployer(Deployer): return arch = host.get_fact(facts.server.Arch) - url = f"https://github.com/chatmail/filtermail/releases/download/v0.7.4/filtermail-{arch}" - sha256sum = { - "x86_64": "484cb8dff083134aefba9fce4a6b7ef4784a0f0e28e5108ecf8bb9e58a44fd2c", - "aarch64": "66aa0ca2ca9add7a12d92883d76f8786384092adfde24a3d3a1d0b1f30d23a9e", - }[arch] - self.download_executable(url, self.bin_path, sha256sum) + url = f"https://github.com/chatmail/filtermail/releases/download/{VERSION}/filtermail-{arch}" + self.download_executable(url, self.bin_path, SHA256SUMS[arch]) def configure(self): for service in self.services: diff --git a/cmdeploy/src/cmdeploy/mtail/deployer.py b/cmdeploy/src/cmdeploy/mtail/deployer.py index 6455bbaf..e00b0fb1 100644 --- a/cmdeploy/src/cmdeploy/mtail/deployer.py +++ b/cmdeploy/src/cmdeploy/mtail/deployer.py @@ -2,6 +2,10 @@ from pyinfra import facts, host from pyinfra.operations import apt from cmdeploy.basedeploy import Deployer +from cmdeploy.filtermail.deployer import ( + MTAIL_PROGRAM_SHA256 as FILTERMAIL_MTAIL_SHA256, + VERSION as FILTERMAIL_VERSION, +) class MtailDeployer(Deployer): @@ -42,9 +46,16 @@ class MtailDeployer(Deployer): bin_path=self.bin_path, progs_dir=self.progs_dir, ) - self.put_file( - "mtail/delivered_mail.mtail", f"{self.progs_dir}/delivered_mail.mtail" - ) + if self.mtail_address: + self.put_file( + "mtail/delivered_mail.mtail", f"{self.progs_dir}/delivered_mail.mtail" + ) + self.download_executable( + f"https://raw.githubusercontent.com/chatmail/filtermail/{FILTERMAIL_VERSION}/contrib/filtermail.mtail", + f"{self.progs_dir}/filtermail.mtail", + FILTERMAIL_MTAIL_SHA256, + mode="644", + ) def activate(self): active = bool(self.mtail_address)