File: process.py

package info (click to toggle)
ansible-core 2.19.0~beta6-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 32,628 kB
  • sloc: python: 180,313; cs: 4,929; sh: 4,601; xml: 34; makefile: 21
file content (65 lines) | stat: -rw-r--r-- 2,234 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 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