pyinfra 3.0.dev0__py2.py3-none-any.whl → 3.0.2__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 +115 -97
- pyinfra/api/arguments_typed.py +80 -0
- pyinfra/api/command.py +5 -3
- pyinfra/api/config.py +139 -39
- pyinfra/api/connectors.py +5 -2
- pyinfra/api/deploy.py +19 -19
- pyinfra/api/exceptions.py +35 -4
- pyinfra/api/facts.py +62 -86
- pyinfra/api/host.py +102 -15
- pyinfra/api/inventory.py +4 -0
- pyinfra/api/operation.py +188 -120
- pyinfra/api/operations.py +66 -113
- pyinfra/api/state.py +53 -34
- pyinfra/api/util.py +64 -33
- pyinfra/connectors/base.py +65 -20
- pyinfra/connectors/chroot.py +15 -13
- pyinfra/connectors/docker.py +62 -72
- pyinfra/connectors/dockerssh.py +20 -19
- pyinfra/connectors/local.py +32 -22
- pyinfra/connectors/ssh.py +162 -86
- pyinfra/connectors/sshuserclient/client.py +1 -1
- pyinfra/connectors/terraform.py +57 -39
- pyinfra/connectors/util.py +26 -27
- pyinfra/connectors/vagrant.py +27 -26
- pyinfra/context.py +1 -0
- pyinfra/facts/apk.py +7 -2
- pyinfra/facts/apt.py +15 -7
- pyinfra/facts/brew.py +28 -13
- pyinfra/facts/bsdinit.py +9 -6
- pyinfra/facts/cargo.py +6 -3
- pyinfra/facts/choco.py +8 -4
- pyinfra/facts/deb.py +21 -9
- pyinfra/facts/dnf.py +11 -6
- pyinfra/facts/docker.py +30 -5
- pyinfra/facts/files.py +49 -33
- pyinfra/facts/gem.py +7 -2
- pyinfra/facts/git.py +14 -21
- pyinfra/facts/gpg.py +4 -1
- pyinfra/facts/hardware.py +186 -138
- pyinfra/facts/launchd.py +7 -2
- pyinfra/facts/lxd.py +8 -2
- pyinfra/facts/mysql.py +19 -12
- pyinfra/facts/npm.py +3 -1
- pyinfra/facts/openrc.py +8 -2
- pyinfra/facts/pacman.py +13 -5
- pyinfra/facts/pip.py +2 -0
- pyinfra/facts/pkg.py +5 -1
- pyinfra/facts/pkgin.py +7 -2
- pyinfra/facts/postgres.py +170 -0
- pyinfra/facts/postgresql.py +5 -162
- pyinfra/facts/rpm.py +21 -15
- pyinfra/facts/runit.py +70 -0
- pyinfra/facts/selinux.py +12 -4
- pyinfra/facts/server.py +240 -82
- pyinfra/facts/snap.py +8 -2
- pyinfra/facts/systemd.py +37 -13
- pyinfra/facts/sysvinit.py +7 -4
- pyinfra/facts/upstart.py +7 -2
- pyinfra/facts/util/packaging.py +3 -2
- pyinfra/facts/vzctl.py +8 -4
- pyinfra/facts/xbps.py +7 -2
- pyinfra/facts/yum.py +10 -5
- pyinfra/facts/zypper.py +9 -4
- pyinfra/operations/apk.py +5 -3
- pyinfra/operations/apt.py +28 -25
- pyinfra/operations/brew.py +60 -29
- pyinfra/operations/bsdinit.py +6 -4
- pyinfra/operations/cargo.py +3 -1
- pyinfra/operations/choco.py +3 -1
- pyinfra/operations/dnf.py +16 -20
- pyinfra/operations/docker.py +339 -0
- pyinfra/operations/files.py +187 -168
- pyinfra/operations/gem.py +3 -1
- pyinfra/operations/git.py +23 -25
- pyinfra/operations/iptables.py +33 -25
- pyinfra/operations/launchd.py +5 -6
- pyinfra/operations/lxd.py +7 -4
- pyinfra/operations/mysql.py +59 -55
- pyinfra/operations/npm.py +8 -1
- pyinfra/operations/openrc.py +5 -3
- pyinfra/operations/pacman.py +6 -7
- pyinfra/operations/pip.py +19 -12
- pyinfra/operations/pkg.py +3 -1
- pyinfra/operations/pkgin.py +5 -3
- pyinfra/operations/postgres.py +349 -0
- pyinfra/operations/postgresql.py +18 -335
- pyinfra/operations/puppet.py +3 -1
- pyinfra/operations/python.py +8 -19
- pyinfra/operations/runit.py +182 -0
- pyinfra/operations/selinux.py +47 -29
- pyinfra/operations/server.py +138 -67
- pyinfra/operations/snap.py +3 -1
- pyinfra/operations/ssh.py +18 -16
- pyinfra/operations/systemd.py +18 -12
- pyinfra/operations/sysvinit.py +7 -5
- pyinfra/operations/upstart.py +7 -5
- pyinfra/operations/util/__init__.py +12 -0
- pyinfra/operations/util/docker.py +177 -0
- pyinfra/operations/util/files.py +24 -16
- pyinfra/operations/util/packaging.py +54 -38
- pyinfra/operations/util/service.py +39 -47
- pyinfra/operations/vzctl.py +12 -10
- pyinfra/operations/xbps.py +5 -3
- pyinfra/operations/yum.py +15 -19
- pyinfra/operations/zypper.py +9 -10
- pyinfra/version.py +5 -2
- {pyinfra-3.0.dev0.dist-info → pyinfra-3.0.2.dist-info}/METADATA +51 -58
- pyinfra-3.0.2.dist-info/RECORD +168 -0
- {pyinfra-3.0.dev0.dist-info → pyinfra-3.0.2.dist-info}/WHEEL +1 -1
- {pyinfra-3.0.dev0.dist-info → pyinfra-3.0.2.dist-info}/entry_points.txt +0 -3
- pyinfra_cli/__main__.py +4 -3
- pyinfra_cli/commands.py +3 -2
- pyinfra_cli/exceptions.py +75 -43
- pyinfra_cli/inventory.py +52 -31
- pyinfra_cli/log.py +10 -2
- pyinfra_cli/main.py +88 -65
- pyinfra_cli/prints.py +37 -109
- pyinfra_cli/util.py +15 -10
- tests/test_api/test_api.py +2 -0
- tests/test_api/test_api_arguments.py +9 -9
- tests/test_api/test_api_deploys.py +15 -19
- tests/test_api/test_api_facts.py +4 -5
- tests/test_api/test_api_operations.py +18 -20
- tests/test_api/test_api_util.py +41 -2
- tests/test_cli/test_cli.py +14 -50
- tests/test_cli/test_cli_deploy.py +17 -14
- tests/test_cli/test_cli_exceptions.py +50 -19
- tests/test_cli/test_cli_inventory.py +66 -0
- tests/test_cli/util.py +1 -1
- tests/test_connectors/test_dockerssh.py +11 -8
- tests/test_connectors/test_ssh.py +88 -23
- tests/test_connectors/test_sshuserclient.py +1 -1
- tests/test_connectors/test_terraform.py +11 -8
- tests/test_connectors/test_vagrant.py +6 -6
- pyinfra/connectors/ansible.py +0 -175
- pyinfra/connectors/mech.py +0 -189
- pyinfra/connectors/pyinfrawinrmsession/__init__.py +0 -28
- pyinfra/connectors/winrm.py +0 -312
- pyinfra/facts/windows.py +0 -366
- pyinfra/facts/windows_files.py +0 -90
- pyinfra/operations/windows.py +0 -59
- pyinfra/operations/windows_files.py +0 -538
- pyinfra-3.0.dev0.dist-info/RECORD +0 -170
- tests/test_connectors/test_ansible.py +0 -64
- tests/test_connectors/test_mech.py +0 -126
- {pyinfra-3.0.dev0.dist-info → pyinfra-3.0.2.dist-info}/LICENSE.md +0 -0
- {pyinfra-3.0.dev0.dist-info → pyinfra-3.0.2.dist-info}/top_level.txt +0 -0
pyinfra/facts/systemd.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import re
|
|
4
|
+
from typing import Dict, Iterable
|
|
2
5
|
|
|
3
|
-
from pyinfra.api import FactBase
|
|
6
|
+
from pyinfra.api import FactBase, QuoteString, StringCommand
|
|
4
7
|
|
|
5
8
|
# Valid unit names consist of a "name prefix" and a dot and a suffix specifying the unit type.
|
|
6
9
|
# The "unit prefix" must consist of one or more valid characters
|
|
@@ -21,21 +24,19 @@ SYSTEMD_UNIT_NAME_REGEX = (
|
|
|
21
24
|
|
|
22
25
|
def _make_systemctl_cmd(user_mode=False, machine=None, user_name=None):
|
|
23
26
|
# base command for normal and user mode
|
|
24
|
-
systemctl_cmd = "systemctl --user" if user_mode else "systemctl"
|
|
27
|
+
systemctl_cmd = ["systemctl --user"] if user_mode else ["systemctl"]
|
|
25
28
|
|
|
26
29
|
# add user and machine flag if given in args
|
|
27
30
|
if machine is not None:
|
|
28
31
|
if user_name is not None:
|
|
29
|
-
|
|
32
|
+
systemctl_cmd.append("--machine={1}@{0}".format(machine, user_name))
|
|
30
33
|
else:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
systemctl_cmd = "{0} {1}".format(systemctl_cmd, machine_opt)
|
|
34
|
+
systemctl_cmd.append("--machine={0}".format(machine))
|
|
34
35
|
|
|
35
|
-
return systemctl_cmd
|
|
36
|
+
return StringCommand(*systemctl_cmd)
|
|
36
37
|
|
|
37
38
|
|
|
38
|
-
class SystemdStatus(FactBase):
|
|
39
|
+
class SystemdStatus(FactBase[Dict[str, bool]]):
|
|
39
40
|
"""
|
|
40
41
|
Returns a dictionary map of systemd units to booleans indicating whether they are active.
|
|
41
42
|
|
|
@@ -51,24 +52,47 @@ class SystemdStatus(FactBase):
|
|
|
51
52
|
}
|
|
52
53
|
"""
|
|
53
54
|
|
|
54
|
-
requires_command
|
|
55
|
+
def requires_command(self, *args, **kwargs) -> str:
|
|
56
|
+
return "systemctl"
|
|
55
57
|
|
|
56
58
|
default = dict
|
|
57
59
|
|
|
58
60
|
state_key = "SubState"
|
|
59
61
|
state_values = ["running", "waiting", "exited"]
|
|
60
62
|
|
|
61
|
-
def command(
|
|
63
|
+
def command(
|
|
64
|
+
self,
|
|
65
|
+
user_mode: bool = False,
|
|
66
|
+
machine: str | None = None,
|
|
67
|
+
user_name: str | None = None,
|
|
68
|
+
services: str | list[str] | None = None,
|
|
69
|
+
) -> StringCommand:
|
|
62
70
|
fact_cmd = _make_systemctl_cmd(
|
|
63
71
|
user_mode=user_mode,
|
|
64
72
|
machine=machine,
|
|
65
73
|
user_name=user_name,
|
|
66
74
|
)
|
|
67
75
|
|
|
68
|
-
|
|
76
|
+
if services is None:
|
|
77
|
+
service_strs = [QuoteString("*")]
|
|
78
|
+
elif isinstance(services, str):
|
|
79
|
+
service_strs = [QuoteString(services)]
|
|
80
|
+
elif isinstance(services, Iterable):
|
|
81
|
+
service_strs = [QuoteString(s) for s in services]
|
|
82
|
+
|
|
83
|
+
return StringCommand(
|
|
84
|
+
fact_cmd,
|
|
85
|
+
"show",
|
|
86
|
+
"--all",
|
|
87
|
+
"--property",
|
|
88
|
+
"Id",
|
|
89
|
+
"--property",
|
|
90
|
+
self.state_key,
|
|
91
|
+
*service_strs,
|
|
92
|
+
)
|
|
69
93
|
|
|
70
|
-
def process(self, output):
|
|
71
|
-
services = {}
|
|
94
|
+
def process(self, output) -> Dict[str, bool]:
|
|
95
|
+
services: Dict[str, bool] = {}
|
|
72
96
|
|
|
73
97
|
current_unit = None
|
|
74
98
|
for line in output:
|
pyinfra/facts/sysvinit.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import re
|
|
2
4
|
from typing import Optional
|
|
3
5
|
|
|
@@ -7,7 +9,7 @@ from pyinfra.api import FactBase
|
|
|
7
9
|
class InitdStatus(FactBase):
|
|
8
10
|
"""
|
|
9
11
|
Low level check for every /etc/init.d/* script. Unfortunately many of these
|
|
10
|
-
|
|
12
|
+
misbehave and return exit status 0 while also displaying the help info/not
|
|
11
13
|
offering status support.
|
|
12
14
|
|
|
13
15
|
Returns a dict of name -> status.
|
|
@@ -16,7 +18,8 @@ class InitdStatus(FactBase):
|
|
|
16
18
|
http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
|
|
17
19
|
"""
|
|
18
20
|
|
|
19
|
-
command
|
|
21
|
+
def command(self) -> str:
|
|
22
|
+
return """
|
|
20
23
|
for SERVICE in `ls /etc/init.d/`; do
|
|
21
24
|
_=`cat /etc/init.d/$SERVICE | grep "### BEGIN INIT INFO"`
|
|
22
25
|
|
|
@@ -30,8 +33,8 @@ class InitdStatus(FactBase):
|
|
|
30
33
|
regex = r"([a-zA-Z0-9\-]+)=([0-9]+)"
|
|
31
34
|
default = dict
|
|
32
35
|
|
|
33
|
-
def process(self, output):
|
|
34
|
-
services = {}
|
|
36
|
+
def process(self, output) -> dict[str, Optional[bool]]:
|
|
37
|
+
services: dict[str, Optional[bool]] = {}
|
|
35
38
|
|
|
36
39
|
for line in output:
|
|
37
40
|
matches = re.match(self.regex, line)
|
pyinfra/facts/upstart.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import re
|
|
2
4
|
|
|
3
5
|
from pyinfra.api import FactBase
|
|
@@ -8,12 +10,15 @@ class UpstartStatus(FactBase):
|
|
|
8
10
|
Returns a dict of name -> status for upstart managed services.
|
|
9
11
|
"""
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
def requires_command(self) -> str:
|
|
14
|
+
return "initctl"
|
|
13
15
|
|
|
14
16
|
regex = r"^([a-z\-]+) [a-z]+\/([a-z]+)"
|
|
15
17
|
default = dict
|
|
16
18
|
|
|
19
|
+
def command(self):
|
|
20
|
+
return "initctl list"
|
|
21
|
+
|
|
17
22
|
def process(self, output):
|
|
18
23
|
services = {}
|
|
19
24
|
|
pyinfra/facts/util/packaging.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
|
+
from typing import Iterable
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
def parse_packages(regex, output):
|
|
7
|
+
def parse_packages(regex: str, output: Iterable[str]) -> dict[str, set[str]]:
|
|
7
8
|
packages: dict[str, set[str]] = {}
|
|
8
9
|
|
|
9
10
|
for line in output:
|
|
@@ -34,7 +35,7 @@ def _parse_yum_or_zypper_repositories(output):
|
|
|
34
35
|
current_repo["name"] = line[1:-1]
|
|
35
36
|
|
|
36
37
|
if current_repo and "=" in line:
|
|
37
|
-
key, value =
|
|
38
|
+
key, value = re.split(r"\s*=\s*", line, maxsplit=1)
|
|
38
39
|
current_repo[key] = value
|
|
39
40
|
|
|
40
41
|
if current_repo:
|
pyinfra/facts/vzctl.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import json
|
|
2
4
|
|
|
3
5
|
from pyinfra.api import FactBase
|
|
@@ -18,13 +20,15 @@ class OpenvzContainers(FactBase):
|
|
|
18
20
|
}
|
|
19
21
|
"""
|
|
20
22
|
|
|
21
|
-
command
|
|
22
|
-
|
|
23
|
+
def command(self) -> str:
|
|
24
|
+
return "vzlist -a -j"
|
|
25
|
+
|
|
26
|
+
def requires_command(self) -> str:
|
|
27
|
+
return "vzlist"
|
|
23
28
|
|
|
24
29
|
default = dict
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
def process(output):
|
|
31
|
+
def process(self, output):
|
|
28
32
|
combined_json = "".join(output)
|
|
29
33
|
vz_data = json.loads(combined_json)
|
|
30
34
|
|
pyinfra/facts/xbps.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from pyinfra.api import FactBase
|
|
2
4
|
|
|
3
5
|
from .util.packaging import parse_packages
|
|
@@ -14,12 +16,15 @@ class XbpsPackages(FactBase):
|
|
|
14
16
|
}
|
|
15
17
|
"""
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
def requires_command(self) -> str:
|
|
20
|
+
return "xbps-query"
|
|
19
21
|
|
|
20
22
|
default = dict
|
|
21
23
|
|
|
22
24
|
regex = r"^.. ([a-zA-Z0-9_\-\+]+)\-([0-9a-z_\.]+)"
|
|
23
25
|
|
|
26
|
+
def command(self):
|
|
27
|
+
return "xbps-query -l"
|
|
28
|
+
|
|
24
29
|
def process(self, output):
|
|
25
30
|
return parse_packages(self.regex, output)
|
pyinfra/facts/yum.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from pyinfra.api import FactBase
|
|
2
4
|
|
|
3
5
|
from .util import make_cat_files_command
|
|
@@ -21,11 +23,14 @@ class YumRepositories(FactBase):
|
|
|
21
23
|
]
|
|
22
24
|
"""
|
|
23
25
|
|
|
24
|
-
command
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
def command(self) -> str:
|
|
27
|
+
return make_cat_files_command(
|
|
28
|
+
"/etc/yum.conf",
|
|
29
|
+
"/etc/yum.repos.d/*.repo",
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def requires_command(self) -> str:
|
|
33
|
+
return "yum"
|
|
29
34
|
|
|
30
35
|
default = list
|
|
31
36
|
|
pyinfra/facts/zypper.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from pyinfra.api import FactBase
|
|
2
4
|
|
|
3
5
|
from .util import make_cat_files_command
|
|
@@ -21,10 +23,13 @@ class ZypperRepositories(FactBase):
|
|
|
21
23
|
]
|
|
22
24
|
"""
|
|
23
25
|
|
|
24
|
-
command
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
def command(self) -> str:
|
|
27
|
+
return make_cat_files_command(
|
|
28
|
+
"/etc/zypp/repos.d/*.repo",
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
def requires_command(self) -> str:
|
|
32
|
+
return "zypper"
|
|
28
33
|
|
|
29
34
|
default = list
|
|
30
35
|
|
pyinfra/operations/apk.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Manage apk packages.
|
|
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.apk import ApkPackages
|
|
@@ -23,7 +25,7 @@ def upgrade(available: bool = False):
|
|
|
23
25
|
yield "apk upgrade"
|
|
24
26
|
|
|
25
27
|
|
|
26
|
-
_upgrade = upgrade # noqa: E305
|
|
28
|
+
_upgrade = upgrade._inner # noqa: E305
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
@operation(is_idempotent=False)
|
|
@@ -35,12 +37,12 @@ def update():
|
|
|
35
37
|
yield "apk update"
|
|
36
38
|
|
|
37
39
|
|
|
38
|
-
_update = update # noqa: E305
|
|
40
|
+
_update = update._inner # noqa: E305
|
|
39
41
|
|
|
40
42
|
|
|
41
43
|
@operation()
|
|
42
44
|
def packages(
|
|
43
|
-
packages=None,
|
|
45
|
+
packages: str | list[str] | None = None,
|
|
44
46
|
present=True,
|
|
45
47
|
latest=False,
|
|
46
48
|
update=False,
|
pyinfra/operations/apt.py
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
Manage apt packages and repositories.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
5
7
|
from datetime import timedelta
|
|
6
8
|
from urllib.parse import urlparse
|
|
7
9
|
|
|
8
|
-
from pyinfra import host
|
|
10
|
+
from pyinfra import host
|
|
9
11
|
from pyinfra.api import OperationError, operation
|
|
10
12
|
from pyinfra.facts.apt import AptKeys, AptSources, parse_apt_repo
|
|
11
13
|
from pyinfra.facts.deb import DebPackage, DebPackages
|
|
@@ -19,7 +21,7 @@ from .util.packaging import ensure_packages
|
|
|
19
21
|
APT_UPDATE_FILENAME = "/var/lib/apt/periodic/update-success-stamp"
|
|
20
22
|
|
|
21
23
|
|
|
22
|
-
def noninteractive_apt(command, force=False):
|
|
24
|
+
def noninteractive_apt(command: str, force=False):
|
|
23
25
|
args = ["DEBIAN_FRONTEND=noninteractive apt-get -y"]
|
|
24
26
|
|
|
25
27
|
if force:
|
|
@@ -37,7 +39,7 @@ def noninteractive_apt(command, force=False):
|
|
|
37
39
|
|
|
38
40
|
|
|
39
41
|
@operation()
|
|
40
|
-
def key(src=None, keyserver=None, keyid=None):
|
|
42
|
+
def key(src: str | None = None, keyserver: str | None = None, keyid: str | list[str] | None = None):
|
|
41
43
|
"""
|
|
42
44
|
Add apt gpg keys with ``apt-key``.
|
|
43
45
|
|
|
@@ -48,6 +50,11 @@ def key(src=None, keyserver=None, keyid=None):
|
|
|
48
50
|
keyserver/id:
|
|
49
51
|
These must be provided together.
|
|
50
52
|
|
|
53
|
+
.. warning::
|
|
54
|
+
``apt-key`` is deprecated in Debian, it is recommended NOT to use this
|
|
55
|
+
operation and instead follow the instructions here:
|
|
56
|
+
https://wiki.debian.org/DebianRepository/UseThirdParty
|
|
57
|
+
|
|
51
58
|
**Examples:**
|
|
52
59
|
|
|
53
60
|
.. code:: python
|
|
@@ -103,7 +110,7 @@ def key(src=None, keyserver=None, keyid=None):
|
|
|
103
110
|
|
|
104
111
|
|
|
105
112
|
@operation()
|
|
106
|
-
def repo(src, present=True, filename=None):
|
|
113
|
+
def repo(src: str, present=True, filename: str | None = None):
|
|
107
114
|
"""
|
|
108
115
|
Add/remove apt repositories.
|
|
109
116
|
|
|
@@ -138,7 +145,7 @@ def repo(src, present=True, filename=None):
|
|
|
138
145
|
|
|
139
146
|
# Doesn't exist and we want it
|
|
140
147
|
if not is_present and present:
|
|
141
|
-
yield from files.line(
|
|
148
|
+
yield from files.line._inner(
|
|
142
149
|
path=filename,
|
|
143
150
|
line=src,
|
|
144
151
|
escape_regex_characters=True,
|
|
@@ -146,7 +153,7 @@ def repo(src, present=True, filename=None):
|
|
|
146
153
|
|
|
147
154
|
# Exists and we don't want it
|
|
148
155
|
elif is_present and not present:
|
|
149
|
-
yield from files.line(
|
|
156
|
+
yield from files.line._inner(
|
|
150
157
|
path=filename,
|
|
151
158
|
line=src,
|
|
152
159
|
present=False,
|
|
@@ -162,7 +169,7 @@ def repo(src, present=True, filename=None):
|
|
|
162
169
|
|
|
163
170
|
|
|
164
171
|
@operation(is_idempotent=False)
|
|
165
|
-
def ppa(src, present=True):
|
|
172
|
+
def ppa(src: str, present=True):
|
|
166
173
|
"""
|
|
167
174
|
Add/remove Ubuntu ppa repositories.
|
|
168
175
|
|
|
@@ -192,7 +199,7 @@ def ppa(src, present=True):
|
|
|
192
199
|
|
|
193
200
|
|
|
194
201
|
@operation()
|
|
195
|
-
def deb(src, present=True, force=False):
|
|
202
|
+
def deb(src: str, present=True, force=False):
|
|
196
203
|
"""
|
|
197
204
|
Add/remove ``.deb`` file packages.
|
|
198
205
|
|
|
@@ -224,27 +231,23 @@ def deb(src, present=True, force=False):
|
|
|
224
231
|
# If source is a url
|
|
225
232
|
if urlparse(src).scheme:
|
|
226
233
|
# Generate a temp filename
|
|
227
|
-
temp_filename =
|
|
234
|
+
temp_filename = host.get_temp_filename(src)
|
|
228
235
|
|
|
229
236
|
# Ensure it's downloaded
|
|
230
|
-
yield from files.download(src=src, dest=temp_filename)
|
|
237
|
+
yield from files.download._inner(src=src, dest=temp_filename)
|
|
231
238
|
|
|
232
239
|
# Override the source with the downloaded file
|
|
233
240
|
src = temp_filename
|
|
234
241
|
|
|
235
242
|
# Check for file .deb information (if file is present)
|
|
236
|
-
info = host.get_fact(DebPackage,
|
|
243
|
+
info = host.get_fact(DebPackage, package=src)
|
|
237
244
|
current_packages = host.get_fact(DebPackages)
|
|
238
245
|
|
|
239
246
|
exists = False
|
|
240
247
|
|
|
241
248
|
# We have deb info! Check against installed packages
|
|
242
|
-
if info:
|
|
243
|
-
|
|
244
|
-
info["name"] in current_packages
|
|
245
|
-
and info.get("version") in current_packages[info["name"]]
|
|
246
|
-
):
|
|
247
|
-
exists = True
|
|
249
|
+
if info and info.get("version") in current_packages.get(info.get("name"), {}):
|
|
250
|
+
exists = True
|
|
248
251
|
|
|
249
252
|
# Package does not exist and we want?
|
|
250
253
|
if present:
|
|
@@ -277,7 +280,7 @@ def deb(src, present=True, force=False):
|
|
|
277
280
|
"unless the ``cache_time`` argument is provided."
|
|
278
281
|
),
|
|
279
282
|
)
|
|
280
|
-
def update(cache_time=None):
|
|
283
|
+
def update(cache_time: int | None = None):
|
|
281
284
|
"""
|
|
282
285
|
Updates apt repositories.
|
|
283
286
|
|
|
@@ -335,7 +338,7 @@ def upgrade(auto_remove: bool = False):
|
|
|
335
338
|
|
|
336
339
|
# Upgrade all packages and remove unneeded transitive dependencies
|
|
337
340
|
apt.upgrade(
|
|
338
|
-
name="Upgrade apt packages and remove unneeded dependencies"
|
|
341
|
+
name="Upgrade apt packages and remove unneeded dependencies",
|
|
339
342
|
auto_remove=True
|
|
340
343
|
)
|
|
341
344
|
"""
|
|
@@ -370,17 +373,17 @@ def dist_upgrade():
|
|
|
370
373
|
|
|
371
374
|
@operation()
|
|
372
375
|
def packages(
|
|
373
|
-
packages=None,
|
|
376
|
+
packages: str | list[str] | None = None,
|
|
374
377
|
present=True,
|
|
375
378
|
latest=False,
|
|
376
379
|
update=False,
|
|
377
|
-
cache_time=None,
|
|
380
|
+
cache_time: int | None = None,
|
|
378
381
|
upgrade=False,
|
|
379
382
|
force=False,
|
|
380
383
|
no_recommends=False,
|
|
381
384
|
allow_downgrades=False,
|
|
382
|
-
extra_install_args=None,
|
|
383
|
-
extra_uninstall_args=None,
|
|
385
|
+
extra_install_args: str | None = None,
|
|
386
|
+
extra_uninstall_args: str | None = None,
|
|
384
387
|
):
|
|
385
388
|
"""
|
|
386
389
|
Install/remove/update packages & update apt.
|
|
@@ -432,10 +435,10 @@ def packages(
|
|
|
432
435
|
"""
|
|
433
436
|
|
|
434
437
|
if update:
|
|
435
|
-
yield from _update(cache_time=cache_time)
|
|
438
|
+
yield from _update._inner(cache_time=cache_time)
|
|
436
439
|
|
|
437
440
|
if upgrade:
|
|
438
|
-
yield from _upgrade()
|
|
441
|
+
yield from _upgrade._inner()
|
|
439
442
|
|
|
440
443
|
install_command_args = ["install"]
|
|
441
444
|
if no_recommends is True:
|
pyinfra/operations/brew.py
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
Manage brew packages on mac/OSX. See https://brew.sh/
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import urllib.parse
|
|
8
|
+
|
|
5
9
|
from pyinfra import host
|
|
6
10
|
from pyinfra.api import operation
|
|
7
11
|
from pyinfra.facts.brew import BrewCasks, BrewPackages, BrewTaps, BrewVersion, new_cask_cli
|
|
@@ -35,7 +39,7 @@ _upgrade = upgrade # noqa: E305
|
|
|
35
39
|
|
|
36
40
|
@operation()
|
|
37
41
|
def packages(
|
|
38
|
-
packages=None,
|
|
42
|
+
packages: str | list[str] | None = None,
|
|
39
43
|
present=True,
|
|
40
44
|
latest=False,
|
|
41
45
|
update=False,
|
|
@@ -73,10 +77,10 @@ def packages(
|
|
|
73
77
|
"""
|
|
74
78
|
|
|
75
79
|
if update:
|
|
76
|
-
yield from _update()
|
|
80
|
+
yield from _update._inner()
|
|
77
81
|
|
|
78
82
|
if upgrade:
|
|
79
|
-
yield from _upgrade()
|
|
83
|
+
yield from _upgrade._inner()
|
|
80
84
|
|
|
81
85
|
yield from ensure_packages(
|
|
82
86
|
host,
|
|
@@ -91,27 +95,22 @@ def packages(
|
|
|
91
95
|
)
|
|
92
96
|
|
|
93
97
|
|
|
94
|
-
def cask_args(
|
|
98
|
+
def cask_args():
|
|
95
99
|
return ("", " --cask") if new_cask_cli(host.get_fact(BrewVersion)) else ("cask ", "")
|
|
96
100
|
|
|
97
101
|
|
|
98
|
-
@operation(
|
|
99
|
-
is_idempotent=False,
|
|
100
|
-
pipeline_facts={"brew_version": ""},
|
|
101
|
-
)
|
|
102
|
+
@operation(is_idempotent=False)
|
|
102
103
|
def cask_upgrade():
|
|
103
104
|
"""
|
|
104
105
|
Upgrades all brew casks.
|
|
105
106
|
"""
|
|
106
107
|
|
|
107
|
-
yield "brew %supgrade%s" % cask_args(
|
|
108
|
+
yield "brew %supgrade%s" % cask_args()
|
|
108
109
|
|
|
109
110
|
|
|
110
|
-
@operation(
|
|
111
|
-
pipeline_facts={"brew_version": ""},
|
|
112
|
-
)
|
|
111
|
+
@operation()
|
|
113
112
|
def casks(
|
|
114
|
-
casks=None,
|
|
113
|
+
casks: str | list[str] | None = None,
|
|
115
114
|
present=True,
|
|
116
115
|
latest=False,
|
|
117
116
|
upgrade=False,
|
|
@@ -141,9 +140,9 @@ def casks(
|
|
|
141
140
|
"""
|
|
142
141
|
|
|
143
142
|
if upgrade:
|
|
144
|
-
yield from cask_upgrade()
|
|
143
|
+
yield from cask_upgrade._inner()
|
|
145
144
|
|
|
146
|
-
args = cask_args(
|
|
145
|
+
args = cask_args()
|
|
147
146
|
|
|
148
147
|
yield from ensure_packages(
|
|
149
148
|
host,
|
|
@@ -159,12 +158,13 @@ def casks(
|
|
|
159
158
|
|
|
160
159
|
|
|
161
160
|
@operation()
|
|
162
|
-
def tap(src, present=True):
|
|
161
|
+
def tap(src: str | None = None, present=True, url: str | None = None):
|
|
163
162
|
"""
|
|
164
163
|
Add/remove brew taps.
|
|
165
164
|
|
|
166
165
|
+ src: the name of the tap
|
|
167
166
|
+ present: whether this tap should be present or not
|
|
167
|
+
+ url: the url of the tap. See https://docs.brew.sh/Taps
|
|
168
168
|
|
|
169
169
|
**Examples:**
|
|
170
170
|
|
|
@@ -175,6 +175,19 @@ def tap(src, present=True):
|
|
|
175
175
|
src="includeos/includeos",
|
|
176
176
|
)
|
|
177
177
|
|
|
178
|
+
# Just url is equivalent to
|
|
179
|
+
# `brew tap kptdev/kpt https://github.com/kptdev/kpt`
|
|
180
|
+
brew.tap(
|
|
181
|
+
url="https://github.com/kptdev/kpt",
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# src and url is equivalent to
|
|
185
|
+
# `brew tap example/project https://github.example.com/project`
|
|
186
|
+
brew.tap(
|
|
187
|
+
src="example/project",
|
|
188
|
+
url="https://github.example.com/project",
|
|
189
|
+
)
|
|
190
|
+
|
|
178
191
|
# Multiple taps
|
|
179
192
|
for tap in ["includeos/includeos", "ktr0731/evans"]:
|
|
180
193
|
brew.tap(
|
|
@@ -184,17 +197,35 @@ def tap(src, present=True):
|
|
|
184
197
|
|
|
185
198
|
"""
|
|
186
199
|
|
|
200
|
+
if not (src or url):
|
|
201
|
+
host.noop("no tap was specified")
|
|
202
|
+
return
|
|
203
|
+
|
|
204
|
+
src = src or str(urllib.parse.urlparse(url).path).strip("/")
|
|
205
|
+
|
|
206
|
+
if len(src.split("/")) != 2:
|
|
207
|
+
host.noop("src '{0}' doesn't have two components.".format(src))
|
|
208
|
+
return
|
|
209
|
+
|
|
187
210
|
taps = host.get_fact(BrewTaps)
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if present:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
211
|
+
already_tapped = src in taps
|
|
212
|
+
|
|
213
|
+
if present and already_tapped:
|
|
214
|
+
host.noop("tap {0} already exists".format(src))
|
|
215
|
+
return
|
|
216
|
+
|
|
217
|
+
if already_tapped:
|
|
218
|
+
yield "brew untap {0}".format(src)
|
|
219
|
+
return
|
|
220
|
+
|
|
221
|
+
if not present:
|
|
222
|
+
host.noop("tap {0} does not exist".format(src))
|
|
223
|
+
return
|
|
224
|
+
|
|
225
|
+
cmd = "brew tap {0}".format(src)
|
|
226
|
+
|
|
227
|
+
if url is not None:
|
|
228
|
+
cmd = " ".join([cmd, url])
|
|
229
|
+
|
|
230
|
+
yield cmd
|
|
231
|
+
return
|
pyinfra/operations/bsdinit.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Manage BSD init services (``/etc/rc.d``, ``/usr/local/etc/rc.d``).
|
|
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.bsdinit import RcdStatus
|
|
@@ -13,12 +15,12 @@ from .util.service import handle_service_control
|
|
|
13
15
|
|
|
14
16
|
@operation()
|
|
15
17
|
def service(
|
|
16
|
-
service,
|
|
18
|
+
service: str,
|
|
17
19
|
running=True,
|
|
18
20
|
restarted=False,
|
|
19
21
|
reloaded=False,
|
|
20
|
-
command=None,
|
|
21
|
-
enabled=None,
|
|
22
|
+
command: str | None = None,
|
|
23
|
+
enabled: bool | None = None,
|
|
22
24
|
):
|
|
23
25
|
"""
|
|
24
26
|
Manage the state of BSD init services.
|
|
@@ -49,7 +51,7 @@ def service(
|
|
|
49
51
|
|
|
50
52
|
# BSD init is simple, just add/remove <service>_enabled="YES"
|
|
51
53
|
if isinstance(enabled, bool):
|
|
52
|
-
yield from files.line(
|
|
54
|
+
yield from files.line._inner(
|
|
53
55
|
path="/etc/rc.conf.local",
|
|
54
56
|
line="^{0}_enable=".format(service),
|
|
55
57
|
replace='{0}_enable="YES"'.format(service),
|
pyinfra/operations/cargo.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Manage cargo (aka Rust) packages.
|
|
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.cargo import CargoPackages
|
|
@@ -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
|
Install/remove/update cargo packages.
|
|
16
18
|
|