pyinfra 3.2__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_typed.py +4 -5
- pyinfra/api/command.py +22 -3
- pyinfra/api/config.py +5 -2
- pyinfra/api/facts.py +3 -0
- pyinfra/api/host.py +10 -4
- 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 +7 -2
- pyinfra/connectors/dockerssh.py +7 -2
- pyinfra/connectors/local.py +7 -2
- pyinfra/connectors/ssh.py +9 -2
- pyinfra/connectors/sshuserclient/client.py +16 -0
- 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 +5 -0
- pyinfra/facts/apt.py +9 -1
- 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 +6 -1
- pyinfra/facts/deb.py +10 -0
- pyinfra/facts/dnf.py +5 -0
- pyinfra/facts/docker.py +10 -0
- pyinfra/facts/efibootmgr.py +5 -0
- pyinfra/facts/files.py +19 -1
- pyinfra/facts/flatpak.py +7 -0
- pyinfra/facts/freebsd.py +75 -0
- pyinfra/facts/gem.py +5 -0
- pyinfra/facts/git.py +9 -0
- 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 +8 -0
- pyinfra/facts/npm.py +5 -0
- pyinfra/facts/openrc.py +8 -0
- pyinfra/facts/opkg.py +12 -0
- pyinfra/facts/pacman.py +9 -1
- pyinfra/facts/pip.py +5 -0
- pyinfra/facts/pipx.py +8 -0
- pyinfra/facts/pkg.py +4 -0
- pyinfra/facts/pkgin.py +5 -0
- pyinfra/facts/podman.py +7 -0
- pyinfra/facts/postgres.py +8 -2
- pyinfra/facts/rpm.py +11 -0
- pyinfra/facts/runit.py +7 -0
- pyinfra/facts/selinux.py +16 -0
- pyinfra/facts/server.py +49 -3
- 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/vzctl.py +5 -0
- pyinfra/facts/xbps.py +6 -1
- pyinfra/facts/yum.py +5 -0
- pyinfra/facts/zfs.py +19 -2
- pyinfra/facts/zypper.py +5 -0
- pyinfra/operations/apt.py +10 -3
- pyinfra/operations/docker.py +48 -44
- pyinfra/operations/files.py +47 -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/opkg.py +5 -5
- pyinfra/operations/postgres.py +99 -16
- pyinfra/operations/server.py +6 -4
- pyinfra/operations/util/docker.py +44 -22
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/LICENSE.md +1 -1
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/METADATA +25 -24
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/RECORD +88 -82
- pyinfra_cli/exceptions.py +5 -0
- pyinfra_cli/log.py +3 -0
- pyinfra_cli/main.py +9 -8
- pyinfra_cli/prints.py +1 -1
- pyinfra_cli/virtualenv.py +1 -1
- tests/test_connectors/test_ssh.py +302 -182
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/WHEEL +0 -0
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/entry_points.txt +0 -0
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/top_level.txt +0 -0
pyinfra/operations/docker.py
CHANGED
|
@@ -8,7 +8,7 @@ from pyinfra import host
|
|
|
8
8
|
from pyinfra.api import operation
|
|
9
9
|
from pyinfra.facts.docker import DockerContainer, DockerNetwork, DockerVolume
|
|
10
10
|
|
|
11
|
-
from .util.docker import handle_docker
|
|
11
|
+
from .util.docker import ContainerSpec, handle_docker
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@operation()
|
|
@@ -70,56 +70,60 @@ def container(
|
|
|
70
70
|
)
|
|
71
71
|
"""
|
|
72
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
|
+
)
|
|
73
81
|
existent_container = host.get_fact(DockerContainer, object_id=container)
|
|
74
82
|
|
|
75
|
-
|
|
76
|
-
if existent_container:
|
|
77
|
-
yield handle_docker(
|
|
78
|
-
resource="container",
|
|
79
|
-
command="remove",
|
|
80
|
-
container=container,
|
|
81
|
-
)
|
|
83
|
+
container_spec_changes = want_spec.diff_from_inspect(existent_container)
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
start=start,
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
if existent_container and start:
|
|
101
|
-
if existent_container[0]["State"]["Status"] != "running":
|
|
102
|
-
yield handle_docker(
|
|
103
|
-
resource="container",
|
|
104
|
-
command="start",
|
|
105
|
-
container=container,
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
if existent_container and not start:
|
|
109
|
-
if existent_container[0]["State"]["Status"] == "running":
|
|
110
|
-
yield handle_docker(
|
|
111
|
-
resource="container",
|
|
112
|
-
command="stop",
|
|
113
|
-
container=container,
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
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:
|
|
117
99
|
yield handle_docker(
|
|
118
100
|
resource="container",
|
|
119
101
|
command="remove",
|
|
120
102
|
container=container,
|
|
121
103
|
)
|
|
122
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
|
+
|
|
123
127
|
|
|
124
128
|
@operation(is_idempotent=False)
|
|
125
129
|
def image(image, present=True):
|
|
@@ -298,7 +302,7 @@ def network(
|
|
|
298
302
|
@operation(is_idempotent=False)
|
|
299
303
|
def prune(
|
|
300
304
|
all=False,
|
|
301
|
-
|
|
305
|
+
volumes=False,
|
|
302
306
|
filter="",
|
|
303
307
|
):
|
|
304
308
|
"""
|
|
@@ -335,6 +339,6 @@ def prune(
|
|
|
335
339
|
resource="system",
|
|
336
340
|
command="prune",
|
|
337
341
|
all=all,
|
|
338
|
-
|
|
342
|
+
volumes=volumes,
|
|
339
343
|
filter=filter,
|
|
340
344
|
)
|
pyinfra/operations/files.py
CHANGED
|
@@ -665,7 +665,7 @@ def sync(
|
|
|
665
665
|
|
|
666
666
|
|
|
667
667
|
@memoize
|
|
668
|
-
def show_rsync_warning():
|
|
668
|
+
def show_rsync_warning() -> None:
|
|
669
669
|
logger.warning("The `files.rsync` operation is in alpha!")
|
|
670
670
|
|
|
671
671
|
|
|
@@ -958,6 +958,9 @@ def template(
|
|
|
958
958
|
a dict with arguments that will be passed as keyword args to the jinja2
|
|
959
959
|
`Environment() <https://jinja.palletsprojects.com/en/3.0.x/api/#jinja2.Environment>`_.
|
|
960
960
|
|
|
961
|
+
The ``host``, ``state``, and ``inventory`` objects will be automatically passed to the template
|
|
962
|
+
if not set explicitly.
|
|
963
|
+
|
|
961
964
|
Notes:
|
|
962
965
|
Common convention is to store templates in a "templates" directory and
|
|
963
966
|
have a filename suffix with '.j2' (for jinja2).
|
|
@@ -1015,6 +1018,21 @@ def template(
|
|
|
1015
1018
|
foo_dict=foo_dict,
|
|
1016
1019
|
foo_list=foo_list
|
|
1017
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
|
+
)
|
|
1018
1036
|
'''
|
|
1019
1037
|
|
|
1020
1038
|
if not hasattr(src, "read") and state.cwd:
|
|
@@ -1069,6 +1087,34 @@ def template(
|
|
|
1069
1087
|
)
|
|
1070
1088
|
|
|
1071
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
|
+
|
|
1072
1118
|
def _validate_path(path):
|
|
1073
1119
|
try:
|
|
1074
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)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage FreeBSD services.
|
|
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.api.exceptions import OperationValueError
|
|
12
|
+
from pyinfra.facts.freebsd import ServiceScript, ServiceStatus
|
|
13
|
+
|
|
14
|
+
SRV_STARTED: str = "started"
|
|
15
|
+
SRV_STOPPED: str = "stopped"
|
|
16
|
+
SRV_RESTARTED: str = "restarted"
|
|
17
|
+
SRV_RELOADED: str = "reloaded"
|
|
18
|
+
SRV_CUSTOM: str = "custom"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@operation()
|
|
22
|
+
def service(
|
|
23
|
+
srvname: str,
|
|
24
|
+
jail: Optional[str] = None,
|
|
25
|
+
srvstate: str = SRV_STARTED,
|
|
26
|
+
command: Optional[Union[str, List[str]]] = None,
|
|
27
|
+
environment: Optional[List[str]] = None,
|
|
28
|
+
verbose: bool = False,
|
|
29
|
+
):
|
|
30
|
+
"""
|
|
31
|
+
Control (start/stop/etc.) ``rc(8)`` scripts.
|
|
32
|
+
|
|
33
|
+
+ srvname: Service.
|
|
34
|
+
+ jail: See ``-j`` in ``service(8)``.
|
|
35
|
+
+ srvstate: Desire state of the service.
|
|
36
|
+
+ command: When ``srvstate`` is ``custom``, the command to execute.
|
|
37
|
+
+ environment: See ``-E`` in ``service(8)``.
|
|
38
|
+
+ verbose: See ``-v`` in ``service(8)``.
|
|
39
|
+
|
|
40
|
+
States:
|
|
41
|
+
There are a few states you can use to manipulate the service:
|
|
42
|
+
|
|
43
|
+
- started: The service must be started.
|
|
44
|
+
- stopped: The service must be stopped.
|
|
45
|
+
- restarted: The service must be restarted.
|
|
46
|
+
- reloaded: The service must be reloaded.
|
|
47
|
+
- custom: Run a custom command for this service.
|
|
48
|
+
|
|
49
|
+
**Examples:**
|
|
50
|
+
|
|
51
|
+
.. code:: python
|
|
52
|
+
|
|
53
|
+
# Start a service.
|
|
54
|
+
service.service(
|
|
55
|
+
"beanstalkd",
|
|
56
|
+
srvstate="started"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Execute a custom command.
|
|
60
|
+
service.service(
|
|
61
|
+
"sopel",
|
|
62
|
+
srvstate="custom",
|
|
63
|
+
command="configure"
|
|
64
|
+
)
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
if not host.get_fact(ServiceScript, srvname=srvname, jail=jail):
|
|
68
|
+
host.noop(f"Cannot find rc(8) script '{srvname}'")
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
args: List[Union[str, "QuoteString"]] = []
|
|
72
|
+
|
|
73
|
+
args.append("service")
|
|
74
|
+
|
|
75
|
+
if verbose:
|
|
76
|
+
args.append("-v")
|
|
77
|
+
|
|
78
|
+
if jail is not None:
|
|
79
|
+
args.extend(["-j", QuoteString(jail)])
|
|
80
|
+
|
|
81
|
+
if environment is not None:
|
|
82
|
+
for env_var in environment:
|
|
83
|
+
args.extend(["-E", QuoteString(env_var)])
|
|
84
|
+
|
|
85
|
+
if srvstate == SRV_STARTED:
|
|
86
|
+
if host.get_fact(ServiceStatus, srvname=srvname, jail=jail):
|
|
87
|
+
host.noop(f"Service '{srvname}' already started")
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
args.extend([QuoteString(srvname), "start"])
|
|
91
|
+
|
|
92
|
+
elif srvstate == SRV_STOPPED:
|
|
93
|
+
if not host.get_fact(ServiceStatus, srvname=srvname, jail=jail):
|
|
94
|
+
host.noop(f"Service '{srvname}' already stopped")
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
args.extend([QuoteString(srvname), "stop"])
|
|
98
|
+
elif srvstate == SRV_RESTARTED:
|
|
99
|
+
args.extend([QuoteString(srvname), "restart"])
|
|
100
|
+
|
|
101
|
+
elif srvstate == SRV_RELOADED:
|
|
102
|
+
args.extend([QuoteString(srvname), "reload"])
|
|
103
|
+
|
|
104
|
+
elif srvstate == SRV_CUSTOM:
|
|
105
|
+
args.append(QuoteString(srvname))
|
|
106
|
+
|
|
107
|
+
if command is not None:
|
|
108
|
+
if isinstance(command, str):
|
|
109
|
+
command = [command]
|
|
110
|
+
|
|
111
|
+
args.extend([QuoteString(c) for c in command])
|
|
112
|
+
|
|
113
|
+
else:
|
|
114
|
+
raise OperationValueError(f"Invalid service command: {srvstate}")
|
|
115
|
+
|
|
116
|
+
yield StringCommand(*args)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manipulate system rc files.
|
|
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.api.exceptions import OperationValueError
|
|
12
|
+
from pyinfra.facts.freebsd import Sysrc
|
|
13
|
+
|
|
14
|
+
SYSRC_ADD: str = "add"
|
|
15
|
+
SYSRC_SUB: str = "sub"
|
|
16
|
+
SYSRC_SET: str = "set"
|
|
17
|
+
SYSRC_DEL: str = "del"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@operation()
|
|
21
|
+
def sysrc(
|
|
22
|
+
parameter: str,
|
|
23
|
+
value: str,
|
|
24
|
+
jail: Optional[str] = None,
|
|
25
|
+
command: str = SYSRC_SET,
|
|
26
|
+
overwrite: bool = False,
|
|
27
|
+
):
|
|
28
|
+
"""
|
|
29
|
+
Safely edit system rc files.
|
|
30
|
+
|
|
31
|
+
+ parameter: Parameter to manipulate.
|
|
32
|
+
+ value: Value, if the parameter requires it.
|
|
33
|
+
+ jail: See ``-j`` in ``sysrc(8)``.
|
|
34
|
+
+ command: Desire state of the parameter.
|
|
35
|
+
+ overwrite: Overwrite the value of the parameter when ``command`` is set to ``set``.
|
|
36
|
+
|
|
37
|
+
Commands:
|
|
38
|
+
There are a few commands you can use to manipulate the rc file:
|
|
39
|
+
|
|
40
|
+
- add: Adds the value to the parameter.
|
|
41
|
+
- sub: Delete the parameter value.
|
|
42
|
+
- set: Change the parameter value. If the parameter already has a value
|
|
43
|
+
set, the changes will not be applied unless ``overwrite`` is set
|
|
44
|
+
to ``True``.
|
|
45
|
+
- del: Delete the parameter.
|
|
46
|
+
|
|
47
|
+
**Example:**
|
|
48
|
+
|
|
49
|
+
.. code:: python
|
|
50
|
+
|
|
51
|
+
sysrc.sysrc(
|
|
52
|
+
"beanstalkd_enable",
|
|
53
|
+
"YES",
|
|
54
|
+
command="set"
|
|
55
|
+
)
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
args: List[Union[str, "QuoteString"]] = []
|
|
59
|
+
|
|
60
|
+
args.extend(["sysrc", "-i"])
|
|
61
|
+
|
|
62
|
+
if command == SYSRC_DEL:
|
|
63
|
+
sign = "="
|
|
64
|
+
|
|
65
|
+
if not host.get_fact(Sysrc, parameter=parameter, jail=jail):
|
|
66
|
+
host.noop(f"Cannot find sysrc(8) parameter '{parameter}'")
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
args.append("-x")
|
|
70
|
+
|
|
71
|
+
elif command == SYSRC_SET:
|
|
72
|
+
sign = "="
|
|
73
|
+
|
|
74
|
+
if not overwrite and host.get_fact(Sysrc, parameter=parameter, jail=jail):
|
|
75
|
+
host.noop(f"sysrc(8) parameter '{parameter}' already set")
|
|
76
|
+
return
|
|
77
|
+
|
|
78
|
+
elif command == SYSRC_ADD:
|
|
79
|
+
sign = "+="
|
|
80
|
+
|
|
81
|
+
elif command == SYSRC_SUB:
|
|
82
|
+
sign = "-="
|
|
83
|
+
|
|
84
|
+
else:
|
|
85
|
+
raise OperationValueError(f"Invalid sysrc command: {command}")
|
|
86
|
+
|
|
87
|
+
if jail is not None:
|
|
88
|
+
args.extend(["-j", QuoteString(jail)])
|
|
89
|
+
|
|
90
|
+
args.extend(["--", QuoteString(f"{parameter}{sign}{value}")])
|
|
91
|
+
|
|
92
|
+
yield StringCommand(*args)
|