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,95 @@
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
+ from pyinfra.operations import flatpak
30
+ # Install vlc flatpak
31
+ flatpak.package(
32
+ name="Install vlc",
33
+ packages="org.videolan.VLC",
34
+ )
35
+
36
+ # Install vlc flatpak from flathub
37
+ flatpak.package(
38
+ name="Install vlc",
39
+ packages="org.videolan.VLC",
40
+ remote="flathub",
41
+ )
42
+
43
+ # Install multiple flatpaks
44
+ flatpak.package(
45
+ name="Install vlc and kodi",
46
+ packages=["org.videolan.VLC", "tv.kodi.Kodi"],
47
+ )
48
+
49
+ # Remove vlc
50
+ flatpak.package(
51
+ name="Remove vlc",
52
+ packages="org.videolan.VLC",
53
+ present=False,
54
+ )
55
+ """
56
+
57
+ if packages is None:
58
+ return
59
+
60
+ if isinstance(packages, str):
61
+ packages = [packages]
62
+
63
+ flatpak_packages = host.get_fact(FlatpakPackages)
64
+
65
+ install_packages = []
66
+ remove_packages = []
67
+
68
+ if remote is None:
69
+ remote = ""
70
+ else:
71
+ # ensure we have a space between the remote and packages
72
+ remote = remote.strip() + " "
73
+
74
+ for package in packages:
75
+ # it's installed
76
+ if package in flatpak_packages:
77
+ if not present:
78
+ # we don't want it
79
+ remove_packages.append(package)
80
+
81
+ # it's not installed
82
+ if package not in flatpak_packages:
83
+ # we want it
84
+ if present:
85
+ install_packages.append(package)
86
+
87
+ # we don't want it
88
+ else:
89
+ host.noop(f"flatpak package {package} is not installed")
90
+
91
+ if install_packages:
92
+ yield f"flatpak install --noninteractive {remote}{' '.join(install_packages)}"
93
+
94
+ if remove_packages:
95
+ 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,48 @@
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
+ from pyinfra.operations import gem
31
+ # Note: Assumes that 'gem' is installed.
32
+ gem.packages(
33
+ name="Install rspec",
34
+ packages=["rspec"],
35
+ )
36
+ """
37
+
38
+ yield from ensure_packages(
39
+ host,
40
+ packages,
41
+ host.get_fact(GemPackages),
42
+ present,
43
+ install_command="gem install",
44
+ uninstall_command="gem uninstall",
45
+ upgrade_command="gem update",
46
+ version_join=":",
47
+ latest=latest,
48
+ )