fix(cmdeploy): Rewrite dovecot install logic, update

The old code did not install updates when the service was running; check
installed version instead of systemd status. Also, rewrite install logic
to extract dovecot version and hashes as module-level constants.
Use blocked_service_startup from lxcdeploy branch as it solves our
problem here too.
This commit is contained in:
j4n
2026-02-19 16:13:55 +01:00
parent 4fabfb31f8
commit 2635ac7e6d

View File

@@ -3,18 +3,29 @@ import urllib.request
from chatmaild.config import Config from chatmaild.config import Config
from pyinfra import host from pyinfra import host
from pyinfra.facts.deb import DebPackages
from pyinfra.facts.server import Arch, Sysctl from pyinfra.facts.server import Arch, Sysctl
from pyinfra.facts.systemd import SystemdEnabled
from pyinfra.operations import apt, files, server, systemd from pyinfra.operations import apt, files, server, systemd
from cmdeploy.basedeploy import ( from cmdeploy.basedeploy import (
Deployer, Deployer,
activate_remote_units, activate_remote_units,
blocked_service_startup,
configure_remote_units, configure_remote_units,
get_resource, get_resource,
has_systemd,
) )
DOVECOT_VERSION = "2.3.21+dfsg1-3"
DOVECOT_SHA256 = {
("core", "amd64"): "dd060706f52a306fa863d874717210b9fe10536c824afe1790eec247ded5b27d",
("core", "arm64"): "e7548e8a82929722e973629ecc40fcfa886894cef3db88f23535149e7f730dc9",
("imapd", "amd64"): "8d8dc6fc00bbb6cdb25d345844f41ce2f1c53f764b79a838eb2a03103eebfa86",
("imapd", "arm64"): "178fa877ddd5df9930e8308b518f4b07df10e759050725f8217a0c1fb3fd707f",
("lmtpd", "amd64"): "2f69ba5e35363de50962d42cccbfe4ed8495265044e244007d7ccddad77513ab",
("lmtpd", "arm64"): "89f52fb36524f5877a177dff4a713ba771fd3f91f22ed0af7238d495e143b38f",
}
class DovecotDeployer(Deployer): class DovecotDeployer(Deployer):
daemon_reload = False daemon_reload = False
@@ -26,11 +37,10 @@ class DovecotDeployer(Deployer):
def install(self): def install(self):
arch = host.get_fact(Arch) arch = host.get_fact(Arch)
if has_systemd() and "dovecot.service" in host.get_fact(SystemdEnabled): with blocked_service_startup():
return # already installed and running _install_dovecot_package("core", arch)
_install_dovecot_package("core", arch) _install_dovecot_package("imapd", arch)
_install_dovecot_package("imapd", arch) _install_dovecot_package("lmtpd", arch)
_install_dovecot_package("lmtpd", arch)
def configure(self): def configure(self):
configure_remote_units(self.config.mail_domain, self.units) configure_remote_units(self.config.mail_domain, self.units)
@@ -66,37 +76,33 @@ def _pick_url(primary, fallback):
def _install_dovecot_package(package: str, arch: str): def _install_dovecot_package(package: str, arch: str):
arch = "amd64" if arch == "x86_64" else arch arch = "amd64" if arch == "x86_64" else arch
arch = "arm64" if arch == "aarch64" else arch arch = "arm64" if arch == "aarch64" else arch
primary_url = f"https://download.delta.chat/dovecot/dovecot-{package}_2.3.21%2Bdfsg1-3_{arch}.deb"
fallback_url = f"https://github.com/chatmail/dovecot/releases/download/upstream%2F2.3.21%2Bdfsg1/dovecot-{package}_2.3.21%2Bdfsg1-3_{arch}.deb"
url = _pick_url(primary_url, fallback_url)
deb_filename = "/root/" + url.split("/")[-1]
match (package, arch): pkg_name = f"dovecot-{package}"
case ("core", "amd64"): sha256 = DOVECOT_SHA256.get((package, arch))
sha256 = "dd060706f52a306fa863d874717210b9fe10536c824afe1790eec247ded5b27d" if sha256 is None:
case ("core", "arm64"): apt.packages(packages=[pkg_name])
sha256 = "e7548e8a82929722e973629ecc40fcfa886894cef3db88f23535149e7f730dc9" return
case ("imapd", "amd64"):
sha256 = "8d8dc6fc00bbb6cdb25d345844f41ce2f1c53f764b79a838eb2a03103eebfa86" installed_versions = host.get_fact(DebPackages).get(pkg_name, [])
case ("imapd", "arm64"): if DOVECOT_VERSION in installed_versions:
sha256 = "178fa877ddd5df9930e8308b518f4b07df10e759050725f8217a0c1fb3fd707f" return
case ("lmtpd", "amd64"):
sha256 = "2f69ba5e35363de50962d42cccbfe4ed8495265044e244007d7ccddad77513ab" url_version = DOVECOT_VERSION.replace("+", "%2B")
case ("lmtpd", "arm64"): deb_base = f"{pkg_name}_{url_version}_{arch}.deb"
sha256 = "89f52fb36524f5877a177dff4a713ba771fd3f91f22ed0af7238d495e143b38f" primary_url = f"https://download.delta.chat/dovecot/{deb_base}"
case _: fallback_url = f"https://github.com/chatmail/dovecot/releases/download/upstream%2F{url_version}/{deb_base}"
apt.packages(packages=[f"dovecot-{package}"]) url = _pick_url(primary_url, fallback_url)
return deb_filename = f"/root/{deb_base}"
files.download( files.download(
name=f"Download dovecot-{package}", name=f"Download {pkg_name}",
src=url, src=url,
dest=deb_filename, dest=deb_filename,
sha256sum=sha256, sha256sum=sha256,
cache_time=60 * 60 * 24 * 365 * 10, # never redownload the package cache_time=60 * 60 * 24 * 365 * 10, # never redownload the package
) )
apt.deb(name=f"Install dovecot-{package}", src=deb_filename) apt.deb(name=f"Install {pkg_name}", src=deb_filename)
def _configure_dovecot(config: Config, debug: bool = False) -> (bool, bool): def _configure_dovecot(config: Config, debug: bool = False) -> (bool, bool):