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