pyinfra 3.2__py2.py3-none-any.whl → 3.3.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. pyinfra/api/arguments_typed.py +4 -5
  2. pyinfra/api/command.py +22 -3
  3. pyinfra/api/config.py +5 -2
  4. pyinfra/api/facts.py +3 -0
  5. pyinfra/api/host.py +10 -4
  6. pyinfra/api/operation.py +2 -1
  7. pyinfra/api/state.py +1 -1
  8. pyinfra/connectors/base.py +34 -8
  9. pyinfra/connectors/chroot.py +7 -2
  10. pyinfra/connectors/docker.py +7 -2
  11. pyinfra/connectors/dockerssh.py +7 -2
  12. pyinfra/connectors/local.py +7 -2
  13. pyinfra/connectors/ssh.py +9 -2
  14. pyinfra/connectors/sshuserclient/client.py +18 -2
  15. pyinfra/connectors/sshuserclient/config.py +2 -0
  16. pyinfra/connectors/terraform.py +1 -1
  17. pyinfra/connectors/util.py +13 -9
  18. pyinfra/context.py +9 -2
  19. pyinfra/facts/apk.py +5 -0
  20. pyinfra/facts/apt.py +9 -1
  21. pyinfra/facts/brew.py +13 -0
  22. pyinfra/facts/bsdinit.py +3 -0
  23. pyinfra/facts/cargo.py +5 -0
  24. pyinfra/facts/choco.py +6 -0
  25. pyinfra/facts/crontab.py +6 -1
  26. pyinfra/facts/deb.py +10 -0
  27. pyinfra/facts/dnf.py +5 -0
  28. pyinfra/facts/docker.py +10 -0
  29. pyinfra/facts/efibootmgr.py +5 -0
  30. pyinfra/facts/files.py +19 -1
  31. pyinfra/facts/flatpak.py +7 -0
  32. pyinfra/facts/freebsd.py +75 -0
  33. pyinfra/facts/gem.py +5 -0
  34. pyinfra/facts/git.py +9 -0
  35. pyinfra/facts/gpg.py +7 -0
  36. pyinfra/facts/hardware.py +13 -0
  37. pyinfra/facts/iptables.py +9 -1
  38. pyinfra/facts/launchd.py +5 -0
  39. pyinfra/facts/lxd.py +5 -0
  40. pyinfra/facts/mysql.py +8 -0
  41. pyinfra/facts/npm.py +5 -0
  42. pyinfra/facts/openrc.py +8 -0
  43. pyinfra/facts/opkg.py +12 -0
  44. pyinfra/facts/pacman.py +9 -1
  45. pyinfra/facts/pip.py +5 -0
  46. pyinfra/facts/pipx.py +8 -0
  47. pyinfra/facts/pkg.py +4 -0
  48. pyinfra/facts/pkgin.py +5 -0
  49. pyinfra/facts/podman.py +7 -0
  50. pyinfra/facts/postgres.py +8 -2
  51. pyinfra/facts/rpm.py +11 -0
  52. pyinfra/facts/runit.py +7 -0
  53. pyinfra/facts/selinux.py +16 -0
  54. pyinfra/facts/server.py +49 -3
  55. pyinfra/facts/snap.py +7 -0
  56. pyinfra/facts/systemd.py +5 -0
  57. pyinfra/facts/sysvinit.py +4 -0
  58. pyinfra/facts/upstart.py +5 -0
  59. pyinfra/facts/util/__init__.py +4 -1
  60. pyinfra/facts/vzctl.py +5 -0
  61. pyinfra/facts/xbps.py +6 -1
  62. pyinfra/facts/yum.py +5 -0
  63. pyinfra/facts/zfs.py +19 -2
  64. pyinfra/facts/zypper.py +5 -0
  65. pyinfra/operations/apt.py +10 -3
  66. pyinfra/operations/docker.py +48 -44
  67. pyinfra/operations/files.py +47 -1
  68. pyinfra/operations/freebsd/__init__.py +12 -0
  69. pyinfra/operations/freebsd/freebsd_update.py +70 -0
  70. pyinfra/operations/freebsd/pkg.py +219 -0
  71. pyinfra/operations/freebsd/service.py +116 -0
  72. pyinfra/operations/freebsd/sysrc.py +92 -0
  73. pyinfra/operations/opkg.py +5 -5
  74. pyinfra/operations/postgres.py +99 -16
  75. pyinfra/operations/server.py +6 -4
  76. pyinfra/operations/util/docker.py +44 -22
  77. {pyinfra-3.2.dist-info → pyinfra-3.3.1.dist-info}/LICENSE.md +1 -1
  78. {pyinfra-3.2.dist-info → pyinfra-3.3.1.dist-info}/METADATA +25 -24
  79. {pyinfra-3.2.dist-info → pyinfra-3.3.1.dist-info}/RECORD +89 -83
  80. pyinfra_cli/exceptions.py +5 -0
  81. pyinfra_cli/log.py +3 -0
  82. pyinfra_cli/main.py +9 -8
  83. pyinfra_cli/prints.py +1 -1
  84. pyinfra_cli/virtualenv.py +1 -1
  85. tests/test_connectors/test_ssh.py +302 -182
  86. tests/test_connectors/test_sshuserclient.py +10 -5
  87. {pyinfra-3.2.dist-info → pyinfra-3.3.1.dist-info}/WHEEL +0 -0
  88. {pyinfra-3.2.dist-info → pyinfra-3.3.1.dist-info}/entry_points.txt +0 -0
  89. {pyinfra-3.2.dist-info → pyinfra-3.3.1.dist-info}/top_level.txt +0 -0
