Add umask as a global state argument

This removes the umask argument from cmd states and makes it a global
state argument.
This commit is contained in:
Erik Johnson 2020-06-25 17:17:47 -05:00 committed by Megan Wilhite
parent 637530a4ce
commit 765a5f0808
4 changed files with 70 additions and 23 deletions

View file

@ -1269,3 +1269,22 @@ times with a 2 second interval, but the file specified did not exist on any run)
Started: 09:08:12.903000
Duration: 47000.0 ms
Changes:
Run State With a Different Umask
================================
.. versionadded:: 3002
NOTE: not available on Windows
The ``umask`` state argument can be used to run a state with a different umask.
Prior to version 3002 this was available to :mod:`cmd <salt.states.cmd>`
states, but it is now a global state argument that can be applied to any state.
.. code-block:: yaml
cleanup_script:
cmd.script:
- name: salt://myapp/files/my_script.sh
- umask: "077"
- onchanges:
- file: /some/file

View file

@ -100,6 +100,7 @@ STATE_RUNTIME_KEYWORDS = frozenset(
"runas_password",
"fire_event",
"saltenv",
"umask",
"use",
"use_in",
"__env__",
@ -116,6 +117,7 @@ STATE_RUNTIME_KEYWORDS = frozenset(
"__pub_tgt_type",
"__prereq__",
"__prerequired__",
"__umask__",
]
)
@ -384,7 +386,7 @@ class Compiler:
self.opts["renderer"],
self.opts["renderer_blacklist"],
self.opts["renderer_whitelist"],
**kwargs
**kwargs,
)
if not high:
return high
@ -1319,6 +1321,12 @@ class State:
type(data["name"]).__name__,
)
)
if "umask" in data:
umask = data.pop("umask")
try:
data["__umask__"] = int(str(umask), 8)
except (TypeError, ValueError):
errors.append(f"Invalid umask: {umask}")
if errors:
return errors
full = data["state"] + "." + data["fun"]
@ -2305,9 +2313,10 @@ class State:
ret = self.call_parallel(cdata, low)
else:
self.format_slots(cdata)
ret = self.states[cdata["full"]](
*cdata["args"], **cdata["kwargs"]
)
with salt.utils.files.set_umask(low.get("__umask__")):
ret = self.states[cdata["full"]](
*cdata["args"], **cdata["kwargs"]
)
self.states.inject_globals = {}
if (
"check_cmd" in low

View file

@ -328,7 +328,6 @@ def wait(
shell=None,
env=(),
stateful=False,
umask=None,
output_loglevel="debug",
hide_output=False,
use_vt=False,
@ -408,9 +407,6 @@ def wait(
matters, i.e. Windows uses `Path` as opposed to `PATH` for other
systems.
umask
The umask (in octal) to use when running the command.
stateful
The command being executed is expected to return data about executing
a state. For more information, see the :ref:`stateful-argument` section.
@ -483,7 +479,6 @@ def wait_script(
shell=None,
env=None,
stateful=False,
umask=None,
use_vt=False,
output_loglevel="debug",
hide_output=False,
@ -566,9 +561,6 @@ def wait_script(
matters, i.e. Windows uses `Path` as opposed to `PATH` for other
systems.
umask
The umask (in octal) to use when running the command.
stateful
The command being executed is expected to return data about executing
a state. For more information, see the :ref:`stateful-argument` section.
@ -630,7 +622,6 @@ def run(
env=None,
prepend_path=None,
stateful=False,
umask=None,
output_loglevel="debug",
hide_output=False,
timeout=None,
@ -729,9 +720,6 @@ def run(
The command being executed is expected to return data about executing
a state. For more information, see the :ref:`stateful-argument` section.
umask
The umask (in octal) to use when running the command.
output_loglevel : debug
Control the loglevel at which the output from the command is logged to
the minion log.
@ -850,7 +838,6 @@ def run(
"shell": shell or __grains__["shell"],
"env": env,
"prepend_path": prepend_path,
"umask": umask,
"output_loglevel": output_loglevel,
"hide_output": hide_output,
"success_retcodes": success_retcodes,
@ -908,7 +895,6 @@ def script(
shell=None,
env=None,
stateful=False,
umask=None,
timeout=None,
use_vt=False,
output_loglevel="debug",
@ -1021,9 +1007,6 @@ def script(
saltenv : ``base``
The Salt environment to use
umask
The umask (in octal) to use when running the command.
stateful
The command being executed is expected to return data about executing
a state. For more information, see the :ref:`stateful-argument` section.
@ -1143,7 +1126,6 @@ def script(
"env": env,
"cwd": cwd,
"template": template,
"umask": umask,
"timeout": timeout,
"output_loglevel": output_loglevel,
"hide_output": hide_output,
@ -1249,7 +1231,6 @@ def call(
"use_vt": use_vt,
"output_loglevel": output_loglevel,
"hide_output": hide_output,
"umask": kwargs.get("umask"),
}
if not kws:

View file

@ -121,3 +121,41 @@ def test_state_sls_unicode_characters(salt_call_cli, base_env_state_tree_root_di
assert ret.data
expected = "cmd_|-echo1_|-echo 'This is Æ test!'_|-run"
assert expected in ret.data
@pytest.mark.skip_on_windows(reason="umask is a no-op on Windows")
@pytest.mark.parametrize("umask", (22, "022"))
def test_umask_022(salt_call_cli, umask):
"""
Should produce a file with mode 644
"""
with pytest.helpers.temp_file() as name:
name.unlink()
salt_call_cli.run("state.single", fun="file.touch", name=str(name), umask=umask)
assert oct(name.stat().st_mode)[-3:] == "644"
@pytest.mark.skip_on_windows(reason="umask is a no-op on Windows")
@pytest.mark.parametrize("umask", (27, "027"))
def test_umask_027(salt_call_cli, umask):
"""
Should produce a file with mode 640
"""
with pytest.helpers.temp_file() as name:
name.unlink()
salt_call_cli.run("state.single", fun="file.touch", name=str(name), umask=umask)
assert oct(name.stat().st_mode)[-3:] == "640"
@pytest.mark.skip_on_windows(reason="umask is a no-op on Windows")
@pytest.mark.parametrize("umask", (999, "999", "foo"))
def test_umask_invalid(salt_call_cli, umask):
"""
Test invalid umask values
"""
with pytest.helpers.temp_file() as name:
name.unlink()
ret = salt_call_cli.run(
"state.single", fun="file.touch", name=str(name), umask=umask
)
assert ret.data == [f"Invalid umask: {umask}"]