qlever 0.5.12__py3-none-any.whl → 0.5.17__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.
Potentially problematic release.
This version of qlever might be problematic. Click here for more details.
- qlever/Qleverfiles/Qleverfile.dblp +1 -1
- qlever/Qleverfiles/Qleverfile.pubchem +102 -26
- qlever/Qleverfiles/Qleverfile.uniprot +48 -16
- qlever/commands/add_text_index.py +2 -1
- qlever/commands/cache_stats.py +1 -1
- qlever/commands/clear_cache.py +4 -2
- qlever/commands/example_queries.py +236 -75
- qlever/commands/extract_queries.py +113 -0
- qlever/commands/get_data.py +1 -1
- qlever/commands/index.py +51 -11
- qlever/commands/index_stats.py +90 -59
- qlever/commands/log.py +12 -2
- qlever/commands/query.py +66 -27
- qlever/commands/settings.py +110 -0
- qlever/commands/setup_config.py +1 -1
- qlever/commands/start.py +222 -105
- qlever/commands/status.py +2 -1
- qlever/commands/stop.py +43 -32
- qlever/commands/system_info.py +1 -1
- qlever/commands/ui.py +3 -1
- qlever/commands/warmup.py +1 -1
- qlever/qlever_main.py +16 -9
- qlever/util.py +34 -17
- {qlever-0.5.12.dist-info → qlever-0.5.17.dist-info}/METADATA +2 -2
- qlever-0.5.17.dist-info/RECORD +54 -0
- {qlever-0.5.12.dist-info → qlever-0.5.17.dist-info}/WHEEL +1 -1
- qlever-0.5.12.dist-info/RECORD +0 -52
- {qlever-0.5.12.dist-info → qlever-0.5.17.dist-info}/LICENSE +0 -0
- {qlever-0.5.12.dist-info → qlever-0.5.17.dist-info}/entry_points.txt +0 -0
- {qlever-0.5.12.dist-info → qlever-0.5.17.dist-info}/top_level.txt +0 -0
qlever/commands/start.py
CHANGED
|
@@ -13,6 +13,110 @@ from qlever.log import log
|
|
|
13
13
|
from qlever.util import is_qlever_server_alive, run_command
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
# Construct the command line based on the config file.
|
|
17
|
+
def construct_command(args) -> str:
|
|
18
|
+
start_cmd = (
|
|
19
|
+
f"{args.server_binary}"
|
|
20
|
+
f" -i {args.name}"
|
|
21
|
+
f" -j {args.num_threads}"
|
|
22
|
+
f" -p {args.port}"
|
|
23
|
+
f" -m {args.memory_for_queries}"
|
|
24
|
+
f" -c {args.cache_max_size}"
|
|
25
|
+
f" -e {args.cache_max_size_single_entry}"
|
|
26
|
+
f" -k {args.cache_max_num_entries}"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
if args.timeout:
|
|
30
|
+
start_cmd += f" -s {args.timeout}"
|
|
31
|
+
if args.access_token:
|
|
32
|
+
start_cmd += f" -a {args.access_token}"
|
|
33
|
+
if args.only_pso_and_pos_permutations:
|
|
34
|
+
start_cmd += " --only-pso-and-pos-permutations"
|
|
35
|
+
if not args.use_patterns:
|
|
36
|
+
start_cmd += " --no-patterns"
|
|
37
|
+
if args.use_text_index == "yes":
|
|
38
|
+
start_cmd += " -t"
|
|
39
|
+
start_cmd += f" > {args.name}.server-log.txt 2>&1"
|
|
40
|
+
return start_cmd
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# Kill existing server on the same port. Trust that StopCommand() works?
|
|
44
|
+
# Maybe return StopCommand().execute(args) and handle it with a try except?
|
|
45
|
+
def kill_existing_server(args) -> bool:
|
|
46
|
+
args.cmdline_regex = f"^ServerMain.* -p {args.port}"
|
|
47
|
+
args.no_containers = True
|
|
48
|
+
if not StopCommand().execute(args):
|
|
49
|
+
log.error("Stopping the existing server failed")
|
|
50
|
+
return False
|
|
51
|
+
log.info("")
|
|
52
|
+
return True
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# Run the command in a container
|
|
56
|
+
def wrap_command_in_container(args, start_cmd) -> str:
|
|
57
|
+
if not args.server_container:
|
|
58
|
+
args.server_container = f"qlever.server.{args.name}"
|
|
59
|
+
start_cmd = Containerize().containerize_command(
|
|
60
|
+
start_cmd,
|
|
61
|
+
args.system,
|
|
62
|
+
"run -d --restart=unless-stopped",
|
|
63
|
+
args.image,
|
|
64
|
+
args.server_container,
|
|
65
|
+
volumes=[("$(pwd)", "/index")],
|
|
66
|
+
ports=[(args.port, args.port)],
|
|
67
|
+
working_directory="/index",
|
|
68
|
+
)
|
|
69
|
+
return start_cmd
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# When running natively, check if the binary exists and works.
|
|
73
|
+
def check_binary(binary) -> bool:
|
|
74
|
+
try:
|
|
75
|
+
run_command(f"{binary} --help")
|
|
76
|
+
return True
|
|
77
|
+
except Exception as e:
|
|
78
|
+
log.error(
|
|
79
|
+
f'Running "{binary}" failed, '
|
|
80
|
+
f"set `--server-binary` to a different binary or "
|
|
81
|
+
f"set `--system to a container system`"
|
|
82
|
+
)
|
|
83
|
+
log.info("")
|
|
84
|
+
log.info(f"The error message was: {e}")
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# Set the index description.
|
|
89
|
+
def set_index_description(access_arg, port, desc) -> bool:
|
|
90
|
+
curl_cmd = (
|
|
91
|
+
f"curl -Gs http://localhost:{port}/api"
|
|
92
|
+
f' --data-urlencode "index-description={desc}"'
|
|
93
|
+
f" {access_arg} > /dev/null"
|
|
94
|
+
)
|
|
95
|
+
log.debug(curl_cmd)
|
|
96
|
+
try:
|
|
97
|
+
run_command(curl_cmd)
|
|
98
|
+
except Exception as e:
|
|
99
|
+
log.error(f"Setting the index description failed ({e})")
|
|
100
|
+
return False
|
|
101
|
+
return True
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# Set the text description.
|
|
105
|
+
def set_text_description(access_arg, port, text_desc) -> bool:
|
|
106
|
+
curl_cmd = (
|
|
107
|
+
f"curl -Gs http://localhost:{port}/api"
|
|
108
|
+
f' --data-urlencode "text-description={text_desc}"'
|
|
109
|
+
f" {access_arg} > /dev/null"
|
|
110
|
+
)
|
|
111
|
+
log.debug(curl_cmd)
|
|
112
|
+
try:
|
|
113
|
+
run_command(curl_cmd)
|
|
114
|
+
except Exception as e:
|
|
115
|
+
log.error(f"Setting the text description failed ({e})")
|
|
116
|
+
return False
|
|
117
|
+
return True
|
|
118
|
+
|
|
119
|
+
|
|
16
120
|
class StartCommand(QleverCommand):
|
|
17
121
|
"""
|
|
18
122
|
Class for executing the `start` command.
|
|
@@ -22,22 +126,35 @@ class StartCommand(QleverCommand):
|
|
|
22
126
|
pass
|
|
23
127
|
|
|
24
128
|
def description(self) -> str:
|
|
25
|
-
return (
|
|
26
|
-
|
|
129
|
+
return (
|
|
130
|
+
"Start the QLever server (requires that you have built "
|
|
131
|
+
"an index with `qlever index` before)"
|
|
132
|
+
)
|
|
27
133
|
|
|
28
134
|
def should_have_qleverfile(self) -> bool:
|
|
29
135
|
return True
|
|
30
136
|
|
|
31
|
-
def relevant_qleverfile_arguments(self) -> dict[str: list[str]]:
|
|
32
|
-
return {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
137
|
+
def relevant_qleverfile_arguments(self) -> dict[str : list[str]]:
|
|
138
|
+
return {
|
|
139
|
+
"data": ["name", "description", "text_description"],
|
|
140
|
+
"server": [
|
|
141
|
+
"server_binary",
|
|
142
|
+
"host_name",
|
|
143
|
+
"port",
|
|
144
|
+
"access_token",
|
|
145
|
+
"memory_for_queries",
|
|
146
|
+
"cache_max_size",
|
|
147
|
+
"cache_max_size_single_entry",
|
|
148
|
+
"cache_max_num_entries",
|
|
149
|
+
"num_threads",
|
|
150
|
+
"timeout",
|
|
151
|
+
"only_pso_and_pos_permutations",
|
|
152
|
+
"use_patterns",
|
|
153
|
+
"use_text_index",
|
|
154
|
+
"warmup_cmd",
|
|
155
|
+
],
|
|
156
|
+
"runtime": ["system", "image", "server_container"],
|
|
157
|
+
}
|
|
41
158
|
|
|
42
159
|
def additional_arguments(self, subparser) -> None:
|
|
43
160
|
# subparser.add_argument("--kill-existing-with-same-name",
|
|
@@ -46,16 +163,27 @@ class StartCommand(QleverCommand):
|
|
|
46
163
|
# help="If a QLever server is already running "
|
|
47
164
|
# "with the same name, kill it before "
|
|
48
165
|
# "starting a new server")
|
|
49
|
-
subparser.add_argument(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
166
|
+
subparser.add_argument(
|
|
167
|
+
"--kill-existing-with-same-port",
|
|
168
|
+
action="store_true",
|
|
169
|
+
default=False,
|
|
170
|
+
help="If a QLever server is already running "
|
|
171
|
+
"on the same port, kill it before "
|
|
172
|
+
"starting a new server",
|
|
173
|
+
)
|
|
174
|
+
subparser.add_argument(
|
|
175
|
+
"--no-warmup",
|
|
176
|
+
action="store_true",
|
|
177
|
+
default=False,
|
|
178
|
+
help="Do not execute the warmup command",
|
|
179
|
+
)
|
|
180
|
+
subparser.add_argument(
|
|
181
|
+
"--run-in-foreground",
|
|
182
|
+
action="store_true",
|
|
183
|
+
default=False,
|
|
184
|
+
help="Run the server in the foreground "
|
|
185
|
+
"(default: run in the background with `nohup`)",
|
|
186
|
+
)
|
|
59
187
|
|
|
60
188
|
def execute(self, args) -> bool:
|
|
61
189
|
# Kill existing server with the same name if so desired.
|
|
@@ -70,84 +198,57 @@ class StartCommand(QleverCommand):
|
|
|
70
198
|
|
|
71
199
|
# Kill existing server on the same port if so desired.
|
|
72
200
|
if args.kill_existing_with_same_port:
|
|
73
|
-
args.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
201
|
+
if args.kill_existing_with_same_port and not kill_existing_server(
|
|
202
|
+
args
|
|
203
|
+
):
|
|
204
|
+
return False
|
|
77
205
|
|
|
78
206
|
# Construct the command line based on the config file.
|
|
79
|
-
start_cmd = (
|
|
80
|
-
f" -i {args.name}"
|
|
81
|
-
f" -j {args.num_threads}"
|
|
82
|
-
f" -p {args.port}"
|
|
83
|
-
f" -m {args.memory_for_queries}"
|
|
84
|
-
f" -c {args.cache_max_size}"
|
|
85
|
-
f" -e {args.cache_max_size_single_entry}"
|
|
86
|
-
f" -k {args.cache_max_num_entries}")
|
|
87
|
-
if args.timeout:
|
|
88
|
-
start_cmd += f" -s {args.timeout}"
|
|
89
|
-
if args.access_token:
|
|
90
|
-
start_cmd += f" -a {args.access_token}"
|
|
91
|
-
if args.only_pso_and_pos_permutations:
|
|
92
|
-
start_cmd += " --only-pso-and-pos-permutations"
|
|
93
|
-
if not args.use_patterns:
|
|
94
|
-
start_cmd += " --no-patterns"
|
|
95
|
-
if args.use_text_index == "yes":
|
|
96
|
-
start_cmd += " -t"
|
|
97
|
-
start_cmd += f" > {args.name}.server-log.txt 2>&1"
|
|
207
|
+
start_cmd = construct_command(args)
|
|
98
208
|
|
|
99
209
|
# Run the command in a container (if so desired). Otherwise run with
|
|
100
|
-
# `nohup` so that it keeps running after the shell is closed.
|
|
210
|
+
# `nohup` so that it keeps running after the shell is closed. With
|
|
211
|
+
# `--run-in-foreground`, run the server in the foreground.
|
|
101
212
|
if args.system in Containerize.supported_systems():
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
start_cmd =
|
|
105
|
-
start_cmd,
|
|
106
|
-
args.system, "run -d --restart=unless-stopped",
|
|
107
|
-
args.image,
|
|
108
|
-
args.server_container,
|
|
109
|
-
volumes=[("$(pwd)", "/index")],
|
|
110
|
-
ports=[(args.port, args.port)],
|
|
111
|
-
working_directory="/index")
|
|
213
|
+
start_cmd = wrap_command_in_container(args, start_cmd)
|
|
214
|
+
elif args.run_in_foreground:
|
|
215
|
+
start_cmd = f"{start_cmd}"
|
|
112
216
|
else:
|
|
113
217
|
start_cmd = f"nohup {start_cmd} &"
|
|
114
218
|
|
|
115
219
|
# Show the command line.
|
|
116
220
|
self.show(start_cmd, only_show=args.show)
|
|
117
221
|
if args.show:
|
|
118
|
-
return
|
|
222
|
+
return True
|
|
119
223
|
|
|
120
224
|
# When running natively, check if the binary exists and works.
|
|
121
225
|
if args.system == "native":
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
except Exception as e:
|
|
125
|
-
log.error(f"Running \"{args.server_binary}\" failed, "
|
|
126
|
-
f"set `--server-binary` to a different binary or "
|
|
127
|
-
f"set `--system to a container system`")
|
|
128
|
-
log.info("")
|
|
129
|
-
log.info(f"The error message was: {e}")
|
|
226
|
+
ret = check_binary(args.server_binary)
|
|
227
|
+
if not ret:
|
|
130
228
|
return False
|
|
131
229
|
|
|
132
230
|
# Check if a QLever server is already running on this port.
|
|
133
|
-
|
|
134
|
-
if is_qlever_server_alive(
|
|
135
|
-
log.error(f"QLever server already running on
|
|
231
|
+
endpoint_url = f"http://localhost:{args.port}"
|
|
232
|
+
if is_qlever_server_alive(endpoint_url):
|
|
233
|
+
log.error(f"QLever server already running on {endpoint_url}")
|
|
136
234
|
log.info("")
|
|
137
|
-
log.info(
|
|
138
|
-
|
|
139
|
-
|
|
235
|
+
log.info(
|
|
236
|
+
"To kill the existing server, use `qlever stop` "
|
|
237
|
+
"or `qlever start` with option "
|
|
238
|
+
"--kill-existing-with-same-port`"
|
|
239
|
+
)
|
|
140
240
|
|
|
141
241
|
# Show output of status command.
|
|
142
|
-
args.cmdline_regex = f"^ServerMain.* -p *{port}"
|
|
242
|
+
args.cmdline_regex = f"^ServerMain.* -p *{args.port}"
|
|
143
243
|
log.info("")
|
|
144
244
|
StatusCommand().execute(args)
|
|
145
|
-
|
|
146
245
|
return False
|
|
147
246
|
|
|
148
247
|
# Remove already existing container.
|
|
149
|
-
if
|
|
150
|
-
|
|
248
|
+
if (
|
|
249
|
+
args.system in Containerize.supported_systems()
|
|
250
|
+
and args.kill_existing_with_same_port
|
|
251
|
+
):
|
|
151
252
|
try:
|
|
152
253
|
run_command(f"{args.system} rm -f {args.server_container}")
|
|
153
254
|
except Exception as e:
|
|
@@ -164,7 +265,10 @@ class StartCommand(QleverCommand):
|
|
|
164
265
|
|
|
165
266
|
# Execute the command line.
|
|
166
267
|
try:
|
|
167
|
-
run_command(
|
|
268
|
+
process = run_command(
|
|
269
|
+
start_cmd,
|
|
270
|
+
use_popen=args.run_in_foreground,
|
|
271
|
+
)
|
|
168
272
|
except Exception as e:
|
|
169
273
|
log.error(f"Starting the QLever server failed ({e})")
|
|
170
274
|
return False
|
|
@@ -172,48 +276,61 @@ class StartCommand(QleverCommand):
|
|
|
172
276
|
# Tail the server log until the server is ready (note that the `exec`
|
|
173
277
|
# is important to make sure that the tail process is killed and not
|
|
174
278
|
# just the bash process).
|
|
175
|
-
|
|
176
|
-
|
|
279
|
+
if args.run_in_foreground:
|
|
280
|
+
log.info(
|
|
281
|
+
f"Follow {args.name}.server-log.txt as long as the server is"
|
|
282
|
+
f" running (Ctrl-C stops the server)"
|
|
283
|
+
)
|
|
284
|
+
else:
|
|
285
|
+
log.info(
|
|
286
|
+
f"Follow {args.name}.server-log.txt until the server is ready"
|
|
287
|
+
f" (Ctrl-C stops following the log, but NOT the server)"
|
|
288
|
+
)
|
|
177
289
|
log.info("")
|
|
178
290
|
tail_cmd = f"exec tail -f {args.name}.server-log.txt"
|
|
179
291
|
tail_proc = subprocess.Popen(tail_cmd, shell=True)
|
|
180
|
-
while not is_qlever_server_alive(
|
|
292
|
+
while not is_qlever_server_alive(endpoint_url):
|
|
181
293
|
time.sleep(1)
|
|
182
294
|
|
|
183
|
-
# Set the
|
|
184
|
-
access_arg = f
|
|
295
|
+
# Set the description for the index and text.
|
|
296
|
+
access_arg = f'--data-urlencode "access-token={args.access_token}"'
|
|
185
297
|
if args.description:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
try:
|
|
192
|
-
run_command(curl_cmd)
|
|
193
|
-
except Exception as e:
|
|
194
|
-
log.error(f"Setting the index description failed ({e})")
|
|
298
|
+
ret = set_index_description(
|
|
299
|
+
access_arg, args.port, args.description
|
|
300
|
+
)
|
|
301
|
+
if not ret:
|
|
302
|
+
return False
|
|
195
303
|
if args.text_description:
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
try:
|
|
202
|
-
run_command(curl_cmd)
|
|
203
|
-
except Exception as e:
|
|
204
|
-
log.error(f"Setting the text description failed ({e})")
|
|
304
|
+
ret = set_text_description(
|
|
305
|
+
access_arg, args.port, args.text_description
|
|
306
|
+
)
|
|
307
|
+
if not ret:
|
|
308
|
+
return False
|
|
205
309
|
|
|
206
310
|
# Kill the tail process. NOTE: `tail_proc.kill()` does not work.
|
|
207
|
-
|
|
311
|
+
if not args.run_in_foreground:
|
|
312
|
+
tail_proc.terminate()
|
|
208
313
|
|
|
209
314
|
# Execute the warmup command.
|
|
210
315
|
if args.warmup_cmd and not args.no_warmup:
|
|
211
316
|
log.info("")
|
|
212
|
-
WarmupCommand().execute(args)
|
|
317
|
+
if not WarmupCommand().execute(args):
|
|
318
|
+
log.error("Warmup failed")
|
|
319
|
+
return False
|
|
213
320
|
|
|
214
321
|
# Show cache stats.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
322
|
+
if not args.run_in_foreground:
|
|
323
|
+
log.info("")
|
|
324
|
+
args.detailed = False
|
|
325
|
+
args.server_url = None
|
|
326
|
+
CacheStatsCommand().execute(args)
|
|
327
|
+
|
|
328
|
+
# With `--run-in-foreground`, wait until the server is stopped.
|
|
329
|
+
if args.run_in_foreground:
|
|
330
|
+
try:
|
|
331
|
+
process.wait()
|
|
332
|
+
except KeyboardInterrupt:
|
|
333
|
+
process.terminate()
|
|
334
|
+
tail_proc.terminate()
|
|
335
|
+
|
|
219
336
|
return True
|
qlever/commands/status.py
CHANGED
|
@@ -35,7 +35,7 @@ class StatusCommand(QleverCommand):
|
|
|
35
35
|
f"the command line matches {args.cmdline_regex}"
|
|
36
36
|
f" using Python's psutil library", only_show=args.show)
|
|
37
37
|
if args.show:
|
|
38
|
-
return
|
|
38
|
+
return True
|
|
39
39
|
|
|
40
40
|
# Show the results as a table.
|
|
41
41
|
num_processes_found = 0
|
|
@@ -47,3 +47,4 @@ class StatusCommand(QleverCommand):
|
|
|
47
47
|
num_processes_found += 1
|
|
48
48
|
if num_processes_found == 0:
|
|
49
49
|
print("No processes found")
|
|
50
|
+
return True
|
qlever/commands/stop.py
CHANGED
|
@@ -1,15 +1,40 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
|
|
3
2
|
import re
|
|
4
|
-
|
|
5
3
|
import psutil
|
|
6
|
-
|
|
7
4
|
from qlever.command import QleverCommand
|
|
8
5
|
from qlever.commands.status import StatusCommand
|
|
9
6
|
from qlever.containerize import Containerize
|
|
10
7
|
from qlever.log import log
|
|
11
8
|
from qlever.util import show_process_info
|
|
12
9
|
|
|
10
|
+
# try to kill the given process, return true iff it was killed successfully.
|
|
11
|
+
# the process_info is used for logging.
|
|
12
|
+
def stop_process(proc, pinfo):
|
|
13
|
+
try:
|
|
14
|
+
proc.kill()
|
|
15
|
+
log.info(f"Killed process {pinfo['pid']}")
|
|
16
|
+
return True
|
|
17
|
+
except Exception as e:
|
|
18
|
+
log.error(f"Could not kill process with PID "
|
|
19
|
+
f"{pinfo['pid']} ({e}) ... try to kill it "
|
|
20
|
+
f"manually")
|
|
21
|
+
log.info("")
|
|
22
|
+
show_process_info(proc, "", show_heading=True)
|
|
23
|
+
return False
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# try to stop and remove container. return True iff it was stopped
|
|
27
|
+
# successfully. Gives log info accordingly.
|
|
28
|
+
def stop_container(server_container):
|
|
29
|
+
for container_system in Containerize.supported_systems():
|
|
30
|
+
if Containerize.stop_and_remove_container(
|
|
31
|
+
container_system, server_container):
|
|
32
|
+
log.info(f"{container_system.capitalize()} container with "
|
|
33
|
+
f"name \"{server_container}\" stopped "
|
|
34
|
+
f" and removed")
|
|
35
|
+
return True
|
|
36
|
+
return False
|
|
37
|
+
|
|
13
38
|
|
|
14
39
|
class StopCommand(QleverCommand):
|
|
15
40
|
"""
|
|
@@ -20,7 +45,7 @@ class StopCommand(QleverCommand):
|
|
|
20
45
|
pass
|
|
21
46
|
|
|
22
47
|
def description(self) -> str:
|
|
23
|
-
return
|
|
48
|
+
return "Stop QLever server for a given datasedataset or port"
|
|
24
49
|
|
|
25
50
|
def should_have_qleverfile(self) -> bool:
|
|
26
51
|
return True
|
|
@@ -49,55 +74,41 @@ class StopCommand(QleverCommand):
|
|
|
49
74
|
f"\"{args.server_container}\"")
|
|
50
75
|
self.show(description, only_show=args.show)
|
|
51
76
|
if args.show:
|
|
52
|
-
return
|
|
77
|
+
return True
|
|
53
78
|
|
|
54
79
|
# First check if there is container running and if yes, stop and remove
|
|
55
80
|
# it (unless the user has specified `--no-containers`).
|
|
56
81
|
if not args.no_containers:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
container_system, args.server_container):
|
|
60
|
-
log.info(f"{container_system.capitalize()} container with "
|
|
61
|
-
f"name \"{args.server_container}\" stopped "
|
|
62
|
-
f" and removed")
|
|
63
|
-
return True
|
|
82
|
+
if stop_container(args.server_container):
|
|
83
|
+
return True
|
|
64
84
|
|
|
65
85
|
# Check if there is a process running on the server port using psutil.
|
|
66
|
-
#
|
|
67
86
|
# NOTE: On MacOS, some of the proc's returned by psutil.process_iter()
|
|
68
87
|
# no longer exist when we try to access them, so we just skip them.
|
|
88
|
+
stop_process_results = []
|
|
69
89
|
for proc in psutil.process_iter():
|
|
70
90
|
try:
|
|
71
91
|
pinfo = proc.as_dict(
|
|
72
|
-
|
|
73
|
-
|
|
92
|
+
attrs=['pid', 'username', 'create_time',
|
|
93
|
+
'memory_info', 'cmdline'])
|
|
74
94
|
cmdline = " ".join(pinfo['cmdline'])
|
|
75
95
|
except Exception as e:
|
|
76
96
|
log.debug(f"Error getting process info: {e}")
|
|
97
|
+
return False
|
|
77
98
|
if re.search(cmdline_regex, cmdline):
|
|
78
99
|
log.info(f"Found process {pinfo['pid']} from user "
|
|
79
100
|
f"{pinfo['username']} with command line: {cmdline}")
|
|
80
101
|
log.info("")
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
except Exception as e:
|
|
85
|
-
log.error(f"Could not kill process with PID "
|
|
86
|
-
f"{pinfo['pid']} ({e}) ... try to kill it "
|
|
87
|
-
f"manually")
|
|
88
|
-
log.info("")
|
|
89
|
-
show_process_info(proc, "", show_heading=True)
|
|
90
|
-
return False
|
|
91
|
-
return True
|
|
102
|
+
stop_process_results.append(stop_process(proc, pinfo))
|
|
103
|
+
if len(stop_process_results) > 0:
|
|
104
|
+
return all(stop_process_results)
|
|
92
105
|
|
|
93
|
-
#
|
|
106
|
+
# If no matching process found, show a message and the output of the
|
|
107
|
+
# status command.
|
|
94
108
|
message = "No matching process found" if args.no_containers else \
|
|
95
|
-
|
|
109
|
+
"No matching process or container found"
|
|
96
110
|
log.error(message)
|
|
97
|
-
|
|
98
|
-
# Show output of status command.
|
|
99
111
|
args.cmdline_regex = "^ServerMain.* -i [^ ]*"
|
|
100
112
|
log.info("")
|
|
101
113
|
StatusCommand().execute(args)
|
|
102
|
-
|
|
103
|
-
return False
|
|
114
|
+
return True
|
qlever/commands/system_info.py
CHANGED
|
@@ -58,7 +58,7 @@ class SystemInfoCommand(QleverCommand):
|
|
|
58
58
|
# Say what the command is doing.
|
|
59
59
|
self.show("Show system information and Qleverfile", only_show=args.show)
|
|
60
60
|
if args.show:
|
|
61
|
-
return
|
|
61
|
+
return True
|
|
62
62
|
|
|
63
63
|
# Show system information.
|
|
64
64
|
show_heading("System Information")
|
qlever/commands/ui.py
CHANGED
|
@@ -70,8 +70,10 @@ class UiCommand(QleverCommand):
|
|
|
70
70
|
"\n".join(["Stop running containers", pull_cmd, run_cmd, exec_cmd]),
|
|
71
71
|
only_show=args.show,
|
|
72
72
|
)
|
|
73
|
-
if qlever_is_running_in_container
|
|
73
|
+
if qlever_is_running_in_container:
|
|
74
74
|
return False
|
|
75
|
+
if args.show:
|
|
76
|
+
return True
|
|
75
77
|
|
|
76
78
|
# Stop running containers.
|
|
77
79
|
for container_system in Containerize.supported_systems():
|
qlever/commands/warmup.py
CHANGED
qlever/qlever_main.py
CHANGED
|
@@ -35,31 +35,38 @@ def main():
|
|
|
35
35
|
log.info("")
|
|
36
36
|
log.info(colored(f"Command: {args.command}", attrs=["bold"]))
|
|
37
37
|
log.info("")
|
|
38
|
-
command_object.execute(args)
|
|
38
|
+
commandWasSuccesful = command_object.execute(args)
|
|
39
39
|
log.info("")
|
|
40
|
+
if not commandWasSuccesful:
|
|
41
|
+
exit(1)
|
|
40
42
|
except KeyboardInterrupt:
|
|
41
43
|
log.info("")
|
|
42
44
|
log.info("Ctrl-C pressed, exiting ...")
|
|
43
45
|
log.info("")
|
|
44
|
-
exit(
|
|
46
|
+
exit(1)
|
|
45
47
|
except Exception as e:
|
|
46
48
|
# Check if it's a certain kind of `AttributeError` and give a hint in
|
|
47
49
|
# that case.
|
|
48
50
|
match_error = re.search(r"object has no attribute '(.+)'", str(e))
|
|
49
|
-
match_trace = re.search(
|
|
50
|
-
|
|
51
|
+
match_trace = re.search(
|
|
52
|
+
r"(qlever/commands/.+\.py)\", line (\d+)", traceback.format_exc()
|
|
53
|
+
)
|
|
51
54
|
if isinstance(e, AttributeError) and match_error and match_trace:
|
|
52
55
|
attribute = match_error.group(1)
|
|
53
56
|
trace_command = match_trace.group(1)
|
|
54
57
|
trace_line = match_trace.group(2)
|
|
55
58
|
log.error(f"{e} in `{trace_command}` at line {trace_line}")
|
|
56
59
|
log.info("")
|
|
57
|
-
log.info(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
log.info(
|
|
61
|
+
f"Likely cause: you used `args.{attribute}`, but it was "
|
|
62
|
+
f"neither defined in `relevant_qleverfile_arguments` "
|
|
63
|
+
f"nor in `additional_arguments`"
|
|
64
|
+
)
|
|
60
65
|
log.info("")
|
|
61
|
-
log.info(
|
|
62
|
-
|
|
66
|
+
log.info(
|
|
67
|
+
f"If you did not implement `{trace_command}` yourself, "
|
|
68
|
+
f"please report this issue"
|
|
69
|
+
)
|
|
63
70
|
log.info("")
|
|
64
71
|
else:
|
|
65
72
|
log.error(f"An unexpected error occurred: {e}")
|