pyinfra 0.11.dev3__py3-none-any.whl → 3.5.1__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/__init__.py +9 -12
- pyinfra/__main__.py +4 -0
- pyinfra/api/__init__.py +18 -3
- pyinfra/api/arguments.py +406 -0
- pyinfra/api/arguments_typed.py +79 -0
- pyinfra/api/command.py +274 -0
- pyinfra/api/config.py +222 -28
- pyinfra/api/connect.py +33 -13
- pyinfra/api/connectors.py +27 -0
- pyinfra/api/deploy.py +65 -66
- pyinfra/api/exceptions.py +67 -18
- pyinfra/api/facts.py +253 -202
- pyinfra/api/host.py +413 -50
- pyinfra/api/inventory.py +121 -160
- pyinfra/api/operation.py +432 -262
- pyinfra/api/operations.py +273 -260
- pyinfra/api/state.py +302 -248
- pyinfra/api/util.py +291 -368
- pyinfra/connectors/base.py +173 -0
- pyinfra/connectors/chroot.py +212 -0
- pyinfra/connectors/docker.py +381 -0
- pyinfra/connectors/dockerssh.py +297 -0
- pyinfra/connectors/local.py +238 -0
- pyinfra/connectors/scp/__init__.py +1 -0
- pyinfra/connectors/scp/client.py +204 -0
- pyinfra/connectors/ssh.py +670 -0
- pyinfra/connectors/ssh_util.py +114 -0
- pyinfra/connectors/sshuserclient/client.py +309 -0
- pyinfra/connectors/sshuserclient/config.py +102 -0
- pyinfra/connectors/terraform.py +135 -0
- pyinfra/connectors/util.py +410 -0
- pyinfra/connectors/vagrant.py +183 -0
- pyinfra/context.py +145 -0
- pyinfra/facts/__init__.py +7 -6
- pyinfra/facts/apk.py +22 -7
- pyinfra/facts/apt.py +117 -60
- pyinfra/facts/brew.py +100 -15
- pyinfra/facts/bsdinit.py +23 -0
- pyinfra/facts/cargo.py +37 -0
- pyinfra/facts/choco.py +47 -0
- pyinfra/facts/crontab.py +195 -0
- pyinfra/facts/deb.py +94 -0
- pyinfra/facts/dnf.py +48 -0
- pyinfra/facts/docker.py +96 -23
- pyinfra/facts/efibootmgr.py +113 -0
- pyinfra/facts/files.py +630 -58
- pyinfra/facts/flatpak.py +77 -0
- pyinfra/facts/freebsd.py +70 -0
- pyinfra/facts/gem.py +19 -6
- pyinfra/facts/git.py +59 -14
- pyinfra/facts/gpg.py +150 -0
- pyinfra/facts/hardware.py +313 -167
- pyinfra/facts/iptables.py +72 -62
- pyinfra/facts/launchd.py +44 -0
- pyinfra/facts/lxd.py +17 -4
- pyinfra/facts/mysql.py +122 -86
- pyinfra/facts/npm.py +17 -9
- pyinfra/facts/openrc.py +71 -0
- pyinfra/facts/opkg.py +246 -0
- pyinfra/facts/pacman.py +50 -7
- pyinfra/facts/pip.py +24 -7
- pyinfra/facts/pipx.py +82 -0
- pyinfra/facts/pkg.py +15 -6
- pyinfra/facts/pkgin.py +35 -0
- pyinfra/facts/podman.py +54 -0
- pyinfra/facts/postgres.py +178 -0
- pyinfra/facts/postgresql.py +6 -147
- pyinfra/facts/rpm.py +105 -0
- pyinfra/facts/runit.py +77 -0
- pyinfra/facts/selinux.py +161 -0
- pyinfra/facts/server.py +746 -285
- pyinfra/facts/snap.py +88 -0
- pyinfra/facts/systemd.py +139 -0
- pyinfra/facts/sysvinit.py +59 -0
- pyinfra/facts/upstart.py +35 -0
- pyinfra/facts/util/__init__.py +17 -0
- pyinfra/facts/util/databases.py +4 -6
- pyinfra/facts/util/packaging.py +37 -6
- pyinfra/facts/util/units.py +30 -0
- pyinfra/facts/util/win_files.py +99 -0
- pyinfra/facts/vzctl.py +20 -13
- pyinfra/facts/xbps.py +35 -0
- pyinfra/facts/yum.py +34 -40
- pyinfra/facts/zfs.py +77 -0
- pyinfra/facts/zypper.py +42 -0
- pyinfra/local.py +45 -83
- pyinfra/operations/__init__.py +12 -0
- pyinfra/operations/apk.py +98 -0
- pyinfra/operations/apt.py +488 -0
- pyinfra/operations/brew.py +231 -0
- pyinfra/operations/bsdinit.py +59 -0
- pyinfra/operations/cargo.py +45 -0
- pyinfra/operations/choco.py +61 -0
- pyinfra/operations/crontab.py +191 -0
- pyinfra/operations/dnf.py +210 -0
- pyinfra/operations/docker.py +446 -0
- pyinfra/operations/files.py +1939 -0
- pyinfra/operations/flatpak.py +94 -0
- 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/gem.py +47 -0
- pyinfra/operations/git.py +419 -0
- pyinfra/operations/iptables.py +311 -0
- pyinfra/operations/launchd.py +45 -0
- pyinfra/operations/lxd.py +68 -0
- pyinfra/operations/mysql.py +609 -0
- pyinfra/operations/npm.py +57 -0
- pyinfra/operations/openrc.py +63 -0
- pyinfra/operations/opkg.py +88 -0
- pyinfra/operations/pacman.py +81 -0
- pyinfra/operations/pip.py +205 -0
- pyinfra/operations/pipx.py +102 -0
- pyinfra/operations/pkg.py +70 -0
- pyinfra/operations/pkgin.py +91 -0
- pyinfra/operations/postgres.py +436 -0
- pyinfra/operations/postgresql.py +30 -0
- pyinfra/operations/puppet.py +40 -0
- pyinfra/operations/python.py +72 -0
- pyinfra/operations/runit.py +184 -0
- pyinfra/operations/selinux.py +189 -0
- pyinfra/operations/server.py +1099 -0
- pyinfra/operations/snap.py +117 -0
- pyinfra/operations/ssh.py +216 -0
- pyinfra/operations/systemd.py +149 -0
- pyinfra/operations/sysvinit.py +141 -0
- pyinfra/operations/upstart.py +68 -0
- pyinfra/operations/util/__init__.py +12 -0
- pyinfra/operations/util/docker.py +251 -0
- pyinfra/operations/util/files.py +247 -0
- pyinfra/operations/util/packaging.py +336 -0
- pyinfra/operations/util/service.py +46 -0
- pyinfra/operations/vzctl.py +137 -0
- pyinfra/operations/xbps.py +77 -0
- pyinfra/operations/yum.py +210 -0
- pyinfra/operations/zfs.py +175 -0
- pyinfra/operations/zypper.py +192 -0
- pyinfra/progress.py +44 -32
- pyinfra/py.typed +0 -0
- pyinfra/version.py +9 -1
- pyinfra-3.5.1.dist-info/METADATA +141 -0
- pyinfra-3.5.1.dist-info/RECORD +159 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.5.1.dist-info}/WHEEL +1 -2
- pyinfra-3.5.1.dist-info/entry_points.txt +12 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.5.1.dist-info/licenses}/LICENSE.md +1 -1
- pyinfra_cli/__init__.py +1 -0
- pyinfra_cli/cli.py +780 -0
- pyinfra_cli/commands.py +66 -0
- pyinfra_cli/exceptions.py +155 -65
- pyinfra_cli/inventory.py +233 -89
- pyinfra_cli/log.py +39 -43
- pyinfra_cli/main.py +26 -495
- pyinfra_cli/prints.py +215 -156
- pyinfra_cli/util.py +172 -105
- pyinfra_cli/virtualenv.py +25 -20
- pyinfra/api/connectors/__init__.py +0 -21
- pyinfra/api/connectors/ansible.py +0 -99
- pyinfra/api/connectors/docker.py +0 -178
- pyinfra/api/connectors/local.py +0 -169
- pyinfra/api/connectors/ssh.py +0 -402
- pyinfra/api/connectors/sshuserclient/client.py +0 -105
- pyinfra/api/connectors/sshuserclient/config.py +0 -90
- pyinfra/api/connectors/util.py +0 -63
- pyinfra/api/connectors/vagrant.py +0 -155
- pyinfra/facts/init.py +0 -176
- pyinfra/facts/util/files.py +0 -102
- pyinfra/hook.py +0 -41
- pyinfra/modules/__init__.py +0 -11
- pyinfra/modules/apk.py +0 -64
- pyinfra/modules/apt.py +0 -272
- pyinfra/modules/brew.py +0 -122
- pyinfra/modules/files.py +0 -711
- pyinfra/modules/gem.py +0 -30
- pyinfra/modules/git.py +0 -115
- pyinfra/modules/init.py +0 -344
- pyinfra/modules/iptables.py +0 -271
- pyinfra/modules/lxd.py +0 -45
- pyinfra/modules/mysql.py +0 -347
- pyinfra/modules/npm.py +0 -47
- pyinfra/modules/pacman.py +0 -60
- pyinfra/modules/pip.py +0 -99
- pyinfra/modules/pkg.py +0 -43
- pyinfra/modules/postgresql.py +0 -245
- pyinfra/modules/puppet.py +0 -20
- pyinfra/modules/python.py +0 -37
- pyinfra/modules/server.py +0 -524
- pyinfra/modules/ssh.py +0 -150
- pyinfra/modules/util/files.py +0 -52
- pyinfra/modules/util/packaging.py +0 -118
- pyinfra/modules/vzctl.py +0 -133
- pyinfra/modules/yum.py +0 -171
- pyinfra/pseudo_modules.py +0 -64
- pyinfra-0.11.dev3.dist-info/.DS_Store +0 -0
- pyinfra-0.11.dev3.dist-info/METADATA +0 -135
- pyinfra-0.11.dev3.dist-info/RECORD +0 -95
- pyinfra-0.11.dev3.dist-info/entry_points.txt +0 -3
- pyinfra-0.11.dev3.dist-info/top_level.txt +0 -2
- pyinfra_cli/__main__.py +0 -40
- pyinfra_cli/config.py +0 -92
- /pyinfra/{modules/util → connectors}/__init__.py +0 -0
- /pyinfra/{api/connectors → connectors}/sshuserclient/__init__.py +0 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage yum packages and repositories. Note that yum package names are case-sensitive.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from pyinfra import host, state
|
|
8
|
+
from pyinfra.api import operation
|
|
9
|
+
from pyinfra.facts.rpm import RpmPackageProvides, RpmPackages
|
|
10
|
+
|
|
11
|
+
from .util.packaging import ensure_packages, ensure_rpm, ensure_yum_repo
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@operation(is_idempotent=False)
|
|
15
|
+
def key(src: str):
|
|
16
|
+
"""
|
|
17
|
+
Add yum gpg keys with ``rpm``.
|
|
18
|
+
|
|
19
|
+
+ src: filename or URL
|
|
20
|
+
|
|
21
|
+
Note:
|
|
22
|
+
always returns one command, not state checking
|
|
23
|
+
|
|
24
|
+
**Example:**
|
|
25
|
+
|
|
26
|
+
.. code:: python
|
|
27
|
+
|
|
28
|
+
linux_id = host.get_fact(LinuxDistribution)["release_meta"].get("ID")
|
|
29
|
+
yum.key(
|
|
30
|
+
name="Add the Docker CentOS gpg key",
|
|
31
|
+
src=f"https://download.docker.com/linux/{linux_id}/gpg",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
yield "rpm --import {0}".format(src)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@operation()
|
|
40
|
+
def repo(
|
|
41
|
+
src: str,
|
|
42
|
+
present=True,
|
|
43
|
+
baseurl: str | None = None,
|
|
44
|
+
description: str | None = None,
|
|
45
|
+
enabled=True,
|
|
46
|
+
gpgcheck=True,
|
|
47
|
+
gpgkey: str | None = None,
|
|
48
|
+
):
|
|
49
|
+
# NOTE: if updating this docstring also update `dnf.repo`
|
|
50
|
+
"""
|
|
51
|
+
Add/remove/update yum repositories.
|
|
52
|
+
|
|
53
|
+
+ src: URL or name for the ``.repo`` file
|
|
54
|
+
+ present: whether the ``.repo`` file should be present
|
|
55
|
+
+ baseurl: the baseurl of the repo (if ``src`` is not a URL)
|
|
56
|
+
+ description: optional verbose description
|
|
57
|
+
+ enabled: whether this repo is enabled
|
|
58
|
+
+ gpgcheck: whether set ``gpgcheck=1``
|
|
59
|
+
+ gpgkey: the URL to the gpg key for this repo
|
|
60
|
+
|
|
61
|
+
``Baseurl``/``description``/``gpgcheck``/``gpgkey``:
|
|
62
|
+
These are only valid when ``src`` is a filename (ie not a URL). This is
|
|
63
|
+
for manual construction of repository files. Use a URL to download and
|
|
64
|
+
install remote repository files.
|
|
65
|
+
|
|
66
|
+
**Examples:**
|
|
67
|
+
|
|
68
|
+
.. code:: python
|
|
69
|
+
|
|
70
|
+
# Download a repository file
|
|
71
|
+
yum.repo(
|
|
72
|
+
name="Install Docker-CE repo via URL",
|
|
73
|
+
src="https://download.docker.com/linux/centos/docker-ce.repo",
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Create the repository file from baseurl/etc
|
|
77
|
+
yum.repo(
|
|
78
|
+
name="Add the Docker CentOS repo",
|
|
79
|
+
src="DockerCE",
|
|
80
|
+
baseurl="https://download.docker.com/linux/centos/7/$basearch/stable",
|
|
81
|
+
)
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
yield from ensure_yum_repo(
|
|
85
|
+
host,
|
|
86
|
+
src,
|
|
87
|
+
baseurl,
|
|
88
|
+
present,
|
|
89
|
+
description,
|
|
90
|
+
enabled,
|
|
91
|
+
gpgcheck,
|
|
92
|
+
gpgkey,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@operation()
|
|
97
|
+
def rpm(src: str, present=True):
|
|
98
|
+
# NOTE: if updating this docstring also update `dnf.rpm`
|
|
99
|
+
"""
|
|
100
|
+
Add/remove ``.rpm`` file packages.
|
|
101
|
+
|
|
102
|
+
+ src: filename or URL of the ``.rpm`` package
|
|
103
|
+
+ present: whether ore not the package should exist on the system
|
|
104
|
+
|
|
105
|
+
URL sources with ``present=False``:
|
|
106
|
+
If the ``.rpm`` file isn't downloaded, pyinfra can't remove any existing
|
|
107
|
+
package as the file won't exist until mid-deploy.
|
|
108
|
+
|
|
109
|
+
**Example:**
|
|
110
|
+
|
|
111
|
+
.. code:: python
|
|
112
|
+
|
|
113
|
+
major_version = host.get_fact(LinuxDistribution)["major"]
|
|
114
|
+
dnf.rpm(
|
|
115
|
+
name="Install EPEL rpm to enable EPEL repo",
|
|
116
|
+
src=f"https://dl.fedoraproject.org/pub/epel/epel-release-latest-{major_version}.noarch.rpm",
|
|
117
|
+
)
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
yield from ensure_rpm(state, host, src, present, "yum")
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@operation(is_idempotent=False)
|
|
124
|
+
def update():
|
|
125
|
+
"""
|
|
126
|
+
Updates all yum packages.
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
yield "yum update -y"
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
_update = update._inner # noqa: E305 (for use below where update is a kwarg)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@operation()
|
|
136
|
+
def packages(
|
|
137
|
+
packages: str | list[str] | None = None,
|
|
138
|
+
present=True,
|
|
139
|
+
latest=False,
|
|
140
|
+
update=False,
|
|
141
|
+
clean=False,
|
|
142
|
+
nobest=False,
|
|
143
|
+
extra_install_args: str | None = None,
|
|
144
|
+
extra_uninstall_args: str | None = None,
|
|
145
|
+
):
|
|
146
|
+
"""
|
|
147
|
+
Install/remove/update yum packages & updates.
|
|
148
|
+
|
|
149
|
+
+ packages: list of packages to ensure
|
|
150
|
+
+ present: whether the packages should be installed
|
|
151
|
+
+ latest: whether to upgrade packages without a specified version
|
|
152
|
+
+ update: run ``yum update`` before installing packages
|
|
153
|
+
+ clean: run ``yum clean all`` before installing packages
|
|
154
|
+
+ nobest: add the no best option to install
|
|
155
|
+
+ extra_install_args: additional arguments to the yum install command
|
|
156
|
+
+ extra_uninstall_args: additional arguments to the yum uninstall command
|
|
157
|
+
|
|
158
|
+
Versions:
|
|
159
|
+
Package versions can be pinned as follows: ``<pkg>=<version>``
|
|
160
|
+
|
|
161
|
+
**Examples:**
|
|
162
|
+
|
|
163
|
+
.. code:: python
|
|
164
|
+
|
|
165
|
+
# Update package list and install packages
|
|
166
|
+
yum.packages(
|
|
167
|
+
name="Install Vim and Vim enhanced",
|
|
168
|
+
packages=["vim-enhanced", "vim"],
|
|
169
|
+
update=True,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
# Install the latest versions of packages (always check)
|
|
173
|
+
yum.packages(
|
|
174
|
+
name="Install latest Vim",
|
|
175
|
+
packages=["vim"],
|
|
176
|
+
latest=True,
|
|
177
|
+
)
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
if clean:
|
|
181
|
+
yield "yum clean all"
|
|
182
|
+
|
|
183
|
+
if update:
|
|
184
|
+
yield from _update()
|
|
185
|
+
|
|
186
|
+
install_command = ["yum", "install", "-y"]
|
|
187
|
+
|
|
188
|
+
if nobest:
|
|
189
|
+
install_command.append("--nobest")
|
|
190
|
+
|
|
191
|
+
if extra_install_args:
|
|
192
|
+
install_command.append(extra_install_args)
|
|
193
|
+
|
|
194
|
+
uninstall_command = ["yum", "remove", "-y"]
|
|
195
|
+
|
|
196
|
+
if extra_uninstall_args:
|
|
197
|
+
uninstall_command.append(extra_uninstall_args)
|
|
198
|
+
|
|
199
|
+
yield from ensure_packages(
|
|
200
|
+
host,
|
|
201
|
+
packages,
|
|
202
|
+
host.get_fact(RpmPackages),
|
|
203
|
+
present,
|
|
204
|
+
install_command=" ".join(install_command),
|
|
205
|
+
uninstall_command=" ".join(uninstall_command),
|
|
206
|
+
upgrade_command="yum update -y",
|
|
207
|
+
version_join="=",
|
|
208
|
+
latest=latest,
|
|
209
|
+
expand_package_fact=lambda package: host.get_fact(RpmPackageProvides, package=package),
|
|
210
|
+
)
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage ZFS filesystems.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from pyinfra import host
|
|
6
|
+
from pyinfra.api import operation
|
|
7
|
+
from pyinfra.facts.zfs import ZfsDatasets, ZfsSnapshots
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@operation()
|
|
11
|
+
def dataset(
|
|
12
|
+
dataset_name,
|
|
13
|
+
present=True,
|
|
14
|
+
recursive=False,
|
|
15
|
+
sparse=None,
|
|
16
|
+
volume_size=None,
|
|
17
|
+
properties={},
|
|
18
|
+
**extra_props,
|
|
19
|
+
):
|
|
20
|
+
"""
|
|
21
|
+
Create, destroy or set properties on a ZFS dataset (e.g. filesystem,
|
|
22
|
+
volume, snapshot).
|
|
23
|
+
|
|
24
|
+
+ dataset_name: name of the filesystem to operate on
|
|
25
|
+
+ present: whether the named filesystem should exist
|
|
26
|
+
+ recursive: whether to create parent datasets, or destroy child datasets
|
|
27
|
+
+ sparse: for volumes, whether to create a sparse volume with no allocation
|
|
28
|
+
+ volume_size: the size of the volume
|
|
29
|
+
+ properties: the ZFS properties that should be set on the dataset.
|
|
30
|
+
+ **extra_props: additional props; merged with `properties` for convenience
|
|
31
|
+
|
|
32
|
+
**Examples:**
|
|
33
|
+
|
|
34
|
+
.. code:: python
|
|
35
|
+
|
|
36
|
+
zfs.dataset(
|
|
37
|
+
"tank/srv",
|
|
38
|
+
mountpoint="/srv",
|
|
39
|
+
compression="lz4",
|
|
40
|
+
properties={"com.sun:auto_snapshot": "true"}
|
|
41
|
+
)
|
|
42
|
+
zfs.dataset("tank/vm-disks/db_srv_04", volume_size="32G") # creates a volume
|
|
43
|
+
zfs.dataset("tank/home@old_version", present=False)
|
|
44
|
+
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
noop_msg = "{0} is already {1}".format(dataset_name, "present" if present else "absent")
|
|
48
|
+
|
|
49
|
+
properties.update(extra_props)
|
|
50
|
+
|
|
51
|
+
datasets = host.get_fact(ZfsDatasets)
|
|
52
|
+
|
|
53
|
+
existing_dataset = datasets.get(dataset_name)
|
|
54
|
+
|
|
55
|
+
if present and not existing_dataset:
|
|
56
|
+
args = ["-o {0}={1}".format(prop, value) for prop, value in properties.items()]
|
|
57
|
+
if recursive:
|
|
58
|
+
args.append("-p")
|
|
59
|
+
if sparse:
|
|
60
|
+
args.append("-s")
|
|
61
|
+
if volume_size:
|
|
62
|
+
args.append("-V {0}".format(volume_size))
|
|
63
|
+
|
|
64
|
+
args.sort() # dicts are unordered, so make sure the test results are deterministic
|
|
65
|
+
|
|
66
|
+
yield "zfs create {0} {1}".format(" ".join(args), dataset_name)
|
|
67
|
+
|
|
68
|
+
elif present and existing_dataset:
|
|
69
|
+
prop_args = [
|
|
70
|
+
"{0}={1}".format(prop, value)
|
|
71
|
+
for prop, value in properties.items() - existing_dataset.items()
|
|
72
|
+
]
|
|
73
|
+
prop_args.sort()
|
|
74
|
+
if prop_args:
|
|
75
|
+
yield "zfs set {0} {1}".format(" ".join(prop_args), dataset_name)
|
|
76
|
+
else:
|
|
77
|
+
host.noop(noop_msg)
|
|
78
|
+
|
|
79
|
+
elif existing_dataset and not present:
|
|
80
|
+
recursive_arg = "-r" if recursive else ""
|
|
81
|
+
yield "zfs destroy {0} {1}".format(recursive_arg, dataset_name)
|
|
82
|
+
|
|
83
|
+
else:
|
|
84
|
+
host.noop(noop_msg)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@operation()
|
|
88
|
+
def snapshot(snapshot_name, present=True, recursive=False, properties={}, **extra_props):
|
|
89
|
+
"""
|
|
90
|
+
Create or destroy a ZFS snapshot, or modify its properties.
|
|
91
|
+
|
|
92
|
+
+ dataset_name: name of the filesystem to operate on
|
|
93
|
+
+ present: whether the named filesystem should exist
|
|
94
|
+
+ recursive: whether to snapshot child datasets
|
|
95
|
+
+ properties: the ZFS properties that should be set on the snapshot.
|
|
96
|
+
+ **extra_props: additional props; merged with `properties` for convenience
|
|
97
|
+
|
|
98
|
+
**Examples:**
|
|
99
|
+
|
|
100
|
+
.. code:: python
|
|
101
|
+
|
|
102
|
+
zfs.snapshot("tank/home@weekly_backup")
|
|
103
|
+
|
|
104
|
+
"""
|
|
105
|
+
properties.update(extra_props)
|
|
106
|
+
snapshots = host.get_fact(ZfsSnapshots)
|
|
107
|
+
|
|
108
|
+
if snapshot_name in snapshots or not present:
|
|
109
|
+
yield from dataset._inner(snapshot_name, present=present, properties=properties)
|
|
110
|
+
|
|
111
|
+
else:
|
|
112
|
+
args = ["-o {0}={1}".format(prop, value) for prop, value in properties.items()]
|
|
113
|
+
if recursive:
|
|
114
|
+
args.append("-r")
|
|
115
|
+
yield "zfs snap {0} {1}".format(" ".join(args), snapshot_name)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@operation()
|
|
119
|
+
def volume(
|
|
120
|
+
volume_name, size, sparse=False, present=True, recursive=False, properties={}, **extra_props
|
|
121
|
+
):
|
|
122
|
+
"""
|
|
123
|
+
Create or destroy a ZFS volume, or modify its properties.
|
|
124
|
+
|
|
125
|
+
+ volume_name: name of the volume to operate on
|
|
126
|
+
+ size: the size of the volume
|
|
127
|
+
+ sparse: create a sparse volume
|
|
128
|
+
+ present: whether the named volume should exist
|
|
129
|
+
+ recursive: whether to create parent datasets or destroy child datasets
|
|
130
|
+
+ properties: the ZFS properties that should be set on the snapshot.
|
|
131
|
+
+ **extra_props: additional props; merged with `properties` for convenience
|
|
132
|
+
|
|
133
|
+
**Examples:**
|
|
134
|
+
|
|
135
|
+
.. code:: python
|
|
136
|
+
|
|
137
|
+
zfs.volume("tank/vm-disks/db_srv_04", "32G")
|
|
138
|
+
|
|
139
|
+
"""
|
|
140
|
+
properties.update(extra_props)
|
|
141
|
+
yield from dataset._inner(
|
|
142
|
+
volume_name,
|
|
143
|
+
volume_size=size,
|
|
144
|
+
present=present,
|
|
145
|
+
sparse=sparse,
|
|
146
|
+
recursive=recursive,
|
|
147
|
+
properties=properties,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
@operation()
|
|
152
|
+
def filesystem(fs_name, present=True, recursive=False, properties={}, **extra_props):
|
|
153
|
+
"""
|
|
154
|
+
Create or destroy a ZFS filesystem, or modify its properties.
|
|
155
|
+
|
|
156
|
+
+ fs_name: name of the volume to operate on
|
|
157
|
+
+ present: whether the named volume should exist
|
|
158
|
+
+ recursive: whether to create parent datasets or destroy child datasets
|
|
159
|
+
+ properties: the ZFS properties that should be set on the snapshot.
|
|
160
|
+
+ **extra_props: additional props; merged with `properties` for convenience
|
|
161
|
+
|
|
162
|
+
**Examples:**
|
|
163
|
+
|
|
164
|
+
.. code:: python
|
|
165
|
+
|
|
166
|
+
zfs.filesystem("tank/vm-disks/db_srv_04", "32G")
|
|
167
|
+
|
|
168
|
+
"""
|
|
169
|
+
properties.update(extra_props)
|
|
170
|
+
yield from dataset._inner(
|
|
171
|
+
fs_name,
|
|
172
|
+
present=present,
|
|
173
|
+
recursive=recursive,
|
|
174
|
+
properties=properties,
|
|
175
|
+
)
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pyinfra import host, state
|
|
4
|
+
from pyinfra.api import operation
|
|
5
|
+
from pyinfra.facts.rpm import RpmPackages
|
|
6
|
+
|
|
7
|
+
from .util.packaging import ensure_packages, ensure_rpm, ensure_yum_repo
|
|
8
|
+
from .yum import key as yum_key
|
|
9
|
+
|
|
10
|
+
key = yum_key
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@operation()
|
|
14
|
+
def repo(
|
|
15
|
+
src,
|
|
16
|
+
baseurl=None,
|
|
17
|
+
present=True,
|
|
18
|
+
description=None,
|
|
19
|
+
enabled=True,
|
|
20
|
+
gpgcheck=True,
|
|
21
|
+
gpgkey=None,
|
|
22
|
+
type="rpm-md",
|
|
23
|
+
):
|
|
24
|
+
"""
|
|
25
|
+
Add/remove/update zypper repositories.
|
|
26
|
+
|
|
27
|
+
+ src: URL or name for the ``.repo`` file
|
|
28
|
+
+ baseurl: the baseurl of the repo (if ``name`` is not a URL)
|
|
29
|
+
+ present: whether the ``.repo`` file should be present
|
|
30
|
+
+ description: optional verbose description
|
|
31
|
+
+ enabled: whether this repo is enabled
|
|
32
|
+
+ gpgcheck: whether set ``gpgcheck=1``
|
|
33
|
+
+ gpgkey: the URL to the gpg key for this repo
|
|
34
|
+
+ type: the type field this repo (defaults to ``rpm-md``)
|
|
35
|
+
|
|
36
|
+
``Baseurl``/``description``/``gpgcheck``/``gpgkey``:
|
|
37
|
+
These are only valid when ``name`` is a filename (ie not a URL). This is
|
|
38
|
+
for manual construction of repository files. Use a URL to download and
|
|
39
|
+
install remote repository files.
|
|
40
|
+
|
|
41
|
+
**Examples:**
|
|
42
|
+
|
|
43
|
+
.. code:: python
|
|
44
|
+
|
|
45
|
+
# Download a repository file
|
|
46
|
+
zypper.repo(
|
|
47
|
+
name="Install container virtualization repo via URL",
|
|
48
|
+
src="https://download.opensuse.org/repositories/Virtualization:containers/openSUSE_Tumbleweed/Virtualization:containers.repo",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Create the repository file from baseurl/etc
|
|
52
|
+
zypper.repo(
|
|
53
|
+
name="Install container virtualization repo",
|
|
54
|
+
src=="Virtualization:containers (openSUSE_Tumbleweed)",
|
|
55
|
+
baseurl="https://download.opensuse.org/repositories/Virtualization:/containers/openSUSE_Tumbleweed/",
|
|
56
|
+
)
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
yield from ensure_yum_repo(
|
|
60
|
+
host,
|
|
61
|
+
src,
|
|
62
|
+
baseurl,
|
|
63
|
+
present,
|
|
64
|
+
description,
|
|
65
|
+
enabled,
|
|
66
|
+
gpgcheck,
|
|
67
|
+
gpgkey,
|
|
68
|
+
type_=type,
|
|
69
|
+
repo_directory="/etc/zypp/repos.d/",
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@operation()
|
|
74
|
+
def rpm(src, present=True):
|
|
75
|
+
# NOTE: if updating this docstring also update `dnf.rpm`
|
|
76
|
+
"""
|
|
77
|
+
Add/remove ``.rpm`` file packages.
|
|
78
|
+
|
|
79
|
+
+ src: filename or URL of the ``.rpm`` package
|
|
80
|
+
+ present: whether ore not the package should exist on the system
|
|
81
|
+
|
|
82
|
+
URL sources with ``present=False``:
|
|
83
|
+
If the ``.rpm`` file isn't downloaded, pyinfra can't remove any existing
|
|
84
|
+
package as the file won't exist until mid-deploy.
|
|
85
|
+
|
|
86
|
+
**Example:**
|
|
87
|
+
|
|
88
|
+
.. code:: python
|
|
89
|
+
|
|
90
|
+
zypper.rpm(
|
|
91
|
+
name="Install task from rpm",
|
|
92
|
+
src="https://github.com/go-task/task/releases/download/v2.8.1/task_linux_amd64.rpm",
|
|
93
|
+
)
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
yield from ensure_rpm(state, host, src, present, "zypper --non-interactive")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@operation(is_idempotent=False)
|
|
100
|
+
def update():
|
|
101
|
+
"""
|
|
102
|
+
Updates all zypper packages.
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
yield "zypper update -y"
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
_update = update._inner # noqa: E305 (for use below where update is a kwarg)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@operation()
|
|
112
|
+
def packages(
|
|
113
|
+
packages: str | list[str] | None = None,
|
|
114
|
+
present=True,
|
|
115
|
+
latest=False,
|
|
116
|
+
update=False,
|
|
117
|
+
clean=False,
|
|
118
|
+
extra_global_install_args: str | None = None,
|
|
119
|
+
extra_install_args: str | None = None,
|
|
120
|
+
extra_global_uninstall_args: str | None = None,
|
|
121
|
+
extra_uninstall_args: str | None = None,
|
|
122
|
+
):
|
|
123
|
+
"""
|
|
124
|
+
Install/remove/update zypper packages & updates.
|
|
125
|
+
|
|
126
|
+
+ packages: list of packages to ensure
|
|
127
|
+
+ present: whether the packages should be installed
|
|
128
|
+
+ latest: whether to upgrade packages without a specified version
|
|
129
|
+
+ update: run ``zypper update`` before installing packages
|
|
130
|
+
+ clean: run ``zypper clean --all`` before installing packages
|
|
131
|
+
+ extra_global_install_args: additional global arguments to the zypper install command
|
|
132
|
+
+ extra_install_args: additional arguments to the zypper install command
|
|
133
|
+
+ extra_global_uninstall_args: additional global arguments to the zypper uninstall command
|
|
134
|
+
+ extra_uninstall_args: additional arguments to the zypper uninstall command
|
|
135
|
+
|
|
136
|
+
Versions:
|
|
137
|
+
Package versions can be pinned like zypper: ``<pkg>=<version>``
|
|
138
|
+
|
|
139
|
+
**Examples:**
|
|
140
|
+
|
|
141
|
+
.. code:: python
|
|
142
|
+
|
|
143
|
+
# Update package list and install packages
|
|
144
|
+
zypper.packages(
|
|
145
|
+
name="Install Vim and Vim enhanced",
|
|
146
|
+
packages=["vim-enhanced", "vim"],
|
|
147
|
+
update=True,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# Install the latest versions of packages (always check)
|
|
151
|
+
zypper.packages(
|
|
152
|
+
name="Install latest Vim",
|
|
153
|
+
packages=["vim"],
|
|
154
|
+
latest=True,
|
|
155
|
+
)
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
if clean:
|
|
159
|
+
yield "zypper clean --all"
|
|
160
|
+
|
|
161
|
+
if update:
|
|
162
|
+
yield from _update()
|
|
163
|
+
|
|
164
|
+
install_command = ["zypper", "--non-interactive", "install", "-y"]
|
|
165
|
+
|
|
166
|
+
if extra_install_args:
|
|
167
|
+
install_command.append(extra_install_args)
|
|
168
|
+
|
|
169
|
+
if extra_global_install_args:
|
|
170
|
+
install_command.insert(1, extra_global_install_args)
|
|
171
|
+
|
|
172
|
+
uninstall_command = ["zypper", "--non-interactive", "remove", "-y"]
|
|
173
|
+
|
|
174
|
+
if extra_uninstall_args:
|
|
175
|
+
uninstall_command.append(extra_uninstall_args)
|
|
176
|
+
|
|
177
|
+
if extra_global_uninstall_args:
|
|
178
|
+
uninstall_command.insert(1, extra_global_uninstall_args)
|
|
179
|
+
|
|
180
|
+
upgrade_command = "zypper update -y"
|
|
181
|
+
|
|
182
|
+
yield from ensure_packages(
|
|
183
|
+
host,
|
|
184
|
+
packages,
|
|
185
|
+
host.get_fact(RpmPackages),
|
|
186
|
+
present,
|
|
187
|
+
install_command=" ".join(install_command),
|
|
188
|
+
uninstall_command=" ".join(uninstall_command),
|
|
189
|
+
upgrade_command=upgrade_command,
|
|
190
|
+
version_join="=",
|
|
191
|
+
latest=latest,
|
|
192
|
+
)
|