meerschaum 2.3.0.dev3__py3-none-any.whl → 2.3.0rc2__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 (55) hide show
  1. meerschaum/__init__.py +3 -2
  2. meerschaum/__main__.py +0 -5
  3. meerschaum/_internal/arguments/__init__.py +1 -1
  4. meerschaum/_internal/arguments/_parse_arguments.py +56 -2
  5. meerschaum/_internal/arguments/_parser.py +6 -2
  6. meerschaum/_internal/entry.py +94 -23
  7. meerschaum/_internal/shell/Shell.py +112 -35
  8. meerschaum/actions/attach.py +12 -7
  9. meerschaum/actions/copy.py +68 -41
  10. meerschaum/actions/delete.py +75 -26
  11. meerschaum/actions/edit.py +3 -3
  12. meerschaum/actions/install.py +40 -32
  13. meerschaum/actions/pause.py +44 -27
  14. meerschaum/actions/restart.py +107 -0
  15. meerschaum/actions/show.py +8 -8
  16. meerschaum/actions/start.py +27 -46
  17. meerschaum/actions/stop.py +11 -4
  18. meerschaum/api/_events.py +10 -3
  19. meerschaum/api/dash/jobs.py +69 -70
  20. meerschaum/api/routes/_actions.py +8 -3
  21. meerschaum/api/routes/_jobs.py +37 -19
  22. meerschaum/config/_default.py +1 -1
  23. meerschaum/config/_paths.py +5 -0
  24. meerschaum/config/_version.py +1 -1
  25. meerschaum/config/static/__init__.py +5 -0
  26. meerschaum/connectors/Connector.py +13 -7
  27. meerschaum/connectors/__init__.py +21 -5
  28. meerschaum/connectors/api/APIConnector.py +3 -0
  29. meerschaum/connectors/api/_jobs.py +30 -3
  30. meerschaum/connectors/parse.py +10 -14
  31. meerschaum/core/Pipe/_bootstrap.py +16 -8
  32. meerschaum/jobs/_Executor.py +69 -0
  33. meerschaum/{utils/jobs → jobs}/_Job.py +169 -21
  34. meerschaum/jobs/_LocalExecutor.py +88 -0
  35. meerschaum/jobs/_SystemdExecutor.py +613 -0
  36. meerschaum/jobs/__init__.py +388 -0
  37. meerschaum/plugins/__init__.py +6 -6
  38. meerschaum/utils/daemon/Daemon.py +7 -0
  39. meerschaum/utils/daemon/RotatingFile.py +5 -2
  40. meerschaum/utils/daemon/StdinFile.py +12 -2
  41. meerschaum/utils/daemon/__init__.py +2 -0
  42. meerschaum/utils/formatting/_jobs.py +49 -25
  43. meerschaum/utils/misc.py +23 -5
  44. meerschaum/utils/packages/_packages.py +7 -4
  45. meerschaum/utils/process.py +9 -9
  46. meerschaum/utils/venv/__init__.py +2 -2
  47. {meerschaum-2.3.0.dev3.dist-info → meerschaum-2.3.0rc2.dist-info}/METADATA +14 -17
  48. {meerschaum-2.3.0.dev3.dist-info → meerschaum-2.3.0rc2.dist-info}/RECORD +54 -50
  49. meerschaum/utils/jobs/__init__.py +0 -245
  50. {meerschaum-2.3.0.dev3.dist-info → meerschaum-2.3.0rc2.dist-info}/LICENSE +0 -0
  51. {meerschaum-2.3.0.dev3.dist-info → meerschaum-2.3.0rc2.dist-info}/NOTICE +0 -0
  52. {meerschaum-2.3.0.dev3.dist-info → meerschaum-2.3.0rc2.dist-info}/WHEEL +0 -0
  53. {meerschaum-2.3.0.dev3.dist-info → meerschaum-2.3.0rc2.dist-info}/entry_points.txt +0 -0
  54. {meerschaum-2.3.0.dev3.dist-info → meerschaum-2.3.0rc2.dist-info}/top_level.txt +0 -0
  55. {meerschaum-2.3.0.dev3.dist-info → meerschaum-2.3.0rc2.dist-info}/zip-safe +0 -0
