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.
Files changed (203) hide show
  1. pyinfra/__init__.py +9 -12
  2. pyinfra/__main__.py +4 -0
  3. pyinfra/api/__init__.py +18 -3
  4. pyinfra/api/arguments.py +406 -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 +67 -18
  12. pyinfra/api/facts.py +253 -202
  13. pyinfra/api/host.py +413 -50
  14. pyinfra/api/inventory.py +121 -160
  15. pyinfra/api/operation.py +432 -262
  16. pyinfra/api/operations.py +273 -260
  17. pyinfra/api/state.py +302 -248
  18. pyinfra/api/util.py +291 -368
  19. pyinfra/connectors/base.py +173 -0
  20. pyinfra/connectors/chroot.py +212 -0
  21. pyinfra/connectors/docker.py +381 -0
  22. pyinfra/connectors/dockerssh.py +297 -0
  23. pyinfra/connectors/local.py +238 -0
  24. pyinfra/connectors/scp/__init__.py +1 -0
  25. pyinfra/connectors/scp/client.py +204 -0
  26. pyinfra/connectors/ssh.py +670 -0
  27. pyinfra/connectors/ssh_util.py +114 -0
  28. pyinfra/connectors/sshuserclient/client.py +309 -0
  29. pyinfra/connectors/sshuserclient/config.py +102 -0
  30. pyinfra/connectors/terraform.py +135 -0
  31. pyinfra/connectors/util.py +410 -0
  32. pyinfra/connectors/vagrant.py +183 -0
  33. pyinfra/context.py +145 -0
  34. pyinfra/facts/__init__.py +7 -6
  35. pyinfra/facts/apk.py +22 -7
  36. pyinfra/facts/apt.py +117 -60
  37. pyinfra/facts/brew.py +100 -15
  38. pyinfra/facts/bsdinit.py +23 -0
  39. pyinfra/facts/cargo.py +37 -0
  40. pyinfra/facts/choco.py +47 -0
  41. pyinfra/facts/crontab.py +195 -0
  42. pyinfra/facts/deb.py +94 -0
  43. pyinfra/facts/dnf.py +48 -0
  44. pyinfra/facts/docker.py +96 -23
  45. pyinfra/facts/efibootmgr.py +113 -0
  46. pyinfra/facts/files.py +630 -58
  47. pyinfra/facts/flatpak.py +77 -0
  48. pyinfra/facts/freebsd.py +70 -0
  49. pyinfra/facts/gem.py +19 -6
  50. pyinfra/facts/git.py +59 -14
  51. pyinfra/facts/gpg.py +150 -0
  52. pyinfra/facts/hardware.py +313 -167
  53. pyinfra/facts/iptables.py +72 -62
  54. pyinfra/facts/launchd.py +44 -0
  55. pyinfra/facts/lxd.py +17 -4
  56. pyinfra/facts/mysql.py +122 -86
  57. pyinfra/facts/npm.py +17 -9
  58. pyinfra/facts/openrc.py +71 -0
  59. pyinfra/facts/opkg.py +246 -0
  60. pyinfra/facts/pacman.py +50 -7
  61. pyinfra/facts/pip.py +24 -7
  62. pyinfra/facts/pipx.py +82 -0
  63. pyinfra/facts/pkg.py +15 -6
  64. pyinfra/facts/pkgin.py +35 -0
  65. pyinfra/facts/podman.py +54 -0
  66. pyinfra/facts/postgres.py +178 -0
  67. pyinfra/facts/postgresql.py +6 -147
  68. pyinfra/facts/rpm.py +105 -0
  69. pyinfra/facts/runit.py +77 -0
  70. pyinfra/facts/selinux.py +161 -0
  71. pyinfra/facts/server.py +746 -285
  72. pyinfra/facts/snap.py +88 -0
  73. pyinfra/facts/systemd.py +139 -0
  74. pyinfra/facts/sysvinit.py +59 -0
  75. pyinfra/facts/upstart.py +35 -0
  76. pyinfra/facts/util/__init__.py +17 -0
  77. pyinfra/facts/util/databases.py +4 -6
  78. pyinfra/facts/util/packaging.py +37 -6
  79. pyinfra/facts/util/units.py +30 -0
  80. pyinfra/facts/util/win_files.py +99 -0
  81. pyinfra/facts/vzctl.py +20 -13
  82. pyinfra/facts/xbps.py +35 -0
  83. pyinfra/facts/yum.py +34 -40
  84. pyinfra/facts/zfs.py +77 -0
  85. pyinfra/facts/zypper.py +42 -0
  86. pyinfra/local.py +45 -83
  87. pyinfra/operations/__init__.py +12 -0
  88. pyinfra/operations/apk.py +98 -0
  89. pyinfra/operations/apt.py +488 -0
  90. pyinfra/operations/brew.py +231 -0
  91. pyinfra/operations/bsdinit.py +59 -0
  92. pyinfra/operations/cargo.py +45 -0
  93. pyinfra/operations/choco.py +61 -0
  94. pyinfra/operations/crontab.py +191 -0
  95. pyinfra/operations/dnf.py +210 -0
  96. pyinfra/operations/docker.py +446 -0
  97. pyinfra/operations/files.py +1939 -0
  98. pyinfra/operations/flatpak.py +94 -0
  99. pyinfra/operations/freebsd/__init__.py +12 -0
  100. pyinfra/operations/freebsd/freebsd_update.py +70 -0
  101. pyinfra/operations/freebsd/pkg.py +219 -0
  102. pyinfra/operations/freebsd/service.py +116 -0
  103. pyinfra/operations/freebsd/sysrc.py +92 -0
  104. pyinfra/operations/gem.py +47 -0
  105. pyinfra/operations/git.py +419 -0
  106. pyinfra/operations/iptables.py +311 -0
  107. pyinfra/operations/launchd.py +45 -0
  108. pyinfra/operations/lxd.py +68 -0
  109. pyinfra/operations/mysql.py +609 -0
  110. pyinfra/operations/npm.py +57 -0
  111. pyinfra/operations/openrc.py +63 -0
  112. pyinfra/operations/opkg.py +88 -0
  113. pyinfra/operations/pacman.py +81 -0
  114. pyinfra/operations/pip.py +205 -0
  115. pyinfra/operations/pipx.py +102 -0
  116. pyinfra/operations/pkg.py +70 -0
  117. pyinfra/operations/pkgin.py +91 -0
  118. pyinfra/operations/postgres.py +436 -0
  119. pyinfra/operations/postgresql.py +30 -0
  120. pyinfra/operations/puppet.py +40 -0
  121. pyinfra/operations/python.py +72 -0
  122. pyinfra/operations/runit.py +184 -0
  123. pyinfra/operations/selinux.py +189 -0
  124. pyinfra/operations/server.py +1099 -0
  125. pyinfra/operations/snap.py +117 -0
  126. pyinfra/operations/ssh.py +216 -0
  127. pyinfra/operations/systemd.py +149 -0
  128. pyinfra/operations/sysvinit.py +141 -0
  129. pyinfra/operations/upstart.py +68 -0
  130. pyinfra/operations/util/__init__.py +12 -0
  131. pyinfra/operations/util/docker.py +251 -0
  132. pyinfra/operations/util/files.py +247 -0
  133. pyinfra/operations/util/packaging.py +336 -0
  134. pyinfra/operations/util/service.py +46 -0
  135. pyinfra/operations/vzctl.py +137 -0
  136. pyinfra/operations/xbps.py +77 -0
  137. pyinfra/operations/yum.py +210 -0
  138. pyinfra/operations/zfs.py +175 -0
  139. pyinfra/operations/zypper.py +192 -0
  140. pyinfra/progress.py +44 -32
  141. pyinfra/py.typed +0 -0
  142. pyinfra/version.py +9 -1
  143. pyinfra-3.5.1.dist-info/METADATA +141 -0
  144. pyinfra-3.5.1.dist-info/RECORD +159 -0
  145. {pyinfra-0.11.dev3.dist-info → pyinfra-3.5.1.dist-info}/WHEEL +1 -2
  146. pyinfra-3.5.1.dist-info/entry_points.txt +12 -0
  147. {pyinfra-0.11.dev3.dist-info → pyinfra-3.5.1.dist-info/licenses}/LICENSE.md +1 -1
  148. pyinfra_cli/__init__.py +1 -0
  149. pyinfra_cli/cli.py +780 -0
  150. pyinfra_cli/commands.py +66 -0
  151. pyinfra_cli/exceptions.py +155 -65
  152. pyinfra_cli/inventory.py +233 -89
  153. pyinfra_cli/log.py +39 -43
  154. pyinfra_cli/main.py +26 -495
  155. pyinfra_cli/prints.py +215 -156
  156. pyinfra_cli/util.py +172 -105
  157. pyinfra_cli/virtualenv.py +25 -20
  158. pyinfra/api/connectors/__init__.py +0 -21
  159. pyinfra/api/connectors/ansible.py +0 -99
  160. pyinfra/api/connectors/docker.py +0 -178
  161. pyinfra/api/connectors/local.py +0 -169
  162. pyinfra/api/connectors/ssh.py +0 -402
  163. pyinfra/api/connectors/sshuserclient/client.py +0 -105
  164. pyinfra/api/connectors/sshuserclient/config.py +0 -90
  165. pyinfra/api/connectors/util.py +0 -63
  166. pyinfra/api/connectors/vagrant.py +0 -155
  167. pyinfra/facts/init.py +0 -176
  168. pyinfra/facts/util/files.py +0 -102
  169. pyinfra/hook.py +0 -41
  170. pyinfra/modules/__init__.py +0 -11
  171. pyinfra/modules/apk.py +0 -64
  172. pyinfra/modules/apt.py +0 -272
  173. pyinfra/modules/brew.py +0 -122
  174. pyinfra/modules/files.py +0 -711
  175. pyinfra/modules/gem.py +0 -30
  176. pyinfra/modules/git.py +0 -115
  177. pyinfra/modules/init.py +0 -344
  178. pyinfra/modules/iptables.py +0 -271
  179. pyinfra/modules/lxd.py +0 -45
  180. pyinfra/modules/mysql.py +0 -347
  181. pyinfra/modules/npm.py +0 -47
  182. pyinfra/modules/pacman.py +0 -60
  183. pyinfra/modules/pip.py +0 -99
  184. pyinfra/modules/pkg.py +0 -43
  185. pyinfra/modules/postgresql.py +0 -245
  186. pyinfra/modules/puppet.py +0 -20
  187. pyinfra/modules/python.py +0 -37
  188. pyinfra/modules/server.py +0 -524
  189. pyinfra/modules/ssh.py +0 -150
  190. pyinfra/modules/util/files.py +0 -52
  191. pyinfra/modules/util/packaging.py +0 -118
  192. pyinfra/modules/vzctl.py +0 -133
  193. pyinfra/modules/yum.py +0 -171
  194. pyinfra/pseudo_modules.py +0 -64
  195. pyinfra-0.11.dev3.dist-info/.DS_Store +0 -0
  196. pyinfra-0.11.dev3.dist-info/METADATA +0 -135
  197. pyinfra-0.11.dev3.dist-info/RECORD +0 -95
  198. pyinfra-0.11.dev3.dist-info/entry_points.txt +0 -3
  199. pyinfra-0.11.dev3.dist-info/top_level.txt +0 -2
  200. pyinfra_cli/__main__.py +0 -40
  201. pyinfra_cli/config.py +0 -92
  202. /pyinfra/{modules/util → connectors}/__init__.py +0 -0
  203. /pyinfra/{api/connectors → connectors}/sshuserclient/__init__.py +0 -0
