meerschaum 2.3.1__py3-none-any.whl → 2.3.3__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.
- meerschaum/_internal/entry.py +44 -14
- meerschaum/actions/restart.py +7 -1
- meerschaum/actions/start.py +3 -4
- meerschaum/api/routes/_jobs.py +9 -2
- meerschaum/config/_default.py +1 -0
- meerschaum/config/_version.py +1 -1
- meerschaum/connectors/api/_jobs.py +16 -3
- meerschaum/jobs/_Executor.py +8 -2
- meerschaum/jobs/_Job.py +31 -1
- meerschaum/jobs/__init__.py +45 -6
- meerschaum/jobs/systemd.py +43 -9
- meerschaum/utils/daemon/Daemon.py +14 -0
- meerschaum/utils/formatting/__init__.py +2 -2
- {meerschaum-2.3.1.dist-info → meerschaum-2.3.3.dist-info}/METADATA +1 -1
- {meerschaum-2.3.1.dist-info → meerschaum-2.3.3.dist-info}/RECORD +21 -21
- {meerschaum-2.3.1.dist-info → meerschaum-2.3.3.dist-info}/LICENSE +0 -0
- {meerschaum-2.3.1.dist-info → meerschaum-2.3.3.dist-info}/NOTICE +0 -0
- {meerschaum-2.3.1.dist-info → meerschaum-2.3.3.dist-info}/WHEEL +0 -0
- {meerschaum-2.3.1.dist-info → meerschaum-2.3.3.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.3.1.dist-info → meerschaum-2.3.3.dist-info}/top_level.txt +0 -0
- {meerschaum-2.3.1.dist-info → meerschaum-2.3.3.dist-info}/zip-safe +0 -0
meerschaum/_internal/entry.py
CHANGED
@@ -111,25 +111,55 @@ def entry(
|
|
111
111
|
)
|
112
112
|
|
113
113
|
entry_success, entry_msg = entry_with_args(_patch_args=_patch_args, **args)
|
114
|
-
if not entry_success:
|
115
|
-
return entry_success, entry_msg
|
116
|
-
|
117
114
|
results.append((entry_success, entry_msg))
|
118
115
|
|
116
|
+
if not entry_success:
|
117
|
+
break
|
118
|
+
|
119
119
|
success = all(_success for _success, _ in results)
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
120
|
+
any_success = any(_success for _success, _ in results)
|
121
|
+
success_messages = [_msg for _success, _msg in results if _success]
|
122
|
+
|
123
|
+
successes_msg = (
|
124
|
+
success_messages[0]
|
125
|
+
if len(success_messages) and len(results) == 1
|
126
|
+
else (
|
127
|
+
(
|
128
|
+
'Successfully c'
|
129
|
+
if success
|
130
|
+
else 'C'
|
131
|
+
) + 'ompleted step'
|
132
|
+
+ ('s' if len(success_messages) != 1 else '')
|
133
|
+
+ ':\n\n'
|
134
|
+
+ '\n'.join(
|
135
|
+
[
|
136
|
+
(
|
137
|
+
make_header(shlex.join(_sysargs))
|
138
|
+
+ '\n ' + _msg + '\n'
|
139
|
+
)
|
140
|
+
for i, (_msg, _sysargs) in enumerate(zip(success_messages, chained_sysargs))
|
141
|
+
]
|
142
|
+
)
|
131
143
|
)
|
132
144
|
)
|
145
|
+
has_fail = results[-1][0] is False
|
146
|
+
fail_ix = len(results) - 1
|
147
|
+
fail_sysargs = chained_sysargs[fail_ix] if has_fail else None
|
148
|
+
fail_msg = results[-1][1] if has_fail else ''
|
149
|
+
fails_msg = (
|
150
|
+
'Failed to complete step:\n\n'
|
151
|
+
+ make_header(shlex.join(fail_sysargs))
|
152
|
+
+ '\n '
|
153
|
+
+ fail_msg
|
154
|
+
|
155
|
+
) if not results[-1][0] else ''
|
156
|
+
|
157
|
+
msg = (
|
158
|
+
successes_msg
|
159
|
+
+ ('\n\n' if any_success else '')
|
160
|
+
+ fails_msg
|
161
|
+
).rstrip()
|
162
|
+
|
133
163
|
if _systemd_result_path:
|
134
164
|
import json
|
135
165
|
with open(_systemd_result_path, 'w+', encoding='utf-8') as f:
|
meerschaum/actions/restart.py
CHANGED
@@ -79,7 +79,13 @@ def _restart_jobs(
|
|
79
79
|
action = action or []
|
80
80
|
|
81
81
|
while True:
|
82
|
-
jobs = get_filtered_jobs(
|
82
|
+
jobs = get_filtered_jobs(
|
83
|
+
executor_keys or 'local',
|
84
|
+
action,
|
85
|
+
include_hidden=True,
|
86
|
+
combine_local_and_systemd=False,
|
87
|
+
debug=debug,
|
88
|
+
)
|
83
89
|
restart_jobs = get_restart_jobs(executor_keys, jobs, debug=debug) if not action else jobs
|
84
90
|
if not restart_jobs and not loop:
|
85
91
|
return True, "No jobs need to be restarted."
|
meerschaum/actions/start.py
CHANGED
@@ -99,7 +99,7 @@ def _start_jobs(
|
|
99
99
|
To start a stopped job, pass the job name after `start job`.
|
100
100
|
|
101
101
|
You may also run a background job with the `-d` or `--daemon` flags.
|
102
|
-
|
102
|
+
|
103
103
|
Examples:
|
104
104
|
|
105
105
|
Create new jobs:
|
@@ -108,9 +108,9 @@ def _start_jobs(
|
|
108
108
|
Run the action `sync pipes --loop` as a background job.
|
109
109
|
Generates a random name; e.g. 'happy_seal'.
|
110
110
|
|
111
|
-
- `start api --daemon --name
|
111
|
+
- `start api --daemon --name api-server`
|
112
112
|
Run the action `start api` as a background job, and assign the job
|
113
|
-
the name '
|
113
|
+
the name 'api-server'.
|
114
114
|
|
115
115
|
Start stopped jobs:
|
116
116
|
|
@@ -119,7 +119,6 @@ def _start_jobs(
|
|
119
119
|
|
120
120
|
- `start job --name happy_seal`
|
121
121
|
Start the job 'happy_seal' but via the `--name` flag.
|
122
|
-
This only applies when no text follows the words 'start job'.
|
123
122
|
"""
|
124
123
|
from meerschaum.utils.warnings import warn, info
|
125
124
|
from meerschaum.utils.daemon._names import get_new_daemon_name
|
meerschaum/api/routes/_jobs.py
CHANGED
@@ -128,7 +128,7 @@ def clean_sysargs(sysargs: List[str]) -> List[str]:
|
|
128
128
|
@app.post(endpoints['jobs'] + '/{name}', tags=['Jobs'])
|
129
129
|
def create_job(
|
130
130
|
name: str,
|
131
|
-
|
131
|
+
metadata: Union[List[str], Dict[str, Any]],
|
132
132
|
curr_user=(
|
133
133
|
fastapi.Depends(manager) if not no_auth else None
|
134
134
|
),
|
@@ -136,7 +136,14 @@ def create_job(
|
|
136
136
|
"""
|
137
137
|
Create and start a new job.
|
138
138
|
"""
|
139
|
-
|
139
|
+
sysargs = metadata if isinstance(metadata, list) else metadata['sysargs']
|
140
|
+
properties = metadata['properties'] if isinstance(metadata, dict) else None
|
141
|
+
job = Job(
|
142
|
+
name,
|
143
|
+
clean_sysargs(sysargs),
|
144
|
+
executor_keys=EXECUTOR_KEYS,
|
145
|
+
_properties=properties,
|
146
|
+
)
|
140
147
|
if job.exists():
|
141
148
|
raise fastapi.HTTPException(
|
142
149
|
status_code=409,
|
meerschaum/config/_default.py
CHANGED
meerschaum/config/_version.py
CHANGED
@@ -12,7 +12,7 @@ import json
|
|
12
12
|
from datetime import datetime
|
13
13
|
|
14
14
|
import meerschaum as mrsm
|
15
|
-
from meerschaum.utils.typing import Dict, Any, SuccessTuple, List, Union, Callable
|
15
|
+
from meerschaum.utils.typing import Dict, Any, SuccessTuple, List, Union, Callable, Optional
|
16
16
|
from meerschaum.jobs import Job
|
17
17
|
from meerschaum.config.static import STATIC_CONFIG
|
18
18
|
from meerschaum.utils.warnings import warn, dprint
|
@@ -184,11 +184,24 @@ def start_job(self, name: str, debug: bool = False) -> SuccessTuple:
|
|
184
184
|
return tuple(response.json())
|
185
185
|
|
186
186
|
|
187
|
-
def create_job(
|
187
|
+
def create_job(
|
188
|
+
self,
|
189
|
+
name: str,
|
190
|
+
sysargs: List[str],
|
191
|
+
properties: Optional[Dict[str, str]] = None,
|
192
|
+
debug: bool = False,
|
193
|
+
) -> SuccessTuple:
|
188
194
|
"""
|
189
195
|
Create a job.
|
190
196
|
"""
|
191
|
-
response = self.post(
|
197
|
+
response = self.post(
|
198
|
+
JOBS_ENDPOINT + f"/{name}",
|
199
|
+
json={
|
200
|
+
'sysargs': sysargs,
|
201
|
+
'properties': properties,
|
202
|
+
},
|
203
|
+
debug=debug,
|
204
|
+
)
|
192
205
|
if not response:
|
193
206
|
if 'detail' in response.text:
|
194
207
|
return False, response.json()['detail']
|
meerschaum/jobs/_Executor.py
CHANGED
@@ -10,7 +10,7 @@ from __future__ import annotations
|
|
10
10
|
from abc import abstractmethod
|
11
11
|
|
12
12
|
from meerschaum.connectors import Connector
|
13
|
-
from meerschaum.utils.typing import List, Dict, SuccessTuple, TYPE_CHECKING
|
13
|
+
from meerschaum.utils.typing import List, Dict, SuccessTuple, TYPE_CHECKING, Optional, Any
|
14
14
|
|
15
15
|
if TYPE_CHECKING:
|
16
16
|
from meerschaum.jobs import Job
|
@@ -33,7 +33,13 @@ class Executor(Connector):
|
|
33
33
|
"""
|
34
34
|
|
35
35
|
@abstractmethod
|
36
|
-
def create_job(
|
36
|
+
def create_job(
|
37
|
+
self,
|
38
|
+
name: str,
|
39
|
+
sysargs: List[str],
|
40
|
+
properties: Optional[Dict[str, Any]] = None,
|
41
|
+
debug: bool = False,
|
42
|
+
) -> SuccessTuple:
|
37
43
|
"""
|
38
44
|
Create a new job.
|
39
45
|
"""
|
meerschaum/jobs/_Job.py
CHANGED
@@ -58,6 +58,7 @@ class Job:
|
|
58
58
|
self,
|
59
59
|
name: str,
|
60
60
|
sysargs: Union[List[str], str, None] = None,
|
61
|
+
env: Optional[Dict[str, str]] = None,
|
61
62
|
executor_keys: Optional[str] = None,
|
62
63
|
_properties: Optional[Dict[str, Any]] = None,
|
63
64
|
_rotating_log = None,
|
@@ -78,6 +79,9 @@ class Job:
|
|
78
79
|
sysargs: Union[List[str], str, None], default None
|
79
80
|
The sysargs of the command to be executed, e.g. 'start api'.
|
80
81
|
|
82
|
+
env: Optional[Dict[str, str]], default None
|
83
|
+
If provided, set these environment variables in the job's process.
|
84
|
+
|
81
85
|
executor_keys: Optional[str], default None
|
82
86
|
If provided, execute the job remotely on an API instance, e.g. 'api:main'.
|
83
87
|
|
@@ -139,6 +143,9 @@ class Job:
|
|
139
143
|
if _externally_managed:
|
140
144
|
self._properties_patch.update({'externally_managed': _externally_managed})
|
141
145
|
|
146
|
+
if env:
|
147
|
+
self._properties_patch.update({'env': env})
|
148
|
+
|
142
149
|
daemon_sysargs = (
|
143
150
|
self._daemon.properties.get('target', {}).get('args', [None])[0]
|
144
151
|
if self._daemon is not None
|
@@ -226,7 +233,12 @@ class Job:
|
|
226
233
|
"""
|
227
234
|
if self.executor is not None:
|
228
235
|
if not self.exists(debug=debug):
|
229
|
-
return self.executor.create_job(
|
236
|
+
return self.executor.create_job(
|
237
|
+
self.name,
|
238
|
+
self.sysargs,
|
239
|
+
properties=self.daemon.properties,
|
240
|
+
debug=debug,
|
241
|
+
)
|
230
242
|
return self.executor.start_job(self.name, debug=debug)
|
231
243
|
|
232
244
|
if self.is_running():
|
@@ -882,6 +894,24 @@ class Job:
|
|
882
894
|
self._externally_managed or self._externally_managed_file.exists()
|
883
895
|
)
|
884
896
|
|
897
|
+
@property
|
898
|
+
def env(self) -> Dict[str, str]:
|
899
|
+
"""
|
900
|
+
Return the environment variables to set for the job's process.
|
901
|
+
"""
|
902
|
+
if '_env' in self.__dict__:
|
903
|
+
return self.__dict__['_env']
|
904
|
+
|
905
|
+
_env = self.daemon.properties.get('env', {})
|
906
|
+
default_env = {
|
907
|
+
'PYTHONUNBUFFERED': '1',
|
908
|
+
'LINES': str(get_config('jobs', 'terminal', 'lines')),
|
909
|
+
'COLUMNS': str(get_config('jobs', 'terminal', 'columns')),
|
910
|
+
}
|
911
|
+
self._env = {**default_env, **_env}
|
912
|
+
return self._env
|
913
|
+
|
914
|
+
|
885
915
|
def __str__(self) -> str:
|
886
916
|
sysargs = self.sysargs
|
887
917
|
sysargs_str = shlex.join(sysargs) if sysargs else ''
|
meerschaum/jobs/__init__.py
CHANGED
@@ -57,6 +57,8 @@ def get_jobs(
|
|
57
57
|
A dictionary mapping job names to jobs.
|
58
58
|
"""
|
59
59
|
from meerschaum.connectors.parse import parse_executor_keys
|
60
|
+
executor_keys = executor_keys or get_executor_keys_from_context()
|
61
|
+
|
60
62
|
include_local_and_system = (
|
61
63
|
combine_local_and_systemd
|
62
64
|
and str(executor_keys).split(':', maxsplit=1)[0] in ('None', 'local', 'systemd')
|
@@ -127,6 +129,7 @@ def get_filtered_jobs(
|
|
127
129
|
executor_keys: Optional[str] = None,
|
128
130
|
filter_list: Optional[List[str]] = None,
|
129
131
|
include_hidden: bool = False,
|
132
|
+
combine_local_and_systemd: bool = True,
|
130
133
|
warn: bool = False,
|
131
134
|
debug: bool = False,
|
132
135
|
) -> Dict[str, Job]:
|
@@ -134,7 +137,12 @@ def get_filtered_jobs(
|
|
134
137
|
Return a list of jobs filtered by the user.
|
135
138
|
"""
|
136
139
|
from meerschaum.utils.warnings import warn as _warn
|
137
|
-
jobs = get_jobs(
|
140
|
+
jobs = get_jobs(
|
141
|
+
executor_keys,
|
142
|
+
include_hidden=True,
|
143
|
+
combine_local_and_systemd=combine_local_and_systemd,
|
144
|
+
debug=debug,
|
145
|
+
)
|
138
146
|
if not filter_list:
|
139
147
|
return {
|
140
148
|
name: job
|
@@ -161,13 +169,19 @@ def get_restart_jobs(
|
|
161
169
|
executor_keys: Optional[str] = None,
|
162
170
|
jobs: Optional[Dict[str, Job]] = None,
|
163
171
|
include_hidden: bool = False,
|
172
|
+
combine_local_and_systemd: bool = True,
|
164
173
|
debug: bool = False,
|
165
174
|
) -> Dict[str, Job]:
|
166
175
|
"""
|
167
176
|
Return jobs which were created with `--restart` or `--loop`.
|
168
177
|
"""
|
169
178
|
if jobs is None:
|
170
|
-
jobs = get_jobs(
|
179
|
+
jobs = get_jobs(
|
180
|
+
executor_keys,
|
181
|
+
include_hidden=include_hidden,
|
182
|
+
combine_local_and_systemd=combine_local_and_systemd,
|
183
|
+
debug=debug,
|
184
|
+
)
|
171
185
|
|
172
186
|
return {
|
173
187
|
name: job
|
@@ -180,13 +194,19 @@ def get_running_jobs(
|
|
180
194
|
executor_keys: Optional[str] = None,
|
181
195
|
jobs: Optional[Dict[str, Job]] = None,
|
182
196
|
include_hidden: bool = False,
|
197
|
+
combine_local_and_systemd: bool = True,
|
183
198
|
debug: bool = False,
|
184
199
|
) -> Dict[str, Job]:
|
185
200
|
"""
|
186
201
|
Return a dictionary of running jobs.
|
187
202
|
"""
|
188
203
|
if jobs is None:
|
189
|
-
jobs = get_jobs(
|
204
|
+
jobs = get_jobs(
|
205
|
+
executor_keys,
|
206
|
+
include_hidden=include_hidden,
|
207
|
+
combine_local_and_systemd=combine_local_and_systemd,
|
208
|
+
debug=debug,
|
209
|
+
)
|
190
210
|
|
191
211
|
return {
|
192
212
|
name: job
|
@@ -199,13 +219,19 @@ def get_paused_jobs(
|
|
199
219
|
executor_keys: Optional[str] = None,
|
200
220
|
jobs: Optional[Dict[str, Job]] = None,
|
201
221
|
include_hidden: bool = False,
|
222
|
+
combine_local_and_systemd: bool = True,
|
202
223
|
debug: bool = False,
|
203
224
|
) -> Dict[str, Job]:
|
204
225
|
"""
|
205
226
|
Return a dictionary of paused jobs.
|
206
227
|
"""
|
207
228
|
if jobs is None:
|
208
|
-
jobs = get_jobs(
|
229
|
+
jobs = get_jobs(
|
230
|
+
executor_keys,
|
231
|
+
include_hidden=include_hidden,
|
232
|
+
combine_local_and_systemd=combine_local_and_systemd,
|
233
|
+
debug=debug,
|
234
|
+
)
|
209
235
|
|
210
236
|
return {
|
211
237
|
name: job
|
@@ -218,13 +244,19 @@ def get_stopped_jobs(
|
|
218
244
|
executor_keys: Optional[str] = None,
|
219
245
|
jobs: Optional[Dict[str, Job]] = None,
|
220
246
|
include_hidden: bool = False,
|
247
|
+
combine_local_and_systemd: bool = True,
|
221
248
|
debug: bool = False,
|
222
249
|
) -> Dict[str, Job]:
|
223
250
|
"""
|
224
251
|
Return a dictionary of stopped jobs.
|
225
252
|
"""
|
226
253
|
if jobs is None:
|
227
|
-
jobs = get_jobs(
|
254
|
+
jobs = get_jobs(
|
255
|
+
executor_keys,
|
256
|
+
include_hidden=include_hidden,
|
257
|
+
combine_local_and_systemd=combine_local_and_systemd,
|
258
|
+
debug=debug,
|
259
|
+
)
|
228
260
|
|
229
261
|
return {
|
230
262
|
name: job
|
@@ -274,6 +306,7 @@ def check_restart_jobs(
|
|
274
306
|
jobs = get_jobs(
|
275
307
|
executor_keys,
|
276
308
|
include_hidden=include_hidden,
|
309
|
+
combine_local_and_systemd=False,
|
277
310
|
debug=debug,
|
278
311
|
)
|
279
312
|
|
@@ -385,12 +418,18 @@ def _install_healthcheck_job() -> SuccessTuple:
|
|
385
418
|
"""
|
386
419
|
Install the systemd job which checks local jobs.
|
387
420
|
"""
|
421
|
+
from meerschaum.config import get_config
|
422
|
+
|
423
|
+
enable_healthcheck = get_config('system', 'experimental', 'systemd_healthcheck')
|
424
|
+
if not enable_healthcheck:
|
425
|
+
return False, "Local healthcheck is disabled."
|
426
|
+
|
388
427
|
if get_executor_keys_from_context() != 'systemd':
|
389
428
|
return False, "Not running systemd."
|
390
429
|
|
391
430
|
job = Job(
|
392
431
|
'.local-healthcheck',
|
393
|
-
['restart', 'jobs', '-e', 'local', '--loop'],
|
432
|
+
['restart', 'jobs', '-e', 'local', '--loop', '--min-seconds', '60'],
|
394
433
|
executor_keys='systemd',
|
395
434
|
)
|
396
435
|
return job.start()
|
meerschaum/jobs/systemd.py
CHANGED
@@ -129,6 +129,7 @@ class SystemdExecutor(Executor):
|
|
129
129
|
service_logs_path = self.get_service_logs_path(name, debug=debug)
|
130
130
|
socket_path = self.get_socket_path(name, debug=debug)
|
131
131
|
result_path = self.get_result_path(name, debug=debug)
|
132
|
+
job = self.get_hidden_job(name, debug=debug)
|
132
133
|
|
133
134
|
sysargs_str = shlex.join(sysargs)
|
134
135
|
exec_str = f'{sys.executable} -m meerschaum {sysargs_str}'
|
@@ -145,9 +146,11 @@ class SystemdExecutor(Executor):
|
|
145
146
|
STATIC_CONFIG['environment']['systemd_log_path']: service_logs_path.as_posix(),
|
146
147
|
STATIC_CONFIG['environment']['systemd_result_path']: result_path.as_posix(),
|
147
148
|
STATIC_CONFIG['environment']['systemd_stdin_path']: socket_path.as_posix(),
|
148
|
-
'LINES': get_config('jobs', 'terminal', 'lines'),
|
149
|
-
'COLUMNS': get_config('jobs', 'terminal', 'columns'),
|
150
149
|
})
|
150
|
+
|
151
|
+
### Allow for user-defined environment variables.
|
152
|
+
mrsm_env_vars.update(job.env)
|
153
|
+
|
151
154
|
environment_lines = [
|
152
155
|
f"Environment={key}={val}"
|
153
156
|
for key, val in mrsm_env_vars.items()
|
@@ -190,7 +193,13 @@ class SystemdExecutor(Executor):
|
|
190
193
|
)
|
191
194
|
return socket_text
|
192
195
|
|
193
|
-
def get_hidden_job(
|
196
|
+
def get_hidden_job(
|
197
|
+
self,
|
198
|
+
name: str,
|
199
|
+
sysargs: Optional[List[str]] = None,
|
200
|
+
properties: Optional[Dict[str, Any]] = None,
|
201
|
+
debug: bool = False,
|
202
|
+
):
|
194
203
|
"""
|
195
204
|
Return the hidden "sister" job to store a job's parameters.
|
196
205
|
"""
|
@@ -198,13 +207,13 @@ class SystemdExecutor(Executor):
|
|
198
207
|
name,
|
199
208
|
sysargs,
|
200
209
|
executor_keys='local',
|
210
|
+
_properties=properties,
|
201
211
|
_rotating_log=self.get_job_rotating_file(name, debug=debug),
|
202
212
|
_stdin_file=self.get_job_stdin_file(name, debug=debug),
|
203
213
|
_status_hook=partial(self.get_job_status, name),
|
204
214
|
_result_hook=partial(self.get_job_result, name),
|
205
215
|
_externally_managed=True,
|
206
216
|
)
|
207
|
-
job._set_externally_managed()
|
208
217
|
return job
|
209
218
|
|
210
219
|
|
@@ -213,6 +222,7 @@ class SystemdExecutor(Executor):
|
|
213
222
|
Return metadata about a job.
|
214
223
|
"""
|
215
224
|
now = time.perf_counter()
|
225
|
+
|
216
226
|
if '_jobs_metadata' not in self.__dict__:
|
217
227
|
self._jobs_metadata: Dict[str, Any] = {}
|
218
228
|
|
@@ -231,6 +241,7 @@ class SystemdExecutor(Executor):
|
|
231
241
|
'daemon': {
|
232
242
|
'status': self.get_job_status(name, debug=debug),
|
233
243
|
'pid': self.get_job_pid(name, debug=debug),
|
244
|
+
'properties': self.get_job_properties(name, debug=debug),
|
234
245
|
},
|
235
246
|
}
|
236
247
|
self._jobs_metadata[name] = {
|
@@ -245,17 +256,24 @@ class SystemdExecutor(Executor):
|
|
245
256
|
"""
|
246
257
|
from meerschaum.jobs._Job import RESTART_FLAGS
|
247
258
|
sysargs = self.get_job_sysargs(name, debug=debug)
|
259
|
+
if not sysargs:
|
260
|
+
return False
|
261
|
+
|
248
262
|
for flag in RESTART_FLAGS:
|
249
263
|
if flag in sysargs:
|
250
264
|
return True
|
265
|
+
|
251
266
|
return False
|
252
267
|
|
253
268
|
def get_job_properties(self, name: str, debug: bool = False) -> Dict[str, Any]:
|
254
269
|
"""
|
255
270
|
Return the properties for a job.
|
256
271
|
"""
|
257
|
-
|
258
|
-
return
|
272
|
+
job = self.get_hidden_job(name, debug=debug)
|
273
|
+
return {
|
274
|
+
k: v for k, v in job.daemon.properties.items()
|
275
|
+
if k != 'externally_managed'
|
276
|
+
}
|
259
277
|
|
260
278
|
def get_job_process(self, name: str, debug: bool = False):
|
261
279
|
"""
|
@@ -499,7 +517,13 @@ class SystemdExecutor(Executor):
|
|
499
517
|
|
500
518
|
return self._stdin_files[name]
|
501
519
|
|
502
|
-
def create_job(
|
520
|
+
def create_job(
|
521
|
+
self,
|
522
|
+
name: str,
|
523
|
+
sysargs: List[str],
|
524
|
+
properties: Optional[Dict[str, Any]] = None,
|
525
|
+
debug: bool = False,
|
526
|
+
) -> SuccessTuple:
|
503
527
|
"""
|
504
528
|
Create a job as a service to be run by `systemd`.
|
505
529
|
"""
|
@@ -510,8 +534,18 @@ class SystemdExecutor(Executor):
|
|
510
534
|
socket_stdin = self.get_job_stdin_file(name, debug=debug)
|
511
535
|
_ = socket_stdin.file_handler
|
512
536
|
|
513
|
-
### Init the
|
514
|
-
|
537
|
+
### Init the externally_managed file.
|
538
|
+
### NOTE: We must write the pickle file in addition to the properties file.
|
539
|
+
job = self.get_hidden_job(name, sysargs=sysargs, properties=properties, debug=debug)
|
540
|
+
job._set_externally_managed()
|
541
|
+
pickle_success, pickle_msg = job.daemon.write_pickle()
|
542
|
+
if not pickle_success:
|
543
|
+
return pickle_success, pickle_msg
|
544
|
+
properties_success, properties_msg = job.daemon.write_properties()
|
545
|
+
if not properties_success:
|
546
|
+
return properties_success, properties_msg
|
547
|
+
|
548
|
+
service_file_path.parent.mkdir(parents=True, exist_ok=True)
|
515
549
|
|
516
550
|
with open(service_file_path, 'w+', encoding='utf-8') as f:
|
517
551
|
f.write(self.get_service_file_text(name, sysargs, debug=debug))
|
@@ -141,6 +141,7 @@ class Daemon:
|
|
141
141
|
target: Optional[Callable[[Any], Any]] = None,
|
142
142
|
target_args: Union[List[Any], Tuple[Any], None] = None,
|
143
143
|
target_kw: Optional[Dict[str, Any]] = None,
|
144
|
+
env: Optional[Dict[str, str]] = None,
|
144
145
|
daemon_id: Optional[str] = None,
|
145
146
|
label: Optional[str] = None,
|
146
147
|
properties: Optional[Dict[str, Any]] = None,
|
@@ -157,6 +158,9 @@ class Daemon:
|
|
157
158
|
target_kw: Optional[Dict[str, Any]], default None
|
158
159
|
Keyword arguments to pass to the target function.
|
159
160
|
|
161
|
+
env: Optional[Dict[str, str]], default None
|
162
|
+
If provided, set these environment variables in the daemon process.
|
163
|
+
|
160
164
|
daemon_id: Optional[str], default None
|
161
165
|
Build a `Daemon` from an existing `daemon_id`.
|
162
166
|
If `daemon_id` is provided, other arguments are ignored and are derived
|
@@ -227,7 +231,11 @@ class Daemon:
|
|
227
231
|
self._properties = properties
|
228
232
|
if self._properties is None:
|
229
233
|
self._properties = {}
|
234
|
+
|
230
235
|
self._properties.update({'label': self.label})
|
236
|
+
if env:
|
237
|
+
self._properties.update({'env': env})
|
238
|
+
|
231
239
|
### Instantiate the process and if it doesn't exist, make sure the PID is removed.
|
232
240
|
_ = self.process
|
233
241
|
|
@@ -295,6 +303,12 @@ class Daemon:
|
|
295
303
|
sys.stdin = self.stdin_file
|
296
304
|
os.environ[STATIC_CONFIG['environment']['daemon_id']] = self.daemon_id
|
297
305
|
os.environ['PYTHONUNBUFFERED'] = '1'
|
306
|
+
|
307
|
+
### Allow the user to override environment variables.
|
308
|
+
env = self.properties.get('env', {})
|
309
|
+
if env and isinstance(env, dict):
|
310
|
+
os.environ.update({str(k): str(v) for k, v in env.items()})
|
311
|
+
|
298
312
|
self.rotating_log.refresh_files(start_interception=True)
|
299
313
|
result = None
|
300
314
|
try:
|
@@ -265,10 +265,10 @@ def print_tuple(
|
|
265
265
|
|
266
266
|
if common_only:
|
267
267
|
skip_common = False
|
268
|
-
do_print = tup[1] in omit_messages
|
268
|
+
do_print = tup[1].strip() in omit_messages
|
269
269
|
|
270
270
|
if skip_common:
|
271
|
-
do_print = tup[1] not in omit_messages
|
271
|
+
do_print = tup[1].strip() not in omit_messages
|
272
272
|
|
273
273
|
if not do_print:
|
274
274
|
return
|
@@ -1,7 +1,7 @@
|
|
1
1
|
meerschaum/__init__.py,sha256=6bn5zz7VInDP4fE_FGBMzJYrM6rQhBMJNQqsf1pU7eI,1701
|
2
2
|
meerschaum/__main__.py,sha256=r5UjYxH1WA6dGG9YGBPul5xOdgF3Iwl0X4dWDtXU-30,2646
|
3
3
|
meerschaum/_internal/__init__.py,sha256=ilC7utfKtin7GAvuN34fKyUQYfPyqH0Mm3MJF5iyEf4,169
|
4
|
-
meerschaum/_internal/entry.py,sha256=
|
4
|
+
meerschaum/_internal/entry.py,sha256=kjRuc8xMOrhhEwIIcHgWfHZ_nhpP6lIdTzb_FjVWeas,10992
|
5
5
|
meerschaum/_internal/arguments/__init__.py,sha256=CbNgnlH6fqNI5n7EuQC6m3Do6ckXDqw4Vuc4T_qPJGQ,566
|
6
6
|
meerschaum/_internal/arguments/_parse_arguments.py,sha256=6Tf9xTXZA-wH51Ep_iuG5JFLzD2rYevuA8n69FTi6Mk,12984
|
7
7
|
meerschaum/_internal/arguments/_parser.py,sha256=LfiVDTr1akj5D31qpJAAXKxMcnLQiD3jRpZtvvHWrAo,14917
|
@@ -38,13 +38,13 @@ meerschaum/actions/pause.py,sha256=WI4dQFfjQ6ObWKUzwQ5FrtYPDyEcnxWwval8cSIzzJw,4
|
|
38
38
|
meerschaum/actions/python.py,sha256=aoSaDSIQ-wJixexFDtsxBMqITktba3DLkJNFIra_6qk,4546
|
39
39
|
meerschaum/actions/register.py,sha256=bOQY0AlZlchsxPF27LL7G1OgdiCyj7mkBaD-PO6bFZc,14491
|
40
40
|
meerschaum/actions/reload.py,sha256=gMXeFBGVfyQ7uhKhYf6bLaDMD0fLPcA9BrLBSiuvWIc,508
|
41
|
-
meerschaum/actions/restart.py,sha256=
|
41
|
+
meerschaum/actions/restart.py,sha256=6ffp3-X9eTEgunVSdD41HnOwqp71yjuSAmXJ5j39ONI,3038
|
42
42
|
meerschaum/actions/setup.py,sha256=KkAGWcgwzl_L6A19fTmTX1KtBjW2FwD8QenLjPy0mQQ,3205
|
43
43
|
meerschaum/actions/sh.py,sha256=fLfTJaacKu4sjLTRqEzzYlT2WbbdZBEczsKb6F-qAek,2026
|
44
44
|
meerschaum/actions/show.py,sha256=Ij6v5so9GHUrYVi7AhPfhHGjABBofXTPAljLFa2xuWA,28141
|
45
45
|
meerschaum/actions/sql.py,sha256=wYofwk1vGO96U2ncigGEfMtYMZeprz2FR1PRRZhkAPI,4311
|
46
46
|
meerschaum/actions/stack.py,sha256=7ODAxzmCx8i9AHxvkbr5ZtzUNPpY-iqlSVo4rZHMOw4,5900
|
47
|
-
meerschaum/actions/start.py,sha256=
|
47
|
+
meerschaum/actions/start.py,sha256=R3ooagL5VazTrC2yOSjakROSC3FoYT1NYhmWF1gsbFo,19262
|
48
48
|
meerschaum/actions/stop.py,sha256=5fdUw70YN-yuUWrC-NhA88cxr9FZ5NbssbQ8xXO8nFU,4632
|
49
49
|
meerschaum/actions/sync.py,sha256=AkH-1O5bkUC-UElQGr0lRhrX-z18ZY2nBPSy9EsW1Kc,17506
|
50
50
|
meerschaum/actions/tag.py,sha256=SJf5qFW0ccLXjqlTdkK_0MCcrCMdg6xhYrhKdco0hdA,3053
|
@@ -118,7 +118,7 @@ meerschaum/api/routes/__init__.py,sha256=jbkeFNl51Tg8aT5gWe560ZLZLojFJsLMe5IENRj
|
|
118
118
|
meerschaum/api/routes/_actions.py,sha256=J_d0jcBZbVDLfzqjR7Ar58oflA-dRQ2oCFYpvk5HHRE,6201
|
119
119
|
meerschaum/api/routes/_connectors.py,sha256=NNbcn5xWhKqw2PqueSEaqRaZ95hFGDKazG5lE7gsssc,1849
|
120
120
|
meerschaum/api/routes/_index.py,sha256=QI6CBo6pI2Zi0a6fJHDjZfiLa9f4okb0BGe3A_JD0kM,578
|
121
|
-
meerschaum/api/routes/_jobs.py,sha256=
|
121
|
+
meerschaum/api/routes/_jobs.py,sha256=gmbgz_yqJB8K6nJVrzzPCnGRC5Kh6g5iiVGLNvZjUQM,11222
|
122
122
|
meerschaum/api/routes/_login.py,sha256=psPKmFkXgYVX83NepqwIhaLsQ5uWgOc4F2QZtPGxY1A,2482
|
123
123
|
meerschaum/api/routes/_misc.py,sha256=05--9ZVFeaCgZrHER2kA3SYdK4TyfkEXOCjLvPbum-w,2469
|
124
124
|
meerschaum/api/routes/_pipes.py,sha256=1gBuE4E-QvIK_kmbmiw7uLcXjnIobFI1t4tb2skpp6E,21592
|
@@ -129,7 +129,7 @@ meerschaum/api/routes/_webterm.py,sha256=7eilgDXckpEc2LyeNmJS5YO6HxlyMkwPnAMWd7e
|
|
129
129
|
meerschaum/api/tables/__init__.py,sha256=e2aNC0CdlWICTUMx1i9RauF8Pm426J0RZJbsJWv4SWo,482
|
130
130
|
meerschaum/config/__init__.py,sha256=jZgQSjvbOWyvGouqRgIeYBg9Pp343_9CDsCWWpwYDGY,11577
|
131
131
|
meerschaum/config/_dash.py,sha256=BJHl4xMrQB-YHUEU7ldEW8q_nOPoIRSOqLrfGElc6Dw,187
|
132
|
-
meerschaum/config/_default.py,sha256=
|
132
|
+
meerschaum/config/_default.py,sha256=SsS80gbxoiYnrmgzpgqmOJIvy0ubT-GI7PpH04UEMv4,5349
|
133
133
|
meerschaum/config/_edit.py,sha256=_kabgFbJdI5kcLs-JIsoaTo0JdyxnPnBdrlTyTAgPm8,8236
|
134
134
|
meerschaum/config/_environment.py,sha256=Vv4DLDfc2vKLbCLsMvkQDj77K4kEvHKEBmUBo-wCrgo,4419
|
135
135
|
meerschaum/config/_formatting.py,sha256=OMuqS1EWOsj_34wSs2tOqGIWci3bTMIZ5l-uelZgsIM,6672
|
@@ -140,7 +140,7 @@ meerschaum/config/_preprocess.py,sha256=-AEA8m_--KivZwTQ1sWN6LTn5sio_fUr2XZ51BO6
|
|
140
140
|
meerschaum/config/_read_config.py,sha256=WFZKIXZMDe_ca0ES7ivgM_mnwShvFxLdoeisT_X5-h0,14720
|
141
141
|
meerschaum/config/_shell.py,sha256=46_m49Txc5q1rGfCgO49ca48BODx45DQJi8D0zz1R18,4245
|
142
142
|
meerschaum/config/_sync.py,sha256=oK2ZujO2T1he08BXCFyiniBUevNGWSQKXLcS_jRv_7Y,4155
|
143
|
-
meerschaum/config/_version.py,sha256
|
143
|
+
meerschaum/config/_version.py,sha256=77O-JjgjLz0XGusI-Yd7mQH2SrggQbyeHPLiUIYO3K4,71
|
144
144
|
meerschaum/config/paths.py,sha256=JjibeGN3YAdSNceRwsd42aNmeUrIgM6ndzC8qZAmNI0,621
|
145
145
|
meerschaum/config/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
146
146
|
meerschaum/config/stack/__init__.py,sha256=Yt7GNzC_hz7iUDZ4gVho_lugJO2DnXgnMtsMG_ReoRg,9114
|
@@ -157,7 +157,7 @@ meerschaum/connectors/api/APIConnector.py,sha256=MPYeImCBAeSpueYis5CxkfT7kkV82Mn
|
|
157
157
|
meerschaum/connectors/api/__init__.py,sha256=JwKrGtuE5aOd2VnsRwudFBYyBf5IxczOwPVdNvCUgSQ,205
|
158
158
|
meerschaum/connectors/api/_actions.py,sha256=Vg_ugl02MUjYtfyx0o9jt5ZoluNC0J1R-UEIRlcIpMI,4701
|
159
159
|
meerschaum/connectors/api/_fetch.py,sha256=Khq9AFr1nk8Dsmcedb77aWhAuHw0JGgVeahDG95Q5MQ,2072
|
160
|
-
meerschaum/connectors/api/_jobs.py,sha256=
|
160
|
+
meerschaum/connectors/api/_jobs.py,sha256=bPQpnacqiJwXxrMEDgsv63Dn6KRprTvDqdeEmpZhkFw,11249
|
161
161
|
meerschaum/connectors/api/_login.py,sha256=5GsD-B214vr5EYfM3XrTUs1sTFApxZA-9dNxq8oNSyg,2050
|
162
162
|
meerschaum/connectors/api/_misc.py,sha256=OZRZBYOokKIEjmQaR8jUYgu6ZRn9VzXBChzR8CfDv_w,1092
|
163
163
|
meerschaum/connectors/api/_pipes.py,sha256=Nnc-IShiTkCia548dePymKosQCcl2InFCyUX3Q-Xx6Q,20604
|
@@ -200,10 +200,10 @@ meerschaum/core/Pipe/_verify.py,sha256=KSnthUzImRLjt9fxyBaLvArqDuOLRpKBfk0tnseJC
|
|
200
200
|
meerschaum/core/Plugin/__init__.py,sha256=UXg64EvJPgI1PCxkY_KM02-ZmBm4FZpLPIQR_uSJJDc,137
|
201
201
|
meerschaum/core/User/_User.py,sha256=CApB7Y0QJL6S9QOCCfrG4SbPuPXJ9AsAYQ5pASMP_Aw,6527
|
202
202
|
meerschaum/core/User/__init__.py,sha256=lJ7beIZTG9sO4dAi3367fFBl17dXYEWHKi7HoaPlDyk,193
|
203
|
-
meerschaum/jobs/_Executor.py,sha256=
|
204
|
-
meerschaum/jobs/_Job.py,sha256=
|
205
|
-
meerschaum/jobs/__init__.py,sha256=
|
206
|
-
meerschaum/jobs/systemd.py,sha256=
|
203
|
+
meerschaum/jobs/_Executor.py,sha256=qM62BhFTM4tyJ7p90KOM0y3qyeRY9k3ZV_aTDJMHnO8,1682
|
204
|
+
meerschaum/jobs/_Job.py,sha256=leyW98wPQUJwvF68zL4vSScalpy6v-e9CiDynoI6aPk,31056
|
205
|
+
meerschaum/jobs/__init__.py,sha256=ieruFbPxozkgyYMEO5wWQ4OXqfD5Pw9VtFWGub6DQxs,11970
|
206
|
+
meerschaum/jobs/systemd.py,sha256=H1hdUh7QJs-DSZ7-jEYZ0NLNEplWmyFo2zt2LAsZO9M,24147
|
207
207
|
meerschaum/plugins/_Plugin.py,sha256=p6j39tm-xrZENBq-eGtixBuXxLLddtEKWRCRFNqpRu0,34086
|
208
208
|
meerschaum/plugins/__init__.py,sha256=trMQ53qgP7ikJhhV_uXzqJw6X1NDz2rPOGXFk40bb1Y,26190
|
209
209
|
meerschaum/plugins/bootstrap.py,sha256=qg9MQ1YAU8ShwGqWDl38WjiXLIxDPl95pSIGDLN9rOw,11423
|
@@ -223,7 +223,7 @@ meerschaum/utils/threading.py,sha256=3N8JXPAnwqJiSjuQcbbJg3Rv9-CCUMJpeQRfKFR7MaA
|
|
223
223
|
meerschaum/utils/typing.py,sha256=U3MC347sh1umpa3Xr1k71eADyDmk4LB6TnVCpq8dVzI,2830
|
224
224
|
meerschaum/utils/warnings.py,sha256=IDiwYspsfjIi1gtk3V9cSo9vNLckB9bCsHhRClpPJTc,6639
|
225
225
|
meerschaum/utils/yaml.py,sha256=Da9ZtNdT8f68sqz6g4eLQM3jz8QQ2J9_FglX-fw5VXY,3901
|
226
|
-
meerschaum/utils/daemon/Daemon.py,sha256=
|
226
|
+
meerschaum/utils/daemon/Daemon.py,sha256=rLUjJTGwKVUGVTHyz_A_lUJ_Wb2CgzT1ZFLhLwvGiNk,42142
|
227
227
|
meerschaum/utils/daemon/FileDescriptorInterceptor.py,sha256=MJKMO0Syf3d8yWUs6xXcQzg8Ptsuvh2aCRRoglOjusA,5257
|
228
228
|
meerschaum/utils/daemon/RotatingFile.py,sha256=ePm_svjwyFDWh6V1k-bp1RHXCSWlyxDtlFu4SU4XvPU,24369
|
229
229
|
meerschaum/utils/daemon/StdinFile.py,sha256=J6tyUReM8NEp3bBQAxMfe8mjJG5mWi6CzHN4x86VQBI,3237
|
@@ -231,7 +231,7 @@ meerschaum/utils/daemon/__init__.py,sha256=o9jWb4lRTIyny4EPt7fPXFgV_vIf1mUofsTwo
|
|
231
231
|
meerschaum/utils/daemon/_names.py,sha256=d2ZwTxBoTAqXZkCfZ5LuX2XrkQmLNUq1OTlUqfoH5dA,4515
|
232
232
|
meerschaum/utils/dtypes/__init__.py,sha256=JR9PViJTzhukZhq0QoPIs73HOnXZZr8OmfhAAD4OAUA,6261
|
233
233
|
meerschaum/utils/dtypes/sql.py,sha256=IkEOyB63je-rCLHM6WwFzGbCerYk1zobL1cXkWqmTa4,14638
|
234
|
-
meerschaum/utils/formatting/__init__.py,sha256=
|
234
|
+
meerschaum/utils/formatting/__init__.py,sha256=GLx3fvTQi7EnC9fo31WggpMRpmR7yTWIuZmHdZgqvuM,15370
|
235
235
|
meerschaum/utils/formatting/_jobs.py,sha256=izsqPJhTtUkXUUtWnbXtReYsUYwulXtci3pBj72Ne64,6637
|
236
236
|
meerschaum/utils/formatting/_pipes.py,sha256=wy0iWJFsFl3X2VloaiA_gp9Yx9w6tD3FQZvAQAqef4A,19492
|
237
237
|
meerschaum/utils/formatting/_pprint.py,sha256=tgrT3FyGyu5CWJYysqK3kX1xdZYorlbOk9fcU_vt9Qg,3096
|
@@ -241,11 +241,11 @@ meerschaum/utils/packages/_packages.py,sha256=GzbJ0kxW_EQogXmY4vguRkUyad42cshFs7
|
|
241
241
|
meerschaum/utils/packages/lazy_loader.py,sha256=VHnph3VozH29R4JnSSBfwtA5WKZYZQFT_GeQSShCnuc,2540
|
242
242
|
meerschaum/utils/venv/_Venv.py,sha256=sBnlmxHdAh2bx8btfVoD79-H9-cYsv5lP02IIXkyECs,3553
|
243
243
|
meerschaum/utils/venv/__init__.py,sha256=bLAWnllKDuE_z6bLk7gLh4mI3Sp1j5hsboTqPKOQq84,24361
|
244
|
-
meerschaum-2.3.
|
245
|
-
meerschaum-2.3.
|
246
|
-
meerschaum-2.3.
|
247
|
-
meerschaum-2.3.
|
248
|
-
meerschaum-2.3.
|
249
|
-
meerschaum-2.3.
|
250
|
-
meerschaum-2.3.
|
251
|
-
meerschaum-2.3.
|
244
|
+
meerschaum-2.3.3.dist-info/LICENSE,sha256=jG2zQEdRNt88EgHUWPpXVWmOrOduUQRx7MnYV9YIPaw,11359
|
245
|
+
meerschaum-2.3.3.dist-info/METADATA,sha256=XXIvdo8w7h0jjkwTUZXj8v-l_B6T9zEN5GXokPZSPNo,24006
|
246
|
+
meerschaum-2.3.3.dist-info/NOTICE,sha256=OTA9Fcthjf5BRvWDDIcBC_xfLpeDV-RPZh3M-HQBRtQ,114
|
247
|
+
meerschaum-2.3.3.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
248
|
+
meerschaum-2.3.3.dist-info/entry_points.txt,sha256=5YBVzibw-0rNA_1VjB16z5GABsOGf-CDhW4yqH8C7Gc,88
|
249
|
+
meerschaum-2.3.3.dist-info/top_level.txt,sha256=bNoSiDj0El6buocix-FRoAtJOeq1qOF5rRm2u9i7Q6A,11
|
250
|
+
meerschaum-2.3.3.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
251
|
+
meerschaum-2.3.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|