Pass lastexitcode through to retcode

This commit is contained in:
twangboy 2025-03-05 11:26:30 -07:00 committed by Daniel Wozniak
parent 8663f32962
commit b128203e9c
4 changed files with 47 additions and 7 deletions

2
changelog/60884.fixed.md Normal file
View file

@ -0,0 +1,2 @@
Fix an issue with cmd.script in Windows so that the exit code from a script will
be passed through to the retcode of the state

View file

@ -283,7 +283,10 @@ def _prep_powershell_cmd(win_shell, cmd, encoded_cmd):
new_cmd.append("-Command")
if isinstance(cmd, list):
cmd = " ".join(cmd)
new_cmd.append(f"& {cmd.strip()}")
# We need to append $LASTEXITCODE here to return the actual exit code
# from the script. Otherwise, it will always return 1 on any non-zero
# exit code failure. Issue: #60884
new_cmd.append(f"& {cmd.strip()}; exit $LASTEXITCODE")
elif encoded_cmd:
new_cmd.extend(["-EncodedCommand", f"{cmd}"])
else:

View file

@ -13,6 +13,17 @@ def cmd(modules):
return modules.cmd
@pytest.fixture(scope="module")
def exitcode_script(state_tree):
exit_code = 12345
script_contents = f"""
Write-Host "Expected exit code: {exit_code}"
exit {exit_code}
"""
with pytest.helpers.temp_file("exit_code.ps1", script_contents, state_tree):
yield exit_code
@pytest.fixture(params=["powershell", "pwsh"])
def shell(request):
"""
@ -85,3 +96,9 @@ def test_windows_script_args_powershell_runas(cmd, shell, account, issue_56195):
)
assert ret["stdout"] == password
@pytest.mark.skip_unless_on_windows(reason="Minion is not Windows")
def test_windows_script_exitcode(cmd, shell, exitcode_script):
ret = cmd.script("salt://exit_code.ps1", shell=shell, saltenv="base")
assert ret["retcode"] == exitcode_script

View file

@ -18,21 +18,39 @@ def user():
yield account
def test_compound_runas(user):
cmd = "hostname && whoami"
@pytest.mark.parametrize(
"cmd, expected",
[
("hostname && whoami", "username"),
("hostname && echo foo", "foo"),
("hostname && python --version", "Python"),
],
)
def test_compound_runas(user, cmd, expected):
if expected == "username":
expected = user.username
result = win_runas.runas(
cmdLine=cmd,
username=user.username,
password=user.password,
)
assert user.username in result["stdout"]
assert expected in result["stdout"]
def test_compound_runas_unpriv(user):
cmd = "hostname && whoami"
@pytest.mark.parametrize(
"cmd, expected",
[
("hostname && whoami", "username"),
("hostname && echo foo", "foo"),
("hostname && python --version", "Python"),
],
)
def test_compound_runas_unpriv(user, cmd, expected):
if expected == "username":
expected = user.username
result = win_runas.runas_unpriv(
cmd=cmd,
username=user.username,
password=user.password,
)
assert user.username in result["stdout"]
assert expected in result["stdout"]