When the shell is passed as powershell or pwsh, only wrapper the shell in quotes if cmd.run is running on Windows. When quoted on Linux hosts, this results in an error when the keyword arguments are appended.

This commit is contained in:
Gareth J. Greenaway 2023-01-30 18:02:28 -08:00
parent 9b0072e9ce
commit 380c9035ec
No known key found for this signature in database
GPG key ID: 10B62F8A7CAD7A41
3 changed files with 86 additions and 13 deletions

1
changelog/63590.fixed Normal file
View file

@ -0,0 +1 @@
When the shell is passed as powershell or pwsh, only wrapper the shell in quotes if cmd.run is running on Windows. When quoted on Linux hosts, this results in an error when the keyword arguments are appended.

View file

@ -256,6 +256,34 @@ def _check_avail(cmd):
return bret and wret
def _prep_powershell_cmd(shell, cmd, stack, encoded_cmd):
"""
Prep cmd when shell is powershell
"""
# If this is running on Windows wrap
# the shell in quotes in case there are
# spaces in the paths.
if salt.utils.platform.is_windows():
shell = '"{}"'.format(shell)
# extract_stack() returns a list of tuples.
# The last item in the list [-1] is the current method.
# The third item[2] in each tuple is the name of that method.
if stack[-2][2] == "script":
cmd = '{} -NonInteractive -NoProfile -ExecutionPolicy Bypass -Command {}'.format(
shell, cmd
)
elif encoded_cmd:
cmd = '{} -NonInteractive -NoProfile -EncodedCommand {}'.format(
shell, cmd
)
else:
cmd = '{} -NonInteractive -NoProfile -Command "{}"'.format(shell, cmd)
return cmd
def _run(
cmd,
cwd=None,
@ -368,19 +396,7 @@ def _run(
# Else just run a Powershell command.
stack = traceback.extract_stack(limit=2)
# extract_stack() returns a list of tuples.
# The last item in the list [-1] is the current method.
# The third item[2] in each tuple is the name of that method.
if stack[-2][2] == "script":
cmd = '"{}" -NonInteractive -NoProfile -ExecutionPolicy Bypass -Command {}'.format(
shell, cmd
)
elif encoded_cmd:
cmd = '"{}" -NonInteractive -NoProfile -EncodedCommand {}'.format(
shell, cmd
)
else:
cmd = '"{}" -NonInteractive -NoProfile -Command "{}"'.format(shell, cmd)
cmd = _prep_powershell_cmd(shell, cmd, stack, encoded_cmd)
# munge the cmd and cwd through the template
(cmd, cwd) = _render_cmd(cmd, cwd, template, saltenv, pillarenv, pillar_override)

View file

@ -302,6 +302,16 @@ def test_powershell():
assert ret == "foo"
@pytest.mark.skip_unless_on_windows
def test_powershell_empty():
"""
Tests cmd.powershell when the output is an empty string
"""
mock_run = {"pid": 1234, "retcode": 0, "stderr": "", "stdout": ""}
with patch("salt.modules.cmdmod._run", return_value=mock_run):
ret = cmdmod.powershell("Set-ExecutionPolicy RemoteSigned")
assert ret == {}
@pytest.mark.skip_unless_on_windows
def test_powershell_empty():
"""
@ -1056,3 +1066,49 @@ def test_runas_env_sudo_group(bundled):
popen_mock.call_args_list[0][0][0]
== exp_ret
)
def test_prep_powershell_cmd():
"""
Tests _prep_powershell_cmd returns correct cmd
"""
stack = [['', '', ''], ['', '', ''], ['', '', '']]
ret = cmdmod._prep_powershell_cmd(shell="powershell",
cmd="$PSVersionTable",
stack=stack,
encoded_cmd=False)
assert ret == 'powershell -NonInteractive -NoProfile -Command "$PSVersionTable"'
ret = cmdmod._prep_powershell_cmd(shell="powershell",
cmd="$PSVersionTable",
stack=stack,
encoded_cmd=True)
assert ret == 'powershell -NonInteractive -NoProfile -EncodedCommand $PSVersionTable'
stack = [['', '', ''], ['', '', 'script'], ['', '', '']]
ret = cmdmod._prep_powershell_cmd(shell="powershell",
cmd="$PSVersionTable",
stack=stack,
encoded_cmd=False)
assert ret == 'powershell -NonInteractive -NoProfile -ExecutionPolicy Bypass -Command $PSVersionTable'
with patch("salt.utils.platform.is_windows", MagicMock(return_value=True)):
stack = [['', '', ''], ['', '', ''], ['', '', '']]
ret = cmdmod._prep_powershell_cmd(shell="powershell",
cmd="$PSVersionTable",
stack=stack,
encoded_cmd=False)
assert ret == '"powershell" -NonInteractive -NoProfile -Command "$PSVersionTable"'
ret = cmdmod._prep_powershell_cmd(shell="powershell",
cmd="$PSVersionTable",
stack=stack,
encoded_cmd=True)
assert ret == '"powershell" -NonInteractive -NoProfile -EncodedCommand $PSVersionTable'
stack = [['', '', ''], ['', '', 'script'], ['', '', '']]
ret = cmdmod._prep_powershell_cmd(shell="powershell",
cmd="$PSVersionTable",
stack=stack,
encoded_cmd=False)
assert ret == '"powershell" -NonInteractive -NoProfile -ExecutionPolicy Bypass -Command $PSVersionTable'