pyinfra 0.11.dev3__py3-none-any.whl → 3.5.1__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/__init__.py +9 -12
- pyinfra/__main__.py +4 -0
- pyinfra/api/__init__.py +18 -3
- pyinfra/api/arguments.py +406 -0
- pyinfra/api/arguments_typed.py +79 -0
- pyinfra/api/command.py +274 -0
- pyinfra/api/config.py +222 -28
- pyinfra/api/connect.py +33 -13
- pyinfra/api/connectors.py +27 -0
- pyinfra/api/deploy.py +65 -66
- pyinfra/api/exceptions.py +67 -18
- pyinfra/api/facts.py +253 -202
- pyinfra/api/host.py +413 -50
- pyinfra/api/inventory.py +121 -160
- pyinfra/api/operation.py +432 -262
- pyinfra/api/operations.py +273 -260
- pyinfra/api/state.py +302 -248
- pyinfra/api/util.py +291 -368
- pyinfra/connectors/base.py +173 -0
- pyinfra/connectors/chroot.py +212 -0
- pyinfra/connectors/docker.py +381 -0
- pyinfra/connectors/dockerssh.py +297 -0
- pyinfra/connectors/local.py +238 -0
- pyinfra/connectors/scp/__init__.py +1 -0
- pyinfra/connectors/scp/client.py +204 -0
- pyinfra/connectors/ssh.py +670 -0
- pyinfra/connectors/ssh_util.py +114 -0
- pyinfra/connectors/sshuserclient/client.py +309 -0
- pyinfra/connectors/sshuserclient/config.py +102 -0
- pyinfra/connectors/terraform.py +135 -0
- pyinfra/connectors/util.py +410 -0
- pyinfra/connectors/vagrant.py +183 -0
- pyinfra/context.py +145 -0
- pyinfra/facts/__init__.py +7 -6
- pyinfra/facts/apk.py +22 -7
- pyinfra/facts/apt.py +117 -60
- pyinfra/facts/brew.py +100 -15
- pyinfra/facts/bsdinit.py +23 -0
- pyinfra/facts/cargo.py +37 -0
- pyinfra/facts/choco.py +47 -0
- pyinfra/facts/crontab.py +195 -0
- pyinfra/facts/deb.py +94 -0
- pyinfra/facts/dnf.py +48 -0
- pyinfra/facts/docker.py +96 -23
- pyinfra/facts/efibootmgr.py +113 -0
- pyinfra/facts/files.py +630 -58
- pyinfra/facts/flatpak.py +77 -0
- pyinfra/facts/freebsd.py +70 -0
- pyinfra/facts/gem.py +19 -6
- pyinfra/facts/git.py +59 -14
- pyinfra/facts/gpg.py +150 -0
- pyinfra/facts/hardware.py +313 -167
- pyinfra/facts/iptables.py +72 -62
- pyinfra/facts/launchd.py +44 -0
- pyinfra/facts/lxd.py +17 -4
- pyinfra/facts/mysql.py +122 -86
- pyinfra/facts/npm.py +17 -9
- pyinfra/facts/openrc.py +71 -0
- pyinfra/facts/opkg.py +246 -0
- pyinfra/facts/pacman.py +50 -7
- pyinfra/facts/pip.py +24 -7
- pyinfra/facts/pipx.py +82 -0
- pyinfra/facts/pkg.py +15 -6
- pyinfra/facts/pkgin.py +35 -0
- pyinfra/facts/podman.py +54 -0
- pyinfra/facts/postgres.py +178 -0
- pyinfra/facts/postgresql.py +6 -147
- pyinfra/facts/rpm.py +105 -0
- pyinfra/facts/runit.py +77 -0
- pyinfra/facts/selinux.py +161 -0
- pyinfra/facts/server.py +746 -285
- pyinfra/facts/snap.py +88 -0
- pyinfra/facts/systemd.py +139 -0
- pyinfra/facts/sysvinit.py +59 -0
- pyinfra/facts/upstart.py +35 -0
- pyinfra/facts/util/__init__.py +17 -0
- pyinfra/facts/util/databases.py +4 -6
- pyinfra/facts/util/packaging.py +37 -6
- pyinfra/facts/util/units.py +30 -0
- pyinfra/facts/util/win_files.py +99 -0
- pyinfra/facts/vzctl.py +20 -13
- pyinfra/facts/xbps.py +35 -0
- pyinfra/facts/yum.py +34 -40
- pyinfra/facts/zfs.py +77 -0
- pyinfra/facts/zypper.py +42 -0
- pyinfra/local.py +45 -83
- pyinfra/operations/__init__.py +12 -0
- pyinfra/operations/apk.py +98 -0
- pyinfra/operations/apt.py +488 -0
- pyinfra/operations/brew.py +231 -0
- pyinfra/operations/bsdinit.py +59 -0
- pyinfra/operations/cargo.py +45 -0
- pyinfra/operations/choco.py +61 -0
- pyinfra/operations/crontab.py +191 -0
- pyinfra/operations/dnf.py +210 -0
- pyinfra/operations/docker.py +446 -0
- pyinfra/operations/files.py +1939 -0
- pyinfra/operations/flatpak.py +94 -0
- pyinfra/operations/freebsd/__init__.py +12 -0
- pyinfra/operations/freebsd/freebsd_update.py +70 -0
- pyinfra/operations/freebsd/pkg.py +219 -0
- pyinfra/operations/freebsd/service.py +116 -0
- pyinfra/operations/freebsd/sysrc.py +92 -0
- pyinfra/operations/gem.py +47 -0
- pyinfra/operations/git.py +419 -0
- pyinfra/operations/iptables.py +311 -0
- pyinfra/operations/launchd.py +45 -0
- pyinfra/operations/lxd.py +68 -0
- pyinfra/operations/mysql.py +609 -0
- pyinfra/operations/npm.py +57 -0
- pyinfra/operations/openrc.py +63 -0
- pyinfra/operations/opkg.py +88 -0
- pyinfra/operations/pacman.py +81 -0
- pyinfra/operations/pip.py +205 -0
- pyinfra/operations/pipx.py +102 -0
- pyinfra/operations/pkg.py +70 -0
- pyinfra/operations/pkgin.py +91 -0
- pyinfra/operations/postgres.py +436 -0
- pyinfra/operations/postgresql.py +30 -0
- pyinfra/operations/puppet.py +40 -0
- pyinfra/operations/python.py +72 -0
- pyinfra/operations/runit.py +184 -0
- pyinfra/operations/selinux.py +189 -0
- pyinfra/operations/server.py +1099 -0
- pyinfra/operations/snap.py +117 -0
- pyinfra/operations/ssh.py +216 -0
- pyinfra/operations/systemd.py +149 -0
- pyinfra/operations/sysvinit.py +141 -0
- pyinfra/operations/upstart.py +68 -0
- pyinfra/operations/util/__init__.py +12 -0
- pyinfra/operations/util/docker.py +251 -0
- pyinfra/operations/util/files.py +247 -0
- pyinfra/operations/util/packaging.py +336 -0
- pyinfra/operations/util/service.py +46 -0
- pyinfra/operations/vzctl.py +137 -0
- pyinfra/operations/xbps.py +77 -0
- pyinfra/operations/yum.py +210 -0
- pyinfra/operations/zfs.py +175 -0
- pyinfra/operations/zypper.py +192 -0
- pyinfra/progress.py +44 -32
- pyinfra/py.typed +0 -0
- pyinfra/version.py +9 -1
- pyinfra-3.5.1.dist-info/METADATA +141 -0
- pyinfra-3.5.1.dist-info/RECORD +159 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.5.1.dist-info}/WHEEL +1 -2
- pyinfra-3.5.1.dist-info/entry_points.txt +12 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.5.1.dist-info/licenses}/LICENSE.md +1 -1
- pyinfra_cli/__init__.py +1 -0
- pyinfra_cli/cli.py +780 -0
- pyinfra_cli/commands.py +66 -0
- pyinfra_cli/exceptions.py +155 -65
- pyinfra_cli/inventory.py +233 -89
- pyinfra_cli/log.py +39 -43
- pyinfra_cli/main.py +26 -495
- pyinfra_cli/prints.py +215 -156
- pyinfra_cli/util.py +172 -105
- pyinfra_cli/virtualenv.py +25 -20
- pyinfra/api/connectors/__init__.py +0 -21
- pyinfra/api/connectors/ansible.py +0 -99
- pyinfra/api/connectors/docker.py +0 -178
- pyinfra/api/connectors/local.py +0 -169
- pyinfra/api/connectors/ssh.py +0 -402
- pyinfra/api/connectors/sshuserclient/client.py +0 -105
- pyinfra/api/connectors/sshuserclient/config.py +0 -90
- pyinfra/api/connectors/util.py +0 -63
- pyinfra/api/connectors/vagrant.py +0 -155
- pyinfra/facts/init.py +0 -176
- pyinfra/facts/util/files.py +0 -102
- pyinfra/hook.py +0 -41
- pyinfra/modules/__init__.py +0 -11
- pyinfra/modules/apk.py +0 -64
- pyinfra/modules/apt.py +0 -272
- pyinfra/modules/brew.py +0 -122
- pyinfra/modules/files.py +0 -711
- pyinfra/modules/gem.py +0 -30
- pyinfra/modules/git.py +0 -115
- pyinfra/modules/init.py +0 -344
- pyinfra/modules/iptables.py +0 -271
- pyinfra/modules/lxd.py +0 -45
- pyinfra/modules/mysql.py +0 -347
- pyinfra/modules/npm.py +0 -47
- pyinfra/modules/pacman.py +0 -60
- pyinfra/modules/pip.py +0 -99
- pyinfra/modules/pkg.py +0 -43
- pyinfra/modules/postgresql.py +0 -245
- pyinfra/modules/puppet.py +0 -20
- pyinfra/modules/python.py +0 -37
- pyinfra/modules/server.py +0 -524
- pyinfra/modules/ssh.py +0 -150
- pyinfra/modules/util/files.py +0 -52
- pyinfra/modules/util/packaging.py +0 -118
- pyinfra/modules/vzctl.py +0 -133
- pyinfra/modules/yum.py +0 -171
- pyinfra/pseudo_modules.py +0 -64
- pyinfra-0.11.dev3.dist-info/.DS_Store +0 -0
- pyinfra-0.11.dev3.dist-info/METADATA +0 -135
- pyinfra-0.11.dev3.dist-info/RECORD +0 -95
- pyinfra-0.11.dev3.dist-info/entry_points.txt +0 -3
- pyinfra-0.11.dev3.dist-info/top_level.txt +0 -2
- pyinfra_cli/__main__.py +0 -40
- pyinfra_cli/config.py +0 -92
- /pyinfra/{modules/util → connectors}/__init__.py +0 -0
- /pyinfra/{api/connectors → connectors}/sshuserclient/__init__.py +0 -0
pyinfra_cli/commands.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from pyinfra.api.facts import FactBase
|
|
6
|
+
|
|
7
|
+
from .exceptions import CliError
|
|
8
|
+
from .util import parse_cli_arg, try_import_module_attribute
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_func_and_args(commands):
|
|
12
|
+
operation_name = commands[0]
|
|
13
|
+
|
|
14
|
+
op = try_import_module_attribute(operation_name, prefix="pyinfra.operations")
|
|
15
|
+
|
|
16
|
+
# Parse the arguments
|
|
17
|
+
operation_args = commands[1:]
|
|
18
|
+
|
|
19
|
+
if len(operation_args) == 1:
|
|
20
|
+
# Check if we're JSON (in which case we expect a list of two items:
|
|
21
|
+
# a list of args and a dict of kwargs).
|
|
22
|
+
try:
|
|
23
|
+
args, kwargs = json.loads(operation_args[0])
|
|
24
|
+
return op, (args or (), kwargs or {})
|
|
25
|
+
except ValueError:
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
args = [parse_cli_arg(arg) for arg in operation_args if "=" not in arg]
|
|
29
|
+
|
|
30
|
+
kwargs = {
|
|
31
|
+
key: parse_cli_arg(value)
|
|
32
|
+
for key, value in [arg.split("=", 1) for arg in operation_args if "=" in arg]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return op, (args, kwargs)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_facts_and_args(commands):
|
|
39
|
+
facts: list[tuple[FactBase, tuple, dict]] = []
|
|
40
|
+
|
|
41
|
+
current_fact = None
|
|
42
|
+
|
|
43
|
+
for command in commands:
|
|
44
|
+
if "=" in command:
|
|
45
|
+
if not current_fact:
|
|
46
|
+
raise CliError("Invalid fact commands: `{0}`".format(commands))
|
|
47
|
+
|
|
48
|
+
key, value = command.split("=", 1)
|
|
49
|
+
current_fact[2][key] = parse_cli_arg(value)
|
|
50
|
+
continue
|
|
51
|
+
|
|
52
|
+
if current_fact:
|
|
53
|
+
facts.append(current_fact)
|
|
54
|
+
current_fact = None
|
|
55
|
+
|
|
56
|
+
if "." not in command:
|
|
57
|
+
raise CliError(f"Invalid fact: `{command}`, should be in the format `module.cls`")
|
|
58
|
+
|
|
59
|
+
fact_cls = try_import_module_attribute(command, prefix="pyinfra.facts")
|
|
60
|
+
assert fact_cls is not None
|
|
61
|
+
current_fact = (fact_cls, (), {})
|
|
62
|
+
|
|
63
|
+
if current_fact:
|
|
64
|
+
facts.append(current_fact)
|
|
65
|
+
|
|
66
|
+
return facts
|
pyinfra_cli/exceptions.py
CHANGED
|
@@ -1,78 +1,168 @@
|
|
|
1
|
+
import abc
|
|
1
2
|
import sys
|
|
2
|
-
|
|
3
|
-
from traceback import format_exception, format_tb
|
|
3
|
+
from inspect import getframeinfo
|
|
4
|
+
from traceback import format_exception, format_tb, walk_tb
|
|
5
|
+
from types import TracebackType
|
|
4
6
|
|
|
5
7
|
import click
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
from pyinfra
|
|
9
|
-
from pyinfra.
|
|
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
|
-
|
|
8
|
+
from typing_extensions import override
|
|
9
|
+
|
|
10
|
+
from pyinfra import logger
|
|
11
|
+
from pyinfra.api.exceptions import (
|
|
12
|
+
ArgumentTypeError,
|
|
13
|
+
ConnectorDataTypeError,
|
|
14
|
+
OperationError,
|
|
15
|
+
PyinfraError,
|
|
16
|
+
)
|
|
17
|
+
from pyinfra.api.util import PYINFRA_INSTALL_DIR
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_frame_line_from_tb(tb: TracebackType):
|
|
21
|
+
frame_lines = list(walk_tb(tb))
|
|
22
|
+
frame_lines.reverse()
|
|
23
|
+
for frame, line in frame_lines:
|
|
24
|
+
info = getframeinfo(frame)
|
|
25
|
+
if info.filename.startswith(PYINFRA_INSTALL_DIR):
|
|
26
|
+
continue
|
|
27
|
+
return info
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class WrappedError(click.ClickException):
|
|
31
|
+
def __init__(self, e: Exception):
|
|
32
|
+
self.traceback = e.__traceback__
|
|
33
|
+
self.exception = e
|
|
34
|
+
|
|
35
|
+
# Pull message from the wrapped exception
|
|
36
|
+
message = getattr(e, "message", e.args[0])
|
|
37
|
+
if not isinstance(message, str):
|
|
38
|
+
message = repr(message)
|
|
39
|
+
self.message = message
|
|
40
|
+
|
|
41
|
+
@override
|
|
42
|
+
def show(self, file=None):
|
|
43
|
+
name = "unknown error"
|
|
44
|
+
|
|
45
|
+
if isinstance(self.exception, ConnectorDataTypeError):
|
|
46
|
+
name = "Connector data type error"
|
|
47
|
+
elif isinstance(self.exception, ArgumentTypeError):
|
|
48
|
+
name = "Argument type error"
|
|
49
|
+
elif isinstance(self.exception, OperationError):
|
|
50
|
+
name = "Operation error"
|
|
51
|
+
elif isinstance(self.exception, PyinfraError):
|
|
52
|
+
name = "pyinfra error"
|
|
53
|
+
elif isinstance(self.exception, IOError):
|
|
54
|
+
name = "Local IO error"
|
|
55
|
+
|
|
56
|
+
if self.traceback:
|
|
57
|
+
info = get_frame_line_from_tb(self.traceback)
|
|
58
|
+
if info:
|
|
59
|
+
name = f"{name} in {info.filename} line {info.lineno}"
|
|
60
|
+
|
|
61
|
+
logger.warning(
|
|
62
|
+
"--> {0}: {1}".format(
|
|
63
|
+
click.style(name, "red", bold=True),
|
|
64
|
+
self,
|
|
65
|
+
),
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class CliError(click.ClickException):
|
|
70
|
+
@override
|
|
71
|
+
def show(self, file=None):
|
|
72
|
+
logger.warning(
|
|
73
|
+
"--> {0}: {1}".format(
|
|
74
|
+
click.style("pyinfra error", "red", bold=True),
|
|
75
|
+
self,
|
|
76
|
+
),
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class UnexpectedMixin(abc.ABC):
|
|
81
|
+
exception: Exception
|
|
82
|
+
traceback: TracebackType
|
|
83
|
+
|
|
84
|
+
def get_traceback_lines(self):
|
|
85
|
+
traceback = getattr(self.exception, "_traceback")
|
|
86
|
+
return format_tb(traceback)
|
|
87
|
+
|
|
88
|
+
def get_traceback(self):
|
|
89
|
+
return "".join(self.get_traceback_lines())
|
|
90
|
+
|
|
91
|
+
def get_exception(self):
|
|
92
|
+
return "".join(format_exception(self.exception.__class__, self.exception, None))
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class UnexpectedExternalError(click.ClickException, UnexpectedMixin):
|
|
96
|
+
def __init__(self, e, filename):
|
|
97
|
+
_, _, traceback = sys.exc_info()
|
|
98
|
+
e._traceback = traceback
|
|
99
|
+
self.exception = e
|
|
100
|
+
self.filename = filename
|
|
101
|
+
|
|
102
|
+
@override
|
|
103
|
+
def show(self, file=None):
|
|
104
|
+
logger.warning(
|
|
105
|
+
"--> {0}:\n".format(
|
|
106
|
+
click.style(
|
|
107
|
+
"An exception occurred in: {0}".format(self.filename),
|
|
108
|
+
"red",
|
|
109
|
+
bold=True,
|
|
110
|
+
),
|
|
111
|
+
),
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
click.echo("Traceback (most recent call last):", err=True)
|
|
115
|
+
click.echo(self.get_traceback(), err=True, nl=False)
|
|
116
|
+
click.echo(self.get_exception(), err=True)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class UnexpectedInternalError(click.ClickException, UnexpectedMixin):
|
|
47
120
|
def __init__(self, e):
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
121
|
+
_, _, traceback = sys.exc_info()
|
|
122
|
+
e._traceback = traceback
|
|
123
|
+
self.exception = e
|
|
124
|
+
|
|
125
|
+
@override
|
|
126
|
+
def show(self, file=None):
|
|
127
|
+
click.echo(
|
|
128
|
+
"--> {0}:\n".format(
|
|
129
|
+
click.style(
|
|
130
|
+
"An internal exception occurred",
|
|
131
|
+
"red",
|
|
132
|
+
bold=True,
|
|
133
|
+
),
|
|
134
|
+
),
|
|
135
|
+
err=True,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
traceback_lines = self.get_traceback_lines()
|
|
139
|
+
traceback = self.get_traceback()
|
|
61
140
|
|
|
62
141
|
# Syntax errors contain the filename/line/etc, but other exceptions
|
|
63
142
|
# don't, so print the *last* call to stderr.
|
|
64
|
-
if not isinstance(self.
|
|
143
|
+
if not isinstance(self.exception, SyntaxError):
|
|
65
144
|
sys.stderr.write(traceback_lines[-1])
|
|
66
145
|
|
|
67
|
-
exception =
|
|
68
|
-
|
|
146
|
+
exception = self.get_exception()
|
|
147
|
+
click.echo(exception, err=True)
|
|
69
148
|
|
|
70
|
-
|
|
71
|
-
with open('pyinfra-debug.log', 'w') as f:
|
|
149
|
+
with open("pyinfra-debug.log", "w", encoding="utf-8") as f:
|
|
72
150
|
f.write(traceback)
|
|
73
151
|
f.write(exception)
|
|
74
152
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
153
|
+
logger.debug(traceback)
|
|
154
|
+
logger.debug(exception)
|
|
155
|
+
|
|
156
|
+
click.echo(
|
|
157
|
+
"--> The full traceback has been written to {0}".format(
|
|
158
|
+
click.style("pyinfra-debug.log", bold=True),
|
|
159
|
+
),
|
|
160
|
+
err=True,
|
|
161
|
+
)
|
|
162
|
+
click.echo(
|
|
163
|
+
(
|
|
164
|
+
"--> If this is unexpected please consider submitting a bug report "
|
|
165
|
+
"on GitHub, for more information run `pyinfra --support`."
|
|
166
|
+
),
|
|
167
|
+
err=True,
|
|
168
|
+
)
|