pyinfra 3.0.2__py2.py3-none-any.whl → 3.1.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.
- pyinfra/api/arguments.py +1 -1
- pyinfra/api/deploy.py +8 -0
- pyinfra/api/host.py +7 -3
- pyinfra/api/util.py +4 -2
- pyinfra/connectors/chroot.py +1 -1
- pyinfra/connectors/local.py +1 -1
- pyinfra/connectors/ssh.py +4 -1
- pyinfra/connectors/terraform.py +30 -20
- pyinfra/facts/apt.py +2 -2
- pyinfra/facts/files.py +8 -1
- pyinfra/facts/flatpak.py +70 -0
- pyinfra/facts/hardware.py +1 -0
- pyinfra/facts/selinux.py +3 -1
- pyinfra/facts/systemd.py +4 -1
- pyinfra/facts/zfs.py +57 -0
- pyinfra/operations/apt.py +2 -1
- pyinfra/operations/docker.py +4 -4
- pyinfra/operations/files.py +11 -4
- pyinfra/operations/flatpak.py +79 -0
- pyinfra/operations/git.py +25 -2
- pyinfra/operations/mysql.py +5 -5
- pyinfra/operations/postgres.py +3 -3
- pyinfra/operations/server.py +10 -10
- pyinfra/operations/zfs.py +175 -0
- {pyinfra-3.0.2.dist-info → pyinfra-3.1.1.dist-info}/METADATA +1 -1
- {pyinfra-3.0.2.dist-info → pyinfra-3.1.1.dist-info}/RECORD +37 -33
- pyinfra_cli/inventory.py +34 -2
- pyinfra_cli/prints.py +16 -0
- pyinfra_cli/util.py +2 -2
- tests/test_api/test_api_inventory.py +21 -0
- tests/test_cli/test_cli_exceptions.py +2 -2
- tests/test_cli/test_cli_util.py +2 -4
- tests/test_connectors/test_terraform.py +6 -6
- {pyinfra-3.0.2.dist-info → pyinfra-3.1.1.dist-info}/LICENSE.md +0 -0
- {pyinfra-3.0.2.dist-info → pyinfra-3.1.1.dist-info}/WHEEL +0 -0
- {pyinfra-3.0.2.dist-info → pyinfra-3.1.1.dist-info}/entry_points.txt +0 -0
- {pyinfra-3.0.2.dist-info → pyinfra-3.1.1.dist-info}/top_level.txt +0 -0
pyinfra/operations/git.py
CHANGED
|
@@ -184,7 +184,7 @@ def worktree(
|
|
|
184
184
|
+ from_remote_branch: a 2-tuple ``(remote, branch)`` that identifies a remote branch
|
|
185
185
|
+ present: whether the working tree should exist
|
|
186
186
|
+ assume_repo_exists: whether to assume the main repo exists
|
|
187
|
-
+ force:
|
|
187
|
+
+ force: whether to use ``--force`` when adding/removing worktrees
|
|
188
188
|
+ user: chown files to this user after
|
|
189
189
|
+ group: chown files to this group after
|
|
190
190
|
|
|
@@ -205,6 +205,14 @@ def worktree(
|
|
|
205
205
|
commitish="4e091aa0"
|
|
206
206
|
)
|
|
207
207
|
|
|
208
|
+
git.worktree(
|
|
209
|
+
name="Create a worktree from the tag `4e091aa0`, even if already registered",
|
|
210
|
+
repo="/usr/local/src/pyinfra/master",
|
|
211
|
+
worktree="/usr/local/src/pyinfra/2.x",
|
|
212
|
+
commitish="2.x",
|
|
213
|
+
force=True
|
|
214
|
+
)
|
|
215
|
+
|
|
208
216
|
git.worktree(
|
|
209
217
|
name="Create a worktree with a new local branch `v1.0`",
|
|
210
218
|
repo="/usr/local/src/pyinfra/master",
|
|
@@ -250,6 +258,15 @@ def worktree(
|
|
|
250
258
|
commitish="v1.0"
|
|
251
259
|
)
|
|
252
260
|
|
|
261
|
+
git.worktree(
|
|
262
|
+
name="Idempotent worktree creation, never pulls",
|
|
263
|
+
repo="/usr/local/src/pyinfra/master",
|
|
264
|
+
worktree="/usr/local/src/pyinfra/hotfix",
|
|
265
|
+
new_branch="v1.0",
|
|
266
|
+
commitish="v1.0",
|
|
267
|
+
pull=False
|
|
268
|
+
)
|
|
269
|
+
|
|
253
270
|
git.worktree(
|
|
254
271
|
name="Pull an existing worktree already linked to a tracking branch",
|
|
255
272
|
repo="/usr/local/src/pyinfra/master",
|
|
@@ -295,6 +312,9 @@ def worktree(
|
|
|
295
312
|
elif detached:
|
|
296
313
|
command_parts.append("--detach")
|
|
297
314
|
|
|
315
|
+
if force:
|
|
316
|
+
command_parts.append("--force")
|
|
317
|
+
|
|
298
318
|
command_parts.append(worktree)
|
|
299
319
|
|
|
300
320
|
if commitish:
|
|
@@ -317,9 +337,12 @@ def worktree(
|
|
|
317
337
|
|
|
318
338
|
# It exists and we still want it => pull/rebase it
|
|
319
339
|
elif host.get_fact(Directory, path=worktree) and present:
|
|
340
|
+
if not pull:
|
|
341
|
+
host.noop("Pull is disabled")
|
|
342
|
+
|
|
320
343
|
# pull the worktree only if it's already linked to a tracking branch or
|
|
321
344
|
# if a remote branch is set
|
|
322
|
-
|
|
345
|
+
elif host.get_fact(GitTrackingBranch, repo=worktree) or from_remote_branch:
|
|
323
346
|
command = "cd {0} && git pull".format(worktree)
|
|
324
347
|
|
|
325
348
|
if rebase:
|
pyinfra/operations/mysql.py
CHANGED
|
@@ -554,7 +554,7 @@ def dump(
|
|
|
554
554
|
)
|
|
555
555
|
"""
|
|
556
556
|
|
|
557
|
-
yield
|
|
557
|
+
yield StringCommand(
|
|
558
558
|
make_mysql_command(
|
|
559
559
|
executable="mysqldump",
|
|
560
560
|
database=database,
|
|
@@ -563,7 +563,8 @@ def dump(
|
|
|
563
563
|
host=mysql_host,
|
|
564
564
|
port=mysql_port,
|
|
565
565
|
),
|
|
566
|
-
|
|
566
|
+
">",
|
|
567
|
+
QuoteString(dest),
|
|
567
568
|
)
|
|
568
569
|
|
|
569
570
|
|
|
@@ -595,7 +596,7 @@ def load(
|
|
|
595
596
|
)
|
|
596
597
|
"""
|
|
597
598
|
|
|
598
|
-
|
|
599
|
+
yield StringCommand(
|
|
599
600
|
make_mysql_command(
|
|
600
601
|
database=database,
|
|
601
602
|
user=mysql_user,
|
|
@@ -605,5 +606,4 @@ def load(
|
|
|
605
606
|
),
|
|
606
607
|
"<",
|
|
607
608
|
QuoteString(src),
|
|
608
|
-
|
|
609
|
-
yield StringCommand(*commands_bits)
|
|
609
|
+
)
|
pyinfra/operations/postgres.py
CHANGED
|
@@ -16,7 +16,7 @@ See example/postgresql.py for detailed example
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
18
|
from pyinfra import host
|
|
19
|
-
from pyinfra.api import MaskString, StringCommand, operation
|
|
19
|
+
from pyinfra.api import MaskString, QuoteString, StringCommand, operation
|
|
20
20
|
from pyinfra.facts.postgres import (
|
|
21
21
|
PostgresDatabases,
|
|
22
22
|
PostgresRoles,
|
|
@@ -302,7 +302,7 @@ def dump(
|
|
|
302
302
|
port=psql_port,
|
|
303
303
|
),
|
|
304
304
|
">",
|
|
305
|
-
dest,
|
|
305
|
+
QuoteString(dest),
|
|
306
306
|
)
|
|
307
307
|
|
|
308
308
|
|
|
@@ -345,5 +345,5 @@ def load(
|
|
|
345
345
|
port=psql_port,
|
|
346
346
|
),
|
|
347
347
|
"<",
|
|
348
|
-
src,
|
|
348
|
+
QuoteString(src),
|
|
349
349
|
)
|
pyinfra/operations/server.py
CHANGED
|
@@ -89,12 +89,12 @@ def reboot(delay=10, interval=1, reboot_timeout=300):
|
|
|
89
89
|
sleep(delay)
|
|
90
90
|
max_retries = round(reboot_timeout / interval)
|
|
91
91
|
|
|
92
|
-
host.
|
|
92
|
+
host.disconnect() # make sure we are properly disconnected
|
|
93
93
|
retries = 0
|
|
94
94
|
|
|
95
95
|
while True:
|
|
96
96
|
host.connect(show_errors=False)
|
|
97
|
-
if host.
|
|
97
|
+
if host.connected:
|
|
98
98
|
break
|
|
99
99
|
|
|
100
100
|
if retries > max_retries:
|
|
@@ -723,11 +723,11 @@ def crontab(
|
|
|
723
723
|
if any(
|
|
724
724
|
(
|
|
725
725
|
special_time != existing_crontab.get("special_time"),
|
|
726
|
-
minute != existing_crontab.get("minute"),
|
|
727
|
-
hour != existing_crontab.get("hour"),
|
|
728
|
-
month != existing_crontab.get("month"),
|
|
729
|
-
day_of_week != existing_crontab.get("day_of_week"),
|
|
730
|
-
day_of_month != existing_crontab.get("day_of_month"),
|
|
726
|
+
try_int(minute) != existing_crontab.get("minute"),
|
|
727
|
+
try_int(hour) != existing_crontab.get("hour"),
|
|
728
|
+
try_int(month) != existing_crontab.get("month"),
|
|
729
|
+
try_int(day_of_week) != existing_crontab.get("day_of_week"),
|
|
730
|
+
try_int(day_of_month) != existing_crontab.get("day_of_month"),
|
|
731
731
|
existing_crontab_command != command,
|
|
732
732
|
),
|
|
733
733
|
):
|
|
@@ -881,11 +881,11 @@ def user_authorized_keys(
|
|
|
881
881
|
|
|
882
882
|
if path.exists(try_path):
|
|
883
883
|
with open(try_path, "r") as f:
|
|
884
|
-
return
|
|
884
|
+
return [key.strip() for key in f.readlines()]
|
|
885
885
|
|
|
886
|
-
return key.strip()
|
|
886
|
+
return [key.strip()]
|
|
887
887
|
|
|
888
|
-
public_keys =
|
|
888
|
+
public_keys = [key for key_or_file in public_keys for key in read_any_pub_key_file(key_or_file)]
|
|
889
889
|
|
|
890
890
|
# Ensure .ssh directory
|
|
891
891
|
# note that this always outputs commands unless the SSH user has access to the
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage ZFS filesystems.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from pyinfra import host
|
|
6
|
+
from pyinfra.api import operation
|
|
7
|
+
from pyinfra.facts.zfs import Datasets, Snapshots
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@operation()
|
|
11
|
+
def dataset(
|
|
12
|
+
dataset_name,
|
|
13
|
+
present=True,
|
|
14
|
+
recursive=False,
|
|
15
|
+
sparse=None,
|
|
16
|
+
volume_size=None,
|
|
17
|
+
properties={},
|
|
18
|
+
**extra_props,
|
|
19
|
+
):
|
|
20
|
+
"""
|
|
21
|
+
Create, destroy or set properties on a ZFS dataset (e.g. filesystem,
|
|
22
|
+
volume, snapshot).
|
|
23
|
+
|
|
24
|
+
+ dataset_name: name of the filesystem to operate on
|
|
25
|
+
+ present: whether the named filesystem should exist
|
|
26
|
+
+ recursive: whether to create parent datasets, or destroy child datasets
|
|
27
|
+
+ sparse: for volumes, whether to create a sparse volume with no allocation
|
|
28
|
+
+ volume_size: the size of the volume
|
|
29
|
+
+ properties: the ZFS properties that should be set on the dataset.
|
|
30
|
+
+ **extra_props: additional props; merged with `properties` for convenience
|
|
31
|
+
|
|
32
|
+
**Examples:**
|
|
33
|
+
|
|
34
|
+
.. code:: python
|
|
35
|
+
|
|
36
|
+
zfs.dataset(
|
|
37
|
+
"tank/srv",
|
|
38
|
+
mountpoint="/srv",
|
|
39
|
+
compression="lz4",
|
|
40
|
+
properties={"com.sun:auto_snapshot": "true"}
|
|
41
|
+
)
|
|
42
|
+
zfs.dataset("tank/vm-disks/db_srv_04", volume_size="32G") # creates a volume
|
|
43
|
+
zfs.dataset("tank/home@old_version", present=False)
|
|
44
|
+
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
noop_msg = "{0} is already {1}".format(dataset_name, "present" if present else "absent")
|
|
48
|
+
|
|
49
|
+
properties.update(extra_props)
|
|
50
|
+
|
|
51
|
+
datasets = host.get_fact(Datasets)
|
|
52
|
+
|
|
53
|
+
existing_dataset = datasets.get(dataset_name)
|
|
54
|
+
|
|
55
|
+
if present and not existing_dataset:
|
|
56
|
+
args = ["-o {0}={1}".format(prop, value) for prop, value in properties.items()]
|
|
57
|
+
if recursive:
|
|
58
|
+
args.append("-p")
|
|
59
|
+
if sparse:
|
|
60
|
+
args.append("-s")
|
|
61
|
+
if volume_size:
|
|
62
|
+
args.append("-V {0}".format(volume_size))
|
|
63
|
+
|
|
64
|
+
args.sort() # dicts are unordered, so make sure the test results are deterministic
|
|
65
|
+
|
|
66
|
+
yield "zfs create {0} {1}".format(" ".join(args), dataset_name)
|
|
67
|
+
|
|
68
|
+
elif present and existing_dataset:
|
|
69
|
+
prop_args = [
|
|
70
|
+
"{0}={1}".format(prop, value)
|
|
71
|
+
for prop, value in properties.items() - existing_dataset.items()
|
|
72
|
+
]
|
|
73
|
+
prop_args.sort()
|
|
74
|
+
if prop_args:
|
|
75
|
+
yield "zfs set {0} {1}".format(" ".join(prop_args), dataset_name)
|
|
76
|
+
else:
|
|
77
|
+
host.noop(noop_msg)
|
|
78
|
+
|
|
79
|
+
elif existing_dataset and not present:
|
|
80
|
+
recursive_arg = "-r" if recursive else ""
|
|
81
|
+
yield "zfs destroy {0} {1}".format(recursive_arg, dataset_name)
|
|
82
|
+
|
|
83
|
+
else:
|
|
84
|
+
host.noop(noop_msg)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@operation()
|
|
88
|
+
def snapshot(snapshot_name, present=True, recursive=False, properties={}, **extra_props):
|
|
89
|
+
"""
|
|
90
|
+
Create or destroy a ZFS snapshot, or modify its properties.
|
|
91
|
+
|
|
92
|
+
+ dataset_name: name of the filesystem to operate on
|
|
93
|
+
+ present: whether the named filesystem should exist
|
|
94
|
+
+ recursive: whether to snapshot child datasets
|
|
95
|
+
+ properties: the ZFS properties that should be set on the snapshot.
|
|
96
|
+
+ **extra_props: additional props; merged with `properties` for convenience
|
|
97
|
+
|
|
98
|
+
**Examples:**
|
|
99
|
+
|
|
100
|
+
.. code:: python
|
|
101
|
+
|
|
102
|
+
zfs.snapshot("tank/home@weekly_backup")
|
|
103
|
+
|
|
104
|
+
"""
|
|
105
|
+
properties.update(extra_props)
|
|
106
|
+
snapshots = host.get_fact(Snapshots)
|
|
107
|
+
|
|
108
|
+
if snapshot_name in snapshots or not present:
|
|
109
|
+
yield from dataset._inner(snapshot_name, present=present, properties=properties)
|
|
110
|
+
|
|
111
|
+
else:
|
|
112
|
+
args = ["-o {0}={1}".format(prop, value) for prop, value in properties.items()]
|
|
113
|
+
if recursive:
|
|
114
|
+
args.append("-r")
|
|
115
|
+
yield "zfs snap {0} {1}".format(" ".join(args), snapshot_name)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@operation()
|
|
119
|
+
def volume(
|
|
120
|
+
volume_name, size, sparse=False, present=True, recursive=False, properties={}, **extra_props
|
|
121
|
+
):
|
|
122
|
+
"""
|
|
123
|
+
Create or destroy a ZFS volume, or modify its properties.
|
|
124
|
+
|
|
125
|
+
+ volume_name: name of the volume to operate on
|
|
126
|
+
+ size: the size of the volume
|
|
127
|
+
+ sparse: create a sparse volume
|
|
128
|
+
+ present: whether the named volume should exist
|
|
129
|
+
+ recursive: whether to create parent datasets or destroy child datasets
|
|
130
|
+
+ properties: the ZFS properties that should be set on the snapshot.
|
|
131
|
+
+ **extra_props: additional props; merged with `properties` for convenience
|
|
132
|
+
|
|
133
|
+
**Examples:**
|
|
134
|
+
|
|
135
|
+
.. code:: python
|
|
136
|
+
|
|
137
|
+
zfs.volume("tank/vm-disks/db_srv_04", "32G")
|
|
138
|
+
|
|
139
|
+
"""
|
|
140
|
+
properties.update(extra_props)
|
|
141
|
+
yield from dataset._inner(
|
|
142
|
+
volume_name,
|
|
143
|
+
volume_size=size,
|
|
144
|
+
present=present,
|
|
145
|
+
sparse=sparse,
|
|
146
|
+
recursive=recursive,
|
|
147
|
+
properties=properties,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
@operation()
|
|
152
|
+
def filesystem(fs_name, present=True, recursive=False, properties={}, **extra_props):
|
|
153
|
+
"""
|
|
154
|
+
Create or destroy a ZFS filesystem, or modify its properties.
|
|
155
|
+
|
|
156
|
+
+ fs_name: name of the volume to operate on
|
|
157
|
+
+ present: whether the named volume should exist
|
|
158
|
+
+ recursive: whether to create parent datasets or destroy child datasets
|
|
159
|
+
+ properties: the ZFS properties that should be set on the snapshot.
|
|
160
|
+
+ **extra_props: additional props; merged with `properties` for convenience
|
|
161
|
+
|
|
162
|
+
**Examples:**
|
|
163
|
+
|
|
164
|
+
.. code:: python
|
|
165
|
+
|
|
166
|
+
zfs.filesystem("tank/vm-disks/db_srv_04", "32G")
|
|
167
|
+
|
|
168
|
+
"""
|
|
169
|
+
properties.update(extra_props)
|
|
170
|
+
yield from dataset._inner(
|
|
171
|
+
fs_name,
|
|
172
|
+
present=present,
|
|
173
|
+
recursive=recursive,
|
|
174
|
+
properties=properties,
|
|
175
|
+
)
|
|
@@ -6,30 +6,30 @@ 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
8
|
pyinfra/api/__init__.py,sha256=suGbKKM-qCduuXFYBEcyswlTqozewtYpdLRhK63PVn0,942
|
|
9
|
-
pyinfra/api/arguments.py,sha256=
|
|
9
|
+
pyinfra/api/arguments.py,sha256=51cMf5GHBAodg5SNuGAqafNYuWtCciKR6n8bn664TVI,9943
|
|
10
10
|
pyinfra/api/arguments_typed.py,sha256=WQKr0wDtlgJGq-Vkv_oPAz7f-LxjqQv3wJCdvVrePWk,2331
|
|
11
11
|
pyinfra/api/command.py,sha256=SyUlxvhYlXpgFpg0jua8bzQ2KPtVYQXHcvD6AUL2SCI,7226
|
|
12
12
|
pyinfra/api/config.py,sha256=wS6Pi4T4DxNkzO4llNY-ghLxyI5VBJ26uGvgMPZxIKY,9043
|
|
13
13
|
pyinfra/api/connect.py,sha256=Z9wusMLR_jBkKKk5D4AUOj8LHl3H5MsNO5FxAeR4jac,1416
|
|
14
14
|
pyinfra/api/connectors.py,sha256=nie7JuLxMSC6gqPjmjuCisQ11R-eAQDtMMWF6YbSQ48,659
|
|
15
|
-
pyinfra/api/deploy.py,sha256=
|
|
15
|
+
pyinfra/api/deploy.py,sha256=GbXtjhmUYpnzf7WNlqwIrFw6tOMiP6WjJBmJ4CyvNYM,3053
|
|
16
16
|
pyinfra/api/exceptions.py,sha256=cCbUp1qN1QO0d9aAvOAbRgYpLi0vUI5j7ZqSjcD1_P8,1861
|
|
17
17
|
pyinfra/api/facts.py,sha256=aMPtkB7vypyXRQDThjwJZzAnEgqjP0wrwyEhRHQf4Js,9449
|
|
18
|
-
pyinfra/api/host.py,sha256=
|
|
18
|
+
pyinfra/api/host.py,sha256=ehTWAAEwpWJ8hQU6lU1kcR0bP-WFnrB12QvnMaaSGu4,13752
|
|
19
19
|
pyinfra/api/inventory.py,sha256=nPITdNEJ7q71adIqS_OKHsMjD7amUuHEuTl6xzgh1Gk,7734
|
|
20
20
|
pyinfra/api/operation.py,sha256=Dp7pH9H3EYs7U1ZvquYUbOtWJPO9iIAa4H7GwXdxFxs,15170
|
|
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=
|
|
23
|
+
pyinfra/api/util.py,sha256=K4aFjGW7KAz2ZQqfRriRqyHMCQFFrX06WPola3epjaE,12410
|
|
24
24
|
pyinfra/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
25
|
pyinfra/connectors/base.py,sha256=2fASiV-MvpXgcZAFLM_PUwYx5ax6EHai44ri_oEKeSE,3732
|
|
26
|
-
pyinfra/connectors/chroot.py,sha256=
|
|
26
|
+
pyinfra/connectors/chroot.py,sha256=X5U3vi-zPm4DV-lHTwoHU8iEl8dppDiYJoWP_1mJVFY,5919
|
|
27
27
|
pyinfra/connectors/docker.py,sha256=2UNHhXS4hpLo7I19ixDeSd7JR8SNo43VgqsaUIZQZJ4,8741
|
|
28
28
|
pyinfra/connectors/dockerssh.py,sha256=VWHY--jqs3yf-RuPUZXav4vLeON9SzoVC9CUyOJo1rg,8919
|
|
29
|
-
pyinfra/connectors/local.py,sha256=
|
|
30
|
-
pyinfra/connectors/ssh.py,sha256=
|
|
29
|
+
pyinfra/connectors/local.py,sha256=eFDrBalS1yPCIUdQzh8h2HF3VP2nDn0uVFKOeeQZfiw,6888
|
|
30
|
+
pyinfra/connectors/ssh.py,sha256=Pr7W_aiGstkWQqrwm-cNENzhzTWTBLWM-XAAbF9uOEQ,21212
|
|
31
31
|
pyinfra/connectors/ssh_util.py,sha256=CN_5AdTA3RpiWCnXTrRBjez1NsN59hITDzQmXIkZvoE,3683
|
|
32
|
-
pyinfra/connectors/terraform.py,sha256=
|
|
32
|
+
pyinfra/connectors/terraform.py,sha256=Tu59cbemll5CfqlIaQtOrLa0HKzl23c64ih0DZXJu1I,4227
|
|
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
|
|
@@ -37,7 +37,7 @@ pyinfra/connectors/sshuserclient/client.py,sha256=24KWAAqIaUPQIod-CSeXKkA_WhQnII
|
|
|
37
37
|
pyinfra/connectors/sshuserclient/config.py,sha256=UMwkvTgAIS7__re6Wz_pwH6EU4kO1-uMQ5zuFakH0v4,2721
|
|
38
38
|
pyinfra/facts/__init__.py,sha256=myTXSOZmAqmU88Fyifn035h9Lr6Gj2mlka_jDcXyKGw,347
|
|
39
39
|
pyinfra/facts/apk.py,sha256=q76WdaCNZGKzYia5vMscCsOi4WlnBhcj_9c7Jj-2LqQ,581
|
|
40
|
-
pyinfra/facts/apt.py,sha256=
|
|
40
|
+
pyinfra/facts/apt.py,sha256=l_ABTyUFlh6C2W6oDdv-9x4MPDJ4M47RRtx8qsTSpJc,2175
|
|
41
41
|
pyinfra/facts/brew.py,sha256=qDz89ZlZOiCZv0GLOXOjgFtqq66SLaYXgCncYP2LwDs,2584
|
|
42
42
|
pyinfra/facts/bsdinit.py,sha256=hyESeGu0hPf8HY1D0bIFFFNFpXRdZB2R52aflVQPf9o,577
|
|
43
43
|
pyinfra/facts/cargo.py,sha256=OQF6nOulp2TIaFK1fiAEevsXnL5OMQUL6LkFHidb1yo,605
|
|
@@ -45,11 +45,12 @@ pyinfra/facts/choco.py,sha256=A0VCXnI5H9RocgO1IvaNWRIxnXiIZYEzIDG1F-ydJi4,790
|
|
|
45
45
|
pyinfra/facts/deb.py,sha256=XGyxnow9wjpE8ZKTZDa1_SNChMyMcNgFeTG1ka5uky4,1922
|
|
46
46
|
pyinfra/facts/dnf.py,sha256=9rTBgLHewbk8XCJuikzAYCumfFAzbmmHMchlaXBhdWw,977
|
|
47
47
|
pyinfra/facts/docker.py,sha256=CVSsUEiBaQrNvM1mggoKCXj5DdzwmcbufUY96koqKBw,2250
|
|
48
|
-
pyinfra/facts/files.py,sha256=
|
|
48
|
+
pyinfra/facts/files.py,sha256=qJw5_xnPxS5orFy2Ch4oUjmiFUFGGe71UEXoXdZBSek,11765
|
|
49
|
+
pyinfra/facts/flatpak.py,sha256=lnuFZYGPtPDe35YXTVgn5M0rhgcA5ys3fMI6EmvCnm4,1536
|
|
49
50
|
pyinfra/facts/gem.py,sha256=ktC2hofSwYX0fVcdWleU74ddjW1RPZvKMW-3wYp9lJE,572
|
|
50
51
|
pyinfra/facts/git.py,sha256=6e_2GjDT2oAxdtkHTyeMYQ9N64gZDorLTTVeZhFel18,1276
|
|
51
52
|
pyinfra/facts/gpg.py,sha256=wYKoQl4aHXB1UqqbWCdVhUoa6N6Liz01AmH8fPjxR48,3813
|
|
52
|
-
pyinfra/facts/hardware.py,sha256=
|
|
53
|
+
pyinfra/facts/hardware.py,sha256=9UOgvzlJ7jx7hPfmkhldYEymKEiKMR3ZVFGfZXl_oe0,12023
|
|
53
54
|
pyinfra/facts/iptables.py,sha256=sUkywfHZUXnMZF_KshAnyJufrJvZ9fBYnERSRbwOCRE,3374
|
|
54
55
|
pyinfra/facts/launchd.py,sha256=D0RSpBQXt4a4zJOxwxIb5RYY34sAx6ZrWj8NxwYqhIc,767
|
|
55
56
|
pyinfra/facts/lxd.py,sha256=NeIMK9VsDXlRf7q3j17oYbdigL7XjLnhmqv63t6CrzQ,466
|
|
@@ -64,15 +65,16 @@ pyinfra/facts/postgres.py,sha256=7cg0Nq8wNIWnKw3B8dJpgjSFZ7q90-_NhwEw2NsSJm8,422
|
|
|
64
65
|
pyinfra/facts/postgresql.py,sha256=4nusMVvGhtku86KX4O4vjSxh_MamxZy_kmTQvvy0GhE,223
|
|
65
66
|
pyinfra/facts/rpm.py,sha256=SzHNCNUMA-j5uJl4PKRTFpckOvNZ2zpxNeQyOCl8Usk,2225
|
|
66
67
|
pyinfra/facts/runit.py,sha256=iarF_Tql8bkNeHsKGRANRKNyBWwMsflsTNXj1Wz14i8,2021
|
|
67
|
-
pyinfra/facts/selinux.py,sha256=
|
|
68
|
+
pyinfra/facts/selinux.py,sha256=as3AvC6p88er0rYBFTdIWf6k3w0pVjDqDAV9Ur5zY90,4443
|
|
68
69
|
pyinfra/facts/server.py,sha256=fDXSNNlZghJTGqr9CWRDob-_N-8xxb-KUZlTf5No-M0,20439
|
|
69
70
|
pyinfra/facts/snap.py,sha256=6br9IMIoq88z_RS0FLXxfodIVjUmyPU9eZBa9zO8H1o,2027
|
|
70
|
-
pyinfra/facts/systemd.py,sha256=
|
|
71
|
+
pyinfra/facts/systemd.py,sha256=RS6pdcgpIvWMbQeT93O57EKXQzFzR0tF29lCAJQmaAk,4227
|
|
71
72
|
pyinfra/facts/sysvinit.py,sha256=RniaROHyeZD3jVOa_sISpZV4zx8ae8HkUQrtriLIlWc,1521
|
|
72
73
|
pyinfra/facts/upstart.py,sha256=HYR7vJ6oqtuRhxXQgzGDKYzyKqqVsjT-TtPPWOjBGdA,635
|
|
73
74
|
pyinfra/facts/vzctl.py,sha256=S9aclpDBF3DmBLwMltsd9j3B4QxQ5-1Kb1hybZodEqI,678
|
|
74
75
|
pyinfra/facts/xbps.py,sha256=4gAajBlTAg3bo7vRdx3b2TTi-vvU1y86WZqC0H9nUUk,573
|
|
75
76
|
pyinfra/facts/yum.py,sha256=i42g0FIZg62TZFqFcaUQWNekFFFo4G8vf5wyaKUuh8Q,938
|
|
77
|
+
pyinfra/facts/zfs.py,sha256=MKqh1AEa5Bpa0KDT673e92TiOb8K7YHoEg-Xo424De8,1311
|
|
76
78
|
pyinfra/facts/zypper.py,sha256=sAIZ5SqjsJ1Dc5e3pJrOoR5Gnu9BqZHpDFI8gKLts84,873
|
|
77
79
|
pyinfra/facts/util/__init__.py,sha256=f7HKu8z9_yFC899ajJ3RFiyivioaZeGfOI6nf9GviCs,521
|
|
78
80
|
pyinfra/facts/util/databases.py,sha256=EphGQApzRBXI2nG1FL9h8bozY-o4SgdQgpv9YcnCkxs,730
|
|
@@ -80,33 +82,34 @@ pyinfra/facts/util/packaging.py,sha256=4RzjDYb3HrRWZuuPlEfYHgbftLH4r1FOccN5QyIGk
|
|
|
80
82
|
pyinfra/facts/util/win_files.py,sha256=S_IQ5kJD6ZgkEcVHajgh7BIMolLV-1q1ghIcwAS-E1Q,2561
|
|
81
83
|
pyinfra/operations/__init__.py,sha256=SOcW337KXIzD_LH-iJJfq14BQcCs5JzwswJ0PIzDgF4,357
|
|
82
84
|
pyinfra/operations/apk.py,sha256=_0vOjbSiGx6EWv9rvTmQdGnRZQ_NA_Dyd3QW1cTzFgI,2111
|
|
83
|
-
pyinfra/operations/apt.py,sha256=
|
|
85
|
+
pyinfra/operations/apt.py,sha256=JztxgKeSTienk8pFWCK9vfH-Gg7i1AtUCFbTZDptcuA,13884
|
|
84
86
|
pyinfra/operations/brew.py,sha256=aghLE4qyuhhRbt6fgSPV6_5fyWgTohA77Dc0gol19UU,5155
|
|
85
87
|
pyinfra/operations/bsdinit.py,sha256=okQUQDr2H8Z-cAdfdbPJiuGujsHLuV5gpuMZ1UlICEM,1648
|
|
86
88
|
pyinfra/operations/cargo.py,sha256=mXWd6pb0IR6kzJMmPHwXZN-VJ-B_y8AdOFlrRzDQOZI,1104
|
|
87
89
|
pyinfra/operations/choco.py,sha256=8nG0wc1tZEA0L0HTIjgR00IDiONARokyzHyKj-R3xmo,1515
|
|
88
90
|
pyinfra/operations/dnf.py,sha256=3154Rer6dejVB1AK-CqyJhpMVn_djaSDJrVMs62GNcE,5599
|
|
89
|
-
pyinfra/operations/docker.py,sha256=
|
|
90
|
-
pyinfra/operations/files.py,sha256=
|
|
91
|
+
pyinfra/operations/docker.py,sha256=RMkrVpS-eeN5zwGnpb3WeeOAoGvFma-A1aPvjE9M1KY,8336
|
|
92
|
+
pyinfra/operations/files.py,sha256=M3Dj9dfBpqNnHxrm0gjDq5kNK_8ERL6iV-TEMme2S0M,54092
|
|
93
|
+
pyinfra/operations/flatpak.py,sha256=c2OAyuAvt3alVm9D8W6gCfmk5JFydcZD36gO_OhB8Bc,1891
|
|
91
94
|
pyinfra/operations/gem.py,sha256=2C85sOwIRMHGvmPg4uAlUVf6MokhiA7LLPqzdJRHsBg,1132
|
|
92
|
-
pyinfra/operations/git.py,sha256=
|
|
95
|
+
pyinfra/operations/git.py,sha256=HXBq07YtEQSo-3bkjBvMem5WzeemQ4omHkh6txQxQKs,12487
|
|
93
96
|
pyinfra/operations/iptables.py,sha256=brYa4kMhZKFTu24BNds_1b6sOaG94EfqWEoWrScx-Ck,9341
|
|
94
97
|
pyinfra/operations/launchd.py,sha256=6HWvqoQ74idV_NStOEmFXwu0dmTv7YDvFtsK8An2Lu4,1177
|
|
95
98
|
pyinfra/operations/lxd.py,sha256=bKm9gsgZaruKYSL7OYFMiou-wGP4BzwIMWzjW4AZYrk,1742
|
|
96
|
-
pyinfra/operations/mysql.py,sha256=
|
|
99
|
+
pyinfra/operations/mysql.py,sha256=ctm2Z6MaB0mOArCNU4TsJzaXiKXQaa_ahmsC5Vvyi10,19857
|
|
97
100
|
pyinfra/operations/npm.py,sha256=bUmfQsClZ2YcHiihiC7k5widIXIi6lbfx_32iyaAKfo,1499
|
|
98
101
|
pyinfra/operations/openrc.py,sha256=GXFoCHEEKeyQyRvrZcNYx8og4fmgmtzTVAViBzt84TE,1580
|
|
99
102
|
pyinfra/operations/pacman.py,sha256=QMjmsBiiw362nhZY0rEDVQL5A32MG3u7GcmX4q4PzfI,1702
|
|
100
103
|
pyinfra/operations/pip.py,sha256=7PpQvZHnwBGZ60V5b0XKNR4tHLW0MXJo6_6UX7HBtGY,5856
|
|
101
104
|
pyinfra/operations/pkg.py,sha256=rORQBbKeb-6gS0LYu0a0VdiWcDZoovcUONCaf6KMdeQ,2298
|
|
102
105
|
pyinfra/operations/pkgin.py,sha256=zhUyGzKjnUfGoyHbMoYMbeeMzcsiOUpBz1zIzppigJ0,1992
|
|
103
|
-
pyinfra/operations/postgres.py,sha256=
|
|
106
|
+
pyinfra/operations/postgres.py,sha256=eh3wjX-l4ri-q3mgfV2bdmVs3m87s3C1_EbJUFss9u4,9700
|
|
104
107
|
pyinfra/operations/postgresql.py,sha256=agZjL2W4yxigk9ThIC0V_3wvmcWVdX308aJO24WkN6g,833
|
|
105
108
|
pyinfra/operations/puppet.py,sha256=eDe8D9jQbHYQ4_r4-dmEZfMASKQvj36BR8z_h8aDfw8,861
|
|
106
109
|
pyinfra/operations/python.py,sha256=u569cdPrPesrmzU09nwIPA3bk6TZ-Qv2QP0lJLcO_bw,2021
|
|
107
110
|
pyinfra/operations/runit.py,sha256=jRR5kt1OUCLbYktnu7yl3YvSiTW51VvEvOuB0yfd7Ww,5126
|
|
108
111
|
pyinfra/operations/selinux.py,sha256=imZ4dbY4tl0GpBSkUgV983jbDDihWNs_OQkOBulT7FQ,5948
|
|
109
|
-
pyinfra/operations/server.py,sha256=
|
|
112
|
+
pyinfra/operations/server.py,sha256=0xDKY9tM7ZvGYxj5zWppmP1fhLUBeGxSsnAxciGifnI,36572
|
|
110
113
|
pyinfra/operations/snap.py,sha256=a-QtNE4Dlsavqq425TUIwpEJu4oGw8UlLRkdTFyT1F8,3049
|
|
111
114
|
pyinfra/operations/ssh.py,sha256=wocoaYDlOhhItItAVQCEfnVowTtkg3AP0hQ3mnpUnl0,5634
|
|
112
115
|
pyinfra/operations/systemd.py,sha256=hPHTjASj6N_fRAzLr3DNHnxxIbiiTIIT9UStSxKDkTk,3984
|
|
@@ -115,6 +118,7 @@ pyinfra/operations/upstart.py,sha256=pHb9RGnVhT14A_y6OezfOH-lmniKpiyJqpeoOJl0beE
|
|
|
115
118
|
pyinfra/operations/vzctl.py,sha256=2u2CDkuDjzHBRQ54HfyfLpLrsbT8U7_05EEjbbhKUiU,3110
|
|
116
119
|
pyinfra/operations/xbps.py,sha256=ru3_srMBUyUXGzAsPo7WwoomfM0AeDglFv8CDqB33B0,1508
|
|
117
120
|
pyinfra/operations/yum.py,sha256=Ig7AzQy1C7I8XM37lWbw0nI5lzFGMoX30P8FV8-V5uA,5600
|
|
121
|
+
pyinfra/operations/zfs.py,sha256=CYaKf_Yealluo0suk9vuhxt-vEUlLfTVbAO35oalvT8,5271
|
|
118
122
|
pyinfra/operations/zypper.py,sha256=z1CWv2uwWBlCLIhHna7U5DojVoKZYoUYpezJ_FM_xK8,5555
|
|
119
123
|
pyinfra/operations/util/__init__.py,sha256=ZAHjeCXtLo0TIOSfZ9h0Sh5IXXRCspfHs3RR1l8tQCE,366
|
|
120
124
|
pyinfra/operations/util/docker.py,sha256=6CvQgeFAXH_lDqKb7RxWpMvlCDwEAXlBaDZoJ8LxrYg,4596
|
|
@@ -125,11 +129,11 @@ pyinfra_cli/__init__.py,sha256=G0X7tNdqT45uWuK3aHIKxMdDeCgJ7zHo6vbxoG6zy_8,284
|
|
|
125
129
|
pyinfra_cli/__main__.py,sha256=WlW7eP0rrL06eguuD_q2RAqgUjg3SW-QnmrayAh2mBQ,887
|
|
126
130
|
pyinfra_cli/commands.py,sha256=J-mCJYvDebJ8M7o3HreB2zToa871-xO6_KjVhPLeHho,1832
|
|
127
131
|
pyinfra_cli/exceptions.py,sha256=iptx9Zj1od7VgSbOyXs7P8tD4zAZ_fwrQFKPlpPrfS0,4806
|
|
128
|
-
pyinfra_cli/inventory.py,sha256=
|
|
132
|
+
pyinfra_cli/inventory.py,sha256=vuSL7dU31hxazHmJoUI0c6QjdItG78x8O5ifLUWuMeI,11292
|
|
129
133
|
pyinfra_cli/log.py,sha256=7WEGtmf3ncF1BtXL2icUjyxeRKy-7XrCcQ2Hg4GWX5Y,2201
|
|
130
134
|
pyinfra_cli/main.py,sha256=5VTniMcbKuIfjPTzaUklad5fM1BW7CUEARoSV9tPf1U,19954
|
|
131
|
-
pyinfra_cli/prints.py,sha256=
|
|
132
|
-
pyinfra_cli/util.py,sha256=
|
|
135
|
+
pyinfra_cli/prints.py,sha256=heCF-ugz0F8gTSr--rYVtRqN6jpAun5DUA4cy0F8l5A,9696
|
|
136
|
+
pyinfra_cli/util.py,sha256=s3-Y2AnRaLLULneaDw8YX1scWTFvGBPADPpYf3RtBms,6362
|
|
133
137
|
pyinfra_cli/virtualenv.py,sha256=6j9W54JkQLN02SrZZIVwszp0GxlaaDEUWFZjBDHIWNA,2466
|
|
134
138
|
tests/test_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
135
139
|
tests/test_api/test_api.py,sha256=Ig2ebkNACYbHcC4_zRkxS9vj5ZEogoPqGx30ErIKChg,2413
|
|
@@ -139,15 +143,15 @@ tests/test_api/test_api_config.py,sha256=bf0mDrUie3On6zGC_hJBpv-wvSf3LHBIBzUDvko
|
|
|
139
143
|
tests/test_api/test_api_deploys.py,sha256=h_zbI6CK4K8SdzEr3LEAMPxOf9hnQBdi_suqiNPqHHQ,4200
|
|
140
144
|
tests/test_api/test_api_facts.py,sha256=WnKwgLq7sk2LNO5IgIZbO5HRkDr-2GdUWO_EFfTjhO8,10695
|
|
141
145
|
tests/test_api/test_api_host.py,sha256=U_VW2vTl35vR8EdyIGMKr4y0ydsDLbvHSjZDa99CyNE,1119
|
|
142
|
-
tests/test_api/test_api_inventory.py,sha256=
|
|
146
|
+
tests/test_api/test_api_inventory.py,sha256=rqXd3e_Wwc-SxCzxgR5eLd7ZOdrF8CcHbcTZndLy5gE,2744
|
|
143
147
|
tests/test_api/test_api_operations.py,sha256=GUfnuHK2NoTAGdOT4AbytT9R8i3ZZIvGP7KBfoYcYUQ,20134
|
|
144
148
|
tests/test_api/test_api_util.py,sha256=uHv4oLpoy1_tzOoqFA1zpdvC74SvjitZbxQwp0dmjTs,1716
|
|
145
149
|
tests/test_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
146
150
|
tests/test_cli/test_cli.py,sha256=IeWuhkhLzIkRbOEx5-yaW6xV5l4Y8fxaGaDGlMcOyYE,6016
|
|
147
151
|
tests/test_cli/test_cli_deploy.py,sha256=3tlXpN_ntCvZDeymfQKrZm0kgADkiLUIAGQg5V8-KrU,5079
|
|
148
|
-
tests/test_cli/test_cli_exceptions.py,sha256=
|
|
152
|
+
tests/test_cli/test_cli_exceptions.py,sha256=QaUv40q6Tp0HdcVEvPggFF4dsP2qdy57y9VAcGcR1So,3060
|
|
149
153
|
tests/test_cli/test_cli_inventory.py,sha256=xlo-p3HdfVPNqxi7SknEZ2mWrKsdDaK3PoVN-tl95Z0,2394
|
|
150
|
-
tests/test_cli/test_cli_util.py,sha256
|
|
154
|
+
tests/test_cli/test_cli_util.py,sha256=Fqn_9fnG6xNfw8OMHSZs9hQoW260aSt409S1bUAJs-Q,2500
|
|
151
155
|
tests/test_cli/test_context_objects.py,sha256=JiUTwQP7yvcqA47Kq9jtdsB_Z8nxGMZN46d9pR--FYA,2130
|
|
152
156
|
tests/test_cli/util.py,sha256=kp_-XsGnTyDgG6IHWorYzl5VD_WLe77dKOH007TDOUE,338
|
|
153
157
|
tests/test_connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -157,12 +161,12 @@ tests/test_connectors/test_dockerssh.py,sha256=MaC9IK1OZDiqoIsuLOZBJnPDglsMoPDoL
|
|
|
157
161
|
tests/test_connectors/test_local.py,sha256=N_FkejDZKu7XLnKeApqfBARYMyxf-hRXCQJrXLHvwRg,7442
|
|
158
162
|
tests/test_connectors/test_ssh.py,sha256=zYL0FbRXzqkYJslhmVeUgSkcHtozhmvZfRcaqDrYKvI,40386
|
|
159
163
|
tests/test_connectors/test_sshuserclient.py,sha256=2PQNLPhNL6lBACc6tQuXmPoog-9L6AdDQNrA-rEw1_8,5734
|
|
160
|
-
tests/test_connectors/test_terraform.py,sha256=
|
|
164
|
+
tests/test_connectors/test_terraform.py,sha256=RZInSjes394eR5CrGGEjzZEFY-UpQj47n4MZH0_ExyY,3779
|
|
161
165
|
tests/test_connectors/test_util.py,sha256=hQir0WyjH0LEF6xvIyHNyqdI5pkJX6qUR9287MgO2bY,4647
|
|
162
166
|
tests/test_connectors/test_vagrant.py,sha256=27qRB7ftjEPaj4ejBNZ-rR4Ou1AD1VyVcf2XjwZPG3M,3640
|
|
163
|
-
pyinfra-3.
|
|
164
|
-
pyinfra-3.
|
|
165
|
-
pyinfra-3.
|
|
166
|
-
pyinfra-3.
|
|
167
|
-
pyinfra-3.
|
|
168
|
-
pyinfra-3.
|
|
167
|
+
pyinfra-3.1.1.dist-info/LICENSE.md,sha256=gwC95tUll0gwB32tHNkTAasN7Sb6vjWzXa305NwClbI,1076
|
|
168
|
+
pyinfra-3.1.1.dist-info/METADATA,sha256=j3fopNCs_edZ2bzLHKAjoCv7_1CFph0D5q56yBJa-sg,8041
|
|
169
|
+
pyinfra-3.1.1.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
|
|
170
|
+
pyinfra-3.1.1.dist-info/entry_points.txt,sha256=BraEFyquy05M8ch33HZXOHoH_m2BTqejL3xX3NrpzOM,471
|
|
171
|
+
pyinfra-3.1.1.dist-info/top_level.txt,sha256=2K6D1mK35JTSEBgOfEPV-N-uA2SDErxGiE0J-HUMMVI,26
|
|
172
|
+
pyinfra-3.1.1.dist-info/RECORD,,
|
pyinfra_cli/inventory.py
CHANGED
|
@@ -6,6 +6,7 @@ from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar, Union
|
|
|
6
6
|
|
|
7
7
|
from pyinfra import logger
|
|
8
8
|
from pyinfra.api.inventory import Inventory
|
|
9
|
+
from pyinfra.connectors.sshuserclient.client import get_ssh_config
|
|
9
10
|
from pyinfra.context import ctx_inventory
|
|
10
11
|
|
|
11
12
|
from .exceptions import CliError
|
|
@@ -88,7 +89,34 @@ def _resolves_to_host(maybe_host: str) -> bool:
|
|
|
88
89
|
socket.getaddrinfo(maybe_host, port=None)
|
|
89
90
|
return True
|
|
90
91
|
except socket.gaierror:
|
|
91
|
-
|
|
92
|
+
alias = _get_ssh_alias(maybe_host)
|
|
93
|
+
if not alias:
|
|
94
|
+
return False
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
socket.getaddrinfo(alias, port=None)
|
|
98
|
+
return True
|
|
99
|
+
except socket.gaierror:
|
|
100
|
+
return False
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _get_ssh_alias(maybe_host: str) -> Optional[str]:
|
|
104
|
+
logger.debug('Checking if "%s" is an SSH alias', maybe_host)
|
|
105
|
+
|
|
106
|
+
# Note this does not cover the case where `host.data.ssh_config_file` is used
|
|
107
|
+
ssh_config = get_ssh_config()
|
|
108
|
+
|
|
109
|
+
if ssh_config is None:
|
|
110
|
+
logger.debug("Could not load SSH config")
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
options = ssh_config.lookup(maybe_host)
|
|
114
|
+
alias = options.get("hostname")
|
|
115
|
+
|
|
116
|
+
if alias is None or maybe_host == alias:
|
|
117
|
+
return None
|
|
118
|
+
|
|
119
|
+
return alias
|
|
92
120
|
|
|
93
121
|
|
|
94
122
|
def make_inventory(
|
|
@@ -105,7 +133,11 @@ def make_inventory(
|
|
|
105
133
|
# (1) an inventory file is a common use case and (2) no other option can have a comma or an @
|
|
106
134
|
# symbol in them.
|
|
107
135
|
is_path_or_host_list_or_connector = (
|
|
108
|
-
path.exists(inventory)
|
|
136
|
+
path.exists(inventory)
|
|
137
|
+
or "," in inventory
|
|
138
|
+
or "@" in inventory
|
|
139
|
+
# Special case: passing an arbitrary name and specifying --data ssh_hostname=a.b.c
|
|
140
|
+
or (override_data is not None and "ssh_hostname" in override_data)
|
|
109
141
|
)
|
|
110
142
|
if not is_path_or_host_list_or_connector:
|
|
111
143
|
# Next, try loading the inventory from a python function. This happens before checking for a
|
pyinfra_cli/prints.py
CHANGED
|
@@ -131,6 +131,10 @@ def print_facts(facts):
|
|
|
131
131
|
|
|
132
132
|
|
|
133
133
|
def print_support_info():
|
|
134
|
+
from importlib.metadata import PackageNotFoundError, requires, version
|
|
135
|
+
|
|
136
|
+
from packaging.requirements import Requirement
|
|
137
|
+
|
|
134
138
|
click.echo(
|
|
135
139
|
"""
|
|
136
140
|
If you are having issues with pyinfra or wish to make feature requests, please
|
|
@@ -144,6 +148,18 @@ def print_support_info():
|
|
|
144
148
|
click.echo(" Release: {0}".format(platform.uname()[2]), err=True)
|
|
145
149
|
click.echo(" Machine: {0}".format(platform.uname()[4]), err=True)
|
|
146
150
|
click.echo(" pyinfra: v{0}".format(__version__), err=True)
|
|
151
|
+
|
|
152
|
+
for requirement_string in sorted(requires("pyinfra") or []):
|
|
153
|
+
requirement = Requirement(requirement_string)
|
|
154
|
+
try:
|
|
155
|
+
click.echo(
|
|
156
|
+
" {0}: v{1}".format(requirement.name, version(requirement.name)),
|
|
157
|
+
err=True,
|
|
158
|
+
)
|
|
159
|
+
except PackageNotFoundError:
|
|
160
|
+
# package not installed in this environment
|
|
161
|
+
continue
|
|
162
|
+
|
|
147
163
|
click.echo(" Executable: {0}".format(sys.argv[0]), err=True)
|
|
148
164
|
click.echo(
|
|
149
165
|
" Python: {0} ({1}, {2})".format(
|
pyinfra_cli/util.py
CHANGED
|
@@ -180,13 +180,13 @@ def try_import_module_attribute(path, prefix=None, raise_for_none=True):
|
|
|
180
180
|
|
|
181
181
|
if module is None:
|
|
182
182
|
if raise_for_none:
|
|
183
|
-
raise CliError(f"No such module: {possible_modules[
|
|
183
|
+
raise CliError(f"No such module: {possible_modules[0]}")
|
|
184
184
|
return
|
|
185
185
|
|
|
186
186
|
attr = getattr(module, attr_name, None)
|
|
187
187
|
if attr is None:
|
|
188
188
|
if raise_for_none:
|
|
189
|
-
raise CliError(f"No such attribute in module {possible_modules[
|
|
189
|
+
raise CliError(f"No such attribute in module {possible_modules[0]}: {attr_name}")
|
|
190
190
|
return
|
|
191
191
|
|
|
192
192
|
return attr
|