pyinfra 3.0.dev0__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.
Files changed (148) hide show
  1. pyinfra/api/__init__.py +3 -0
  2. pyinfra/api/arguments.py +115 -97
  3. pyinfra/api/arguments_typed.py +80 -0
  4. pyinfra/api/command.py +5 -3
  5. pyinfra/api/config.py +139 -39
  6. pyinfra/api/connectors.py +5 -2
  7. pyinfra/api/deploy.py +19 -19
  8. pyinfra/api/exceptions.py +35 -4
  9. pyinfra/api/facts.py +62 -86
  10. pyinfra/api/host.py +102 -15
  11. pyinfra/api/inventory.py +4 -0
  12. pyinfra/api/operation.py +184 -118
  13. pyinfra/api/operations.py +66 -113
  14. pyinfra/api/state.py +53 -34
  15. pyinfra/api/util.py +64 -33
  16. pyinfra/connectors/base.py +65 -20
  17. pyinfra/connectors/chroot.py +15 -13
  18. pyinfra/connectors/docker.py +62 -72
  19. pyinfra/connectors/dockerssh.py +20 -19
  20. pyinfra/connectors/local.py +32 -22
  21. pyinfra/connectors/ssh.py +162 -86
  22. pyinfra/connectors/sshuserclient/client.py +1 -1
  23. pyinfra/connectors/terraform.py +57 -39
  24. pyinfra/connectors/util.py +26 -27
  25. pyinfra/connectors/vagrant.py +27 -26
  26. pyinfra/context.py +1 -0
  27. pyinfra/facts/apk.py +7 -2
  28. pyinfra/facts/apt.py +15 -7
  29. pyinfra/facts/brew.py +28 -13
  30. pyinfra/facts/bsdinit.py +9 -6
  31. pyinfra/facts/cargo.py +6 -3
  32. pyinfra/facts/choco.py +8 -4
  33. pyinfra/facts/deb.py +21 -9
  34. pyinfra/facts/dnf.py +11 -6
  35. pyinfra/facts/docker.py +30 -5
  36. pyinfra/facts/files.py +49 -33
  37. pyinfra/facts/gem.py +7 -2
  38. pyinfra/facts/git.py +14 -21
  39. pyinfra/facts/gpg.py +4 -1
  40. pyinfra/facts/hardware.py +186 -138
  41. pyinfra/facts/launchd.py +7 -2
  42. pyinfra/facts/lxd.py +8 -2
  43. pyinfra/facts/mysql.py +19 -12
  44. pyinfra/facts/npm.py +3 -1
  45. pyinfra/facts/openrc.py +8 -2
  46. pyinfra/facts/pacman.py +13 -5
  47. pyinfra/facts/pip.py +2 -0
  48. pyinfra/facts/pkg.py +5 -1
  49. pyinfra/facts/pkgin.py +7 -2
  50. pyinfra/facts/postgres.py +170 -0
  51. pyinfra/facts/postgresql.py +5 -162
  52. pyinfra/facts/rpm.py +21 -15
  53. pyinfra/facts/runit.py +70 -0
  54. pyinfra/facts/selinux.py +12 -4
  55. pyinfra/facts/server.py +240 -82
  56. pyinfra/facts/snap.py +8 -2
  57. pyinfra/facts/systemd.py +37 -13
  58. pyinfra/facts/sysvinit.py +7 -4
  59. pyinfra/facts/upstart.py +7 -2
  60. pyinfra/facts/util/packaging.py +3 -2
  61. pyinfra/facts/vzctl.py +8 -4
  62. pyinfra/facts/xbps.py +7 -2
  63. pyinfra/facts/yum.py +10 -5
  64. pyinfra/facts/zypper.py +9 -4
  65. pyinfra/operations/apk.py +5 -3
  66. pyinfra/operations/apt.py +28 -25
  67. pyinfra/operations/brew.py +60 -29
  68. pyinfra/operations/bsdinit.py +6 -4
  69. pyinfra/operations/cargo.py +3 -1
  70. pyinfra/operations/choco.py +3 -1
  71. pyinfra/operations/dnf.py +16 -20
  72. pyinfra/operations/docker.py +339 -0
  73. pyinfra/operations/files.py +187 -168
  74. pyinfra/operations/gem.py +3 -1
  75. pyinfra/operations/git.py +23 -25
  76. pyinfra/operations/iptables.py +33 -25
  77. pyinfra/operations/launchd.py +5 -6
  78. pyinfra/operations/lxd.py +7 -4
  79. pyinfra/operations/mysql.py +59 -55
  80. pyinfra/operations/npm.py +8 -1
  81. pyinfra/operations/openrc.py +5 -3
  82. pyinfra/operations/pacman.py +6 -7
  83. pyinfra/operations/pip.py +19 -12
  84. pyinfra/operations/pkg.py +3 -1
  85. pyinfra/operations/pkgin.py +5 -3
  86. pyinfra/operations/postgres.py +349 -0
  87. pyinfra/operations/postgresql.py +18 -335
  88. pyinfra/operations/puppet.py +3 -1
  89. pyinfra/operations/python.py +8 -19
  90. pyinfra/operations/runit.py +182 -0
  91. pyinfra/operations/selinux.py +47 -29
  92. pyinfra/operations/server.py +138 -67
  93. pyinfra/operations/snap.py +3 -1
  94. pyinfra/operations/ssh.py +18 -16
  95. pyinfra/operations/systemd.py +18 -12
  96. pyinfra/operations/sysvinit.py +7 -5
  97. pyinfra/operations/upstart.py +7 -5
  98. pyinfra/operations/util/__init__.py +12 -0
  99. pyinfra/operations/util/docker.py +177 -0
  100. pyinfra/operations/util/files.py +24 -16
  101. pyinfra/operations/util/packaging.py +54 -38
  102. pyinfra/operations/util/service.py +39 -47
  103. pyinfra/operations/vzctl.py +12 -10
  104. pyinfra/operations/xbps.py +5 -3
  105. pyinfra/operations/yum.py +15 -19
  106. pyinfra/operations/zypper.py +9 -10
  107. pyinfra/version.py +5 -2
  108. {pyinfra-3.0.dev0.dist-info → pyinfra-3.0.1.dist-info}/METADATA +51 -58
  109. pyinfra-3.0.1.dist-info/RECORD +168 -0
  110. {pyinfra-3.0.dev0.dist-info → pyinfra-3.0.1.dist-info}/WHEEL +1 -1
  111. {pyinfra-3.0.dev0.dist-info → pyinfra-3.0.1.dist-info}/entry_points.txt +0 -3
  112. pyinfra_cli/__main__.py +4 -3
  113. pyinfra_cli/commands.py +3 -2
  114. pyinfra_cli/exceptions.py +75 -43
  115. pyinfra_cli/inventory.py +52 -31
  116. pyinfra_cli/log.py +10 -2
  117. pyinfra_cli/main.py +88 -65
  118. pyinfra_cli/prints.py +37 -109
  119. pyinfra_cli/util.py +15 -10
  120. tests/test_api/test_api.py +2 -0
  121. tests/test_api/test_api_arguments.py +9 -9
  122. tests/test_api/test_api_deploys.py +15 -19
  123. tests/test_api/test_api_facts.py +4 -5
  124. tests/test_api/test_api_operations.py +18 -20
  125. tests/test_api/test_api_util.py +41 -2
  126. tests/test_cli/test_cli.py +14 -50
  127. tests/test_cli/test_cli_deploy.py +10 -12
  128. tests/test_cli/test_cli_exceptions.py +50 -19
  129. tests/test_cli/test_cli_inventory.py +66 -0
  130. tests/test_cli/util.py +1 -1
  131. tests/test_connectors/test_dockerssh.py +11 -8
  132. tests/test_connectors/test_ssh.py +88 -23
  133. tests/test_connectors/test_sshuserclient.py +1 -1
  134. tests/test_connectors/test_terraform.py +11 -8
  135. tests/test_connectors/test_vagrant.py +6 -6
  136. pyinfra/connectors/ansible.py +0 -175
  137. pyinfra/connectors/mech.py +0 -189
  138. pyinfra/connectors/pyinfrawinrmsession/__init__.py +0 -28
  139. pyinfra/connectors/winrm.py +0 -312
  140. pyinfra/facts/windows.py +0 -366
  141. pyinfra/facts/windows_files.py +0 -90
  142. pyinfra/operations/windows.py +0 -59
  143. pyinfra/operations/windows_files.py +0 -538
  144. pyinfra-3.0.dev0.dist-info/RECORD +0 -170
  145. tests/test_connectors/test_ansible.py +0 -64
  146. tests/test_connectors/test_mech.py +0 -126
  147. {pyinfra-3.0.dev0.dist-info → pyinfra-3.0.1.dist-info}/LICENSE.md +0 -0
  148. {pyinfra-3.0.dev0.dist-info → pyinfra-3.0.1.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyinfra
3
- Version: 3.0.dev0
3
+ Version: 3.0.1
4
4
  Summary: pyinfra automates/provisions/manages/deploys infrastructure.
5
5
  Home-page: https://pyinfra.com
6
6
  Author: Nick / Fizzadar
@@ -16,71 +16,69 @@ 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.7
20
19
  Classifier: Programming Language :: Python :: 3.8
21
20
  Classifier: Programming Language :: Python :: 3.9
22
21
  Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
23
24
  Classifier: Topic :: System :: Systems Administration
24
25
  Classifier: Topic :: System :: Installation/Setup
25
26
  Classifier: Topic :: Utilities
27
+ Requires-Python: >=3.8
26
28
  Description-Content-Type: text/markdown
27
29
  License-File: LICENSE.md
28
- Requires-Dist: gevent (>=1.5)
29
- Requires-Dist: paramiko (<3,>=2.7)
30
- Requires-Dist: click (>2)
31
- Requires-Dist: colorama (<1)
32
- Requires-Dist: jinja2 (<4,>2)
33
- Requires-Dist: python-dateutil (<3,>2)
30
+ Requires-Dist: gevent >=1.5
31
+ Requires-Dist: paramiko <4,>=2.7
32
+ Requires-Dist: click >2
33
+ Requires-Dist: jinja2 <4,>2
34
+ Requires-Dist: python-dateutil <3,>2
34
35
  Requires-Dist: setuptools
35
36
  Requires-Dist: configparser
36
37
  Requires-Dist: pywinrm
37
- Requires-Dist: distro (<2,>=1.6)
38
+ Requires-Dist: typeguard
39
+ Requires-Dist: distro <2,>=1.6
40
+ Requires-Dist: packaging >=16.1
41
+ Requires-Dist: importlib-metadata >=3.6 ; python_version < "3.10"
38
42
  Requires-Dist: typing-extensions ; python_version < "3.11"
39
43
  Requires-Dist: graphlib-backport ; python_version < "3.9"
40
- Provides-Extra: ansible
41
- Requires-Dist: pyyaml ; extra == 'ansible'
42
44
  Provides-Extra: dev
43
- Requires-Dist: pyyaml ; extra == 'dev'
44
- Requires-Dist: pytest (==7.2.0) ; extra == 'dev'
45
- Requires-Dist: coverage (==6.5) ; extra == 'dev'
46
- Requires-Dist: pytest-cov (==4.0.0) ; extra == 'dev'
47
- Requires-Dist: black (==22.3.0) ; extra == 'dev'
48
- Requires-Dist: isort (==5.10.1) ; extra == 'dev'
49
- Requires-Dist: flake8 (==4.0.1) ; extra == 'dev'
50
- Requires-Dist: flake8-black (==0.3.0) ; extra == 'dev'
51
- Requires-Dist: flake8-isort (==4.1.1) ; extra == 'dev'
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'
52
53
  Requires-Dist: mypy ; extra == 'dev'
53
54
  Requires-Dist: types-cryptography ; extra == 'dev'
54
55
  Requires-Dist: types-paramiko ; extra == 'dev'
55
56
  Requires-Dist: types-python-dateutil ; extra == 'dev'
56
57
  Requires-Dist: types-PyYAML ; extra == 'dev'
57
58
  Requires-Dist: types-setuptools ; extra == 'dev'
58
- Requires-Dist: pyinfra-guzzle-sphinx-theme (==0.14) ; extra == 'dev'
59
- Requires-Dist: recommonmark (==0.5.0) ; extra == 'dev'
60
- Requires-Dist: sphinx (==2.2.1) ; extra == 'dev'
61
- Requires-Dist: docutils (==0.17.1) ; extra == 'dev'
59
+ Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.16 ; extra == 'dev'
60
+ Requires-Dist: myst-parser ==2.0.0 ; extra == 'dev'
61
+ Requires-Dist: sphinx ==6.2.1 ; extra == 'dev'
62
62
  Requires-Dist: wheel ; extra == 'dev'
63
63
  Requires-Dist: twine ; extra == 'dev'
64
64
  Requires-Dist: ipython ; extra == 'dev'
65
65
  Requires-Dist: ipdb ; extra == 'dev'
66
66
  Requires-Dist: ipdbplugin ; extra == 'dev'
67
- Requires-Dist: flake8-spellcheck (==0.12.1) ; extra == 'dev'
67
+ Requires-Dist: flake8-spellcheck ==0.12.1 ; extra == 'dev'
68
68
  Requires-Dist: redbaron ; extra == 'dev'
69
69
  Provides-Extra: docs
70
- Requires-Dist: pyinfra-guzzle-sphinx-theme (==0.14) ; extra == 'docs'
71
- Requires-Dist: recommonmark (==0.5.0) ; extra == 'docs'
72
- Requires-Dist: sphinx (==2.2.1) ; extra == 'docs'
73
- Requires-Dist: docutils (==0.17.1) ; extra == 'docs'
70
+ Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.16 ; extra == 'docs'
71
+ Requires-Dist: myst-parser ==2.0.0 ; extra == 'docs'
72
+ Requires-Dist: sphinx ==6.2.1 ; extra == 'docs'
74
73
  Provides-Extra: test
75
- Requires-Dist: pyyaml ; extra == 'test'
76
- Requires-Dist: pytest (==7.2.0) ; extra == 'test'
77
- Requires-Dist: coverage (==6.5) ; extra == 'test'
78
- Requires-Dist: pytest-cov (==4.0.0) ; extra == 'test'
79
- Requires-Dist: black (==22.3.0) ; extra == 'test'
80
- Requires-Dist: isort (==5.10.1) ; extra == 'test'
81
- Requires-Dist: flake8 (==4.0.1) ; extra == 'test'
82
- Requires-Dist: flake8-black (==0.3.0) ; extra == 'test'
83
- Requires-Dist: flake8-isort (==4.1.1) ; extra == 'test'
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'
84
82
  Requires-Dist: mypy ; extra == 'test'
85
83
  Requires-Dist: types-cryptography ; extra == 'test'
86
84
  Requires-Dist: types-paramiko ; extra == 'test'
@@ -94,47 +92,42 @@ Requires-Dist: types-setuptools ; extra == 'test'
94
92
  </a>
95
93
  </p>
96
94
 
97
- <p align="center">
98
- <em>pyinfra automates infrastructure super fast at massive scale<br />ad-hoc command execution, service deployment, configuration management and more</em>
95
+ <p>
96
+ 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.
99
97
  </p>
100
98
 
101
99
  ---
102
100
 
103
- <p align="center">
104
- <a href="https://docs.pyinfra.com"><strong>Documentation</strong></a> &rArr;
101
+ <h3>
105
102
  <a href="https://docs.pyinfra.com/page/getting-started.html"><strong>Getting Started</strong></a> &bull;
106
- <a href="https://docs.pyinfra.com/page/examples.html"><strong>Examples</strong></a> &bull;
103
+ <a href="https://github.com/pyinfra-dev/pyinfra-examples"><strong>Examples Repo</strong></a> &bull;
104
+ <a href="https://matrix.to/#/#pyinfra:matrix.org"><strong>Chat on Matrix</strong></a>
105
+ </h3>
106
+ <p>
107
+ <a href="https://docs.pyinfra.com"><strong>Documentation</strong></a> &bull;
107
108
  <a href="https://docs.pyinfra.com/page/support.html"><strong>Help & Support</strong></a> &bull;
108
109
  <a href="https://docs.pyinfra.com/page/contributing.html"><strong>Contributing</strong></a>
109
110
  </p>
110
111
 
111
- <p align="center">
112
- Chat (both bridged) &rArr;
113
- <a href="https://matrix.to/#/#pyinfra:matrix.org"><strong><code>#pyinfra</code> on Matrix</strong></a> &bull;
114
- <a href="https://discord.gg/w3XxuKw"><strong>Discord</strong></a>
115
- </p>
116
-
117
112
  ---
118
113
 
119
114
  Why pyinfra? Design features include:
120
115
 
121
116
  + 🚀 **Super fast** execution over thousands of hosts with predictable performance.
122
117
  + 🚨 **Instant debugging** with realtime stdin/stdout/stderr output (`-vvv`).
123
- + 🔄 **Idempotent operations** that enable diffs and `--dry` runs before executing any changes.
124
- + 📦 **Extendable** with _any_ Python package as configured & written in standard Python.
125
- + 💻 **Agentless execution** against SSH/Docker/subprocess/WinRM hosts.
126
- + 🔌 **Integrated** with Docker, Terraform, Vagrant/Mech & Ansible out of the box.
127
-
128
- When you run pyinfra you'll see something like ([non animated version](https://pyinfra.com/static/example_deploy.png)):
118
+ + 🔄 **Idempotent operations** that enable diffs and dry runs before making changes.
119
+ + 📦 **Extendable** with the entire Python package ecosystem.
120
+ + 💻 **Agentless execution** against anything with shell access.
121
+ + 🔌 **Integrated** with connectors for Docker, Terraform, Vagrant and more.
129
122
 
130
123
  <img width="100%" src="https://pyinfra.com/static/example_deploy.gif" />
131
124
 
132
125
  ## Quickstart
133
126
 
134
- Install pyinfra with [`pipx`](https://pipxproject.github.io/pipx/) (recommended) or `pip`:
127
+ Install pyinfra with `pip`:
135
128
 
136
129
  ```
137
- pipx install pyinfra
130
+ pip install pyinfra
138
131
  ```
139
132
 
140
133
  Now you can execute commands on hosts via SSH:
@@ -143,7 +136,7 @@ Now you can execute commands on hosts via SSH:
143
136
  pyinfra my-server.net exec -- echo "hello world"
144
137
  ```
145
138
 
146
- Or execute in Docker, on the local machine, and other [connectors](https://docs.pyinfra.com/page/connectors.html):
139
+ Or target Docker containers, the local machine, and other [connectors](https://docs.pyinfra.com/page/connectors.html):
147
140
 
148
141
  ```sh
149
142
  pyinfra @docker/ubuntu exec -- echo "Hello world"
@@ -0,0 +1,168 @@
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=aMPtkB7vypyXRQDThjwJZzAnEgqjP0wrwyEhRHQf4Js,9449
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=qbrC-Hjvzre2_U0l3hHo4wzZBDFN-zcWBNoWQgIyXxE,12272
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=24KWAAqIaUPQIod-CSeXKkA_WhQnIIGWaLKlnVUATDY,9746
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=q76WdaCNZGKzYia5vMscCsOi4WlnBhcj_9c7Jj-2LqQ,581
40
+ pyinfra/facts/apt.py,sha256=Cs5AyfEoxWmKU2wU9pYeTDeikA4mxU4TehwwKr5i57g,2173
41
+ pyinfra/facts/brew.py,sha256=qDz89ZlZOiCZv0GLOXOjgFtqq66SLaYXgCncYP2LwDs,2584
42
+ pyinfra/facts/bsdinit.py,sha256=hyESeGu0hPf8HY1D0bIFFFNFpXRdZB2R52aflVQPf9o,577
43
+ pyinfra/facts/cargo.py,sha256=OQF6nOulp2TIaFK1fiAEevsXnL5OMQUL6LkFHidb1yo,605
44
+ pyinfra/facts/choco.py,sha256=A0VCXnI5H9RocgO1IvaNWRIxnXiIZYEzIDG1F-ydJi4,790
45
+ pyinfra/facts/deb.py,sha256=XGyxnow9wjpE8ZKTZDa1_SNChMyMcNgFeTG1ka5uky4,1922
46
+ pyinfra/facts/dnf.py,sha256=9rTBgLHewbk8XCJuikzAYCumfFAzbmmHMchlaXBhdWw,977
47
+ pyinfra/facts/docker.py,sha256=CVSsUEiBaQrNvM1mggoKCXj5DdzwmcbufUY96koqKBw,2250
48
+ pyinfra/facts/files.py,sha256=cHbK2S8jJCLB7pDRBTqekHAkBo3_HnlqVcRdiZu8_VU,11536
49
+ pyinfra/facts/gem.py,sha256=ktC2hofSwYX0fVcdWleU74ddjW1RPZvKMW-3wYp9lJE,572
50
+ pyinfra/facts/git.py,sha256=6e_2GjDT2oAxdtkHTyeMYQ9N64gZDorLTTVeZhFel18,1276
51
+ pyinfra/facts/gpg.py,sha256=wYKoQl4aHXB1UqqbWCdVhUoa6N6Liz01AmH8fPjxR48,3813
52
+ pyinfra/facts/hardware.py,sha256=YUK1rZ2tygry9_m7HjV3TQ_GZOW7WHqTlonsOT-zRxk,12022
53
+ pyinfra/facts/iptables.py,sha256=sUkywfHZUXnMZF_KshAnyJufrJvZ9fBYnERSRbwOCRE,3374
54
+ pyinfra/facts/launchd.py,sha256=D0RSpBQXt4a4zJOxwxIb5RYY34sAx6ZrWj8NxwYqhIc,767
55
+ pyinfra/facts/lxd.py,sha256=NeIMK9VsDXlRf7q3j17oYbdigL7XjLnhmqv63t6CrzQ,466
56
+ pyinfra/facts/mysql.py,sha256=dHEn3E5rTe4aw3DNHikmgj_VBkQeJZs-gfuS5N35BqE,6135
57
+ pyinfra/facts/npm.py,sha256=rI3at2M6Rfwb4cPj5gTivMTss5POs5_W2Ilcrgv8XAA,756
58
+ pyinfra/facts/openrc.py,sha256=gAXl3evsDXSHcIKIj4E_CRerAugEFpGGNRxJBr0rBAk,1490
59
+ pyinfra/facts/pacman.py,sha256=NJ43rYc5k4uhl5sFxd9sTg7yqTQhB3xsREsusS6BzwU,1198
60
+ pyinfra/facts/pip.py,sha256=ORyrVxu_-8eIr0uSCkI6x4MH-sorDEavml4aozcdrOA,738
61
+ pyinfra/facts/pkg.py,sha256=iIvinsJxEaSYAaRw_5_WD5WlIlcy4ksKa0lwj0CFxco,520
62
+ pyinfra/facts/pkgin.py,sha256=Y4QfUwtWcBH-h77O-MtiixSepHK0p-lcebrqdmABfs8,580
63
+ pyinfra/facts/postgres.py,sha256=7cg0Nq8wNIWnKw3B8dJpgjSFZ7q90-_NhwEw2NsSJm8,4229
64
+ pyinfra/facts/postgresql.py,sha256=4nusMVvGhtku86KX4O4vjSxh_MamxZy_kmTQvvy0GhE,223
65
+ pyinfra/facts/rpm.py,sha256=SzHNCNUMA-j5uJl4PKRTFpckOvNZ2zpxNeQyOCl8Usk,2225
66
+ pyinfra/facts/runit.py,sha256=iarF_Tql8bkNeHsKGRANRKNyBWwMsflsTNXj1Wz14i8,2021
67
+ pyinfra/facts/selinux.py,sha256=zzh7o0SU8ocMRJzcYMuAv6ss93onfojpa1pAN1azgeU,4433
68
+ pyinfra/facts/server.py,sha256=fDXSNNlZghJTGqr9CWRDob-_N-8xxb-KUZlTf5No-M0,20439
69
+ pyinfra/facts/snap.py,sha256=6br9IMIoq88z_RS0FLXxfodIVjUmyPU9eZBa9zO8H1o,2027
70
+ pyinfra/facts/systemd.py,sha256=eRbhK2A1jWy-jrXFdKVm-VkiCfT_PQP5xR6QbP3pQuc,4012
71
+ pyinfra/facts/sysvinit.py,sha256=RniaROHyeZD3jVOa_sISpZV4zx8ae8HkUQrtriLIlWc,1521
72
+ pyinfra/facts/upstart.py,sha256=HYR7vJ6oqtuRhxXQgzGDKYzyKqqVsjT-TtPPWOjBGdA,635
73
+ pyinfra/facts/vzctl.py,sha256=S9aclpDBF3DmBLwMltsd9j3B4QxQ5-1Kb1hybZodEqI,678
74
+ pyinfra/facts/xbps.py,sha256=4gAajBlTAg3bo7vRdx3b2TTi-vvU1y86WZqC0H9nUUk,573
75
+ pyinfra/facts/yum.py,sha256=i42g0FIZg62TZFqFcaUQWNekFFFo4G8vf5wyaKUuh8Q,938
76
+ pyinfra/facts/zypper.py,sha256=sAIZ5SqjsJ1Dc5e3pJrOoR5Gnu9BqZHpDFI8gKLts84,873
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=imZ4dbY4tl0GpBSkUgV983jbDDihWNs_OQkOBulT7FQ,5948
109
+ pyinfra/operations/server.py,sha256=cjQRZMYkSNKDwlKpTSj3iuJO3mNre0jR4R3MTIS_xIk,36462
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=S8aSl8TrF72Ni7eHiB40GjtAJeqyB1VxHobG2k254hQ,10329
129
+ pyinfra_cli/log.py,sha256=7WEGtmf3ncF1BtXL2icUjyxeRKy-7XrCcQ2Hg4GWX5Y,2201
130
+ pyinfra_cli/main.py,sha256=PjZ1Fe3jlodvBsnY-xXU8ASJim2ocU6j6ICQzsoXhRU,19922
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=WnKwgLq7sk2LNO5IgIZbO5HRkDr-2GdUWO_EFfTjhO8,10695
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=IeWuhkhLzIkRbOEx5-yaW6xV5l4Y8fxaGaDGlMcOyYE,6016
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_inventory.py,sha256=xlo-p3HdfVPNqxi7SknEZ2mWrKsdDaK3PoVN-tl95Z0,2394
150
+ tests/test_cli/test_cli_util.py,sha256=-Ehnj0cO-EkF-6KLxcPPcFeuAUMTz-fKITrxhuiYhV4,2562
151
+ tests/test_cli/test_context_objects.py,sha256=JiUTwQP7yvcqA47Kq9jtdsB_Z8nxGMZN46d9pR--FYA,2130
152
+ tests/test_cli/util.py,sha256=kp_-XsGnTyDgG6IHWorYzl5VD_WLe77dKOH007TDOUE,338
153
+ tests/test_connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
154
+ tests/test_connectors/test_chroot.py,sha256=QK7YgFPXzHh8y363-tmHvzZ0Ok5PVJWFTDAvwt91eac,5907
155
+ tests/test_connectors/test_docker.py,sha256=0EjkfhCHpLCfL4X-AIdMNw5ASaseY0tbRAn7T_TAkMQ,6566
156
+ tests/test_connectors/test_dockerssh.py,sha256=MaC9IK1OZDiqoIsuLOZBJnPDglsMoPDoL19LQtXsyCE,9303
157
+ tests/test_connectors/test_local.py,sha256=N_FkejDZKu7XLnKeApqfBARYMyxf-hRXCQJrXLHvwRg,7442
158
+ tests/test_connectors/test_ssh.py,sha256=zYL0FbRXzqkYJslhmVeUgSkcHtozhmvZfRcaqDrYKvI,40386
159
+ tests/test_connectors/test_sshuserclient.py,sha256=2PQNLPhNL6lBACc6tQuXmPoog-9L6AdDQNrA-rEw1_8,5734
160
+ tests/test_connectors/test_terraform.py,sha256=Z5MhgDeRDFumu-GlbjMD0ZRkecwBIPP8C8ZVg-mq7C8,3743
161
+ tests/test_connectors/test_util.py,sha256=hQir0WyjH0LEF6xvIyHNyqdI5pkJX6qUR9287MgO2bY,4647
162
+ tests/test_connectors/test_vagrant.py,sha256=27qRB7ftjEPaj4ejBNZ-rR4Ou1AD1VyVcf2XjwZPG3M,3640
163
+ pyinfra-3.0.1.dist-info/LICENSE.md,sha256=gwC95tUll0gwB32tHNkTAasN7Sb6vjWzXa305NwClbI,1076
164
+ pyinfra-3.0.1.dist-info/METADATA,sha256=vpa6_3c318yjxCjV4OsawHtZFm_ESQ-CuR2ox3hUdQA,8041
165
+ pyinfra-3.0.1.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
166
+ pyinfra-3.0.1.dist-info/entry_points.txt,sha256=BraEFyquy05M8ch33HZXOHoH_m2BTqejL3xX3NrpzOM,471
167
+ pyinfra-3.0.1.dist-info/top_level.txt,sha256=2K6D1mK35JTSEBgOfEPV-N-uA2SDErxGiE0J-HUMMVI,26
168
+ pyinfra-3.0.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.38.4)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
@@ -2,13 +2,10 @@
2
2
  pyinfra = pyinfra_cli.__main__:execute_pyinfra
3
3
 
4
4
  [pyinfra.connectors]
5
- ansible = pyinfra.connectors.ansible:AnsibleInventoryConnector
6
5
  chroot = pyinfra.connectors.chroot:ChrootConnector
7
6
  docker = pyinfra.connectors.docker:DockerConnector
8
7
  dockerssh = pyinfra.connectors.dockerssh:DockerSSHConnector
9
8
  local = pyinfra.connectors.local:LocalConnector
10
- mech = pyinfra.connectors.mech:MechInventoryConnector
11
9
  ssh = pyinfra.connectors.ssh:SSHConnector
12
10
  terraform = pyinfra.connectors.terraform:TerraformInventoryConnector
13
11
  vagrant = pyinfra.connectors.vagrant:VagrantInventoryConnector
14
- winrm = pyinfra.connectors.winrm:WinRMConnector
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 = os.fdopen(sys.stdout.fileno(), "w", 1)
23
- sys.stderr = os.fdopen(sys.stderr.fileno(), "w", 1)
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
@@ -36,7 +36,7 @@ def get_func_and_args(commands):
36
36
 
37
37
 
38
38
  def get_facts_and_args(commands):
39
- facts: list[FactBase] = []
39
+ facts: list[tuple[FactBase, tuple, dict]] = []
40
40
 
41
41
  current_fact = None
42
42
 
@@ -46,7 +46,7 @@ def get_facts_and_args(commands):
46
46
  raise CliError("Invalid fact commands: `{0}`".format(commands))
47
47
 
48
48
  key, value = command.split("=", 1)
49
- current_fact[2][key] = value
49
+ current_fact[2][key] = parse_cli_arg(value)
50
50
  continue
51
51
 
52
52
  if current_fact:
@@ -57,6 +57,7 @@ def get_facts_and_args(commands):
57
57
  raise CliError(f"Invalid fact: `{command}`, should be in the format `module.cls`")
58
58
 
59
59
  fact_cls = try_import_module_attribute(command, prefix="pyinfra.facts")
60
+ assert fact_cls is not None
60
61
  current_fact = (fact_cls, (), {})
61
62
 
62
63
  if current_fact:
pyinfra_cli/exceptions.py CHANGED
@@ -1,71 +1,103 @@
1
1
  import abc
2
2
  import sys
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
8
 
7
- from pyinfra import host, logger, state
8
- from pyinfra.api.exceptions import PyinfraError
9
- from pyinfra.context import ctx_host
10
-
11
-
12
- class CliError(PyinfraError, click.ClickException):
13
- def show(self):
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):
14
41
  name = "unknown error"
15
42
 
16
- if isinstance(self, PyinfraError):
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):
17
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
+ )
18
65
 
19
- elif isinstance(self, IOError):
20
- name = "local IO error"
21
-
22
- if ctx_host.isset():
23
- # Get any operation meta + name
24
- op_name = None
25
- current_op_hash = host.current_op_hash
26
- if current_op_hash:
27
- current_op_meta = state.op_meta.get(current_op_hash)
28
- if current_op_meta:
29
- op_name = ", ".join(current_op_meta.names)
30
-
31
- sys.stderr.write(
32
- "--> {0}{1}{2}: ".format(
33
- host.print_prefix,
34
- click.style(name, "red", bold=True),
35
- " (operation={0})".format(op_name) if op_name else "",
36
- ),
37
- )
38
- else:
39
- sys.stderr.write(
40
- "--> {0}: ".format(click.style(name, "red", bold=True)),
41
- )
42
66
 
43
- logger.warning(self)
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
+ )
44
75
 
45
76
 
46
77
  class UnexpectedMixin(abc.ABC):
47
- e: Exception
78
+ exception: Exception
79
+ traceback: TracebackType
48
80
 
49
81
  def get_traceback_lines(self):
50
- traceback = getattr(self.e, "_traceback")
82
+ traceback = getattr(self.exception, "_traceback")
51
83
  return format_tb(traceback)
