diff --git a/changelog/66939.fixed.md b/changelog/66939.fixed.md new file mode 100644 index 000000000000..a68f15f7f129 --- /dev/null +++ b/changelog/66939.fixed.md @@ -0,0 +1 @@ +Allows file.symlink to pass a string to cmd_check diff --git a/salt/state.py b/salt/state.py index b29016560d92..5129b1929c40 100644 --- a/salt/state.py +++ b/salt/state.py @@ -1231,6 +1231,8 @@ def _run_check_cmd(self, low_data): cmd_opts = {} if "shell" in self.opts["grains"]: cmd_opts["shell"] = self.opts["grains"].get("shell") + if isinstance(low_data["check_cmd"], str): + low_data["check_cmd"] = [low_data["check_cmd"]] for entry in low_data["check_cmd"]: cmd = self.functions["cmd.retcode"]( entry, ignore_retcode=True, python_shell=True, **cmd_opts diff --git a/tests/pytests/integration/modules/test_file.py b/tests/pytests/integration/modules/test_file.py index f68031b67e71..ef8b3b4eb1c3 100644 --- a/tests/pytests/integration/modules/test_file.py +++ b/tests/pytests/integration/modules/test_file.py @@ -6,6 +6,54 @@ import pytest +import salt.utils.win_dacl + + +@pytest.fixture +def setup_symlink(tmp_path): + name = tmp_path / "test-symlink" + name.mkdir() + if salt.utils.platform.is_windows(): + principal = salt.utils.win_functions.get_current_user() + salt.utils.win_dacl.set_owner(obj_name=str(name), principal=principal) + salt.utils.win_dacl.set_inheritance(obj_name=str(name), enabled=True) + source_file = name / "source" + source_file.write_text("jaguar", encoding="utf-8") + assert source_file.exists() + assert source_file.is_file() + assert name.exists() + assert name.is_dir() + return str(name), str(source_file) + + +@pytest.fixture(params=["str", "list"]) +def sls_content(setup_symlink, request): + name, symlink_file = setup_symlink + string_contents = """ + {name}/testing: + file.symlink: + - target: {symlink_file} + - makedirs: true + - check_cmd: grep 'jaguar' {symlink_file} + """.format( + name=name, symlink_file=symlink_file + ) + list_contents = """ + {name}/testing: + file.symlink: + - target: {symlink_file} + - makedirs: true + - check_cmd: + - grep 'jaguar' {symlink_file} + - grep "j" {symlink_file} + """.format( + name=name, symlink_file=symlink_file + ) + if request.param == str: + return string_contents, name, symlink_file + else: + return list_contents, name, symlink_file + @pytest.mark.parametrize("verify_ssl", [True, False]) @pytest.mark.slow_test @@ -197,3 +245,19 @@ def test_check_file_meta_verify_ssl( ) else: assert "SSL: CERTIFICATE_VERIFY_FAILED" in ret.stderr + + +@pytest.mark.slow_test +def test_create_symlink_with_check_cmd(salt_call_cli, salt_master, sls_content): + """ + file.symlink test to make sure check_cmd runs before + creating the symlink and can run a list of commands + """ + sls_contents, name, symlink_file = sls_content + with salt_master.state_tree.base.temp_file("test_symlink.sls", sls_contents): + ret = salt_call_cli.run("state.apply", "test_symlink") + symlink_file = os.path.join(name, "testing") + assert os.path.exists(symlink_file) + assert os.path.islink(symlink_file) + expected_comment = "check_cmd determined the state succeeded" + assert expected_comment in ret.stdout