pyinfra 3.1.1__py2.py3-none-any.whl → 3.3__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyinfra/api/arguments.py +9 -2
- pyinfra/api/arguments_typed.py +4 -5
- pyinfra/api/command.py +22 -3
- pyinfra/api/config.py +5 -2
- pyinfra/api/deploy.py +4 -2
- pyinfra/api/facts.py +3 -0
- pyinfra/api/host.py +15 -7
- pyinfra/api/operation.py +2 -1
- pyinfra/api/state.py +1 -1
- pyinfra/connectors/base.py +34 -8
- pyinfra/connectors/chroot.py +7 -2
- pyinfra/connectors/docker.py +24 -8
- pyinfra/connectors/dockerssh.py +7 -2
- pyinfra/connectors/local.py +7 -2
- pyinfra/connectors/ssh.py +9 -2
- pyinfra/connectors/sshuserclient/client.py +42 -14
- pyinfra/connectors/sshuserclient/config.py +2 -0
- pyinfra/connectors/terraform.py +1 -1
- pyinfra/connectors/util.py +13 -9
- pyinfra/context.py +9 -2
- pyinfra/facts/apk.py +8 -1
- pyinfra/facts/apt.py +68 -0
- pyinfra/facts/brew.py +13 -0
- pyinfra/facts/bsdinit.py +3 -0
- pyinfra/facts/cargo.py +5 -0
- pyinfra/facts/choco.py +6 -0
- pyinfra/facts/crontab.py +195 -0
- pyinfra/facts/deb.py +10 -0
- pyinfra/facts/dnf.py +5 -0
- pyinfra/facts/docker.py +16 -0
- pyinfra/facts/efibootmgr.py +113 -0
- pyinfra/facts/files.py +112 -7
- pyinfra/facts/flatpak.py +7 -0
- pyinfra/facts/freebsd.py +75 -0
- pyinfra/facts/gem.py +5 -0
- pyinfra/facts/git.py +12 -2
- pyinfra/facts/gpg.py +7 -0
- pyinfra/facts/hardware.py +13 -0
- pyinfra/facts/iptables.py +9 -1
- pyinfra/facts/launchd.py +5 -0
- pyinfra/facts/lxd.py +5 -0
- pyinfra/facts/mysql.py +9 -2
- pyinfra/facts/npm.py +5 -0
- pyinfra/facts/openrc.py +8 -0
- pyinfra/facts/opkg.py +245 -0
- pyinfra/facts/pacman.py +9 -1
- pyinfra/facts/pip.py +5 -0
- pyinfra/facts/pipx.py +82 -0
- pyinfra/facts/pkg.py +4 -0
- pyinfra/facts/pkgin.py +5 -0
- pyinfra/facts/podman.py +54 -0
- pyinfra/facts/postgres.py +10 -2
- pyinfra/facts/rpm.py +11 -0
- pyinfra/facts/runit.py +7 -0
- pyinfra/facts/selinux.py +16 -0
- pyinfra/facts/server.py +87 -79
- pyinfra/facts/snap.py +7 -0
- pyinfra/facts/systemd.py +5 -0
- pyinfra/facts/sysvinit.py +4 -0
- pyinfra/facts/upstart.py +5 -0
- pyinfra/facts/util/__init__.py +4 -1
- pyinfra/facts/util/units.py +30 -0
- pyinfra/facts/vzctl.py +5 -0
- pyinfra/facts/xbps.py +6 -1
- pyinfra/facts/yum.py +5 -0
- pyinfra/facts/zfs.py +41 -21
- pyinfra/facts/zypper.py +5 -0
- pyinfra/local.py +3 -2
- pyinfra/operations/apt.py +36 -22
- pyinfra/operations/crontab.py +189 -0
- pyinfra/operations/docker.py +61 -56
- pyinfra/operations/files.py +65 -1
- pyinfra/operations/freebsd/__init__.py +12 -0
- pyinfra/operations/freebsd/freebsd_update.py +70 -0
- pyinfra/operations/freebsd/pkg.py +219 -0
- pyinfra/operations/freebsd/service.py +116 -0
- pyinfra/operations/freebsd/sysrc.py +92 -0
- pyinfra/operations/git.py +23 -7
- pyinfra/operations/opkg.py +88 -0
- pyinfra/operations/pip.py +3 -2
- pyinfra/operations/pipx.py +90 -0
- pyinfra/operations/postgres.py +114 -27
- pyinfra/operations/runit.py +2 -0
- pyinfra/operations/server.py +9 -181
- pyinfra/operations/util/docker.py +44 -22
- pyinfra/operations/zfs.py +3 -3
- {pyinfra-3.1.1.dist-info → pyinfra-3.3.dist-info}/LICENSE.md +1 -1
- {pyinfra-3.1.1.dist-info → pyinfra-3.3.dist-info}/METADATA +25 -25
- pyinfra-3.3.dist-info/RECORD +187 -0
- pyinfra_cli/exceptions.py +5 -0
- pyinfra_cli/inventory.py +26 -9
- pyinfra_cli/log.py +3 -0
- pyinfra_cli/main.py +9 -8
- pyinfra_cli/prints.py +19 -4
- pyinfra_cli/util.py +3 -0
- pyinfra_cli/virtualenv.py +1 -1
- tests/test_cli/test_cli_deploy.py +15 -13
- tests/test_cli/test_cli_inventory.py +53 -0
- tests/test_connectors/test_ssh.py +302 -182
- tests/test_connectors/test_sshuserclient.py +68 -1
- pyinfra-3.1.1.dist-info/RECORD +0 -172
- {pyinfra-3.1.1.dist-info → pyinfra-3.3.dist-info}/WHEEL +0 -0
- {pyinfra-3.1.1.dist-info → pyinfra-3.3.dist-info}/entry_points.txt +0 -0
- {pyinfra-3.1.1.dist-info → pyinfra-3.3.dist-info}/top_level.txt +0 -0
pyinfra/operations/zfs.py
CHANGED
|
@@ -4,7 +4,7 @@ Manage ZFS filesystems.
|
|
|
4
4
|
|
|
5
5
|
from pyinfra import host
|
|
6
6
|
from pyinfra.api import operation
|
|
7
|
-
from pyinfra.facts.zfs import
|
|
7
|
+
from pyinfra.facts.zfs import ZfsDatasets, ZfsSnapshots
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@operation()
|
|
@@ -48,7 +48,7 @@ def dataset(
|
|
|
48
48
|
|
|
49
49
|
properties.update(extra_props)
|
|
50
50
|
|
|
51
|
-
datasets = host.get_fact(
|
|
51
|
+
datasets = host.get_fact(ZfsDatasets)
|
|
52
52
|
|
|
53
53
|
existing_dataset = datasets.get(dataset_name)
|
|
54
54
|
|
|
@@ -103,7 +103,7 @@ def snapshot(snapshot_name, present=True, recursive=False, properties={}, **extr
|
|
|
103
103
|
|
|
104
104
|
"""
|
|
105
105
|
properties.update(extra_props)
|
|
106
|
-
snapshots = host.get_fact(
|
|
106
|
+
snapshots = host.get_fact(ZfsSnapshots)
|
|
107
107
|
|
|
108
108
|
if snapshot_name in snapshots or not present:
|
|
109
109
|
yield from dataset._inner(snapshot_name, present=present, properties=properties)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (C)
|
|
1
|
+
Copyright (C) 2025 Nick Barrett <nick@fizzadar.com>
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
4
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyinfra
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3
|
|
4
4
|
Summary: pyinfra automates/provisions/manages/deploys infrastructure.
|
|
5
5
|
Home-page: https://pyinfra.com
|
|
6
6
|
Author: Nick / Fizzadar
|
|
@@ -16,7 +16,6 @@ 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.8
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.9
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -24,7 +23,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
24
23
|
Classifier: Topic :: System :: Systems Administration
|
|
25
24
|
Classifier: Topic :: System :: Installation/Setup
|
|
26
25
|
Classifier: Topic :: Utilities
|
|
27
|
-
Requires-Python: >=3.
|
|
26
|
+
Requires-Python: >=3.9
|
|
28
27
|
Description-Content-Type: text/markdown
|
|
29
28
|
License-File: LICENSE.md
|
|
30
29
|
Requires-Dist: gevent >=1.5
|
|
@@ -33,7 +32,6 @@ Requires-Dist: click >2
|
|
|
33
32
|
Requires-Dist: jinja2 <4,>2
|
|
34
33
|
Requires-Dist: python-dateutil <3,>2
|
|
35
34
|
Requires-Dist: setuptools
|
|
36
|
-
Requires-Dist: configparser
|
|
37
35
|
Requires-Dist: pywinrm
|
|
38
36
|
Requires-Dist: typeguard
|
|
39
37
|
Requires-Dist: distro <2,>=1.6
|
|
@@ -42,43 +40,45 @@ Requires-Dist: importlib-metadata >=3.6 ; python_version < "3.10"
|
|
|
42
40
|
Requires-Dist: typing-extensions ; python_version < "3.11"
|
|
43
41
|
Requires-Dist: graphlib-backport ; python_version < "3.9"
|
|
44
42
|
Provides-Extra: dev
|
|
45
|
-
Requires-Dist: pytest ==8.
|
|
46
|
-
Requires-Dist: coverage ==7.
|
|
47
|
-
Requires-Dist: pytest-cov ==
|
|
48
|
-
Requires-Dist: black ==
|
|
49
|
-
Requires-Dist: isort ==
|
|
50
|
-
Requires-Dist: flake8 ==7.
|
|
43
|
+
Requires-Dist: pytest ==8.3.5 ; extra == 'dev'
|
|
44
|
+
Requires-Dist: coverage ==7.7.1 ; extra == 'dev'
|
|
45
|
+
Requires-Dist: pytest-cov ==6.0.0 ; extra == 'dev'
|
|
46
|
+
Requires-Dist: black ==25.1.0 ; extra == 'dev'
|
|
47
|
+
Requires-Dist: isort ==6.0.1 ; extra == 'dev'
|
|
48
|
+
Requires-Dist: flake8 ==7.1.2 ; extra == 'dev'
|
|
51
49
|
Requires-Dist: flake8-black ==0.3.6 ; extra == 'dev'
|
|
52
|
-
Requires-Dist: flake8-isort ==6.1.
|
|
50
|
+
Requires-Dist: flake8-isort ==6.1.2 ; extra == 'dev'
|
|
51
|
+
Requires-Dist: pyyaml ==6.0.2 ; extra == 'dev'
|
|
53
52
|
Requires-Dist: mypy ; extra == 'dev'
|
|
54
53
|
Requires-Dist: types-cryptography ; extra == 'dev'
|
|
55
54
|
Requires-Dist: types-paramiko ; extra == 'dev'
|
|
56
55
|
Requires-Dist: types-python-dateutil ; extra == 'dev'
|
|
57
56
|
Requires-Dist: types-PyYAML ; extra == 'dev'
|
|
58
57
|
Requires-Dist: types-setuptools ; extra == 'dev'
|
|
59
|
-
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.
|
|
60
|
-
Requires-Dist: myst-parser ==
|
|
61
|
-
Requires-Dist: sphinx ==
|
|
58
|
+
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.17 ; extra == 'dev'
|
|
59
|
+
Requires-Dist: myst-parser ==4.0.1 ; extra == 'dev'
|
|
60
|
+
Requires-Dist: sphinx ==8.2.3 ; extra == 'dev'
|
|
62
61
|
Requires-Dist: wheel ; extra == 'dev'
|
|
63
62
|
Requires-Dist: twine ; extra == 'dev'
|
|
64
63
|
Requires-Dist: ipython ; extra == 'dev'
|
|
65
64
|
Requires-Dist: ipdb ; extra == 'dev'
|
|
66
65
|
Requires-Dist: ipdbplugin ; extra == 'dev'
|
|
67
|
-
Requires-Dist: flake8-spellcheck ==0.
|
|
66
|
+
Requires-Dist: flake8-spellcheck ==0.28.0 ; extra == 'dev'
|
|
68
67
|
Requires-Dist: redbaron ; extra == 'dev'
|
|
69
68
|
Provides-Extra: docs
|
|
70
|
-
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.
|
|
71
|
-
Requires-Dist: myst-parser ==
|
|
72
|
-
Requires-Dist: sphinx ==
|
|
69
|
+
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.17 ; extra == 'docs'
|
|
70
|
+
Requires-Dist: myst-parser ==4.0.1 ; extra == 'docs'
|
|
71
|
+
Requires-Dist: sphinx ==8.2.3 ; extra == 'docs'
|
|
73
72
|
Provides-Extra: test
|
|
74
|
-
Requires-Dist: pytest ==8.
|
|
75
|
-
Requires-Dist: coverage ==7.
|
|
76
|
-
Requires-Dist: pytest-cov ==
|
|
77
|
-
Requires-Dist: black ==
|
|
78
|
-
Requires-Dist: isort ==
|
|
79
|
-
Requires-Dist: flake8 ==7.
|
|
73
|
+
Requires-Dist: pytest ==8.3.5 ; extra == 'test'
|
|
74
|
+
Requires-Dist: coverage ==7.7.1 ; extra == 'test'
|
|
75
|
+
Requires-Dist: pytest-cov ==6.0.0 ; extra == 'test'
|
|
76
|
+
Requires-Dist: black ==25.1.0 ; extra == 'test'
|
|
77
|
+
Requires-Dist: isort ==6.0.1 ; extra == 'test'
|
|
78
|
+
Requires-Dist: flake8 ==7.1.2 ; extra == 'test'
|
|
80
79
|
Requires-Dist: flake8-black ==0.3.6 ; extra == 'test'
|
|
81
|
-
Requires-Dist: flake8-isort ==6.1.
|
|
80
|
+
Requires-Dist: flake8-isort ==6.1.2 ; extra == 'test'
|
|
81
|
+
Requires-Dist: pyyaml ==6.0.2 ; extra == 'test'
|
|
82
82
|
Requires-Dist: mypy ; extra == 'test'
|
|
83
83
|
Requires-Dist: types-cryptography ; extra == 'test'
|
|
84
84
|
Requires-Dist: types-paramiko ; extra == 'test'
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
pyinfra/__init__.py,sha256=7ZcKHGWk7_nYxsYrbFBB_vJr-J-Ddbc56ZS4sk5ArVw,535
|
|
2
|
+
pyinfra/__main__.py,sha256=aVd00glLz5CMJGXgt1XxbOvC2HluqaowoTOjxgIpBaA,47
|
|
3
|
+
pyinfra/context.py,sha256=CLUKJxvZm3VGtxMp6OlZnhYvZBGevSnJYemSDhQRd6E,3534
|
|
4
|
+
pyinfra/local.py,sha256=wT84xkJc9UBN5isvIVbNpm2fzZaadwE-dkbAwaFQdZk,2808
|
|
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=GdkwOpBOUKCDer6gxXtChKmRD8iDr_1pQMXXv7jzfDw,10266
|
|
10
|
+
pyinfra/api/arguments_typed.py,sha256=IZuhpmDfW9CP6ASS5Ie-3Wcnxl6bDNR3egU4Mfhbsb4,2303
|
|
11
|
+
pyinfra/api/command.py,sha256=NwF2syxV3zxCbBdHzvJ6ve5G-xwdNTjPHFPwguKVcYs,7741
|
|
12
|
+
pyinfra/api/config.py,sha256=LhmMKOoAaawSsrSnl55BBj63oT-U-Wn8nwgbe43kzd0,9113
|
|
13
|
+
pyinfra/api/connect.py,sha256=Z9wusMLR_jBkKKk5D4AUOj8LHl3H5MsNO5FxAeR4jac,1416
|
|
14
|
+
pyinfra/api/connectors.py,sha256=nie7JuLxMSC6gqPjmjuCisQ11R-eAQDtMMWF6YbSQ48,659
|
|
15
|
+
pyinfra/api/deploy.py,sha256=CllKp1QYLseeMStj35waZazB0hUuy3iGvDt7b_lH31M,3138
|
|
16
|
+
pyinfra/api/exceptions.py,sha256=cCbUp1qN1QO0d9aAvOAbRgYpLi0vUI5j7ZqSjcD1_P8,1861
|
|
17
|
+
pyinfra/api/facts.py,sha256=CoUtBfn5_O9oFHqwVEghQftH-Hc2XUBJI8LCEpn0nPc,9516
|
|
18
|
+
pyinfra/api/host.py,sha256=KZr2ZvcCM3asrFkpKL25tQIGCr8lZFKTh1aoC2wIpyE,14002
|
|
19
|
+
pyinfra/api/inventory.py,sha256=nPITdNEJ7q71adIqS_OKHsMjD7amUuHEuTl6xzgh1Gk,7734
|
|
20
|
+
pyinfra/api/operation.py,sha256=tyslPCFmHDGydxf0Sv-QfDq1DzGGul9oOgKCXYEfusM,15194
|
|
21
|
+
pyinfra/api/operations.py,sha256=jvz9ISfwmQnAQVUKLnbrRdD9QHIAAfypo9l5b3fYG1w,10894
|
|
22
|
+
pyinfra/api/state.py,sha256=IqdWT1Uwf_Rd5piqYLrf7y8HsXPs1hY6wCmxoRGqPTE,12630
|
|
23
|
+
pyinfra/api/util.py,sha256=K4aFjGW7KAz2ZQqfRriRqyHMCQFFrX06WPola3epjaE,12410
|
|
24
|
+
pyinfra/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
+
pyinfra/connectors/base.py,sha256=0-BKInwTpjbnTakJhMTn_8LUOl81vUmC-q-HzVrwhkw,4703
|
|
26
|
+
pyinfra/connectors/chroot.py,sha256=sQIM1nOLzyIvv7FsqgAZsZ71jJtWLAQB_uaeB4m4GqE,6007
|
|
27
|
+
pyinfra/connectors/docker.py,sha256=bPbw9g9y5-WreD9drTRbDJ1x-CKuO-hgIDUZxuGc86s,9284
|
|
28
|
+
pyinfra/connectors/dockerssh.py,sha256=sJxnmZ-xG19C9BSw6jx54zJhM3PH5ucmdTCZR2ywbrk,9007
|
|
29
|
+
pyinfra/connectors/local.py,sha256=E57xCdBibo2M0IJQ7o6V5nTeBCCn_Bg6vmhydDhHagI,6976
|
|
30
|
+
pyinfra/connectors/ssh.py,sha256=RF_0R8Vy8MFO8A6Eq-F3VjvZXVVWiN7dXVKaWt_5cww,21328
|
|
31
|
+
pyinfra/connectors/ssh_util.py,sha256=CN_5AdTA3RpiWCnXTrRBjez1NsN59hITDzQmXIkZvoE,3683
|
|
32
|
+
pyinfra/connectors/terraform.py,sha256=92KwojQKQhqRYuX3UE9ANRvj0Diwg3EEi6blTgu_LPk,4235
|
|
33
|
+
pyinfra/connectors/util.py,sha256=Up7kToERfcyjoayY9K6-Xdwjg4-SO2THAy7jzzcznJ8,11651
|
|
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=z4FpWJ9zX3TNdb1SM4g53m5XByADVSyu2A_oPcalj3I,10489
|
|
37
|
+
pyinfra/connectors/sshuserclient/config.py,sha256=FZkPrUYXkURZcFUHBGWw9lLC9uiH3DJ0rBYXJePchxw,2774
|
|
38
|
+
pyinfra/facts/__init__.py,sha256=myTXSOZmAqmU88Fyifn035h9Lr6Gj2mlka_jDcXyKGw,347
|
|
39
|
+
pyinfra/facts/apk.py,sha256=UEMHzhx2Wx3qq-OcjetWgE2iZ7_EjI-bszLxSN6PJa0,799
|
|
40
|
+
pyinfra/facts/apt.py,sha256=RYPqGgdH0QpDIoMNhBY9nKtMu-baQNX4DIYNrsllcLQ,4026
|
|
41
|
+
pyinfra/facts/brew.py,sha256=vkl3tr9U6gyx3UDZzanz3WXmvpZ3HqBpUGUxkxdnjU4,2778
|
|
42
|
+
pyinfra/facts/bsdinit.py,sha256=SVY4hagjyy1yz8FKWhIbX9fHm5AugvTFl4xQh2FFO74,631
|
|
43
|
+
pyinfra/facts/cargo.py,sha256=qgOClhwZm4COcncDzOZccCzs67nPBi_x6VGiF2UA0sA,687
|
|
44
|
+
pyinfra/facts/choco.py,sha256=mpLleSqNqiaGRgyrhgceno2iPB1_1yjn8UJ90pvOZCs,886
|
|
45
|
+
pyinfra/facts/crontab.py,sha256=yCpBzBqgXt2BjAGCIttuQ2xKKtuhzg0VQ9WCDV46eV8,5754
|
|
46
|
+
pyinfra/facts/deb.py,sha256=1dR1puwY5wyyhhYYwaEBLjKU9sIyaNBNBlamVZ2KQg0,2074
|
|
47
|
+
pyinfra/facts/dnf.py,sha256=IFOJWeXMLYxSZEgleOCMZaBIZOzJzklwCmemZIUwDmk,1059
|
|
48
|
+
pyinfra/facts/docker.py,sha256=KCHz0onAHXOtMlF8ljG7AOrDS57ajhE5RJ34qnTT1VA,2626
|
|
49
|
+
pyinfra/facts/efibootmgr.py,sha256=JPJSokE_RV9JstEPJRECnqSU-B0JCxmrocY8zBOva7M,3555
|
|
50
|
+
pyinfra/facts/files.py,sha256=bnu3JSoWRdOR1Uxv9nBn1DbanBeF3kWet_rc-3Aj63s,15363
|
|
51
|
+
pyinfra/facts/flatpak.py,sha256=ovi3duwTqqwvt5GoDRN7R-PpkvR6sQ1SmgEADcSnkUE,1646
|
|
52
|
+
pyinfra/facts/freebsd.py,sha256=z7ZJRK8NV5HL-BfAdQs6pQKLEdrfdv7dVUmmOtVKUbA,2248
|
|
53
|
+
pyinfra/facts/gem.py,sha256=aX2-vcEqkxUIP0UJ_SVp9bf4B944oyDjsuujjs5q_9w,654
|
|
54
|
+
pyinfra/facts/git.py,sha256=os8zA2F8UbdX444VUedfL3zYFN_sKsumMjEo-H3isc4,1485
|
|
55
|
+
pyinfra/facts/gpg.py,sha256=8fvC9AglzmO08SAT_Py6H6G0i73soO1D2cSCbw-O9JA,3923
|
|
56
|
+
pyinfra/facts/hardware.py,sha256=JKyz3gZxSXPcVaMuH7iKHOww5a4kbZTiLIQbNmvkF2Q,12217
|
|
57
|
+
pyinfra/facts/iptables.py,sha256=ORRExNnPR5ysymDbkUjeQWt9mzjSI7su4uQfsu3FlJQ,3506
|
|
58
|
+
pyinfra/facts/launchd.py,sha256=Nl4EFbGwlXTj8GNWlS9UMZODHr63bve73xmMeqyf2gc,849
|
|
59
|
+
pyinfra/facts/lxd.py,sha256=A2LQN5armY_nI6gV-m1j4l2J2_mMZnvVa1X2RntDnDk,548
|
|
60
|
+
pyinfra/facts/mysql.py,sha256=ZVN6eN0Xetidvq_RAntSCzHgy4jmf8Enrm2mPXxO488,6247
|
|
61
|
+
pyinfra/facts/npm.py,sha256=WzZHCfgWwY9WsPPzL0njlazwiBHI0gpvyZV93Nfu428,838
|
|
62
|
+
pyinfra/facts/openrc.py,sha256=wB4fjzgWCgX6wexBm4jlWv4YH6b4z5_tAqQAO1qO9Kg,1614
|
|
63
|
+
pyinfra/facts/opkg.py,sha256=o11yGcox2q5O8K_pvCxPqNywiV2lET9WJrgkeCU0Ahs,7390
|
|
64
|
+
pyinfra/facts/pacman.py,sha256=SPI3jpzZbq_VnJ0z5q7A2Rw___EHVntOz6M19ErGpmQ,1324
|
|
65
|
+
pyinfra/facts/pip.py,sha256=MA2yed2_kVzLNjCulnCJEz4GeQ5dbGVtaAv4Bqm9fLw,820
|
|
66
|
+
pyinfra/facts/pipx.py,sha256=3-oP0yHWvi__RGRlgkQzRKQBMwZN3Ke9A-z8oYB5upM,1854
|
|
67
|
+
pyinfra/facts/pkg.py,sha256=4qcp0iO3TgWL9zvPCXcZDCRwrbWg65Wg8H0OvWqNqJk,588
|
|
68
|
+
pyinfra/facts/pkgin.py,sha256=ErtNMLn-Si6_nA69V1x_dZOX_Y_z5CkkevctXq0Nj-w,662
|
|
69
|
+
pyinfra/facts/podman.py,sha256=ONDyCaWe3k_BLO8ec0_KLHxrVgpUKLpKhuJ2bdrEuuo,1201
|
|
70
|
+
pyinfra/facts/postgres.py,sha256=TPcrYc9IhVFNW_rltc1oFUk4nfF0iWlS4gZMv0w7pXM,4499
|
|
71
|
+
pyinfra/facts/postgresql.py,sha256=4nusMVvGhtku86KX4O4vjSxh_MamxZy_kmTQvvy0GhE,223
|
|
72
|
+
pyinfra/facts/rpm.py,sha256=ikuKYiUmjgvPA84qfE-gbq4Iv4AB5cvor1uKU6uHbXQ,2391
|
|
73
|
+
pyinfra/facts/runit.py,sha256=qok1FTSshiNrN603vjYTKOeM-NIlxwLbwOp-vPbPySo,2131
|
|
74
|
+
pyinfra/facts/selinux.py,sha256=8OylQ3H-huktRS34g5FYwivlp1wb4mKP0EFVf1LtMEE,4679
|
|
75
|
+
pyinfra/facts/server.py,sha256=peaK4q2MGhFoKkQGTJ20rU1P9_YPrLQKNPmmw2VqYbA,19678
|
|
76
|
+
pyinfra/facts/snap.py,sha256=2-c3z1qpOG7prmKJssLpOXmKo_wwdfROryro6gif2vo,2137
|
|
77
|
+
pyinfra/facts/systemd.py,sha256=ua5ACLINcCwXv39gnU6HJuIYhQB896yi6-M6hSuUtsU,4309
|
|
78
|
+
pyinfra/facts/sysvinit.py,sha256=q1OpHATFJxjLwatcnYRfpTR7_K2c29b4ppmZu-wgC-4,1589
|
|
79
|
+
pyinfra/facts/upstart.py,sha256=GcreN0mIM6_qRgqzFaA7PnX45RtbBpvVC00J6bKujyA,717
|
|
80
|
+
pyinfra/facts/vzctl.py,sha256=lUacmyakn2sJ2tD2FDAh1eeX3sxEVq7aRRwWM4QTguQ,760
|
|
81
|
+
pyinfra/facts/xbps.py,sha256=pNpgeITdHoJWhnJ_XFjySJ7H35d9h_v2F7GKqIrxgt0,663
|
|
82
|
+
pyinfra/facts/yum.py,sha256=OE1CJrX0AFOHuOdoPMfZuqUQ8hMLgJPtZGCzC9HH4Ho,1020
|
|
83
|
+
pyinfra/facts/zfs.py,sha256=4cWfTu2_V3Rkku8LfWzwruP_Tu4gJV2ZOrtW3otbP2w,1805
|
|
84
|
+
pyinfra/facts/zypper.py,sha256=RRSGrWAfgyiFVQAesjKpYf6i3M2d2Fagdb69BSF0iEM,955
|
|
85
|
+
pyinfra/facts/util/__init__.py,sha256=FNqUZjHPzJplb6ctHdZCVvmxAeVDQfFYmghC6B5edWQ,573
|
|
86
|
+
pyinfra/facts/util/databases.py,sha256=EphGQApzRBXI2nG1FL9h8bozY-o4SgdQgpv9YcnCkxs,730
|
|
87
|
+
pyinfra/facts/util/packaging.py,sha256=4RzjDYb3HrRWZuuPlEfYHgbftLH4r1FOccN5QyIGkrk,1181
|
|
88
|
+
pyinfra/facts/util/units.py,sha256=SNHCisxGwZedCOqO9tfOWJpZ5Stc0Wcg9mZcXoKBY0A,714
|
|
89
|
+
pyinfra/facts/util/win_files.py,sha256=S_IQ5kJD6ZgkEcVHajgh7BIMolLV-1q1ghIcwAS-E1Q,2561
|
|
90
|
+
pyinfra/operations/__init__.py,sha256=SOcW337KXIzD_LH-iJJfq14BQcCs5JzwswJ0PIzDgF4,357
|
|
91
|
+
pyinfra/operations/apk.py,sha256=_0vOjbSiGx6EWv9rvTmQdGnRZQ_NA_Dyd3QW1cTzFgI,2111
|
|
92
|
+
pyinfra/operations/apt.py,sha256=w8rb8_yH4gKrdhDLKfWcziC5XQRXfhcGqNUwVcqrXpk,14352
|
|
93
|
+
pyinfra/operations/brew.py,sha256=aghLE4qyuhhRbt6fgSPV6_5fyWgTohA77Dc0gol19UU,5155
|
|
94
|
+
pyinfra/operations/bsdinit.py,sha256=okQUQDr2H8Z-cAdfdbPJiuGujsHLuV5gpuMZ1UlICEM,1648
|
|
95
|
+
pyinfra/operations/cargo.py,sha256=mXWd6pb0IR6kzJMmPHwXZN-VJ-B_y8AdOFlrRzDQOZI,1104
|
|
96
|
+
pyinfra/operations/choco.py,sha256=8nG0wc1tZEA0L0HTIjgR00IDiONARokyzHyKj-R3xmo,1515
|
|
97
|
+
pyinfra/operations/crontab.py,sha256=qhYzj9xh-A6p95sJ0i_DDKOIm7WoNgiPjcR43ZB9iv8,6454
|
|
98
|
+
pyinfra/operations/dnf.py,sha256=3154Rer6dejVB1AK-CqyJhpMVn_djaSDJrVMs62GNcE,5599
|
|
99
|
+
pyinfra/operations/docker.py,sha256=lU0AQqfIQYPHniruu770ClQODUSMuPVhFdIKy9gGmbw,8455
|
|
100
|
+
pyinfra/operations/files.py,sha256=Hs_HKU2STE0Byt-fZHdsfcrhM6m82mzAELMA22b_X_c,56215
|
|
101
|
+
pyinfra/operations/flatpak.py,sha256=c2OAyuAvt3alVm9D8W6gCfmk5JFydcZD36gO_OhB8Bc,1891
|
|
102
|
+
pyinfra/operations/gem.py,sha256=2C85sOwIRMHGvmPg4uAlUVf6MokhiA7LLPqzdJRHsBg,1132
|
|
103
|
+
pyinfra/operations/git.py,sha256=ajyusK8rFeU_u3piR3glzJGLhomKF0IuzlbR667eyts,13035
|
|
104
|
+
pyinfra/operations/iptables.py,sha256=brYa4kMhZKFTu24BNds_1b6sOaG94EfqWEoWrScx-Ck,9341
|
|
105
|
+
pyinfra/operations/launchd.py,sha256=6HWvqoQ74idV_NStOEmFXwu0dmTv7YDvFtsK8An2Lu4,1177
|
|
106
|
+
pyinfra/operations/lxd.py,sha256=bKm9gsgZaruKYSL7OYFMiou-wGP4BzwIMWzjW4AZYrk,1742
|
|
107
|
+
pyinfra/operations/mysql.py,sha256=ctm2Z6MaB0mOArCNU4TsJzaXiKXQaa_ahmsC5Vvyi10,19857
|
|
108
|
+
pyinfra/operations/npm.py,sha256=bUmfQsClZ2YcHiihiC7k5widIXIi6lbfx_32iyaAKfo,1499
|
|
109
|
+
pyinfra/operations/openrc.py,sha256=GXFoCHEEKeyQyRvrZcNYx8og4fmgmtzTVAViBzt84TE,1580
|
|
110
|
+
pyinfra/operations/opkg.py,sha256=xBdmU07MWr-YBKX0EV0GuVrwMy6MOOf7wzYvD42sF_I,2607
|
|
111
|
+
pyinfra/operations/pacman.py,sha256=QMjmsBiiw362nhZY0rEDVQL5A32MG3u7GcmX4q4PzfI,1702
|
|
112
|
+
pyinfra/operations/pip.py,sha256=MCmb9FPcyvg6M7lTlRtx2qpXHtyf-SwBVtHqcAkqVzQ,5925
|
|
113
|
+
pyinfra/operations/pipx.py,sha256=PFVXriRIk5gnJXWcFoghsCIVfTy7RvQyvDggjXHALQc,2188
|
|
114
|
+
pyinfra/operations/pkg.py,sha256=rORQBbKeb-6gS0LYu0a0VdiWcDZoovcUONCaf6KMdeQ,2298
|
|
115
|
+
pyinfra/operations/pkgin.py,sha256=zhUyGzKjnUfGoyHbMoYMbeeMzcsiOUpBz1zIzppigJ0,1992
|
|
116
|
+
pyinfra/operations/postgres.py,sha256=hD65hRb8s3h6zlG-9WwT4JsNEXuxJUCY8ZRX61qlvlI,13367
|
|
117
|
+
pyinfra/operations/postgresql.py,sha256=agZjL2W4yxigk9ThIC0V_3wvmcWVdX308aJO24WkN6g,833
|
|
118
|
+
pyinfra/operations/puppet.py,sha256=eDe8D9jQbHYQ4_r4-dmEZfMASKQvj36BR8z_h8aDfw8,861
|
|
119
|
+
pyinfra/operations/python.py,sha256=u569cdPrPesrmzU09nwIPA3bk6TZ-Qv2QP0lJLcO_bw,2021
|
|
120
|
+
pyinfra/operations/runit.py,sha256=-K0GhORE56J4Gjh7PCriSx9zZI7XJV-cIb-LnnSuKdY,5162
|
|
121
|
+
pyinfra/operations/selinux.py,sha256=imZ4dbY4tl0GpBSkUgV983jbDDihWNs_OQkOBulT7FQ,5948
|
|
122
|
+
pyinfra/operations/server.py,sha256=6OkfbEH5jWltXjiQkXoq_82UidHPB551dL6TyxCfzr8,30733
|
|
123
|
+
pyinfra/operations/snap.py,sha256=a-QtNE4Dlsavqq425TUIwpEJu4oGw8UlLRkdTFyT1F8,3049
|
|
124
|
+
pyinfra/operations/ssh.py,sha256=wocoaYDlOhhItItAVQCEfnVowTtkg3AP0hQ3mnpUnl0,5634
|
|
125
|
+
pyinfra/operations/systemd.py,sha256=hPHTjASj6N_fRAzLr3DNHnxxIbiiTIIT9UStSxKDkTk,3984
|
|
126
|
+
pyinfra/operations/sysvinit.py,sha256=WzzthkmWL46MNNY6LsBZ90e37yPj0w2QyUtEAlGBwqY,4078
|
|
127
|
+
pyinfra/operations/upstart.py,sha256=pHb9RGnVhT14A_y6OezfOH-lmniKpiyJqpeoOJl0beE,1978
|
|
128
|
+
pyinfra/operations/vzctl.py,sha256=2u2CDkuDjzHBRQ54HfyfLpLrsbT8U7_05EEjbbhKUiU,3110
|
|
129
|
+
pyinfra/operations/xbps.py,sha256=ru3_srMBUyUXGzAsPo7WwoomfM0AeDglFv8CDqB33B0,1508
|
|
130
|
+
pyinfra/operations/yum.py,sha256=Ig7AzQy1C7I8XM37lWbw0nI5lzFGMoX30P8FV8-V5uA,5600
|
|
131
|
+
pyinfra/operations/zfs.py,sha256=FnhiXreqf5qJBusC31dwrQsEi0MvH4qxzjBayHKFcYY,5283
|
|
132
|
+
pyinfra/operations/zypper.py,sha256=z1CWv2uwWBlCLIhHna7U5DojVoKZYoUYpezJ_FM_xK8,5555
|
|
133
|
+
pyinfra/operations/freebsd/__init__.py,sha256=PXsCLQG29VhimYw4uwwB2FcDt6CrofOtD3LTHC-ik-8,362
|
|
134
|
+
pyinfra/operations/freebsd/freebsd_update.py,sha256=lH0wB_i6DkaXQnDPjsDq8ocO1hYHL0v_a1go4exYcR8,1864
|
|
135
|
+
pyinfra/operations/freebsd/pkg.py,sha256=3AyfI0-_9F4ho47KqZsOMQocwNtTF2q9g0i6TffJVak,4413
|
|
136
|
+
pyinfra/operations/freebsd/service.py,sha256=1f7nTHELnhs3HBSrMFsmopVgYFMIwB8Se88yneRQ8Rw,3198
|
|
137
|
+
pyinfra/operations/freebsd/sysrc.py,sha256=eg7u_JsCge_uKq3Ysc_mohUc6qgJrOZStp_B_l2Hav4,2330
|
|
138
|
+
pyinfra/operations/util/__init__.py,sha256=ZAHjeCXtLo0TIOSfZ9h0Sh5IXXRCspfHs3RR1l8tQCE,366
|
|
139
|
+
pyinfra/operations/util/docker.py,sha256=WUyn2BZGClBwQDNTNNM3UNOX64YkpD4JMGk3lBufMTg,5285
|
|
140
|
+
pyinfra/operations/util/files.py,sha256=Zcet3ydNVbdT9jss0BDm6RJFyR_s6XTr0isDR60Zubw,3622
|
|
141
|
+
pyinfra/operations/util/packaging.py,sha256=xFtOlEX46ms7g3gDvOOInRVR1RVfgsmhLzFzsJAL_eU,9381
|
|
142
|
+
pyinfra/operations/util/service.py,sha256=kJd1zj4-sAaGIp5Ts7yAJznogWaGr8oQTztwenLAr7Y,1309
|
|
143
|
+
pyinfra_cli/__init__.py,sha256=G0X7tNdqT45uWuK3aHIKxMdDeCgJ7zHo6vbxoG6zy_8,284
|
|
144
|
+
pyinfra_cli/__main__.py,sha256=WlW7eP0rrL06eguuD_q2RAqgUjg3SW-QnmrayAh2mBQ,887
|
|
145
|
+
pyinfra_cli/commands.py,sha256=J-mCJYvDebJ8M7o3HreB2zToa871-xO6_KjVhPLeHho,1832
|
|
146
|
+
pyinfra_cli/exceptions.py,sha256=RRaOprL7SmVv--FLy4x7fxeTitx9wYI0Y3_h01LfhJA,4901
|
|
147
|
+
pyinfra_cli/inventory.py,sha256=05Z0LpMW8Qt3c2X2sx-roYCQGxNlEDD0RgZILpXCcJs,11768
|
|
148
|
+
pyinfra_cli/log.py,sha256=mD96MH2owQQ5AsYRw7osCKENdp-E3Wum5IDr6qhSIa4,2268
|
|
149
|
+
pyinfra_cli/main.py,sha256=PyofivS-dRF8Sfq-PIy7_GrJKKAdmucZ0IbtkNlcHy4,20085
|
|
150
|
+
pyinfra_cli/prints.py,sha256=eaLRQAdiVGmPR2GsHF_fCY706aSt5JyXxz42z6qLAFM,10299
|
|
151
|
+
pyinfra_cli/util.py,sha256=9ehdJQ8pDNBLHXoFst9p696VDT-b_qo8UFMJrqdE1rE,6424
|
|
152
|
+
pyinfra_cli/virtualenv.py,sha256=wRNxOPcUkbD_Pzuj-Lnrz1KxGmsLlb2ObmCTFrdD-S8,2474
|
|
153
|
+
tests/test_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
154
|
+
tests/test_api/test_api.py,sha256=Ig2ebkNACYbHcC4_zRkxS9vj5ZEogoPqGx30ErIKChg,2413
|
|
155
|
+
tests/test_api/test_api_arguments.py,sha256=5k7w0_x5cnABEFOk0LQBCt5gU9iTN9lo2XS6MlJTnhQ,1961
|
|
156
|
+
tests/test_api/test_api_command.py,sha256=OW0ESMyS5vo38u17DHeCrSIaIkW9gMU5PSkXL7mRrq0,3204
|
|
157
|
+
tests/test_api/test_api_config.py,sha256=bf0mDrUie3On6zGC_hJBpv-wvSf3LHBIBzUDvkopEt0,708
|
|
158
|
+
tests/test_api/test_api_deploys.py,sha256=h_zbI6CK4K8SdzEr3LEAMPxOf9hnQBdi_suqiNPqHHQ,4200
|
|
159
|
+
tests/test_api/test_api_facts.py,sha256=WnKwgLq7sk2LNO5IgIZbO5HRkDr-2GdUWO_EFfTjhO8,10695
|
|
160
|
+
tests/test_api/test_api_host.py,sha256=U_VW2vTl35vR8EdyIGMKr4y0ydsDLbvHSjZDa99CyNE,1119
|
|
161
|
+
tests/test_api/test_api_inventory.py,sha256=rqXd3e_Wwc-SxCzxgR5eLd7ZOdrF8CcHbcTZndLy5gE,2744
|
|
162
|
+
tests/test_api/test_api_operations.py,sha256=GUfnuHK2NoTAGdOT4AbytT9R8i3ZZIvGP7KBfoYcYUQ,20134
|
|
163
|
+
tests/test_api/test_api_util.py,sha256=uHv4oLpoy1_tzOoqFA1zpdvC74SvjitZbxQwp0dmjTs,1716
|
|
164
|
+
tests/test_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
165
|
+
tests/test_cli/test_cli.py,sha256=IeWuhkhLzIkRbOEx5-yaW6xV5l4Y8fxaGaDGlMcOyYE,6016
|
|
166
|
+
tests/test_cli/test_cli_deploy.py,sha256=vZC7twj8sPCy05loO50P-D_Xf73r6XN4m7yVj7TIFmo,5243
|
|
167
|
+
tests/test_cli/test_cli_exceptions.py,sha256=QaUv40q6Tp0HdcVEvPggFF4dsP2qdy57y9VAcGcR1So,3060
|
|
168
|
+
tests/test_cli/test_cli_inventory.py,sha256=feYSyxGBUsDGriOaqs0CBMbAIW7yUfoT1mktLwqMI0w,4036
|
|
169
|
+
tests/test_cli/test_cli_util.py,sha256=Fqn_9fnG6xNfw8OMHSZs9hQoW260aSt409S1bUAJs-Q,2500
|
|
170
|
+
tests/test_cli/test_context_objects.py,sha256=JiUTwQP7yvcqA47Kq9jtdsB_Z8nxGMZN46d9pR--FYA,2130
|
|
171
|
+
tests/test_cli/util.py,sha256=kp_-XsGnTyDgG6IHWorYzl5VD_WLe77dKOH007TDOUE,338
|
|
172
|
+
tests/test_connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
173
|
+
tests/test_connectors/test_chroot.py,sha256=QK7YgFPXzHh8y363-tmHvzZ0Ok5PVJWFTDAvwt91eac,5907
|
|
174
|
+
tests/test_connectors/test_docker.py,sha256=0EjkfhCHpLCfL4X-AIdMNw5ASaseY0tbRAn7T_TAkMQ,6566
|
|
175
|
+
tests/test_connectors/test_dockerssh.py,sha256=MaC9IK1OZDiqoIsuLOZBJnPDglsMoPDoL19LQtXsyCE,9303
|
|
176
|
+
tests/test_connectors/test_local.py,sha256=N_FkejDZKu7XLnKeApqfBARYMyxf-hRXCQJrXLHvwRg,7442
|
|
177
|
+
tests/test_connectors/test_ssh.py,sha256=YeCZtYDogm6M8xSFXjNXXmfgMGOH-0fzTeRaNXyOAtU,42995
|
|
178
|
+
tests/test_connectors/test_sshuserclient.py,sha256=Rm1zxSODDXQXuQ3qdkCA12FCUj7Zkgwwe-s2UrsZAoE,8599
|
|
179
|
+
tests/test_connectors/test_terraform.py,sha256=RZInSjes394eR5CrGGEjzZEFY-UpQj47n4MZH0_ExyY,3779
|
|
180
|
+
tests/test_connectors/test_util.py,sha256=hQir0WyjH0LEF6xvIyHNyqdI5pkJX6qUR9287MgO2bY,4647
|
|
181
|
+
tests/test_connectors/test_vagrant.py,sha256=27qRB7ftjEPaj4ejBNZ-rR4Ou1AD1VyVcf2XjwZPG3M,3640
|
|
182
|
+
pyinfra-3.3.dist-info/LICENSE.md,sha256=BzCnRYLJv0yb-FJuEd_XOrrQSOEQKzIVo0yHT8taNnM,1076
|
|
183
|
+
pyinfra-3.3.dist-info/METADATA,sha256=altc2EhdZvDuH_4Nbn_T4yocK5cA7feHsKONJBvEm4E,8054
|
|
184
|
+
pyinfra-3.3.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
|
|
185
|
+
pyinfra-3.3.dist-info/entry_points.txt,sha256=BraEFyquy05M8ch33HZXOHoH_m2BTqejL3xX3NrpzOM,471
|
|
186
|
+
pyinfra-3.3.dist-info/top_level.txt,sha256=2K6D1mK35JTSEBgOfEPV-N-uA2SDErxGiE0J-HUMMVI,26
|
|
187
|
+
pyinfra-3.3.dist-info/RECORD,,
|
pyinfra_cli/exceptions.py
CHANGED
|
@@ -5,6 +5,7 @@ from traceback import format_exception, format_tb, walk_tb
|
|
|
5
5
|
from types import TracebackType
|
|
6
6
|
|
|
7
7
|
import click
|
|
8
|
+
from typing_extensions import override
|
|
8
9
|
|
|
9
10
|
from pyinfra import logger
|
|
10
11
|
from pyinfra.api.exceptions import (
|
|
@@ -37,6 +38,7 @@ class WrappedError(click.ClickException):
|
|
|
37
38
|
message = repr(message)
|
|
38
39
|
self.message = message
|
|
39
40
|
|
|
41
|
+
@override
|
|
40
42
|
def show(self, file=None):
|
|
41
43
|
name = "unknown error"
|
|
42
44
|
|
|
@@ -65,6 +67,7 @@ class WrappedError(click.ClickException):
|
|
|
65
67
|
|
|
66
68
|
|
|
67
69
|
class CliError(click.ClickException):
|
|
70
|
+
@override
|
|
68
71
|
def show(self, file=None):
|
|
69
72
|
logger.warning(
|
|
70
73
|
"--> {0}: {1}".format(
|
|
@@ -96,6 +99,7 @@ class UnexpectedExternalError(click.ClickException, UnexpectedMixin):
|
|
|
96
99
|
self.exception = e
|
|
97
100
|
self.filename = filename
|
|
98
101
|
|
|
102
|
+
@override
|
|
99
103
|
def show(self, file=None):
|
|
100
104
|
logger.warning(
|
|
101
105
|
"--> {0}:\n".format(
|
|
@@ -118,6 +122,7 @@ class UnexpectedInternalError(click.ClickException, UnexpectedMixin):
|
|
|
118
122
|
e._traceback = traceback
|
|
119
123
|
self.exception = e
|
|
120
124
|
|
|
125
|
+
@override
|
|
121
126
|
def show(self, file=None):
|
|
122
127
|
click.echo(
|
|
123
128
|
"--> {0}:\n".format(
|
pyinfra_cli/inventory.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import socket
|
|
2
2
|
from collections import defaultdict
|
|
3
3
|
from os import listdir, path
|
|
4
|
-
from types import GeneratorType
|
|
5
4
|
from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar, Union
|
|
6
5
|
|
|
7
6
|
from pyinfra import logger
|
|
@@ -23,18 +22,37 @@ def _is_inventory_group(key: str, value: Any):
|
|
|
23
22
|
Verify that a module-level variable (key = value) is a valid inventory group.
|
|
24
23
|
"""
|
|
25
24
|
|
|
26
|
-
if key.startswith("
|
|
25
|
+
if key.startswith("__"):
|
|
26
|
+
# Ignore __builtins__/__file__
|
|
27
|
+
return False
|
|
28
|
+
elif key.startswith("_"):
|
|
29
|
+
logger.debug(
|
|
30
|
+
'Ignoring variable "%s" in inventory file since it starts with a leading underscore',
|
|
31
|
+
key,
|
|
32
|
+
)
|
|
27
33
|
return False
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
if isinstance(value, list):
|
|
36
|
+
pass
|
|
37
|
+
elif isinstance(value, tuple):
|
|
38
|
+
# If the group is a tuple of (hosts, data), check the hosts
|
|
31
39
|
value = value[0]
|
|
40
|
+
else:
|
|
41
|
+
logger.debug(
|
|
42
|
+
'Ignoring variable "%s" in inventory file since it is not a list or tuple',
|
|
43
|
+
key,
|
|
44
|
+
)
|
|
45
|
+
return False
|
|
32
46
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
if not all(isinstance(item, ALLOWED_HOST_TYPES) for item in value):
|
|
48
|
+
logger.warning(
|
|
49
|
+
'Ignoring host group "%s". '
|
|
50
|
+
"Host groups may only contain strings (host) or tuples (host, data).",
|
|
51
|
+
key,
|
|
52
|
+
)
|
|
53
|
+
return False
|
|
36
54
|
|
|
37
|
-
return
|
|
55
|
+
return True
|
|
38
56
|
|
|
39
57
|
|
|
40
58
|
def _get_group_data(dirname_or_filename: str):
|
|
@@ -258,7 +276,6 @@ def make_inventory_from_files(
|
|
|
258
276
|
for hosts in groups.values():
|
|
259
277
|
# Groups can be a list of hosts or tuple of (hosts, data)
|
|
260
278
|
hosts = _get_any_tuple_first(hosts)
|
|
261
|
-
|
|
262
279
|
for host in hosts:
|
|
263
280
|
# Hosts can be a hostname or tuple of (hostname, data)
|
|
264
281
|
hostname = _get_any_tuple_first(host)
|
pyinfra_cli/log.py
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
3
|
import click
|
|
4
|
+
from typing_extensions import override
|
|
4
5
|
|
|
5
6
|
from pyinfra import logger, state
|
|
6
7
|
from pyinfra.context import ctx_state
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class LogHandler(logging.Handler):
|
|
11
|
+
@override
|
|
10
12
|
def emit(self, record):
|
|
11
13
|
try:
|
|
12
14
|
message = self.format(record)
|
|
@@ -25,6 +27,7 @@ class LogFormatter(logging.Formatter):
|
|
|
25
27
|
logging.CRITICAL: lambda s: click.style(s, "red", bold=True),
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
@override
|
|
28
31
|
def format(self, record):
|
|
29
32
|
message = record.msg
|
|
30
33
|
|
pyinfra_cli/main.py
CHANGED
|
@@ -34,7 +34,7 @@ from .util import exec_file, load_deploy_file, load_func, parse_cli_arg
|
|
|
34
34
|
from .virtualenv import init_virtualenv
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def _exit():
|
|
37
|
+
def _exit() -> None:
|
|
38
38
|
if ctx_state.isset() and state.failed_hosts:
|
|
39
39
|
sys.exit(1)
|
|
40
40
|
sys.exit(0)
|
|
@@ -49,7 +49,10 @@ def _print_support(ctx, param, value):
|
|
|
49
49
|
ctx.exit()
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@click.command(context_settings=CONTEXT_SETTINGS)
|
|
53
56
|
@click.argument("inventory", nargs=1, type=click.Path(exists=False))
|
|
54
57
|
@click.argument("operations", nargs=-1, required=True, type=click.Path(exists=False))
|
|
55
58
|
@click.option(
|
|
@@ -347,7 +350,6 @@ def _main(
|
|
|
347
350
|
state.set_stage(StateStage.Connect)
|
|
348
351
|
connect_all(state)
|
|
349
352
|
|
|
350
|
-
logger.info("--> Preparing operations...")
|
|
351
353
|
state.set_stage(StateStage.Prepare)
|
|
352
354
|
can_diff, state, config = _handle_commands(
|
|
353
355
|
state, config, command, original_operations, operations
|
|
@@ -648,6 +650,7 @@ def _apply_inventory_limit(inventory, limit):
|
|
|
648
650
|
#
|
|
649
651
|
def _handle_commands(state, config, command, original_operations, operations):
|
|
650
652
|
if command is CliCommands.FACT:
|
|
653
|
+
logger.info("--> Gathering facts...")
|
|
651
654
|
state, fact_data = _run_fact_operations(state, config, operations)
|
|
652
655
|
print_facts(fact_data)
|
|
653
656
|
_exit()
|
|
@@ -655,13 +658,16 @@ def _handle_commands(state, config, command, original_operations, operations):
|
|
|
655
658
|
can_diff = True
|
|
656
659
|
|
|
657
660
|
if command == CliCommands.SHELL:
|
|
661
|
+
logger.info("--> Preparing exec operation...")
|
|
658
662
|
state = _prepare_exec_operations(state, config, operations)
|
|
659
663
|
can_diff = False
|
|
660
664
|
|
|
661
665
|
elif command == CliCommands.DEPLOY_FILES:
|
|
666
|
+
logger.info("--> Preparing operation files...")
|
|
662
667
|
state, config, operations = _prepare_deploy_operations(state, config, operations)
|
|
663
668
|
|
|
664
669
|
elif command == CliCommands.FUNC:
|
|
670
|
+
logger.info("--> Preparing operation func...")
|
|
665
671
|
state, kwargs = _prepare_func_operations(
|
|
666
672
|
state,
|
|
667
673
|
config,
|
|
@@ -673,8 +679,6 @@ def _handle_commands(state, config, command, original_operations, operations):
|
|
|
673
679
|
|
|
674
680
|
|
|
675
681
|
def _run_fact_operations(state, config, operations):
|
|
676
|
-
logger.info("--> Gathering facts...")
|
|
677
|
-
|
|
678
682
|
state.print_fact_info = True
|
|
679
683
|
fact_data = {}
|
|
680
684
|
|
|
@@ -712,7 +716,6 @@ def _prepare_exec_operations(state, config, operations):
|
|
|
712
716
|
|
|
713
717
|
|
|
714
718
|
def _prepare_deploy_operations(state, config, operations):
|
|
715
|
-
logger.info("--> Preparing Operations...")
|
|
716
719
|
|
|
717
720
|
# Number of "steps" to make = number of files * number of hosts
|
|
718
721
|
for i, filename in enumerate(operations):
|
|
@@ -729,8 +732,6 @@ def _prepare_deploy_operations(state, config, operations):
|
|
|
729
732
|
|
|
730
733
|
|
|
731
734
|
def _prepare_func_operations(state, config, operations, original_operations):
|
|
732
|
-
logger.info("--> Preparing operation...")
|
|
733
|
-
|
|
734
735
|
op, args = operations
|
|
735
736
|
args, kwargs = args
|
|
736
737
|
|
pyinfra_cli/prints.py
CHANGED
|
@@ -130,7 +130,7 @@ def print_facts(facts):
|
|
|
130
130
|
print_fact(data)
|
|
131
131
|
|
|
132
132
|
|
|
133
|
-
def print_support_info():
|
|
133
|
+
def print_support_info() -> None:
|
|
134
134
|
from importlib.metadata import PackageNotFoundError, requires, version
|
|
135
135
|
|
|
136
136
|
from packaging.requirements import Requirement
|
|
@@ -281,6 +281,8 @@ def print_results(state: "State"):
|
|
|
281
281
|
(logger.info, ["Operation", "Hosts", "Success", "Error", "No Change"]),
|
|
282
282
|
]
|
|
283
283
|
|
|
284
|
+
totals = {"hosts": 0, "success": 0, "error": 0, "no_change": 0}
|
|
285
|
+
|
|
284
286
|
for op_hash in state.get_op_order():
|
|
285
287
|
hosts_in_op = 0
|
|
286
288
|
hosts_in_op_success: list[str] = []
|
|
@@ -306,19 +308,32 @@ def print_results(state: "State"):
|
|
|
306
308
|
str(hosts_in_op),
|
|
307
309
|
]
|
|
308
310
|
|
|
311
|
+
totals["hosts"] += hosts_in_op
|
|
312
|
+
|
|
309
313
|
if hosts_in_op_success:
|
|
310
|
-
|
|
314
|
+
num_hosts_in_op_success = len(hosts_in_op_success)
|
|
315
|
+
row.append(str(num_hosts_in_op_success))
|
|
316
|
+
totals["success"] += num_hosts_in_op_success
|
|
311
317
|
else:
|
|
312
318
|
row.append("-")
|
|
319
|
+
|
|
313
320
|
if hosts_in_op_error:
|
|
314
|
-
|
|
321
|
+
num_hosts_in_op_error = len(hosts_in_op_error)
|
|
322
|
+
row.append(str(num_hosts_in_op_error))
|
|
323
|
+
totals["error"] += num_hosts_in_op_error
|
|
315
324
|
else:
|
|
316
325
|
row.append("-")
|
|
326
|
+
|
|
317
327
|
if hosts_in_op_no_change:
|
|
318
|
-
|
|
328
|
+
num_hosts_in_op_no_change = len(hosts_in_op_no_change)
|
|
329
|
+
row.append(str(num_hosts_in_op_no_change))
|
|
330
|
+
totals["no_change"] += num_hosts_in_op_no_change
|
|
319
331
|
else:
|
|
320
332
|
row.append("-")
|
|
321
333
|
|
|
322
334
|
rows.append((logger.info, row))
|
|
323
335
|
|
|
336
|
+
totals_row = ["Grand total"] + [str(i) if i else "-" for i in totals.values()]
|
|
337
|
+
rows.append((logger.info, totals_row))
|
|
338
|
+
|
|
324
339
|
print_rows(rows)
|
pyinfra_cli/util.py
CHANGED
pyinfra_cli/virtualenv.py
CHANGED
|
@@ -43,26 +43,28 @@ class TestCliDeployState(PatchSSHTestCase):
|
|
|
43
43
|
assert executed is False
|
|
44
44
|
|
|
45
45
|
def test_deploy(self):
|
|
46
|
-
|
|
46
|
+
a_task_file_path = path.join("tasks", "a_task.py")
|
|
47
|
+
b_task_file_path = path.join("tasks", "b_task.py")
|
|
47
48
|
nested_task_path = path.join("tasks", "another_task.py")
|
|
48
49
|
correct_op_name_and_host_names = [
|
|
49
50
|
("First main operation", True), # true for all hosts
|
|
50
51
|
("Second main operation", ("somehost",)),
|
|
51
|
-
("{0} | First task operation".format(
|
|
52
|
-
("{0} | Task order loop 1".format(
|
|
53
|
-
("{0} | 2nd Task order loop 1".format(
|
|
54
|
-
("{0} | Task order loop 2".format(
|
|
55
|
-
("{0} | 2nd Task order loop 2".format(
|
|
52
|
+
("{0} | First task operation".format(a_task_file_path), ("anotherhost",)),
|
|
53
|
+
("{0} | Task order loop 1".format(a_task_file_path), ("anotherhost",)),
|
|
54
|
+
("{0} | 2nd Task order loop 1".format(a_task_file_path), ("anotherhost",)),
|
|
55
|
+
("{0} | Task order loop 2".format(a_task_file_path), ("anotherhost",)),
|
|
56
|
+
("{0} | 2nd Task order loop 2".format(a_task_file_path), ("anotherhost",)),
|
|
56
57
|
(
|
|
57
|
-
"{0} | {1} | Second task operation".format(
|
|
58
|
+
"{0} | {1} | Second task operation".format(a_task_file_path, nested_task_path),
|
|
58
59
|
("anotherhost",),
|
|
59
60
|
),
|
|
60
|
-
("{0} | First task operation".format(
|
|
61
|
-
("{0} | Task order loop 1".format(
|
|
62
|
-
("{0} | 2nd Task order loop 1".format(
|
|
63
|
-
("{0} | Task order loop 2".format(
|
|
64
|
-
("{0} | 2nd Task order loop 2".format(
|
|
65
|
-
("{0} | {1} | Second task operation".format(
|
|
61
|
+
("{0} | First task operation".format(a_task_file_path), True),
|
|
62
|
+
("{0} | Task order loop 1".format(a_task_file_path), True),
|
|
63
|
+
("{0} | 2nd Task order loop 1".format(a_task_file_path), True),
|
|
64
|
+
("{0} | Task order loop 2".format(a_task_file_path), True),
|
|
65
|
+
("{0} | 2nd Task order loop 2".format(a_task_file_path), True),
|
|
66
|
+
("{0} | {1} | Second task operation".format(a_task_file_path, nested_task_path), True),
|
|
67
|
+
("{0} | Important task operation".format(b_task_file_path), True),
|
|
66
68
|
("My deploy | First deploy operation", True),
|
|
67
69
|
("My deploy | My nested deploy | First nested deploy operation", True),
|
|
68
70
|
("My deploy | Second deploy operation", True),
|