@@ -10,9 +10,9 @@ from __future__ import annotations
10
10
  from meerschaum.utils.typing import Union, Any, Sequence, SuccessTuple, Optional, Tuple, List
11
11
 
12
12
  def copy(
13
- action: Optional[List[str]] = None,
14
- **kw : Any
15
- ) -> SuccessTuple:
13
+ action: Optional[List[str]] = None,
14
+ **kw : Any
15
+ ) -> SuccessTuple:
16
16
  """
17
17
  Duplicate connectors or pipes.
18
18
 
@@ -32,17 +32,16 @@ def copy(
32
32
 
33
33
 
34
34
  def _complete_copy(
35
- action : Optional[List[str]] = None,
36
- **kw : Any
37
- ) -> List[str]:
35
+ action: Optional[List[str]] = None,
36
+ **kw: Any
37
+ ) -> List[str]:
38
38
  """
39
39
  Override the default Meerschaum `complete_` function.
40
-
41
40
  """
42
- from meerschaum.actions.start import _complete_start_jobs
43
41
  from meerschaum.actions.edit import _complete_edit_config
44
42
  if action is None:
45
43
  action = []
44
+
46
45
  options = {
47
46
  'connector': _complete_copy_connectors,
48
47
  'connectors': _complete_copy_connectors,
@@ -61,15 +60,14 @@ def _complete_copy(
61
60
 
62
61
 
63
62
  def _copy_pipes(
64
- yes: bool = False,
65
- noask: bool = False,
66
- force: bool = False,
67
- debug: bool = False,
68
- **kw
69
- ) -> SuccessTuple:
63
+ yes: bool = False,
64
+ noask: bool = False,
65
+ force: bool = False,
66
+ debug: bool = False,
67
+ **kw
68
+ ) -> SuccessTuple:
70
69
  """
71
70
  Copy pipes' attributes and make new pipes.
72
-
73
71
  """
74
72
  from meerschaum import get_pipes, Pipe
75
73
  from meerschaum.utils.prompt import prompt, yes_no
@@ -132,16 +130,15 @@ def _copy_pipes(
132
130
 
133
131
  return successes > 0, msg
134
132
 
133
+
135
134
  def _copy_connectors(
136
- action: Optional[List[str]] = None,
137
- connector_keys: Optional[List[str]] = None,
138
- nopretty: bool = False,
139
- yes: bool = False,
140
- force: bool = False,
141
- noask: bool = False,
142
- debug: bool = False,
143
- **kw
144
- ) -> SuccessTuple:
135
+ action: Optional[List[str]] = None,
136
+ connector_keys: Optional[List[str]] = None,
137
+ nopretty: bool = False,
138
+ force: bool = False,
139
+ debug: bool = False,
140
+ **kwargs: Any
141
+ ) -> SuccessTuple:
145
142
  """
146
143
  Create a new connector from an existing one.
147
144
 
@@ -153,39 +150,69 @@ def _copy_connectors(
153
150
  from meerschaum.config._edit import write_config
154
151
  from meerschaum.utils.warnings import info, warn
155
152
  from meerschaum.utils.formatting import pprint
153
+ from meerschaum.actions import get_action
156
154
  cf = _config()
157
155
  if action is None:
158
156
  action = []
159
157
  if connector_keys is None:
160
158
  connector_keys = []
161
159
 
162
- _keys = list(set(action + connector_keys))
160
+ _keys = (action or []) + connector_keys
163
161
 
164
162
  if not _keys:
165
163
  return False, "No connectors to copy."
166
164
 
167
- for ck in _keys:
168
- try:
169
- conn = parse_connector_keys(ck)
170
- except Exception as e:
171
- warn(f"Unable to parse connector '{ck}'. Skipping...", stack=False)
172
- continue
165
+ if len(_keys) < 1 or len(_keys) > 2:
166
+ return False, "Provide one set of connector keys."
173
167
 
174
- attrs = get_config('meerschaum', 'connectors', conn.type, conn.label)
175
- pprint(attrs, nopretty=nopretty)
168
+ ck = _keys[0]
176
169
 
177
- asking = True
178
- # while asking:
179
- # new_ck = prompt("Please enter a new label for the new connector ():")
170
+ try:
171
+ conn = parse_connector_keys(ck)
172
+ except Exception as e:
173
+ return False, f"Unable to parse connector '{ck}'."
180
174
 
175
+ if len(_keys) == 2:
176
+ new_ck = _keys[1] if ':' in _keys[1] else None
177
+ new_label = _keys[1].split(':')[-1]
178
+ else:
179
+ new_ck = None
180
+ new_label = None
181
+
182
+ try:
183
+ if new_label is None:
184
+ new_label = prompt(f"Enter a label for the new '{conn.type}' connector:")
185
+ except KeyboardInterrupt:
186
+ return False, "Nothing was copied."
187
+
188
+ if new_ck is None:
189
+ new_ck = f"{conn.type}:{new_label}"
190
+
191
+ info(f"Registering connector '{new_ck}' from '{ck}'...")
192
+
193
+ attrs = get_config('meerschaum', 'connectors', conn.type, conn.label)
194
+ pprint(attrs, nopretty=nopretty)
195
+ if not force and not yes_no(
196
+ f"Register connector '{new_ck}' with the above attributes?",
197
+ default='n',
198
+ **kwargs
199
+ ):
200
+ return False, "Nothing was copied."
201
+
202
+ register_connector = get_action(['register', 'connector'])
203
+ register_success, register_msg = register_connector(
204
+ [new_ck],
205
+ params=attrs,
206
+ **kwargs
207
+ )
208
+ return register_success, register_msg
181
209
 
182
- return False, "Not implemented."
183
210
 
184
211
  def _complete_copy_connectors(
185
- action : Optional[List[str]] = None,
186
- line : str = '',
187
- **kw : Any
188
- ) -> List[str]:
212
+ action: Optional[List[str]] = None,
213
+ line: str = '',
214
+ **kw: Any
215
+ ) -> List[str]:
189
216
  from meerschaum.config import get_config
190
217
  from meerschaum.utils.misc import get_connector_labels
191
218
  types = list(get_config('meerschaum', 'connectors').keys())
@@ -10,9 +10,9 @@ from __future__ import annotations
10
10
  from meerschaum.utils.typing import Any, SuccessTuple, Union, Optional, List
11
11
 
12
12
  def delete(
13
- action: Optional[List[str]] = None,
14
- **kw: Any
15
- ) -> SuccessTuple:
13
+ action: Optional[List[str]] = None,
14
+ **kw: Any
15
+ ) -> SuccessTuple:
16
16
  """
17
17
  Delete an element.
18
18
 
@@ -35,23 +35,21 @@ def delete(
35
35
 
36
36
 
37
37
  def _complete_delete(
38
- action: Optional[List[str]] = None,
39
- **kw: Any
40
- ) -> List[str]:
38
+ action: Optional[List[str]] = None,
39
+ **kw: Any
40
+ ) -> List[str]:
41
41
  """
42
42
  Override the default Meerschaum `complete_` function.
43
-
44
43
  """
45
- from meerschaum.actions.start import _complete_start_jobs
46
44
  from meerschaum.actions.edit import _complete_edit_config
47
45
  if action is None:
48
46
  action = []
49
47
  options = {
50
48
  'connector': _complete_delete_connectors,
51
49
  'connectors': _complete_delete_connectors,
52
- 'config' : _complete_edit_config,
53
- 'job' : _complete_start_jobs,
54
- 'jobs' : _complete_start_jobs,
50
+ 'config': _complete_edit_config,
51
+ 'job': _complete_delete_jobs,
52
+ 'jobs': _complete_delete_jobs,
55
53
  }
56
54
 
57
55
  if (
@@ -390,22 +388,22 @@ def _complete_delete_connectors(
390
388
 
391
389
 
392
390
  def _delete_jobs(
393
- action: Optional[List[str]] = None,
394
- executor_keys: Optional[str] = None,
395
- noask: bool = False,
396
- nopretty: bool = False,
397
- force: bool = False,
398
- yes: bool = False,
399
- debug: bool = False,
400
- **kw
401
- ) -> SuccessTuple:
391
+ action: Optional[List[str]] = None,
392
+ executor_keys: Optional[str] = None,
393
+ noask: bool = False,
394
+ nopretty: bool = False,
395
+ force: bool = False,
396
+ yes: bool = False,
397
+ debug: bool = False,
398
+ **kw
399
+ ) -> SuccessTuple:
402
400
  """
