Mini Shell
"""
Module for viewing and modifying sysctl parameters
"""
import os
import salt.utils.files
from salt.exceptions import CommandExecutionError
# Define the module's virtual name
__virtualname__ = "sysctl"
def __virtual__():
"""
Only run on Darwin (macOS) systems
"""
if __grains__["os"] == "MacOS":
return __virtualname__
return (
False,
"The darwin_sysctl execution module cannot be loaded: "
"Only available on macOS systems.",
)
def show(config_file=False):
"""
Return a list of sysctl parameters for this minion
config: Pull the data from the system configuration file
instead of the live data.
CLI Example:
.. code-block:: bash
salt '*' sysctl.show
"""
roots = (
"audit",
"debug",
"hw",
"hw",
"kern",
"machdep",
"net",
"net",
"security",
"user",
"vfs",
"vm",
)
cmd = "sysctl -a"
ret = {}
out = __salt__["cmd.run"](cmd, output_loglevel="trace", python_shell=False)
comps = [""]
for line in out.splitlines():
# This might need to be converted to a regex, and more, as sysctl output
# can for some reason contain entries such as:
#
# user.tzname_max = 255
# kern.clockrate: hz = 100, tick = 10000, profhz = 100, stathz = 100
# kern.clockrate: {hz = 100, tick = 10000, tickadj = 2, profhz = 100,
# stathz = 100}
#
# Yes. That's two `kern.clockrate`.
#
if any([line.startswith(f"{root}.") for root in roots]):
comps = line.split(": " if ": " in line else " = ", 1)
if len(comps) == 2:
ret[comps[0]] = comps[1]
else:
ret[comps[0]] = ""
elif comps[0]:
ret[comps[0]] += f"{line}\n"
else:
continue
return ret
def get(name):
"""
Return a single sysctl parameter for this minion
name
The name of the sysctl value to display.
CLI Example:
.. code-block:: bash
salt '*' sysctl.get hw.physmem
"""
cmd = f"sysctl -n {name}"
out = __salt__["cmd.run"](cmd, python_shell=False)
return out
def assign(name, value):
"""
Assign a single sysctl parameter for this minion
name
The name of the sysctl value to edit.
value
The sysctl value to apply.
CLI Example:
.. code-block:: bash
salt '*' sysctl.assign net.inet.icmp.icmplim 50
"""
ret = {}
cmd = f'sysctl -w {name}="{value}"'
data = __salt__["cmd.run_all"](cmd, python_shell=False)
if data["retcode"] != 0:
raise CommandExecutionError("sysctl failed: {}".format(data["stderr"]))
new_name, new_value = data["stdout"].split(":", 1)
ret[new_name] = new_value.split(" -> ")[-1]
return ret
def persist(name, value, config="/etc/sysctl.conf", apply_change=False):
"""
Assign and persist a simple sysctl parameter for this minion
name
The name of the sysctl value to edit.
value
The sysctl value to apply.
config
The location of the sysctl configuration file.
apply_change
Default is False; Default behavior only creates or edits
the sysctl.conf file. If apply is set to True, the changes are
applied to the system.
CLI Example:
.. code-block:: bash
salt '*' sysctl.persist net.inet.icmp.icmplim 50
salt '*' sysctl.persist coretemp_load NO config=/etc/sysctl.conf
"""
nlines = []
edited = False
value = str(value)
# If the sysctl.conf is not present, add it
if not os.path.isfile(config):
try:
with salt.utils.files.fopen(config, "w+") as _fh:
_fh.write("#\n# Kernel sysctl configuration\n#\n")
except OSError:
msg = "Could not write to file: {0}"
raise CommandExecutionError(msg.format(config))
with salt.utils.files.fopen(config, "r") as ifile:
for line in ifile:
line = salt.utils.stringutils.to_unicode(line)
if not line.startswith(f"{name}="):
nlines.append(line)
continue
else:
key, rest = line.split("=", 1)
if rest.startswith('"'):
_, rest_v, rest = rest.split('"', 2)
elif rest.startswith("'"):
_, rest_v, rest = rest.split("'", 2)
else:
rest_v = rest.split()[0]
rest = rest[len(rest_v) :]
if rest_v == value:
return "Already set"
nlines.append(f"{name}={value}\n")
edited = True
if not edited:
nlines.append(f"{name}={value}\n")
nlines = [salt.utils.stringutils.to_str(_l) for _l in nlines]
with salt.utils.files.fopen(config, "w+") as ofile:
ofile.writelines(nlines)
# If apply_change=True, apply edits to system
if apply_change is True:
assign(name, value)
return "Updated and applied"
return "Updated"
Zerion Mini Shell 1.0