From fa2827a07e9c852235709f004c3f343459f4f1f4 Mon Sep 17 00:00:00 2001 From: j4n Date: Fri, 13 Feb 2026 14:58:27 +0100 Subject: [PATCH] feat(cmdeploy): guard against non-running systemd This enables docker image building without systemd running, which would make pyinfra SystemdEnabled fail. --- cmdeploy/src/cmdeploy/basedeploy.py | 5 +++++ cmdeploy/src/cmdeploy/deployers.py | 5 ++++- cmdeploy/src/cmdeploy/dovecot/deployer.py | 10 ++++++---- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cmdeploy/src/cmdeploy/basedeploy.py b/cmdeploy/src/cmdeploy/basedeploy.py index dcb17a3c..45654c27 100644 --- a/cmdeploy/src/cmdeploy/basedeploy.py +++ b/cmdeploy/src/cmdeploy/basedeploy.py @@ -5,6 +5,11 @@ import os from pyinfra.operations import files, server, systemd +def has_systemd(): + """Returns False during Docker image builds or any other non-systemd environment.""" + return os.path.isdir("/run/systemd/system") + + def get_resource(arg, pkg=__package__): return importlib.resources.files(pkg).joinpath(arg) diff --git a/cmdeploy/src/cmdeploy/deployers.py b/cmdeploy/src/cmdeploy/deployers.py index d9a549d9..c38f2dd5 100644 --- a/cmdeploy/src/cmdeploy/deployers.py +++ b/cmdeploy/src/cmdeploy/deployers.py @@ -25,6 +25,7 @@ from .basedeploy import ( activate_remote_units, configure_remote_units, get_resource, + has_systemd, ) from .dovecot.deployer import DovecotDeployer from .filtermail.deployer import FiltermailDeployer @@ -65,6 +66,8 @@ def _build_chatmaild(dist_dir) -> None: def remove_legacy_artifacts(): + if not has_systemd(): + return # disable legacy doveauth-dictproxy.service if host.get_fact(SystemdEnabled).get("doveauth-dictproxy.service"): systemd.service( @@ -299,7 +302,7 @@ class LegacyRemoveDeployer(Deployer): present=False, ) # remove echobot if it is still running - if host.get_fact(SystemdEnabled).get("echobot.service"): + if has_systemd() and host.get_fact(SystemdEnabled).get("echobot.service"): systemd.service( name="Disable echobot.service", service="echobot.service", diff --git a/cmdeploy/src/cmdeploy/dovecot/deployer.py b/cmdeploy/src/cmdeploy/dovecot/deployer.py index 5a505ecb..9a7a4232 100644 --- a/cmdeploy/src/cmdeploy/dovecot/deployer.py +++ b/cmdeploy/src/cmdeploy/dovecot/deployer.py @@ -9,6 +9,7 @@ from cmdeploy.basedeploy import ( activate_remote_units, configure_remote_units, get_resource, + has_systemd, ) @@ -22,10 +23,11 @@ class DovecotDeployer(Deployer): def install(self): arch = host.get_fact(Arch) - if not "dovecot.service" in host.get_fact(SystemdEnabled): - _install_dovecot_package("core", arch) - _install_dovecot_package("imapd", arch) - _install_dovecot_package("lmtpd", arch) + if has_systemd() and "dovecot.service" in host.get_fact(SystemdEnabled): + return # already installed and running + _install_dovecot_package("core", arch) + _install_dovecot_package("imapd", arch) + _install_dovecot_package("lmtpd", arch) def configure(self): configure_remote_units(self.config.mail_domain, self.units)