pyinfra/facts/files.py CHANGED
@@ -1,5 +1,9 @@
1
1
  """
2
2
  The files facts provide information about the filesystem and it's contents on the target host.
3
+
4
+ Facts need to be imported before use, eg
5
+
6
+ from pyinfra.facts.files import File
3
7
  """
4
8
 
5
9
  from __future__ import annotations
@@ -10,7 +14,7 @@ import stat
10
14
  from datetime import datetime
11
15
  from typing import TYPE_CHECKING, List, Optional, Tuple, Union
12
16
 
13
- from typing_extensions import Literal, NotRequired, TypedDict
17
+ from typing_extensions import Literal, NotRequired, TypedDict, override
14
18
 
15
19
  from pyinfra.api import StringCommand
16
20
  from pyinfra.api.command import QuoteString, make_formatted_string_command
@@ -111,6 +115,7 @@ class File(FactBase[Union[FileDict, Literal[False], None]]):
111
115
 
112
116
  type = "file"
113
117
 
118
+ @override
114
119
  def command(self, path):
115
120
  if path.startswith("~/"):
116
121
  # Do not quote leading tilde to ensure that it gets properly expanded by the shell
@@ -129,6 +134,7 @@ class File(FactBase[Union[FileDict, Literal[False], None]]):
129
134
  bsd_stat_command=BSD_STAT_COMMAND,
130
135
  )
131
136
 
137
+ @override
132
138
  def process(self, output) -> Union[FileDict, Literal[False], None]:
133
139
  match = re.match(STAT_REGEX, output[0])
134
140
  if not match:
@@ -233,6 +239,7 @@ class HashFileFactBase(FactBaseOptionalStr):
233
239
  _raw_cmd: str
234
240
  _regexes: Tuple[str, str]
235
241
 
242
+ @override
236
243
  def __init_subclass__(cls, digits: int, cmds: List[str], **kwargs) -> None:
237
244
  super().__init_subclass__(**kwargs)
238
245
 
@@ -249,10 +256,12 @@ class HashFileFactBase(FactBaseOptionalStr):
249
256
  r"^%s\s+\(%%s\)\s+=\s+([a-fA-F0-9]{%d})$" % (hash_name, digits),
250
257
  )
251
258
 
259
+ @override
252
260
  def command(self, path):
253
261
  self.path = path
254
262
  return make_formatted_string_command(self._raw_cmd, QuoteString(path))
255
263
 
264
+ @override
256
265
  def process(self, output) -> Optional[str]:
257
266
  output = output[0]
258
267
  escaped_path = re.escape(self.path)
@@ -294,6 +303,7 @@ class FindInFile(FactBase):
294
303
  lines if the file exists, and ``None`` if the file does not.
