From 1b0337a5f7ea5989a2867c13eafe720ff0f149d8 Mon Sep 17 00:00:00 2001 From: j4n Date: Tue, 10 Feb 2026 17:03:04 +0100 Subject: [PATCH] fix(cmdeploy): port check: check addresses, fix single services Ensure that the interface for mtail_address is available and fix a bug in port checking where single services were always passing regardless of the specified service name. --- cmdeploy/src/cmdeploy/deployers.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cmdeploy/src/cmdeploy/deployers.py b/cmdeploy/src/cmdeploy/deployers.py index 74e077d9..5812aa28 100644 --- a/cmdeploy/src/cmdeploy/deployers.py +++ b/cmdeploy/src/cmdeploy/deployers.py @@ -10,6 +10,7 @@ from pathlib import Path from chatmaild.config import read_config from pyinfra import facts, host, logger +from pyinfra.facts import hardware from pyinfra.api import FactBase from pyinfra.facts.files import Sha256File from pyinfra.facts.systemd import SystemdEnabled @@ -36,7 +37,7 @@ from .www import build_webpages, find_merge_conflict, get_paths class Port(FactBase): """ - Returns the process occuping a port. + Returns the process occupying a port. """ def command(self, port: int) -> str: @@ -557,6 +558,14 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) - line="\nnameserver 9.9.9.9", ) + # Check if mtail_address interface is available (if configured) + if config.mtail_address and config.mtail_address not in ('127.0.0.1', '::1', 'localhost'): + ipv4_addrs = host.get_fact(hardware.Ipv4Addrs) + all_addresses = [addr for addrs in ipv4_addrs.values() for addr in addrs] + if config.mtail_address not in all_addresses: + Out().red(f"Deploy failed: mtail_address {config.mtail_address} is not available (VPN up?).\n") + exit(1) + port_services = [ (["master", "smtpd"], 25), ("unbound", 53), @@ -568,7 +577,7 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) - (["imap-login", "dovecot"], 993), ("iroh-relay", 3340), ("mtail", 3903), - ("dovecot-stats", 3904), + ("stats", 3904), ("nginx", 8443), (["master", "smtpd"], config.postfix_reinject_port), (["master", "smtpd"], config.postfix_reinject_port_incoming), @@ -578,8 +587,9 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) - for service, port in port_services: print(f"Checking if port {port} is available for {service}...") running_service = host.get_fact(Port, port=port) + services = [service] if isinstance(service, str) else service if running_service: - if running_service not in service: + if running_service not in services: Out().red( f"Deploy failed: port {port} is occupied by: {running_service}" )