403
401
  Remove a job's log files and delete the job's ID.
404
402
 
405
403
  If the job is running, ask to kill the job first.
406
404
 
407
405
  """
408
- from meerschaum.utils.jobs import (
406
+ from meerschaum.jobs import (
409
407
  Job,
410
408
  get_running_jobs,
411
409
  get_stopped_jobs,
@@ -496,12 +494,63 @@ def _delete_jobs(
496
494
  )
497
495
 
498
496
 
497
+ def _complete_delete_jobs(
498
+ action: Optional[List[str]] = None,
499
+ executor_keys: Optional[str] = None,
500
+ line: str = '',
501
+ _get_job_method: Optional[str, List[str]] = None,
502
+ **kw
503
+ ) -> List[str]:
504
+ from meerschaum._internal.shell.Shell import shell_attrs
505
+ from meerschaum.jobs import (
506
+ get_jobs,
507
+ get_filtered_jobs,
508
+ get_restart_jobs,
509
+ get_stopped_jobs,
510
+ get_paused_jobs,
511
+ get_running_jobs,
512
+ get_executor_keys_from_context,
513
+ )
514
+ from meerschaum.utils.misc import remove_ansi
515
+
516
+ executor_keys = (
517
+ executor_keys
518
+ or remove_ansi(
519
+ shell_attrs.get('executor_keys', get_executor_keys_from_context())
520
+ )
521
+ )
522
+
523
+ jobs = get_jobs(executor_keys, include_hidden=False)
524
+ if _get_job_method:
525
+ method_keys = [_get_job_method] if isinstance(_get_job_method, str) else _get_job_method
526
+ method_jobs = {}
527
+ for method_key in method_keys:
528
+ method_func = locals()[f'get_{method_key}_jobs']
529
+ method_jobs.update(method_func(jobs=jobs))
530
+ jobs = method_jobs
531
+
532
+ if not action:
533
+ return list(jobs)
534
+
535
+ possibilities = []
536
+ _line_end = line.split(' ')[-1]
537
+ for name in jobs:
538
+ if name in action:
539
+ continue
540
+ if _line_end == '':
541
+ possibilities.append(name)
542
+ continue
543
+ if name.startswith(action[-1]):
544
+ possibilities.append(name)
545
+ return possibilities
546
+
547
+
499
548
  def _delete_venvs(
500
- action: Optional[List[str]] = None,
501
- yes: bool = False,
502
- force: bool = False,
503
- **kwargs: Any
504
- ) -> SuccessTuple:
549
+ action: Optional[List[str]] = None,
550
+ yes: bool = False,
551
+ force: bool = False,
552
+ **kwargs: Any
553
+ ) -> SuccessTuple:
505
554
  """
506
555
  Remove virtual environments.
507
556
  Specify which venvs to remove, or remove everything at once.
@@ -11,9 +11,9 @@ import meerschaum as mrsm
11
11
  from meerschaum.utils.typing import List, Any, SuccessTuple, Optional, Dict
12
12
 
13
13
  def edit(
14
- action: Optional[List[str]] = None,
15
- **kw: Any
16
- ) -> SuccessTuple:
14
+ action: Optional[List[str]] = None,
15
+ **kw: Any
16
+ ) -> SuccessTuple:
17
17
  """
18
18
  Edit an existing element.
19
19
  """
@@ -10,9 +10,9 @@ from __future__ import annotations
10
10
  from meerschaum.utils.typing import List, Any, SuccessTuple, Optional, Union
11
11
 
12
12
  def install(
13
- action: Optional[List[str]] = None,
14
- **kw: Any
15
- ) -> SuccessTuple:
13
+ action: Optional[List[str]] = None,
14
+ **kw: Any
15
+ ) -> SuccessTuple:
16
16
  """
17
17
  Install Meerschaum plugins or Python packages.
18
18
  """