295
304
  """
296
305
 
306
+ @override
297
307
  def command(self, path, pattern, interpolate_variables=False):
298
308
  self.exists_flag = "__pyinfra_exists_{0}".format(path)
299
309
 
@@ -312,6 +322,7 @@ class FindInFile(FactBase):
312
322
  QuoteString(self.exists_flag),
313
323
  )
314
324
 
325
+ @override
315
326
  def process(self, output):
316
327
  # If output is the special string: no matches, so return an empty list;
317
328
  # this allows us to differentiate between no matches in an existing file
@@ -327,9 +338,11 @@ class FindFilesBase(FactBase):
327
338
  default = list
328
339
  type_flag: str
329
340
 
341
+ @override
330
342
  def process(self, output):
331
343
  return output
332
344
 
345
+ @override
333
346
  def command(
334
347
  self,
335
348
  path: str,
@@ -446,15 +459,18 @@ class Flags(FactBase):
446
459
  Returns a list of the file flags set for the specified file or directory.
447
460
  """
448
461
 
462
+ @override
449
463
  def requires_command(self, path) -> str:
450
464
  return "chflags" # don't try to retrieve them if we can't set them
451
465
 
466
+ @override
452
467
  def command(self, path):
453
468
  return make_formatted_string_command(
454
469
  "! test -e {0} || stat -f %Sf {0}",
455
470
  QuoteString(path),
456
471
  )
457
472
 
473
+ @override
458
474
  def process(self, output):
459
475
  return [flag for flag in output[0].split(",") if len(flag) > 0] if len(output) == 1 else []
460
476
 
@@ -490,6 +506,7 @@ class Block(FactBase):
490
506
  # the list with a single empty string.
491
507
  default = list
492
508
 
509
+ @override
493
510
  def command(self, path, marker=None, begin=None, end=None):
494
511
  self.path = path
495
512
  start = (marker or MARKER_DEFAULT).format(mark=begin or MARKER_BEGIN_DEFAULT)
@@ -510,6 +527,7 @@ class Block(FactBase):
510
527
  )
511
528
  return cmd
512
529
 
530
+ @override
513
531
  def process(self, output):
514
532
  if output and (output[0] == f"{EXISTS}{self.path}"):
515
533
  return []
pyinfra/facts/flatpak.py CHANGED
@@ -2,12 +2,15 @@ from __future__ import annotations
2
2
 
3
3
  import re
4
4
 
5
+ from typing_extensions import override
6
+
5
7
  from pyinfra.api import FactBase
6
8
 
7
9
 
8
10
  class FlatpakBaseFact(FactBase):
9
11
  abstract = True
10
12
 
13
+ @override
11
14
  def requires_command(self, *args, **kwargs) -> str:
12
15
  return "flatpak"
13
16
 
@@ -32,9 +35,11 @@ class FlatpakPackage(FlatpakBaseFact):
32
35
  "version": r"^[ ]+Version:[ ]+([\w\d.-]+).*$",
33
36
  }
34
37
 
38
+ @override
35
39
  def command(self, package):
36
40
  return f"flatpak info {package}"
37
41
 
42
+ @override
38
43
  def process(self, output):
39
44
  data = {}
40
45
  for line in output:
@@ -63,8 +68,10 @@ class FlatpakPackages(FlatpakBaseFact):
63
68
 
64
69
  default = list
65
70
 
71
+ @override
66
72
  def command(self):
67
73
  return "flatpak list --columns=application"
68
74
 
75
+ @override
69
76
  def process(self, output):
70
77
  return [flatpak for flatpak in output[1:]]
