cmdeploy: print dots for every local DNS query

This commit is contained in:
missytake
2025-08-26 12:26:13 +02:00
parent 7d99dfc0fd
commit 950b0ffcb3
4 changed files with 20 additions and 17 deletions

View File

@@ -49,7 +49,7 @@ def check_full_zone(sshexec, remote_data, out, zonefile) -> int:
and return (exitcode, remote_data) tuple.""" and return (exitcode, remote_data) tuple."""
if sshexec in ["docker", "localhost"]: if sshexec in ["docker", "localhost"]:
required_diff, recommended_diff = remote.rdns.check_zonefile(zonefile, remote_data["mail_domain"]) required_diff, recommended_diff = remote.rdns.check_zonefile(zonefile, remote_data["mail_domain"], verbose=False)
else: else:
required_diff, recommended_diff = sshexec.logged( required_diff, recommended_diff = sshexec.logged(
remote.rdns.check_zonefile, remote.rdns.check_zonefile,
@@ -58,7 +58,7 @@ def check_full_zone(sshexec, remote_data, out, zonefile) -> int:
returncode = 0 returncode = 0
if required_diff: if required_diff:
out.red("Please set required DNS entries at your DNS provider:\n") out.red("\nPlease set required DNS entries at your DNS provider:\n")
for line in required_diff: for line in required_diff:
out(line) out(line)
out("") out("")

View File

@@ -12,21 +12,21 @@ All functions of this module
import re import re
from .rshell import CalledProcessError, shell from .rshell import CalledProcessError, shell, log_progress
def perform_initial_checks(mail_domain, pre_command=""): def perform_initial_checks(mail_domain, pre_command=""):
"""Collecting initial DNS settings.""" """Collecting initial DNS settings."""
assert mail_domain assert mail_domain
if not shell("dig", fail_ok=True): if not shell("dig", fail_ok=True, print=log_progress):
shell("apt-get update && apt-get install -y dnsutils") shell("apt-get update && apt-get install -y dnsutils", print=log_progress)
A = query_dns("A", mail_domain) A = query_dns("A", mail_domain)
AAAA = query_dns("AAAA", mail_domain) AAAA = query_dns("AAAA", mail_domain)
MTA_STS = query_dns("CNAME", f"mta-sts.{mail_domain}") MTA_STS = query_dns("CNAME", f"mta-sts.{mail_domain}")
WWW = query_dns("CNAME", f"www.{mail_domain}") WWW = query_dns("CNAME", f"www.{mail_domain}")
res = dict(mail_domain=mail_domain, A=A, AAAA=AAAA, MTA_STS=MTA_STS, WWW=WWW) res = dict(mail_domain=mail_domain, A=A, AAAA=AAAA, MTA_STS=MTA_STS, WWW=WWW)
res["acme_account_url"] = shell(pre_command + "acmetool account-url", fail_ok=True) res["acme_account_url"] = shell(pre_command + "acmetool account-url", fail_ok=True, print=log_progress)
res["dkim_entry"], res["web_dkim_entry"] = get_dkim_entry( res["dkim_entry"], res["web_dkim_entry"] = get_dkim_entry(
mail_domain, pre_command, dkim_selector="opendkim" mail_domain, pre_command, dkim_selector="opendkim"
) )
@@ -44,7 +44,8 @@ def get_dkim_entry(mail_domain, pre_command, dkim_selector):
try: try:
dkim_pubkey = shell( dkim_pubkey = shell(
f"{pre_command} openssl rsa -in /etc/dkimkeys/{dkim_selector}.private " f"{pre_command} openssl rsa -in /etc/dkimkeys/{dkim_selector}.private "
"-pubout 2>/dev/null | awk '/-/{next}{printf(\"%s\",$0)}'" "-pubout 2>/dev/null | awk '/-/{next}{printf(\"%s\",$0)}'",
print=log_progress
) )
except CalledProcessError: except CalledProcessError:
return return
@@ -61,7 +62,7 @@ def query_dns(typ, domain):
# Get autoritative nameserver from the SOA record. # Get autoritative nameserver from the SOA record.
soa_answers = [ soa_answers = [
x.split() x.split()
for x in shell(f"dig -r -q {domain} -t SOA +noall +authority +answer").split( for x in shell(f"dig -r -q {domain} -t SOA +noall +authority +answer", print=log_progress).split(
"\n" "\n"
) )
] ]
@@ -71,13 +72,13 @@ def query_dns(typ, domain):
ns = soa[0][4] ns = soa[0][4]
# Query authoritative nameserver directly to bypass DNS cache. # Query authoritative nameserver directly to bypass DNS cache.
res = shell(f"dig @{ns} -r -q {domain} -t {typ} +short") res = shell(f"dig @{ns} -r -q {domain} -t {typ} +short", print=log_progress)
if res: if res:
return res.split("\n")[0] return res.split("\n")[0]
return "" return ""
def check_zonefile(zonefile, mail_domain): def check_zonefile(zonefile, mail_domain, verbose=True):
"""Check expected zone file entries.""" """Check expected zone file entries."""
required = True required = True
required_diff = [] required_diff = []
@@ -89,7 +90,7 @@ def check_zonefile(zonefile, mail_domain):
continue continue
if not zf_line.strip() or zf_line.startswith(";"): if not zf_line.strip() or zf_line.startswith(";"):
continue continue
print(f"dns-checking {zf_line!r}") print(f"dns-checking {zf_line!r}") if verbose else log_progress("")
zf_domain, zf_typ, zf_value = zf_line.split(maxsplit=2) zf_domain, zf_typ, zf_value = zf_line.split(maxsplit=2)
zf_domain = zf_domain.rstrip(".") zf_domain = zf_domain.rstrip(".")
zf_value = zf_value.strip() zf_value = zf_value.strip()

View File

@@ -1,7 +1,13 @@
from subprocess import DEVNULL, CalledProcessError, check_output from subprocess import DEVNULL, CalledProcessError, check_output
import sys
def shell(command, fail_ok=False): def log_progress(data):
sys.stderr.write(".")
sys.stderr.flush()
def shell(command, fail_ok=False, print=print):
print(f"$ {command}") print(f"$ {command}")
args = dict(shell=True) args = dict(shell=True)
if fail_ok: if fail_ok:

View File

@@ -70,10 +70,6 @@ class SSHExec:
raise self.FuncError(data) raise self.FuncError(data)
def logged(self, call, kwargs): def logged(self, call, kwargs):
def log_progress(data):
sys.stderr.write(".")
sys.stderr.flush()
title = call.__doc__ title = call.__doc__
if not title: if not title:
title = call.__name__ title = call.__name__
@@ -82,6 +78,6 @@ class SSHExec:
return self(call, kwargs, log_callback=print_stderr) return self(call, kwargs, log_callback=print_stderr)
else: else:
print_stderr(title, end="") print_stderr(title, end="")
res = self(call, kwargs, log_callback=log_progress) res = self(call, kwargs, log_callback=remote.rshell.log_progress)
print_stderr() print_stderr()
return res return res