From 20348734e34b7e18ac0dbe894b189aeac91b1e34 Mon Sep 17 00:00:00 2001 From: Skyler Hawthorne Date: Tue, 8 Oct 2024 19:50:57 -0400 Subject: [PATCH] print minion output, mirror salt-ssh log level --- changelog/66951.fixed | 1 + salt/client/ssh/__init__.py | 20 +++++++++++--------- salt/client/ssh/shell.py | 10 +++++++--- salt/client/ssh/ssh_py_shim.py | 5 +++-- salt/client/ssh/wrapper/state.py | 14 +++++++------- 5 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 changelog/66951.fixed diff --git a/changelog/66951.fixed b/changelog/66951.fixed new file mode 100644 index 000000000000..c73c6d666fd3 --- /dev/null +++ b/changelog/66951.fixed @@ -0,0 +1 @@ +Fix salt-ssh minion logs to stdout diff --git a/salt/client/ssh/__init__.py b/salt/client/ssh/__init__.py index a2cda6d1dc85..218502afc8c9 100644 --- a/salt/client/ssh/__init__.py +++ b/salt/client/ssh/__init__.py @@ -1446,6 +1446,7 @@ def _cmd_str(self): OPTIONS.tty = {tty} OPTIONS.cmd_umask = {cmd_umask} OPTIONS.code_checksum = {code_checksum} +OPTIONS.log_level = '{log_level}' ARGS = {arguments}\n'''.format( config=self.minion_config, delimeter=RSTR, @@ -1459,6 +1460,7 @@ def _cmd_str(self): cmd_umask=self.cmd_umask, code_checksum=thin_code_digest, arguments=self.argv, + log_level=self.opts["log_level"], ) py_code = SSH_PY_SHIM.replace("#%%OPTS", arg_str) py_code_enc = base64.encodebytes(py_code.encode("utf-8")).decode("utf-8") @@ -1501,7 +1503,7 @@ def execute_script(self, script, extension="py", pre_dir="", script_args=None): return ret - def shim_cmd(self, cmd_str, extension="py"): + def shim_cmd(self, cmd_str, extension="py", print_output=False): """ Run a shim command. @@ -1509,7 +1511,7 @@ def shim_cmd(self, cmd_str, extension="py"): execute it there """ if not self.tty and not self.winrm: - return self.shell.exec_cmd(cmd_str) + return self.shell.exec_cmd(cmd_str, print_output=print_output) # Write the shim to a temporary file in the default temp directory with tempfile.NamedTemporaryFile(mode="w+b", delete=False) as shim_tmp_file: @@ -1537,7 +1539,7 @@ def shim_cmd(self, cmd_str, extension="py"): return ret - def cmd_block(self, is_retry=False): + def cmd_block(self, is_retry=False, print_output=False): """ Prepare the pre-check command to send to the subsystem @@ -1554,7 +1556,7 @@ def cmd_block(self, is_retry=False): " ".join([str(arg) for arg in self.argv]), ) cmd_str = self._cmd_str() - stdout, stderr, retcode = self.shim_cmd(cmd_str) + stdout, stderr, retcode = self.shim_cmd(cmd_str, print_output=print_output) log.trace("STDOUT %s\n%s", self.target["host"], stdout) log.trace("STDERR %s\n%s", self.target["host"], stderr) @@ -1564,14 +1566,14 @@ def cmd_block(self, is_retry=False): if error: if error == "Python environment not found on Windows system": saltwinshell.deploy_python(self) - stdout, stderr, retcode = self.shim_cmd(cmd_str) + stdout, stderr, retcode = self.shim_cmd(cmd_str, print_output=print_output) while re.search(RSTR_RE, stdout): stdout = re.split(RSTR_RE, stdout, 1)[1].strip() while re.search(RSTR_RE, stderr): stderr = re.split(RSTR_RE, stderr, 1)[1].strip() elif error == "Undefined SHIM state": self.deploy() - stdout, stderr, retcode = self.shim_cmd(cmd_str) + stdout, stderr, retcode = self.shim_cmd(cmd_str, print_output=print_output) if not re.search(RSTR_RE, stdout) or not re.search(RSTR_RE, stderr): # If RSTR is not seen in both stdout and stderr then there # was a thin deployment problem. @@ -1610,7 +1612,7 @@ def cmd_block(self, is_retry=False): and retcode == salt.defaults.exitcodes.EX_THIN_DEPLOY ): self.deploy() - stdout, stderr, retcode = self.shim_cmd(cmd_str) + stdout, stderr, retcode = self.shim_cmd(cmd_str, print_output=print_output) if not re.search(RSTR_RE, stdout) or not re.search(RSTR_RE, stderr): if not self.tty: # If RSTR is not seen in both stdout and stderr then there @@ -1622,7 +1624,7 @@ def cmd_block(self, is_retry=False): stderr, retcode, ) - return self.cmd_block() + return self.cmd_block(print_output=print_output) elif not re.search(RSTR_RE, stdout): # If RSTR is not seen in stdout with tty, then there # was a thin deployment problem. @@ -1642,7 +1644,7 @@ def cmd_block(self, is_retry=False): stderr = re.split(RSTR_RE, stderr, 1)[1].strip() elif "ext_mods" == shim_command: self.deploy_ext() - stdout, stderr, retcode = self.shim_cmd(cmd_str) + stdout, stderr, retcode = self.shim_cmd(cmd_str, print_output=print_output) if not re.search(RSTR_RE, stdout) or not re.search(RSTR_RE, stderr): # If RSTR is not seen in both stdout and stderr then there # was a thin deployment problem. diff --git a/salt/client/ssh/shell.py b/salt/client/ssh/shell.py index 674e9f075191..8b5b39572e34 100644 --- a/salt/client/ssh/shell.py +++ b/salt/client/ssh/shell.py @@ -321,7 +321,7 @@ def exec_nb_cmd(self, cmd): yield None, None, None yield "".join(r_out), "".join(r_err), rcode - def exec_cmd(self, cmd): + def exec_cmd(self, cmd, print_output=False): """ Execute a remote command """ @@ -336,7 +336,7 @@ def exec_cmd(self, cmd): else: log.debug(logmsg) - ret = self._run_cmd(cmd) + ret = self._run_cmd(cmd, print_output=print_output) return ret def send(self, local, remote, makedirs=False): @@ -384,7 +384,7 @@ def _split_cmd(self, cmd): cmd_lst.append(f"/bin/sh {cmd_part}") return cmd_lst - def _run_cmd(self, cmd, key_accept=False, passwd_retries=3): + def _run_cmd(self, cmd, key_accept=False, passwd_retries=3, print_output=False): """ Execute a shell command via VT. This is blocking and assumes that ssh is being run @@ -419,12 +419,16 @@ def _run_cmd(self, cmd, key_accept=False, passwd_retries=3): stdout = stdout.replace(self.passwd, ("*" * 6)) ret_stdout += stdout buff = old_stdout + stdout + if print_output: + print(stdout, file=sys.stdout, end="") else: buff = stdout if stderr: if self.passwd: stderr = stderr.replace(self.passwd, ("*" * 6)) ret_stderr += stderr + if print_output: + print(stderr, file=sys.stderr, end="") if buff and RSTR_RE.search(buff): # We're getting results back, don't try to send passwords send_password = False diff --git a/salt/client/ssh/ssh_py_shim.py b/salt/client/ssh/ssh_py_shim.py index 679fb52cbbb4..4e746f4dd82a 100644 --- a/salt/client/ssh/ssh_py_shim.py +++ b/salt/client/ssh/ssh_py_shim.py @@ -7,6 +7,7 @@ helper script used by salt.client.ssh.Single. It is here, in a separate file, for convenience of development. """ + from __future__ import absolute_import, print_function import hashlib @@ -359,8 +360,8 @@ def main(argv): # pylint: disable=W0613 "--metadata", "--out", "json", - "-l", - "quiet", + "--log-level", + OPTIONS.log_level, "-c", OPTIONS.saltdir, ] diff --git a/salt/client/ssh/wrapper/state.py b/salt/client/ssh/wrapper/state.py index 4f29c92bc176..8eb47c7b7f14 100644 --- a/salt/client/ssh/wrapper/state.py +++ b/salt/client/ssh/wrapper/state.py @@ -60,7 +60,7 @@ def _ssh_state(chunks, st_kwargs, kwargs, pillar, test=False): **st_kwargs, ) single.shell.send(trans_tar, "{}/salt_state.tgz".format(__opts__["thin_dir"])) - stdout, stderr, retcode = single.cmd_block() + stdout, stderr, retcode = single.cmd_block(print_output=True) # Clean up our tar try: @@ -234,7 +234,7 @@ def sls(mods, saltenv="base", test=None, exclude=None, **kwargs): **st_kwargs, ) single.shell.send(trans_tar, "{}/salt_state.tgz".format(opts["thin_dir"])) - stdout, stderr, retcode = single.cmd_block() + stdout, stderr, retcode = single.cmd_block(print_output=True) # Clean up our tar try: @@ -372,7 +372,7 @@ def low(data, **kwargs): **st_kwargs, ) single.shell.send(trans_tar, "{}/salt_state.tgz".format(__opts__["thin_dir"])) - stdout, stderr, retcode = single.cmd_block() + stdout, stderr, retcode = single.cmd_block(print_output=True) # Clean up our tar try: @@ -465,7 +465,7 @@ def high(data, **kwargs): **st_kwargs, ) single.shell.send(trans_tar, "{}/salt_state.tgz".format(opts["thin_dir"])) - stdout, stderr, retcode = single.cmd_block() + stdout, stderr, retcode = single.cmd_block(print_output=True) # Clean up our tar try: @@ -716,7 +716,7 @@ def highstate(test=None, **kwargs): **st_kwargs, ) single.shell.send(trans_tar, "{}/salt_state.tgz".format(opts["thin_dir"])) - stdout, stderr, retcode = single.cmd_block() + stdout, stderr, retcode = single.cmd_block(print_output=True) # Clean up our tar try: @@ -807,7 +807,7 @@ def top(topfn, test=None, **kwargs): **st_kwargs, ) single.shell.send(trans_tar, "{}/salt_state.tgz".format(opts["thin_dir"])) - stdout, stderr, retcode = single.cmd_block() + stdout, stderr, retcode = single.cmd_block(print_output=True) # Clean up our tar try: @@ -1247,7 +1247,7 @@ def single(fun, name, test=None, **kwargs): single.shell.send(trans_tar, "{}/salt_state.tgz".format(opts["thin_dir"])) # Run the state.pkg command on the target - stdout, stderr, retcode = single.cmd_block() + stdout, stderr, retcode = single.cmd_block(print_output=True) # Clean up our tar try: