diff --git a/cmdeploy/src/cmdeploy/cmdeploy.py b/cmdeploy/src/cmdeploy/cmdeploy.py index e1b0ded00..e71d0ce80 100644 --- a/cmdeploy/src/cmdeploy/cmdeploy.py +++ b/cmdeploy/src/cmdeploy/cmdeploy.py @@ -19,7 +19,7 @@ from termcolor import colored from . import dns, remote -from .sshexec import SSHExec +from .sshexec import SSHExec, LocalExec # # cmdeploy sub commands and options @@ -99,7 +99,7 @@ def run_cmd(args, out): pyinf = "pyinfra --dry" if args.dry_run else "pyinfra" cmd = f"{pyinf} --ssh-user root {ssh_host} {deploy_path} -y" - if ssh_host == "localhost": + if ssh_host in ["localhost", "@docker"]: cmd = f"{pyinf} @local {deploy_path} -y" if version.parse(pyinfra.__version__) < version.parse("3"): @@ -303,7 +303,7 @@ def add_ssh_host_option(parser): parser.add_argument( "--ssh-host", dest="ssh_host", - help="Run commands on 'localhost' or a specific SSH host " + help="Run commands on 'localhost', via '@docker', or on a specific SSH host " "instead of chatmail.ini's mail_domain.", ) @@ -365,7 +365,9 @@ def get_parser(): def get_sshexec(ssh_host: str, verbose=True): if ssh_host in ["localhost", "@local"]: - return "localhost" + return LocalExec(verbose, docker=False) + elif ssh_host == "@docker": + return LocalExec(verbose, docker=True) if verbose: print(f"[ssh] login to {ssh_host}") return SSHExec(ssh_host, verbose=verbose) diff --git a/cmdeploy/src/cmdeploy/dns.py b/cmdeploy/src/cmdeploy/dns.py index 6277d158a..2d37084d8 100644 --- a/cmdeploy/src/cmdeploy/dns.py +++ b/cmdeploy/src/cmdeploy/dns.py @@ -7,13 +7,9 @@ def get_initial_remote_data(sshexec, mail_domain): - if sshexec == "localhost": - result = remote.rdns.perform_initial_checks(mail_domain) - else: - result = sshexec.logged( - call=remote.rdns.perform_initial_checks, kwargs=dict(mail_domain=mail_domain) - ) - return result + return sshexec.logged( + call=remote.rdns.perform_initial_checks, kwargs=dict(mail_domain=mail_domain) + ) def check_initial_remote_data(remote_data, *, print=print): @@ -48,14 +44,9 @@ def check_full_zone(sshexec, remote_data, out, zonefile) -> int: """Check existing DNS records, optionally write them to zone file and return (exitcode, remote_data) tuple.""" - if sshexec == "localhost": - required_diff, recommended_diff = remote.rdns.check_zonefile( - zonefile=zonefile, verbose=False - ) - else: - required_diff, recommended_diff = sshexec.logged( - remote.rdns.check_zonefile, kwargs=dict(zonefile=zonefile, verbose=False), - ) + required_diff, recommended_diff = sshexec.logged( + remote.rdns.check_zonefile, kwargs=dict(zonefile=zonefile, verbose=False), + ) returncode = 0 if required_diff: diff --git a/cmdeploy/src/cmdeploy/sshexec.py b/cmdeploy/src/cmdeploy/sshexec.py index 400ce50d9..c8f85eee4 100644 --- a/cmdeploy/src/cmdeploy/sshexec.py +++ b/cmdeploy/src/cmdeploy/sshexec.py @@ -82,3 +82,19 @@ def logged(self, call, kwargs): res = self(call, kwargs, log_callback=remote.rshell.log_progress) print_stderr() return res + + +class LocalExec: + def __init__(self, verbose=False, docker=False): + self.verbose = verbose + self.docker = docker + + def logged(self, call, kwargs: dict): + where = "locally" + if self.docker: + if call == remote.rdns.perform_initial_checks: + kwargs['pre_command'] = "docker exec chatmail " + where = "in docker" + if self.verbose: + print(f"Running {where}: {call.__name__}(**{kwargs})") + return call(**kwargs)