refactor: Add AcmetoolDeployer

- This splits the existing deploy_acmetool() routine into methods for
  the install, configure, and activate stages.
This commit is contained in:
cliffmccarthy
2025-09-08 08:16:59 -05:00
parent 04451ad537
commit 84ab4bb6b8
2 changed files with 79 additions and 62 deletions

View File

@@ -19,7 +19,7 @@ from pyinfra.facts.server import Sysctl
from pyinfra.facts.systemd import SystemdEnabled from pyinfra.facts.systemd import SystemdEnabled
from pyinfra.operations import apt, files, pip, server, systemd from pyinfra.operations import apt, files, pip, server, systemd
from .acmetool import deploy_acmetool from .acmetool import AcmetoolDeployer
from .deployer import Deployer from .deployer import Deployer
from .www import build_webpages, find_merge_conflict, get_paths from .www import build_webpages, find_merge_conflict, get_paths
@@ -913,8 +913,14 @@ def deploy_chatmail(config_path: Path, disable_mail: bool) -> None:
line="nameserver 9.9.9.9", line="nameserver 9.9.9.9",
) )
tls_domains = [mail_domain, f"mta-sts.{mail_domain}", f"www.{mail_domain}"]
unbound_deployer = UnboundDeployer() unbound_deployer = UnboundDeployer()
iroh_deployer = IrohDeployer(enable_iroh_relay=config.enable_iroh_relay) iroh_deployer = IrohDeployer(enable_iroh_relay=config.enable_iroh_relay)
# Deploy acmetool to have TLS certificates.
acmetool_deployer = AcmetoolDeployer(email=config.acme_email, domains=tls_domains)
opendkim_deployer = OpendkimDeployer(mail_domain=mail_domain) opendkim_deployer = OpendkimDeployer(mail_domain=mail_domain)
# Dovecot should be started before Postfix # Dovecot should be started before Postfix
@@ -929,6 +935,7 @@ def deploy_chatmail(config_path: Path, disable_mail: bool) -> None:
all_deployers = [ all_deployers = [
unbound_deployer, unbound_deployer,
iroh_deployer, iroh_deployer,
acmetool_deployer,
opendkim_deployer, opendkim_deployer,
dovecot_deployer, dovecot_deployer,
postfix_deployer, postfix_deployer,
@@ -1013,12 +1020,9 @@ def deploy_chatmail(config_path: Path, disable_mail: bool) -> None:
iroh_deployer.configure() iroh_deployer.configure()
iroh_deployer.activate() iroh_deployer.activate()
# Deploy acmetool to have TLS certificates. acmetool_deployer.install()
tls_domains = [mail_domain, f"mta-sts.{mail_domain}", f"www.{mail_domain}"] acmetool_deployer.configure()
deploy_acmetool( acmetool_deployer.activate()
email=config.acme_email,
domains=tls_domains,
)
apt.packages( apt.packages(
# required for setfacl for echobot # required for setfacl for echobot

View File

@@ -2,14 +2,24 @@ import importlib.resources
from pyinfra.operations import apt, files, server, systemd from pyinfra.operations import apt, files, server, systemd
from ..deployer import Deployer
def deploy_acmetool(email="", domains=[]):
"""Deploy acmetool.""" class AcmetoolDeployer(Deployer):
def __init__(self, *, email, domains, **kwargs):
super().__init__(**kwargs)
self.domains = domains
self.email = email
self.need_restart = False
@staticmethod
def install_impl():
apt.packages( apt.packages(
name="Install acmetool", name="Install acmetool",
packages=["acmetool"], packages=["acmetool"],
) )
def configure_impl(self):
files.put( files.put(
src=importlib.resources.files(__package__).joinpath("acmetool.cron").open("rb"), src=importlib.resources.files(__package__).joinpath("acmetool.cron").open("rb"),
dest="/etc/cron.d/acmetool", dest="/etc/cron.d/acmetool",
@@ -32,7 +42,7 @@ def deploy_acmetool(email="", domains=[]):
user="root", user="root",
group="root", group="root",
mode="644", mode="644",
email=email, email=self.email,
) )
files.template( files.template(
@@ -52,16 +62,19 @@ def deploy_acmetool(email="", domains=[]):
group="root", group="root",
mode="644", mode="644",
) )
self.need_restart = service_file.changed
def activate_impl(self):
systemd.service( systemd.service(
name="Setup acmetool-redirector service", name="Setup acmetool-redirector service",
service="acmetool-redirector.service", service="acmetool-redirector.service",
running=True, running=True,
enabled=True, enabled=True,
restarted=service_file.changed, restarted=self.need_restart,
) )
self.need_restart = False
server.shell( server.shell(
name=f"Request certificate for: {', '.join(domains)}", name=f"Request certificate for: {', '.join(self.domains)}",
commands=[f"acmetool want --xlog.severity=debug {' '.join(domains)}"], commands=[f"acmetool want --xlog.severity=debug {' '.join(self.domains)}"],
) )