pyinfra 3.5.1__py3-none-any.whl → 3.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. pyinfra/api/__init__.py +1 -0
  2. pyinfra/api/arguments.py +9 -2
  3. pyinfra/api/arguments_typed.py +18 -23
  4. pyinfra/api/command.py +9 -3
  5. pyinfra/api/deploy.py +1 -1
  6. pyinfra/api/exceptions.py +12 -0
  7. pyinfra/api/facts.py +20 -4
  8. pyinfra/api/host.py +3 -0
  9. pyinfra/api/inventory.py +2 -2
  10. pyinfra/api/metadata.py +69 -0
  11. pyinfra/api/operation.py +9 -4
  12. pyinfra/api/operations.py +16 -14
  13. pyinfra/api/util.py +22 -5
  14. pyinfra/connectors/docker.py +25 -1
  15. pyinfra/connectors/ssh.py +57 -0
  16. pyinfra/connectors/sshuserclient/client.py +47 -28
  17. pyinfra/connectors/util.py +16 -9
  18. pyinfra/facts/crontab.py +10 -8
  19. pyinfra/facts/files.py +12 -3
  20. pyinfra/facts/flatpak.py +1 -1
  21. pyinfra/facts/npm.py +1 -1
  22. pyinfra/facts/server.py +18 -2
  23. pyinfra/operations/apk.py +2 -1
  24. pyinfra/operations/apt.py +15 -7
  25. pyinfra/operations/brew.py +1 -0
  26. pyinfra/operations/crontab.py +4 -1
  27. pyinfra/operations/dnf.py +4 -1
  28. pyinfra/operations/docker.py +70 -16
  29. pyinfra/operations/files.py +87 -12
  30. pyinfra/operations/flatpak.py +1 -0
  31. pyinfra/operations/gem.py +1 -0
  32. pyinfra/operations/git.py +1 -0
  33. pyinfra/operations/iptables.py +1 -0
  34. pyinfra/operations/lxd.py +1 -0
  35. pyinfra/operations/mysql.py +1 -0
  36. pyinfra/operations/opkg.py +2 -1
  37. pyinfra/operations/pacman.py +1 -0
  38. pyinfra/operations/pip.py +1 -0
  39. pyinfra/operations/pipx.py +1 -0
  40. pyinfra/operations/pkg.py +1 -0
  41. pyinfra/operations/pkgin.py +1 -0
  42. pyinfra/operations/postgres.py +7 -1
  43. pyinfra/operations/puppet.py +1 -0
  44. pyinfra/operations/python.py +1 -0
  45. pyinfra/operations/selinux.py +1 -0
  46. pyinfra/operations/server.py +1 -0
  47. pyinfra/operations/snap.py +2 -1
  48. pyinfra/operations/ssh.py +1 -0
  49. pyinfra/operations/systemd.py +1 -0
  50. pyinfra/operations/sysvinit.py +2 -1
  51. pyinfra/operations/util/docker.py +172 -8
  52. pyinfra/operations/util/packaging.py +2 -0
  53. pyinfra/operations/xbps.py +1 -0
  54. pyinfra/operations/yum.py +4 -1
  55. pyinfra/operations/zfs.py +1 -0
  56. pyinfra/operations/zypper.py +1 -0
  57. {pyinfra-3.5.1.dist-info → pyinfra-3.6.1.dist-info}/METADATA +2 -1
  58. {pyinfra-3.5.1.dist-info → pyinfra-3.6.1.dist-info}/RECORD +64 -63
  59. {pyinfra-3.5.1.dist-info → pyinfra-3.6.1.dist-info}/WHEEL +1 -1
  60. pyinfra_cli/cli.py +20 -4
  61. pyinfra_cli/inventory.py +26 -1
  62. pyinfra_cli/util.py +1 -1
  63. {pyinfra-3.5.1.dist-info → pyinfra-3.6.1.dist-info}/entry_points.txt +0 -0
  64. {pyinfra-3.5.1.dist-info → pyinfra-3.6.1.dist-info}/licenses/LICENSE.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyinfra
3
- Version: 3.5.1
3
+ Version: 3.6.1
4
4
  Summary: pyinfra automates/provisions/manages/deploys infrastructure.
5
5
  Project-URL: homepage, https://pyinfra.com
6
6
  Project-URL: documentation, https://docs.pyinfra.com
@@ -29,6 +29,7 @@ Requires-Dist: gevent>=1.5
29
29
  Requires-Dist: jinja2<4,>3
30
30
  Requires-Dist: packaging>=16.1
31
31
  Requires-Dist: paramiko<4,>=2.7
32
+ Requires-Dist: pydantic<3,>=2.11
32
33
  Requires-Dist: python-dateutil<3,>2
33
34
  Requires-Dist: typeguard<5,>=4
34
35
  Requires-Dist: typing-extensions; python_version < '3.11'
@@ -5,37 +5,38 @@ pyinfra/local.py,sha256=wT84xkJc9UBN5isvIVbNpm2fzZaadwE-dkbAwaFQdZk,2808
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=LZf50PHDzEZv65w0G-iMICoQ9US0U5LWHAOEmNtkF3I,216
8
- pyinfra/api/__init__.py,sha256=suGbKKM-qCduuXFYBEcyswlTqozewtYpdLRhK63PVn0,942
9
- pyinfra/api/arguments.py,sha256=pxfizvECzEahbIyPfmVnk9FsQFnOnDIFPhBZvFLEhFg,12231
10
- pyinfra/api/arguments_typed.py,sha256=IZuhpmDfW9CP6ASS5Ie-3Wcnxl6bDNR3egU4Mfhbsb4,2303
11
- pyinfra/api/command.py,sha256=NwF2syxV3zxCbBdHzvJ6ve5G-xwdNTjPHFPwguKVcYs,7741
8
+ pyinfra/api/__init__.py,sha256=89brynFpoKWCE513go2pK2wfbGaU1V1gajX3UMm9LVA,964
9
+ pyinfra/api/arguments.py,sha256=0c_xENyzPlAyD41lXpL5rPbxU8Rny-uWyXgd8izcg9w,12439
10
+ pyinfra/api/arguments_typed.py,sha256=8a3vPKkz28i9Q1Byo3DDJRLL2CuM8dbPGH-12Afh0ZY,2434
11
+ pyinfra/api/command.py,sha256=X-gK2K8oyoHAPu4HE4tI93G57mkY4nGx7GmQZwEgV3M,7949
12
12
  pyinfra/api/config.py,sha256=gVDV-aGh6LYOnHtBaivICrd3RBfjFRWy3-K9sG__eP8,9321
13
13
  pyinfra/api/connect.py,sha256=jkx07iUL29u9pHHKH4WcNtvxwOA4DIbF7ixguFyuFjo,1984
14
14
  pyinfra/api/connectors.py,sha256=nie7JuLxMSC6gqPjmjuCisQ11R-eAQDtMMWF6YbSQ48,659
15
- pyinfra/api/deploy.py,sha256=Upd92oThQN0zhKbKW8vyPvBuoYiEGStuiEy7kNhZ00Y,3167
16
- pyinfra/api/exceptions.py,sha256=cCbUp1qN1QO0d9aAvOAbRgYpLi0vUI5j7ZqSjcD1_P8,1861
17
- pyinfra/api/facts.py,sha256=nybuKLncxHrJ7rHT2JH0Bg7YwHjQWb-fc8ABJ1J9Y4I,9278
18
- pyinfra/api/host.py,sha256=4a1bFR8vX8mUuXRZttXlzp2_ARzrg-xsH7n8uOxaaqQ,14098
19
- pyinfra/api/inventory.py,sha256=i_LBI-Gn5FF-9SVDBH6xefTtvFzjuz12QQiFPGK2TrQ,7864
20
- pyinfra/api/operation.py,sha256=WtZyVwPoh9_AytqcCf_W6sMHhWEfSex9RE54aMBHU5M,17053
21
- pyinfra/api/operations.py,sha256=MedR-5W4BF23p_FMI7o62K72pgE7G1z2scKeC-b3JF0,13677
15
+ pyinfra/api/deploy.py,sha256=xR5VRGkRoax3dBVLX8vn_pS2x9RL0u3IrCWCPeJ_SFQ,3166
16
+ pyinfra/api/exceptions.py,sha256=Nf6QFRzQBLfqb1kmVY0JXwLZ0YAIZE4nxUcxBEgRSqA,2141
17
+ pyinfra/api/facts.py,sha256=u_8M4ijdZnQszdRpIWPTGtZ_fSWt_Zv_jUIq-uJsBAA,9870
18
+ pyinfra/api/host.py,sha256=192rj8fsrHXudfnxzPlYxljXU24pReeWjXtrcCe9Kj4,14214
19
+ pyinfra/api/inventory.py,sha256=tMvnAstPqAGdj8bAxCeH27KxlueUHj7VnBNVBRXqWZM,7859
20
+ pyinfra/api/metadata.py,sha256=73BjwxKKA4mgP7D60K7Z8YIwPC11YN4IXaq26d209BI,1884
21
+ pyinfra/api/operation.py,sha256=Ae_V_8ObPEQntU5_vXbOn2KeMvKTBYO1LSvjJFT2zQ0,17176
22
+ pyinfra/api/operations.py,sha256=kUGpC9ytA7Zaw9cJZ7zFTtLFFuyMqr2PAWaOmyAzeD0,13846
22
23
  pyinfra/api/state.py,sha256=cj-JvxOljeDshWvRpq8AMQxdGaUaht8KyuyR3mEsI-Y,12859
23
- pyinfra/api/util.py,sha256=N13IPSConC5XhJCDtBB5s-PC39B-PPWaujrzY3Pm2a0,12837
24
+ pyinfra/api/util.py,sha256=fwlgiFGFpHPQQ6BVT3SRDDunZBS3fZ7ApTEFuRI6r5M,13276
24
25
  pyinfra/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
26
  pyinfra/connectors/base.py,sha256=0-BKInwTpjbnTakJhMTn_8LUOl81vUmC-q-HzVrwhkw,4703
26
27
  pyinfra/connectors/chroot.py,sha256=dBgruen5vS4j-OEFwF6ew-LPBR4kJEIQw_W5nXqlvVg,6064
27
- pyinfra/connectors/docker.py,sha256=QweBHSE5pRP5UuRp97xIDwr_tduBf88JHpSmgwU5SpM,11930
28
+ pyinfra/connectors/docker.py,sha256=BgSPsiqTY1SxchnSSPsuYNEA8YdWo6KD57h9TIE8YQQ,12679
28
29
  pyinfra/connectors/dockerssh.py,sha256=NGG6hSZ3z66RRKt6T0hnG2jiXFLR4P5uudi1COcGnY0,9021
29
30
  pyinfra/connectors/local.py,sha256=DJMmZiPgeYvZyW0ANvWjCxF3elmDlmolkY0ktTW3rcg,6990
30
- pyinfra/connectors/ssh.py,sha256=qAr_4To6llbj_lW2uVztzNj_aSWP_i-2iAjNN70Wf2E,22572
31
+ pyinfra/connectors/ssh.py,sha256=zESbhrA8Vp1FuzLdaeu21oHaBwpnYfK4VnbIFLo8oUY,24299
31
32
  pyinfra/connectors/ssh_util.py,sha256=CN_5AdTA3RpiWCnXTrRBjez1NsN59hITDzQmXIkZvoE,3683
32
33
  pyinfra/connectors/terraform.py,sha256=j-a2yStBLdw1QLZRVnl_9TanDtdyujyCxBO2Oa00rPM,4289
33
- pyinfra/connectors/util.py,sha256=-Ei6FMIzbVHD7G1R834Tg7RLoNzo-62wUYIkj043MRQ,11780
34
+ pyinfra/connectors/util.py,sha256=XJamDcmPLhTQQIycXUuUovi4herse-ZEI_rJcl-yskE,12029
34
35
  pyinfra/connectors/vagrant.py,sha256=0TT73ks64I4Yl-JSZjMBbpWA3VYBkqqLB-fUS8pS8GY,4813
35
36
  pyinfra/connectors/scp/__init__.py,sha256=jnO-_8GfkKWhsFcDjAxjOkuUT2RbS22b8P_xPrX889U,44
36
37
  pyinfra/connectors/scp/client.py,sha256=l_fPsbgz-7U6Y50ssuKKPFxD_cFoIPtaVXMCYDotbDI,6399
37
38
  pyinfra/connectors/sshuserclient/__init__.py,sha256=Qc4RO2wknSWIiNTwOeQ0y2TeiuKHmyWDW2Dz4MOo9CE,44
38
- pyinfra/connectors/sshuserclient/client.py,sha256=Ei2_mzCMNJopbpvpeLsdSiNb98rxEEy7uCOmpJbfd2o,10506
39
+ pyinfra/connectors/sshuserclient/client.py,sha256=WUmpo2LUOSXucUwVHb3EgLVxQIoCJ7pBFqFiCynjlMI,11069
39
40
  pyinfra/connectors/sshuserclient/config.py,sha256=FZkPrUYXkURZcFUHBGWw9lLC9uiH3DJ0rBYXJePchxw,2774
40
41
  pyinfra/facts/__init__.py,sha256=myTXSOZmAqmU88Fyifn035h9Lr6Gj2mlka_jDcXyKGw,347
41
42
  pyinfra/facts/apk.py,sha256=UEMHzhx2Wx3qq-OcjetWgE2iZ7_EjI-bszLxSN6PJa0,799
@@ -44,13 +45,13 @@ pyinfra/facts/brew.py,sha256=nE6YVc2S9zasyJPZmPR5FMeGKPViZYEcpnnBQlDf1EU,2792
44
45
  pyinfra/facts/bsdinit.py,sha256=SVY4hagjyy1yz8FKWhIbX9fHm5AugvTFl4xQh2FFO74,631
45
46
  pyinfra/facts/cargo.py,sha256=qgOClhwZm4COcncDzOZccCzs67nPBi_x6VGiF2UA0sA,687
46
47
  pyinfra/facts/choco.py,sha256=mpLleSqNqiaGRgyrhgceno2iPB1_1yjn8UJ90pvOZCs,886
47
- pyinfra/facts/crontab.py,sha256=yCpBzBqgXt2BjAGCIttuQ2xKKtuhzg0VQ9WCDV46eV8,5754
48
+ pyinfra/facts/crontab.py,sha256=mm5eHCA0jL0zDflZKUyEk3V1j_opVZLvEezgwEXrucs,5820
48
49
  pyinfra/facts/deb.py,sha256=1dR1puwY5wyyhhYYwaEBLjKU9sIyaNBNBlamVZ2KQg0,2074
49
50
  pyinfra/facts/dnf.py,sha256=wXatfZWVrrdLY7LM-vHKMg8Md1FiwkqHxmgRYbQqw90,1208
50
51
  pyinfra/facts/docker.py,sha256=fqIqMR6HwSYpTUAjhCX8Hk57pcyL6ShIl98H32Ly6HM,3233
51
52
  pyinfra/facts/efibootmgr.py,sha256=JPJSokE_RV9JstEPJRECnqSU-B0JCxmrocY8zBOva7M,3555
52
- pyinfra/facts/files.py,sha256=rZi7e6E3oq5XBzkh375ztHya5fHusrTbU7B3rZDbHrQ,19501
53
- pyinfra/facts/flatpak.py,sha256=ovi3duwTqqwvt5GoDRN7R-PpkvR6sQ1SmgEADcSnkUE,1646
53
+ pyinfra/facts/files.py,sha256=y6aOC8k2UH6421t3NXgc01BfPmcy7pLFdQACJYlHFWE,19798
54
+ pyinfra/facts/flatpak.py,sha256=Fwyaq2YP0SL_ChlGk3cTvujtb7bg1XBdICaEY1dzbBY,1696
54
55
  pyinfra/facts/freebsd.py,sha256=za42Di2M2-hcSTPei1YE6BsJxqapm9jysshs9hKJZaY,2161
55
56
  pyinfra/facts/gem.py,sha256=aX2-vcEqkxUIP0UJ_SVp9bf4B944oyDjsuujjs5q_9w,654
56
57
  pyinfra/facts/git.py,sha256=Zfzpdccsz2InviirJO17EkEFTVNqYQclSlXJIRFkD_s,1699
@@ -60,7 +61,7 @@ pyinfra/facts/iptables.py,sha256=ORRExNnPR5ysymDbkUjeQWt9mzjSI7su4uQfsu3FlJQ,350
60
61
  pyinfra/facts/launchd.py,sha256=Nl4EFbGwlXTj8GNWlS9UMZODHr63bve73xmMeqyf2gc,849
61
62
  pyinfra/facts/lxd.py,sha256=A2LQN5armY_nI6gV-m1j4l2J2_mMZnvVa1X2RntDnDk,548
62
63
  pyinfra/facts/mysql.py,sha256=ZVN6eN0Xetidvq_RAntSCzHgy4jmf8Enrm2mPXxO488,6247
63
- pyinfra/facts/npm.py,sha256=WzZHCfgWwY9WsPPzL0njlazwiBHI0gpvyZV93Nfu428,838
64
+ pyinfra/facts/npm.py,sha256=lbiLHoRMZ4POSjK_S5jbqp7ulrDqT-MIUhrI4uYV7BU,857
64
65
  pyinfra/facts/openrc.py,sha256=wB4fjzgWCgX6wexBm4jlWv4YH6b4z5_tAqQAO1qO9Kg,1614
65
66
  pyinfra/facts/opkg.py,sha256=yTPuzoUyDDn-o7H97lPtyPe-FOkYg5zqkVmfKt9HwY4,7404
66
67
  pyinfra/facts/pacman.py,sha256=SPI3jpzZbq_VnJ0z5q7A2Rw___EHVntOz6M19ErGpmQ,1324
@@ -74,7 +75,7 @@ pyinfra/facts/postgresql.py,sha256=4nusMVvGhtku86KX4O4vjSxh_MamxZy_kmTQvvy0GhE,2
74
75
  pyinfra/facts/rpm.py,sha256=ikuKYiUmjgvPA84qfE-gbq4Iv4AB5cvor1uKU6uHbXQ,2391
75
76
  pyinfra/facts/runit.py,sha256=qok1FTSshiNrN603vjYTKOeM-NIlxwLbwOp-vPbPySo,2131
76
77
  pyinfra/facts/selinux.py,sha256=umVGK_6Iuj4Xbw5vhhbpxdUA4Mzg2Fhy7QmaNflNrp8,4650
77
- pyinfra/facts/server.py,sha256=uafB7XYNT2eJB21XxNip_WrSyaRqe7uzFab5K4DCZqo,23446
78
+ pyinfra/facts/server.py,sha256=mfLHY8R6NxysPr9x_awB1lcxNplgnFFqrYdF30xrgms,23921
78
79
  pyinfra/facts/snap.py,sha256=2-c3z1qpOG7prmKJssLpOXmKo_wwdfROryro6gif2vo,2137
79
80
  pyinfra/facts/systemd.py,sha256=meHXURtnoxeJbmPzWFTwvhjQBZ2NlQCY8Tj-oHTG_dI,4320
80
81
  pyinfra/facts/sysvinit.py,sha256=q1OpHATFJxjLwatcnYRfpTR7_K2c29b4ppmZu-wgC-4,1589
@@ -90,70 +91,70 @@ pyinfra/facts/util/packaging.py,sha256=Bo7QxYO0Eyj4_i8G27aOWUD_Rfw741RhkEBm3dF5O
90
91
  pyinfra/facts/util/units.py,sha256=SNHCisxGwZedCOqO9tfOWJpZ5Stc0Wcg9mZcXoKBY0A,714
91
92
  pyinfra/facts/util/win_files.py,sha256=S_IQ5kJD6ZgkEcVHajgh7BIMolLV-1q1ghIcwAS-E1Q,2561
92
93
  pyinfra/operations/__init__.py,sha256=SOcW337KXIzD_LH-iJJfq14BQcCs5JzwswJ0PIzDgF4,357
93
- pyinfra/operations/apk.py,sha256=_0vOjbSiGx6EWv9rvTmQdGnRZQ_NA_Dyd3QW1cTzFgI,2111
94
- pyinfra/operations/apt.py,sha256=w8rb8_yH4gKrdhDLKfWcziC5XQRXfhcGqNUwVcqrXpk,14352
95
- pyinfra/operations/brew.py,sha256=aghLE4qyuhhRbt6fgSPV6_5fyWgTohA77Dc0gol19UU,5155
94
+ pyinfra/operations/apk.py,sha256=I1tYoPMN3OsIl_TJvmd_G1daqhiynOyK2-O2PxYHlUQ,2169
95
+ pyinfra/operations/apt.py,sha256=BrNbTlw1HRY5ZMOMFF0XCibeC8QsYM6bYlMRPuiUuNo,14767
96
+ pyinfra/operations/brew.py,sha256=o2T3siobQ_1CNDba7OInI2N60ReplRPELxgjEVDcCRg,5199
96
97
  pyinfra/operations/bsdinit.py,sha256=okQUQDr2H8Z-cAdfdbPJiuGujsHLuV5gpuMZ1UlICEM,1648
97
98
  pyinfra/operations/cargo.py,sha256=mXWd6pb0IR6kzJMmPHwXZN-VJ-B_y8AdOFlrRzDQOZI,1104
98
99
  pyinfra/operations/choco.py,sha256=nIj4bWhChOd5DkybpbD-oupaoODgS7lYx6Vrou5ksuc,1547
99
- pyinfra/operations/crontab.py,sha256=4jxNsgmJED7w9w2Rq6Irsa4wMXxH_yPDIjkFlcpXj7E,6552
100
- pyinfra/operations/dnf.py,sha256=3154Rer6dejVB1AK-CqyJhpMVn_djaSDJrVMs62GNcE,5599
101
- pyinfra/operations/docker.py,sha256=p8sG4BpcxSZwzKj4ystVgKmxmaF4GgDlnyJw1LeIsY4,12271
102
- pyinfra/operations/files.py,sha256=E4SQTZZSIihXUWuzp7a3zBp_5gy_Agx9Ag45zrh6pgs,65686
103
- pyinfra/operations/flatpak.py,sha256=QEJpzSXLyMQFk1XPAPHAfJVWcYWHnKA-tQr2hX6sB9o,2319
104
- pyinfra/operations/gem.py,sha256=2C85sOwIRMHGvmPg4uAlUVf6MokhiA7LLPqzdJRHsBg,1132
105
- pyinfra/operations/git.py,sha256=BqYQbG1VRw_XPtagbZHXitzss-U_LNGXRTwHE7L8P6M,13244
106
- pyinfra/operations/iptables.py,sha256=EVav144bK25F5KQcSivBWqIdffdskTcMcUuWaSK1RRE,9338
100
+ pyinfra/operations/crontab.py,sha256=L1U_fBvgXkbfbpzb6OzUBrrY-RuvvPlbW5FqDmAT8rI,6644
101
+ pyinfra/operations/dnf.py,sha256=wMFUoUB679bVydt01N7Sd7Cs16RhAaLca-zsmQU86rk,5727
102
+ pyinfra/operations/docker.py,sha256=vsNm8PVh7_oIi8RmnpHeOekX-1gliNTwvzo9-2zVJY8,14525
103
+ pyinfra/operations/files.py,sha256=jqkYIPn94z4MRqH1eU-ooOJzuQyle8wYiyDvFfXDMPI,68492
104
+ pyinfra/operations/flatpak.py,sha256=Eif5KZkWOVElKF4hL5xOyk_oZEOziHqyyDxGHZ1KPYk,2366
105
+ pyinfra/operations/gem.py,sha256=YtVUKVp1zYPAxy2t1ryw-vgucBVYJASOxhauLOvRj6U,1175
106
+ pyinfra/operations/git.py,sha256=IE41_MGOZ3nc7gtIzVssQDgi1eSoCbK07jm9EniFt54,13287
107
+ pyinfra/operations/iptables.py,sha256=ETdNPFkc5DyydBr7IncxYdR7DBAFQzE4X85AoGZGBZI,9386
107
108
  pyinfra/operations/launchd.py,sha256=6HWvqoQ74idV_NStOEmFXwu0dmTv7YDvFtsK8An2Lu4,1177
108
- pyinfra/operations/lxd.py,sha256=bKm9gsgZaruKYSL7OYFMiou-wGP4BzwIMWzjW4AZYrk,1742
109
- pyinfra/operations/mysql.py,sha256=mmTb8es8OQ9FB7dHpeD1aB3Px9p9Fp3WQEwMkWZ0-R4,19851
109
+ pyinfra/operations/lxd.py,sha256=eTsLOni3LAlq-f4dj4OJiHkLlhhMI7fW1N0M_7ekon4,1785
110
+ pyinfra/operations/mysql.py,sha256=kQmshmia7rNh9pZI3iGk95PG4T0TadChCiDYGy8jbuw,19896
110
111
  pyinfra/operations/npm.py,sha256=bUmfQsClZ2YcHiihiC7k5widIXIi6lbfx_32iyaAKfo,1499
111
112
  pyinfra/operations/openrc.py,sha256=AThQQO7u_pO0M-rQbxkX7EWDuR569smkoPVaQoRoFeE,1834
112
- pyinfra/operations/opkg.py,sha256=xBdmU07MWr-YBKX0EV0GuVrwMy6MOOf7wzYvD42sF_I,2607
113
- pyinfra/operations/pacman.py,sha256=QMjmsBiiw362nhZY0rEDVQL5A32MG3u7GcmX4q4PzfI,1702
114
- pyinfra/operations/pip.py,sha256=Gh1vmrkCNktYXO8bh0IMEqjqhV07J8FYJcLHETZhjcQ,5995
115
- pyinfra/operations/pipx.py,sha256=05AUm3nkkCfoxl0o4V5o9P_qb__0Yfv495dTBq7zkE4,2800
116
- pyinfra/operations/pkg.py,sha256=rORQBbKeb-6gS0LYu0a0VdiWcDZoovcUONCaf6KMdeQ,2298
117
- pyinfra/operations/pkgin.py,sha256=zhUyGzKjnUfGoyHbMoYMbeeMzcsiOUpBz1zIzppigJ0,1992
118
- pyinfra/operations/postgres.py,sha256=hD65hRb8s3h6zlG-9WwT4JsNEXuxJUCY8ZRX61qlvlI,13367
113
+ pyinfra/operations/opkg.py,sha256=ebv-SS0WaHp0dxKF2HnSY6m__vhQYNlh5zzbjgEzK9Q,2648
114
+ pyinfra/operations/pacman.py,sha256=e10D4XUwT0VTtZzBeB1tRomr9pEfun1VvNH1ia5eBhI,1748
115
+ pyinfra/operations/pip.py,sha256=uTfK36_vBNqCXsWMU4iypOLhnhKduJK6f0b9srlMEqg,6038
116
+ pyinfra/operations/pipx.py,sha256=oWcJXKogC43cKNsf625FU4ClIAV6KZA26o2cRoa3avQ,2844
117
+ pyinfra/operations/pkg.py,sha256=m5okKIXU1xIIcNQXQnFKXbL97ZcokmGn-hnruokE7is,2341
118
+ pyinfra/operations/pkgin.py,sha256=6bZyvdjYDqn-0a-r23O_122r1QSjHP8SkJiWZ_k231A,2037
119
+ pyinfra/operations/postgres.py,sha256=FN7wDYgtjqShbzSr-_CKbYY0PSlj2XdVijzaveUYols,13601
119
120
  pyinfra/operations/postgresql.py,sha256=agZjL2W4yxigk9ThIC0V_3wvmcWVdX308aJO24WkN6g,833
120
- pyinfra/operations/puppet.py,sha256=eDe8D9jQbHYQ4_r4-dmEZfMASKQvj36BR8z_h8aDfw8,861
121
- pyinfra/operations/python.py,sha256=u569cdPrPesrmzU09nwIPA3bk6TZ-Qv2QP0lJLcO_bw,2021
121
+ pyinfra/operations/puppet.py,sha256=e9vO6SQnkMoyVWjy3oP08GaXgyIPajoA2QJ4g4ib4-M,907
122
+ pyinfra/operations/python.py,sha256=5IXcywwhwITPRJAs8BEL5H5vSPvk_QFMbhF8Iuexp_s,2067
122
123
  pyinfra/operations/runit.py,sha256=-K0GhORE56J4Gjh7PCriSx9zZI7XJV-cIb-LnnSuKdY,5162
123
- pyinfra/operations/selinux.py,sha256=imZ4dbY4tl0GpBSkUgV983jbDDihWNs_OQkOBulT7FQ,5948
124
- pyinfra/operations/server.py,sha256=HsnNBZtjXq_SPIDacs1owzXbODBZya1idk5Cpp-32kc,31245
125
- pyinfra/operations/snap.py,sha256=a-QtNE4Dlsavqq425TUIwpEJu4oGw8UlLRkdTFyT1F8,3049
126
- pyinfra/operations/ssh.py,sha256=wocoaYDlOhhItItAVQCEfnVowTtkg3AP0hQ3mnpUnl0,5634
127
- pyinfra/operations/systemd.py,sha256=hPHTjASj6N_fRAzLr3DNHnxxIbiiTIIT9UStSxKDkTk,3984
128
- pyinfra/operations/sysvinit.py,sha256=WzzthkmWL46MNNY6LsBZ90e37yPj0w2QyUtEAlGBwqY,4078
124
+ pyinfra/operations/selinux.py,sha256=AZLLpYHBZbpLftUbigM7vjkjEajOQEQsLKc5y9OIpSQ,5995
125
+ pyinfra/operations/server.py,sha256=7CrmzWqTjQkync0y_Wdqt82VlmNn293XmoN720MSUWo,31291
126
+ pyinfra/operations/snap.py,sha256=vMCdH274ToI1Pi3un3qihZMS9UW9fXQD5PzLd7lT49E,3097
127
+ pyinfra/operations/ssh.py,sha256=8KdkzxevejX-PfQ6Lgt5c_sk8TutCxUOl9AbvwKUrlE,5677
128
+ pyinfra/operations/systemd.py,sha256=4geQSsuNNBC4F5S_gZBXLfH2UI0JgZZckQfNFJD2gDY,4031
129
+ pyinfra/operations/sysvinit.py,sha256=FMkjQ_jWxs9UR_QSRrogYMHT7lS4cmkDco-rU3waOWE,4119
129
130
  pyinfra/operations/upstart.py,sha256=pHb9RGnVhT14A_y6OezfOH-lmniKpiyJqpeoOJl0beE,1978
130
131
  pyinfra/operations/vzctl.py,sha256=2u2CDkuDjzHBRQ54HfyfLpLrsbT8U7_05EEjbbhKUiU,3110
131
- pyinfra/operations/xbps.py,sha256=ru3_srMBUyUXGzAsPo7WwoomfM0AeDglFv8CDqB33B0,1508
132
- pyinfra/operations/yum.py,sha256=Ig7AzQy1C7I8XM37lWbw0nI5lzFGMoX30P8FV8-V5uA,5600
133
- pyinfra/operations/zfs.py,sha256=FnhiXreqf5qJBusC31dwrQsEi0MvH4qxzjBayHKFcYY,5283
134
- pyinfra/operations/zypper.py,sha256=z1CWv2uwWBlCLIhHna7U5DojVoKZYoUYpezJ_FM_xK8,5555
132
+ pyinfra/operations/xbps.py,sha256=46t05vAdXj9r_VElMT0mxKTtIgeDKVK54wRB_2bSGCI,1552
133
+ pyinfra/operations/yum.py,sha256=Rls0ypn5_OaSGkpBHy---TLOw0fmvrecTQ8CuDR0VJE,5728
134
+ pyinfra/operations/zfs.py,sha256=1V-T04RN7Goxqj-wQzsqeXfCV5H1hEfys3l362lcRek,5326
135
+ pyinfra/operations/zypper.py,sha256=WEUmuRux7_TOdzeTZA_3I5qtqYPpr0N175qIKbYtI5M,5601
135
136
  pyinfra/operations/freebsd/__init__.py,sha256=PXsCLQG29VhimYw4uwwB2FcDt6CrofOtD3LTHC-ik-8,362
136
137
  pyinfra/operations/freebsd/freebsd_update.py,sha256=lH0wB_i6DkaXQnDPjsDq8ocO1hYHL0v_a1go4exYcR8,1864
137
138
  pyinfra/operations/freebsd/pkg.py,sha256=3AyfI0-_9F4ho47KqZsOMQocwNtTF2q9g0i6TffJVak,4413
138
139
  pyinfra/operations/freebsd/service.py,sha256=1f7nTHELnhs3HBSrMFsmopVgYFMIwB8Se88yneRQ8Rw,3198
139
140
  pyinfra/operations/freebsd/sysrc.py,sha256=eg7u_JsCge_uKq3Ysc_mohUc6qgJrOZStp_B_l2Hav4,2330
140
141
  pyinfra/operations/util/__init__.py,sha256=ZAHjeCXtLo0TIOSfZ9h0Sh5IXXRCspfHs3RR1l8tQCE,366
141
- pyinfra/operations/util/docker.py,sha256=F7YmWIRSDyFaosf9q81nnwHhhIG7ktXOkM4VVOiUXTs,6931
142
+ pyinfra/operations/util/docker.py,sha256=aOL8iEOPlg5LpC1ix37_XbzwEG5V05wz-PhyrsBKWQI,12152
142
143
  pyinfra/operations/util/files.py,sha256=PFJDccNTwXK4tIoFB8ycRj7yD1x7LpSflBy7mPQtJCg,7148
143
- pyinfra/operations/util/packaging.py,sha256=s5lP7lRORirQVDwGRARAatUZvz5lv_WpSSP-qq__2JQ,12034
144
+ pyinfra/operations/util/packaging.py,sha256=RXZgUlWqEBtArK7wJfXE2Ndvl_aP0YjjksxxCnPpexk,12086
144
145
  pyinfra/operations/util/service.py,sha256=kJd1zj4-sAaGIp5Ts7yAJznogWaGr8oQTztwenLAr7Y,1309
145
146
  pyinfra_cli/__init__.py,sha256=G0X7tNdqT45uWuK3aHIKxMdDeCgJ7zHo6vbxoG6zy_8,284
146
- pyinfra_cli/cli.py,sha256=Bpt-mRNmvz0sNNhMAO5J3m0Kg-6M8tkJNMGY4C01ARc,20938
147
+ pyinfra_cli/cli.py,sha256=xD24zgSB1VdOx9F8avD405lj-ASWsTsZ21TC_nYdTkY,21418
147
148
  pyinfra_cli/commands.py,sha256=J-mCJYvDebJ8M7o3HreB2zToa871-xO6_KjVhPLeHho,1832
148
149
  pyinfra_cli/exceptions.py,sha256=RRaOprL7SmVv--FLy4x7fxeTitx9wYI0Y3_h01LfhJA,4901
149
- pyinfra_cli/inventory.py,sha256=JYSixJZKY8GNWlOxh-nGDsAknCdaAktlWAmdg13kvNk,11771
150
+ pyinfra_cli/inventory.py,sha256=tU0qaF5jFlYu0tbs961QLdjHU0wJL3Tr7Sk9TM36Ggw,12648
150
151
  pyinfra_cli/log.py,sha256=mD96MH2owQQ5AsYRw7osCKENdp-E3Wum5IDr6qhSIa4,2268
151
152
  pyinfra_cli/main.py,sha256=1CR3IS-O6BkAzkn7UW6pdKktTmN4Qnt0_jPdkhueRM8,936
152
153
  pyinfra_cli/prints.py,sha256=1h6vgKVRKUxcGz_HdyEEDUvkp-lgiiVGwx3hc9rw24A,10434
153
- pyinfra_cli/util.py,sha256=8KKW5LTHX4ebbwbHqMvLqwjZ11mOHI-xIYn-cZCWltg,6722
154
+ pyinfra_cli/util.py,sha256=P5ULsCweyNc7OkqmQTEplNfzNtNyxhQWfcp2540YeE0,6721
154
155
  pyinfra_cli/virtualenv.py,sha256=wRNxOPcUkbD_Pzuj-Lnrz1KxGmsLlb2ObmCTFrdD-S8,2474
155
- pyinfra-3.5.1.dist-info/METADATA,sha256=vlQV0UOJp4UabXoiD6rlQU6HV1oJ76tj3jklwU3cBPk,5740
156
- pyinfra-3.5.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
157
- pyinfra-3.5.1.dist-info/entry_points.txt,sha256=b1nLI6oVRvkeQDS00xcYGdGl4XVR_3tMbKs6T58-NW4,507
158
- pyinfra-3.5.1.dist-info/licenses/LICENSE.md,sha256=BzCnRYLJv0yb-FJuEd_XOrrQSOEQKzIVo0yHT8taNnM,1076
159
- pyinfra-3.5.1.dist-info/RECORD,,
156
+ pyinfra-3.6.1.dist-info/METADATA,sha256=CbbyXsZMgFh0FnvreQoIElKZRPl-UzFiDupEpWsGMPQ,5773
157
+ pyinfra-3.6.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
158
+ pyinfra-3.6.1.dist-info/entry_points.txt,sha256=b1nLI6oVRvkeQDS00xcYGdGl4XVR_3tMbKs6T58-NW4,507
159
+ pyinfra-3.6.1.dist-info/licenses/LICENSE.md,sha256=BzCnRYLJv0yb-FJuEd_XOrrQSOEQKzIVo0yHT8taNnM,1076
160
+ pyinfra-3.6.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
pyinfra_cli/cli.py CHANGED
@@ -2,6 +2,7 @@ import logging
2
2
  import sys
