pyinfra 3.0b4__py2.py3-none-any.whl → 3.0.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. pyinfra/api/facts.py +7 -50
  2. pyinfra/api/util.py +1 -1
  3. pyinfra/connectors/ssh.py +3 -3
  4. pyinfra/connectors/sshuserclient/client.py +1 -1
  5. pyinfra/facts/apk.py +5 -2
  6. pyinfra/facts/apt.py +13 -7
  7. pyinfra/facts/brew.py +26 -13
  8. pyinfra/facts/bsdinit.py +7 -6
  9. pyinfra/facts/cargo.py +4 -3
  10. pyinfra/facts/choco.py +6 -4
  11. pyinfra/facts/deb.py +12 -5
  12. pyinfra/facts/dnf.py +9 -6
  13. pyinfra/facts/docker.py +13 -6
  14. pyinfra/facts/files.py +3 -3
  15. pyinfra/facts/gem.py +5 -2
  16. pyinfra/facts/git.py +14 -21
  17. pyinfra/facts/gpg.py +2 -1
  18. pyinfra/facts/hardware.py +17 -11
  19. pyinfra/facts/launchd.py +5 -2
  20. pyinfra/facts/lxd.py +6 -2
  21. pyinfra/facts/mysql.py +7 -6
  22. pyinfra/facts/npm.py +2 -1
  23. pyinfra/facts/openrc.py +6 -2
  24. pyinfra/facts/pacman.py +7 -3
  25. pyinfra/facts/pkg.py +3 -1
  26. pyinfra/facts/pkgin.py +5 -2
  27. pyinfra/facts/postgres.py +3 -1
  28. pyinfra/facts/rpm.py +12 -9
  29. pyinfra/facts/runit.py +4 -2
  30. pyinfra/facts/selinux.py +12 -4
  31. pyinfra/facts/server.py +80 -51
  32. pyinfra/facts/snap.py +6 -2
  33. pyinfra/facts/systemd.py +10 -5
  34. pyinfra/facts/sysvinit.py +2 -1
  35. pyinfra/facts/upstart.py +5 -2
  36. pyinfra/facts/vzctl.py +6 -4
  37. pyinfra/facts/xbps.py +5 -2
  38. pyinfra/facts/yum.py +8 -5
  39. pyinfra/facts/zypper.py +7 -4
  40. pyinfra/operations/apt.py +5 -0
  41. pyinfra/operations/selinux.py +1 -1
  42. pyinfra/operations/server.py +1 -1
  43. {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/METADATA +1 -5
  44. {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/RECORD +54 -53
  45. pyinfra_cli/__main__.py +2 -3
  46. pyinfra_cli/inventory.py +13 -11
  47. pyinfra_cli/main.py +10 -9
  48. tests/test_api/test_api_facts.py +2 -2
  49. tests/test_cli/test_cli.py +0 -1
  50. tests/test_cli/test_cli_inventory.py +66 -0
  51. {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/LICENSE.md +0 -0
  52. {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/WHEEL +0 -0
  53. {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/entry_points.txt +0 -0
  54. {pyinfra-3.0b4.dist-info → pyinfra-3.0.1.dist-info}/top_level.txt +0 -0
pyinfra/facts/vzctl.py CHANGED
@@ -20,13 +20,15 @@ class OpenvzContainers(FactBase):
20
20
  }
21
21
  """
22
22
 
23
- command = "vzlist -a -j"
24
- requires_command = "vzlist"
23
+ def command(self) -> str:
24
+ return "vzlist -a -j"
25
+
26
+ def requires_command(self) -> str:
27
+ return "vzlist"
25
28
 
26
29
  default = dict
27
30
 
28
- @staticmethod
29
- def process(output):
31
+ def process(self, output):
30
32
  combined_json = "".join(output)
31
33
  vz_data = json.loads(combined_json)
32
34
 
pyinfra/facts/xbps.py CHANGED
@@ -16,12 +16,15 @@ class XbpsPackages(FactBase):
16
16
  }
17
17
  """
18
18
 
19
- command = "xbps-query -l"
20
- requires_command = "xbps-query"
19
+ def requires_command(self) -> str:
20
+ return "xbps-query"
21
21
 
22
22
  default = dict
23
23
 
24
24
  regex = r"^.. ([a-zA-Z0-9_\-\+]+)\-([0-9a-z_\.]+)"
25
25
 
26
+ def command(self):
27
+ return "xbps-query -l"
28
+
26
29
  def process(self, output):
27
30
  return parse_packages(self.regex, output)
pyinfra/facts/yum.py CHANGED
@@ -23,11 +23,14 @@ class YumRepositories(FactBase):
23
23
  ]
24
24
  """
25
25
 
26
- command = make_cat_files_command(
27
- "/etc/yum.conf",
28
- "/etc/yum.repos.d/*.repo",
29
- )
30
- requires_command = "yum"
26
+ def command(self) -> str:
27
+ return make_cat_files_command(
28
+ "/etc/yum.conf",
29
+ "/etc/yum.repos.d/*.repo",
30
+ )
31
+
32
+ def requires_command(self) -> str:
33
+ return "yum"
31
34
 
32
35
  default = list
33
36
 
pyinfra/facts/zypper.py CHANGED
@@ -23,10 +23,13 @@ class ZypperRepositories(FactBase):
23
23
  ]
24
24
  """
25
25
 
26
- command = make_cat_files_command(
27
- "/etc/zypp/repos.d/*.repo",
28
- )
29
- requires_command = "zypper"
26
+ def command(self) -> str:
27
+ return make_cat_files_command(
28
+ "/etc/zypp/repos.d/*.repo",
29
+ )
30
+
31
+ def requires_command(self) -> str:
32
+ return "zypper"
30
33
 
31
34
  default = list
32
35
 
pyinfra/operations/apt.py CHANGED
@@ -50,6 +50,11 @@ def key(src: str | None = None, keyserver: str | None = None, keyid: str | list[
50
50
  keyserver/id:
51
51
  These must be provided together.
52
52
 
53
+ .. warning::
54
+ ``apt-key`` is deprecated in Debian, it is recommended NOT to use this
55
+ operation and instead follow the instructions here:
56
+ https://wiki.debian.org/DebianRepository/UseThirdParty
57
+
53
58
  **Examples:**
54
59
 
55
60
  .. code:: python
@@ -163,7 +163,7 @@ def port(protocol: Protocol | str, port_num: int, se_type: str | None = None, pr
163
163
  raise ValueError("se_type must have a valid value if present is set")
164
164
 
165
165
  new_type = se_type if present else ""
166
- direct_get = len(host.get_fact(Which, command=SEPort.requires_command) or "") > 0
166
+ direct_get = len(host.get_fact(Which, command="sepolicy") or "") > 0
167
167
  if direct_get:
168
168
  current = host.get_fact(SEPort, protocol=protocol, port=port_num)
169
169
  else:
@@ -568,7 +568,7 @@ def packages(
568
568
  elif host.get_fact(Which, command="pacman"):
569
569
  package_operation = pacman.packages
570
570
 
571
- elif host.get_fact(Which, command="xbps"):
571
+ elif host.get_fact(Which, command="xbps-install") or host.get_fact(Which, command="xbps"):
572
572
  package_operation = xbps.packages
573
573
 
574
574
  elif host.get_fact(Which, command="yum"):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyinfra
3
- Version: 3.0b4
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
@@ -92,10 +92,6 @@ Requires-Dist: types-setuptools ; extra == 'test'
92
92
  </a>
93
93
  </p>
94
94
 
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
95
  <p>
100
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.
101
97
  </p>
@@ -14,73 +14,73 @@ pyinfra/api/connect.py,sha256=Z9wusMLR_jBkKKk5D4AUOj8LHl3H5MsNO5FxAeR4jac,1416
14
14
  pyinfra/api/connectors.py,sha256=nie7JuLxMSC6gqPjmjuCisQ11R-eAQDtMMWF6YbSQ48,659
15
15
  pyinfra/api/deploy.py,sha256=xo4F7URUf3xzIChRHZn4zwqs_WTjLjZNC9i9eQjAFk8,2756
16
16
  pyinfra/api/exceptions.py,sha256=cCbUp1qN1QO0d9aAvOAbRgYpLi0vUI5j7ZqSjcD1_P8,1861
17
- pyinfra/api/facts.py,sha256=L_Wsrdq-u0zR69klnXWZ_2j9H7m3Oto53X0bQf670X8,10574
17
+ pyinfra/api/facts.py,sha256=aMPtkB7vypyXRQDThjwJZzAnEgqjP0wrwyEhRHQf4Js,9449
18
18
  pyinfra/api/host.py,sha256=3lRhlZDRKvCNvpziaTglExy2Ep1wd4YdmGDNY4emAdA,13466
19
19
  pyinfra/api/inventory.py,sha256=nPITdNEJ7q71adIqS_OKHsMjD7amUuHEuTl6xzgh1Gk,7734
20
20
  pyinfra/api/operation.py,sha256=pB0LpjUqbMLGtoDnsckNw0FRoeo1BopL0fnXVDM1JyU,15112
21
21
  pyinfra/api/operations.py,sha256=jvz9ISfwmQnAQVUKLnbrRdD9QHIAAfypo9l5b3fYG1w,10894
22
22
  pyinfra/api/state.py,sha256=3dXRjeZJXnzLcbP9E4aogkRPwIg3_kK1h4Tf4FVZock,12622
23
- pyinfra/api/util.py,sha256=vesFOxExETb-B-oAhWpJJrmALTubg3fkFqi0gYd0pJs,12265
23
+ pyinfra/api/util.py,sha256=qbrC-Hjvzre2_U0l3hHo4wzZBDFN-zcWBNoWQgIyXxE,12272
24
24
  pyinfra/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  pyinfra/connectors/base.py,sha256=2fASiV-MvpXgcZAFLM_PUwYx5ax6EHai44ri_oEKeSE,3732
26
26
  pyinfra/connectors/chroot.py,sha256=Xd72I8T58KIwKOoc0LXCw91AoEIaiHfRLDcDVTHGJ0o,5931
27
27
  pyinfra/connectors/docker.py,sha256=2UNHhXS4hpLo7I19ixDeSd7JR8SNo43VgqsaUIZQZJ4,8741
28
28
  pyinfra/connectors/dockerssh.py,sha256=VWHY--jqs3yf-RuPUZXav4vLeON9SzoVC9CUyOJo1rg,8919
29
29
  pyinfra/connectors/local.py,sha256=vYOBQS_5rf-dVaPeG4dJlLwBHqkxAzLjj3aDEgbAsx8,6900
30
- pyinfra/connectors/ssh.py,sha256=kUtp86GlIteM_bqXtoPtdQE1--AmxzAtBOXv5oK0IOI,21136
30
+ pyinfra/connectors/ssh.py,sha256=QvXrmg3G47VwGEiPP-8Nse-9Yostc5N4PxwiiSlhlwo,21124
31
31
  pyinfra/connectors/ssh_util.py,sha256=CN_5AdTA3RpiWCnXTrRBjez1NsN59hITDzQmXIkZvoE,3683
32
32
  pyinfra/connectors/terraform.py,sha256=G7lK168Fz0jNFetc_7_bPT-RnoaRDksJat0R26fqkUk,3617
33
33
  pyinfra/connectors/util.py,sha256=0bvoMsGMD-Tbfaer8NUhWJjBnaNKdmE83PDg48BYjcU,11374
34
34
  pyinfra/connectors/vagrant.py,sha256=oEeRglzRmemRXW3vilsp_Xg9qnZMRprRJO9fd_C-f5M,4759
35
35
  pyinfra/connectors/sshuserclient/__init__.py,sha256=Qc4RO2wknSWIiNTwOeQ0y2TeiuKHmyWDW2Dz4MOo9CE,44
36
- pyinfra/connectors/sshuserclient/client.py,sha256=7YSd3QckZuPDRnKzy2FfG3J8zp7CY-jny8tbWwxvKro,9720
36
+ pyinfra/connectors/sshuserclient/client.py,sha256=24KWAAqIaUPQIod-CSeXKkA_WhQnIIGWaLKlnVUATDY,9746
37
37
  pyinfra/connectors/sshuserclient/config.py,sha256=UMwkvTgAIS7__re6Wz_pwH6EU4kO1-uMQ5zuFakH0v4,2721
38
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
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
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
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
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
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
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
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
77
  pyinfra/facts/util/__init__.py,sha256=f7HKu8z9_yFC899ajJ3RFiyivioaZeGfOI6nf9GviCs,521
78
78
  pyinfra/facts/util/databases.py,sha256=EphGQApzRBXI2nG1FL9h8bozY-o4SgdQgpv9YcnCkxs,730
79
79
  pyinfra/facts/util/packaging.py,sha256=4RzjDYb3HrRWZuuPlEfYHgbftLH4r1FOccN5QyIGkrk,1181
80
80
  pyinfra/facts/util/win_files.py,sha256=S_IQ5kJD6ZgkEcVHajgh7BIMolLV-1q1ghIcwAS-E1Q,2561
81
81
  pyinfra/operations/__init__.py,sha256=SOcW337KXIzD_LH-iJJfq14BQcCs5JzwswJ0PIzDgF4,357
82
82
  pyinfra/operations/apk.py,sha256=_0vOjbSiGx6EWv9rvTmQdGnRZQ_NA_Dyd3QW1cTzFgI,2111
83
- pyinfra/operations/apt.py,sha256=TGNO-ovc24v0T5pBzweB68Z3Hd_130sauGsmNzcXyJI,13663
83
+ pyinfra/operations/apt.py,sha256=YAVZXzCE5zvPQb6FMTcQVVKhdKHUKkV8Ra6fRhD8rYA,13887
84
84
  pyinfra/operations/brew.py,sha256=aghLE4qyuhhRbt6fgSPV6_5fyWgTohA77Dc0gol19UU,5155
85
85
  pyinfra/operations/bsdinit.py,sha256=okQUQDr2H8Z-cAdfdbPJiuGujsHLuV5gpuMZ1UlICEM,1648
86
86
  pyinfra/operations/cargo.py,sha256=mXWd6pb0IR6kzJMmPHwXZN-VJ-B_y8AdOFlrRzDQOZI,1104
@@ -105,8 +105,8 @@ pyinfra/operations/postgresql.py,sha256=agZjL2W4yxigk9ThIC0V_3wvmcWVdX308aJO24Wk
105
105
  pyinfra/operations/puppet.py,sha256=eDe8D9jQbHYQ4_r4-dmEZfMASKQvj36BR8z_h8aDfw8,861
106
106
  pyinfra/operations/python.py,sha256=u569cdPrPesrmzU09nwIPA3bk6TZ-Qv2QP0lJLcO_bw,2021
107
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
108
+ pyinfra/operations/selinux.py,sha256=imZ4dbY4tl0GpBSkUgV983jbDDihWNs_OQkOBulT7FQ,5948
109
+ pyinfra/operations/server.py,sha256=cjQRZMYkSNKDwlKpTSj3iuJO3mNre0jR4R3MTIS_xIk,36462
110
110
  pyinfra/operations/snap.py,sha256=a-QtNE4Dlsavqq425TUIwpEJu4oGw8UlLRkdTFyT1F8,3049
111
111
  pyinfra/operations/ssh.py,sha256=wocoaYDlOhhItItAVQCEfnVowTtkg3AP0hQ3mnpUnl0,5634
112
112
  pyinfra/operations/systemd.py,sha256=hPHTjASj6N_fRAzLr3DNHnxxIbiiTIIT9UStSxKDkTk,3984
@@ -122,12 +122,12 @@ pyinfra/operations/util/files.py,sha256=Zcet3ydNVbdT9jss0BDm6RJFyR_s6XTr0isDR60Z
122
122
  pyinfra/operations/util/packaging.py,sha256=xFtOlEX46ms7g3gDvOOInRVR1RVfgsmhLzFzsJAL_eU,9381
123
123
  pyinfra/operations/util/service.py,sha256=kJd1zj4-sAaGIp5Ts7yAJznogWaGr8oQTztwenLAr7Y,1309
124
124
  pyinfra_cli/__init__.py,sha256=G0X7tNdqT45uWuK3aHIKxMdDeCgJ7zHo6vbxoG6zy_8,284
125
- pyinfra_cli/__main__.py,sha256=8tjq8HUll8P8naFw7pGlygwSz7u9je_MQ-0pqcDlENY,881
125
+ pyinfra_cli/__main__.py,sha256=WlW7eP0rrL06eguuD_q2RAqgUjg3SW-QnmrayAh2mBQ,887
126
126
  pyinfra_cli/commands.py,sha256=J-mCJYvDebJ8M7o3HreB2zToa871-xO6_KjVhPLeHho,1832
127
127
  pyinfra_cli/exceptions.py,sha256=iptx9Zj1od7VgSbOyXs7P8tD4zAZ_fwrQFKPlpPrfS0,4806
128
- pyinfra_cli/inventory.py,sha256=lggXV9blVqNDT2lgVkq9FQWqYBPOakoLYLbuuVQ8upE,10179
128
+ pyinfra_cli/inventory.py,sha256=S8aSl8TrF72Ni7eHiB40GjtAJeqyB1VxHobG2k254hQ,10329
129
129
  pyinfra_cli/log.py,sha256=7WEGtmf3ncF1BtXL2icUjyxeRKy-7XrCcQ2Hg4GWX5Y,2201
130
- pyinfra_cli/main.py,sha256=MsBn0RCD5ce4GY-dDBe6vLXT0LanDrrQZpJOTIYZPBs,19715
130
+ pyinfra_cli/main.py,sha256=PjZ1Fe3jlodvBsnY-xXU8ASJim2ocU6j6ICQzsoXhRU,19922
131
131
  pyinfra_cli/prints.py,sha256=za6V-yjXf-LViBW73qWcyfsajCUnf0NCG-7K0ugOA0k,9170
132
132
  pyinfra_cli/util.py,sha256=f3iGIPxlUiQJ5LmUGYbEz0QrySQAKmf9xov9WvHXbrk,6364
133
133
  pyinfra_cli/virtualenv.py,sha256=6j9W54JkQLN02SrZZIVwszp0GxlaaDEUWFZjBDHIWNA,2466
@@ -137,15 +137,16 @@ tests/test_api/test_api_arguments.py,sha256=5k7w0_x5cnABEFOk0LQBCt5gU9iTN9lo2XS6
137
137
  tests/test_api/test_api_command.py,sha256=OW0ESMyS5vo38u17DHeCrSIaIkW9gMU5PSkXL7mRrq0,3204
138
138
  tests/test_api/test_api_config.py,sha256=bf0mDrUie3On6zGC_hJBpv-wvSf3LHBIBzUDvkopEt0,708
139
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
140
+ tests/test_api/test_api_facts.py,sha256=WnKwgLq7sk2LNO5IgIZbO5HRkDr-2GdUWO_EFfTjhO8,10695
141
141
  tests/test_api/test_api_host.py,sha256=U_VW2vTl35vR8EdyIGMKr4y0ydsDLbvHSjZDa99CyNE,1119
142
142
  tests/test_api/test_api_inventory.py,sha256=VLbV0MXdRLOPvTXJF156ne6rAx1cBlFfgq_1S79s4tw,2013
143
143
  tests/test_api/test_api_operations.py,sha256=GUfnuHK2NoTAGdOT4AbytT9R8i3ZZIvGP7KBfoYcYUQ,20134
144
144
  tests/test_api/test_api_util.py,sha256=uHv4oLpoy1_tzOoqFA1zpdvC74SvjitZbxQwp0dmjTs,1716
145
145
  tests/test_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
- tests/test_cli/test_cli.py,sha256=nZQH0zK1SOgIr5VxBuuHH68hyzG4lhwyw_Z7EhjPtf4,6045
146
+ tests/test_cli/test_cli.py,sha256=IeWuhkhLzIkRbOEx5-yaW6xV5l4Y8fxaGaDGlMcOyYE,6016
147
147
  tests/test_cli/test_cli_deploy.py,sha256=KBnnDsiD21h7t1S2JXpEDpiMxh0AFqwxaEl0z78IE9E,4858
148
148
  tests/test_cli/test_cli_exceptions.py,sha256=02sjC6rMptuqchgcdjdsVNQbSQYW6HwGutSy6Q6sMs4,3088
149
+ tests/test_cli/test_cli_inventory.py,sha256=xlo-p3HdfVPNqxi7SknEZ2mWrKsdDaK3PoVN-tl95Z0,2394
149
150
  tests/test_cli/test_cli_util.py,sha256=-Ehnj0cO-EkF-6KLxcPPcFeuAUMTz-fKITrxhuiYhV4,2562
150
151
  tests/test_cli/test_context_objects.py,sha256=JiUTwQP7yvcqA47Kq9jtdsB_Z8nxGMZN46d9pR--FYA,2130
151
152
  tests/test_cli/util.py,sha256=kp_-XsGnTyDgG6IHWorYzl5VD_WLe77dKOH007TDOUE,338
@@ -159,9 +160,9 @@ tests/test_connectors/test_sshuserclient.py,sha256=2PQNLPhNL6lBACc6tQuXmPoog-9L6
159
160
  tests/test_connectors/test_terraform.py,sha256=Z5MhgDeRDFumu-GlbjMD0ZRkecwBIPP8C8ZVg-mq7C8,3743
160
161
  tests/test_connectors/test_util.py,sha256=hQir0WyjH0LEF6xvIyHNyqdI5pkJX6qUR9287MgO2bY,4647
161
162
  tests/test_connectors/test_vagrant.py,sha256=27qRB7ftjEPaj4ejBNZ-rR4Ou1AD1VyVcf2XjwZPG3M,3640
162
- pyinfra-3.0b4.dist-info/LICENSE.md,sha256=gwC95tUll0gwB32tHNkTAasN7Sb6vjWzXa305NwClbI,1076
163
- pyinfra-3.0b4.dist-info/METADATA,sha256=L9PyC6qdNCq30gCNvpPpl41jLlqacs9n-IlbHHO-lwc,8322
164
- pyinfra-3.0b4.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
165
- pyinfra-3.0b4.dist-info/entry_points.txt,sha256=BraEFyquy05M8ch33HZXOHoH_m2BTqejL3xX3NrpzOM,471
166
- pyinfra-3.0b4.dist-info/top_level.txt,sha256=2K6D1mK35JTSEBgOfEPV-N-uA2SDErxGiE0J-HUMMVI,26
167
- pyinfra-3.0b4.dist-info/RECORD,,
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,,
pyinfra_cli/__main__.py CHANGED
@@ -1,4 +1,3 @@
1
- import os
2
1
  import signal
3
2
  import sys
4
3
 
@@ -21,8 +20,8 @@ sys.path.append(".")
21
20
  click.disable_unicode_literals_warning = True # type: ignore
22
21
 
23
22
  # Force line buffering
24
- sys.stdout = os.fdopen(sys.stdout.fileno(), "w", 1)
25
- 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
26
25
 
27
26
 
28
27
  def _handle_interrupt(signum, frame):
pyinfra_cli/inventory.py CHANGED
@@ -36,32 +36,33 @@ def _is_inventory_group(key: str, value: Any):
36
36
  return all(isinstance(item, ALLOWED_HOST_TYPES) for item in value)
37
37
 
38
38
 
39
- def _get_group_data(dirname: str):
39
+ def _get_group_data(dirname_or_filename: str):
40
40
  group_data = {}
41
- group_data_directory = path.join(dirname, "group_data")
42
41
 
43
- logger.debug("Checking possible group_data directory: %s", dirname)
42
+ logger.debug("Checking possible group_data at: %s", dirname_or_filename)
44
43
 
45
- if path.exists(group_data_directory):
46
- files = listdir(group_data_directory)
44
+ if path.exists(dirname_or_filename):
45
+ if path.isfile(dirname_or_filename):
46
+ files = [dirname_or_filename]
47
+ else:
48
+ files = [path.join(dirname_or_filename, file) for file in listdir(dirname_or_filename)]
47
49
 
48
50
  for file in files:
49
51
  if not file.endswith(".py"):
50
52
  continue
51
53
 
52
- group_data_file = path.join(group_data_directory, file)
53
54
  group_name = path.basename(file)[:-3]
54
55
 
55
- logger.debug("Looking for group data in: %s", group_data_file)
56
+ logger.debug("Looking for group data in: %s", file)
56
57
 
57
58
  # Read the files locals into a dict
58
- attrs = exec_file(group_data_file, return_locals=True)
59
+ attrs = exec_file(file, return_locals=True)
59
60
  keys = attrs.get("__all__", attrs.keys())
60
61
 
61
62
  group_data[group_name] = {
62
63
  key: value
63
64
  for key, value in attrs.items()
64
- if key in keys and not key.startswith("_")
65
+ if key in keys and not key.startswith("__")
65
66
  }
66
67
 
67
68
  return group_data
@@ -255,10 +256,10 @@ def make_inventory_from_files(
255
256
 
256
257
  possible_group_data_folders = []
257
258
  if cwd:
258
- possible_group_data_folders.append(cwd)
259
+ possible_group_data_folders.append(path.join(cwd, "group_data"))
259
260
  inventory_dirname = path.abspath(path.dirname(inventory_filename))
260
261
  if inventory_dirname != cwd:
261
- possible_group_data_folders.append(inventory_dirname)
262
+ possible_group_data_folders.append(path.join(inventory_dirname, "group_data"))
262
263
 
263
264
  if group_data_directories:
264
265
  possible_group_data_folders.extend(group_data_directories)
@@ -269,6 +270,7 @@ def make_inventory_from_files(
269
270
  for folder in possible_group_data_folders:
270
271
  for group_name, data in _get_group_data(folder).items():
271
272
  group_data[group_name].update(data)
273
+ logger.debug("Adding data to group %s: %r", group_name, data)
272
274
 
273
275
  # For each group load up any data
274
276
  for name, hosts in groups.items():
pyinfra_cli/main.py CHANGED
@@ -150,12 +150,6 @@ def _print_support(ctx, param, value):
150
150
  help="Print useful information for support and exit.",
151
151
  )
152
152
  # Debug args
153
- @click.option(
154
- "--quiet",
155
- is_flag=True,
156
- default=False,
157
- help="Hide most pyinfra output.",
158
- )
159
153
  @click.option(
160
154
  "--debug",
161
155
  is_flag=True,
@@ -274,7 +268,6 @@ def _main(
274
268
  limit: Iterable,
275
269
  no_wait: bool,
276
270
  serial: bool,
277
- quiet: bool,
278
271
  debug: bool,
279
272
  debug_all: bool,
280
273
  debug_facts: bool,
@@ -297,7 +290,7 @@ def _main(
297
290
 
298
291
  # Setup state, config & inventory
299
292
  #
300
- state = _setup_state(verbosity, quiet, yes)
293
+ state = _setup_state(verbosity, yes)
301
294
  config = Config()
302
295
  ctx_config.set(config)
303
296
 
@@ -379,6 +372,14 @@ def _main(
379
372
  if dry:
380
373
  _exit()
381
374
 
375
+ click.echo(
376
+ """
377
+ Detected changes may not include every change pyinfra will execute.
378
+ Hidden side effects of operations may alter behaviour of future operations,
379
+ this will be shown in the results. The remote state will always be updated
380
+ to reflect the state defined by the input operations.""",
381
+ err=True,
382
+ )
382
383
  if (
383
384
  can_diff
384
385
  and not yes
@@ -520,7 +521,7 @@ def _set_verbosity(state, verbosity):
520
521
  return state
521
522
 
522
523
 
523
- def _setup_state(verbosity, quiet, yes):
524
+ def _setup_state(verbosity, yes):
524
525
  cwd = getcwd()
525
526
  if cwd not in sys.path: # ensure cwd is present in sys.path
526
527
  sys.path.append(cwd)
@@ -236,7 +236,7 @@ class TestFactsApi(PatchSSHTestCase):
236
236
 
237
237
  assert fact_data == {host_1: "some-output"}
238
238
  fake_run_command.assert_called_with(
239
- Arch.command,
239
+ Arch().command(),
240
240
  print_input=False,
241
241
  print_output=False,
242
242
  **defaults,
@@ -309,7 +309,7 @@ class TestHostFactsApi(PatchSSHTestCase):
309
309
 
310
310
  assert fact_data == "some-output"
311
311
  fake_run_command.assert_called_with(
312
- Arch.command,
312
+ Arch().command(),
313
313
  print_input=False,
314
314
  print_output=False,
315
315
  **defaults,
@@ -182,7 +182,6 @@ class TestDirectMainExecution(PatchSSHTestCase):
182
182
  no_wait=False,
183
183
  serial=False,
184
184
  shell_executable=None,
185
- quiet=False,
186
185
  data=tuple(),
187
186
  debug=False,
188
187
  debug_facts=False,
@@ -0,0 +1,66 @@
1
+ from os import path
2
+
3
+ from pyinfra import inventory
4
+ from pyinfra.context import ctx_inventory, ctx_state
5
+
6
+ from ..paramiko_util import PatchSSHTestCase
7
+ from .util import run_cli
8
+
9
+
10
+ class TestCliInventory(PatchSSHTestCase):
11
+ def test_load_deploy_group_data(self):
12
+ ctx_state.reset()
13
+ ctx_inventory.reset()
14
+
15
+ hosts = ["somehost", "anotherhost", "someotherhost"]
16
+ result = run_cli(
17
+ "-y",
18
+ ",".join(hosts),
19
+ path.join("tests", "test_cli", "deploy", "deploy.py"),
20
+ f'--chdir={path.join("tests", "test_cli", "deploy")}',
21
+ )
22
+ assert result.exit_code == 0, result.stdout
23
+
24
+ assert inventory.data.get("hello") == "world"
25
+ assert "leftover_data" in inventory.group_data
26
+ assert inventory.group_data["leftover_data"].get("still_parsed") == "never_used"
27
+ assert inventory.group_data["leftover_data"].get("_global_arg") == "gets_parsed"
28
+
29
+ def test_load_group_data(self):
30
+ ctx_state.reset()
31
+ ctx_inventory.reset()
32
+
33
+ hosts = ["somehost", "anotherhost", "someotherhost"]
34
+ result = run_cli(
35
+ "-y",
36
+ ",".join(hosts),
37
+ f'--group-data={path.join("tests", "test_cli", "deploy", "group_data")}',
38
+ "exec",
39
+ "uptime",
40
+ )
41
+ assert result.exit_code == 0, result.stdout
42
+
43
+ assert inventory.data.get("hello") == "world"
44
+ assert "leftover_data" in inventory.group_data
45
+ assert inventory.group_data["leftover_data"].get("still_parsed") == "never_used"
46
+ assert inventory.group_data["leftover_data"].get("_global_arg") == "gets_parsed"
47
+
48
+ def test_load_group_data_file(self):
49
+ ctx_state.reset()
50
+ ctx_inventory.reset()
51
+
52
+ hosts = ["somehost", "anotherhost", "someotherhost"]
53
+ filename = path.join("tests", "test_cli", "deploy", "group_data", "leftover_data.py")
54
+ result = run_cli(
55
+ "-y",
56
+ ",".join(hosts),
57
+ f"--group-data={filename}",
58
+ "exec",
59
+ "uptime",
60
+ )
61
+ assert result.exit_code == 0, result.stdout
62
+
63
+ assert "hello" not in inventory.data
64
+ assert "leftover_data" in inventory.group_data
65
+ assert inventory.group_data["leftover_data"].get("still_parsed") == "never_used"
66
+ assert inventory.group_data["leftover_data"].get("_global_arg") == "gets_parsed"