@@ -0,0 +1,94 @@
1
+ """
2
+ Manage flatpak packages. See https://www.flatpak.org/
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from pyinfra import host
8
+ from pyinfra.api import operation
9
+ from pyinfra.facts.flatpak import FlatpakPackages
10
+
11
+
12
+ @operation()
13
+ def packages(
14
+ packages: str | list[str] | None = None,
15
+ remote: str | None = None,
16
+ present=True,
17
+ ):
18
+ """
19
+ Install/remove a flatpak package
20
+
21
+ + packages: List of packages
22
+ + remote: Source to install the application or runtime from
23
+ + present: whether the package should be installed
24
+
25
+ **Examples:**
26
+
27
+ .. code:: python
28
+
29
+ # Install vlc flatpak
30
+ flatpak.package(
31
+ name="Install vlc",
32
+ packages="org.videolan.VLC",
33
+ )
34
+
35
+ # Install vlc flatpak from flathub
36
+ flatpak.package(
37
+ name="Install vlc",
38
+ packages="org.videolan.VLC",
39
+ remote="flathub",
40
+ )
41
+
42
+ # Install multiple flatpaks
43
+ flatpak.package(
44
+ name="Install vlc and kodi",
45
+ packages=["org.videolan.VLC", "tv.kodi.Kodi"],
46
+ )
47
+
48
+ # Remove vlc
49
+ flatpak.package(
50
+ name="Remove vlc",
51
+ packages="org.videolan.VLC",
52
+ present=False,
53
+ )
54
+ """
55
+
56
+ if packages is None:
57
+ return
58
+
59
+ if isinstance(packages, str):
60
+ packages = [packages]
61
+
62
+ flatpak_packages = host.get_fact(FlatpakPackages)
63
+
64
+ install_packages = []
65
+ remove_packages = []
66
+
67
+ if remote is None:
68
+ remote = ""
69
+ else:
70
+ # ensure we have a space between the remote and packages
71
+ remote = remote.strip() + " "
72
+
73
+ for package in packages:
74
+ # it's installed
75
+ if package in flatpak_packages:
76
+ if not present:
77
+ # we don't want it
78
+ remove_packages.append(package)
79
+
80
+ # it's not installed
81
+ if package not in flatpak_packages:
82
+ # we want it
83
+ if present:
84
+ install_packages.append(package)
85
+
86
+ # we don't want it
87
+ else:
88
+ host.noop(f"flatpak package {package} is not installed")
89
+
90
+ if install_packages:
91
+ yield f"flatpak install --noninteractive {remote}{' '.join(install_packages)}"
92
+
93
+ if remove_packages:
94
+ yield f"flatpak uninstall --noninteractive {' '.join(remove_packages)}"
@@ -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)
@@ -0,0 +1,47 @@
1
+ """
2
+ Manage Ruby gem packages. (see https://rubygems.org/ )
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from pyinfra import host
8
+ from pyinfra.api import operation
9
+ from pyinfra.facts.gem import GemPackages
10
+
11
+ from .util.packaging import ensure_packages
12
+
13
+
14
+ @operation()
15
+ def packages(packages: str | list[str] | None = None, present=True, latest=False):
16
+ """
17
+ Add/remove/update gem packages.
18
+
19
+ + packages: list of packages to ensure
20
+ + present: whether the packages should be installed
21
+ + latest: whether to upgrade packages without a specified version
22
+
23
+ Versions:
24
+ Package versions can be pinned like gem: ``<pkg>:<version>``.
25
+
26
+ **Example:**
27
+
28
+ .. code:: python
29
+
30
+ # Note: Assumes that 'gem' is installed.
31
+ gem.packages(
32
+ name="Install rspec",
33
+ packages=["rspec"],
34
+ )
35
+ """
36
+
37
+ yield from ensure_packages(
38
+ host,
39
+ packages,
40
+ host.get_fact(GemPackages),
41
+ present,
42
+ install_command="gem install",
43
+ uninstall_command="gem uninstall",
44
+ upgrade_command="gem update",
45
+ version_join=":",
46
+ latest=latest,
47
+ )