pyinfra 3.0b1__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/arguments.py +9 -3
- pyinfra/api/arguments_typed.py +8 -5
- pyinfra/api/command.py +5 -3
- pyinfra/api/config.py +115 -13
- pyinfra/api/connectors.py +5 -2
- pyinfra/api/facts.py +33 -32
- pyinfra/api/host.py +5 -5
- pyinfra/api/inventory.py +4 -0
- pyinfra/api/operation.py +22 -14
- pyinfra/api/util.py +24 -16
- pyinfra/connectors/base.py +3 -6
- pyinfra/connectors/docker.py +2 -9
- pyinfra/connectors/local.py +2 -2
- pyinfra/connectors/ssh.py +2 -2
- pyinfra/connectors/util.py +6 -7
- pyinfra/connectors/vagrant.py +5 -5
- 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 +2 -0
- pyinfra/facts/deb.py +7 -2
- 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 +6 -6
- pyinfra/facts/postgresql.py +2 -0
- pyinfra/facts/rpm.py +12 -9
- pyinfra/facts/server.py +10 -13
- pyinfra/facts/snap.py +2 -0
- pyinfra/facts/systemd.py +2 -0
- 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 +81 -66
- pyinfra/operations/gem.py +3 -1
- pyinfra/operations/git.py +18 -16
- pyinfra/operations/iptables.py +27 -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 +11 -9
- pyinfra/operations/pkg.py +3 -1
- pyinfra/operations/pkgin.py +3 -1
- pyinfra/operations/postgres.py +39 -37
- pyinfra/operations/postgresql.py +2 -0
- 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 +8 -6
- 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.0b1.dist-info → pyinfra-3.0b2.dist-info}/METADATA +28 -26
- pyinfra-3.0b2.dist-info/RECORD +163 -0
- {pyinfra-3.0b1.dist-info → pyinfra-3.0b2.dist-info}/WHEEL +1 -1
- pyinfra_cli/exceptions.py +0 -5
- pyinfra_cli/inventory.py +38 -19
- pyinfra_cli/prints.py +15 -11
- pyinfra_cli/util.py +3 -1
- tests/test_api/test_api_operations.py +1 -1
- tests/test_connectors/test_ssh.py +66 -13
- tests/test_connectors/test_vagrant.py +3 -3
- pyinfra-3.0b1.dist-info/RECORD +0 -163
- {pyinfra-3.0b1.dist-info → pyinfra-3.0b2.dist-info}/LICENSE.md +0 -0
- {pyinfra-3.0b1.dist-info → pyinfra-3.0b2.dist-info}/entry_points.txt +0 -0
- {pyinfra-3.0b1.dist-info → pyinfra-3.0b2.dist-info}/top_level.txt +0 -0
pyinfra/operations/apt.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
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
|
|
|
@@ -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
|
|
|
@@ -103,7 +105,7 @@ def key(src=None, keyserver=None, keyid=None):
|
|
|
103
105
|
|
|
104
106
|
|
|
105
107
|
@operation()
|
|
106
|
-
def repo(src, present=True, filename=None):
|
|
108
|
+
def repo(src: str, present=True, filename: str | None = None):
|
|
107
109
|
"""
|
|
108
110
|
Add/remove apt repositories.
|
|
109
111
|
|
|
@@ -162,7 +164,7 @@ def repo(src, present=True, filename=None):
|
|
|
162
164
|
|
|
163
165
|
|
|
164
166
|
@operation(is_idempotent=False)
|
|
165
|
-
def ppa(src, present=True):
|
|
167
|
+
def ppa(src: str, present=True):
|
|
166
168
|
"""
|
|
167
169
|
Add/remove Ubuntu ppa repositories.
|
|
168
170
|
|
|
@@ -192,7 +194,7 @@ def ppa(src, present=True):
|
|
|
192
194
|
|
|
193
195
|
|
|
194
196
|
@operation()
|
|
195
|
-
def deb(src, present=True, force=False):
|
|
197
|
+
def deb(src: str, present=True, force=False):
|
|
196
198
|
"""
|
|
197
199
|
Add/remove ``.deb`` file packages.
|
|
198
200
|
|
|
@@ -233,18 +235,14 @@ def deb(src, present=True, force=False):
|
|
|
233
235
|
src = temp_filename
|
|
234
236
|
|
|
235
237
|
# Check for file .deb information (if file is present)
|
|
236
|
-
info = host.get_fact(DebPackage,
|
|
238
|
+
info = host.get_fact(DebPackage, package=src)
|
|
237
239
|
current_packages = host.get_fact(DebPackages)
|
|
238
240
|
|
|
239
241
|
exists = False
|
|
240
242
|
|
|
241
243
|
# 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
|
|
244
|
+
if info and info.get("version") in current_packages.get(info.get("name"), {}):
|
|
245
|
+
exists = True
|
|
248
246
|
|
|
249
247
|
# Package does not exist and we want?
|
|
250
248
|
if present:
|
|
@@ -277,7 +275,7 @@ def deb(src, present=True, force=False):
|
|
|
277
275
|
"unless the ``cache_time`` argument is provided."
|
|
278
276
|
),
|
|
279
277
|
)
|
|
280
|
-
def update(cache_time=None):
|
|
278
|
+
def update(cache_time: int | None = None):
|
|
281
279
|
"""
|
|
282
280
|
Updates apt repositories.
|
|
283
281
|
|
|
@@ -335,7 +333,7 @@ def upgrade(auto_remove: bool = False):
|
|
|
335
333
|
|
|
336
334
|
# Upgrade all packages and remove unneeded transitive dependencies
|
|
337
335
|
apt.upgrade(
|
|
338
|
-
name="Upgrade apt packages and remove unneeded dependencies"
|
|
336
|
+
name="Upgrade apt packages and remove unneeded dependencies",
|
|
339
337
|
auto_remove=True
|
|
340
338
|
)
|
|
341
339
|
"""
|
|
@@ -370,17 +368,17 @@ def dist_upgrade():
|
|
|
370
368
|
|
|
371
369
|
@operation()
|
|
372
370
|
def packages(
|
|
373
|
-
packages=None,
|
|
371
|
+
packages: str | list[str] | None = None,
|
|
374
372
|
present=True,
|
|
375
373
|
latest=False,
|
|
376
374
|
update=False,
|
|
377
|
-
cache_time=None,
|
|
375
|
+
cache_time: int | None = None,
|
|
378
376
|
upgrade=False,
|
|
379
377
|
force=False,
|
|
380
378
|
no_recommends=False,
|
|
381
379
|
allow_downgrades=False,
|
|
382
|
-
extra_install_args=None,
|
|
383
|
-
extra_uninstall_args=None,
|
|
380
|
+
extra_install_args: str | None = None,
|
|
381
|
+
extra_uninstall_args: str | None = None,
|
|
384
382
|
):
|
|
385
383
|
"""
|
|
386
384
|
Install/remove/update packages & update apt.
|
pyinfra/operations/brew.py
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
Manage brew packages on mac/OSX. See https://brew.sh/
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import urllib.parse
|
|
6
8
|
|
|
7
9
|
from pyinfra import host
|
|
8
10
|
from pyinfra.api import operation
|
|
@@ -37,7 +39,7 @@ _upgrade = upgrade # noqa: E305
|
|
|
37
39
|
|
|
38
40
|
@operation()
|
|
39
41
|
def packages(
|
|
40
|
-
packages=None,
|
|
42
|
+
packages: str | list[str] | None = None,
|
|
41
43
|
present=True,
|
|
42
44
|
latest=False,
|
|
43
45
|
update=False,
|
|
@@ -93,7 +95,7 @@ def packages(
|
|
|
93
95
|
)
|
|
94
96
|
|
|
95
97
|
|
|
96
|
-
def cask_args(
|
|
98
|
+
def cask_args():
|
|
97
99
|
return ("", " --cask") if new_cask_cli(host.get_fact(BrewVersion)) else ("cask ", "")
|
|
98
100
|
|
|
99
101
|
|
|
@@ -103,12 +105,12 @@ def cask_upgrade():
|
|
|
103
105
|
Upgrades all brew casks.
|
|
104
106
|
"""
|
|
105
107
|
|
|
106
|
-
yield "brew %supgrade%s" % cask_args(
|
|
108
|
+
yield "brew %supgrade%s" % cask_args()
|
|
107
109
|
|
|
108
110
|
|
|
109
111
|
@operation()
|
|
110
112
|
def casks(
|
|
111
|
-
casks=None,
|
|
113
|
+
casks: str | list[str] | None = None,
|
|
112
114
|
present=True,
|
|
113
115
|
latest=False,
|
|
114
116
|
upgrade=False,
|
|
@@ -140,7 +142,7 @@ def casks(
|
|
|
140
142
|
if upgrade:
|
|
141
143
|
yield from cask_upgrade._inner()
|
|
142
144
|
|
|
143
|
-
args = cask_args(
|
|
145
|
+
args = cask_args()
|
|
144
146
|
|
|
145
147
|
yield from ensure_packages(
|
|
146
148
|
host,
|
|
@@ -156,7 +158,7 @@ def casks(
|
|
|
156
158
|
|
|
157
159
|
|
|
158
160
|
@operation()
|
|
159
|
-
def tap(src=None, present=True, url=None):
|
|
161
|
+
def tap(src: str | None = None, present=True, url: str | None = None):
|
|
160
162
|
"""
|
|
161
163
|
Add/remove brew taps.
|
|
162
164
|
|
|
@@ -199,7 +201,7 @@ def tap(src=None, present=True, url=None):
|
|
|
199
201
|
host.noop("no tap was specified")
|
|
200
202
|
return
|
|
201
203
|
|
|
202
|
-
src = src or urllib.parse.urlparse(url).path.strip("/")
|
|
204
|
+
src = src or str(urllib.parse.urlparse(url).path).strip("/")
|
|
203
205
|
|
|
204
206
|
if len(src.split("/")) != 2:
|
|
205
207
|
host.noop("src '{0}' doesn't have two components.".format(src))
|
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.
|
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
|
|
pyinfra/operations/choco.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Manage ``choco`` (Chocolatey) packages (https://chocolatey.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.choco import ChocoPackages
|
|
@@ -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 ``choco`` packages.
|
|
16
18
|
|
pyinfra/operations/dnf.py
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
Manage dnf packages and repositories. Note that dnf package names are case-sensitive.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
5
7
|
from pyinfra import host, state
|
|
6
8
|
from pyinfra.api import operation
|
|
7
9
|
from pyinfra.facts.rpm import RpmPackageProvides, RpmPackages
|
|
8
10
|
|
|
9
|
-
from . import files
|
|
10
11
|
from .util.packaging import ensure_packages, ensure_rpm, ensure_yum_repo
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
@operation(is_idempotent=False)
|
|
14
|
-
def key(src):
|
|
15
|
+
def key(src: str):
|
|
15
16
|
"""
|
|
16
17
|
Add dnf gpg keys with ``rpm``.
|
|
17
18
|
|
|
@@ -37,19 +38,19 @@ def key(src):
|
|
|
37
38
|
|
|
38
39
|
@operation()
|
|
39
40
|
def repo(
|
|
40
|
-
src,
|
|
41
|
+
src: str,
|
|
41
42
|
present=True,
|
|
42
|
-
baseurl=None,
|
|
43
|
-
description=None,
|
|
43
|
+
baseurl: str | None = None,
|
|
44
|
+
description: str | None = None,
|
|
44
45
|
enabled=True,
|
|
45
46
|
gpgcheck=True,
|
|
46
|
-
gpgkey=None,
|
|
47
|
+
gpgkey: str | None = None,
|
|
47
48
|
):
|
|
48
49
|
# NOTE: if updating this docstring also update `yum.repo`
|
|
49
50
|
"""
|
|
50
51
|
Add/remove/update dnf repositories.
|
|
51
52
|
|
|
52
|
-
+
|
|
53
|
+
+ src: URL or name for the ``.repo`` file
|
|
53
54
|
+ present: whether the ``.repo`` file should be present
|
|
54
55
|
+ baseurl: the baseurl of the repo (if ``name`` is not a URL)
|
|
55
56
|
+ description: optional verbose description
|
|
@@ -81,9 +82,7 @@ def repo(
|
|
|
81
82
|
"""
|
|
82
83
|
|
|
83
84
|
yield from ensure_yum_repo(
|
|
84
|
-
state,
|
|
85
85
|
host,
|
|
86
|
-
files,
|
|
87
86
|
src,
|
|
88
87
|
baseurl,
|
|
89
88
|
present,
|
|
@@ -95,7 +94,7 @@ def repo(
|
|
|
95
94
|
|
|
96
95
|
|
|
97
96
|
@operation()
|
|
98
|
-
def rpm(src, present=True):
|
|
97
|
+
def rpm(src: str, present=True):
|
|
99
98
|
# NOTE: if updating this docstring also update `yum.rpm`
|
|
100
99
|
"""
|
|
101
100
|
Add/remove ``.rpm`` file packages.
|
|
@@ -118,7 +117,7 @@ def rpm(src, present=True):
|
|
|
118
117
|
)
|
|
119
118
|
"""
|
|
120
119
|
|
|
121
|
-
yield from ensure_rpm(state, host,
|
|
120
|
+
yield from ensure_rpm(state, host, src, present, "dnf")
|
|
122
121
|
|
|
123
122
|
|
|
124
123
|
@operation(is_idempotent=False)
|
|
@@ -135,19 +134,19 @@ _update = update._inner # noqa: E305 (for use below where update is a kwarg)
|
|
|
135
134
|
|
|
136
135
|
@operation()
|
|
137
136
|
def packages(
|
|
138
|
-
packages=None,
|
|
137
|
+
packages: str | list[str] | None = None,
|
|
139
138
|
present=True,
|
|
140
139
|
latest=False,
|
|
141
140
|
update=False,
|
|
142
141
|
clean=False,
|
|
143
142
|
nobest=False,
|
|
144
|
-
extra_install_args=None,
|
|
145
|
-
extra_uninstall_args=None,
|
|
143
|
+
extra_install_args: str | None = None,
|
|
144
|
+
extra_uninstall_args: str | None = None,
|
|
146
145
|
):
|
|
147
146
|
"""
|
|
148
147
|
Install/remove/update dnf packages & updates.
|
|
149
148
|
|
|
150
|
-
+ packages:
|
|
149
|
+
+ packages: packages to ensure
|
|
151
150
|
+ present: whether the packages should be installed
|
|
152
151
|
+ latest: whether to upgrade packages without a specified version
|
|
153
152
|
+ update: run ``dnf update`` before installing packages
|
|
@@ -207,8 +206,5 @@ def packages(
|
|
|
207
206
|
upgrade_command="dnf update -y",
|
|
208
207
|
version_join="=",
|
|
209
208
|
latest=latest,
|
|
210
|
-
expand_package_fact=lambda package: host.get_fact(
|
|
211
|
-
RpmPackageProvides,
|
|
212
|
-
name=package,
|
|
213
|
-
),
|
|
209
|
+
expand_package_fact=lambda package: host.get_fact(RpmPackageProvides, package=package),
|
|
214
210
|
)
|
pyinfra/operations/files.py
CHANGED
|
@@ -12,7 +12,7 @@ from datetime import timedelta
|
|
|
12
12
|
from fnmatch import fnmatch
|
|
13
13
|
from io import StringIO
|
|
14
14
|
from pathlib import Path
|
|
15
|
-
from typing import Union
|
|
15
|
+
from typing import IO, Any, Union
|
|
16
16
|
|
|
17
17
|
from jinja2 import TemplateRuntimeError, TemplateSyntaxError, UndefinedError
|
|
18
18
|
|
|
@@ -60,19 +60,19 @@ from .util.files import adjust_regex, ensure_mode_int, get_timestamp, sed_replac
|
|
|
60
60
|
|
|
61
61
|
@operation()
|
|
62
62
|
def download(
|
|
63
|
-
src,
|
|
64
|
-
dest,
|
|
65
|
-
user=None,
|
|
66
|
-
group=None,
|
|
67
|
-
mode=None,
|
|
68
|
-
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,
|
|
69
69
|
force=False,
|
|
70
|
-
sha256sum=None,
|
|
71
|
-
sha1sum=None,
|
|
72
|
-
md5sum=None,
|
|
73
|
-
headers=None,
|
|
70
|
+
sha256sum: str | None = None,
|
|
71
|
+
sha1sum: str | None = None,
|
|
72
|
+
md5sum: str | None = None,
|
|
73
|
+
headers: dict[str, str] | None = None,
|
|
74
74
|
insecure=False,
|
|
75
|
-
proxy=None,
|
|
75
|
+
proxy: str | None = None,
|
|
76
76
|
):
|
|
77
77
|
"""
|
|
78
78
|
Download files from remote locations using ``curl`` or ``wget``.
|
|
@@ -123,8 +123,8 @@ def download(
|
|
|
123
123
|
if cache_time:
|
|
124
124
|
# Time on files is not tz-aware, and will be the same tz as the server's time,
|
|
125
125
|
# so we can safely remove the tzinfo from the Date fact before comparison.
|
|
126
|
-
|
|
127
|
-
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:
|
|
128
128
|
download = True
|
|
129
129
|
|
|
130
130
|
if sha1sum:
|
|
@@ -227,11 +227,11 @@ def download(
|
|
|
227
227
|
|
|
228
228
|
@operation()
|
|
229
229
|
def line(
|
|
230
|
-
path,
|
|
231
|
-
line,
|
|
230
|
+
path: str,
|
|
231
|
+
line: str,
|
|
232
232
|
present=True,
|
|
233
|
-
replace=None,
|
|
234
|
-
flags=None,
|
|
233
|
+
replace: str | None = None,
|
|
234
|
+
flags: list[str] | None = None,
|
|
235
235
|
backup=False,
|
|
236
236
|
interpolate_variables=False,
|
|
237
237
|
escape_regex_characters=False,
|
|
@@ -269,7 +269,7 @@ def line(
|
|
|
269
269
|
it will be append to the end of the file.
|
|
270
270
|
|
|
271
271
|
Ensure new line:
|
|
272
|
-
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
|
|
273
273
|
line in case the file doesn't end with a newline character.
|
|
274
274
|
|
|
275
275
|
|
|
@@ -427,10 +427,10 @@ def line(
|
|
|
427
427
|
|
|
428
428
|
@operation()
|
|
429
429
|
def replace(
|
|
430
|
-
path,
|
|
431
|
-
text=None,
|
|
432
|
-
replace=None,
|
|
433
|
-
flags=None,
|
|
430
|
+
path: str,
|
|
431
|
+
text: str | None = None,
|
|
432
|
+
replace: str | None = None,
|
|
433
|
+
flags: list[str] | None = None,
|
|
434
434
|
backup=False,
|
|
435
435
|
interpolate_variables=False,
|
|
436
436
|
match=None, # deprecated
|
|
@@ -501,15 +501,15 @@ def replace(
|
|
|
501
501
|
|
|
502
502
|
@operation()
|
|
503
503
|
def sync(
|
|
504
|
-
src,
|
|
505
|
-
dest,
|
|
506
|
-
user=None,
|
|
507
|
-
group=None,
|
|
508
|
-
mode=None,
|
|
509
|
-
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,
|
|
510
510
|
delete=False,
|
|
511
|
-
exclude=None,
|
|
512
|
-
exclude_dir=None,
|
|
511
|
+
exclude: str | list[str] | tuple[str] | None = None,
|
|
512
|
+
exclude_dir: str | list[str] | tuple[str] | None = None,
|
|
513
513
|
add_deploy_dir=True,
|
|
514
514
|
):
|
|
515
515
|
"""
|
|
@@ -652,7 +652,7 @@ def show_rsync_warning():
|
|
|
652
652
|
|
|
653
653
|
|
|
654
654
|
@operation(is_idempotent=False)
|
|
655
|
-
def rsync(src, dest, flags
|
|
655
|
+
def rsync(src: str, dest: str, flags: list[str] | None = None):
|
|
656
656
|
"""
|
|
657
657
|
Use ``rsync`` to sync a local directory to the remote system. This operation will actually call
|
|
658
658
|
the ``rsync`` binary on your system.
|
|
@@ -667,6 +667,8 @@ def rsync(src, dest, flags=["-ax", "--delete"]):
|
|
|
667
667
|
global arguments.
|
|
668
668
|
"""
|
|
669
669
|
|
|
670
|
+
if flags is None:
|
|
671
|
+
flags = ["-ax", "--delete"]
|
|
670
672
|
show_rsync_warning()
|
|
671
673
|
|
|
672
674
|
try:
|
|
@@ -696,8 +698,8 @@ def _create_remote_dir(remote_filename, user, group):
|
|
|
696
698
|
is_idempotent=False,
|
|
697
699
|
)
|
|
698
700
|
def get(
|
|
699
|
-
src,
|
|
700
|
-
dest,
|
|
701
|
+
src: str,
|
|
702
|
+
dest: str,
|
|
701
703
|
add_deploy_dir=True,
|
|
702
704
|
create_local_dir=False,
|
|
703
705
|
force=False,
|
|
@@ -756,11 +758,11 @@ def get(
|
|
|
756
758
|
|
|
757
759
|
@operation()
|
|
758
760
|
def put(
|
|
759
|
-
src,
|
|
760
|
-
dest,
|
|
761
|
-
user=None,
|
|
762
|
-
group=None,
|
|
763
|
-
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,
|
|
764
766
|
add_deploy_dir=True,
|
|
765
767
|
create_remote_dir=True,
|
|
766
768
|
force=False,
|
|
@@ -821,6 +823,7 @@ def put(
|
|
|
821
823
|
|
|
822
824
|
# Assume string filename
|
|
823
825
|
else:
|
|
826
|
+
assert isinstance(src, (str, Path))
|
|
824
827
|
# Add deploy directory?
|
|
825
828
|
if add_deploy_dir and state.cwd:
|
|
826
829
|
src = os.path.join(state.cwd, src)
|
|
@@ -835,7 +838,7 @@ def put(
|
|
|
835
838
|
raise IOError("No such file: {0}".format(local_file))
|
|
836
839
|
|
|
837
840
|
if mode is True:
|
|
838
|
-
if os.path.isfile(local_file):
|
|
841
|
+
if isinstance(local_file, str) and os.path.isfile(local_file):
|
|
839
842
|
mode = get_path_permissions_mode(local_file)
|
|
840
843
|
else:
|
|
841
844
|
logger.warning(
|
|
@@ -849,6 +852,7 @@ def put(
|
|
|
849
852
|
remote_file = host.get_fact(File, path=dest)
|
|
850
853
|
|
|
851
854
|
if not remote_file and bool(host.get_fact(Directory, path=dest)):
|
|
855
|
+
assert isinstance(src, str)
|
|
852
856
|
dest = unix_path_join(dest, os.path.basename(src))
|
|
853
857
|
remote_file = host.get_fact(File, path=dest)
|
|
854
858
|
|
|
@@ -905,7 +909,15 @@ def put(
|
|
|
905
909
|
|
|
906
910
|
|
|
907
911
|
@operation()
|
|
908
|
-
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
|
+
):
|
|
909
921
|
'''
|
|
910
922
|
Generate a template using jinja2 and write it to the remote system.
|
|
911
923
|
|
|
@@ -1055,16 +1067,16 @@ def _raise_or_remove_invalid_path(fs_type, path, force, force_backup, force_back
|
|
|
1055
1067
|
|
|
1056
1068
|
@operation()
|
|
1057
1069
|
def link(
|
|
1058
|
-
path,
|
|
1059
|
-
target=None,
|
|
1070
|
+
path: str,
|
|
1071
|
+
target: str | None = None,
|
|
1060
1072
|
present=True,
|
|
1061
|
-
user=None,
|
|
1062
|
-
group=None,
|
|
1073
|
+
user: str | None = None,
|
|
1074
|
+
group: str | None = None,
|
|
1063
1075
|
symbolic=True,
|
|
1064
1076
|
create_remote_dir=True,
|
|
1065
1077
|
force=False,
|
|
1066
1078
|
force_backup=True,
|
|
1067
|
-
force_backup_dir=None,
|
|
1079
|
+
force_backup_dir: str | None = None,
|
|
1068
1080
|
):
|
|
1069
1081
|
"""
|
|
1070
1082
|
Add/remove/update links.
|
|
@@ -1162,16 +1174,16 @@ def link(
|
|
|
1162
1174
|
|
|
1163
1175
|
@operation()
|
|
1164
1176
|
def file(
|
|
1165
|
-
path,
|
|
1177
|
+
path: str,
|
|
1166
1178
|
present=True,
|
|
1167
|
-
user=None,
|
|
1168
|
-
group=None,
|
|
1169
|
-
mode=None,
|
|
1179
|
+
user: str | None = None,
|
|
1180
|
+
group: str | None = None,
|
|
1181
|
+
mode: int | str | None = None,
|
|
1170
1182
|
touch=False,
|
|
1171
1183
|
create_remote_dir=True,
|
|
1172
1184
|
force=False,
|
|
1173
1185
|
force_backup=True,
|
|
1174
|
-
force_backup_dir=None,
|
|
1186
|
+
force_backup_dir: str | None = None,
|
|
1175
1187
|
):
|
|
1176
1188
|
"""
|
|
1177
1189
|
Add/remove/update files.
|
|
@@ -1264,15 +1276,15 @@ def file(
|
|
|
1264
1276
|
|
|
1265
1277
|
@operation()
|
|
1266
1278
|
def directory(
|
|
1267
|
-
path,
|
|
1279
|
+
path: str,
|
|
1268
1280
|
present=True,
|
|
1269
|
-
user=None,
|
|
1270
|
-
group=None,
|
|
1271
|
-
mode=None,
|
|
1281
|
+
user: str | None = None,
|
|
1282
|
+
group: str | None = None,
|
|
1283
|
+
mode: int | str | None = None,
|
|
1272
1284
|
recursive=False,
|
|
1273
1285
|
force=False,
|
|
1274
1286
|
force_backup=True,
|
|
1275
|
-
force_backup_dir=None,
|
|
1287
|
+
force_backup_dir: str | None = None,
|
|
1276
1288
|
_no_check_owner_mode=False,
|
|
1277
1289
|
_no_fail_on_link=False,
|
|
1278
1290
|
):
|
|
@@ -1365,7 +1377,7 @@ def directory(
|
|
|
1365
1377
|
|
|
1366
1378
|
|
|
1367
1379
|
@operation()
|
|
1368
|
-
def flags(path, flags=None, present=True):
|
|
1380
|
+
def flags(path: str, flags: list[str] | None = None, present=True):
|
|
1369
1381
|
"""
|
|
1370
1382
|
Set/clear file flags.
|
|
1371
1383
|
|
|
@@ -1414,18 +1426,18 @@ def flags(path, flags=None, present=True):
|
|
|
1414
1426
|
|
|
1415
1427
|
@operation()
|
|
1416
1428
|
def block(
|
|
1417
|
-
path,
|
|
1418
|
-
content=None,
|
|
1429
|
+
path: str,
|
|
1430
|
+
content: str | list[str] | None = None,
|
|
1419
1431
|
present=True,
|
|
1420
|
-
line=None,
|
|
1432
|
+
line: str | None = None,
|
|
1421
1433
|
backup=False,
|
|
1422
1434
|
escape_regex_characters=False,
|
|
1423
1435
|
try_prevent_shell_expansion=False,
|
|
1424
1436
|
before=False,
|
|
1425
1437
|
after=False,
|
|
1426
|
-
marker=None,
|
|
1427
|
-
begin=None,
|
|
1428
|
-
end=None,
|
|
1438
|
+
marker: str | None = None,
|
|
1439
|
+
begin: str | None = None,
|
|
1440
|
+
end: str | None = None,
|
|
1429
1441
|
):
|
|
1430
1442
|
"""
|
|
1431
1443
|
Ensure content, surrounded by the appropriate markers, is present (or not) in the file.
|
|
@@ -1573,6 +1585,7 @@ def block(
|
|
|
1573
1585
|
f"\n{the_block}\n{here}",
|
|
1574
1586
|
)
|
|
1575
1587
|
elif current == []: # markers not found and have a pattern to match (not start or end)
|
|
1588
|
+
assert isinstance(line, str)
|
|
1576
1589
|
regex = adjust_regex(line, escape_regex_characters)
|
|
1577
1590
|
print_before = "{ print }" if before else ""
|
|
1578
1591
|
print_after = "{ print }" if after else ""
|
|
@@ -1601,9 +1614,11 @@ def block(
|
|
|
1601
1614
|
out_prep,
|
|
1602
1615
|
prog,
|
|
1603
1616
|
q_path,
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1617
|
+
(
|
|
1618
|
+
'"' + "\n".join(content) + '"'
|
|
1619
|
+
if not try_prevent_shell_expansion
|
|
1620
|
+
else "'" + "\n".join(content) + "'"
|
|
1621
|
+
),
|
|
1607
1622
|
"> $OUT &&",
|
|
1608
1623
|
real_out,
|
|
1609
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
|
|