pyinfra 3.1.1__py2.py3-none-any.whl → 3.3__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyinfra/api/arguments.py +9 -2
- pyinfra/api/arguments_typed.py +4 -5
- pyinfra/api/command.py +22 -3
- pyinfra/api/config.py +5 -2
- pyinfra/api/deploy.py +4 -2
- pyinfra/api/facts.py +3 -0
- pyinfra/api/host.py +15 -7
- pyinfra/api/operation.py +2 -1
- pyinfra/api/state.py +1 -1
- pyinfra/connectors/base.py +34 -8
- pyinfra/connectors/chroot.py +7 -2
- pyinfra/connectors/docker.py +24 -8
- pyinfra/connectors/dockerssh.py +7 -2
- pyinfra/connectors/local.py +7 -2
- pyinfra/connectors/ssh.py +9 -2
- pyinfra/connectors/sshuserclient/client.py +42 -14
- pyinfra/connectors/sshuserclient/config.py +2 -0
- pyinfra/connectors/terraform.py +1 -1
- pyinfra/connectors/util.py +13 -9
- pyinfra/context.py +9 -2
- pyinfra/facts/apk.py +8 -1
- pyinfra/facts/apt.py +68 -0
- pyinfra/facts/brew.py +13 -0
- pyinfra/facts/bsdinit.py +3 -0
- pyinfra/facts/cargo.py +5 -0
- pyinfra/facts/choco.py +6 -0
- pyinfra/facts/crontab.py +195 -0
- pyinfra/facts/deb.py +10 -0
- pyinfra/facts/dnf.py +5 -0
- pyinfra/facts/docker.py +16 -0
- pyinfra/facts/efibootmgr.py +113 -0
- pyinfra/facts/files.py +112 -7
- pyinfra/facts/flatpak.py +7 -0
- pyinfra/facts/freebsd.py +75 -0
- pyinfra/facts/gem.py +5 -0
- pyinfra/facts/git.py +12 -2
- pyinfra/facts/gpg.py +7 -0
- pyinfra/facts/hardware.py +13 -0
- pyinfra/facts/iptables.py +9 -1
- pyinfra/facts/launchd.py +5 -0
- pyinfra/facts/lxd.py +5 -0
- pyinfra/facts/mysql.py +9 -2
- pyinfra/facts/npm.py +5 -0
- pyinfra/facts/openrc.py +8 -0
- pyinfra/facts/opkg.py +245 -0
- pyinfra/facts/pacman.py +9 -1
- pyinfra/facts/pip.py +5 -0
- pyinfra/facts/pipx.py +82 -0
- pyinfra/facts/pkg.py +4 -0
- pyinfra/facts/pkgin.py +5 -0
- pyinfra/facts/podman.py +54 -0
- pyinfra/facts/postgres.py +10 -2
- pyinfra/facts/rpm.py +11 -0
- pyinfra/facts/runit.py +7 -0
- pyinfra/facts/selinux.py +16 -0
- pyinfra/facts/server.py +87 -79
- pyinfra/facts/snap.py +7 -0
- pyinfra/facts/systemd.py +5 -0
- pyinfra/facts/sysvinit.py +4 -0
- pyinfra/facts/upstart.py +5 -0
- pyinfra/facts/util/__init__.py +4 -1
- pyinfra/facts/util/units.py +30 -0
- pyinfra/facts/vzctl.py +5 -0
- pyinfra/facts/xbps.py +6 -1
- pyinfra/facts/yum.py +5 -0
- pyinfra/facts/zfs.py +41 -21
- pyinfra/facts/zypper.py +5 -0
- pyinfra/local.py +3 -2
- pyinfra/operations/apt.py +36 -22
- pyinfra/operations/crontab.py +189 -0
- pyinfra/operations/docker.py +61 -56
- pyinfra/operations/files.py +65 -1
- pyinfra/operations/freebsd/__init__.py +12 -0
- pyinfra/operations/freebsd/freebsd_update.py +70 -0
- pyinfra/operations/freebsd/pkg.py +219 -0
- pyinfra/operations/freebsd/service.py +116 -0
- pyinfra/operations/freebsd/sysrc.py +92 -0
- pyinfra/operations/git.py +23 -7
- pyinfra/operations/opkg.py +88 -0
- pyinfra/operations/pip.py +3 -2
- pyinfra/operations/pipx.py +90 -0
- pyinfra/operations/postgres.py +114 -27
- pyinfra/operations/runit.py +2 -0
- pyinfra/operations/server.py +9 -181
- pyinfra/operations/util/docker.py +44 -22
- pyinfra/operations/zfs.py +3 -3
- {pyinfra-3.1.1.dist-info → pyinfra-3.3.dist-info}/LICENSE.md +1 -1
- {pyinfra-3.1.1.dist-info → pyinfra-3.3.dist-info}/METADATA +25 -25
- pyinfra-3.3.dist-info/RECORD +187 -0
- pyinfra_cli/exceptions.py +5 -0
- pyinfra_cli/inventory.py +26 -9
- pyinfra_cli/log.py +3 -0
- pyinfra_cli/main.py +9 -8
- pyinfra_cli/prints.py +19 -4
- pyinfra_cli/util.py +3 -0
- pyinfra_cli/virtualenv.py +1 -1
- tests/test_cli/test_cli_deploy.py +15 -13
- tests/test_cli/test_cli_inventory.py +53 -0
- tests/test_connectors/test_ssh.py +302 -182
- tests/test_connectors/test_sshuserclient.py +68 -1
- pyinfra-3.1.1.dist-info/RECORD +0 -172
- {pyinfra-3.1.1.dist-info → pyinfra-3.3.dist-info}/WHEEL +0 -0
- {pyinfra-3.1.1.dist-info → pyinfra-3.3.dist-info}/entry_points.txt +0 -0
- {pyinfra-3.1.1.dist-info → pyinfra-3.3.dist-info}/top_level.txt +0 -0
pyinfra/operations/docker.py
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Manager Docker
|
|
2
|
+
Manager Docker containers, volumes and networks. These operations allow you to manage Docker from
|
|
3
|
+
the view of the current inventory host. See the :doc:`../connectors/docker` to use Docker containers
|
|
4
|
+
as inventory directly.
|
|
3
5
|
"""
|
|
4
6
|
|
|
5
7
|
from pyinfra import host
|
|
6
8
|
from pyinfra.api import operation
|
|
7
9
|
from pyinfra.facts.docker import DockerContainer, DockerNetwork, DockerVolume
|
|
8
10
|
|
|
9
|
-
from .util.docker import handle_docker
|
|
11
|
+
from .util.docker import ContainerSpec, handle_docker
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
@operation()
|
|
@@ -30,9 +32,9 @@ def container(
|
|
|
30
32
|
+ networks: network list to attach on container
|
|
31
33
|
+ ports: port list to expose
|
|
32
34
|
+ volumes: volume list to map on container
|
|
33
|
-
+ env_vars: environment
|
|
35
|
+
+ env_vars: environment variable list to inject on container
|
|
34
36
|
+ pull_always: force image pull
|
|
35
|
-
+ force: remove a
|
|
37
|
+
+ force: remove a container with same name and create a new one
|
|
36
38
|
+ present: whether the container should be up and running
|
|
37
39
|
+ start: start or stop the container
|
|
38
40
|
|
|
@@ -68,56 +70,60 @@ def container(
|
|
|
68
70
|
)
|
|
69
71
|
"""
|
|
70
72
|
|
|
73
|
+
want_spec = ContainerSpec(
|
|
74
|
+
image,
|
|
75
|
+
ports or list(),
|
|
76
|
+
networks or list(),
|
|
77
|
+
volumes or list(),
|
|
78
|
+
env_vars or list(),
|
|
79
|
+
pull_always,
|
|
80
|
+
)
|
|
71
81
|
existent_container = host.get_fact(DockerContainer, object_id=container)
|
|
72
82
|
|
|
73
|
-
|
|
74
|
-
if existent_container:
|
|
75
|
-
yield handle_docker(
|
|
76
|
-
resource="container",
|
|
77
|
-
command="remove",
|
|
78
|
-
container=container,
|
|
79
|
-
)
|
|
83
|
+
container_spec_changes = want_spec.diff_from_inspect(existent_container)
|
|
80
84
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
start=start,
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
if existent_container and start:
|
|
99
|
-
if existent_container[0]["State"]["Status"] != "running":
|
|
100
|
-
yield handle_docker(
|
|
101
|
-
resource="container",
|
|
102
|
-
command="start",
|
|
103
|
-
container=container,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
if existent_container and not start:
|
|
107
|
-
if existent_container[0]["State"]["Status"] == "running":
|
|
108
|
-
yield handle_docker(
|
|
109
|
-
resource="container",
|
|
110
|
-
command="stop",
|
|
111
|
-
container=container,
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
if existent_container and not present:
|
|
85
|
+
is_running = (
|
|
86
|
+
(existent_container[0]["State"]["Status"] == "running")
|
|
87
|
+
if existent_container and existent_container[0]
|
|
88
|
+
else False
|
|
89
|
+
)
|
|
90
|
+
recreating = existent_container and (force or container_spec_changes)
|
|
91
|
+
removing = existent_container and not present
|
|
92
|
+
|
|
93
|
+
do_remove = recreating or removing
|
|
94
|
+
do_create = (present and not existent_container) or recreating
|
|
95
|
+
do_start = start and (recreating or not is_running)
|
|
96
|
+
do_stop = not start and not removing and is_running
|
|
97
|
+
|
|
98
|
+
if do_remove:
|
|
115
99
|
yield handle_docker(
|
|
116
100
|
resource="container",
|
|
117
101
|
command="remove",
|
|
118
102
|
container=container,
|
|
119
103
|
)
|
|
120
104
|
|
|
105
|
+
if do_create:
|
|
106
|
+
yield handle_docker(
|
|
107
|
+
resource="container",
|
|
108
|
+
command="create",
|
|
109
|
+
container=container,
|
|
110
|
+
spec=want_spec,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
if do_start:
|
|
114
|
+
yield handle_docker(
|
|
115
|
+
resource="container",
|
|
116
|
+
command="start",
|
|
117
|
+
container=container,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if do_stop:
|
|
121
|
+
yield handle_docker(
|
|
122
|
+
resource="container",
|
|
123
|
+
command="stop",
|
|
124
|
+
container=container,
|
|
125
|
+
)
|
|
126
|
+
|
|
121
127
|
|
|
122
128
|
@operation(is_idempotent=False)
|
|
123
129
|
def image(image, present=True):
|
|
@@ -125,7 +131,7 @@ def image(image, present=True):
|
|
|
125
131
|
Manage Docker images
|
|
126
132
|
|
|
127
133
|
+ image: Image and tag ex: nginx:alpine
|
|
128
|
-
+ present: whether the Docker image should
|
|
134
|
+
+ present: whether the Docker image should exist
|
|
129
135
|
|
|
130
136
|
**Examples:**
|
|
131
137
|
|
|
@@ -188,7 +194,7 @@ def volume(volume, driver="", labels=None, present=True):
|
|
|
188
194
|
if present:
|
|
189
195
|
|
|
190
196
|
if existent_volume:
|
|
191
|
-
host.noop("Volume
|
|
197
|
+
host.noop("Volume already exists!")
|
|
192
198
|
return
|
|
193
199
|
|
|
194
200
|
yield handle_docker(
|
|
@@ -231,8 +237,8 @@ def network(
|
|
|
231
237
|
"""
|
|
232
238
|
Manage docker networks
|
|
233
239
|
|
|
234
|
-
+
|
|
235
|
-
+ driver:
|
|
240
|
+
+ network: Network name
|
|
241
|
+
+ driver: Network driver ex: bridge or overlay
|
|
236
242
|
+ gateway: IPv4 or IPv6 Gateway for the master subnet
|
|
237
243
|
+ ip_range: Allocate container ip from a sub-range
|
|
238
244
|
+ ipam_driver: IP Address Management Driver
|
|
@@ -251,8 +257,7 @@ def network(
|
|
|
251
257
|
|
|
252
258
|
# Create Docker network
|
|
253
259
|
docker.network(
|
|
254
|
-
|
|
255
|
-
network_name="nginx",
|
|
260
|
+
network="nginx",
|
|
256
261
|
attachable=True,
|
|
257
262
|
present=True,
|
|
258
263
|
)
|
|
@@ -261,7 +266,7 @@ def network(
|
|
|
261
266
|
|
|
262
267
|
if present:
|
|
263
268
|
if existent_network:
|
|
264
|
-
host.noop("
|
|
269
|
+
host.noop("Network {0} already exists!".format(network))
|
|
265
270
|
return
|
|
266
271
|
|
|
267
272
|
yield handle_docker(
|
|
@@ -284,12 +289,12 @@ def network(
|
|
|
284
289
|
|
|
285
290
|
else:
|
|
286
291
|
if existent_network is None:
|
|
287
|
-
host.noop("
|
|
292
|
+
host.noop("Network {0} does not exist!".format(network))
|
|
288
293
|
return
|
|
289
294
|
|
|
290
295
|
yield handle_docker(
|
|
291
296
|
resource="network",
|
|
292
|
-
command="
|
|
297
|
+
command="remove",
|
|
293
298
|
network=network,
|
|
294
299
|
)
|
|
295
300
|
|
|
@@ -297,7 +302,7 @@ def network(
|
|
|
297
302
|
@operation(is_idempotent=False)
|
|
298
303
|
def prune(
|
|
299
304
|
all=False,
|
|
300
|
-
|
|
305
|
+
volumes=False,
|
|
301
306
|
filter="",
|
|
302
307
|
):
|
|
303
308
|
"""
|
|
@@ -334,6 +339,6 @@ def prune(
|
|
|
334
339
|
resource="system",
|
|
335
340
|
command="prune",
|
|
336
341
|
all=all,
|
|
337
|
-
|
|
342
|
+
volumes=volumes,
|
|
338
343
|
filter=filter,
|
|
339
344
|
)
|
pyinfra/operations/files.py
CHANGED
|
@@ -51,6 +51,7 @@ from pyinfra.facts.files import (
|
|
|
51
51
|
Md5File,
|
|
52
52
|
Sha1File,
|
|
53
53
|
Sha256File,
|
|
54
|
+
Sha384File,
|
|
54
55
|
)
|
|
55
56
|
from pyinfra.facts.server import Date, Which
|
|
56
57
|
|
|
@@ -67,6 +68,7 @@ def download(
|
|
|
67
68
|
mode: str | None = None,
|
|
68
69
|
cache_time: int | None = None,
|
|
69
70
|
force=False,
|
|
71
|
+
sha384sum: str | None = None,
|
|
70
72
|
sha256sum: str | None = None,
|
|
71
73
|
sha1sum: str | None = None,
|
|
72
74
|
md5sum: str | None = None,
|
|
@@ -84,6 +86,7 @@ def download(
|
|
|
84
86
|
+ mode: permissions of the files
|
|
85
87
|
+ cache_time: if the file exists already, re-download after this time (in seconds)
|
|
86
88
|
+ force: always download the file, even if it already exists
|
|
89
|
+
+ sha384sum: sha384 hash to checksum the downloaded file against
|
|
87
90
|
+ sha256sum: sha256 hash to checksum the downloaded file against
|
|
88
91
|
+ sha1sum: sha1 hash to checksum the downloaded file against
|
|
89
92
|
+ md5sum: md5 hash to checksum the downloaded file against
|
|
@@ -135,6 +138,10 @@ def download(
|
|
|
135
138
|
if sha256sum != host.get_fact(Sha256File, path=dest):
|
|
136
139
|
download = True
|
|
137
140
|
|
|
141
|
+
if sha384sum:
|
|
142
|
+
if sha384sum != host.get_fact(Sha384File, path=dest):
|
|
143
|
+
download = True
|
|
144
|
+
|
|
138
145
|
if md5sum:
|
|
139
146
|
if md5sum != host.get_fact(Md5File, path=dest):
|
|
140
147
|
download = True
|
|
@@ -211,6 +218,17 @@ def download(
|
|
|
211
218
|
QuoteString("SHA256 did not match!"),
|
|
212
219
|
)
|
|
213
220
|
|
|
221
|
+
if sha384sum:
|
|
222
|
+
yield make_formatted_string_command(
|
|
223
|
+
(
|
|
224
|
+
"(( sha384sum {0} 2> /dev/null || shasum -a 384 {0} ) "
|
|
225
|
+
"| grep {1}) || ( echo {2} && exit 1 )"
|
|
226
|
+
),
|
|
227
|
+
QuoteString(dest),
|
|
228
|
+
sha384sum,
|
|
229
|
+
QuoteString("SHA384 did not match!"),
|
|
230
|
+
)
|
|
231
|
+
|
|
214
232
|
if md5sum:
|
|
215
233
|
yield make_formatted_string_command(
|
|
216
234
|
(
|
|
@@ -647,7 +665,7 @@ def sync(
|
|
|
647
665
|
|
|
648
666
|
|
|
649
667
|
@memoize
|
|
650
|
-
def show_rsync_warning():
|
|
668
|
+
def show_rsync_warning() -> None:
|
|
651
669
|
logger.warning("The `files.rsync` operation is in alpha!")
|
|
652
670
|
|
|
653
671
|
|
|
@@ -940,6 +958,9 @@ def template(
|
|
|
940
958
|
a dict with arguments that will be passed as keyword args to the jinja2
|
|
941
959
|
`Environment() <https://jinja.palletsprojects.com/en/3.0.x/api/#jinja2.Environment>`_.
|
|
942
960
|
|
|
961
|
+
The ``host``, ``state``, and ``inventory`` objects will be automatically passed to the template
|
|
962
|
+
if not set explicitly.
|
|
963
|
+
|
|
943
964
|
Notes:
|
|
944
965
|
Common convention is to store templates in a "templates" directory and
|
|
945
966
|
have a filename suffix with '.j2' (for jinja2).
|
|
@@ -997,6 +1018,21 @@ def template(
|
|
|
997
1018
|
foo_dict=foo_dict,
|
|
998
1019
|
foo_list=foo_list
|
|
999
1020
|
)
|
|
1021
|
+
|
|
1022
|
+
# Example showing how to use host and inventory in a template file.
|
|
1023
|
+
template = StringIO("""
|
|
1024
|
+
name: "{{ host.name }}"
|
|
1025
|
+
list_contents:
|
|
1026
|
+
{% for entry in inventory.groups.my_servers %}
|
|
1027
|
+
- "{{ entry }}"
|
|
1028
|
+
{% endfor %}
|
|
1029
|
+
""")
|
|
1030
|
+
|
|
1031
|
+
files.template(
|
|
1032
|
+
name="Create a templated file",
|
|
1033
|
+
src=template,
|
|
1034
|
+
dest="/tmp/foo.yml"
|
|
1035
|
+
)
|
|
1000
1036
|
'''
|
|
1001
1037
|
|
|
1002
1038
|
if not hasattr(src, "read") and state.cwd:
|
|
@@ -1051,6 +1087,34 @@ def template(
|
|
|
1051
1087
|
)
|
|
1052
1088
|
|
|
1053
1089
|
|
|
1090
|
+
@operation()
|
|
1091
|
+
def move(src: str, dest: str, overwrite=False):
|
|
1092
|
+
"""
|
|
1093
|
+
Move remote file/directory/link into remote directory
|
|
1094
|
+
|
|
1095
|
+
+ src: remote file/directory to move
|
|
1096
|
+
+ dest: remote directory to move `src` into
|
|
1097
|
+
+ overwrite: whether to overwrite dest, if present
|
|
1098
|
+
"""
|
|
1099
|
+
|
|
1100
|
+
if host.get_fact(File, src) is None:
|
|
1101
|
+
raise OperationError("src {0} does not exist".format(src))
|
|
1102
|
+
|
|
1103
|
+
if not host.get_fact(Directory, dest):
|
|
1104
|
+
raise OperationError("dest {0} is not an existing directory".format(dest))
|
|
1105
|
+
|
|
1106
|
+
full_dest_path = os.path.join(dest, os.path.basename(src))
|
|
1107
|
+
if host.get_fact(File, full_dest_path) is not None:
|
|
1108
|
+
if overwrite:
|
|
1109
|
+
yield StringCommand("rm", "-rf", QuoteString(full_dest_path))
|
|
1110
|
+
else:
|
|
1111
|
+
raise OperationError(
|
|
1112
|
+
"dest {0} already exists and `overwrite` is unset".format(full_dest_path)
|
|
1113
|
+
)
|
|
1114
|
+
|
|
1115
|
+
yield StringCommand("mv", QuoteString(src), QuoteString(dest))
|
|
1116
|
+
|
|
1117
|
+
|
|
1054
1118
|
def _validate_path(path):
|
|
1055
1119
|
try:
|
|
1056
1120
|
return os.fspath(path)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# This file only exists to support:
|
|
2
|
+
# from pyinfra.operations import freebsd
|
|
3
|
+
# freebsd.X.Y
|
|
4
|
+
|
|
5
|
+
from glob import glob
|
|
6
|
+
from os import path
|
|
7
|
+
|
|
8
|
+
module_filenames = glob(path.join(path.dirname(__file__), "*.py"))
|
|
9
|
+
module_names = [path.basename(name)[:-3] for name in module_filenames]
|
|
10
|
+
__all__ = [name for name in module_names if name != "__init__"]
|
|
11
|
+
|
|
12
|
+
from . import * # noqa
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Fetch and install binary updates to FreeBSD.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing_extensions import List, Optional, Union
|
|
8
|
+
|
|
9
|
+
from pyinfra.api import QuoteString, StringCommand, operation
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@operation()
|
|
13
|
+
def update(
|
|
14
|
+
force: bool = False,
|
|
15
|
+
basedir: Optional[str] = None,
|
|
16
|
+
workdir: Optional[str] = None,
|
|
17
|
+
conffile: Optional[str] = None,
|
|
18
|
+
jail: Optional[str] = None,
|
|
19
|
+
key: Optional[str] = None,
|
|
20
|
+
currently_running: Optional[str] = None,
|
|
21
|
+
server: Optional[str] = None,
|
|
22
|
+
):
|
|
23
|
+
"""
|
|
24
|
+
Based on the currently installed world and the configuration options set, fetch
|
|
25
|
+
all available binary updates and install them.
|
|
26
|
+
|
|
27
|
+
+ force: See ``-F`` in ``freebsd-update(8)``.
|
|
28
|
+
+ basedir: See ``-b`` in ``freebsd-update(8)``.
|
|
29
|
+
+ workdir: See ``-d`` in ``freebsd-update(8)``.
|
|
30
|
+
+ conffile: See ``-f`` in ``freebsd-update(8)``.
|
|
31
|
+
+ jail: See ``-j`` in ``freebsd-update(8)``.
|
|
32
|
+
+ key: See ``-k`` in ``freebsd-update(8)``.
|
|
33
|
+
+ currently_running: See ``--currently-running`` in ``freebsd-update(8)``.
|
|
34
|
+
+ server: See ``-s`` in ``freebsd-update(8)``.
|
|
35
|
+
|
|
36
|
+
**Example:**
|
|
37
|
+
|
|
38
|
+
.. code:: python
|
|
39
|
+
|
|
40
|
+
freebsd_update.update()
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
args: List[Union[str, "QuoteString"]] = []
|
|
44
|
+
|
|
45
|
+
args.extend(["PAGER=cat", "freebsd-update", "--not-running-from-cron"])
|
|
46
|
+
|
|
47
|
+
if force:
|
|
48
|
+
args.append("-F")
|
|
49
|
+
|
|
50
|
+
if basedir is not None:
|
|
51
|
+
args.extend(["-b", QuoteString(basedir)])
|
|
52
|
+
|
|
53
|
+
if workdir is not None:
|
|
54
|
+
args.extend(["-d", QuoteString(workdir)])
|
|
55
|
+
|
|
56
|
+
if conffile is not None:
|
|
57
|
+
args.extend(["-f", QuoteString(conffile)])
|
|
58
|
+
|
|
59
|
+
if jail is not None:
|
|
60
|
+
args.extend(["-j", QuoteString(jail)])
|
|
61
|
+
|
|
62
|
+
if key is not None:
|
|
63
|
+
args.extend(["-k", QuoteString(key)])
|
|
64
|
+
|
|
65
|
+
if server is not None:
|
|
66
|
+
args.extend(["-s", QuoteString(server)])
|
|
67
|
+
|
|
68
|
+
args.extend(["fetch", "install"])
|
|
69
|
+
|
|
70
|
+
yield StringCommand(*args)
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage FreeBSD packages.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing_extensions import List, Optional, Union
|
|
8
|
+
|
|
9
|
+
from pyinfra import host
|
|
10
|
+
from pyinfra.api import QuoteString, StringCommand, operation
|
|
11
|
+
from pyinfra.facts.freebsd import PkgPackage
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@operation()
|
|
15
|
+
def update(jail: Optional[str] = None, force: bool = False, reponame: Optional[str] = None):
|
|
16
|
+
"""
|
|
17
|
+
Update the local catalogues of the enabled package repositories.
|
|
18
|
+
|
|
19
|
+
+ jail: See ``-j`` in ``pkg(8)``.
|
|
20
|
+
+ force: See ``-f`` in ``pkg-update(8)``.
|
|
21
|
+
+ reponame: See ``-r`` in ``pkg-update(8)``
|
|
22
|
+
|
|
23
|
+
**Examples:**
|
|
24
|
+
|
|
25
|
+
.. code:: python
|
|
26
|
+
|
|
27
|
+
# host
|
|
28
|
+
pkg.update()
|
|
29
|
+
|
|
30
|
+
# jail
|
|
31
|
+
pkg.update(
|
|
32
|
+
jail="nginx"
|
|
33
|
+
)
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
args: List[Union[str, "QuoteString"]] = []
|
|
37
|
+
|
|
38
|
+
args.append("pkg")
|
|
39
|
+
|
|
40
|
+
if jail is not None:
|
|
41
|
+
args.extend(["-j", QuoteString(jail)])
|
|
42
|
+
|
|
43
|
+
args.extend(["update"])
|
|
44
|
+
|
|
45
|
+
if force:
|
|
46
|
+
args.append("-f")
|
|
47
|
+
|
|
48
|
+
if reponame is not None:
|
|
49
|
+
args.extend(["-r", QuoteString(reponame)])
|
|
50
|
+
|
|
51
|
+
yield StringCommand(*args)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@operation()
|
|
55
|
+
def upgrade(jail: Optional[str] = None, force: bool = False, reponame: Optional[str] = None):
|
|
56
|
+
"""
|
|
57
|
+
Perform upgrades of package software distributions.
|
|
58
|
+
|
|
59
|
+
+ jail: See ``-j`` in ``pkg(8)``.
|
|
60
|
+
+ force: See ``-f`` in ``pkg-upgrade(8)``.
|
|
61
|
+
+ reponame: See ``-r`` in ``pkg-upgrade(8)``.
|
|
62
|
+
|
|
63
|
+
**Examples:**
|
|
64
|
+
|
|
65
|
+
.. code:: python
|
|
66
|
+
|
|
67
|
+
# host
|
|
68
|
+
pkg.upgrade()
|
|
69
|
+
|
|
70
|
+
# jail
|
|
71
|
+
pkg.upgrade(
|
|
72
|
+
jail="nginx"
|
|
73
|
+
)
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
args: List[Union[str, "QuoteString"]] = []
|
|
77
|
+
|
|
78
|
+
args.append("pkg")
|
|
79
|
+
|
|
80
|
+
if jail is not None:
|
|
81
|
+
args.extend(["-j", QuoteString(jail)])
|
|
82
|
+
|
|
83
|
+
args.extend(["upgrade", "-y"])
|
|
84
|
+
|
|
85
|
+
if force:
|
|
86
|
+
args.append("-f")
|
|
87
|
+
|
|
88
|
+
if reponame is not None:
|
|
89
|
+
args.extend(["-r", QuoteString(reponame)])
|
|
90
|
+
|
|
91
|
+
yield StringCommand(*args)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@operation()
|
|
95
|
+
def install(package: str, jail: Optional[str] = None, reponame: Optional[str] = None):
|
|
96
|
+
"""
|
|
97
|
+
Install packages from remote packages repositories or local archives.
|
|
98
|
+
|
|
99
|
+
+ package: Package to install.
|
|
100
|
+
+ jail: See ``-j`` in ``pkg(8)``.
|
|
101
|
+
+ reponame: See ``-r`` in ``pkg-install(8)``.
|
|
102
|
+
|
|
103
|
+
**Example:**
|
|
104
|
+
|
|
105
|
+
.. code:: python
|
|
106
|
+
|
|
107
|
+
pkg.install("nginx")
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
if host.get_fact(PkgPackage, package=package, jail=jail):
|
|
111
|
+
host.noop(f"Package '{package}' already installed")
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
args: List[Union[str, "QuoteString"]] = []
|
|
115
|
+
|
|
116
|
+
args.append("pkg")
|
|
117
|
+
|
|
118
|
+
if jail is not None:
|
|
119
|
+
args.extend(["-j", QuoteString(jail)])
|
|
120
|
+
|
|
121
|
+
args.extend(["install", "-y"])
|
|
122
|
+
|
|
123
|
+
if reponame is not None:
|
|
124
|
+
args.extend(["-r", QuoteString(reponame)])
|
|
125
|
+
|
|
126
|
+
args.extend(["--", QuoteString(package)])
|
|
127
|
+
|
|
128
|
+
yield StringCommand(*args)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@operation()
|
|
132
|
+
def remove(package: str, jail: Optional[str] = None):
|
|
133
|
+
"""
|
|
134
|
+
Deletes packages from the database and the system.
|
|
135
|
+
|
|
136
|
+
+ package: Package to remove.
|
|
137
|
+
+ jail: See ``-j`` in ``pkg(8)``.
|
|
138
|
+
|
|
139
|
+
**Example:**
|
|
140
|
+
|
|
141
|
+
.. code:: python
|
|
142
|
+
|
|
143
|
+
pkg.remove("nginx")
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
if not host.get_fact(PkgPackage, package=package, jail=jail):
|
|
147
|
+
host.noop(f"Package '{package}' cannot be found")
|
|
148
|
+
return
|
|
149
|
+
|
|
150
|
+
args: List[Union[str, "QuoteString"]] = []
|
|
151
|
+
|
|
152
|
+
args.append("pkg")
|
|
153
|
+
|
|
154
|
+
if jail is not None:
|
|
155
|
+
args.extend(["-j", QuoteString(jail)])
|
|
156
|
+
|
|
157
|
+
args.extend(["remove", "-y"])
|
|
158
|
+
|
|
159
|
+
args.extend(["--", QuoteString(package)])
|
|
160
|
+
|
|
161
|
+
yield StringCommand(*args)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@operation()
|
|
165
|
+
def autoremove(jail: Optional[str] = None):
|
|
166
|
+
"""
|
|
167
|
+
Remove orphan packages.
|
|
168
|
+
|
|
169
|
+
+ jail: See ``-j`` in ``pkg(8)``.
|
|
170
|
+
|
|
171
|
+
**Example:**
|
|
172
|
+
|
|
173
|
+
.. code:: python
|
|
174
|
+
|
|
175
|
+
pkg.autoremove()
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
args: List[Union[str, "QuoteString"]] = []
|
|
179
|
+
|
|
180
|
+
args.append("pkg")
|
|
181
|
+
|
|
182
|
+
if jail is not None:
|
|
183
|
+
args.extend(["-j", QuoteString(jail)])
|
|
184
|
+
|
|
185
|
+
args.extend(["autoremove", "-y"])
|
|
186
|
+
|
|
187
|
+
yield StringCommand(*args)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@operation()
|
|
191
|
+
def clean(all_pkg: bool = False, jail: Optional[str] = None):
|
|
192
|
+
"""
|
|
193
|
+
Clean the local cache of fetched remote packages.
|
|
194
|
+
|
|
195
|
+
+ all_pkg: See ``-a`` in ``pkg-clean(8)``.
|
|
196
|
+
+ jail: See ``-j`` in ``pkg(8)``.
|
|
197
|
+
|
|
198
|
+
**Example:**
|
|
199
|
+
|
|
200
|
+
.. code:: python
|
|
201
|
+
|
|
202
|
+
pkg.clean(
|
|
203
|
+
all_pkg=True
|
|
204
|
+
)
|
|
205
|
+
"""
|
|
206
|
+
|
|
207
|
+
args: List[Union[str, "QuoteString"]] = []
|
|
208
|
+
|
|
209
|
+
args.append("pkg")
|
|
210
|
+
|
|
211
|
+
if jail is not None:
|
|
212
|
+
args.extend(["-j", QuoteString(jail)])
|
|
213
|
+
|
|
214
|
+
args.extend(["clean", "-y"])
|
|
215
|
+
|
|
216
|
+
if all_pkg:
|
|
217
|
+
args.append("-a")
|
|
218
|
+
|
|
219
|
+
yield StringCommand(*args)
|