pyinfra 3.0b0__py2.py3-none-any.whl → 3.0b2__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/__init__.py +3 -0
- pyinfra/api/arguments.py +12 -5
- pyinfra/api/arguments_typed.py +19 -6
- pyinfra/api/command.py +5 -3
- pyinfra/api/config.py +115 -13
- pyinfra/api/connectors.py +5 -2
- pyinfra/api/exceptions.py +19 -0
- pyinfra/api/facts.py +34 -33
- pyinfra/api/host.py +51 -12
- pyinfra/api/inventory.py +4 -0
- pyinfra/api/operation.py +88 -42
- pyinfra/api/operations.py +10 -11
- pyinfra/api/state.py +11 -2
- pyinfra/api/util.py +24 -16
- pyinfra/connectors/base.py +4 -7
- pyinfra/connectors/chroot.py +5 -6
- pyinfra/connectors/docker.py +13 -19
- pyinfra/connectors/dockerssh.py +5 -4
- pyinfra/connectors/local.py +7 -7
- pyinfra/connectors/ssh.py +46 -25
- pyinfra/connectors/terraform.py +9 -6
- pyinfra/connectors/util.py +7 -8
- pyinfra/connectors/vagrant.py +11 -10
- pyinfra/context.py +1 -0
- pyinfra/facts/apk.py +2 -0
- pyinfra/facts/apt.py +2 -0
- pyinfra/facts/brew.py +2 -0
- pyinfra/facts/bsdinit.py +2 -0
- pyinfra/facts/cargo.py +2 -0
- pyinfra/facts/choco.py +3 -1
- pyinfra/facts/deb.py +9 -4
- pyinfra/facts/dnf.py +2 -0
- pyinfra/facts/docker.py +2 -0
- pyinfra/facts/files.py +2 -0
- pyinfra/facts/gem.py +2 -0
- pyinfra/facts/gpg.py +2 -0
- pyinfra/facts/hardware.py +30 -22
- pyinfra/facts/launchd.py +2 -0
- pyinfra/facts/lxd.py +2 -0
- pyinfra/facts/mysql.py +12 -6
- pyinfra/facts/npm.py +1 -0
- pyinfra/facts/openrc.py +2 -0
- pyinfra/facts/pacman.py +6 -2
- pyinfra/facts/pip.py +2 -0
- pyinfra/facts/pkg.py +2 -0
- pyinfra/facts/pkgin.py +2 -0
- pyinfra/facts/postgres.py +168 -0
- pyinfra/facts/postgresql.py +5 -162
- pyinfra/facts/rpm.py +12 -9
- pyinfra/facts/server.py +10 -13
- pyinfra/facts/snap.py +2 -0
- pyinfra/facts/systemd.py +28 -10
- pyinfra/facts/upstart.py +2 -0
- pyinfra/facts/util/packaging.py +3 -2
- pyinfra/facts/vzctl.py +2 -0
- pyinfra/facts/xbps.py +2 -0
- pyinfra/facts/yum.py +2 -0
- pyinfra/facts/zypper.py +2 -0
- pyinfra/operations/apk.py +3 -1
- pyinfra/operations/apt.py +16 -18
- pyinfra/operations/brew.py +10 -8
- pyinfra/operations/bsdinit.py +5 -3
- pyinfra/operations/cargo.py +3 -1
- pyinfra/operations/choco.py +3 -1
- pyinfra/operations/dnf.py +15 -19
- pyinfra/operations/files.py +86 -69
- pyinfra/operations/gem.py +3 -1
- pyinfra/operations/git.py +18 -16
- pyinfra/operations/iptables.py +33 -25
- pyinfra/operations/launchd.py +5 -6
- pyinfra/operations/lxd.py +7 -4
- pyinfra/operations/mysql.py +57 -53
- pyinfra/operations/npm.py +8 -1
- pyinfra/operations/openrc.py +5 -3
- pyinfra/operations/pacman.py +4 -5
- pyinfra/operations/pip.py +16 -9
- pyinfra/operations/pkg.py +3 -1
- pyinfra/operations/pkgin.py +3 -1
- pyinfra/operations/postgres.py +349 -0
- pyinfra/operations/postgresql.py +18 -335
- pyinfra/operations/puppet.py +3 -1
- pyinfra/operations/python.py +7 -3
- pyinfra/operations/selinux.py +42 -16
- pyinfra/operations/server.py +48 -43
- pyinfra/operations/snap.py +3 -1
- pyinfra/operations/ssh.py +12 -10
- pyinfra/operations/systemd.py +13 -9
- pyinfra/operations/sysvinit.py +6 -4
- pyinfra/operations/upstart.py +5 -3
- pyinfra/operations/util/files.py +24 -16
- pyinfra/operations/util/packaging.py +53 -37
- pyinfra/operations/util/service.py +18 -13
- pyinfra/operations/vzctl.py +12 -10
- pyinfra/operations/xbps.py +3 -1
- pyinfra/operations/yum.py +14 -18
- pyinfra/operations/zypper.py +8 -9
- pyinfra/version.py +5 -2
- {pyinfra-3.0b0.dist-info → pyinfra-3.0b2.dist-info}/METADATA +31 -29
- pyinfra-3.0b2.dist-info/RECORD +163 -0
- {pyinfra-3.0b0.dist-info → pyinfra-3.0b2.dist-info}/WHEEL +1 -1
- pyinfra_cli/commands.py +3 -2
- pyinfra_cli/inventory.py +38 -19
- pyinfra_cli/main.py +2 -0
- pyinfra_cli/prints.py +27 -105
- pyinfra_cli/util.py +3 -1
- tests/test_api/test_api_deploys.py +5 -5
- tests/test_api/test_api_operations.py +5 -5
- tests/test_connectors/test_ssh.py +105 -0
- tests/test_connectors/test_terraform.py +11 -8
- tests/test_connectors/test_vagrant.py +6 -6
- pyinfra-3.0b0.dist-info/RECORD +0 -162
- pyinfra_cli/inventory_dsl.py +0 -23
- {pyinfra-3.0b0.dist-info → pyinfra-3.0b2.dist-info}/LICENSE.md +0 -0
- {pyinfra-3.0b0.dist-info → pyinfra-3.0b2.dist-info}/entry_points.txt +0 -0
- {pyinfra-3.0b0.dist-info → pyinfra-3.0b2.dist-info}/top_level.txt +0 -0
pyinfra/operations/files.py
CHANGED
|
@@ -11,7 +11,8 @@ import traceback
|
|
|
11
11
|
from datetime import timedelta
|
|
12
12
|
from fnmatch import fnmatch
|
|
13
13
|
from io import StringIO
|
|
14
|
-
from
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import IO, Any, Union
|
|
15
16
|
|
|
16
17
|
from jinja2 import TemplateRuntimeError, TemplateSyntaxError, UndefinedError
|
|
17
18
|
|
|
@@ -30,6 +31,7 @@ from pyinfra.api import (
|
|
|
30
31
|
from pyinfra.api.command import make_formatted_string_command
|
|
31
32
|
from pyinfra.api.util import (
|
|
32
33
|
get_call_location,
|
|
34
|
+
get_file_io,
|
|
33
35
|
get_file_sha1,
|
|
34
36
|
get_path_permissions_mode,
|
|
35
37
|
get_template,
|
|
@@ -58,19 +60,19 @@ from .util.files import adjust_regex, ensure_mode_int, get_timestamp, sed_replac
|
|
|
58
60
|
|
|
59
61
|
@operation()
|
|
60
62
|
def download(
|
|
61
|
-
src,
|
|
62
|
-
dest,
|
|
63
|
-
user=None,
|
|
64
|
-
group=None,
|
|
65
|
-
mode=None,
|
|
66
|
-
cache_time=None,
|
|
63
|
+
src: str,
|
|
64
|
+
dest: str,
|
|
65
|
+
user: str | None = None,
|
|
66
|
+
group: str | None = None,
|
|
67
|
+
mode: str | None = None,
|
|
68
|
+
cache_time: int | None = None,
|
|
67
69
|
force=False,
|
|
68
|
-
sha256sum=None,
|
|
69
|
-
sha1sum=None,
|
|
70
|
-
md5sum=None,
|
|
71
|
-
headers=None,
|
|
70
|
+
sha256sum: str | None = None,
|
|
71
|
+
sha1sum: str | None = None,
|
|
72
|
+
md5sum: str | None = None,
|
|
73
|
+
headers: dict[str, str] | None = None,
|
|
72
74
|
insecure=False,
|
|
73
|
-
proxy=None,
|
|
75
|
+
proxy: str | None = None,
|
|
74
76
|
):
|
|
75
77
|
"""
|
|
76
78
|
Download files from remote locations using ``curl`` or ``wget``.
|
|
@@ -121,8 +123,8 @@ def download(
|
|
|
121
123
|
if cache_time:
|
|
122
124
|
# Time on files is not tz-aware, and will be the same tz as the server's time,
|
|
123
125
|
# so we can safely remove the tzinfo from the Date fact before comparison.
|
|
124
|
-
|
|
125
|
-
if info["mtime"] and info["mtime"] <
|
|
126
|
+
ctime = host.get_fact(Date).replace(tzinfo=None) - timedelta(seconds=cache_time)
|
|
127
|
+
if info["mtime"] and info["mtime"] < ctime:
|
|
126
128
|
download = True
|
|
127
129
|
|
|
128
130
|
if sha1sum:
|
|
@@ -225,11 +227,11 @@ def download(
|
|
|
225
227
|
|
|
226
228
|
@operation()
|
|
227
229
|
def line(
|
|
228
|
-
path,
|
|
229
|
-
line,
|
|
230
|
+
path: str,
|
|
231
|
+
line: str,
|
|
230
232
|
present=True,
|
|
231
|
-
replace=None,
|
|
232
|
-
flags=None,
|
|
233
|
+
replace: str | None = None,
|
|
234
|
+
flags: list[str] | None = None,
|
|
233
235
|
backup=False,
|
|
234
236
|
interpolate_variables=False,
|
|
235
237
|
escape_regex_characters=False,
|
|
@@ -267,7 +269,7 @@ def line(
|
|
|
267
269
|
it will be append to the end of the file.
|
|
268
270
|
|
|
269
271
|
Ensure new line:
|
|
270
|
-
This will ensure that the ``line`` being appended is always on a
|
|
272
|
+
This will ensure that the ``line`` being appended is always on a separate new
|
|
271
273
|
line in case the file doesn't end with a newline character.
|
|
272
274
|
|
|
273
275
|
|
|
@@ -425,10 +427,10 @@ def line(
|
|
|
425
427
|
|
|
426
428
|
@operation()
|
|
427
429
|
def replace(
|
|
428
|
-
path,
|
|
429
|
-
text=None,
|
|
430
|
-
replace=None,
|
|
431
|
-
flags=None,
|
|
430
|
+
path: str,
|
|
431
|
+
text: str | None = None,
|
|
432
|
+
replace: str | None = None,
|
|
433
|
+
flags: list[str] | None = None,
|
|
432
434
|
backup=False,
|
|
433
435
|
interpolate_variables=False,
|
|
434
436
|
match=None, # deprecated
|
|
@@ -499,15 +501,15 @@ def replace(
|
|
|
499
501
|
|
|
500
502
|
@operation()
|
|
501
503
|
def sync(
|
|
502
|
-
src,
|
|
503
|
-
dest,
|
|
504
|
-
user=None,
|
|
505
|
-
group=None,
|
|
506
|
-
mode=None,
|
|
507
|
-
dir_mode=None,
|
|
504
|
+
src: str,
|
|
505
|
+
dest: str,
|
|
506
|
+
user: str | None = None,
|
|
507
|
+
group: str | None = None,
|
|
508
|
+
mode: str | None = None,
|
|
509
|
+
dir_mode: str | None = None,
|
|
508
510
|
delete=False,
|
|
509
|
-
exclude=None,
|
|
510
|
-
exclude_dir=None,
|
|
511
|
+
exclude: str | list[str] | tuple[str] | None = None,
|
|
512
|
+
exclude_dir: str | list[str] | tuple[str] | None = None,
|
|
511
513
|
add_deploy_dir=True,
|
|
512
514
|
):
|
|
513
515
|
"""
|
|
@@ -569,7 +571,7 @@ def sync(
|
|
|
569
571
|
put_files = []
|
|
570
572
|
ensure_dirnames = []
|
|
571
573
|
for dirpath, dirnames, filenames in os.walk(src, topdown=True):
|
|
572
|
-
remote_dirpath = os.path.normpath(os.path.relpath(dirpath, src))
|
|
574
|
+
remote_dirpath = Path(os.path.normpath(os.path.relpath(dirpath, src))).as_posix()
|
|
573
575
|
|
|
574
576
|
# Filter excluded dirs
|
|
575
577
|
for child_dir in dirnames[:]:
|
|
@@ -650,7 +652,7 @@ def show_rsync_warning():
|
|
|
650
652
|
|
|
651
653
|
|
|
652
654
|
@operation(is_idempotent=False)
|
|
653
|
-
def rsync(src, dest, flags
|
|
655
|
+
def rsync(src: str, dest: str, flags: list[str] | None = None):
|
|
654
656
|
"""
|
|
655
657
|
Use ``rsync`` to sync a local directory to the remote system. This operation will actually call
|
|
656
658
|
the ``rsync`` binary on your system.
|
|
@@ -665,6 +667,8 @@ def rsync(src, dest, flags=["-ax", "--delete"]):
|
|
|
665
667
|
global arguments.
|
|
666
668
|
"""
|
|
667
669
|
|
|
670
|
+
if flags is None:
|
|
671
|
+
flags = ["-ax", "--delete"]
|
|
668
672
|
show_rsync_warning()
|
|
669
673
|
|
|
670
674
|
try:
|
|
@@ -694,8 +698,8 @@ def _create_remote_dir(remote_filename, user, group):
|
|
|
694
698
|
is_idempotent=False,
|
|
695
699
|
)
|
|
696
700
|
def get(
|
|
697
|
-
src,
|
|
698
|
-
dest,
|
|
701
|
+
src: str,
|
|
702
|
+
dest: str,
|
|
699
703
|
add_deploy_dir=True,
|
|
700
704
|
create_local_dir=False,
|
|
701
705
|
force=False,
|
|
@@ -754,11 +758,11 @@ def get(
|
|
|
754
758
|
|
|
755
759
|
@operation()
|
|
756
760
|
def put(
|
|
757
|
-
src,
|
|
758
|
-
dest,
|
|
759
|
-
user=None,
|
|
760
|
-
group=None,
|
|
761
|
-
mode=None,
|
|
761
|
+
src: str | IO[Any],
|
|
762
|
+
dest: str,
|
|
763
|
+
user: str | None = None,
|
|
764
|
+
group: str | None = None,
|
|
765
|
+
mode: int | str | bool | None = None,
|
|
762
766
|
add_deploy_dir=True,
|
|
763
767
|
create_remote_dir=True,
|
|
764
768
|
force=False,
|
|
@@ -819,6 +823,7 @@ def put(
|
|
|
819
823
|
|
|
820
824
|
# Assume string filename
|
|
821
825
|
else:
|
|
826
|
+
assert isinstance(src, (str, Path))
|
|
822
827
|
# Add deploy directory?
|
|
823
828
|
if add_deploy_dir and state.cwd:
|
|
824
829
|
src = os.path.join(state.cwd, src)
|
|
@@ -833,7 +838,7 @@ def put(
|
|
|
833
838
|
raise IOError("No such file: {0}".format(local_file))
|
|
834
839
|
|
|
835
840
|
if mode is True:
|
|
836
|
-
if os.path.isfile(local_file):
|
|
841
|
+
if isinstance(local_file, str) and os.path.isfile(local_file):
|
|
837
842
|
mode = get_path_permissions_mode(local_file)
|
|
838
843
|
else:
|
|
839
844
|
logger.warning(
|
|
@@ -847,6 +852,7 @@ def put(
|
|
|
847
852
|
remote_file = host.get_fact(File, path=dest)
|
|
848
853
|
|
|
849
854
|
if not remote_file and bool(host.get_fact(Directory, path=dest)):
|
|
855
|
+
assert isinstance(src, str)
|
|
850
856
|
dest = unix_path_join(dest, os.path.basename(src))
|
|
851
857
|
remote_file = host.get_fact(File, path=dest)
|
|
852
858
|
|
|
@@ -903,7 +909,15 @@ def put(
|
|
|
903
909
|
|
|
904
910
|
|
|
905
911
|
@operation()
|
|
906
|
-
def template(
|
|
912
|
+
def template(
|
|
913
|
+
src: str | IO[Any],
|
|
914
|
+
dest: str,
|
|
915
|
+
user: str | None = None,
|
|
916
|
+
group: str | None = None,
|
|
917
|
+
mode: str | None = None,
|
|
918
|
+
create_remote_dir=True,
|
|
919
|
+
**data,
|
|
920
|
+
):
|
|
907
921
|
'''
|
|
908
922
|
Generate a template using jinja2 and write it to the remote system.
|
|
909
923
|
|
|
@@ -999,7 +1013,7 @@ def template(src, dest, user=None, group=None, mode=None, create_remote_dir=True
|
|
|
999
1013
|
line_number = trace_frames[-1][1]
|
|
1000
1014
|
|
|
1001
1015
|
# Quickly read the line in question and one above/below for nicer debugging
|
|
1002
|
-
with
|
|
1016
|
+
with get_file_io(src, "r") as f:
|
|
1003
1017
|
template_lines = f.readlines()
|
|
1004
1018
|
|
|
1005
1019
|
template_lines = [line.strip() for line in template_lines]
|
|
@@ -1012,7 +1026,7 @@ def template(src, dest, user=None, group=None, mode=None, create_remote_dir=True
|
|
|
1012
1026
|
e,
|
|
1013
1027
|
"\n".join(relevant_lines),
|
|
1014
1028
|
),
|
|
1015
|
-
)
|
|
1029
|
+
) from None
|
|
1016
1030
|
|
|
1017
1031
|
output_file = StringIO(output)
|
|
1018
1032
|
# Set the template attribute for nicer debugging
|
|
@@ -1053,16 +1067,16 @@ def _raise_or_remove_invalid_path(fs_type, path, force, force_backup, force_back
|
|
|
1053
1067
|
|
|
1054
1068
|
@operation()
|
|
1055
1069
|
def link(
|
|
1056
|
-
path,
|
|
1057
|
-
target=None,
|
|
1070
|
+
path: str,
|
|
1071
|
+
target: str | None = None,
|
|
1058
1072
|
present=True,
|
|
1059
|
-
user=None,
|
|
1060
|
-
group=None,
|
|
1073
|
+
user: str | None = None,
|
|
1074
|
+
group: str | None = None,
|
|
1061
1075
|
symbolic=True,
|
|
1062
1076
|
create_remote_dir=True,
|
|
1063
1077
|
force=False,
|
|
1064
1078
|
force_backup=True,
|
|
1065
|
-
force_backup_dir=None,
|
|
1079
|
+
force_backup_dir: str | None = None,
|
|
1066
1080
|
):
|
|
1067
1081
|
"""
|
|
1068
1082
|
Add/remove/update links.
|
|
@@ -1160,16 +1174,16 @@ def link(
|
|
|
1160
1174
|
|
|
1161
1175
|
@operation()
|
|
1162
1176
|
def file(
|
|
1163
|
-
path,
|
|
1177
|
+
path: str,
|
|
1164
1178
|
present=True,
|
|
1165
|
-
user=None,
|
|
1166
|
-
group=None,
|
|
1167
|
-
mode=None,
|
|
1179
|
+
user: str | None = None,
|
|
1180
|
+
group: str | None = None,
|
|
1181
|
+
mode: int | str | None = None,
|
|
1168
1182
|
touch=False,
|
|
1169
1183
|
create_remote_dir=True,
|
|
1170
1184
|
force=False,
|
|
1171
1185
|
force_backup=True,
|
|
1172
|
-
force_backup_dir=None,
|
|
1186
|
+
force_backup_dir: str | None = None,
|
|
1173
1187
|
):
|
|
1174
1188
|
"""
|
|
1175
1189
|
Add/remove/update files.
|
|
@@ -1262,15 +1276,15 @@ def file(
|
|
|
1262
1276
|
|
|
1263
1277
|
@operation()
|
|
1264
1278
|
def directory(
|
|
1265
|
-
path,
|
|
1279
|
+
path: str,
|
|
1266
1280
|
present=True,
|
|
1267
|
-
user=None,
|
|
1268
|
-
group=None,
|
|
1269
|
-
mode=None,
|
|
1281
|
+
user: str | None = None,
|
|
1282
|
+
group: str | None = None,
|
|
1283
|
+
mode: int | str | None = None,
|
|
1270
1284
|
recursive=False,
|
|
1271
1285
|
force=False,
|
|
1272
1286
|
force_backup=True,
|
|
1273
|
-
force_backup_dir=None,
|
|
1287
|
+
force_backup_dir: str | None = None,
|
|
1274
1288
|
_no_check_owner_mode=False,
|
|
1275
1289
|
_no_fail_on_link=False,
|
|
1276
1290
|
):
|
|
@@ -1363,7 +1377,7 @@ def directory(
|
|
|
1363
1377
|
|
|
1364
1378
|
|
|
1365
1379
|
@operation()
|
|
1366
|
-
def flags(path, flags=None, present=True):
|
|
1380
|
+
def flags(path: str, flags: list[str] | None = None, present=True):
|
|
1367
1381
|
"""
|
|
1368
1382
|
Set/clear file flags.
|
|
1369
1383
|
|
|
@@ -1412,18 +1426,18 @@ def flags(path, flags=None, present=True):
|
|
|
1412
1426
|
|
|
1413
1427
|
@operation()
|
|
1414
1428
|
def block(
|
|
1415
|
-
path,
|
|
1416
|
-
content=None,
|
|
1429
|
+
path: str,
|
|
1430
|
+
content: str | list[str] | None = None,
|
|
1417
1431
|
present=True,
|
|
1418
|
-
line=None,
|
|
1432
|
+
line: str | None = None,
|
|
1419
1433
|
backup=False,
|
|
1420
1434
|
escape_regex_characters=False,
|
|
1421
1435
|
try_prevent_shell_expansion=False,
|
|
1422
1436
|
before=False,
|
|
1423
1437
|
after=False,
|
|
1424
|
-
marker=None,
|
|
1425
|
-
begin=None,
|
|
1426
|
-
end=None,
|
|
1438
|
+
marker: str | None = None,
|
|
1439
|
+
begin: str | None = None,
|
|
1440
|
+
end: str | None = None,
|
|
1427
1441
|
):
|
|
1428
1442
|
"""
|
|
1429
1443
|
Ensure content, surrounded by the appropriate markers, is present (or not) in the file.
|
|
@@ -1571,6 +1585,7 @@ def block(
|
|
|
1571
1585
|
f"\n{the_block}\n{here}",
|
|
1572
1586
|
)
|
|
1573
1587
|
elif current == []: # markers not found and have a pattern to match (not start or end)
|
|
1588
|
+
assert isinstance(line, str)
|
|
1574
1589
|
regex = adjust_regex(line, escape_regex_characters)
|
|
1575
1590
|
print_before = "{ print }" if before else ""
|
|
1576
1591
|
print_after = "{ print }" if after else ""
|
|
@@ -1599,9 +1614,11 @@ def block(
|
|
|
1599
1614
|
out_prep,
|
|
1600
1615
|
prog,
|
|
1601
1616
|
q_path,
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1617
|
+
(
|
|
1618
|
+
'"' + "\n".join(content) + '"'
|
|
1619
|
+
if not try_prevent_shell_expansion
|
|
1620
|
+
else "'" + "\n".join(content) + "'"
|
|
1621
|
+
),
|
|
1605
1622
|
"> $OUT &&",
|
|
1606
1623
|
real_out,
|
|
1607
1624
|
)
|
pyinfra/operations/gem.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Manage Ruby gem packages. (see https://rubygems.org/ )
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
5
7
|
from pyinfra import host
|
|
6
8
|
from pyinfra.api import operation
|
|
7
9
|
from pyinfra.facts.gem import GemPackages
|
|
@@ -10,7 +12,7 @@ from .util.packaging import ensure_packages
|
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
@operation()
|
|
13
|
-
def packages(packages=None, present=True, latest=False):
|
|
15
|
+
def packages(packages: str | list[str] | None = None, present=True, latest=False):
|
|
14
16
|
"""
|
|
15
17
|
Add/remove/update gem packages.
|
|
16
18
|
|
pyinfra/operations/git.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Manage git repositories and configuration.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
5
7
|
import re
|
|
6
8
|
|
|
7
9
|
from pyinfra import host
|
|
@@ -14,7 +16,7 @@ from .util.files import chown, unix_path_join
|
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
@operation()
|
|
17
|
-
def config(key, value, multi_value=False, repo=None):
|
|
19
|
+
def config(key: str, value: str, multi_value=False, repo: str | None = None):
|
|
18
20
|
"""
|
|
19
21
|
Manage git config for a repository or globally.
|
|
20
22
|
|
|
@@ -62,13 +64,13 @@ def config(key, value, multi_value=False, repo=None):
|
|
|
62
64
|
|
|
63
65
|
@operation()
|
|
64
66
|
def repo(
|
|
65
|
-
src,
|
|
66
|
-
dest,
|
|
67
|
-
branch=None,
|
|
67
|
+
src: str,
|
|
68
|
+
dest: str,
|
|
69
|
+
branch: str | None = None,
|
|
68
70
|
pull=True,
|
|
69
71
|
rebase=False,
|
|
70
|
-
user=None,
|
|
71
|
-
group=None,
|
|
72
|
+
user: str | None = None,
|
|
73
|
+
group: str | None = None,
|
|
72
74
|
ssh_keyscan=False,
|
|
73
75
|
update_submodules=False,
|
|
74
76
|
recursive_submodules=False,
|
|
@@ -155,19 +157,19 @@ def repo(
|
|
|
155
157
|
|
|
156
158
|
@operation()
|
|
157
159
|
def worktree(
|
|
158
|
-
worktree,
|
|
159
|
-
repo=None,
|
|
160
|
+
worktree: str,
|
|
161
|
+
repo: str | None = None,
|
|
160
162
|
detached=False,
|
|
161
|
-
new_branch=None,
|
|
162
|
-
commitish=None,
|
|
163
|
+
new_branch: str | None = None,
|
|
164
|
+
commitish: str | None = None,
|
|
163
165
|
pull=True,
|
|
164
166
|
rebase=False,
|
|
165
|
-
from_remote_branch=None,
|
|
167
|
+
from_remote_branch: tuple[str, str] | None = None,
|
|
166
168
|
present=True,
|
|
167
169
|
assume_repo_exists=False,
|
|
168
170
|
force=False,
|
|
169
|
-
user=None,
|
|
170
|
-
group=None,
|
|
171
|
+
user: str | None = None,
|
|
172
|
+
group: str | None = None,
|
|
171
173
|
):
|
|
172
174
|
"""
|
|
173
175
|
Manage git worktrees.
|
|
@@ -336,9 +338,9 @@ def worktree(
|
|
|
336
338
|
|
|
337
339
|
@operation()
|
|
338
340
|
def bare_repo(
|
|
339
|
-
path,
|
|
340
|
-
user=None,
|
|
341
|
-
group=None,
|
|
341
|
+
path: str,
|
|
342
|
+
user: str | None = None,
|
|
343
|
+
group: str | None = None,
|
|
342
344
|
present=True,
|
|
343
345
|
):
|
|
344
346
|
"""
|
pyinfra/operations/iptables.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
The iptables modules handles iptables rules
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
5
7
|
from pyinfra import host
|
|
6
8
|
from pyinfra.api import operation
|
|
7
9
|
from pyinfra.api.exceptions import OperationError
|
|
@@ -10,10 +12,10 @@ from pyinfra.facts.iptables import Ip6tablesChains, Ip6tablesRules, IptablesChai
|
|
|
10
12
|
|
|
11
13
|
@operation()
|
|
12
14
|
def chain(
|
|
13
|
-
chain,
|
|
15
|
+
chain: str,
|
|
14
16
|
present=True,
|
|
15
17
|
table="filter",
|
|
16
|
-
policy=None,
|
|
18
|
+
policy: str | None = None,
|
|
17
19
|
version=4,
|
|
18
20
|
):
|
|
19
21
|
"""
|
|
@@ -58,32 +60,32 @@ def chain(
|
|
|
58
60
|
|
|
59
61
|
@operation()
|
|
60
62
|
def rule(
|
|
61
|
-
chain,
|
|
62
|
-
jump,
|
|
63
|
-
present=True,
|
|
64
|
-
table="filter",
|
|
65
|
-
append=True,
|
|
66
|
-
version=4,
|
|
63
|
+
chain: str,
|
|
64
|
+
jump: str,
|
|
65
|
+
present: bool = True,
|
|
66
|
+
table: str = "filter",
|
|
67
|
+
append: bool = True,
|
|
68
|
+
version: int = 4,
|
|
67
69
|
# Core iptables filter arguments
|
|
68
|
-
protocol=None,
|
|
69
|
-
not_protocol=None,
|
|
70
|
-
source=None,
|
|
71
|
-
not_source=None,
|
|
72
|
-
destination=None,
|
|
73
|
-
not_destination=None,
|
|
74
|
-
in_interface=None,
|
|
75
|
-
not_in_interface=None,
|
|
76
|
-
out_interface=None,
|
|
77
|
-
not_out_interface=None,
|
|
70
|
+
protocol: str | None = None,
|
|
71
|
+
not_protocol: str | None = None,
|
|
72
|
+
source: str | None = None,
|
|
73
|
+
not_source: str | None = None,
|
|
74
|
+
destination: str | None = None,
|
|
75
|
+
not_destination: str | None = None,
|
|
76
|
+
in_interface: str | None = None,
|
|
77
|
+
not_in_interface: str | None = None,
|
|
78
|
+
out_interface: str | None = None,
|
|
79
|
+
not_out_interface: str | None = None,
|
|
78
80
|
# After-rule arguments
|
|
79
|
-
to_destination=None,
|
|
80
|
-
to_source=None,
|
|
81
|
-
to_ports=None,
|
|
82
|
-
log_prefix=None,
|
|
81
|
+
to_destination: str | None = None,
|
|
82
|
+
to_source: str | None = None,
|
|
83
|
+
to_ports: int | str | None = None,
|
|
84
|
+
log_prefix: str | None = None,
|
|
83
85
|
# Extras and extra shortcuts
|
|
84
|
-
destination_port=None,
|
|
85
|
-
source_port=None,
|
|
86
|
-
extras="",
|
|
86
|
+
destination_port: int | None = None,
|
|
87
|
+
source_port: int | None = None,
|
|
88
|
+
extras: str = "",
|
|
87
89
|
):
|
|
88
90
|
"""
|
|
89
91
|
Add/remove iptables rules.
|
|
@@ -263,6 +265,9 @@ def rule(
|
|
|
263
265
|
if source:
|
|
264
266
|
args.extend(("-s", source))
|
|
265
267
|
|
|
268
|
+
if destination:
|
|
269
|
+
args.extend(("-d", destination))
|
|
270
|
+
|
|
266
271
|
if in_interface:
|
|
267
272
|
args.extend(("-i", in_interface))
|
|
268
273
|
|
|
@@ -275,6 +280,9 @@ def rule(
|
|
|
275
280
|
if not_source:
|
|
276
281
|
args.extend(("!", "-s", not_source))
|
|
277
282
|
|
|
283
|
+
if not_destination:
|
|
284
|
+
args.extend(("!", "-d", not_destination))
|
|
285
|
+
|
|
278
286
|
if not_in_interface:
|
|
279
287
|
args.extend(("!", "-i", not_in_interface))
|
|
280
288
|
|
pyinfra/operations/launchd.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Manage launchd services.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
5
7
|
from pyinfra import host
|
|
6
8
|
from pyinfra.api import operation
|
|
7
9
|
from pyinfra.facts.launchd import LaunchdStatus
|
|
@@ -11,10 +13,10 @@ from .util.service import handle_service_control
|
|
|
11
13
|
|
|
12
14
|
@operation()
|
|
13
15
|
def service(
|
|
14
|
-
service,
|
|
16
|
+
service: str,
|
|
15
17
|
running=True,
|
|
16
18
|
restarted=False,
|
|
17
|
-
command=None,
|
|
19
|
+
command: str | None = None,
|
|
18
20
|
):
|
|
19
21
|
"""
|
|
20
22
|
Manage the state of systemd managed services.
|
|
@@ -33,11 +35,8 @@ def service(
|
|
|
33
35
|
service,
|
|
34
36
|
host.get_fact(LaunchdStatus),
|
|
35
37
|
"launchctl {1} {0}",
|
|
36
|
-
# No support for restart/reload/command
|
|
37
38
|
running,
|
|
38
|
-
|
|
39
|
-
None,
|
|
40
|
-
None,
|
|
39
|
+
# No support for restart/reload/command
|
|
41
40
|
)
|
|
42
41
|
|
|
43
42
|
# No restart command, so just stop/start
|
pyinfra/operations/lxd.py
CHANGED
|
@@ -2,22 +2,25 @@
|
|
|
2
2
|
The LXD modules manage LXD containers
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
5
9
|
from pyinfra import host
|
|
6
10
|
from pyinfra.api import operation
|
|
7
11
|
from pyinfra.facts.lxd import LxdContainers
|
|
8
12
|
|
|
9
13
|
|
|
10
|
-
def get_container_named(name, containers):
|
|
14
|
+
def get_container_named(name: str, containers: list[dict[str, Any]]) -> dict[str, Any] | None:
|
|
11
15
|
for container in containers:
|
|
12
16
|
if container["name"] == name:
|
|
13
17
|
return container
|
|
14
|
-
|
|
15
|
-
return None
|
|
18
|
+
return None
|
|
16
19
|
|
|
17
20
|
|
|
18
21
|
@operation()
|
|
19
22
|
def container(
|
|
20
|
-
id,
|
|
23
|
+
id: str,
|
|
21
24
|
present=True,
|
|
22
25
|
image="ubuntu:16.04",
|
|
23
26
|
):
|