@@ -26,9 +26,9 @@ def install(
26
26
 
27
27
 
28
28
  def _complete_install(
29
- action: Optional[List[str]] = None,
30
- **kw: Any
31
- ) -> List[str]:
29
+ action: Optional[List[str]] = None,
30
+ **kw: Any
31
+ ) -> List[str]:
32
32
  """
33
33
  Override the default Meerschaum `complete_` function.
34
34
  """
@@ -52,13 +52,13 @@ def _complete_install(
52
52
 
53
53
 
54
54
  def _install_plugins(
55
- action: Optional[List[str]] = None,
56
- repository: Optional[str] = None,
57
- skip_deps: bool = False,
58
- force: bool = False,
59
- debug: bool = False,
60
- **kw: Any
61
- ) -> SuccessTuple:
55
+ action: Optional[List[str]] = None,
56
+ repository: Optional[str] = None,
57
+ skip_deps: bool = False,
58
+ force: bool = False,
59
+ debug: bool = False,
60
+ **kw: Any
61
+ ) -> SuccessTuple:
62
62
  """
63
63
  Install a plugin.
64
64
 
@@ -103,10 +103,10 @@ def _install_plugins(
103
103
 
104
104
 
105
105
  def _complete_install_plugins(
106
- action: Optional[List[str]] = None,
107
- repository: Optional[str] = None,
108
- **kw: Any
109
- ) -> List[str]:
106
+ action: Optional[List[str]] = None,
107
+ repository: Optional[str] = None,
108
+ **kw: Any
109
+ ) -> List[str]:
110
110
  """
111
111
  Search for plugins to autocomplete command line text.
112
112
  NOTE: Disabled for the time being so we don't interrupt the user typing.
@@ -143,12 +143,12 @@ class NoVenv:
143
143
  pass
144
144
 
145
145
  def _install_packages(
146
- action: Optional[List[str]] = None,
147
- sub_args: Optional[List[str]] = None,
148
- venv: Union[str, NoVenv] = NoVenv,
149
- debug: bool = False,
150
- **kw: Any
151
- ) -> SuccessTuple:
146
+ action: Optional[List[str]] = None,
147
+ sub_args: Optional[List[str]] = None,
148
+ venv: Union[str, NoVenv] = NoVenv,
149
+ debug: bool = False,
150
+ **kw: Any
151
+ ) -> SuccessTuple:
152
152
  """
153
153
  Install PyPI packages into the Meerschaum virtual environment.
154
154
 
@@ -179,19 +179,17 @@ def _install_packages(
179
179
  )
180
180
 
181
181
 
182
- def _complete_install_packages(
183
- **kw : Any
184
- ) -> List[str]:
182
+ def _complete_install_packages(**kw : Any) -> List[str]:
185
183
  return []
186
184
 
187
185
 
188
186
  def _install_required(
189
- action: Optional[List[str]] = None,
190
- repository: Optional[str] = None,
191
- force: bool = False,
192
- debug: bool = False,
193
- **kw
194
- ) -> SuccessTuple:
187
+ action: Optional[List[str]] = None,
188
+ repository: Optional[str] = None,
189
+ force: bool = False,
190
+ debug: bool = False,
191
+ **kw
192
+ ) -> SuccessTuple:
195
193
  """
196
194
  Install the required packages for Meerschaum plugins.
197
195
  Each plugin's packages will be installed into its virtual environment.
@@ -237,6 +235,16 @@ def _complete_install_required(*args, **kw) -> List[str]:
237
235
  return _complete_uninstall_plugins(*args, **kw)
238
236
 
239
237
 
238
+ def _install_systemd(
239
+ action: Optional[List[str]] = None,
240
+ **kwargs: Any
241
+ ) -> SuccessTuple:
242
+ """
243
+ Install the Meerschaum job monitor as a systemd service.
244
+ """
245
+ import sys
246
+
247
+
240
248
  ### NOTE: This must be the final statement of the module.
241
249
  ### Any subactions added below these lines will not
242
250
  ### be added to the `help` docstring.
