mirror of
https://github.com/chatmail/relay.git
synced 2026-05-20 04:48:06 +00:00
Compare commits
6 Commits
hpk/lxc-ci
...
hpk/fixver
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a676c7e35 | ||
|
|
ba3d86c9c7 | ||
|
|
b53fd912d6 | ||
|
|
c819ee20ad | ||
|
|
7138fc7f55 | ||
|
|
d14f384de3 |
@@ -463,8 +463,9 @@ class ChatmailDeployer(Deployer):
|
|||||||
("iroh", None, None),
|
("iroh", None, None),
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, mail_domain):
|
def __init__(self, config):
|
||||||
self.mail_domain = mail_domain
|
self.config = config
|
||||||
|
self.mail_domain = config.mail_domain
|
||||||
|
|
||||||
def install(self):
|
def install(self):
|
||||||
files.put(
|
files.put(
|
||||||
@@ -513,6 +514,15 @@ class ChatmailDeployer(Deployer):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
files.directory(
|
||||||
|
name=f"Ensure mailboxes directory {self.config.mailboxes_dir} exists",
|
||||||
|
path=str(self.config.mailboxes_dir),
|
||||||
|
user="vmail",
|
||||||
|
group="vmail",
|
||||||
|
mode="700",
|
||||||
|
present=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FcgiwrapDeployer(Deployer):
|
class FcgiwrapDeployer(Deployer):
|
||||||
def install(self):
|
def install(self):
|
||||||
@@ -631,7 +641,7 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) -
|
|||||||
tls_deployer = get_tls_deployer(config, mail_domain)
|
tls_deployer = get_tls_deployer(config, mail_domain)
|
||||||
|
|
||||||
all_deployers = [
|
all_deployers = [
|
||||||
ChatmailDeployer(mail_domain),
|
ChatmailDeployer(config),
|
||||||
LegacyRemoveDeployer(),
|
LegacyRemoveDeployer(),
|
||||||
FiltermailDeployer(),
|
FiltermailDeployer(),
|
||||||
JournaldDeployer(),
|
JournaldDeployer(),
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ def _configure_dovecot(config: Config, debug: bool = False) -> (bool, bool):
|
|||||||
if not can_modify:
|
if not can_modify:
|
||||||
print(
|
print(
|
||||||
"\n!!!! refusing to attempt sysctl setting in shared-kernel containers\n"
|
"\n!!!! refusing to attempt sysctl setting in shared-kernel containers\n"
|
||||||
f"!!!! dovecot: sysctl {key!r}={value}, should be >65535 for production setups\n"
|
f"!!!! dovecot: sysctl {key!r}={value}, should be >65534 for production setups\n"
|
||||||
"!!!!"
|
"!!!!"
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ def _lxc_start_cmd(args, out):
|
|||||||
)
|
)
|
||||||
sub.green(f" Include {ssh_cfg}")
|
sub.green(f" Include {ssh_cfg}")
|
||||||
|
|
||||||
# Optionally run cmdeploy run on each relay
|
# Optionally run cmdeploy run + dns on each relay
|
||||||
if args.run:
|
if args.run:
|
||||||
for ct in relays:
|
for ct in relays:
|
||||||
with out.section(f"cmdeploy run: {ct.sname} ({ct.domain})"):
|
with out.section(f"cmdeploy run: {ct.sname} ({ct.domain})"):
|
||||||
@@ -123,6 +123,20 @@ def _lxc_start_cmd(args, out):
|
|||||||
out.red(f"Deploy to {ct.sname} failed (exit {ret})")
|
out.red(f"Deploy to {ct.sname} failed (exit {ret})")
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
with out.section("loading DNS zones"):
|
||||||
|
for ct in relays:
|
||||||
|
ret = _run_cmdeploy(
|
||||||
|
"dns", ct, ix, out,
|
||||||
|
extra=["--zonefile", str(ct.zone)],
|
||||||
|
)
|
||||||
|
if ret:
|
||||||
|
out.red(f"DNS for {ct.sname} failed (exit {ret})")
|
||||||
|
return ret
|
||||||
|
if ct.zone.exists():
|
||||||
|
dns_ct.set_dns_records(ct.zone.read_text())
|
||||||
|
out.print(f"Restarting filtermail-incoming on {ct.name}")
|
||||||
|
ct.bash("systemctl restart filtermail-incoming")
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------
|
# -------------------------------------------------------------------
|
||||||
# lxc-stop
|
# lxc-stop
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class Incus:
|
|||||||
to the terminal line-by-line while also being captured for
|
to the terminal line-by-line while also being captured for
|
||||||
later return via result.stdout.
|
later return via result.stdout.
|
||||||
"""
|
"""
|
||||||
cmd = ["incus"] + list(args)
|
cmd = ["incus", "--quiet"] + list(args)
|
||||||
sub = self.out.new_prefixed_out(" ")
|
sub = self.out.new_prefixed_out(" ")
|
||||||
|
|
||||||
if not capture:
|
if not capture:
|
||||||
@@ -146,7 +146,7 @@ class Incus:
|
|||||||
text=True,
|
text=True,
|
||||||
stdin=subprocess.PIPE if input else subprocess.DEVNULL,
|
stdin=subprocess.PIPE if input else subprocess.DEVNULL,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.PIPE,
|
||||||
)
|
)
|
||||||
|
|
||||||
stdout_lines = []
|
stdout_lines = []
|
||||||
@@ -159,15 +159,17 @@ class Incus:
|
|||||||
if sub.verbosity >= 2:
|
if sub.verbosity >= 2:
|
||||||
sub.print(f" > {line.rstrip()}")
|
sub.print(f" > {line.rstrip()}")
|
||||||
|
|
||||||
|
stderr = proc.stderr.read()
|
||||||
ret = proc.wait()
|
ret = proc.wait()
|
||||||
stdout = "".join(stdout_lines)
|
stdout = "".join(stdout_lines)
|
||||||
if check and ret != 0:
|
if check and ret != 0:
|
||||||
for line in stdout.splitlines():
|
full_output = stdout + stderr
|
||||||
|
for line in full_output.splitlines():
|
||||||
if sub.verbosity < 1: # and we haven't printed it yet
|
if sub.verbosity < 1: # and we haven't printed it yet
|
||||||
sub.red(line)
|
sub.red(line)
|
||||||
raise subprocess.CalledProcessError(ret, cmd, output=stdout)
|
raise subprocess.CalledProcessError(ret, cmd, output=stdout, stderr=stderr)
|
||||||
|
|
||||||
return subprocess.CompletedProcess(cmd, ret, stdout=stdout)
|
return subprocess.CompletedProcess(cmd, ret, stdout=stdout, stderr=stderr)
|
||||||
|
|
||||||
def run_json(self, args, check=True):
|
def run_json(self, args, check=True):
|
||||||
"""Run an incus command with ``--format=json``.
|
"""Run an incus command with ``--format=json``.
|
||||||
@@ -454,11 +456,14 @@ class RelayContainer(Container):
|
|||||||
self.bash("""
|
self.bash("""
|
||||||
sysctl -w net.ipv6.conf.all.disable_ipv6=1
|
sysctl -w net.ipv6.conf.all.disable_ipv6=1
|
||||||
sysctl -w net.ipv6.conf.default.disable_ipv6=1
|
sysctl -w net.ipv6.conf.default.disable_ipv6=1
|
||||||
mkdir -p /etc/sysctl.d
|
|
||||||
printf 'net.ipv6.conf.all.disable_ipv6=1\\n
|
|
||||||
net.ipv6.conf.default.disable_ipv6=1\\n'
|
|
||||||
> /etc/sysctl.d/99-disable-ipv6.conf
|
|
||||||
""")
|
""")
|
||||||
|
self.push_file_content(
|
||||||
|
"/etc/sysctl.d/99-disable-ipv6.conf",
|
||||||
|
"""
|
||||||
|
net.ipv6.conf.all.disable_ipv6=1
|
||||||
|
net.ipv6.conf.default.disable_ipv6=1
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
|
||||||
def configure_hosts(self, ip):
|
def configure_hosts(self, ip):
|
||||||
"""Set hostname and /etc/hosts inside the container."""
|
"""Set hostname and /etc/hosts inside the container."""
|
||||||
@@ -506,14 +511,21 @@ class RelayContainer(Container):
|
|||||||
self.bash(f"""
|
self.bash(f"""
|
||||||
systemctl disable --now systemd-resolved 2>/dev/null || true
|
systemctl disable --now systemd-resolved 2>/dev/null || true
|
||||||
rm -f /etc/resolv.conf
|
rm -f /etc/resolv.conf
|
||||||
printf 'nameserver {dns_ip}\n' >/etc/resolv.conf
|
printf 'nameserver {dns_ip}\\n' >/etc/resolv.conf
|
||||||
mkdir -p /etc/unbound/unbound.conf.d
|
mkdir -p /etc/unbound/unbound.conf.d
|
||||||
printf 'server:\\n domain-insecure: "localchat"\\n\\n
|
|
||||||
forward-zone:\\n name: "localchat"\\n
|
|
||||||
forward-addr: {dns_ip}\\n'
|
|
||||||
> /etc/unbound/unbound.conf.d/localchat-forward.conf
|
|
||||||
systemctl restart unbound 2>/dev/null || true
|
|
||||||
""")
|
""")
|
||||||
|
self.push_file_content(
|
||||||
|
"/etc/unbound/unbound.conf.d/localchat-forward.conf",
|
||||||
|
f"""
|
||||||
|
server:
|
||||||
|
domain-insecure: "localchat"
|
||||||
|
|
||||||
|
forward-zone:
|
||||||
|
name: "localchat"
|
||||||
|
forward-addr: {dns_ip}
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
self.bash("systemctl restart unbound 2>/dev/null || true")
|
||||||
self._wait_dns_reachable(dns_ip)
|
self._wait_dns_reachable(dns_ip)
|
||||||
|
|
||||||
def _wait_dns_reachable(self, dns_ip, timeout=10):
|
def _wait_dns_reachable(self, dns_ip, timeout=10):
|
||||||
|
|||||||
@@ -89,7 +89,10 @@ def test_concurrent_logins_same_account(
|
|||||||
assert login_results.get()
|
assert login_results.get()
|
||||||
|
|
||||||
|
|
||||||
def test_no_vrfy(chatmail_config):
|
def test_no_vrfy(chatmail_config, cmfactory):
|
||||||
|
ac1 = cmfactory.get_online_account()
|
||||||
|
addr = ac1.get_config("addr")
|
||||||
|
|
||||||
domain = chatmail_config.mail_domain
|
domain = chatmail_config.mail_domain
|
||||||
|
|
||||||
s = smtplib.SMTP(domain)
|
s = smtplib.SMTP(domain)
|
||||||
@@ -98,7 +101,7 @@ def test_no_vrfy(chatmail_config):
|
|||||||
s.putcmd("vrfy", f"wrongaddress@{chatmail_config.mail_domain}")
|
s.putcmd("vrfy", f"wrongaddress@{chatmail_config.mail_domain}")
|
||||||
result = s.getreply()
|
result = s.getreply()
|
||||||
print(result)
|
print(result)
|
||||||
s.putcmd("vrfy", f"echo@{chatmail_config.mail_domain}")
|
s.putcmd("vrfy", addr)
|
||||||
result2 = s.getreply()
|
result2 = s.getreply()
|
||||||
print(result2)
|
print(result2)
|
||||||
assert result[0] == result2[0] == 252
|
assert result[0] == result2[0] == 252
|
||||||
|
|||||||
@@ -516,6 +516,7 @@ class Remote:
|
|||||||
command,
|
command,
|
||||||
stdin=subprocess.DEVNULL,
|
stdin=subprocess.DEVNULL,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
)
|
)
|
||||||
self._procs.append(popen)
|
self._procs.append(popen)
|
||||||
while 1:
|
while 1:
|
||||||
|
|||||||
Reference in New Issue
Block a user