pyinfra 2.9.2__py2.py3-none-any.whl → 3.0__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/__init__.py +3 -0
- pyinfra/api/arguments.py +265 -253
- pyinfra/api/arguments_typed.py +80 -0
- pyinfra/api/command.py +68 -53
- pyinfra/api/config.py +139 -32
- pyinfra/api/connect.py +1 -1
- pyinfra/api/connectors.py +7 -26
- pyinfra/api/deploy.py +21 -52
- pyinfra/api/exceptions.py +33 -8
- pyinfra/api/facts.py +102 -137
- pyinfra/api/host.py +150 -82
- pyinfra/api/inventory.py +21 -25
- pyinfra/api/operation.py +240 -198
- pyinfra/api/operations.py +102 -148
- pyinfra/api/state.py +137 -79
- pyinfra/api/util.py +79 -86
- pyinfra/connectors/base.py +147 -0
- pyinfra/connectors/chroot.py +160 -169
- pyinfra/connectors/docker.py +220 -237
- pyinfra/connectors/dockerssh.py +231 -253
- pyinfra/connectors/local.py +196 -208
- pyinfra/connectors/ssh.py +530 -613
- pyinfra/connectors/ssh_util.py +114 -0
- pyinfra/connectors/sshuserclient/client.py +5 -3
- pyinfra/connectors/terraform.py +86 -65
- pyinfra/connectors/util.py +211 -137
- pyinfra/connectors/vagrant.py +60 -53
- pyinfra/context.py +4 -2
- pyinfra/facts/apk.py +2 -0
- pyinfra/facts/apt.py +2 -0
- pyinfra/facts/brew.py +2 -0
- pyinfra/facts/bsdinit.py +2 -0
- pyinfra/facts/cargo.py +2 -0
- pyinfra/facts/choco.py +2 -0
- pyinfra/facts/deb.py +7 -2
- pyinfra/facts/dnf.py +2 -0
- pyinfra/facts/docker.py +19 -0
- pyinfra/facts/files.py +47 -32
- pyinfra/facts/gem.py +2 -0
- pyinfra/facts/git.py +3 -1
- pyinfra/facts/gpg.py +3 -1
- pyinfra/facts/hardware.py +34 -24
- pyinfra/facts/iptables.py +5 -3
- pyinfra/facts/launchd.py +2 -0
- pyinfra/facts/lxd.py +2 -0
- pyinfra/facts/mysql.py +13 -6
- pyinfra/facts/npm.py +1 -0
- pyinfra/facts/openrc.py +2 -0
- pyinfra/facts/pacman.py +6 -2
- pyinfra/facts/pip.py +2 -0
- pyinfra/facts/pkg.py +2 -0
- pyinfra/facts/pkgin.py +2 -0
- pyinfra/facts/postgres.py +168 -0
- pyinfra/facts/postgresql.py +6 -160
- pyinfra/facts/rpm.py +12 -9
- pyinfra/facts/runit.py +68 -0
- pyinfra/facts/selinux.py +3 -1
- pyinfra/facts/server.py +80 -36
- pyinfra/facts/snap.py +2 -0
- pyinfra/facts/systemd.py +31 -12
- pyinfra/facts/sysvinit.py +10 -10
- pyinfra/facts/upstart.py +2 -0
- pyinfra/facts/util/packaging.py +7 -4
- pyinfra/facts/vzctl.py +2 -0
- pyinfra/facts/xbps.py +2 -0
- pyinfra/facts/yum.py +2 -0
- pyinfra/facts/zypper.py +2 -0
- pyinfra/local.py +4 -5
- pyinfra/operations/apk.py +6 -4
- pyinfra/operations/apt.py +46 -65
- pyinfra/operations/brew.py +17 -22
- pyinfra/operations/bsdinit.py +9 -7
- pyinfra/operations/cargo.py +4 -2
- pyinfra/operations/choco.py +4 -2
- pyinfra/operations/dnf.py +19 -23
- pyinfra/operations/docker.py +339 -0
- pyinfra/operations/files.py +188 -386
- pyinfra/operations/gem.py +4 -2
- pyinfra/operations/git.py +24 -53
- pyinfra/operations/iptables.py +29 -35
- pyinfra/operations/launchd.py +6 -7
- pyinfra/operations/lxd.py +8 -13
- pyinfra/operations/mysql.py +62 -81
- pyinfra/operations/npm.py +9 -2
- pyinfra/operations/openrc.py +6 -4
- pyinfra/operations/pacman.py +7 -8
- pyinfra/operations/pip.py +25 -24
- pyinfra/operations/pkg.py +4 -2
- pyinfra/operations/pkgin.py +6 -4
- pyinfra/operations/postgres.py +349 -0
- pyinfra/operations/postgresql.py +18 -379
- pyinfra/operations/puppet.py +3 -1
- pyinfra/operations/python.py +8 -19
- pyinfra/operations/runit.py +182 -0
- pyinfra/operations/selinux.py +47 -44
- pyinfra/operations/server.py +111 -127
- pyinfra/operations/snap.py +4 -4
- pyinfra/operations/ssh.py +20 -33
- pyinfra/operations/systemd.py +19 -15
- pyinfra/operations/sysvinit.py +9 -16
- pyinfra/operations/upstart.py +9 -7
- pyinfra/operations/util/__init__.py +12 -0
- pyinfra/operations/util/docker.py +177 -0
- pyinfra/operations/util/files.py +24 -16
- pyinfra/operations/util/packaging.py +55 -57
- pyinfra/operations/util/service.py +39 -51
- pyinfra/operations/vzctl.py +12 -10
- pyinfra/operations/xbps.py +6 -4
- pyinfra/operations/yum.py +18 -22
- pyinfra/operations/zypper.py +12 -13
- pyinfra/version.py +5 -2
- {pyinfra-2.9.2.dist-info → pyinfra-3.0.dist-info}/METADATA +40 -41
- pyinfra-3.0.dist-info/RECORD +167 -0
- {pyinfra-2.9.2.dist-info → pyinfra-3.0.dist-info}/WHEEL +1 -1
- pyinfra-3.0.dist-info/entry_points.txt +11 -0
- pyinfra_cli/__main__.py +4 -3
- pyinfra_cli/commands.py +7 -2
- pyinfra_cli/exceptions.py +78 -42
- pyinfra_cli/inventory.py +40 -6
- pyinfra_cli/log.py +17 -3
- pyinfra_cli/main.py +133 -90
- pyinfra_cli/prints.py +95 -127
- pyinfra_cli/util.py +62 -29
- tests/test_api/test_api.py +2 -0
- tests/test_api/test_api_arguments.py +13 -13
- tests/test_api/test_api_deploys.py +28 -29
- tests/test_api/test_api_facts.py +60 -98
- tests/test_api/test_api_operations.py +101 -201
- tests/test_cli/test_cli.py +18 -49
- tests/test_cli/test_cli_deploy.py +11 -37
- tests/test_cli/test_cli_exceptions.py +50 -19
- tests/test_cli/util.py +1 -1
- tests/test_connectors/test_chroot.py +6 -6
- tests/test_connectors/test_docker.py +4 -4
- tests/test_connectors/test_dockerssh.py +38 -50
- tests/test_connectors/test_local.py +11 -12
- tests/test_connectors/test_ssh.py +105 -93
- tests/test_connectors/test_terraform.py +9 -15
- tests/test_connectors/test_util.py +24 -46
- tests/test_connectors/test_vagrant.py +7 -7
- pyinfra/api/operation.pyi +0 -117
- pyinfra/connectors/ansible.py +0 -171
- pyinfra/connectors/mech.py +0 -186
- pyinfra/connectors/pyinfrawinrmsession/__init__.py +0 -28
- pyinfra/connectors/winrm.py +0 -320
- pyinfra/facts/windows.py +0 -366
- pyinfra/facts/windows_files.py +0 -90
- pyinfra/operations/windows.py +0 -59
- pyinfra/operations/windows_files.py +0 -551
- pyinfra-2.9.2.dist-info/RECORD +0 -170
- pyinfra-2.9.2.dist-info/entry_points.txt +0 -14
- tests/test_connectors/test_ansible.py +0 -64
- tests/test_connectors/test_mech.py +0 -126
- tests/test_connectors/test_winrm.py +0 -76
- {pyinfra-2.9.2.dist-info → pyinfra-3.0.dist-info}/LICENSE.md +0 -0
- {pyinfra-2.9.2.dist-info → pyinfra-3.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyinfra
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0
|
|
4
4
|
Summary: pyinfra automates/provisions/manages/deploys infrastructure.
|
|
5
5
|
Home-page: https://pyinfra.com
|
|
6
6
|
Author: Nick / Fizzadar
|
|
@@ -16,14 +16,15 @@ Classifier: Intended Audience :: Information Technology
|
|
|
16
16
|
Classifier: License :: OSI Approved :: MIT License
|
|
17
17
|
Classifier: Operating System :: OS Independent
|
|
18
18
|
Classifier: Programming Language :: Python :: 3
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
21
19
|
Classifier: Programming Language :: Python :: 3.8
|
|
22
20
|
Classifier: Programming Language :: Python :: 3.9
|
|
23
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
24
|
Classifier: Topic :: System :: Systems Administration
|
|
25
25
|
Classifier: Topic :: System :: Installation/Setup
|
|
26
26
|
Classifier: Topic :: Utilities
|
|
27
|
+
Requires-Python: >=3.8
|
|
27
28
|
Description-Content-Type: text/markdown
|
|
28
29
|
License-File: LICENSE.md
|
|
29
30
|
Requires-Dist: gevent >=1.5
|
|
@@ -34,25 +35,28 @@ Requires-Dist: python-dateutil <3,>2
|
|
|
34
35
|
Requires-Dist: setuptools
|
|
35
36
|
Requires-Dist: configparser
|
|
36
37
|
Requires-Dist: pywinrm
|
|
38
|
+
Requires-Dist: typeguard
|
|
37
39
|
Requires-Dist: distro <2,>=1.6
|
|
40
|
+
Requires-Dist: packaging >=16.1
|
|
41
|
+
Requires-Dist: importlib-metadata >=3.6 ; python_version < "3.10"
|
|
42
|
+
Requires-Dist: typing-extensions ; python_version < "3.11"
|
|
38
43
|
Requires-Dist: graphlib-backport ; python_version < "3.9"
|
|
39
|
-
Provides-Extra: ansible
|
|
40
|
-
Requires-Dist: pyyaml ; extra == 'ansible'
|
|
41
44
|
Provides-Extra: dev
|
|
42
|
-
Requires-Dist:
|
|
43
|
-
Requires-Dist:
|
|
44
|
-
Requires-Dist:
|
|
45
|
-
Requires-Dist:
|
|
46
|
-
Requires-Dist:
|
|
47
|
-
Requires-Dist: flake8
|
|
48
|
-
Requires-Dist: flake8-
|
|
49
|
-
Requires-Dist:
|
|
45
|
+
Requires-Dist: pytest ==8.2.1 ; extra == 'dev'
|
|
46
|
+
Requires-Dist: coverage ==7.5.1 ; extra == 'dev'
|
|
47
|
+
Requires-Dist: pytest-cov ==5.0.0 ; extra == 'dev'
|
|
48
|
+
Requires-Dist: black ==24.4.2 ; extra == 'dev'
|
|
49
|
+
Requires-Dist: isort ==5.13.2 ; extra == 'dev'
|
|
50
|
+
Requires-Dist: flake8 ==7.0.0 ; extra == 'dev'
|
|
51
|
+
Requires-Dist: flake8-black ==0.3.6 ; extra == 'dev'
|
|
52
|
+
Requires-Dist: flake8-isort ==6.1.1 ; extra == 'dev'
|
|
53
|
+
Requires-Dist: mypy ; extra == 'dev'
|
|
50
54
|
Requires-Dist: types-cryptography ; extra == 'dev'
|
|
51
55
|
Requires-Dist: types-paramiko ; extra == 'dev'
|
|
52
56
|
Requires-Dist: types-python-dateutil ; extra == 'dev'
|
|
53
57
|
Requires-Dist: types-PyYAML ; extra == 'dev'
|
|
54
58
|
Requires-Dist: types-setuptools ; extra == 'dev'
|
|
55
|
-
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.
|
|
59
|
+
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.16 ; extra == 'dev'
|
|
56
60
|
Requires-Dist: myst-parser ==2.0.0 ; extra == 'dev'
|
|
57
61
|
Requires-Dist: sphinx ==6.2.1 ; extra == 'dev'
|
|
58
62
|
Requires-Dist: wheel ; extra == 'dev'
|
|
@@ -62,32 +66,25 @@ Requires-Dist: ipdb ; extra == 'dev'
|
|
|
62
66
|
Requires-Dist: ipdbplugin ; extra == 'dev'
|
|
63
67
|
Requires-Dist: flake8-spellcheck ==0.12.1 ; extra == 'dev'
|
|
64
68
|
Requires-Dist: redbaron ; extra == 'dev'
|
|
65
|
-
Requires-Dist: pytest ==7.0.1 ; (python_version <= "3.6") and extra == 'dev'
|
|
66
|
-
Requires-Dist: coverage ==6.2 ; (python_version <= "3.6") and extra == 'dev'
|
|
67
|
-
Requires-Dist: pytest ==7.2.0 ; (python_version > "3.6") and extra == 'dev'
|
|
68
|
-
Requires-Dist: coverage ==6.5 ; (python_version > "3.6") and extra == 'dev'
|
|
69
69
|
Provides-Extra: docs
|
|
70
|
-
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.
|
|
70
|
+
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.16 ; extra == 'docs'
|
|
71
71
|
Requires-Dist: myst-parser ==2.0.0 ; extra == 'docs'
|
|
72
72
|
Requires-Dist: sphinx ==6.2.1 ; extra == 'docs'
|
|
73
73
|
Provides-Extra: test
|
|
74
|
-
Requires-Dist:
|
|
75
|
-
Requires-Dist:
|
|
76
|
-
Requires-Dist:
|
|
77
|
-
Requires-Dist:
|
|
78
|
-
Requires-Dist:
|
|
79
|
-
Requires-Dist: flake8
|
|
80
|
-
Requires-Dist: flake8-
|
|
81
|
-
Requires-Dist:
|
|
74
|
+
Requires-Dist: pytest ==8.2.1 ; extra == 'test'
|
|
75
|
+
Requires-Dist: coverage ==7.5.1 ; extra == 'test'
|
|
76
|
+
Requires-Dist: pytest-cov ==5.0.0 ; extra == 'test'
|
|
77
|
+
Requires-Dist: black ==24.4.2 ; extra == 'test'
|
|
78
|
+
Requires-Dist: isort ==5.13.2 ; extra == 'test'
|
|
79
|
+
Requires-Dist: flake8 ==7.0.0 ; extra == 'test'
|
|
80
|
+
Requires-Dist: flake8-black ==0.3.6 ; extra == 'test'
|
|
81
|
+
Requires-Dist: flake8-isort ==6.1.1 ; extra == 'test'
|
|
82
|
+
Requires-Dist: mypy ; extra == 'test'
|
|
82
83
|
Requires-Dist: types-cryptography ; extra == 'test'
|
|
83
84
|
Requires-Dist: types-paramiko ; extra == 'test'
|
|
84
85
|
Requires-Dist: types-python-dateutil ; extra == 'test'
|
|
85
86
|
Requires-Dist: types-PyYAML ; extra == 'test'
|
|
86
87
|
Requires-Dist: types-setuptools ; extra == 'test'
|
|
87
|
-
Requires-Dist: pytest ==7.0.1 ; (python_version <= "3.6") and extra == 'test'
|
|
88
|
-
Requires-Dist: coverage ==6.2 ; (python_version <= "3.6") and extra == 'test'
|
|
89
|
-
Requires-Dist: pytest ==7.2.0 ; (python_version > "3.6") and extra == 'test'
|
|
90
|
-
Requires-Dist: coverage ==6.5 ; (python_version > "3.6") and extra == 'test'
|
|
91
88
|
|
|
92
89
|
<p align="center">
|
|
93
90
|
<a href="https://pyinfra.com">
|
|
@@ -95,25 +92,27 @@ Requires-Dist: coverage ==6.5 ; (python_version > "3.6") and extra == 'test'
|
|
|
95
92
|
</a>
|
|
96
93
|
</p>
|
|
97
94
|
|
|
98
|
-
<p
|
|
99
|
-
<
|
|
95
|
+
<p>
|
|
96
|
+
<strong>Note: this is the v3 branch, which is currently in beta. <a href="https://docs.pyinfra.com/en/next">See the docs for v3</a>. If needed the <a href="https://github.com/pyinfra-dev/pyinfra/tree/2.x/">2.x branch is here</a>, but is in bugfix only mode.</strong>
|
|
97
|
+
</p>
|
|
98
|
+
|
|
99
|
+
<p>
|
|
100
|
+
pyinfra turns Python code into shell commands and runs them on your servers. Execute ad-hoc commands and write declarative operations. Target SSH servers, local machine and Docker containers. Fast and scales from one server to thousands. Think <code>ansible</code> but Python instead of YAML, and a lot faster.
|
|
100
101
|
</p>
|
|
101
102
|
|
|
102
103
|
---
|
|
103
104
|
|
|
104
|
-
<
|
|
105
|
-
<a href="https://docs.pyinfra.com"><strong>Documentation</strong></a> ⇒
|
|
105
|
+
<h3>
|
|
106
106
|
<a href="https://docs.pyinfra.com/page/getting-started.html"><strong>Getting Started</strong></a> •
|
|
107
|
-
<a href="https://
|
|
107
|
+
<a href="https://github.com/pyinfra-dev/pyinfra-examples"><strong>Examples Repo</strong></a> •
|
|
108
|
+
<a href="https://matrix.to/#/#pyinfra:matrix.org"><strong>Chat on Matrix</strong></a>
|
|
109
|
+
</h3>
|
|
110
|
+
<p>
|
|
111
|
+
<a href="https://docs.pyinfra.com"><strong>Documentation</strong></a> •
|
|
108
112
|
<a href="https://docs.pyinfra.com/page/support.html"><strong>Help & Support</strong></a> •
|
|
109
113
|
<a href="https://docs.pyinfra.com/page/contributing.html"><strong>Contributing</strong></a>
|
|
110
114
|
</p>
|
|
111
115
|
|
|
112
|
-
<p align="center">
|
|
113
|
-
Chat ⇒
|
|
114
|
-
<a href="https://matrix.to/#/#pyinfra:matrix.org"><strong><code>#pyinfra</code> on Matrix</strong></a>
|
|
115
|
-
</p>
|
|
116
|
-
|
|
117
116
|
---
|
|
118
117
|
|
|
119
118
|
Why pyinfra? Design features include:
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
pyinfra/__init__.py,sha256=7ZcKHGWk7_nYxsYrbFBB_vJr-J-Ddbc56ZS4sk5ArVw,535
|
|
2
|
+
pyinfra/__main__.py,sha256=aVd00glLz5CMJGXgt1XxbOvC2HluqaowoTOjxgIpBaA,47
|
|
3
|
+
pyinfra/context.py,sha256=S6DvGjjTEjM4u2m9oIAmAaV7kXIJzVwYf725P1muIuY,3395
|
|
4
|
+
pyinfra/local.py,sha256=0bpIRCyDKM6i_jA1i8Ej2qr_iWIF9cUYWutXNdLj8po,2751
|
|
5
|
+
pyinfra/progress.py,sha256=X3hXZ4Flh_L9FE4ZEWxWoG0R4dA5UPd1FCO-Exd5Xtc,4193
|
|
6
|
+
pyinfra/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
pyinfra/version.py,sha256=LZf50PHDzEZv65w0G-iMICoQ9US0U5LWHAOEmNtkF3I,216
|
|
8
|
+
pyinfra/api/__init__.py,sha256=suGbKKM-qCduuXFYBEcyswlTqozewtYpdLRhK63PVn0,942
|
|
9
|
+
pyinfra/api/arguments.py,sha256=8BhuJiljFJzaCi9lM8HoEBB9mcnCBilv4Zwdx_349g8,9941
|
|
10
|
+
pyinfra/api/arguments_typed.py,sha256=WQKr0wDtlgJGq-Vkv_oPAz7f-LxjqQv3wJCdvVrePWk,2331
|
|
11
|
+
pyinfra/api/command.py,sha256=SyUlxvhYlXpgFpg0jua8bzQ2KPtVYQXHcvD6AUL2SCI,7226
|
|
12
|
+
pyinfra/api/config.py,sha256=wS6Pi4T4DxNkzO4llNY-ghLxyI5VBJ26uGvgMPZxIKY,9043
|
|
13
|
+
pyinfra/api/connect.py,sha256=Z9wusMLR_jBkKKk5D4AUOj8LHl3H5MsNO5FxAeR4jac,1416
|
|
14
|
+
pyinfra/api/connectors.py,sha256=nie7JuLxMSC6gqPjmjuCisQ11R-eAQDtMMWF6YbSQ48,659
|
|
15
|
+
pyinfra/api/deploy.py,sha256=xo4F7URUf3xzIChRHZn4zwqs_WTjLjZNC9i9eQjAFk8,2756
|
|
16
|
+
pyinfra/api/exceptions.py,sha256=cCbUp1qN1QO0d9aAvOAbRgYpLi0vUI5j7ZqSjcD1_P8,1861
|
|
17
|
+
pyinfra/api/facts.py,sha256=L_Wsrdq-u0zR69klnXWZ_2j9H7m3Oto53X0bQf670X8,10574
|
|
18
|
+
pyinfra/api/host.py,sha256=3lRhlZDRKvCNvpziaTglExy2Ep1wd4YdmGDNY4emAdA,13466
|
|
19
|
+
pyinfra/api/inventory.py,sha256=nPITdNEJ7q71adIqS_OKHsMjD7amUuHEuTl6xzgh1Gk,7734
|
|
20
|
+
pyinfra/api/operation.py,sha256=pB0LpjUqbMLGtoDnsckNw0FRoeo1BopL0fnXVDM1JyU,15112
|
|
21
|
+
pyinfra/api/operations.py,sha256=jvz9ISfwmQnAQVUKLnbrRdD9QHIAAfypo9l5b3fYG1w,10894
|
|
22
|
+
pyinfra/api/state.py,sha256=3dXRjeZJXnzLcbP9E4aogkRPwIg3_kK1h4Tf4FVZock,12622
|
|
23
|
+
pyinfra/api/util.py,sha256=vesFOxExETb-B-oAhWpJJrmALTubg3fkFqi0gYd0pJs,12265
|
|
24
|
+
pyinfra/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
+
pyinfra/connectors/base.py,sha256=2fASiV-MvpXgcZAFLM_PUwYx5ax6EHai44ri_oEKeSE,3732
|
|
26
|
+
pyinfra/connectors/chroot.py,sha256=Xd72I8T58KIwKOoc0LXCw91AoEIaiHfRLDcDVTHGJ0o,5931
|
|
27
|
+
pyinfra/connectors/docker.py,sha256=2UNHhXS4hpLo7I19ixDeSd7JR8SNo43VgqsaUIZQZJ4,8741
|
|
28
|
+
pyinfra/connectors/dockerssh.py,sha256=VWHY--jqs3yf-RuPUZXav4vLeON9SzoVC9CUyOJo1rg,8919
|
|
29
|
+
pyinfra/connectors/local.py,sha256=vYOBQS_5rf-dVaPeG4dJlLwBHqkxAzLjj3aDEgbAsx8,6900
|
|
30
|
+
pyinfra/connectors/ssh.py,sha256=QvXrmg3G47VwGEiPP-8Nse-9Yostc5N4PxwiiSlhlwo,21124
|
|
31
|
+
pyinfra/connectors/ssh_util.py,sha256=CN_5AdTA3RpiWCnXTrRBjez1NsN59hITDzQmXIkZvoE,3683
|
|
32
|
+
pyinfra/connectors/terraform.py,sha256=G7lK168Fz0jNFetc_7_bPT-RnoaRDksJat0R26fqkUk,3617
|
|
33
|
+
pyinfra/connectors/util.py,sha256=0bvoMsGMD-Tbfaer8NUhWJjBnaNKdmE83PDg48BYjcU,11374
|
|
34
|
+
pyinfra/connectors/vagrant.py,sha256=oEeRglzRmemRXW3vilsp_Xg9qnZMRprRJO9fd_C-f5M,4759
|
|
35
|
+
pyinfra/connectors/sshuserclient/__init__.py,sha256=Qc4RO2wknSWIiNTwOeQ0y2TeiuKHmyWDW2Dz4MOo9CE,44
|
|
36
|
+
pyinfra/connectors/sshuserclient/client.py,sha256=7YSd3QckZuPDRnKzy2FfG3J8zp7CY-jny8tbWwxvKro,9720
|
|
37
|
+
pyinfra/connectors/sshuserclient/config.py,sha256=UMwkvTgAIS7__re6Wz_pwH6EU4kO1-uMQ5zuFakH0v4,2721
|
|
38
|
+
pyinfra/facts/__init__.py,sha256=myTXSOZmAqmU88Fyifn035h9Lr6Gj2mlka_jDcXyKGw,347
|
|
39
|
+
pyinfra/facts/apk.py,sha256=zihlHc6BbBUNQRL3v6wVFUHypfIL7wC6CPLrp4yynHo,518
|
|
40
|
+
pyinfra/facts/apt.py,sha256=8BJX79dBM9t3ceOhP_B5-I008HEJAUj_ijKDVvSxbFo,2035
|
|
41
|
+
pyinfra/facts/brew.py,sha256=aG77URXfNYT50ZpeHyyByiiX08GR6Oz6L0M3UMf9ztI,2302
|
|
42
|
+
pyinfra/facts/bsdinit.py,sha256=KyX4gc8cXKNn3O_NAlKWvEDKvMCnkTWJQg61oTV9ZN0,526
|
|
43
|
+
pyinfra/facts/cargo.py,sha256=mHtT2Yxoqx_g0akDq6jkHFN5VWNHQu70vKvNLZ10-b8,567
|
|
44
|
+
pyinfra/facts/choco.py,sha256=Tf7_DuQY0eZ4SIxV0rlyulrBCg7A0qyPbtTcHgkVP_0,739
|
|
45
|
+
pyinfra/facts/deb.py,sha256=dy5PKdQqy1oLdCUd6iTxCa6yG8agsaxZrPVsjvlDi74,1756
|
|
46
|
+
pyinfra/facts/dnf.py,sha256=7YNicP8EbRvWJQKU0OcwcW3bnIxx9GJ1Fy4qdCFnI0Y,898
|
|
47
|
+
pyinfra/facts/docker.py,sha256=Vr0rIEXSpK33yc2dDGct2lKhPQamvKEztxIAfwN0sk0,2046
|
|
48
|
+
pyinfra/facts/files.py,sha256=ki9-NQnYyt1VzuqKwEOYpX1nz5gJ_ph-ruq-4DS1VLg,11511
|
|
49
|
+
pyinfra/facts/gem.py,sha256=U1oF32LeiBo3ruaFm6hfF3XwNmgyhqamFUAeGn4cD3k,509
|
|
50
|
+
pyinfra/facts/git.py,sha256=rk4NS2SQJiosI6eY2eCy_p9kOP4O8UARRjFi16ObE2w,1294
|
|
51
|
+
pyinfra/facts/gpg.py,sha256=T5yVc_X9BLrDc77Yjk69x9SnP0qRWnKYEpi4JU__pKo,3765
|
|
52
|
+
pyinfra/facts/hardware.py,sha256=je1KjLfr4t-QZxTYei-V3Xqpll4TjbNeQxlHUvADg-c,11877
|
|
53
|
+
pyinfra/facts/iptables.py,sha256=sUkywfHZUXnMZF_KshAnyJufrJvZ9fBYnERSRbwOCRE,3374
|
|
54
|
+
pyinfra/facts/launchd.py,sha256=xjkszKmi9XNkovp7J33WTV19XfQbc5xGJkIBbFRTRhE,704
|
|
55
|
+
pyinfra/facts/lxd.py,sha256=ymBb_SdHbfAlx_tQyRPVa1ij_e68ZDODg1id1E0V8Rg,373
|
|
56
|
+
pyinfra/facts/mysql.py,sha256=0tpNks5be_mBWzIxuEqOyQ9MTYD9rRjeC3Oc_MQ2nns,6038
|
|
57
|
+
pyinfra/facts/npm.py,sha256=l_61BmbAWrO9RlYKUzLUcgicJ4RCMZHD70alrngC7-M,709
|
|
58
|
+
pyinfra/facts/openrc.py,sha256=NitG8BkwUCBrn-3SqM3FDiP4r6tAQTAWuHXTm1-3WGM,1386
|
|
59
|
+
pyinfra/facts/pacman.py,sha256=lU8IQYpQI3tzxRvKZHJD8giM_n17D5abzxIPasbII-A,1070
|
|
60
|
+
pyinfra/facts/pip.py,sha256=ORyrVxu_-8eIr0uSCkI6x4MH-sorDEavml4aozcdrOA,738
|
|
61
|
+
pyinfra/facts/pkg.py,sha256=2N-NlY_f3eQaW3dxCGKaKvu_ymC5_EF0-KASeul0EJc,488
|
|
62
|
+
pyinfra/facts/pkgin.py,sha256=Q1q7m4CCs_na92dDdQIjTuQnJ3axYv5qUdxnAy7e_XY,517
|
|
63
|
+
pyinfra/facts/postgres.py,sha256=M7ppmVvUXy8HSNPqrc8zLPyt8JamAyGs2IO2ocbzSZ8,4187
|
|
64
|
+
pyinfra/facts/postgresql.py,sha256=4nusMVvGhtku86KX4O4vjSxh_MamxZy_kmTQvvy0GhE,223
|
|
65
|
+
pyinfra/facts/rpm.py,sha256=v9OCfTlTSqs4UQWDwnt2tVJkqHOmHZvj7Cd1g4mZ3WI,2091
|
|
66
|
+
pyinfra/facts/runit.py,sha256=uqwftOBmjWma09hNhIZ9ZF2QqqgdcA5NzrbBtP95lRM,1965
|
|
67
|
+
pyinfra/facts/selinux.py,sha256=N0zbJrAtBeRBtxZFUHbYTLQ2L4mRV7_Oj3Cj3OA1Npw,4272
|
|
68
|
+
pyinfra/facts/server.py,sha256=ocUPIIveHWfe4K4-7mt7Je7TswWbKmjdu1xAF2VxaD8,19798
|
|
69
|
+
pyinfra/facts/snap.py,sha256=MnZDllRZ1JKLw0SKRFQ1tI6Wi05gvipQPo7m4gpL4fI,1946
|
|
70
|
+
pyinfra/facts/systemd.py,sha256=7uYJyP9yryq9PZT0lRH597HHQFExxebz8og2OrRQUc8,3963
|
|
71
|
+
pyinfra/facts/sysvinit.py,sha256=PS7yMOrVxclywKjF3BIXmxTBgn2_vpSTQrDeOly_j8Q,1490
|
|
72
|
+
pyinfra/facts/upstart.py,sha256=4OSQ257KmYvWWboeXiqKGbhvOmLCMCwwOBgDXKCq1XE,579
|
|
73
|
+
pyinfra/facts/vzctl.py,sha256=LoWXJdFVg7bWcY-aGvSk-teFaAjUjKzQHnR-VuaomZ8,627
|
|
74
|
+
pyinfra/facts/xbps.py,sha256=k7G0L_IgOWIQUs-UswVgs3WzqdjokSCzq0TKT3Tvok0,517
|
|
75
|
+
pyinfra/facts/yum.py,sha256=5nhp7iXLFyEM7MSrBqierSQpTzqyBOwMB-e658Fe838,863
|
|
76
|
+
pyinfra/facts/zypper.py,sha256=hCgm37xwVqgrsG6h2FMNnzW17UH64y8qZbDOVrLglIY,802
|
|
77
|
+
pyinfra/facts/util/__init__.py,sha256=f7HKu8z9_yFC899ajJ3RFiyivioaZeGfOI6nf9GviCs,521
|
|
78
|
+
pyinfra/facts/util/databases.py,sha256=EphGQApzRBXI2nG1FL9h8bozY-o4SgdQgpv9YcnCkxs,730
|
|
79
|
+
pyinfra/facts/util/packaging.py,sha256=4RzjDYb3HrRWZuuPlEfYHgbftLH4r1FOccN5QyIGkrk,1181
|
|
80
|
+
pyinfra/facts/util/win_files.py,sha256=S_IQ5kJD6ZgkEcVHajgh7BIMolLV-1q1ghIcwAS-E1Q,2561
|
|
81
|
+
pyinfra/operations/__init__.py,sha256=SOcW337KXIzD_LH-iJJfq14BQcCs5JzwswJ0PIzDgF4,357
|
|
82
|
+
pyinfra/operations/apk.py,sha256=_0vOjbSiGx6EWv9rvTmQdGnRZQ_NA_Dyd3QW1cTzFgI,2111
|
|
83
|
+
pyinfra/operations/apt.py,sha256=YAVZXzCE5zvPQb6FMTcQVVKhdKHUKkV8Ra6fRhD8rYA,13887
|
|
84
|
+
pyinfra/operations/brew.py,sha256=aghLE4qyuhhRbt6fgSPV6_5fyWgTohA77Dc0gol19UU,5155
|
|
85
|
+
pyinfra/operations/bsdinit.py,sha256=okQUQDr2H8Z-cAdfdbPJiuGujsHLuV5gpuMZ1UlICEM,1648
|
|
86
|
+
pyinfra/operations/cargo.py,sha256=mXWd6pb0IR6kzJMmPHwXZN-VJ-B_y8AdOFlrRzDQOZI,1104
|
|
87
|
+
pyinfra/operations/choco.py,sha256=8nG0wc1tZEA0L0HTIjgR00IDiONARokyzHyKj-R3xmo,1515
|
|
88
|
+
pyinfra/operations/dnf.py,sha256=3154Rer6dejVB1AK-CqyJhpMVn_djaSDJrVMs62GNcE,5599
|
|
89
|
+
pyinfra/operations/docker.py,sha256=Mra-m2iayXkc2LgCk2tuE6M7lZHhOGNJD3WQIPM9t2I,8396
|
|
90
|
+
pyinfra/operations/files.py,sha256=9O_HKgmVD_z74jtSivY4pKBPrCDKKHDSy0jAB9QERHU,53639
|
|
91
|
+
pyinfra/operations/gem.py,sha256=2C85sOwIRMHGvmPg4uAlUVf6MokhiA7LLPqzdJRHsBg,1132
|
|
92
|
+
pyinfra/operations/git.py,sha256=b26tQF_4hykTy0FtxiuCkqPk9i8JdZaz-RBhH4X96yw,11789
|
|
93
|
+
pyinfra/operations/iptables.py,sha256=brYa4kMhZKFTu24BNds_1b6sOaG94EfqWEoWrScx-Ck,9341
|
|
94
|
+
pyinfra/operations/launchd.py,sha256=6HWvqoQ74idV_NStOEmFXwu0dmTv7YDvFtsK8An2Lu4,1177
|
|
95
|
+
pyinfra/operations/lxd.py,sha256=bKm9gsgZaruKYSL7OYFMiou-wGP4BzwIMWzjW4AZYrk,1742
|
|
96
|
+
pyinfra/operations/mysql.py,sha256=QcYvEQDlPESzDDoJ-HFwJFzN7ftsbsP892LMRZrmaLQ,19873
|
|
97
|
+
pyinfra/operations/npm.py,sha256=bUmfQsClZ2YcHiihiC7k5widIXIi6lbfx_32iyaAKfo,1499
|
|
98
|
+
pyinfra/operations/openrc.py,sha256=GXFoCHEEKeyQyRvrZcNYx8og4fmgmtzTVAViBzt84TE,1580
|
|
99
|
+
pyinfra/operations/pacman.py,sha256=QMjmsBiiw362nhZY0rEDVQL5A32MG3u7GcmX4q4PzfI,1702
|
|
100
|
+
pyinfra/operations/pip.py,sha256=7PpQvZHnwBGZ60V5b0XKNR4tHLW0MXJo6_6UX7HBtGY,5856
|
|
101
|
+
pyinfra/operations/pkg.py,sha256=rORQBbKeb-6gS0LYu0a0VdiWcDZoovcUONCaf6KMdeQ,2298
|
|
102
|
+
pyinfra/operations/pkgin.py,sha256=zhUyGzKjnUfGoyHbMoYMbeeMzcsiOUpBz1zIzppigJ0,1992
|
|
103
|
+
pyinfra/operations/postgres.py,sha256=LRoedDevQqiM5eX5Lmzb5mr_E9Od0ROVC0j18ZqaR0w,9661
|
|
104
|
+
pyinfra/operations/postgresql.py,sha256=agZjL2W4yxigk9ThIC0V_3wvmcWVdX308aJO24WkN6g,833
|
|
105
|
+
pyinfra/operations/puppet.py,sha256=eDe8D9jQbHYQ4_r4-dmEZfMASKQvj36BR8z_h8aDfw8,861
|
|
106
|
+
pyinfra/operations/python.py,sha256=u569cdPrPesrmzU09nwIPA3bk6TZ-Qv2QP0lJLcO_bw,2021
|
|
107
|
+
pyinfra/operations/runit.py,sha256=jRR5kt1OUCLbYktnu7yl3YvSiTW51VvEvOuB0yfd7Ww,5126
|
|
108
|
+
pyinfra/operations/selinux.py,sha256=khqWJsr9MOTyZmxP9P4dQ_7KUNlAfo5fx3Nv7kWm49w,5961
|
|
109
|
+
pyinfra/operations/server.py,sha256=wc5pNDQzEiwl9XEz1cG1m-51z1TV-5P39eMvSig90tY,36414
|
|
110
|
+
pyinfra/operations/snap.py,sha256=a-QtNE4Dlsavqq425TUIwpEJu4oGw8UlLRkdTFyT1F8,3049
|
|
111
|
+
pyinfra/operations/ssh.py,sha256=wocoaYDlOhhItItAVQCEfnVowTtkg3AP0hQ3mnpUnl0,5634
|
|
112
|
+
pyinfra/operations/systemd.py,sha256=hPHTjASj6N_fRAzLr3DNHnxxIbiiTIIT9UStSxKDkTk,3984
|
|
113
|
+
pyinfra/operations/sysvinit.py,sha256=WzzthkmWL46MNNY6LsBZ90e37yPj0w2QyUtEAlGBwqY,4078
|
|
114
|
+
pyinfra/operations/upstart.py,sha256=pHb9RGnVhT14A_y6OezfOH-lmniKpiyJqpeoOJl0beE,1978
|
|
115
|
+
pyinfra/operations/vzctl.py,sha256=2u2CDkuDjzHBRQ54HfyfLpLrsbT8U7_05EEjbbhKUiU,3110
|
|
116
|
+
pyinfra/operations/xbps.py,sha256=ru3_srMBUyUXGzAsPo7WwoomfM0AeDglFv8CDqB33B0,1508
|
|
117
|
+
pyinfra/operations/yum.py,sha256=Ig7AzQy1C7I8XM37lWbw0nI5lzFGMoX30P8FV8-V5uA,5600
|
|
118
|
+
pyinfra/operations/zypper.py,sha256=z1CWv2uwWBlCLIhHna7U5DojVoKZYoUYpezJ_FM_xK8,5555
|
|
119
|
+
pyinfra/operations/util/__init__.py,sha256=ZAHjeCXtLo0TIOSfZ9h0Sh5IXXRCspfHs3RR1l8tQCE,366
|
|
120
|
+
pyinfra/operations/util/docker.py,sha256=6CvQgeFAXH_lDqKb7RxWpMvlCDwEAXlBaDZoJ8LxrYg,4596
|
|
121
|
+
pyinfra/operations/util/files.py,sha256=Zcet3ydNVbdT9jss0BDm6RJFyR_s6XTr0isDR60Zubw,3622
|
|
122
|
+
pyinfra/operations/util/packaging.py,sha256=xFtOlEX46ms7g3gDvOOInRVR1RVfgsmhLzFzsJAL_eU,9381
|
|
123
|
+
pyinfra/operations/util/service.py,sha256=kJd1zj4-sAaGIp5Ts7yAJznogWaGr8oQTztwenLAr7Y,1309
|
|
124
|
+
pyinfra_cli/__init__.py,sha256=G0X7tNdqT45uWuK3aHIKxMdDeCgJ7zHo6vbxoG6zy_8,284
|
|
125
|
+
pyinfra_cli/__main__.py,sha256=WlW7eP0rrL06eguuD_q2RAqgUjg3SW-QnmrayAh2mBQ,887
|
|
126
|
+
pyinfra_cli/commands.py,sha256=J-mCJYvDebJ8M7o3HreB2zToa871-xO6_KjVhPLeHho,1832
|
|
127
|
+
pyinfra_cli/exceptions.py,sha256=iptx9Zj1od7VgSbOyXs7P8tD4zAZ_fwrQFKPlpPrfS0,4806
|
|
128
|
+
pyinfra_cli/inventory.py,sha256=lggXV9blVqNDT2lgVkq9FQWqYBPOakoLYLbuuVQ8upE,10179
|
|
129
|
+
pyinfra_cli/log.py,sha256=7WEGtmf3ncF1BtXL2icUjyxeRKy-7XrCcQ2Hg4GWX5Y,2201
|
|
130
|
+
pyinfra_cli/main.py,sha256=MsBn0RCD5ce4GY-dDBe6vLXT0LanDrrQZpJOTIYZPBs,19715
|
|
131
|
+
pyinfra_cli/prints.py,sha256=za6V-yjXf-LViBW73qWcyfsajCUnf0NCG-7K0ugOA0k,9170
|
|
132
|
+
pyinfra_cli/util.py,sha256=f3iGIPxlUiQJ5LmUGYbEz0QrySQAKmf9xov9WvHXbrk,6364
|
|
133
|
+
pyinfra_cli/virtualenv.py,sha256=6j9W54JkQLN02SrZZIVwszp0GxlaaDEUWFZjBDHIWNA,2466
|
|
134
|
+
tests/test_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
135
|
+
tests/test_api/test_api.py,sha256=Ig2ebkNACYbHcC4_zRkxS9vj5ZEogoPqGx30ErIKChg,2413
|
|
136
|
+
tests/test_api/test_api_arguments.py,sha256=5k7w0_x5cnABEFOk0LQBCt5gU9iTN9lo2XS6MlJTnhQ,1961
|
|
137
|
+
tests/test_api/test_api_command.py,sha256=OW0ESMyS5vo38u17DHeCrSIaIkW9gMU5PSkXL7mRrq0,3204
|
|
138
|
+
tests/test_api/test_api_config.py,sha256=bf0mDrUie3On6zGC_hJBpv-wvSf3LHBIBzUDvkopEt0,708
|
|
139
|
+
tests/test_api/test_api_deploys.py,sha256=h_zbI6CK4K8SdzEr3LEAMPxOf9hnQBdi_suqiNPqHHQ,4200
|
|
140
|
+
tests/test_api/test_api_facts.py,sha256=fUPadZbZ5xaKSF-kmLj7XGwsNiBmfj7Av0gl8fE01Qc,10687
|
|
141
|
+
tests/test_api/test_api_host.py,sha256=U_VW2vTl35vR8EdyIGMKr4y0ydsDLbvHSjZDa99CyNE,1119
|
|
142
|
+
tests/test_api/test_api_inventory.py,sha256=VLbV0MXdRLOPvTXJF156ne6rAx1cBlFfgq_1S79s4tw,2013
|
|
143
|
+
tests/test_api/test_api_operations.py,sha256=GUfnuHK2NoTAGdOT4AbytT9R8i3ZZIvGP7KBfoYcYUQ,20134
|
|
144
|
+
tests/test_api/test_api_util.py,sha256=uHv4oLpoy1_tzOoqFA1zpdvC74SvjitZbxQwp0dmjTs,1716
|
|
145
|
+
tests/test_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
146
|
+
tests/test_cli/test_cli.py,sha256=nZQH0zK1SOgIr5VxBuuHH68hyzG4lhwyw_Z7EhjPtf4,6045
|
|
147
|
+
tests/test_cli/test_cli_deploy.py,sha256=KBnnDsiD21h7t1S2JXpEDpiMxh0AFqwxaEl0z78IE9E,4858
|
|
148
|
+
tests/test_cli/test_cli_exceptions.py,sha256=02sjC6rMptuqchgcdjdsVNQbSQYW6HwGutSy6Q6sMs4,3088
|
|
149
|
+
tests/test_cli/test_cli_util.py,sha256=-Ehnj0cO-EkF-6KLxcPPcFeuAUMTz-fKITrxhuiYhV4,2562
|
|
150
|
+
tests/test_cli/test_context_objects.py,sha256=JiUTwQP7yvcqA47Kq9jtdsB_Z8nxGMZN46d9pR--FYA,2130
|
|
151
|
+
tests/test_cli/util.py,sha256=kp_-XsGnTyDgG6IHWorYzl5VD_WLe77dKOH007TDOUE,338
|
|
152
|
+
tests/test_connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
153
|
+
tests/test_connectors/test_chroot.py,sha256=QK7YgFPXzHh8y363-tmHvzZ0Ok5PVJWFTDAvwt91eac,5907
|
|
154
|
+
tests/test_connectors/test_docker.py,sha256=0EjkfhCHpLCfL4X-AIdMNw5ASaseY0tbRAn7T_TAkMQ,6566
|
|
155
|
+
tests/test_connectors/test_dockerssh.py,sha256=MaC9IK1OZDiqoIsuLOZBJnPDglsMoPDoL19LQtXsyCE,9303
|
|
156
|
+
tests/test_connectors/test_local.py,sha256=N_FkejDZKu7XLnKeApqfBARYMyxf-hRXCQJrXLHvwRg,7442
|
|
157
|
+
tests/test_connectors/test_ssh.py,sha256=zYL0FbRXzqkYJslhmVeUgSkcHtozhmvZfRcaqDrYKvI,40386
|
|
158
|
+
tests/test_connectors/test_sshuserclient.py,sha256=2PQNLPhNL6lBACc6tQuXmPoog-9L6AdDQNrA-rEw1_8,5734
|
|
159
|
+
tests/test_connectors/test_terraform.py,sha256=Z5MhgDeRDFumu-GlbjMD0ZRkecwBIPP8C8ZVg-mq7C8,3743
|
|
160
|
+
tests/test_connectors/test_util.py,sha256=hQir0WyjH0LEF6xvIyHNyqdI5pkJX6qUR9287MgO2bY,4647
|
|
161
|
+
tests/test_connectors/test_vagrant.py,sha256=27qRB7ftjEPaj4ejBNZ-rR4Ou1AD1VyVcf2XjwZPG3M,3640
|
|
162
|
+
pyinfra-3.0.dist-info/LICENSE.md,sha256=gwC95tUll0gwB32tHNkTAasN7Sb6vjWzXa305NwClbI,1076
|
|
163
|
+
pyinfra-3.0.dist-info/METADATA,sha256=2hewmitxy4sio520Cdl_pYYey1Df-zj80v_CjH6dZsI,8320
|
|
164
|
+
pyinfra-3.0.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
|
|
165
|
+
pyinfra-3.0.dist-info/entry_points.txt,sha256=BraEFyquy05M8ch33HZXOHoH_m2BTqejL3xX3NrpzOM,471
|
|
166
|
+
pyinfra-3.0.dist-info/top_level.txt,sha256=2K6D1mK35JTSEBgOfEPV-N-uA2SDErxGiE0J-HUMMVI,26
|
|
167
|
+
pyinfra-3.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[console_scripts]
|
|
2
|
+
pyinfra = pyinfra_cli.__main__:execute_pyinfra
|
|
3
|
+
|
|
4
|
+
[pyinfra.connectors]
|
|
5
|
+
chroot = pyinfra.connectors.chroot:ChrootConnector
|
|
6
|
+
docker = pyinfra.connectors.docker:DockerConnector
|
|
7
|
+
dockerssh = pyinfra.connectors.dockerssh:DockerSSHConnector
|
|
8
|
+
local = pyinfra.connectors.local:LocalConnector
|
|
9
|
+
ssh = pyinfra.connectors.ssh:SSHConnector
|
|
10
|
+
terraform = pyinfra.connectors.terraform:TerraformInventoryConnector
|
|
11
|
+
vagrant = pyinfra.connectors.vagrant:VagrantInventoryConnector
|
pyinfra_cli/__main__.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import signal
|
|
3
2
|
import sys
|
|
4
3
|
|
|
@@ -15,12 +14,14 @@ pyinfra.is_cli = True
|
|
|
15
14
|
# Don't write out deploy.pyc/config.pyc etc
|
|
16
15
|
sys.dont_write_bytecode = True
|
|
17
16
|
|
|
17
|
+
sys.path.append(".")
|
|
18
|
+
|
|
18
19
|
# Shut it click
|
|
19
20
|
click.disable_unicode_literals_warning = True # type: ignore
|
|
20
21
|
|
|
21
22
|
# Force line buffering
|
|
22
|
-
sys.stdout
|
|
23
|
-
sys.stderr
|
|
23
|
+
sys.stdout.reconfigure(line_buffering=True) # type: ignore
|
|
24
|
+
sys.stderr.reconfigure(line_buffering=True) # type: ignore
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
def _handle_interrupt(signum, frame):
|
pyinfra_cli/commands.py
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import json
|
|
2
4
|
|
|
5
|
+
from pyinfra.api.facts import FactBase
|
|
6
|
+
|
|
3
7
|
from .exceptions import CliError
|
|
4
8
|
from .util import parse_cli_arg, try_import_module_attribute
|
|
5
9
|
|
|
@@ -32,7 +36,7 @@ def get_func_and_args(commands):
|
|
|
32
36
|
|
|
33
37
|
|
|
34
38
|
def get_facts_and_args(commands):
|
|
35
|
-
facts = []
|
|
39
|
+
facts: list[tuple[FactBase, tuple, dict]] = []
|
|
36
40
|
|
|
37
41
|
current_fact = None
|
|
38
42
|
|
|
@@ -42,7 +46,7 @@ def get_facts_and_args(commands):
|
|
|
42
46
|
raise CliError("Invalid fact commands: `{0}`".format(commands))
|
|
43
47
|
|
|
44
48
|
key, value = command.split("=", 1)
|
|
45
|
-
current_fact[2][key] = value
|
|
49
|
+
current_fact[2][key] = parse_cli_arg(value)
|
|
46
50
|
continue
|
|
47
51
|
|
|
48
52
|
if current_fact:
|
|
@@ -53,6 +57,7 @@ def get_facts_and_args(commands):
|
|
|
53
57
|
raise CliError(f"Invalid fact: `{command}`, should be in the format `module.cls`")
|
|
54
58
|
|
|
55
59
|
fact_cls = try_import_module_attribute(command, prefix="pyinfra.facts")
|
|
60
|
+
assert fact_cls is not None
|
|
56
61
|
current_fact = (fact_cls, (), {})
|
|
57
62
|
|
|
58
63
|
if current_fact:
|
pyinfra_cli/exceptions.py
CHANGED
|
@@ -1,67 +1,103 @@
|
|
|
1
|
+
import abc
|
|
1
2
|
import sys
|
|
2
|
-
from
|
|
3
|
+
from inspect import getframeinfo
|
|
4
|
+
from traceback import format_exception, format_tb, walk_tb
|
|
5
|
+
from types import TracebackType
|
|
3
6
|
|
|
4
7
|
import click
|
|
5
8
|
|
|
6
|
-
from pyinfra import
|
|
7
|
-
from pyinfra.api.exceptions import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
from pyinfra import logger
|
|
10
|
+
from pyinfra.api.exceptions import (
|
|
11
|
+
ArgumentTypeError,
|
|
12
|
+
ConnectorDataTypeError,
|
|
13
|
+
OperationError,
|
|
14
|
+
PyinfraError,
|
|
15
|
+
)
|
|
16
|
+
from pyinfra.api.util import PYINFRA_INSTALL_DIR
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_frame_line_from_tb(tb: TracebackType):
|
|
20
|
+
frame_lines = list(walk_tb(tb))
|
|
21
|
+
frame_lines.reverse()
|
|
22
|
+
for frame, line in frame_lines:
|
|
23
|
+
info = getframeinfo(frame)
|
|
24
|
+
if info.filename.startswith(PYINFRA_INSTALL_DIR):
|
|
25
|
+
continue
|
|
26
|
+
return info
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class WrappedError(click.ClickException):
|
|
30
|
+
def __init__(self, e: Exception):
|
|
31
|
+
self.traceback = e.__traceback__
|
|
32
|
+
self.exception = e
|
|
33
|
+
|
|
34
|
+
# Pull message from the wrapped exception
|
|
35
|
+
message = getattr(e, "message", e.args[0])
|
|
36
|
+
if not isinstance(message, str):
|
|
37
|
+
message = repr(message)
|
|
38
|
+
self.message = message
|
|
39
|
+
|
|
40
|
+
def show(self, file=None):
|
|
13
41
|
name = "unknown error"
|
|
14
42
|
|
|
15
|
-
if isinstance(self,
|
|
43
|
+
if isinstance(self.exception, ConnectorDataTypeError):
|
|
44
|
+
name = "Connector data type error"
|
|
45
|
+
elif isinstance(self.exception, ArgumentTypeError):
|
|
46
|
+
name = "Argument type error"
|
|
47
|
+
elif isinstance(self.exception, OperationError):
|
|
48
|
+
name = "Operation error"
|
|
49
|
+
elif isinstance(self.exception, PyinfraError):
|
|
16
50
|
name = "pyinfra error"
|
|
51
|
+
elif isinstance(self.exception, IOError):
|
|
52
|
+
name = "Local IO error"
|
|
53
|
+
|
|
54
|
+
if self.traceback:
|
|
55
|
+
info = get_frame_line_from_tb(self.traceback)
|
|
56
|
+
if info:
|
|
57
|
+
name = f"{name} in {info.filename} line {info.lineno}"
|
|
58
|
+
|
|
59
|
+
logger.warning(
|
|
60
|
+
"--> {0}: {1}".format(
|
|
61
|
+
click.style(name, "red", bold=True),
|
|
62
|
+
self,
|
|
63
|
+
),
|
|
64
|
+
)
|
|
17
65
|
|
|
18
|
-
elif isinstance(self, IOError):
|
|
19
|
-
name = "local IO error"
|
|
20
|
-
|
|
21
|
-
if ctx_host.isset():
|
|
22
|
-
# Get any operation meta + name
|
|
23
|
-
op_name = None
|
|
24
|
-
current_op_hash = host.current_op_hash
|
|
25
|
-
current_op_meta = state.op_meta.get(current_op_hash)
|
|
26
|
-
if current_op_meta:
|
|
27
|
-
op_name = ", ".join(current_op_meta["names"])
|
|
28
|
-
|
|
29
|
-
sys.stderr.write(
|
|
30
|
-
"--> {0}{1}{2}: ".format(
|
|
31
|
-
host.print_prefix,
|
|
32
|
-
click.style(name, "red", bold=True),
|
|
33
|
-
" (operation={0})".format(op_name) if op_name else "",
|
|
34
|
-
),
|
|
35
|
-
)
|
|
36
|
-
else:
|
|
37
|
-
sys.stderr.write(
|
|
38
|
-
"--> {0}: ".format(click.style(name, "red", bold=True)),
|
|
39
|
-
)
|
|
40
66
|
|
|
41
|
-
|
|
67
|
+
class CliError(click.ClickException):
|
|
68
|
+
def show(self, file=None):
|
|
69
|
+
logger.warning(
|
|
70
|
+
"--> {0}: {1}".format(
|
|
71
|
+
click.style("pyinfra error", "red", bold=True),
|
|
72
|
+
self,
|
|
73
|
+
),
|
|
74
|
+
)
|
|
75
|
+
|
|
42
76
|
|
|
77
|
+
class UnexpectedMixin(abc.ABC):
|
|
78
|
+
exception: Exception
|
|
79
|
+
traceback: TracebackType
|
|
43
80
|
|
|
44
|
-
class UnexpectedMixin:
|
|
45
81
|
def get_traceback_lines(self):
|
|
46
|
-
traceback = getattr(self.
|
|
82
|
+
traceback = getattr(self.exception, "_traceback")
|
|
47
83
|
return format_tb(traceback)
|
|
48
84
|
|
|
49
85
|
def get_traceback(self):
|
|
50
86
|
return "".join(self.get_traceback_lines())
|
|
51
87
|
|
|
52
88
|
def get_exception(self):
|
|
53
|
-
return "".join(format_exception(self.
|
|
89
|
+
return "".join(format_exception(self.exception.__class__, self.exception, None))
|
|
54
90
|
|
|
55
91
|
|
|
56
92
|
class UnexpectedExternalError(click.ClickException, UnexpectedMixin):
|
|
57
93
|
def __init__(self, e, filename):
|
|
58
94
|
_, _, traceback = sys.exc_info()
|
|
59
95
|
e._traceback = traceback
|
|
60
|
-
self.
|
|
96
|
+
self.exception = e
|
|
61
97
|
self.filename = filename
|
|
62
98
|
|
|
63
|
-
def show(self):
|
|
64
|
-
|
|
99
|
+
def show(self, file=None):
|
|
100
|
+
logger.warning(
|
|
65
101
|
"--> {0}:\n".format(
|
|
66
102
|
click.style(
|
|
67
103
|
"An exception occurred in: {0}".format(self.filename),
|
|
@@ -69,9 +105,9 @@ class UnexpectedExternalError(click.ClickException, UnexpectedMixin):
|
|
|
69
105
|
bold=True,
|
|
70
106
|
),
|
|
71
107
|
),
|
|
72
|
-
err=True,
|
|
73
108
|
)
|
|
74
109
|
|
|
110
|
+
click.echo("Traceback (most recent call last):", err=True)
|
|
75
111
|
click.echo(self.get_traceback(), err=True, nl=False)
|
|
76
112
|
click.echo(self.get_exception(), err=True)
|
|
77
113
|
|
|
@@ -80,9 +116,9 @@ class UnexpectedInternalError(click.ClickException, UnexpectedMixin):
|
|
|
80
116
|
def __init__(self, e):
|
|
81
117
|
_, _, traceback = sys.exc_info()
|
|
82
118
|
e._traceback = traceback
|
|
83
|
-
self.
|
|
119
|
+
self.exception = e
|
|
84
120
|
|
|
85
|
-
def show(self):
|
|
121
|
+
def show(self, file=None):
|
|
86
122
|
click.echo(
|
|
87
123
|
"--> {0}:\n".format(
|
|
88
124
|
click.style(
|
|
@@ -99,7 +135,7 @@ class UnexpectedInternalError(click.ClickException, UnexpectedMixin):
|
|
|
99
135
|
|
|
100
136
|
# Syntax errors contain the filename/line/etc, but other exceptions
|
|
101
137
|
# don't, so print the *last* call to stderr.
|
|
102
|
-
if not isinstance(self.
|
|
138
|
+
if not isinstance(self.exception, SyntaxError):
|
|
103
139
|
sys.stderr.write(traceback_lines[-1])
|
|
104
140
|
|
|
105
141
|
exception = self.get_exception()
|
pyinfra_cli/inventory.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import socket
|
|
1
2
|
from collections import defaultdict
|
|
2
3
|
from os import listdir, path
|
|
3
4
|
from types import GeneratorType
|
|
@@ -79,19 +80,52 @@ def _get_any_tuple_first(item: Union[T, Tuple[T, Any]]) -> T:
|
|
|
79
80
|
return item[0] if isinstance(item, tuple) else item
|
|
80
81
|
|
|
81
82
|
|
|
83
|
+
def _resolves_to_host(maybe_host: str) -> bool:
|
|
84
|
+
"""Check if a string resolves to a valid IP address."""
|
|
85
|
+
try:
|
|
86
|
+
# Use getaddrinfo to support IPv6 hosts
|
|
87
|
+
socket.getaddrinfo(maybe_host, port=None)
|
|
88
|
+
return True
|
|
89
|
+
except socket.gaierror:
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
|
|
82
93
|
def make_inventory(
|
|
83
94
|
inventory: str,
|
|
84
95
|
override_data=None,
|
|
85
96
|
cwd: Optional[str] = None,
|
|
86
97
|
group_data_directories=None,
|
|
87
98
|
):
|
|
88
|
-
#
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
99
|
+
# (Un)fortunately the CLI is pretty flexible for inventory inputs; we support inventory files, a
|
|
100
|
+
# single hostname, list of hosts, connectors, and python module.function or module:function
|
|
101
|
+
# imports.
|
|
102
|
+
#
|
|
103
|
+
# We check first for an inventory file, a list of hosts or anything with a connector, because
|
|
104
|
+
# (1) an inventory file is a common use case and (2) no other option can have a comma or an @
|
|
105
|
+
# symbol in them.
|
|
106
|
+
is_path_or_host_list_or_connector = (
|
|
107
|
+
path.exists(inventory) or "," in inventory or "@" in inventory
|
|
108
|
+
)
|
|
109
|
+
if not is_path_or_host_list_or_connector:
|
|
110
|
+
# Next, try loading the inventory from a python function. This happens before checking for a
|
|
111
|
+
# single-host inventory, so that your command does not stop working because somebody
|
|
112
|
+
# registered the domain `my.module.name`.
|
|
113
|
+
inventory_func = try_import_module_attribute(inventory, raise_for_none=False)
|
|
114
|
+
|
|
115
|
+
# If the inventory does not refer to a module, we finally check if it refers to a reachable
|
|
116
|
+
# host
|
|
117
|
+
if inventory_func is None and _resolves_to_host(inventory):
|
|
118
|
+
is_path_or_host_list_or_connector = True
|
|
119
|
+
|
|
120
|
+
if is_path_or_host_list_or_connector:
|
|
121
|
+
# The inventory is either an inventory file or a (list of) hosts
|
|
94
122
|
return make_inventory_from_files(inventory, override_data, cwd, group_data_directories)
|
|
123
|
+
elif inventory_func is None:
|
|
124
|
+
logger.warn(
|
|
125
|
+
f"{inventory} is neither an inventory file, a (list of) hosts or connectors "
|
|
126
|
+
"nor refers to a python module"
|
|
127
|
+
)
|
|
128
|
+
return Inventory.empty()
|
|
95
129
|
else:
|
|
96
130
|
return make_inventory_from_func(inventory_func, override_data)
|
|
97
131
|
|