Mini Shell
"""
Support for Alternatives system
:codeauthor: Radek Rada <radek.rada@gmail.com>
"""
import logging
import os
import salt.utils.files
import salt.utils.path
__outputter__ = {
"display": "txt",
"install": "txt",
"remove": "txt",
}
log = logging.getLogger(__name__)
# Don't shadow built-in's.
__func_alias__ = {"set_": "set"}
def __virtual__():
"""
Only if alternatives dir is available
"""
if os.path.isdir("/etc/alternatives"):
return True
return (False, "Cannot load alternatives module: /etc/alternatives dir not found")
def _get_cmd():
"""
Alteratives commands and differ across distributions
"""
if __grains__["os_family"] == "RedHat":
return "alternatives"
return "update-alternatives"
def display(name):
"""
Display alternatives settings for defined command name
CLI Example:
.. code-block:: bash
salt '*' alternatives.display editor
"""
cmd = [_get_cmd(), "--display", name]
out = __salt__["cmd.run_all"](cmd, python_shell=False, ignore_retcode=True)
if out["retcode"] > 0 and out["stderr"] != "":
return out["stderr"]
return out["stdout"]
def _read_alternative_link_directly(name, path):
try:
with salt.utils.files.fopen(os.path.join(path, name), "rb") as r_file:
contents = salt.utils.stringutils.to_unicode(r_file.read())
return contents.splitlines(True)[1].rstrip("\n")
except OSError:
log.error("alternatives: %s does not exist", name)
except (OSError, IndexError) as exc: # pylint: disable=duplicate-except
log.error(
"alternatives: unable to get master link for %s. Exception: %s",
name,
exc,
)
return False
def _read_alternative_link_with_command(name):
cmd = [_get_cmd(), "--query", name]
out = __salt__["cmd.run_all"](cmd, python_shell=False, ignore_retcode=True)
if out["retcode"] > 0 and out["stderr"] != "":
return False
first_block = out["stdout"].split("\n\n", 1)[0]
for line in first_block.split("\n"):
if line.startswith("Link:"):
return line.split(":", 1)[1].strip()
return False
def show_link(name):
"""
Display master link for the alternative
.. versionadded:: 2015.8.13,2016.3.4,2016.11.0
CLI Example:
.. code-block:: bash
salt '*' alternatives.show_link editor
"""
if __grains__["os_family"] == "RedHat":
return _read_alternative_link_directly(name, "/var/lib/alternatives")
elif __grains__["os_family"] == "Suse":
return _read_alternative_link_directly(name, "/var/lib/rpm/alternatives")
else:
# Debian based systems
return _read_alternative_link_with_command(name)
def show_current(name):
"""
Display the current highest-priority alternative for a given alternatives
link
CLI Example:
.. code-block:: bash
salt '*' alternatives.show_current editor
"""
try:
return _read_link(name)
except OSError:
log.error("alternative: %s does not exist", name)
return False
def check_exists(name, path):
"""
Check if the given path is an alternative for a name.
.. versionadded:: 2015.8.4
CLI Example:
.. code-block:: bash
salt '*' alternatives.check_exists name path
"""
cmd = [_get_cmd(), "--display", name]
out = __salt__["cmd.run_all"](cmd, python_shell=False, ignore_retcode=True)
if out["retcode"] > 0 and out["stderr"] != "":
return False
return any(line.startswith(path) for line in out["stdout"].splitlines())
def check_installed(name, path):
"""
Check if the current highest-priority match for a given alternatives link
is set to the desired path
CLI Example:
.. code-block:: bash
salt '*' alternatives.check_installed name path
"""
try:
return _read_link(name) == path
except OSError:
return False
def install(name, link, path, priority):
"""
Install symbolic links determining default commands
CLI Example:
.. code-block:: bash
salt '*' alternatives.install editor /usr/bin/editor /usr/bin/emacs23 50
"""
cmd = [_get_cmd(), "--install", link, name, path, str(priority)]
out = __salt__["cmd.run_all"](cmd, python_shell=False)
if out["retcode"] > 0 and out["stderr"] != "":
return out["stderr"]
return out["stdout"]
def remove(name, path):
"""
Remove symbolic links determining the default commands.
CLI Example:
.. code-block:: bash
salt '*' alternatives.remove name path
"""
cmd = [_get_cmd(), "--remove", name, path]
out = __salt__["cmd.run_all"](cmd, python_shell=False)
if out["retcode"] > 0:
return out["stderr"]
return out["stdout"]
def auto(name):
"""
Trigger alternatives to set the path for <name> as
specified by priority.
CLI Example:
.. code-block:: bash
salt '*' alternatives.auto name
"""
cmd = [_get_cmd(), "--auto", name]
out = __salt__["cmd.run_all"](cmd, python_shell=False)
if out["retcode"] > 0:
return out["stderr"]
return out["stdout"]
def set_(name, path):
"""
Manually set the alternative <path> for <name>.
CLI Example:
.. code-block:: bash
salt '*' alternatives.set name path
"""
cmd = [_get_cmd(), "--set", name, path]
out = __salt__["cmd.run_all"](cmd, python_shell=False)
if out["retcode"] > 0:
return out["stderr"]
return out["stdout"]
def _read_link(name):
"""
Read the link from /etc/alternatives
Throws an OSError if the link does not exist
"""
alt_link_path = f"/etc/alternatives/{name}"
return salt.utils.path.readlink(alt_link_path)
Zerion Mini Shell 1.0