pyinfra 3.0b0__py2.py3-none-any.whl → 3.0b1__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 (45) hide show
  1. pyinfra/api/__init__.py +3 -0
  2. pyinfra/api/arguments.py +5 -4
  3. pyinfra/api/arguments_typed.py +12 -2
  4. pyinfra/api/exceptions.py +19 -0
  5. pyinfra/api/facts.py +1 -1
  6. pyinfra/api/host.py +46 -7
  7. pyinfra/api/operation.py +77 -39
  8. pyinfra/api/operations.py +10 -11
  9. pyinfra/api/state.py +11 -2
  10. pyinfra/connectors/base.py +1 -1
  11. pyinfra/connectors/chroot.py +5 -6
  12. pyinfra/connectors/docker.py +11 -10
  13. pyinfra/connectors/dockerssh.py +5 -4
  14. pyinfra/connectors/local.py +5 -5
  15. pyinfra/connectors/ssh.py +44 -23
  16. pyinfra/connectors/terraform.py +9 -6
  17. pyinfra/connectors/util.py +1 -1
  18. pyinfra/connectors/vagrant.py +6 -5
  19. pyinfra/facts/choco.py +1 -1
  20. pyinfra/facts/deb.py +2 -2
  21. pyinfra/facts/postgres.py +168 -0
  22. pyinfra/facts/postgresql.py +5 -164
  23. pyinfra/facts/systemd.py +26 -10
  24. pyinfra/operations/files.py +5 -3
  25. pyinfra/operations/iptables.py +6 -0
  26. pyinfra/operations/pip.py +5 -0
  27. pyinfra/operations/postgres.py +347 -0
  28. pyinfra/operations/postgresql.py +17 -336
  29. pyinfra/operations/systemd.py +5 -3
  30. {pyinfra-3.0b0.dist-info → pyinfra-3.0b1.dist-info}/METADATA +6 -6
  31. {pyinfra-3.0b0.dist-info → pyinfra-3.0b1.dist-info}/RECORD +44 -43
  32. pyinfra_cli/commands.py +3 -2
  33. pyinfra_cli/exceptions.py +5 -0
  34. pyinfra_cli/main.py +2 -0
  35. pyinfra_cli/prints.py +22 -104
  36. tests/test_api/test_api_deploys.py +5 -5
  37. tests/test_api/test_api_operations.py +4 -4
  38. tests/test_connectors/test_ssh.py +52 -0
  39. tests/test_connectors/test_terraform.py +11 -8
  40. tests/test_connectors/test_vagrant.py +3 -3
  41. pyinfra_cli/inventory_dsl.py +0 -23
  42. {pyinfra-3.0b0.dist-info → pyinfra-3.0b1.dist-info}/LICENSE.md +0 -0
  43. {pyinfra-3.0b0.dist-info → pyinfra-3.0b1.dist-info}/WHEEL +0 -0
  44. {pyinfra-3.0b0.dist-info → pyinfra-3.0b1.dist-info}/entry_points.txt +0 -0
  45. {pyinfra-3.0b0.dist-info → pyinfra-3.0b1.dist-info}/top_level.txt +0 -0
@@ -1,347 +1,28 @@
1
- """
2
- The PostgreSQL modules manage PostgreSQL databases, users and privileges.
1
+ from pyinfra.api import operation
3
2
 
4
- Requires the ``psql`` CLI executable on the target host(s).
3
+ from . import postgres
5
4
 
6
- All operations in this module take four optional arguments:
7
- + ``psql_user``: the username to connect to postgresql to
8
- + ``psql_password``: the password for the connecting user
9
- + ``psql_host``: the hostname of the server to connect to
10
- + ``psql_port``: the port of the server to connect to
11
5
 
12
- See example/postgresql.py for detailed example
6
+ @operation(is_idempotent=False, is_deprecated=True, deprecated_for="postgres.sql")
7
+ def sql(*args, **kwargs):
8
+ yield from postgres.sql._inner(*args, **kwargs)
13
9
 
14
- """
15
10
 
16
- from pyinfra import host
17
- from pyinfra.api import MaskString, StringCommand, operation
18
- from pyinfra.facts.postgresql import (
19
- PostgresqlDatabases,
20
- PostgresqlRoles,
21
- make_execute_psql_command,
22
- make_psql_command,
23
- )
11
+ @operation(is_idempotent=False, is_deprecated=True, deprecated_for="postgres.role")
12
+ def role(*args, **kwargs):
13
+ yield from postgres.role._inner(*args, **kwargs)
24
14
 
25
15
 
26
- @operation(is_idempotent=False)
27
- def sql(
28
- sql,
29
- database=None,
30
- # Details for speaking to PostgreSQL via `psql` CLI
31
- psql_user=None,
32
- psql_password=None,
33
- psql_host=None,
34
- psql_port=None,
35
- ):
36
- """
37
- Execute arbitrary SQL against PostgreSQL.
16
+ @operation(is_idempotent=False, is_deprecated=True)
17
+ def database(*args, **kwargs):
18
+ yield from postgres.database._inner(*args, **kwargs)
38
19
 
39
- + sql: SQL command(s) to execute
40
- + database: optional database to execute against
41
- + psql_*: global module arguments, see above
42
- """
43
20
 
44
- yield make_execute_psql_command(
45
- sql,
46
- database=database,
47
- user=psql_user,
48
- password=psql_password,
49
- host=psql_host,
50
- port=psql_port,
51
- )
21
+ @operation(is_idempotent=False, is_deprecated=True)
22
+ def dump(*args, **kwargs):
23
+ yield from postgres.dump._inner(*args, **kwargs)
52
24
 
53
25
 
