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.
This commit is contained in:
j4n
2026-02-10 17:03:04 +01:00
parent dfcaf415b1
commit 1b0337a5f7

View File

@@ -10,6 +10,7 @@ from pathlib import Path
from chatmaild.config import read_config from chatmaild.config import read_config
from pyinfra import facts, host, logger from pyinfra import facts, host, logger
from pyinfra.facts import hardware
from pyinfra.api import FactBase from pyinfra.api import FactBase
from pyinfra.facts.files import Sha256File from pyinfra.facts.files import Sha256File
from pyinfra.facts.systemd import SystemdEnabled from pyinfra.facts.systemd import SystemdEnabled
@@ -36,7 +37,7 @@ from .www import build_webpages, find_merge_conflict, get_paths
class Port(FactBase): class Port(FactBase):
""" """
Returns the process occuping a port. Returns the process occupying a port.
""" """
def command(self, port: int) -> str: 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", 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 = [ port_services = [
(["master", "smtpd"], 25), (["master", "smtpd"], 25),
("unbound", 53), ("unbound", 53),
@@ -568,7 +577,7 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) -
(["imap-login", "dovecot"], 993), (["imap-login", "dovecot"], 993),
("iroh-relay", 3340), ("iroh-relay", 3340),
("mtail", 3903), ("mtail", 3903),
("dovecot-stats", 3904), ("stats", 3904),
("nginx", 8443), ("nginx", 8443),
(["master", "smtpd"], config.postfix_reinject_port), (["master", "smtpd"], config.postfix_reinject_port),
(["master", "smtpd"], config.postfix_reinject_port_incoming), (["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: for service, port in port_services:
print(f"Checking if port {port} is available for {service}...") print(f"Checking if port {port} is available for {service}...")
running_service = host.get_fact(Port, port=port) running_service = host.get_fact(Port, port=port)
services = [service] if isinstance(service, str) else service
if running_service: if running_service:
if running_service not in service: if running_service not in services:
Out().red( Out().red(
f"Deploy failed: port {port} is occupied by: {running_service}" f"Deploy failed: port {port} is occupied by: {running_service}"
) )