mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
65 lines
2.3 KiB
Python
65 lines
2.3 KiB
Python
"""Prefixes: shell that runs before a probe without judging the container.
|
|
|
|
A prefix does something on the way past -- sending a smoke mail is the only
|
|
one so far -- and deliberately cannot decide liveness. That separation is what
|
|
lets a probe stay the single verdict.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
MAIL_MARKER = "/tmp/email_sent" # noqa: S108 container-internal path, not a host tmpfile
|
|
|
|
|
|
def mail_branch(context: dict[str, Any]) -> str:
|
|
"""The one-shot smoke mail the msmtp prefix puts in front of a probe.
|
|
|
|
Args:
|
|
context: the probe context; needs ``email_enabled`` to do anything, plus
|
|
``domain`` -- the EHLO identity msmtp otherwise defaults to
|
|
``localhost``, which a strict relay refuses -- and ``blackhole``
|
|
for the recipient.
|
|
|
|
Returns:
|
|
The shell prefix, or an empty string when email is disabled.
|
|
|
|
Two joins carry the whole design and neither is accidental. The branch ends
|
|
in ``; `` so a relay that refuses the message cannot decide liveness -- that
|
|
verdict belongs to the probe this prefixes, and coupling them once left live
|
|
web apps marked dead until the swarm converge gate gave up (ebdadd91b). The
|
|
``&&`` before ``touch`` stays, so a refused mail leaves no marker and the
|
|
next probe retries instead of the smoke test becoming one-shot.
|
|
"""
|
|
if not context.get("email_enabled"):
|
|
return ""
|
|
domain = context.get("domain", "")
|
|
blackhole = context.get("blackhole", "")
|
|
ehlo = f"--domain={domain} " if domain else ""
|
|
return (
|
|
f"if [ ! -f {MAIL_MARKER} ]; then "
|
|
f"echo 'Subject: testmessage from {domain}\\n\\nSUCCESSFULL' "
|
|
f"| msmtp {ehlo}-t {blackhole} && touch {MAIL_MARKER}; fi; "
|
|
)
|
|
|
|
|
|
class MsmtpPrefix:
|
|
"""Sends one test mail before the liveness probe it is composed with.
|
|
|
|
Not a probe: it never judges the container. Its timings are floors the
|
|
composition may raise the probe's to, because the first run has a relay
|
|
handshake in front of it.
|
|
"""
|
|
|
|
name = "msmtp"
|
|
timeout = "20s"
|
|
retries = 5
|
|
start_period = "120s"
|
|
|
|
@staticmethod
|
|
def render(context: dict[str, Any]) -> str:
|
|
return mail_branch(context)
|
|
|
|
|
|
PREFIXES: dict[str, type[MsmtpPrefix]] = {MsmtpPrefix.name: MsmtpPrefix}
|