@@ -0,0 +1,75 @@
1
+ from __future__ import annotations
2
+
3
+ from typing_extensions import Optional, override
4
+
5
+ from pyinfra.api import FactBase
6
+ from pyinfra.api.command import QuoteString, StringCommand, make_formatted_string_command
7
+
8
+
9
+ class ServiceScript(FactBase):
10
+ @override
11
+ def command(self, srvname: str, jail: Optional[str] = None) -> StringCommand:
12
+ if jail is None:
13
+ jail = ""
14
+
15
+ return make_formatted_string_command(
16
+ (
17
+ "for service in `service -j {0} -l`; do "
18
+ 'if [ {1} = \\"$service\\" ]; '
19
+ 'then echo \\"$service\\"; '
20
+ "fi; "
21
+ "done"
22
+ ),
23
+ QuoteString(jail),
24
+ QuoteString(srvname),
25
+ )
26
+
27
+
28
+ class ServiceStatus(FactBase):
29
+ @override
30
+ def command(self, srvname: str, jail: Optional[str] = None) -> StringCommand:
31
+ if jail is None:
32
+ jail = ""
33
+
34
+ return make_formatted_string_command(
35
+ (
36
+ "service -j {0} {1} status > /dev/null 2>&1; "
37
+ "if [ $? -eq 0 ]; then "
38
+ "echo running; "
39
+ "fi"
40
+ ),
41
+ QuoteString(jail),
42
+ QuoteString(srvname),
43
+ )
44
+
45
+
46
+ class Sysrc(FactBase):
47
+ @override
48
+ def command(self, parameter: str, jail: Optional[str] = None) -> StringCommand:
49
+ if jail is None:
50
+ command = make_formatted_string_command(
51
+ ("sysrc -in -- {0} || true"), QuoteString(parameter)
52
+ )
53
+ else:
54
+ command = make_formatted_string_command(
55
+ ("sysrc -j {0} -in -- {1} || true"), QuoteString(jail), QuoteString(parameter)
56
+ )
57
+
58
+ return command
59
+
60
+
61
+ class PkgPackage(FactBase):
62
+ @override
63
+ def command(self, package: str, jail: Optional[str] = None) -> StringCommand:
64
+ if jail is None:
65
+ command = make_formatted_string_command(
66
+ ("pkg info -E -- {0} 2> /dev/null || true"), QuoteString(package)
67
+ )
68
+ else:
69
+ command = make_formatted_string_command(
70
+ ("pkg -j {0} info -E -- {1} 2> /dev/null || true"),
71
+ QuoteString(jail),
72
+ QuoteString(package),
73
+ )
74
+
75
+ return command
pyinfra/facts/gem.py CHANGED
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from typing_extensions import override
4
+
3
5
  from pyinfra.api import FactBase
4
6
 
5
7
  from .util.packaging import parse_packages
@@ -18,13 +20,16 @@ class GemPackages(FactBase):
18
20
  }
19
21
  """
20
22
 
23
+ @override
21
24
  def command(self) -> str:
22
25
  return "gem list --local"
23
26
 
27
+ @override
24
28
  def requires_command(self) -> str:
25
29
  return "gem"
26
30
 
27
31
  default = dict
28
32
 
33
+ @override
29
34
  def process(self, output):
30
35
  return parse_packages(GEM_REGEX, output)
pyinfra/facts/git.py CHANGED
@@ -2,18 +2,23 @@ from __future__ import annotations
2
2
 
3
3
  import re
4
4
 
5
+ from typing_extensions import override
6
+
5
7
  from pyinfra.api.facts import FactBase
6
8
 
7
9
 
8
10
  class GitFactBase(FactBase):
11
+ @override
9
12
  def requires_command(self, *args, **kwargs) -> str:
10
13
  return "git"
11
14
 
12
15
 
13
16
  class GitBranch(GitFactBase):
17
+ @override
14
18
  def command(self, repo) -> str:
15
19
  return "! test -d {0} || (cd {0} && git describe --all)".format(repo)
16
20
 
21
+ @override
17
22
  def process(self, output):
18
23
  return re.sub(r"(heads|tags)/", r"", "\n".join(output))
19
24
 
@@ -21,6 +26,7 @@ class GitBranch(GitFactBase):
21
26
  class GitConfig(GitFactBase):
22
27
  default = dict
23
28
 
29
+ @override
24
30
  def command(self, repo=None, system=False) -> str:
25
31
  if repo is None:
26
32
  level = "--system" if system else "--global"
@@ -28,6 +34,7 @@ class GitConfig(GitFactBase):
28
34
 
29
35
  return "! test -d {0} || (cd {0} && git config --local -l)".format(repo)
30
36
 
37
+ @override
31
38
  def process(self, output):
32
39
  items: dict[str, list[str]] = {}
33
40
 
@@ -39,9 +46,11 @@ class GitConfig(GitFactBase):
39
46
 
40
47
 
41
48
  class GitTrackingBranch(GitFactBase):
49
+ @override
42
50
  def command(self, repo) -> str:
43
51
  return r"! test -d {0} || (cd {0} && git status --branch --porcelain)".format(repo)
44
52
 
53
+ @override
45
54
  def process(self, output):
46
55
  if not output:
47
56
  return None
pyinfra/facts/gpg.py CHANGED
@@ -2,18 +2,22 @@ from __future__ import annotations
2
2
 
3
3
  from urllib.parse import urlparse
4
4
 
5
+ from typing_extensions import override
6
+
5
7
  from pyinfra.api import FactBase
6
8
 
7
9
 
8
10
  class GpgFactBase(FactBase):
9
11
  abstract = True
10
12
 
13
+ @override
11
14
  def requires_command(self, *args, **kwargs) -> str:
12
15
  return "gpg"
13
16
 
14
17
  key_record_type = "pub"
15
18
  subkey_record_type = "sub"
16
19
 
20
+ @override
17
21
  def process(self, output):
18
22
  # For details on the field values see:
19
23
  # https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS
@@ -88,6 +92,7 @@ class GpgKey(GpgFactBase):
88
92
  }
89
93
  """