@@ -27,13 +27,20 @@ def _complete_pause(
27
27
  """
28
28
  Override the default Meerschaum `complete_` function.
29
29
  """
30
- from meerschaum.actions.start import _complete_start_jobs
30
+ from meerschaum.actions.delete import _complete_delete_jobs
31
+ from functools import partial
32
+
31
33
  if action is None:
32
34
  action = []
33
35
 
36
+ _complete_pause_jobs = partial(
37
+ _complete_delete_jobs,
38
+ _get_job_method='running',
39
+ )
40
+
34
41
  options = {
35
- 'job' : _complete_start_jobs,
36
- 'jobs' : _complete_start_jobs,
42
+ 'job': _complete_pause_jobs,
43
+ 'jobs': _complete_pause_jobs,
37
44
  }
38
45
 
39
46
  if (
@@ -49,43 +56,53 @@ def _complete_pause(
49
56
 
50
57
 
51
58
  def _pause_jobs(
52
- action: Optional[List[str]] = None,
53
- noask: bool = False,
54
- force: bool = False,
55
- yes: bool = False,
56
- nopretty: bool = False,
57
- **kw
58
- ) -> SuccessTuple:
59
+ action: Optional[List[str]] = None,
60
+ executor_keys: Optional[str] = None,
61
+ noask: bool = False,
62
+ force: bool = False,
63
+ yes: bool = False,
64
+ nopretty: bool = False,
65
+ debug: bool = False,
66
+ **kw
67
+ ) -> SuccessTuple:
59
68
  """
60
- Pause running jobs that were started with `-d` or `start job`.
61
-
62
- To see running jobs, run `show jobs`.
69
+ Pause (suspend) running jobs.
63
70
  """
64
71
  from meerschaum.utils.formatting._jobs import pprint_jobs
65
72
  from meerschaum.utils.daemon import (
66
73
  get_filtered_daemons, get_running_daemons, get_stopped_daemons, get_paused_daemons,
67
74
  )
75
+ from meerschaum.jobs import (
76
+ get_filtered_jobs,
77
+ get_running_jobs,
78
+ get_stopped_jobs,
79
+ get_paused_jobs,
80
+ )
68
81
  from meerschaum.utils.warnings import warn
69
82
  from meerschaum.utils.prompt import yes_no
70
83
  from meerschaum.utils.misc import items_str
71
- daemons = get_filtered_daemons(action, warn=(not nopretty))
72
- _running_daemons = get_running_daemons(daemons)
73
- _paused_daemons = get_paused_daemons(daemons)
74
- _stopped_daemons = get_stopped_daemons(daemons)
75
- if action and _stopped_daemons and not nopretty:
84
+
85
+ jobs = get_filtered_jobs(executor_keys, action, debug=debug, warn=(not nopretty))
86
+ running_jobs = get_running_jobs(executor_keys, jobs, debug=debug)
87
+ paused_jobs = get_paused_jobs(executor_keys, jobs, debug=debug)
88
+ stopped_jobs = get_stopped_jobs(executor_keys, jobs, debug=debug)
89
+
90
+ if action and stopped_jobs and not nopretty:
76
91
  warn(
77
- f"Skipping stopped job" + ("s" if len(_stopped_daemons) > 1 else '') + " '" +
78
- ("', '".join(d.daemon_id for d in _stopped_daemons)) + "'.",
79
- stack = False
92
+ f"Skipping stopped job" + ("s" if len(stopped_jobs) > 1 else '')
93
+ + " '"
94
+ + ("', '".join(stopped_jobs.keys()))
95
+ + "'.",
96
+ stack=False,
80
97
  )
81
98
 
82
- daemons_to_pause = _running_daemons + _paused_daemons
83
- if not daemons_to_pause:
99
+ jobs_to_pause = {**running_jobs, **paused_jobs}
100
+ if not jobs_to_pause:
84
101
  return False, "No running jobs to pause. You can start jobs with `-d` or `start jobs`."
85
102
 
86
103
  if not action:
87
104
  if not force:
88
- pprint_jobs(_running_daemons)
105
+ pprint_jobs(running_jobs)
89
106
  if not yes_no(
90
107
  "Pause all running jobs?",
91
108
  noask=noask, yes=yes, default='n'
@@ -93,9 +110,9 @@ def _pause_jobs(
93
110
  return False, "No jobs were paused."
94
111
 
95
112
  successes, fails = [], []
96
- for d in daemons_to_pause:
97
- pause_success, pause_msg = d.pause()
98
- (successes if pause_success else fails).append(d.daemon_id)
113
+ for name, job in jobs_to_pause.items():
114
+ pause_success, pause_msg = job.pause()
115
+ (successes if pause_success else fails).append(name)
99
116
 
100
117
  msg = (
101
118
  (
@@ -0,0 +1,107 @@
1
+ #! /usr/bin/env python3
2
+ # vim:fenc=utf-8
3
+
4
+ """
5
+ Restart stopped jobs which have not been manually stopped.
6
+ """
7
+
8
+ from meerschaum.utils.typing import SuccessTuple, Optional, List, Any
9
+
10
+ def restart(
11
+ action: Optional[List[str]] = None,
12
+ executor_keys: Optional[str] = None,
13
+ **kwargs: Any
14
+ ) -> SuccessTuple:
15
+ """
16
+ Restart stopped jobs which have not been manually stopped.
17
+ """
18
+ from meerschaum.actions import choose_subaction
19
+ attach_options = {
20
+ 'jobs': _restart_jobs,
21
+ }
22
+ return choose_subaction(action, attach_options, executor_keys=executor_keys, **kwargs)
23
+
24
+
25
+ def _complete_restart(
26
+ action: Optional[List[str]] = None,
27
+ **kw: Any
28
+ ) -> List[str]:
29
+ """
30
+ Override the default Meerschaum `complete_` function.
31
+ """
32
+ from functools import partial
33
+ from meerschaum.actions.delete import _complete_delete_jobs
34
+
35
+ if action is None:
36
+ action = []
37
+
38
+ _complete_restart_jobs = partial(
39
+ _complete_delete_jobs,
40
+ _get_job_method='restart',
41
+ )
42
+
43
+ options = {
44
+ 'job': _complete_restart_jobs,
45
+ 'jobs': _complete_restart_jobs,
46
+ }
47
+
48
+ if (
49
+ len(action) > 0 and action[0] in options
50
+ and kw.get('line', '').split(' ')[-1] != action[0]
51
+ ):
52
+ sub = action[0]
53
+ del action[0]
54
+ return options[sub](action=action, **kw)
55
+
56
+ from meerschaum._internal.shell import default_action_completer
57
+ return default_action_completer(action=(['restart'] + action), **kw)
58
+
59
+
60
+ def _restart_jobs(
61
+ action: Optional[List[str]] = None,
62
+ executor_keys: Optional[str] = None,
63
+ loop: bool = False,
64
+ min_seconds: Optional[float] = 1.0,
65
+ debug: bool = False,
66
+ **kwargs: Any
67
+ ) -> SuccessTuple:
68
+ """
69
+ Restart stopped jobs which have not been manually stopped.
70
+ """
71
+ import time
72
+ from meerschaum.jobs import (
73
+ get_restart_jobs,
74
+ get_filtered_jobs,
75
+ check_restart_jobs,
76
+ )
77
+ from meerschaum.utils.misc import items_str
78
+ from meerschaum.utils.warnings import info
79
+ action = action or []
80
+
81
+ while True:
82
+ jobs = get_filtered_jobs(executor_keys, action, include_hidden=True, debug=debug)
83
+ restart_jobs = get_restart_jobs(executor_keys, jobs, debug=debug) if not action else jobs
84
+ if not restart_jobs and not loop:
85
+ return True, "No jobs need to be restarted."
86
+
87
+ info(
88
+ "Checking job"
89
+ + ('s' if len(restart_jobs) != 1 else '')
90
+ + ' '
91
+ + items_str(list(restart_jobs.keys()))
92
+ + '...'
93
+ )
94
+
95
+ check_success, check_msg = check_restart_jobs(
96
+ executor_keys,
97
+ restart_jobs,
98
+ debug=debug,
99
+ )
100
+ if not loop:
101
+ break
102
+
103
+ if min_seconds is not None and min_seconds != 0.0:
104
+ info(f"Sleeping for {min_seconds} seconds...")
105
+ time.sleep(min_seconds)
106
+
107
+ return check_success, check_msg