1"""
2Functions for identifying which platform a machine is
3"""
4
5import multiprocessing
6import os
7import platform
8import subprocess
9import sys
10
11from distro import linux_distribution
12from salt.utils.decorators import memoize as real_memoize
13
14
15@real_memoize
16def is_windows():
17    """
18    Simple function to return if a host is Windows or not
19    """
20    return sys.platform.startswith("win")
21
22
23@real_memoize
24def is_proxy():
25    """
26    Return True if this minion is a proxy minion.
27    Leverages the fact that is_linux() and is_windows
28    both return False for proxies.
29    TODO: Need to extend this for proxies that might run on
30    other Unices
31    """
32    import __main__ as main
33
34    # This is a hack.  If a proxy minion is started by other
35    # means, e.g. a custom script that creates the minion objects
36    # then this will fail.
37    ret = False
38    try:
39        # Changed this from 'salt-proxy in main...' to 'proxy in main...'
40        # to support the testsuite's temp script that is called 'cli_salt_proxy'
41        #
42        # Add '--proxyid' or '--proxyid=...' in sys.argv so that salt-call
43        # is seen as a proxy minion
44        if "proxy" in main.__file__ or any(
45            arg for arg in sys.argv if arg.startswith("--proxyid")
46        ):
47            ret = True
48    except AttributeError:
49        pass
50    return ret
51
52
53@real_memoize
54def is_linux():
55    """
56    Simple function to return if a host is Linux or not.
57    Note for a proxy minion, we need to return something else
58    """
59    return sys.platform.startswith("linux")
60
61
62@real_memoize
63def is_darwin():
64    """
65    Simple function to return if a host is Darwin (macOS) or not
66    """
67    return sys.platform.startswith("darwin")
68
69
70@real_memoize
71def is_sunos():
72    """
73    Simple function to return if host is SunOS or not
74    """
75    return sys.platform.startswith("sunos")
76
77
78@real_memoize
79def is_smartos():
80    """
81    Simple function to return if host is SmartOS (Illumos) or not
82    """
83    if not is_sunos():
84        return False
85    else:
86        return os.uname()[3].startswith("joyent_")
87
88
89@real_memoize
90def is_smartos_globalzone():
91    """
92    Function to return if host is SmartOS (Illumos) global zone or not
93    """
94    if not is_smartos():
95        return False
96    else:
97        try:
98            zonename_proc = subprocess.Popen(
99                ["zonename"],
100                stdout=subprocess.PIPE,
101                stderr=subprocess.STDOUT,
102            )
103            zonename_output = (
104                zonename_proc.communicate()[0].strip().decode(__salt_system_encoding__)
105            )
106            zonename_retcode = zonename_proc.poll()
107        except OSError:
108            return False
109        if zonename_retcode:
110            return False
111        if zonename_output == "global":
112            return True
113
114        return False
115
116
117@real_memoize
118def is_smartos_zone():
119    """
120    Function to return if host is SmartOS (Illumos) and not the gz
121    """
122    if not is_smartos():
123        return False
124    else:
125        try:
126            zonename_proc = subprocess.Popen(
127                ["zonename"],
128                stdout=subprocess.PIPE,
129                stderr=subprocess.STDOUT,
130            )
131            zonename_output = (
132                zonename_proc.communicate()[0].strip().decode(__salt_system_encoding__)
133            )
134            zonename_retcode = zonename_proc.poll()
135        except OSError:
136            return False
137        if zonename_retcode:
138            return False
139        if zonename_output == "global":
140            return False
141
142        return True
143
144
145@real_memoize
146def is_junos():
147    """
148    Simple function to return if host is Junos or not
149    """
150    return sys.platform.startswith("freebsd") and os.uname().release.startswith("JNPR")
151
152
153@real_memoize
154def is_freebsd():
155    """
156    Simple function to return if host is FreeBSD or not
157    """
158    return sys.platform.startswith("freebsd")
159
160
161@real_memoize
162def is_netbsd():
163    """
164    Simple function to return if host is NetBSD or not
165    """
166    return sys.platform.startswith("netbsd")
167
168
169@real_memoize
170def is_openbsd():
171    """
172    Simple function to return if host is OpenBSD or not
173    """
174    return sys.platform.startswith("openbsd")
175
176
177@real_memoize
178def is_aix():
179    """
180    Simple function to return if host is AIX or not
181    """
182    return sys.platform.startswith("aix")
183
184
185@real_memoize
186def is_fedora():
187    """
188    Simple function to return if host is Fedora or not
189    """
190    (osname, osrelease, oscodename) = [
191        x.strip('"').strip("'") for x in linux_distribution()
192    ]
193    return osname == "Fedora"
194
195
196@real_memoize
197def is_photonos():
198    """
199    Simple function to return if host is Photon OS or not
200    """
201    (osname, osrelease, oscodename) = [
202        x.strip('"').strip("'") for x in linux_distribution()
203    ]
204    return osname == "VMware Photon OS"
205
206
207@real_memoize
208def is_aarch64():
209    """
210    Simple function to return if host is AArch64 or not
211    """
212    return platform.machine().startswith("aarch64")
213
214
215def spawning_platform():
216    """
217    Returns True if multiprocessing.get_start_method(allow_none=False) returns "spawn"
218
219    This is the default for Windows Python >= 3.4 and macOS on Python >= 3.8.
220    """
221    return multiprocessing.get_start_method(allow_none=False) == "spawn"
222