pyinfra 3.0b4__py2.py3-none-any.whl → 3.0.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyinfra/api/facts.py +7 -50
- pyinfra/api/util.py +1 -1
- pyinfra/connectors/ssh.py +3 -3
- pyinfra/connectors/sshuserclient/client.py +1 -1
- pyinfra/facts/apk.py +5 -2
- pyinfra/facts/apt.py +13 -7
- pyinfra/facts/brew.py +26 -13
- pyinfra/facts/bsdinit.py +7 -6
- pyinfra/facts/cargo.py +4 -3
- pyinfra/facts/choco.py +6 -4
- pyinfra/facts/deb.py +12 -5
- pyinfra/facts/dnf.py +9 -6
- pyinfra/facts/docker.py +13 -6
- pyinfra/facts/files.py +3 -3
- pyinfra/facts/gem.py +5 -2
- pyinfra/facts/git.py +14 -21
- pyinfra/facts/gpg.py +2 -1
- pyinfra/facts/hardware.py +17 -11
- pyinfra/facts/launchd.py +5 -2
- pyinfra/facts/lxd.py +6 -2
- pyinfra/facts/mysql.py +7 -6
- pyinfra/facts/npm.py +2 -1
- pyinfra/facts/openrc.py +6 -2
- pyinfra/facts/pacman.py +7 -3
- pyinfra/facts/pkg.py +3 -1
- pyinfra/facts/pkgin.py +5 -2
- pyinfra/facts/postgres.py +3 -1
- pyinfra/facts/rpm.py +12 -9
- pyinfra/facts/runit.py +4 -2
- pyinfra/facts/selinux.py +12 -4
- pyinfra/facts/server.py +80 -51
- pyinfra/facts/snap.py +6 -2
- pyinfra/facts/systemd.py +10 -5
- pyinfra/facts/sysvinit.py +2 -1
- pyinfra/facts/upstart.py +5 -2
- pyinfra/facts/vzctl.py +6 -4
- pyinfra/facts/xbps.py +5 -2
- pyinfra/facts/yum.py +8 -5
- pyinfra/facts/zypper.py +7 -4
- pyinfra/operations/apt.py +5 -0
- pyinfra/operations/selinux.py +1 -1
- pyinfra/operations/server.py +1 -1
- {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/METADATA +1 -5
- {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/RECORD +54 -53
- pyinfra_cli/__main__.py +2 -3
- pyinfra_cli/inventory.py +13 -11
- pyinfra_cli/main.py +10 -9
- tests/test_api/test_api_facts.py +2 -2
- tests/test_cli/test_cli.py +0 -1
- tests/test_cli/test_cli_inventory.py +66 -0
- {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/LICENSE.md +0 -0
- {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/WHEEL +0 -0
- {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/entry_points.txt +0 -0
- {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/top_level.txt +0 -0
pyinfra/api/facts.py
CHANGED
|
@@ -14,18 +14,7 @@ import inspect
|
|
|
14
14
|
import re
|
|
15
15
|
from inspect import getcallargs
|
|
16
16
|
from socket import error as socket_error, timeout as timeout_error
|
|
17
|
-
from typing import
|
|
18
|
-
TYPE_CHECKING,
|
|
19
|
-
Any,
|
|
20
|
-
Callable,
|
|
21
|
-
Generic,
|
|
22
|
-
Iterable,
|
|
23
|
-
Optional,
|
|
24
|
-
Type,
|
|
25
|
-
TypeVar,
|
|
26
|
-
Union,
|
|
27
|
-
cast,
|
|
28
|
-
)
|
|
17
|
+
from typing import TYPE_CHECKING, Any, Callable, Generic, Iterable, Optional, Type, TypeVar, cast
|
|
29
18
|
|
|
30
19
|
import click
|
|
31
20
|
import gevent
|
|
@@ -38,7 +27,6 @@ from pyinfra.api.util import (
|
|
|
38
27
|
get_kwargs_str,
|
|
39
28
|
log_error_or_warning,
|
|
40
29
|
log_host_command_error,
|
|
41
|
-
make_hash,
|
|
42
30
|
print_host_combined_output,
|
|
43
31
|
)
|
|
44
32
|
from pyinfra.connectors.util import CommandOutput
|
|
@@ -66,11 +54,12 @@ class FactBase(Generic[T]):
|
|
|
66
54
|
|
|
67
55
|
abstract: bool = True
|
|
68
56
|
|
|
69
|
-
shell_executable:
|
|
57
|
+
shell_executable: str | None = None
|
|
70
58
|
|
|
71
|
-
|
|
59
|
+
command: Callable[..., str | StringCommand]
|
|
72
60
|
|
|
73
|
-
|
|
61
|
+
def requires_command(self, *args, **kwargs) -> str | None:
|
|
62
|
+
return None
|
|
74
63
|
|
|
75
64
|
def __init_subclass__(cls) -> None:
|
|
76
65
|
super().__init_subclass__()
|
|
@@ -113,8 +102,7 @@ class ShortFactBase(Generic[T]):
|
|
|
113
102
|
module_name = cls.__module__.replace("pyinfra.facts.", "")
|
|
114
103
|
cls.name = f"{module_name}.{cls.__name__}"
|
|
115
104
|
|
|
116
|
-
|
|
117
|
-
def process_data(data):
|
|
105
|
+
def process_data(self, data):
|
|
118
106
|
return data
|
|
119
107
|
|
|
120
108
|
|
|
@@ -130,30 +118,6 @@ def _make_command(command_attribute, host_args):
|
|
|
130
118
|
return command_attribute
|
|
131
119
|
|
|
132
120
|
|
|
133
|
-
def _get_executor_kwargs(
|
|
134
|
-
state: "State",
|
|
135
|
-
host: "Host",
|
|
136
|
-
override_kwargs: Optional[dict[str, Any]] = None,
|
|
137
|
-
override_kwarg_keys: Optional[list[str]] = None,
|
|
138
|
-
):
|
|
139
|
-
if override_kwargs is None:
|
|
140
|
-
override_kwargs = {}
|
|
141
|
-
if override_kwarg_keys is None:
|
|
142
|
-
override_kwarg_keys = []
|
|
143
|
-
|
|
144
|
-
# Use the current operation global kwargs, or generate defaults
|
|
145
|
-
global_kwargs = host.current_op_global_arguments
|
|
146
|
-
if not global_kwargs:
|
|
147
|
-
global_kwargs, _ = pop_global_arguments({}, state, host)
|
|
148
|
-
|
|
149
|
-
# Apply any current op kwargs that *weren't* found in the overrides
|
|
150
|
-
override_kwargs.update(
|
|
151
|
-
{key: value for key, value in global_kwargs.items() if key not in override_kwarg_keys},
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
return {key: value for key, value in override_kwargs.items() if key in CONNECTOR_ARGUMENT_KEYS}
|
|
155
|
-
|
|
156
|
-
|
|
157
121
|
def _handle_fact_kwargs(state, host, cls, args, kwargs):
|
|
158
122
|
args = args or []
|
|
159
123
|
kwargs = kwargs or {}
|
|
@@ -296,7 +260,7 @@ def _get_fact(
|
|
|
296
260
|
log_host_command_error(
|
|
297
261
|
host,
|
|
298
262
|
e,
|
|
299
|
-
timeout=global_kwargs
|
|
263
|
+
timeout=global_kwargs.get("_timeout"),
|
|
300
264
|
)
|
|
301
265
|
|
|
302
266
|
stdout_lines, stderr_lines = output.stdout_lines, output.stderr_lines
|
|
@@ -346,13 +310,6 @@ def _get_fact(
|
|
|
346
310
|
return data
|
|
347
311
|
|
|
348
312
|
|
|
349
|
-
def _get_fact_hash(state: "State", host: "Host", cls, args, kwargs):
|
|
350
|
-
if issubclass(cls, ShortFactBase):
|
|
351
|
-
cls = cls.fact
|
|
352
|
-
fact_kwargs, executor_kwargs = _handle_fact_kwargs(state, host, cls, args, kwargs)
|
|
353
|
-
return make_hash((cls, fact_kwargs, executor_kwargs))
|
|
354
|
-
|
|
355
|
-
|
|
356
313
|
def get_host_fact(
|
|
357
314
|
state: "State",
|
|
358
315
|
host: "Host",
|
pyinfra/api/util.py
CHANGED
|
@@ -241,7 +241,7 @@ def log_error_or_warning(
|
|
|
241
241
|
)
|
|
242
242
|
|
|
243
243
|
|
|
244
|
-
def log_host_command_error(host: "Host", e: Exception, timeout: int = 0) -> None:
|
|
244
|
+
def log_host_command_error(host: "Host", e: Exception, timeout: int | None = 0) -> None:
|
|
245
245
|
if isinstance(e, timeout_error):
|
|
246
246
|
logger.error(
|
|
247
247
|
"{0}{1}".format(
|
pyinfra/connectors/ssh.py
CHANGED
|
@@ -123,7 +123,7 @@ class SSHConnector(BaseConnector):
|
|
|
123
123
|
|
|
124
124
|
hosts = (
|
|
125
125
|
["my-host-1.net", "my-host-2.net"],
|
|
126
|
-
{"
|
|
126
|
+
{"ssh_user": "ssh-user"},
|
|
127
127
|
)
|
|
128
128
|
|
|
129
129
|
Multiple hosts with different SSH usernames:
|
|
@@ -131,8 +131,8 @@ class SSHConnector(BaseConnector):
|
|
|
131
131
|
.. code:: python
|
|
132
132
|
|
|
133
133
|
hosts = [
|
|
134
|
-
("my-host-1.net", {"
|
|
135
|
-
("my-host-2.net", {"
|
|
134
|
+
("my-host-1.net", {"ssh_user": "ssh-user"}),
|
|
135
|
+
("my-host-2.net", {"ssh_user": "other-user"}),
|
|
136
136
|
]
|
|
137
137
|
"""
|
|
138
138
|
|
pyinfra/facts/apk.py
CHANGED
|
@@ -18,8 +18,11 @@ class ApkPackages(FactBase):
|
|
|
18
18
|
}
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
command
|
|
22
|
-
|
|
21
|
+
def command(self) -> str:
|
|
22
|
+
return "apk list --installed"
|
|
23
|
+
|
|
24
|
+
def requires_command(self) -> str:
|
|
25
|
+
return "apk"
|
|
23
26
|
|
|
24
27
|
default = dict
|
|
25
28
|
|
pyinfra/facts/apt.py
CHANGED
|
@@ -52,11 +52,14 @@ class AptSources(FactBase):
|
|
|
52
52
|
]
|
|
53
53
|
"""
|
|
54
54
|
|
|
55
|
-
command
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
def command(self) -> str:
|
|
56
|
+
return make_cat_files_command(
|
|
57
|
+
"/etc/apt/sources.list",
|
|
58
|
+
"/etc/apt/sources.list.d/*.list",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def requires_command(self) -> str:
|
|
62
|
+
return "apt" # if apt installed, above should exist
|
|
60
63
|
|
|
61
64
|
default = list
|
|
62
65
|
|
|
@@ -86,5 +89,8 @@ class AptKeys(GpgFactBase):
|
|
|
86
89
|
"""
|
|
87
90
|
|
|
88
91
|
# This requires both apt-key *and* apt-key itself requires gpg
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
def command(self) -> str:
|
|
93
|
+
return "! command -v gpg || apt-key list --with-colons"
|
|
94
|
+
|
|
95
|
+
def requires_command(self) -> str:
|
|
96
|
+
return "apt-key"
|
pyinfra/facts/brew.py
CHANGED
|
@@ -37,18 +37,22 @@ class BrewVersion(FactBase):
|
|
|
37
37
|
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
|
-
command
|
|
41
|
-
|
|
40
|
+
def command(self) -> str:
|
|
41
|
+
return "brew --version"
|
|
42
|
+
|
|
43
|
+
def requires_command(self) -> str:
|
|
44
|
+
return "brew"
|
|
42
45
|
|
|
43
46
|
@staticmethod
|
|
44
47
|
def default():
|
|
45
48
|
return [0, 0, 0]
|
|
46
49
|
|
|
47
50
|
def process(self, output):
|
|
48
|
-
|
|
51
|
+
out = list(output)[0]
|
|
52
|
+
m = VERSION_MATCHER.match(out)
|
|
49
53
|
if m is not None:
|
|
50
54
|
return [int(m.group(key)) for key in ["major", "minor", "patch"]]
|
|
51
|
-
logger.warning("could not parse version string from brew: %s",
|
|
55
|
+
logger.warning("could not parse version string from brew: %s", out)
|
|
52
56
|
return self.default()
|
|
53
57
|
|
|
54
58
|
|
|
@@ -63,8 +67,11 @@ class BrewPackages(FactBase):
|
|
|
63
67
|
}
|
|
64
68
|
"""
|
|
65
69
|
|
|
66
|
-
command
|
|
67
|
-
|
|
70
|
+
def command(self) -> str:
|
|
71
|
+
return "brew list --versions"
|
|
72
|
+
|
|
73
|
+
def requires_command(self) -> str:
|
|
74
|
+
return "brew"
|
|
68
75
|
|
|
69
76
|
default = dict
|
|
70
77
|
|
|
@@ -83,11 +90,14 @@ class BrewCasks(BrewPackages):
|
|
|
83
90
|
}
|
|
84
91
|
"""
|
|
85
92
|
|
|
86
|
-
command
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
def command(self) -> str:
|
|
94
|
+
return (
|
|
95
|
+
r'if brew --version | grep -q -e "Homebrew\ +(1\.|2\.[0-5]).*" 1>/dev/null;'
|
|
96
|
+
r"then brew cask list --versions; else brew list --cask --versions; fi"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def requires_command(self) -> str:
|
|
100
|
+
return "brew"
|
|
91
101
|
|
|
92
102
|
|
|
93
103
|
class BrewTaps(FactBase):
|
|
@@ -95,8 +105,11 @@ class BrewTaps(FactBase):
|
|
|
95
105
|
Returns a list of brew taps.
|
|
96
106
|
"""
|
|
97
107
|
|
|
98
|
-
command
|
|
99
|
-
|
|
108
|
+
def command(self) -> str:
|
|
109
|
+
return "brew tap"
|
|
110
|
+
|
|
111
|
+
def requires_command(self) -> str:
|
|
112
|
+
return "brew"
|
|
100
113
|
|
|
101
114
|
default = list
|
|
102
115
|
|
pyinfra/facts/bsdinit.py
CHANGED
|
@@ -9,11 +9,12 @@ class RcdStatus(InitdStatus):
|
|
|
9
9
|
BSD init scripts are well behaved and as such their output can be trusted.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
|
-
command
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
def command(self) -> str:
|
|
13
|
+
return """
|
|
14
|
+
for SERVICE in `find /etc/rc.d /usr/local/etc/rc.d -type f`; do
|
|
15
|
+
$SERVICE status 2> /dev/null || $SERVICE check 2> /dev/null
|
|
16
|
+
echo "`basename $SERVICE`=$?"
|
|
17
|
+
done
|
|
18
|
+
"""
|
|
18
19
|
|
|
19
20
|
default = dict
|
pyinfra/facts/cargo.py
CHANGED
|
@@ -22,10 +22,11 @@ class CargoPackages(FactBase):
|
|
|
22
22
|
|
|
23
23
|
default = dict
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def command(self):
|
|
25
|
+
def command(self) -> str:
|
|
28
26
|
return "cargo install --list"
|
|
29
27
|
|
|
28
|
+
def requires_command(self) -> str:
|
|
29
|
+
return "cargo"
|
|
30
|
+
|
|
30
31
|
def process(self, output):
|
|
31
32
|
return parse_packages(CARGO_REGEX, output)
|
pyinfra/facts/choco.py
CHANGED
|
@@ -18,7 +18,9 @@ class ChocoPackages(FactBase):
|
|
|
18
18
|
}
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
command
|
|
21
|
+
def command(self) -> str:
|
|
22
|
+
return "choco list"
|
|
23
|
+
|
|
22
24
|
shell_executable = "ps"
|
|
23
25
|
|
|
24
26
|
default = dict
|
|
@@ -32,8 +34,8 @@ class ChocoVersion(FactBase):
|
|
|
32
34
|
Returns the choco (Chocolatey) version.
|
|
33
35
|
"""
|
|
34
36
|
|
|
35
|
-
command
|
|
37
|
+
def command(self) -> str:
|
|
38
|
+
return "choco --version"
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
def process(output):
|
|
40
|
+
def process(self, output):
|
|
39
41
|
return "".join(output).replace("\n", "")
|
pyinfra/facts/deb.py
CHANGED
|
@@ -16,8 +16,11 @@ class DebArch(FactBase):
|
|
|
16
16
|
Returns the architecture string used in apt repository sources, eg ``amd64``.
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
-
command
|
|
20
|
-
|
|
19
|
+
def command(self) -> str:
|
|
20
|
+
return "dpkg --print-architecture"
|
|
21
|
+
|
|
22
|
+
def requires_command(self) -> str:
|
|
23
|
+
return "dpkg"
|
|
21
24
|
|
|
22
25
|
|
|
23
26
|
class DebPackages(FactBase):
|
|
@@ -31,8 +34,11 @@ class DebPackages(FactBase):
|
|
|
31
34
|
}
|
|
32
35
|
"""
|
|
33
36
|
|
|
34
|
-
command
|
|
35
|
-
|
|
37
|
+
def command(self) -> str:
|
|
38
|
+
return "dpkg -l"
|
|
39
|
+
|
|
40
|
+
def requires_command(self) -> str:
|
|
41
|
+
return "dpkg"
|
|
36
42
|
|
|
37
43
|
default = dict
|
|
38
44
|
|
|
@@ -55,7 +61,8 @@ class DebPackage(FactBase):
|
|
|
55
61
|
"version": r"^Version:\s+({0})$".format(DEB_PACKAGE_VERSION_REGEX),
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
requires_command
|
|
64
|
+
def requires_command(self, package) -> str:
|
|
65
|
+
return "dpkg"
|
|
59
66
|
|
|
60
67
|
def command(self, package):
|
|
61
68
|
return "! test -e {0} && (dpkg -s {0} 2>/dev/null || true) || dpkg -I {0}".format(
|
pyinfra/facts/dnf.py
CHANGED
|
@@ -23,12 +23,15 @@ class DnfRepositories(FactBase):
|
|
|
23
23
|
]
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
|
-
command
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
def command(self) -> str:
|
|
27
|
+
return make_cat_files_command(
|
|
28
|
+
"/etc/dnf.conf",
|
|
29
|
+
"/etc/dnf.repos.d/*.repo",
|
|
30
|
+
"/etc/yum.repos.d/*.repo",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
def requires_command(self) -> str:
|
|
34
|
+
return "dnf"
|
|
32
35
|
|
|
33
36
|
default = list
|
|
34
37
|
|
pyinfra/facts/docker.py
CHANGED
|
@@ -9,7 +9,9 @@ class DockerFactBase(FactBase):
|
|
|
9
9
|
abstract = True
|
|
10
10
|
|
|
11
11
|
docker_type: str
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
def requires_command(self, *args, **kwargs) -> str:
|
|
14
|
+
return "docker"
|
|
13
15
|
|
|
14
16
|
def process(self, output):
|
|
15
17
|
output = "".join(output)
|
|
@@ -21,7 +23,8 @@ class DockerSystemInfo(DockerFactBase):
|
|
|
21
23
|
Returns ``docker system info`` output in JSON format.
|
|
22
24
|
"""
|
|
23
25
|
|
|
24
|
-
command
|
|
26
|
+
def command(self) -> str:
|
|
27
|
+
return 'docker system info --format="{{json .}}"'
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
# All Docker objects
|
|
@@ -33,7 +36,8 @@ class DockerContainers(DockerFactBase):
|
|
|
33
36
|
Returns ``docker inspect`` output for all Docker containers.
|
|
34
37
|
"""
|
|
35
38
|
|
|
36
|
-
command
|
|
39
|
+
def command(self) -> str:
|
|
40
|
+
return "docker container inspect `docker ps -qa`"
|
|
37
41
|
|
|
38
42
|
|
|
39
43
|
class DockerImages(DockerFactBase):
|
|
@@ -41,7 +45,8 @@ class DockerImages(DockerFactBase):
|
|
|
41
45
|
Returns ``docker inspect`` output for all Docker images.
|
|
42
46
|
"""
|
|
43
47
|
|
|
44
|
-
command
|
|
48
|
+
def command(self) -> str:
|
|
49
|
+
return "docker image inspect `docker images -q`"
|
|
45
50
|
|
|
46
51
|
|
|
47
52
|
class DockerNetworks(DockerFactBase):
|
|
@@ -49,7 +54,8 @@ class DockerNetworks(DockerFactBase):
|
|
|
49
54
|
Returns ``docker inspect`` output for all Docker networks.
|
|
50
55
|
"""
|
|
51
56
|
|
|
52
|
-
command
|
|
57
|
+
def command(self) -> str:
|
|
58
|
+
return "docker network inspect `docker network ls -q`"
|
|
53
59
|
|
|
54
60
|
|
|
55
61
|
# Single Docker objects
|
|
@@ -93,7 +99,8 @@ class DockerVolumes(DockerFactBase):
|
|
|
93
99
|
Returns ``docker inspect`` output for all Docker volumes.
|
|
94
100
|
"""
|
|
95
101
|
|
|
96
|
-
command
|
|
102
|
+
def command(self) -> str:
|
|
103
|
+
return "docker volume inspect `docker volume ls -q`"
|
|
97
104
|
|
|
98
105
|
|
|
99
106
|
class DockerVolume(DockerSingleMixin):
|
pyinfra/facts/files.py
CHANGED
|
@@ -312,8 +312,7 @@ class FindFilesBase(FactBase):
|
|
|
312
312
|
default = list
|
|
313
313
|
type_flag: str
|
|
314
314
|
|
|
315
|
-
|
|
316
|
-
def process(output):
|
|
315
|
+
def process(self, output):
|
|
317
316
|
return output
|
|
318
317
|
|
|
319
318
|
def command(self, path, quote_path=True):
|
|
@@ -353,7 +352,8 @@ class Flags(FactBase):
|
|
|
353
352
|
Returns a list of the file flags set for the specified file or directory.
|
|
354
353
|
"""
|
|
355
354
|
|
|
356
|
-
requires_command
|
|
355
|
+
def requires_command(self, path) -> str:
|
|
356
|
+
return "chflags" # don't try to retrieve them if we can't set them
|
|
357
357
|
|
|
358
358
|
def command(self, path):
|
|
359
359
|
return make_formatted_string_command(
|
pyinfra/facts/gem.py
CHANGED
pyinfra/facts/git.py
CHANGED
|
@@ -5,32 +5,29 @@ import re
|
|
|
5
5
|
from pyinfra.api.facts import FactBase
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class
|
|
9
|
-
requires_command
|
|
8
|
+
class GitFactBase(FactBase):
|
|
9
|
+
def requires_command(self, *args, **kwargs) -> str:
|
|
10
|
+
return "git"
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
class GitBranch(GitFactBase):
|
|
14
|
+
def command(self, repo) -> str:
|
|
13
15
|
return "! test -d {0} || (cd {0} && git describe --all)".format(repo)
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
def process(output):
|
|
17
|
+
def process(self, output):
|
|
17
18
|
return re.sub(r"(heads|tags)/", r"", "\n".join(output))
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
class GitConfig(
|
|
21
|
+
class GitConfig(GitFactBase):
|
|
21
22
|
default = dict
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@staticmethod
|
|
26
|
-
def command(repo=None):
|
|
24
|
+
def command(self, repo=None) -> str:
|
|
27
25
|
if repo is None:
|
|
28
26
|
return "git config --global -l || true"
|
|
29
27
|
|
|
30
28
|
return "! test -d {0} || (cd {0} && git config --local -l)".format(repo)
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
def process(output):
|
|
30
|
+
def process(self, output):
|
|
34
31
|
items: dict[str, list[str]] = {}
|
|
35
32
|
|
|
36
33
|
for line in output:
|
|
@@ -40,19 +37,15 @@ class GitConfig(FactBase):
|
|
|
40
37
|
return items
|
|
41
38
|
|
|
42
39
|
|
|
43
|
-
class GitTrackingBranch(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@staticmethod
|
|
47
|
-
def command(repo):
|
|
40
|
+
class GitTrackingBranch(GitFactBase):
|
|
41
|
+
def command(self, repo) -> str:
|
|
48
42
|
return r"! test -d {0} || (cd {0} && git status --branch --porcelain)".format(repo)
|
|
49
43
|
|
|
50
|
-
|
|
51
|
-
def process(output):
|
|
44
|
+
def process(self, output):
|
|
52
45
|
if not output:
|
|
53
46
|
return None
|
|
54
47
|
|
|
55
|
-
m = re.search(r"\.{3}(\S+)\b", output[0])
|
|
48
|
+
m = re.search(r"\.{3}(\S+)\b", list(output)[0])
|
|
56
49
|
if m:
|
|
57
50
|
return m.group(1)
|
|
58
51
|
return None
|
pyinfra/facts/gpg.py
CHANGED
pyinfra/facts/hardware.py
CHANGED
|
@@ -5,17 +5,17 @@ import re
|
|
|
5
5
|
from pyinfra.api import FactBase, ShortFactBase
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class Cpus(FactBase):
|
|
8
|
+
class Cpus(FactBase[int]):
|
|
9
9
|
"""
|
|
10
10
|
Returns the number of CPUs on this server.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
command
|
|
13
|
+
def command(self) -> str:
|
|
14
|
+
return "getconf NPROCESSORS_ONLN 2> /dev/null || getconf _NPROCESSORS_ONLN"
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
def process(output):
|
|
16
|
+
def process(self, output):
|
|
17
17
|
try:
|
|
18
|
-
return int(output[0])
|
|
18
|
+
return int(list(output)[0])
|
|
19
19
|
except ValueError:
|
|
20
20
|
pass
|
|
21
21
|
|
|
@@ -25,11 +25,13 @@ class Memory(FactBase):
|
|
|
25
25
|
Returns the memory installed in this server, in MB.
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
def requires_command(self) -> str:
|
|
29
|
+
return "vmstat"
|
|
30
|
+
|
|
31
|
+
def command(self) -> str:
|
|
32
|
+
return "vmstat -s"
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
def process(output):
|
|
34
|
+
def process(self, output):
|
|
33
35
|
data = {}
|
|
34
36
|
|
|
35
37
|
for line in output:
|
|
@@ -75,10 +77,12 @@ class BlockDevices(FactBase):
|
|
|
75
77
|
}
|
|
76
78
|
"""
|
|
77
79
|
|
|
78
|
-
command = "df"
|
|
79
80
|
regex = r"([a-zA-Z0-9\/\-_]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]{1,3})%\s+([a-zA-Z\/0-9\-_]+)" # noqa: E501
|
|
80
81
|
default = dict
|
|
81
82
|
|
|
83
|
+
def command(self) -> str:
|
|
84
|
+
return "df"
|
|
85
|
+
|
|
82
86
|
def process(self, output):
|
|
83
87
|
devices = {}
|
|
84
88
|
|
|
@@ -170,9 +174,11 @@ class NetworkDevices(FactBase):
|
|
|
170
174
|
}
|
|
171
175
|
"""
|
|
172
176
|
|
|
173
|
-
command = "ip addr show 2> /dev/null || ifconfig -a"
|
|
174
177
|
default = dict
|
|
175
178
|
|
|
179
|
+
def command(self) -> str:
|
|
180
|
+
return "ip addr show 2> /dev/null || ifconfig -a"
|
|
181
|
+
|
|
176
182
|
# Definition of valid interface names for Linux:
|
|
177
183
|
# https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/net/core/dev.c?h=v5.1.3#n1020
|
|
178
184
|
def process(self, output):
|
pyinfra/facts/launchd.py
CHANGED
|
@@ -8,8 +8,11 @@ class LaunchdStatus(FactBase):
|
|
|
8
8
|
Returns a dict of name -> status for launchd managed services.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
command
|
|
12
|
-
|
|
11
|
+
def command(self) -> str:
|
|
12
|
+
return "launchctl list"
|
|
13
|
+
|
|
14
|
+
def requires_command(self) -> str:
|
|
15
|
+
return "launchctl"
|
|
13
16
|
|
|
14
17
|
default = dict
|
|
15
18
|
|
pyinfra/facts/lxd.py
CHANGED
|
@@ -10,11 +10,15 @@ class LxdContainers(FactBase):
|
|
|
10
10
|
Returns a list of running LXD containers
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
command
|
|
14
|
-
|
|
13
|
+
def command(self) -> str:
|
|
14
|
+
return "lxc list --format json --fast"
|
|
15
|
+
|
|
16
|
+
def requires_command(self) -> str:
|
|
17
|
+
return "lxc"
|
|
15
18
|
|
|
16
19
|
default = list
|
|
17
20
|
|
|
18
21
|
def process(self, output):
|
|
22
|
+
output = list(output)
|
|
19
23
|
assert len(output) == 1
|
|
20
24
|
return json.loads(output[0])
|