52
84
 
53
85
  def get_traceback(self):
54
86
  return "".join(self.get_traceback_lines())
55
87
 
56
88
  def get_exception(self):
57
- return "".join(format_exception(self.e.__class__, self.e, None))
89
+ return "".join(format_exception(self.exception.__class__, self.exception, None))
58
90
 
59
91
 
60
92
  class UnexpectedExternalError(click.ClickException, UnexpectedMixin):
61
93
  def __init__(self, e, filename):
62
94
  _, _, traceback = sys.exc_info()
63
95
  e._traceback = traceback
64
- self.e = e
96
+ self.exception = e
65
97
  self.filename = filename
66
98
 
67
- def show(self):
68
- click.echo(
99
+ def show(self, file=None):
100
+ logger.warning(
69
101
  "--> {0}:\n".format(
70
102
  click.style(
71
103
  "An exception occurred in: {0}".format(self.filename),
@@ -73,9 +105,9 @@ class UnexpectedExternalError(click.ClickException, UnexpectedMixin):
73
105
  bold=True,
74
106
  ),
75
107
  ),
76
- err=True,
77
108
  )
78
109
 
110
+ click.echo("Traceback (most recent call last):", err=True)
79
111
  click.echo(self.get_traceback(), err=True, nl=False)
80
112
  click.echo(self.get_exception(), err=True)
81
113
 
@@ -84,9 +116,9 @@ class UnexpectedInternalError(click.ClickException, UnexpectedMixin):
84
116
  def __init__(self, e):
85
117
  _, _, traceback = sys.exc_info()
86
118
  e._traceback = traceback
87
- self.e = e
119
+ self.exception = e
88
120
 
89
- def show(self):
121
+ def show(self, file=None):
90
122
  click.echo(
91
123
  "--> {0}:\n".format(
92
124
  click.style(
@@ -103,7 +135,7 @@ class UnexpectedInternalError(click.ClickException, UnexpectedMixin):
103
135
 
104
136
  # Syntax errors contain the filename/line/etc, but other exceptions
105
137
  # don't, so print the *last* call to stderr.
106
- if not isinstance(self.e, SyntaxError):
138
+ if not isinstance(self.exception, SyntaxError):
107
139
  sys.stderr.write(traceback_lines[-1])
108
140
 
109
141
  exception = self.get_exception()