3
3
  import warnings
4
4
  from fnmatch import fnmatch
5
+ from getpass import getpass
5
6
  from os import chdir as os_chdir, getcwd, path
6
7
  from typing import Iterable, List, Tuple, Union
7
8
 
@@ -116,6 +117,12 @@ CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
116
117
  help="Whether to execute operations with sudo.",
117
118
  )
118
119
  @click.option("--sudo-user", help="Which user to sudo when sudoing.")
120
+ @click.option(
121
+ "--same-sudo-password",
122
+ is_flag=True,
123
+ default=False,
124
+ help="All hosts have the same sudo password, so ask only once.",
125
+ )
119
126
  @click.option(
120
127
  "--use-sudo-password",
121
128
  is_flag=True,
@@ -274,6 +281,7 @@ def _main(
274
281
  ssh_key,
275
282
  ssh_key_password: str,
276
283
  ssh_password: str,
284
+ same_sudo_password: bool,
277
285
  shell_executable,
278
286
  sudo: bool,
279
287
  sudo_user: str,
@@ -326,6 +334,7 @@ def _main(
326
334
  sudo,
327
335
  sudo_user,
328
336
  use_sudo_password,
337
+ same_sudo_password,
329
338
  su_user,
330
339
  parallel,
331
340
  shell_executable,
@@ -568,6 +577,7 @@ def _set_config(
568
577
  sudo,
569
578
  sudo_user,
570
579
  use_sudo_password,
580
+ same_sudo_password,
571
581
  su_user,
572
582
  parallel,
573
583
  shell_executable,
@@ -585,10 +595,6 @@ def _set_config(
585
595
  if path.exists(config_filename):
586
596
  exec_file(config_filename)
587
597
 
588
- # Lock the current config, this allows us to restore this version after
589
- # executing deploy files that may alter them.
590
- config.lock_current_state()
591
-
592
598
  # Arg based config overrides
593
599
  if sudo:
594
600
  config.SUDO = True
@@ -598,6 +604,9 @@ def _set_config(
598
604
  if use_sudo_password:
599
605
  config.USE_SUDO_PASSWORD = use_sudo_password
600
606
 
607
+ if same_sudo_password:
608
+ config.SUDO_PASSWORD = getpass("sudo password: ")
609
+
601
610
  if su_user:
602
611
  config.SU_USER = su_user
603
612
 
@@ -619,6 +628,11 @@ def _set_config(
619
628
  if retry_delay is not None:
620
629
  config.RETRY_DELAY = retry_delay
621
630
 
631
+ # Lock the current config, this allows us to restore this version after
632
+ # executing deploy files that may alter them. This must happen after CLI
633
+ # args are applied so they persist across multiple deploy files.
634
+ config.lock_current_state()
635
+
622
636
  return config
623
637
 
624
638
 
@@ -759,6 +773,8 @@ def _prepare_exec_operations(state, config, operations):
759
773
  def _prepare_deploy_operations(state, config, operations):
760
774
  # Number of "steps" to make = number of files * number of hosts
761
775
  for i, filename in enumerate(operations):
776
+ config.lock_current_state()
777
+
762
778
  _log_styled_msg = click.style(filename, bold=True)
763
779
  logger.info("Loading: {0}".format(_log_styled_msg))
764
780
 
pyinfra_cli/inventory.py CHANGED
@@ -177,8 +177,11 @@ def make_inventory(
177
177
  "nor refers to a python module"
178
178
  )
179
179
  return Inventory.empty()
180
- else:
180
+ elif callable(inventory_func):
181
181
  return make_inventory_from_func(inventory_func, override_data)
182
+ else:
183
+ # The inventory is an iterable (list/tuple) of hosts from a module attribute
184
+ return make_inventory_from_iterable(inventory_func, override_data)
182
185
 
183
186
 
184
187
  def make_inventory_from_func(
@@ -235,6 +238,28 @@ def make_inventory_from_func(
235
238
  )
236
239
 
237
240
 
241
+ def make_inventory_from_iterable(
242
+ hosts: List[HostType],
243
+ override_data: Optional[Dict[Any, Any]] = None,
244
+ ):
245
+ """
246
+ Builds a ``pyinfra.api.Inventory`` from an iterable of hosts loaded from a module attribute.
247
+ """
248
+ logger.warning("Loading inventory via module attribute is in alpha!")
249
+
250
+ if not isinstance(hosts, (list, tuple)):
251
+ raise TypeError(f"Inventory attribute is not a list or tuple: {type(hosts).__name__}")
252
+
253
+ for host in hosts:
254
+ if not isinstance(host, ALLOWED_HOST_TYPES):
255
+ raise TypeError(f"Invalid host in inventory: {host}")
256
+
257
+ return Inventory(
258
+ (list(hosts), {}),
259
+ override_data=override_data,
260
+ )
261
+
262
+
238
263
  def make_inventory_from_files(
239
264
  inventory_filename: str,
240
265
  override_data=None,
pyinfra_cli/util.py CHANGED
@@ -218,7 +218,7 @@ def _parallel_load_hosts(state: "State", callback: Callable, name: str):
218
218
  return e
219
219
 
220
220
  greenlet_to_host = {
221
- state.pool.spawn(load_file, host): host for host in state.inventory.iter_active_hosts()
221
+ state.pool.spawn(load_file, host): host for host in state.inventory.get_active_hosts()
222
222
  }
223
223
 
224
224
  with progress_spinner(greenlet_to_host.values()) as progress: