mirror of https://github.com/ansible/ansible.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
2.2 KiB
Python
66 lines
2.2 KiB
Python
# Copyright (c) 2018, Ansible Project
|
|
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
from ansible.module_utils.common.file import is_executable
|
|
from ansible.module_utils.common.warnings import deprecate
|
|
|
|
|
|
def get_bin_path(arg, opt_dirs=None, required=None):
|
|
"""
|
|
Find system executable in PATH. Raises ValueError if the executable is not found.
|
|
|
|
:param arg: the executable to find
|
|
:type arg: string
|
|
:param opt_dirs: optional list of directories to search in addition to PATH
|
|
:type opt_dirs: list of strings
|
|
:param required: DEPRECATED. This parameter will be removed in 2.21
|
|
:type required: boolean
|
|
:returns: path to arg (should be abs path unless PATH or opt_dirs are relative paths)
|
|
:raises: ValueError: if arg is not found
|
|
|
|
In addition to PATH and opt_dirs, this function also looks through /sbin, /usr/sbin and /usr/local/sbin. A lot of
|
|
modules, especially for gathering facts, depend on this behaviour.
|
|
"""
|
|
if required is not None:
|
|
deprecate(
|
|
msg="The `required` parameter in `get_bin_path` API is deprecated.",
|
|
version="2.21",
|
|
)
|
|
|
|
paths = []
|
|
sbin_paths = ['/sbin', '/usr/sbin', '/usr/local/sbin']
|
|
opt_dirs = [] if opt_dirs is None else opt_dirs
|
|
|
|
# Construct possible paths with precedence
|
|
# passed in paths
|
|
for d in opt_dirs:
|
|
if d is not None and os.path.exists(d):
|
|
paths.append(d)
|
|
# system configured paths
|
|
paths += os.environ.get('PATH', '').split(os.pathsep)
|
|
|
|
# existing /sbin dirs, if not there already
|
|
for p in sbin_paths:
|
|
if p not in paths and os.path.exists(p):
|
|
paths.append(p)
|
|
|
|
# Search for binary
|
|
bin_path = None
|
|
for d in paths:
|
|
if not d:
|
|
continue
|
|
path = os.path.join(d, arg)
|
|
if os.path.exists(path) and not os.path.isdir(path) and is_executable(path):
|
|
# fist found wins
|
|
bin_path = path
|
|
break
|
|
|
|
if bin_path is None:
|
|
raise ValueError('Failed to find required executable "%s" in paths: %s' % (arg, os.pathsep.join(paths)))
|
|
|
|
return bin_path
|