90
94
 
95
+ @override
91
96
  def command(self, src):
92
97
  if urlparse(src).scheme:
93
98
  return ("(wget -O - {0} || curl -sSLf {0}) | gpg --with-colons").format(src)
@@ -109,6 +114,7 @@ class GpgKeys(GpgFactBase):
109
114
  }
110
115
  """
111
116
 
117
+ @override
112
118
  def command(self, keyring=None):
113
119
  if not keyring:
114
120
  return "gpg --list-keys --with-colons"
@@ -134,6 +140,7 @@ class GpgSecretKeys(GpgFactBase):
134
140
  key_record_type = "sec"
135
141
  subkey_record_type = "ssb"
136
142
 
143
+ @override
137
144
  def command(self, keyring=None):
138
145
  if not keyring:
139
146
  return "gpg --list-secret-keys --with-colons"
pyinfra/facts/hardware.py CHANGED
@@ -2,6 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  import re
4
4
 
5
+ from typing_extensions import override
6
+
5
7
  from pyinfra.api import FactBase, ShortFactBase
6
8
 
7
9
 
@@ -10,9 +12,11 @@ class Cpus(FactBase[int]):
10
12
  Returns the number of CPUs on this server.
11
13
  """
12
14
 
15
+ @override
13
16
  def command(self) -> str:
14
17
  return "getconf NPROCESSORS_ONLN 2> /dev/null || getconf _NPROCESSORS_ONLN"
15
18
 
19
+ @override
16
20
  def process(self, output):
17
21
  try:
18
22
  return int(list(output)[0])
@@ -25,12 +29,15 @@ class Memory(FactBase):
25
29
  Returns the memory installed in this server, in MB.