54
- @operation()
55
- def role(
56
- role,
57
- present=True,
58
- password=None,
59
- login=True,
60
- superuser=False,
61
- inherit=False,
62
- createdb=False,
63
- createrole=False,
64
- replication=False,
65
- connection_limit=None,
66
- # Details for speaking to PostgreSQL via `psql` CLI
67
- psql_user=None,
68
- psql_password=None,
69
- psql_host=None,
70
- psql_port=None,
71
- ):
72
- """
73
- Add/remove PostgreSQL roles.
74
-
75
- + role: name of the role
76
- + present: whether the role should be present or absent
77
- + password: the password for the role
78
- + login: whether the role can login
79
- + superuser: whether role will be a superuser
80
- + inherit: whether the role inherits from other roles
81
- + createdb: whether the role is allowed to create databases
82
- + createrole: whether the role is allowed to create new roles
83
- + replication: whether this role is allowed to replicate
84
- + connection_limit: the connection limit for the role
85
- + psql_*: global module arguments, see above
86
-
87
- Updates:
88
- pyinfra will not attempt to change existing roles - it will either
89
- create or drop roles, but not alter them (if the role exists this
90
- operation will make no changes).
91
-
92
- **Example:**
93
-
94
- .. code:: python
95
-
96
- postgresql.role(
97
- name="Create the pyinfra PostgreSQL role",
98
- role="pyinfra",
99
- password="somepassword",
100
- superuser=True,
101
- login=True,
102
- sudo_user="postgres",
103
- )
104
-
105
- """
106
-
107
- roles = host.get_fact(
108
- PostgresqlRoles,
109
- psql_user=psql_user,
110
- psql_password=psql_password,
111
- psql_host=psql_host,
112
- psql_port=psql_port,
113
- )
114
-
115
- is_present = role in roles
116
-
117
- # User not wanted?
118
- if not present:
119
- if is_present:
120
- yield make_execute_psql_command(
121
- 'DROP ROLE "{0}"'.format(role),
122
- user=psql_user,
123
- password=psql_password,
124
- host=psql_host,
125
- port=psql_port,
126
- )
127
- else:
128
- host.noop("postgresql role {0} does not exist".format(role))
129
- return
130
-
131
- # If we want the user and they don't exist
132
- if not is_present:
133
- sql_bits = ['CREATE ROLE "{0}"'.format(role)]
134
-
135
- for key, value in (
136
- ("LOGIN", login),
137
- ("SUPERUSER", superuser),
138
- ("INHERIT", inherit),
139
- ("CREATEDB", createdb),
140
- ("CREATEROLE", createrole),
141
- ("REPLICATION", replication),
142
- ):
143
- if value:
144
- sql_bits.append(key)
145
-
146
- if connection_limit:
147
- sql_bits.append("CONNECTION LIMIT {0}".format(connection_limit))
148
-
149
- if password:
150
- sql_bits.append(MaskString("PASSWORD '{0}'".format(password)))
151
-
152
- yield make_execute_psql_command(
153
- StringCommand(*sql_bits),
154
- user=psql_user,
155
- password=psql_password,
156
- host=psql_host,
157
- port=psql_port,
158
- )
159
- else:
160
- host.noop("postgresql role {0} exists".format(role))
161
-
162
-
163
- @operation()
164
- def database(
165
- database,
166
- present=True,
167
- owner=None,
168
- template=None,
169
- encoding=None,
170
- lc_collate=None,
171
- lc_ctype=None,
172
- tablespace=None,
173
- connection_limit=None,
174
- # Details for speaking to PostgreSQL via `psql` CLI
175
- psql_user=None,
176
- psql_password=None,
177
- psql_host=None,
178
- psql_port=None,
179
- ):
180
- """
181
- Add/remove PostgreSQL databases.
182
-
183
- + name: name of the database
184
- + present: whether the database should exist or not
185
- + owner: the PostgreSQL role that owns the database
186
- + template: name of the PostgreSQL template to use
187
- + encoding: encoding of the database
188
- + lc_collate: lc_collate of the database
189
- + lc_ctype: lc_ctype of the database
190
- + tablespace: the tablespace to use for the template
191
- + connection_limit: the connection limit to apply to the database
192
- + psql_*: global module arguments, see above
193
-
194
- Updates:
195
- pyinfra will not attempt to change existing databases - it will either
196
- create or drop databases, but not alter them (if the db exists this
197
- operation will make no changes).
198
-
199
- **Example:**
200
-
201
- .. code:: python
202
-
203
- postgresql.database(
204
- name="Create the pyinfra_stuff database",
205
- database="pyinfra_stuff",
206
- owner="pyinfra",
207
- encoding="UTF8",
208
- sudo_user="postgres",
209
- )
210
-
211
- """
212
-
213
- current_databases = host.get_fact(
214
- PostgresqlDatabases,
215
- psql_user=psql_user,
216
- psql_password=psql_password,
217
- psql_host=psql_host,
218
- psql_port=psql_port,
219
- )
220
-
221
- is_present = database in current_databases
222
-
223
- if not present:
224
- if is_present:
225
- yield make_execute_psql_command(
226
- 'DROP DATABASE "{0}"'.format(database),
227
- user=psql_user,
228
- password=psql_password,
229
- host=psql_host,
230
- port=psql_port,
231
- )
232
- else:
233
- host.noop("postgresql database {0} does not exist".format(database))
234
- return
235
-
236
- # We want the database but it doesn't exist
237
- if present and not is_present:
238
- sql_bits = ['CREATE DATABASE "{0}"'.format(database)]
239
-
240
- for key, value in (
241
- ("OWNER", '"{0}"'.format(owner) if owner else owner),
242
- ("TEMPLATE", template),
243
- ("ENCODING", encoding),
244
- ("LC_COLLATE", lc_collate),
245
- ("LC_CTYPE", lc_ctype),
246
- ("TABLESPACE", tablespace),
247
- ("CONNECTION LIMIT", connection_limit),
248
- ):
249
- if value:
250
- sql_bits.append("{0} {1}".format(key, value))
251
-
252
- yield make_execute_psql_command(
253
- StringCommand(*sql_bits),
254
- user=psql_user,
255
- password=psql_password,
256
- host=psql_host,
257
- port=psql_port,
258
- )
259
- else:
260
- host.noop("postgresql database {0} exists".format(database))
261
-
262
-
263
- @operation(is_idempotent=False)
264
- def dump(
265
- dest,
266
- database=None,
267
- # Details for speaking to PostgreSQL via `psql` CLI
268
- psql_user=None,
269
- psql_password=None,
270
- psql_host=None,
271
- psql_port=None,
272
- ):
273
- """
274
- Dump a PostgreSQL database into a ``.sql`` file. Requires ``pg_dump``.
275
-
276
- + dest: name of the file to dump the SQL to
277
- + database: name of the database to dump
278
- + psql_*: global module arguments, see above
279
-
280
- **Example:**
281
-
282
- .. code:: python
283
-
284
- postgresql.dump(
285
- name="Dump the pyinfra_stuff database",
286
- dest="/tmp/pyinfra_stuff.dump",
287
- database="pyinfra_stuff",
288
- sudo_user="postgres",
289
- )
290
-
291
- """
292
-
293
- yield StringCommand(
294
- make_psql_command(
295
- executable="pg_dump",
296
- database=database,
297
- user=psql_user,
298
- password=psql_password,
299
- host=psql_host,
300
- port=psql_port,
301
- ),
302
- ">",
303
- dest,
304
- )
305
-
306
-
307
- @operation(is_idempotent=False)
308
- def load(
309
- src,
310
- database=None,
311
- # Details for speaking to PostgreSQL via `psql` CLI
312
- psql_user=None,
313
- psql_password=None,
314
- psql_host=None,
315
- psql_port=None,
316
- ):
317
- """
318
- Load ``.sql`` file into a database.
319
-
320
- + src: the filename to read from
321
- + database: name of the database to import into
322
- + psql_*: global module arguments, see above
323
-
324
- **Example:**
325
-
326
- .. code:: python
327
-
328
- postgresql.load(
329
- name="Import the pyinfra_stuff dump into pyinfra_stuff_copy",
330
- src="/tmp/pyinfra_stuff.dump",
331
- database="pyinfra_stuff_copy",
332
- sudo_user="postgres",
333
- )
334
-
335
- """
336
-
337
- yield StringCommand(
338
- make_psql_command(
339
- database=database,
340
- user=psql_user,
341
- password=psql_password,
342
- host=psql_host,
343
- port=psql_port,
344
- ),
345
- "<",
346
- src,
347
- )
26
+ @operation(is_idempotent=False, is_deprecated=True)
27
+ def load(*args, **kwargs):
28
+ yield from postgres.load._inner(*args, **kwargs)
@@ -3,7 +3,7 @@ Manage systemd services.
3
3
  """
4
4
 
5
5
  from pyinfra import host
6
- from pyinfra.api import operation
6
+ from pyinfra.api import StringCommand, operation
7
7
  from pyinfra.facts.systemd import SystemdEnabled, SystemdStatus, _make_systemctl_cmd
8
8
 
9
9
  from .util.service import handle_service_control
@@ -25,7 +25,7 @@ def daemon_reload(user_mode=False, machine=None, user_name=None):
25
25
  user_name=user_name,
26
26
  )
27
27
 
28
- yield "{0} daemon-reload".format(systemctl_cmd)
28
+ yield StringCommand(systemctl_cmd, "daemon-reload")
29
29
 
30
30
 
31
31
  _daemon_reload = daemon_reload._inner # noqa: E305
@@ -117,8 +117,9 @@ def service(
117
117
  user_mode=user_mode,
118
118
  machine=machine,
119
119
  user_name=user_name,
120
+ services=[service],
120
121
  ),
121
- " ".join([systemctl_cmd, "{1}", "{0}"]),
122
+ " ".join([systemctl_cmd.get_raw_value(), "{1}", "{0}"]),
122
123
  running,
123
124
  restarted,
124
125
  reloaded,
@@ -131,6 +132,7 @@ def service(
131
132
  user_mode=user_mode,
132
133
  machine=machine,
133
134
  user_name=user_name,
135
+ services=[service],
134
136
  )
135
137
  is_enabled = systemd_enabled.get(service, False)
136
138
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyinfra
3
- Version: 3.0b0
3
+ Version: 3.0b1
4
4
  Summary: pyinfra automates/provisions/manages/deploys infrastructure.
5
5
  Home-page: https://pyinfra.com
6
6
  Author: Nick / Fizzadar
@@ -88,17 +88,17 @@ Requires-Dist: types-setuptools ; extra == 'test'
88
88
  </a>
89
89
  </p>
90
90
 
91
- <p align="center">
91
+ <p>
92
92
  <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>
93
93
  </p>
94
94
 
95
- <p align="center">
96
- <em>pyinfra automates infrastructure using Python. It’s fast and scales from one server to thousands. Great for 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.
97
97
  </p>
98
98
 
99
99
  ---
100
100
 
101
- <p align="center">
101
+ <p>
102
102
  <a href="https://docs.pyinfra.com"><strong>Documentation</strong></a> &rArr;
103
103
  <a href="https://docs.pyinfra.com/page/getting-started.html"><strong>Getting Started</strong></a> &bull;
104
104
  <a href="https://docs.pyinfra.com/page/examples.html"><strong>Examples</strong></a> &bull;
@@ -106,7 +106,7 @@ Requires-Dist: types-setuptools ; extra == 'test'
106
106
  <a href="https://docs.pyinfra.com/page/contributing.html"><strong>Contributing</strong></a>
107
107
  </p>
108
108
 
109
- <p align="center">
109
+ <p>
110
110
  Chat &rArr;
111
111
  <a href="https://matrix.to/#/#pyinfra:matrix.org"><strong><code>#pyinfra</code> on Matrix</strong></a>
112
112
  </p>
@@ -5,33 +5,33 @@ pyinfra/local.py,sha256=0bpIRCyDKM6i_jA1i8Ej2qr_iWIF9cUYWutXNdLj8po,2751
5
5
  pyinfra/progress.py,sha256=X3hXZ4Flh_L9FE4ZEWxWoG0R4dA5UPd1FCO-Exd5Xtc,4193
6
6
  pyinfra/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  pyinfra/version.py,sha256=hAgEPHVJVjA2I-rI0gy038UAPVKcmulk-3dZLOmkYrI,153
8
- pyinfra/api/__init__.py,sha256=_gId0L-DYg7A1aofFN5ra--GBE2sq7hpobjL470OhTc,888
9
- pyinfra/api/arguments.py,sha256=iOtGiQvRhh8gk0spesH5i0ccDSwEQr2ri6xKL0ADduM,9688
10
- pyinfra/api/arguments_typed.py,sha256=OYB4uEGYogKZV2Amz9fosQEqi9hrkU1eDpWThMX3_Vk,2201
8
+ pyinfra/api/__init__.py,sha256=suGbKKM-qCduuXFYBEcyswlTqozewtYpdLRhK63PVn0,942
9
+ pyinfra/api/arguments.py,sha256=1kTpgvCeKpMnmf7IhIfARjEjz0-94L7ud1qP90JSeAU,9748
10
+ pyinfra/api/arguments_typed.py,sha256=fy_Sg3UgzYmm7rG8Vvheu_Ah-YjpfpIkBIRDFUbYhaY,2254
11
11
  pyinfra/api/command.py,sha256=KGhAnaxZGZv5NJa0-aOgu2g9nOYTsdjlCaFHR6QO53E,7176
12
12
  pyinfra/api/config.py,sha256=G1ZNHw26G1QyqEBU6AuFsK3jVKdgW-VPqE9WZgtlzkg,4221
13
13
  pyinfra/api/connect.py,sha256=Z9wusMLR_jBkKKk5D4AUOj8LHl3H5MsNO5FxAeR4jac,1416
14
14
  pyinfra/api/connectors.py,sha256=SLmKtoN4cXvcQz9IgWSPI-d3ZMzJ09pcvka42Fiuo7s,544
15
15
  pyinfra/api/deploy.py,sha256=xo4F7URUf3xzIChRHZn4zwqs_WTjLjZNC9i9eQjAFk8,2756
16
- pyinfra/api/exceptions.py,sha256=uzMTtTWXwUGNj5F3z9EOyMSdVkmqurZUdZGd9P_F-xQ,1445
17
- pyinfra/api/facts.py,sha256=ub2LGAcO2K6ofZXQwQSvd6z04_Fc0iez1A6ZQ0Dxec4,10283
18
- pyinfra/api/host.py,sha256=8Ed1pSKmzApX6BfOPXVNmIuN8nHog77qry_5I7mYO3I,12394
16
+ pyinfra/api/exceptions.py,sha256=cCbUp1qN1QO0d9aAvOAbRgYpLi0vUI5j7ZqSjcD1_P8,1861
17
+ pyinfra/api/facts.py,sha256=FOIn6qO2tw5I1hkS0fAaBmhGfnMwKWZjn1ZqCnU6_pA,10282
18
+ pyinfra/api/host.py,sha256=CzTDyYROIZqDSCVTrlIOoX1ODqLMNlW08W1nN9oH-Rs,13475
19
19
  pyinfra/api/inventory.py,sha256=83ttxbGbIwN2tvmVTW68fumIDXNMk48qvL0NxwGPkNs,7663
20
- pyinfra/api/operation.py,sha256=HKcTBmWqdHvGpjAXce9Cbx0WLYOdwFvwBc2UiFzhWHA,13225
21
- pyinfra/api/operations.py,sha256=v2WY6lVUoyGRP3bwIM0cgrJEO5HpM1l2eFwRvOQmSpI,10921
22
- pyinfra/api/state.py,sha256=nMPGmNGsEuUDcUU0rp3ky3PA-c2jhrocK-A5NJcPTIc,12526
20
+ pyinfra/api/operation.py,sha256=2r3RylueNAjDL0SwCIln84Jpwl2KA3Xep2rtwGQXX3I,14789
21
+ pyinfra/api/operations.py,sha256=jvz9ISfwmQnAQVUKLnbrRdD9QHIAAfypo9l5b3fYG1w,10894
22
+ pyinfra/api/state.py,sha256=3dXRjeZJXnzLcbP9E4aogkRPwIg3_kK1h4Tf4FVZock,12622
23
23
  pyinfra/api/util.py,sha256=TkUlcMPIrLGxRQY19CvCXL1H_20DjFTmFL0QbFqQ0gw,11977
24
24
  pyinfra/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- pyinfra/connectors/base.py,sha256=HYlAcup7kNsrzNjw3PyPvt1PESDQadGt_M2hQM8vKQQ,3754
26
- pyinfra/connectors/chroot.py,sha256=mtrQO3wsJj3jlp7bZR0if_LghWjAacEAgBYZw9ysiNo,5963
27
- pyinfra/connectors/docker.py,sha256=nXvtj1J-8wFtG1UkoV_6_NxPeSgvn1uA0pJXGJMfysw,8954
28
- pyinfra/connectors/dockerssh.py,sha256=V4G2g9dRPwDj0UxvGBRM93IHSpGpO5PiBdWJ4KsKjbg,8943
29
- pyinfra/connectors/local.py,sha256=-ofyZA9trondAyzhYnGqk15HtuZdo0gl-N1GHOu_rG0,6937
30
- pyinfra/connectors/ssh.py,sha256=YNbpNAy67pSzlhlVcz9YQPlcBhVVJ5nTrBCF6UL_UnY,20263
25
+ pyinfra/connectors/base.py,sha256=41RSf0t6LlYZe3nW9B1CfbOwbOulaDnZT3fnGn23DWw,3756
26
+ pyinfra/connectors/chroot.py,sha256=Xd72I8T58KIwKOoc0LXCw91AoEIaiHfRLDcDVTHGJ0o,5931
27
+ pyinfra/connectors/docker.py,sha256=NRqE8543j0eqUnjv2wbokW-hWkam2kZNiokPTGYDBXI,8964
28
+ pyinfra/connectors/dockerssh.py,sha256=VWHY--jqs3yf-RuPUZXav4vLeON9SzoVC9CUyOJo1rg,8919
29
+ pyinfra/connectors/local.py,sha256=szFO9VP5xNWpqK9ThkjroyFvnxckiG5kjM08vgqbVhc,6929
30
+ pyinfra/connectors/ssh.py,sha256=w3UTuZOeO9fFwcvQWZ7xS8KyCvsWWd4uKJc_6ONSMrU,21018
31
31
  pyinfra/connectors/ssh_util.py,sha256=CN_5AdTA3RpiWCnXTrRBjez1NsN59hITDzQmXIkZvoE,3683
32
- pyinfra/connectors/terraform.py,sha256=e7-azZfJpe51UwCWwMRHExup1ePq6AiAyIwB9cu9Fbw,3541
33
- pyinfra/connectors/util.py,sha256=_R5QEyP0A1LBupJ7LPAJeqmWPcPwp_69k9eqFRZkp6A,11321
34
- pyinfra/connectors/vagrant.py,sha256=lUCC3cH8CAmGphDqIfzHSueWYp9jgKldH2MatG0zCv0,4697
32
+ pyinfra/connectors/terraform.py,sha256=G7lK168Fz0jNFetc_7_bPT-RnoaRDksJat0R26fqkUk,3617
33
+ pyinfra/connectors/util.py,sha256=JBGTgBkXQTu7l5uVYPzVfQdPXwehmRWkMf8IEVj2gGs,11326
34
+ pyinfra/connectors/vagrant.py,sha256=6edwwc5rMfEFridUN9BXytoIeXeBQvyoucLcSUTGivs,4722
35
35
  pyinfra/connectors/sshuserclient/__init__.py,sha256=Qc4RO2wknSWIiNTwOeQ0y2TeiuKHmyWDW2Dz4MOo9CE,44
36
36
  pyinfra/connectors/sshuserclient/client.py,sha256=7YSd3QckZuPDRnKzy2FfG3J8zp7CY-jny8tbWwxvKro,9720
37
37
  pyinfra/connectors/sshuserclient/config.py,sha256=UMwkvTgAIS7__re6Wz_pwH6EU4kO1-uMQ5zuFakH0v4,2721
@@ -41,8 +41,8 @@ pyinfra/facts/apt.py,sha256=zqFSPIAaIgHWWg3eGgL-BDX1aqvgiQ7rNc8QrE1LXLg,1999
41
41
  pyinfra/facts/brew.py,sha256=POnOx3PWzK1B8pbtkI9wBmYSUsG0IblpwrMHZsMC7Og,2266
42
42
  pyinfra/facts/bsdinit.py,sha256=sx54RAmS7rjTDzLbUWv86UFtfE8H56qokektf5smN30,490
43
43
  pyinfra/facts/cargo.py,sha256=C_2NIWcDzT5Y6xxnT5TvuhWpLJCQTqVVXK8biiUvhjI,531
44
- pyinfra/facts/choco.py,sha256=CatATw35ToFTgFNO_aXwl7ZSi2Mply47VixOJzK7Dp8,716
45
- pyinfra/facts/deb.py,sha256=aTlXoBsuORIe5cbFV_UbXZZLOskcfrWoyuDg_cSAEFY,1662
44
+ pyinfra/facts/choco.py,sha256=gYdgqglICBn6SStyJvHwQGD8ayo0Zwp5EMiNuYRs5VY,703
45
+ pyinfra/facts/deb.py,sha256=v2wSbOIFefY7QrQbXZ584mH_bDW9kzUqozCvZ_5dEgE,1666
46
46
  pyinfra/facts/dnf.py,sha256=zV_Fx4cq81lyKctDYki65e088kXDAyZiwkEcBDOoLtU,862
47
47
  pyinfra/facts/docker.py,sha256=0EUskxna88haXeHYJBFUDnUHJcX2QIwwKME_dRcfoiY,1678
48
48
  pyinfra/facts/files.py,sha256=VJujyRa9FiowXnNJUuDmYk6hJi8DYJYetvOAnatkpcg,11475
@@ -60,12 +60,13 @@ pyinfra/facts/pacman.py,sha256=SJTdi49nBHk7Gb6ajf2I5PZTHWkqZ_k4npAf695luRs,1001
60
60
  pyinfra/facts/pip.py,sha256=v6pJCQHOB8DaDgpyrLTz3kKKCSqvLG_zs0uy6_gGOf8,702
61
61
  pyinfra/facts/pkg.py,sha256=GgRU5x9OWfAfqF-KgJiJz0ndtLKhiRGhtTG4agfunuM,452
62
62
  pyinfra/facts/pkgin.py,sha256=_rekZJtKLx2TOHd_REJLMDp02typZMpQkZ7sC4FLJSQ,481
63
- pyinfra/facts/postgresql.py,sha256=1xob1BqC6jt4PlUW1jXJkCzTfYvKHiw6cKem0ycerq8,4104
63
+ pyinfra/facts/postgres.py,sha256=ncx16P6UDZBuOw_7TG_t4AMLSKiI2Xu2nEBPLZ4HZ6Y,4094
64
+ pyinfra/facts/postgresql.py,sha256=nWXwIFFYnF7vGj-yGmhtI2OAQEvlnpIAs-WupUja9vI,187
64
65
  pyinfra/facts/rpm.py,sha256=CdC-r2_cfbt81z3sjAE4I-ne46jI-Of6uyDSvELVJfk,1973
65
66
  pyinfra/facts/selinux.py,sha256=N0zbJrAtBeRBtxZFUHbYTLQ2L4mRV7_Oj3Cj3OA1Npw,4272
66
67
  pyinfra/facts/server.py,sha256=gxEW1By_mi9BVZcAQZC5o1Sz0pxQdPVzoQRXV7WxM5w,19794
67
68
  pyinfra/facts/snap.py,sha256=9PYA73ASi-FgBk_y42lGJyETqEgfcJGm-6EFeKzayhE,1910
68
- pyinfra/facts/systemd.py,sha256=gAw8rLXwXOevs0OLxW0-zACIBC2fcyEtA3Gman4FaOs,3367
69
+ pyinfra/facts/systemd.py,sha256=jhTIMcN96lJbV03xrEjB_0YLg1BxKTFfq5KcpNXtH9Y,3927
69
70
  pyinfra/facts/sysvinit.py,sha256=PS7yMOrVxclywKjF3BIXmxTBgn2_vpSTQrDeOly_j8Q,1490
70
71
  pyinfra/facts/upstart.py,sha256=9mqTYsUpDs7gC5Rest2sQS3EohGXAPjEQUINJWELkW0,543
71
72
  pyinfra/facts/vzctl.py,sha256=AnRl6SZ7HxMGOVl021v0P37pN4tujbwLFuvxUMOCW_M,591
@@ -84,27 +85,28 @@ pyinfra/operations/bsdinit.py,sha256=HtBJERhSiBPaTG0H-m4CG6SY_7iCkl0LtHLGYuNYhVM
84
85
  pyinfra/operations/cargo.py,sha256=wcEhQEz02e6_WGL6ve_bW1IOrnHQqOGzhyMiMjmm0co,1042
85
86
  pyinfra/operations/choco.py,sha256=Qr2lg471XiIhMJ4QvUbmRMNCP-3BNE4VbxNaJE-JjzU,1453
86
87
  pyinfra/operations/dnf.py,sha256=qN9xwLzSFOOJwuUSDhRLTE2TdaNB58HYgtKZMHVn494,5550
87
- pyinfra/operations/files.py,sha256=pQgj40zYB8GM9_JS8v4gh_jO8d3ISVa6DoM072lQrlA,52409
88
+ pyinfra/operations/files.py,sha256=9I5c823Y4hoAsXVHcAK5TixV8fMIbHGOJEzOBPxi1Fc,52485
88
89
  pyinfra/operations/gem.py,sha256=vEGYFniRGrxll8ARNauZQdSPjSHP8-me4UEH1srK-q0,1070
89
90
  pyinfra/operations/git.py,sha256=mxK2q8Hl3xmo27qz9cRCzVvNxK9UPeG3YFh4cV5fSSM,11543
90
- pyinfra/operations/iptables.py,sha256=KMMWct43Ovx-L2tRY4E1GAyTalk96WOJ4iEJMAjxySU,8856
91
+ pyinfra/operations/iptables.py,sha256=moaeEfjrPLHZSiq6vgVRCTXE9191aKF5WlGccHywO9k,9009
91
92
  pyinfra/operations/launchd.py,sha256=i5oeCEekOEQTVlNlayQO057DRXT103H3tWRwp8IRVko,1164
92
93
  pyinfra/operations/lxd.py,sha256=pcdvmxfG6Bm8m_cuF1wRpmpaUzTq2nTd6iOf4jDRicA,1639
93
94
  pyinfra/operations/mysql.py,sha256=wtuUi9IhPaehe3qSFf_woEUpPD8mASAIisdIYbnNy3c,19141
94
95
  pyinfra/operations/npm.py,sha256=PyQJ2DQ_u0jclHNLL21ltUV64VPhC9rriGv5HOc75zY,1404
95
96
  pyinfra/operations/openrc.py,sha256=eta2j16uC24ZHFBB1CVgV1BdzuvY7S5JjcyGA_iVyYw,1510
96
97
  pyinfra/operations/pacman.py,sha256=qPtgIzH0151qhmxzoT4rz5xunffNOICcscknCkzLr8o,1672
97
- pyinfra/operations/pip.py,sha256=l3iI1OqGDbOYqO69l-FRgom1NDfVB5HA5hOjnLCTVPI,5377
98
+ pyinfra/operations/pip.py,sha256=jvUBAalQnFtZFDL5dqSOnBjAWEgzIGQNxHLMPUMvT3Y,5699
98
99
  pyinfra/operations/pkg.py,sha256=sLa3-_YoRMkGNdCovduaZwtAcuADDdaeiKWnIHDiq_k,2222
99
100
  pyinfra/operations/pkgin.py,sha256=hL_l9kN7Dn68CwPd2efrcJoa2KOToTHLhMpi1P8k3oQ,1930
100
- pyinfra/operations/postgresql.py,sha256=0F7oyf0GXIa4Ex2B187sGdAh2gODZ6mnqCFn-oSDgJU,9162
101
+ pyinfra/operations/postgres.py,sha256=ASCPx_WZLk31sZUXHbP_CT5Xr2xz6KwnV-EG6xzPSIo,9152
102
+ pyinfra/operations/postgresql.py,sha256=79i5q3mtFVl3-B8V2FGLmy1n_O5A5i5BCf-ncp90UAI,797
101
103
  pyinfra/operations/puppet.py,sha256=EOT4RnYro9K6N_HrPvYHd3bZX8rcAQxPNfLcuzm-LqE,797
102
104
  pyinfra/operations/python.py,sha256=lQ8lAwy-d_Gg9PVuZVn9-Dl3r5K_XfyUeRKZwekHiuI,1909
103
105
  pyinfra/operations/selinux.py,sha256=v9Wt1-uLButowbNP8iSEYXSXMd7xAsGp6U9EBXUq5sw,5347
104
106
  pyinfra/operations/server.py,sha256=evcQgux6fAU5v9z1XUr7ELob2t8HI9n70U5mi0iYm5k,35710
105
107
  pyinfra/operations/snap.py,sha256=_K-0UdketVIJMe3VlvfvnKGd6NM_3PC-ZzZeeMiGHME,2987
106
108
  pyinfra/operations/ssh.py,sha256=qrU13gmR-XUcT7l7PvRDfU6WhmfOXd50DZKSZASIyiE,5493
107
- pyinfra/operations/systemd.py,sha256=06xeD7HiNyIcWZ18-GV-3cVdVA-vOx7ij0S9JQv3OEs,3719
109
+ pyinfra/operations/systemd.py,sha256=EpQqLNo9P6tnBdre7E7X2UuL-CeK8YJ1wwgr8cKKe5s,3818
108
110
  pyinfra/operations/sysvinit.py,sha256=cAtfKmGZ0T1HxF0KNTLEU-CrS97n1Vpby58jB3S1Eho,4003
109
111
  pyinfra/operations/upstart.py,sha256=1lM09OBzH0vWylCHEA_zZPOv_x5W8DVKpnlAd-km7Rc,1908
110
112
  pyinfra/operations/vzctl.py,sha256=konF-T1KyqZaltRK9BMoUGse8TQb89J2Xbn3kcXh1uM,3010
@@ -117,13 +119,12 @@ pyinfra/operations/util/packaging.py,sha256=fNQaLRtGVrEWFqz2pRAB2nvc1rE7Xd29sXJC
117
119
  pyinfra/operations/util/service.py,sha256=eT_-3r1Lc0aNsNI0p-ocPGjoMfsdcDADqHU82T7GKFE,1031
118
120
  pyinfra_cli/__init__.py,sha256=G0X7tNdqT45uWuK3aHIKxMdDeCgJ7zHo6vbxoG6zy_8,284
119
121
  pyinfra_cli/__main__.py,sha256=8tjq8HUll8P8naFw7pGlygwSz7u9je_MQ-0pqcDlENY,881
120
- pyinfra_cli/commands.py,sha256=eQr3HCuashedJDSxRGdY463FCYHpOmect6I0P_3Z0_U,1761
121
- pyinfra_cli/exceptions.py,sha256=iptx9Zj1od7VgSbOyXs7P8tD4zAZ_fwrQFKPlpPrfS0,4806
122
+ pyinfra_cli/commands.py,sha256=J-mCJYvDebJ8M7o3HreB2zToa871-xO6_KjVhPLeHho,1832
123
+ pyinfra_cli/exceptions.py,sha256=b14C3xZ6PMqe1q-XosozPNhbABVIAdeivWoTdBn77ZE,4953
122
124
  pyinfra_cli/inventory.py,sha256=mgj_T_T-lCy6Diyb466doRKIcz4zXLhRJi3ui_VBlXM,9513
123
- pyinfra_cli/inventory_dsl.py,sha256=MY5Qahs6t3yUvc3ughW8gk-iaKbO54doWhZTsI4-mOQ,461
124
125
  pyinfra_cli/log.py,sha256=7WEGtmf3ncF1BtXL2icUjyxeRKy-7XrCcQ2Hg4GWX5Y,2201
125
- pyinfra_cli/main.py,sha256=zI6sh3aqFIzsnSU9GocmwKo1B8cjH-pYHHV5FA9kKUY,19667
126
- pyinfra_cli/prints.py,sha256=lqNVnGt6Pwr3ooDtbNDeiG0UcKJEUqEXM0rJQlNpIHI,11769
126
+ pyinfra_cli/main.py,sha256=MsBn0RCD5ce4GY-dDBe6vLXT0LanDrrQZpJOTIYZPBs,19715
127
+ pyinfra_cli/prints.py,sha256=MGU8DvHGiE4ZRVPee1Mixia6VWB3zn0OWn7FwTASWpc,9006
127
128
  pyinfra_cli/util.py,sha256=7z6xg1GtbD_lB40yLL_m2EwGVTly0Z7V8oeAdQXnKi0,6322
128
129
  pyinfra_cli/virtualenv.py,sha256=6j9W54JkQLN02SrZZIVwszp0GxlaaDEUWFZjBDHIWNA,2466
129
130
  tests/test_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -131,11 +132,11 @@ tests/test_api/test_api.py,sha256=Ig2ebkNACYbHcC4_zRkxS9vj5ZEogoPqGx30ErIKChg,24
131
132
  tests/test_api/test_api_arguments.py,sha256=5k7w0_x5cnABEFOk0LQBCt5gU9iTN9lo2XS6MlJTnhQ,1961
132
133
  tests/test_api/test_api_command.py,sha256=OW0ESMyS5vo38u17DHeCrSIaIkW9gMU5PSkXL7mRrq0,3204
133
134
  tests/test_api/test_api_config.py,sha256=bf0mDrUie3On6zGC_hJBpv-wvSf3LHBIBzUDvkopEt0,708
134
- tests/test_api/test_api_deploys.py,sha256=diROd47tpFlZAtNfu_E6ijJ4MTzGeRpgRgBSM5kAmjk,4200
135
+ tests/test_api/test_api_deploys.py,sha256=h_zbI6CK4K8SdzEr3LEAMPxOf9hnQBdi_suqiNPqHHQ,4200
135
136
  tests/test_api/test_api_facts.py,sha256=fUPadZbZ5xaKSF-kmLj7XGwsNiBmfj7Av0gl8fE01Qc,10687
136
137
  tests/test_api/test_api_host.py,sha256=U_VW2vTl35vR8EdyIGMKr4y0ydsDLbvHSjZDa99CyNE,1119
137
138
  tests/test_api/test_api_inventory.py,sha256=VLbV0MXdRLOPvTXJF156ne6rAx1cBlFfgq_1S79s4tw,2013
138
- tests/test_api/test_api_operations.py,sha256=z5ChclOsFshU2WEo62uYr9TxCixuUKCU0OJnwBNt4n8,20162
139
+ tests/test_api/test_api_operations.py,sha256=OqLA-d5i-3FWu4rx6Hj_IyjKEp5wrqQ4za1tNQFPJRs,20144
139
140
  tests/test_api/test_api_util.py,sha256=uHv4oLpoy1_tzOoqFA1zpdvC74SvjitZbxQwp0dmjTs,1716
140
141
  tests/test_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
141
142
  tests/test_cli/test_cli.py,sha256=nZQH0zK1SOgIr5VxBuuHH68hyzG4lhwyw_Z7EhjPtf4,6045
@@ -149,14 +150,14 @@ tests/test_connectors/test_chroot.py,sha256=QK7YgFPXzHh8y363-tmHvzZ0Ok5PVJWFTDAv
149
150
  tests/test_connectors/test_docker.py,sha256=0EjkfhCHpLCfL4X-AIdMNw5ASaseY0tbRAn7T_TAkMQ,6566
150
151
  tests/test_connectors/test_dockerssh.py,sha256=MaC9IK1OZDiqoIsuLOZBJnPDglsMoPDoL19LQtXsyCE,9303
151
152
  tests/test_connectors/test_local.py,sha256=N_FkejDZKu7XLnKeApqfBARYMyxf-hRXCQJrXLHvwRg,7442
152
- tests/test_connectors/test_ssh.py,sha256=5PUG-_6VwHbozgulrjkAtwQekc9UA4EQIpOINcz0R_o,36438
153
+ tests/test_connectors/test_ssh.py,sha256=6YPdNv_h12hn6C7Gksuyflf3V0cdvlc8o4e8oWBv-iM,38399
153
154
  tests/test_connectors/test_sshuserclient.py,sha256=2PQNLPhNL6lBACc6tQuXmPoog-9L6AdDQNrA-rEw1_8,5734
154
- tests/test_connectors/test_terraform.py,sha256=9KPHgBxfy0eni1lGFL6x4ZehG0vJAKjS1E1MO0-6vCw,3807
155
+ tests/test_connectors/test_terraform.py,sha256=Z5MhgDeRDFumu-GlbjMD0ZRkecwBIPP8C8ZVg-mq7C8,3743
155
156
  tests/test_connectors/test_util.py,sha256=hQir0WyjH0LEF6xvIyHNyqdI5pkJX6qUR9287MgO2bY,4647
156
- tests/test_connectors/test_vagrant.py,sha256=A7eHwi2JKjwoKuFQPJZJiCUJ7bdJn9JY2P81Ln3NoIo,3630
157
- pyinfra-3.0b0.dist-info/LICENSE.md,sha256=gwC95tUll0gwB32tHNkTAasN7Sb6vjWzXa305NwClbI,1076
158
- pyinfra-3.0b0.dist-info/METADATA,sha256=Q_w81LJ7bde4NhE8UP2OgkieqFvL_I4FX96e1V2cdTw,8117
159
- pyinfra-3.0b0.dist-info/WHEEL,sha256=P2T-6epvtXQ2cBOE_U1K4_noqlJFN3tj15djMgEu4NM,110
160
- pyinfra-3.0b0.dist-info/entry_points.txt,sha256=BraEFyquy05M8ch33HZXOHoH_m2BTqejL3xX3NrpzOM,471
161
- pyinfra-3.0b0.dist-info/top_level.txt,sha256=2K6D1mK35JTSEBgOfEPV-N-uA2SDErxGiE0J-HUMMVI,26
162
- pyinfra-3.0b0.dist-info/RECORD,,
157
+ tests/test_connectors/test_vagrant.py,sha256=_MBX2b7I-FlEX4rcKeaEcJBSmpCtxxcwJN-7yY_Ivbk,3646
158
+ pyinfra-3.0b1.dist-info/LICENSE.md,sha256=gwC95tUll0gwB32tHNkTAasN7Sb6vjWzXa305NwClbI,1076
159
+ pyinfra-3.0b1.dist-info/METADATA,sha256=w4CVwxaxwspgoqLhaa04KKS3Ge8FcQj8lixIoQ9mUPc,8168
160
+ pyinfra-3.0b1.dist-info/WHEEL,sha256=P2T-6epvtXQ2cBOE_U1K4_noqlJFN3tj15djMgEu4NM,110
161
+ pyinfra-3.0b1.dist-info/entry_points.txt,sha256=BraEFyquy05M8ch33HZXOHoH_m2BTqejL3xX3NrpzOM,471
162
+ pyinfra-3.0b1.dist-info/top_level.txt,sha256=2K6D1mK35JTSEBgOfEPV-N-uA2SDErxGiE0J-HUMMVI,26
163
+ pyinfra-3.0b1.dist-info/RECORD,,
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,6 +1,7 @@
1
1
  import abc
2
2
  import sys
3
3
  from inspect import getframeinfo
4
+ from os import path
4
5
  from traceback import format_exception, format_tb, walk_tb
5
6
  from types import TracebackType
6
7
 
@@ -23,6 +24,10 @@ def get_frame_line_from_tb(tb: TracebackType):
23
24
  info = getframeinfo(frame)
24
25
  if info.filename.startswith(PYINFRA_INSTALL_DIR):
25
26
  continue
27
+ if info.filename.startswith("/"):
28
+ continue
29
+ if not path.exists(info.filename):
30
+ continue
26
31
  return info
27
32
 
28
33
 
pyinfra_cli/main.py CHANGED
@@ -70,6 +70,8 @@ def _print_support(ctx, param, value):
70
70
  is_flag=True,
71
71
  default=False,
72
72
  help="Execute operations immediately on hosts without prompt or checking for changes.",
73
+ envvar="PYINFRA_YES",
74
+ show_envvar=True,
73
75
  )
74
76
  @click.option(
75
77
  "--limit",