From 08b63231768c8b8d1be74b1f23d1dbca08825126 Mon Sep 17 00:00:00 2001 From: simon987 Date: Tue, 30 Jan 2024 10:42:16 -0500 Subject: [PATCH] Add error message when frontend does not start --- sist2-admin/frontend/src/i18n/messages.js | 3 + sist2-admin/frontend/src/views/Frontend.vue | 235 ++++++++++---------- sist2-admin/sist2_admin/app.py | 20 +- sist2-admin/sist2_admin/sist2.py | 15 +- sist2-admin/sist2_admin/util.py | 41 ++++ 5 files changed, 194 insertions(+), 120 deletions(-) create mode 100644 sist2-admin/sist2_admin/util.py diff --git a/sist2-admin/frontend/src/i18n/messages.js b/sist2-admin/frontend/src/i18n/messages.js index a012d94..85e49f8 100644 --- a/sist2-admin/frontend/src/i18n/messages.js +++ b/sist2-admin/frontend/src/i18n/messages.js @@ -65,6 +65,9 @@ export default { gitRepository: "Git repository URL", extraArgs: "Extra command line arguments", + couldNotStartFrontend: "Could not start frontend", + couldNotStartFrontendBody: "Unable to start the frontend, check server logs for more details.", + selectJobs: "Available jobs", selectJob: "Select a job", webOptions: { diff --git a/sist2-admin/frontend/src/views/Frontend.vue b/sist2-admin/frontend/src/views/Frontend.vue index e0662af..c8c3c79 100644 --- a/sist2-admin/frontend/src/views/Frontend.vue +++ b/sist2-admin/frontend/src/views/Frontend.vue @@ -1,63 +1,63 @@ \ No newline at end of file diff --git a/sist2-admin/sist2_admin/app.py b/sist2-admin/sist2_admin/app.py index 8a2f65a..14ccb19 100644 --- a/sist2-admin/sist2_admin/app.py +++ b/sist2-admin/sist2_admin/app.py @@ -2,6 +2,7 @@ import asyncio import os import signal from datetime import datetime +from time import sleep from urllib.parse import urlparse import requests @@ -25,6 +26,7 @@ from state import migrate_v1_to_v2, RUNNING_FRONTENDS, TESSERACT_LANGS, DB_SCHEM get_log_files_to_remove, delete_log_file, create_default_search_backends from web import Sist2Frontend from script import UserScript, SCRIPT_TEMPLATES +from util import tail_sync, pid_is_running sist2 = Sist2(SIST2_BINARY, DATA_FOLDER) db = PersistentState(dbfile=os.path.join(DATA_FOLDER, "state.db")) @@ -324,7 +326,18 @@ def start_frontend_(frontend: Sist2Frontend): logger.debug(f"Fetched search backend options for {backend_name}") pid = sist2.web(frontend.web_options, search_backend, frontend.name) + + sleep(0.2) + if not pid_is_running(pid): + frontend_log = frontend.get_log_path(LOG_FOLDER) + logger.error(f"Frontend exited too quickly, check {frontend_log} for more details:") + for line in tail_sync(frontend.get_log_path(LOG_FOLDER), 3): + logger.error(line.strip()) + + return False + RUNNING_FRONTENDS[frontend.name] = pid + return True @app.post("/api/frontend/{name:str}/start") @@ -333,7 +346,12 @@ async def start_frontend(name: str): if not frontend: raise HTTPException(status_code=404) - start_frontend_(frontend) + ok = start_frontend_(frontend) + + if not ok: + raise HTTPException(status_code=500) + + return "ok" @app.post("/api/frontend/{name:str}/stop") diff --git a/sist2-admin/sist2_admin/sist2.py b/sist2-admin/sist2_admin/sist2.py index 57b6609..099edd6 100644 --- a/sist2-admin/sist2_admin/sist2.py +++ b/sist2-admin/sist2_admin/sist2.py @@ -257,7 +257,7 @@ class Sist2: set_pid_cb(proc.pid) - t_stderr = Thread(target=self._consume_logs_stderr, args=(logs_cb, proc)) + t_stderr = Thread(target=self._consume_logs_stderr, args=(logs_cb, None, proc)) t_stderr.start() self._consume_logs_stdout(logs_cb, proc) @@ -284,7 +284,7 @@ class Sist2: set_pid_cb(proc.pid) - t_stderr = Thread(target=self._consume_logs_stderr, args=(logs_cb, proc)) + t_stderr = Thread(target=self._consume_logs_stderr, args=(logs_cb, None, proc)) t_stderr.start() self._consume_logs_stdout(logs_cb, proc) @@ -294,7 +294,7 @@ class Sist2: return proc.returncode @staticmethod - def _consume_logs_stderr(logs_cb, proc): + def _consume_logs_stderr(logs_cb, exit_cb, proc): pipe_wrapper = TextIOWrapper(proc.stderr, encoding="utf8", errors="ignore") try: for line in pipe_wrapper: @@ -302,7 +302,9 @@ class Sist2: continue logs_cb({"stderr": line}) finally: - proc.wait() + return_code = proc.wait() + if exit_cb: + exit_cb(return_code) pipe_wrapper.close() @staticmethod @@ -340,11 +342,14 @@ class Sist2: def logs_cb(message): web_logger.info(json.dumps(message)) + def exit_cb(return_code): + logger.info(f"Web frontend exited with return code {return_code}") + logger.info(f"Starting frontend {' '.join(args)}") proc = Popen(args, stdout=PIPE, stderr=PIPE) - t_stderr = Thread(target=self._consume_logs_stderr, args=(logs_cb, proc)) + t_stderr = Thread(target=self._consume_logs_stderr, args=(logs_cb, exit_cb, proc)) t_stderr.start() t_stdout = Thread(target=self._consume_logs_stdout, args=(logs_cb, proc)) diff --git a/sist2-admin/sist2_admin/util.py b/sist2-admin/sist2_admin/util.py new file mode 100644 index 0000000..550dc7c --- /dev/null +++ b/sist2-admin/sist2_admin/util.py @@ -0,0 +1,41 @@ +from glob import glob +import os +from config import DATA_FOLDER + + +def get_old_index_files(name): + files = glob(os.path.join(DATA_FOLDER, f"scan-{name.replace('/', '_')}-*.sist2")) + files = list(sorted(files, key=lambda f: os.stat(f).st_mtime)) + files = files[-1:] + + return files + + +def tail_sync(filename, lines=1, _buffer=4098): + with open(filename) as f: + lines_found = [] + + block_counter = -1 + + while len(lines_found) < lines: + try: + f.seek(block_counter * _buffer, os.SEEK_END) + except IOError: + f.seek(0) + lines_found = f.readlines() + break + + lines_found = f.readlines() + + block_counter -= 1 + + return lines_found[-lines:] + + +def pid_is_running(pid): + try: + os.kill(pid, 0) + except OSError: + return False + + return True