26
30
  """
27
31
 
32
+ @override
28
33
  def requires_command(self) -> str:
29
34
  return "vmstat"
30
35
 
36
+ @override
31
37
  def command(self) -> str:
32
38
  return "vmstat -s"
33
39
 
40
+ @override
34
41
  def process(self, output):
35
42
  data = {}
36
43
 
@@ -80,9 +87,11 @@ class BlockDevices(FactBase):
80
87
  regex = r"([a-zA-Z0-9\/\-_]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]{1,3})%\s+([a-zA-Z\/0-9\-_]+)" # noqa: E501
81
88
  default = dict
82
89
 
90
+ @override
83
91
  def command(self) -> str:
84
92
  return "df"
85
93
 
94
+ @override
86
95
  def process(self, output):
87
96
  devices = {}
88
97
 
@@ -177,11 +186,13 @@ class NetworkDevices(FactBase):
177
186
 
178
187
  default = dict
179
188
 
189
+ @override
180
190
  def command(self) -> str:
181
191
  return "ip addr show 2> /dev/null || ifconfig -a"
182
192
 
183
193
  # Definition of valid interface names for Linux:
184
194
  # https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/net/core/dev.c?h=v5.1.3#n1020
195
+ @override
185
196
  def process(self, output):
186
197
  def mask(value):
187
198
  try:
@@ -318,6 +329,7 @@ class Ipv4Addrs(ShortFactBase):
318
329
  fact = NetworkDevices
319
330
  ip_type = "ipv4"
320
331
 
332
+ @override
321
333
  def process_data(self, data):
322
334
  host_to_ips = {}
323
335
 
@@ -379,6 +391,7 @@ class Ipv4Addresses(ShortFactBase):
379
391
  fact = NetworkDevices
380
392
  ip_type = "ipv4"
381
393
 
394
+ @override
382
395
  def process_data(self, data):
383
396
  addresses = {}
384
397
 
pyinfra/facts/iptables.py CHANGED
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from typing_extensions import override
4
+
3
5
  from pyinfra.api import FactBase
4
6
 
5
7
  # Mapping for iptables code arguments to variable names
@@ -35,7 +37,7 @@ def parse_iptables_rule(line):
35
37
  args: list[str] = []
36
38
  not_arg = False
37
39
 
38
- def add_args():
40
+ def add_args() -> None:
39
41
  arg_string = " ".join(args)
40
42
 
41
43
  if key and key in IPTABLES_ARGS:
@@ -89,9 +91,11 @@ class IptablesRules(FactBase):
89
91
 
90
92
  default = list
91
93
 
94
+ @override
92
95
  def command(self, table="filter"):
93
96
  return "iptables-save -t {0}".format(table)
94
97
 
98
+ @override
95
99
  def process(self, output):
96
100
  rules = []
97
101
 
@@ -116,6 +120,7 @@ class Ip6tablesRules(IptablesRules):
116
120
  ]
117
121
  """
118
122
 
123
+ @override
119
124
  def command(self, table="filter"):
120
125
  return "ip6tables-save -t {0}".format(table)
121
126
 
@@ -133,9 +138,11 @@ class IptablesChains(FactBase):
133
138
 
134
139
  default = dict
135
140
 
141
+ @override
136
142
  def command(self, table="filter"):
137
143
  return "iptables-save -t {0}".format(table)
138
144
 
145
+ @override
139
146
  def process(self, output):
140
147
  chains = {}
141
148
 
@@ -160,5 +167,6 @@ class Ip6tablesChains(IptablesChains):
160
167
  }
161
168
  """
162
169
 
170
+ @override
163
171
  def command(self, table="filter"):
164
172
  return "ip6tables-save -t {0}".format(table)
pyinfra/facts/launchd.py CHANGED
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from typing_extensions import override
4
+
3
5
  from pyinfra.api import FactBase
4
6
 
5
7
 
@@ -8,14 +10,17 @@ class LaunchdStatus(FactBase):
8
10
  Returns a dict of name -> status for launchd managed services.
9
11
  """
10
12
 
13
+ @override
11
14
  def command(self) -> str:
12
15
  return "launchctl list"
13
16
 
17
+ @override
14
18
  def requires_command(self) -> str:
15
19
  return "launchctl"
16
20
 
17
21
  default = dict
18
22
 
23
+ @override
19
24
  def process(self, output):
20
25
  services = {}
21
26
 
pyinfra/facts/lxd.py CHANGED
@@ -2,6 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
 
5
+ from typing_extensions import override
6
+
5
7
  from pyinfra.api import FactBase
6
8
 
7
9
 
@@ -10,14 +12,17 @@ class LxdContainers(FactBase):
10
12
  Returns a list of running LXD containers
11
13
  """
12
14
 
15
+ @override
13
16
  def command(self) -> str:
14
17
  return "lxc list --format json --fast"
15
18
 
19
+ @override
16
20
  def requires_command(self) -> str:
17
21
  return "lxc"
18
22
 
19
23
  default = list
20
24
 
25
+ @override
21
26
  def process(self, output):
22
27
  output = list(output)
23
28
  assert len(output) == 1
pyinfra/facts/mysql.py CHANGED
@@ -3,6 +3,8 @@ from __future__ import annotations
3
3
  import re
4
4
  from collections import defaultdict
5
5
 
6
+ from typing_extensions import override
7
+
6
8
  from pyinfra.api import FactBase, MaskString, QuoteString, StringCommand
7
9
  from pyinfra.api.util import try_int
8
10
 
@@ -62,9 +64,11 @@ class MysqlFactBase(FactBase):
62
64
  mysql_command: str
63
65
  ignore_errors = False
64
66
 
67
+ @override
65
68
  def requires_command(self, *args, **kwargs) -> str:
66
69
  return "mysql"
67
70
 
71
+ @override
68
72
  def command(
69
73
  self,
70
74
  # Details for speaking to MySQL via `mysql` CLI via `mysql` CLI
@@ -100,6 +104,7 @@ class MysqlDatabases(MysqlFactBase):
100
104
  default = dict
101
105
  mysql_command = "SELECT * FROM information_schema.SCHEMATA"
102
106
 
107
+ @override
103
108
  def process(self, output):
104
109
  rows = parse_columns_and_rows(
105
110
  output,
@@ -136,6 +141,7 @@ class MysqlUsers(MysqlFactBase):
136
141
  default = dict
137
142
  mysql_command = "SELECT * FROM mysql.user"
138
143
 
144
+ @override
139
145
  def process(self, output):
140
146
  rows = parse_columns_and_rows(output, "\t")
141
147
 
@@ -195,6 +201,7 @@ class MysqlUserGrants(MysqlFactBase):
195
201
  # Ignore errors as SHOW GRANTS will error if the user does not exist
196
202
  ignore_errors = True
197
203
 
204
+ @override
198
205
  def command( # type: ignore[override]
199
206
  self,
200
207
  user,
@@ -214,6 +221,7 @@ class MysqlUserGrants(MysqlFactBase):
214
221
  mysql_port,
215
222
  )
216
223
 
224
+ @override
217
225
  def process(self, output):
218
226
  database_table_privileges = defaultdict(set)
219
227
 
pyinfra/facts/npm.py CHANGED
@@ -1,6 +1,8 @@
1
1
  # encoding: utf8
2
2
  from __future__ import annotations
3
3
 
4
+ from typing_extensions import override
5
+
4
6
  from pyinfra.api import FactBase
5
7
 
6
8
  from .util.packaging import parse_packages
@@ -21,13 +23,16 @@ class NpmPackages(FactBase):
21
23
 
22
24
  default = dict
23
25
 
26
+ @override
24
27
  def requires_command(self, directory=None) -> str:
25
28
  return "npm"
26
29
 
30
+ @override
27
31
  def command(self, directory=None):
28
32
  if directory:
29
33
  return ("cd {0} && npm list -g --depth=0").format(directory)
30
34
  return "npm list -g --depth=0"
31
35
 
36
+ @override
32
37
  def process(self, output):
33
38
  return parse_packages(NPM_REGEX, output)
pyinfra/facts/openrc.py CHANGED
@@ -2,6 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  import re
4
4
 
5
+ from typing_extensions import override
6
+
5
7
  from pyinfra.api import FactBase
6
8
 
7
9
 
@@ -20,12 +22,15 @@ class OpenrcStatus(FactBase):
20
22
  r"\s+\]"
21
23
  )
22
24
 
25
+ @override
23
26
  def requires_command(self, runlevel="default") -> str:
24
27
  return "rc-status"
25
28
 
29
+ @override
26
30
  def command(self, runlevel="default"):
27
31
  return "rc-status {0}".format(runlevel)
28
32
 
33
+ @override
29
34
  def process(self, output):
30
35
  services = {}
31
36
 
@@ -44,13 +49,16 @@ class OpenrcEnabled(FactBase):
44
49
 
45
50
  default = dict
46
51
 
52
+ @override
47
53
  def requires_command(self, runlevel="default") -> str:
48
54
  return "rc-update"
49
55
 
56
+ @override
50
57
  def command(self, runlevel="default"):
51
58
  self.runlevel = runlevel
52
59
  return "rc-update show -v"
53
60
 
61
+ @override
54
62
  def process(self, output):
55
63
  services = {}
56
64