From d64471c349e3575af139f9af110dafcaafbbc235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Csord=C3=A1s?= Date: Mon, 28 Oct 2019 14:04:37 +0100 Subject: [PATCH] [server] Add a liveness and readiness urls Add 2 new url endpoints: - `localhost:8001/live`: simply say that the server is running. In case of succes it will response with 200 status code and a `CODECHECKER_SERVER_IS_LIVE` message. - `localhost:8001/ready`: it will run a simple query on the database. In case of success it will response with 200 status code and a `CODECHECKER_SERVER_IS_READY` message. In case of error it will response with 500 error code and a `CODECHECKER_SERVER_IS_NOT_READY` error message. --- docs/images/kubernetes.png | Bin 0 -> 29962 bytes docs/web/docker.md | 30 +++++++++++++++++++ web/server/codechecker_server/routing.py | 4 ++- web/server/codechecker_server/server.py | 35 ++++++++++++++++++++++- 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 docs/images/kubernetes.png diff --git a/docs/images/kubernetes.png b/docs/images/kubernetes.png new file mode 100644 index 0000000000000000000000000000000000000000..84b806250620efb72c742f73ebf9b39bf3c50ce3 GIT binary patch literal 29962 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 up -d` and Compose starts and runs your entire app. + +## Kubernetes +[![Kubernetes](../images/kubernetes.png)](https://kubernetes.io/) + +CodeChecker supports to configure liveness, readiness and startup probes for +containers when using +[Kubernetes]( https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/). + +If your server is running on `my.company.org` at `8080` port then two URL +endpoints will be available for you: +* `my.company.org:8080/live`: simply say that the server is running. In case of +succes it will response with `200` status code and a +`CODECHECKER_SERVER_IS_LIVE` message. +* `my.company.org:8080/ready`: it will run a simple query on the database. In +case of success it will response with `200` status code and a +`CODECHECKER_SERVER_IS_READY` message. In case of error it will response with +`500` error code and a `CODECHECKER_SERVER_IS_NOT_READY` error message. diff --git a/web/server/codechecker_server/routing.py b/web/server/codechecker_server/routing.py index 8837e9f0d3..da44197448 100644 --- a/web/server/codechecker_server/routing.py +++ b/web/server/codechecker_server/routing.py @@ -28,7 +28,9 @@ 'scripts', 'style', 'userguide', - 'docs'] + 'docs', + 'live', + 'ready'] # A list of top-level path elements in requests (such as Thrift endpoints) # which should not be considered as a product route. diff --git a/web/server/codechecker_server/server.py b/web/server/codechecker_server/server.py index c98818a03d..1fdfcc47cd 100644 --- a/web/server/codechecker_server/server.py +++ b/web/server/codechecker_server/server.py @@ -63,7 +63,8 @@ from .api.report_server import ThriftRequestHandler as ReportHandler_v6 from .database import database from .database import db_cleanup -from .database.config_db_model import Product as ORMProduct +from .database.config_db_model import Product as ORMProduct, \ + Configuration as ORMConfiguration from .database.run_db_model import IDENTIFIER as RUN_META, Run, RunLock LOG = get_logger('server') @@ -154,6 +155,30 @@ def __has_access_permission(self, product): perm_args, self.auth_session) + def __handle_readiness(self): + """ Handle readiness probe. """ + try: + cfg_sess = self.server.config_session() + cfg_sess.query(ORMConfiguration).count() + + self.send_response(200) + self.end_headers() + self.wfile.write('CODECHECKER_SERVER_IS_READY') + except Exception: + self.send_response(500) + self.end_headers() + self.wfile.write('CODECHECKER_SERVER_IS_NOT_READY') + finally: + if cfg_sess: + cfg_sess.close() + cfg_sess.commit() + + def __handle_liveness(self): + """ Handle liveness probe. """ + self.send_response(200) + self.end_headers() + self.wfile.write('CODECHECKER_SERVER_IS_LIVE') + def end_headers(self): # Sending the authentication cookie # in every response if any. @@ -189,6 +214,14 @@ def do_GET(self): product_endpoint, path = routing.split_client_GET_request(self.path) + if self.path == '/live': + self.__handle_liveness() + return + + if self.path == '/ready': + self.__handle_readiness() + return + if self.server.manager.is_enabled and not self.auth_session \ and routing.is_protected_GET_entrypoint(path): # If necessary, prompt the user for authentication.