diff --git a/CHANGELOG.md b/CHANGELOG.md index 85f99ad0..4ecd6232 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ This is the current release cycle, so stay tuned for future releases! +### v1.6.14 + +- **Added healthchecks to `mrsm stack up`.** + The internal Docker Compose file for `mrsm stack` was bumped to version 3.9, and secrets were replaced with environment variable references. + +- **Fixed `--no-auth` when starting the API.** + The command `mrsm start api --no-auth` now correctly handles sessions. + ### v1.6.13 - **Remove `\\u0000` from strings when inserting into PostgreSQL.** diff --git a/docs/mkdocs/news/changelog.md b/docs/mkdocs/news/changelog.md index 85f99ad0..4ecd6232 100644 --- a/docs/mkdocs/news/changelog.md +++ b/docs/mkdocs/news/changelog.md @@ -4,6 +4,14 @@ This is the current release cycle, so stay tuned for future releases! +### v1.6.14 + +- **Added healthchecks to `mrsm stack up`.** + The internal Docker Compose file for `mrsm stack` was bumped to version 3.9, and secrets were replaced with environment variable references. + +- **Fixed `--no-auth` when starting the API.** + The command `mrsm start api --no-auth` now correctly handles sessions. + ### v1.6.13 - **Remove `\\u0000` from strings when inserting into PostgreSQL.** diff --git a/meerschaum/actions/stack.py b/meerschaum/actions/stack.py index 8027cdd3..5b11d408 100644 --- a/meerschaum/actions/stack.py +++ b/meerschaum/actions/stack.py @@ -47,6 +47,15 @@ def stack( from meerschaum.utils.warnings import warn from meerschaum.utils.formatting import ANSI from meerschaum.utils.misc import is_docker_available + from meerschaum.config._read_config import search_and_substitute_config + + stack_env_dict = { + var: val + for var, val in search_and_substitute_config( + meerschaum.config.stack.env_dict + ).items() + if isinstance(val, str) + } if action is None: action = [] @@ -139,7 +148,7 @@ def stack( cwd = STACK_COMPOSE_PATH.parent, stdout = stdout, stderr = stderr, - env = os.environ, + env = stack_env_dict, ) if (has_builtin_compose or has_binary_compose) else run_python_package( 'compose', args = cmd_list, @@ -147,6 +156,7 @@ def stack( venv = _compose_venv, capture_output = _capture_output, as_proc = True, + env = stack_env_dict, ) try: rc = proc.wait() if proc is not None else 1 diff --git a/meerschaum/api/dash/callbacks/dashboard.py b/meerschaum/api/dash/callbacks/dashboard.py index 431d630e..6cc8d67c 100644 --- a/meerschaum/api/dash/callbacks/dashboard.py +++ b/meerschaum/api/dash/callbacks/dashboard.py @@ -129,17 +129,23 @@ def update_page_layout_div(pathname: str, session_store_data: Dict[str, Any]): session_id = session_store_data.get('session-id', None) except AttributeError: session_id = None + ### Bypass login if `--no-auth` is specified. - if session_id is None and no_auth: + if session_id not in active_sessions and no_auth: session_store_data['session-id'] = str(uuid.uuid4()) active_sessions[session_store_data['session-id']] = {'username': 'no-auth'} - session_store_to_return = session_data + session_store_to_return = session_store_data else: session_store_to_return = dash.no_update _path = (pathname.rstrip('/') + '/').replace((dash_endpoint + '/'), '').rstrip('/') - path = _path if no_auth or _path not in _required_login else ( - _path if session_id in active_sessions else 'login' + path = ( + _path + if no_auth or _path not in _required_login else ( + _path + if session_id in active_sessions + else 'login' + ) ) layout = _paths.get(path, pages.error.layout) return layout, session_store_to_return @@ -447,21 +453,22 @@ def show_arguments_collapse(n_clicks : int, is_open : bool): Output('ws', 'send'), Input('test-button', 'n_clicks'), Input('ws', 'url'), + Input('session-store', 'data'), State('ws', 'state'), State('ws', 'message'), State('ws', 'error'), State('ws', 'protocols'), - State('session-store', 'data'), - # prevent_initial_call = True, ) -def ws_send(n_clicks: int, url, *states): +def ws_send(n_clicks: int, url, session_store_data: Dict[str, Any], *states): """ Send an initial connection message over the websocket. """ ctx = dash.callback_context if not url: raise PreventUpdate - session_id = ctx.states['session-store.data']['session-id'] + session_id = session_store_data.get('session-id', None) + if session_id is None: + raise PreventUpdate return json.dumps({ 'connect-time': json_serialize_datetime(datetime.datetime.utcnow()), 'session-id': session_id, diff --git a/meerschaum/config/_version.py b/meerschaum/config/_version.py index d2ef5cfb..6dd053e7 100644 --- a/meerschaum/config/_version.py +++ b/meerschaum/config/_version.py @@ -2,4 +2,4 @@ Specify the Meerschaum release version. """ -__version__ = "1.6.13" +__version__ = "1.6.14" diff --git a/meerschaum/config/stack/__init__.py b/meerschaum/config/stack/__init__.py index 94b9e0fa..9fc9b763 100644 --- a/meerschaum/config/stack/__init__.py +++ b/meerschaum/config/stack/__init__.py @@ -47,7 +47,6 @@ 'meerschaum' : 'MRSM{!meerschaum}', 'system' : 'MRSM{!system}', }, - # separators = (',', ':'), indent = 4, ).replace( '"MRSM{!system}"', 'MRSM{!system}' @@ -94,17 +93,26 @@ } default_docker_compose_config = { - 'version': '3.2', + 'version': '3.9', 'services': { 'db': { 'environment': { 'TIMESCALEDB_TELEMETRY': 'off', - 'POSTGRES_USER': env_dict['POSTGRES_USER'], - 'POSTGRES_DB': env_dict['POSTGRES_DB'], - 'POSTGRES_PASSWORD': env_dict['POSTGRES_PASSWORD'], + 'POSTGRES_USER': '$POSTGRES_USER', + 'POSTGRES_DB': '$POSTGRES_DB', + 'POSTGRES_PASSWORD': '$POSTGRES_PASSWORD', 'ALLOW_IP_RANGE': env_dict['ALLOW_IP_RANGE'], }, 'command': 'postgres -c max_connections=1000 -c shared_buffers=1024MB', + 'healthcheck': { + 'test': [ + 'CMD-SHELL', 'pg_isready', + '-U', '$POSTGRES_USER', '-d', '$POSTGRES_DB', + ], + 'interval': '5s', + 'timeout': '3s', + 'retries': 3 + }, 'restart': 'always', 'image' : 'timescale/timescaledb:' + env_dict['TIMESCALEDB_VERSION'], 'ports' : [ @@ -132,11 +140,13 @@ 'MRSM_CONFIG': env_dict['MEERSCHAUM_API_CONFIG'], 'MRSM_PATCH': env_dict['MEERSCHAUM_API_PATCH'], }, - 'restart' : 'always', + 'restart': 'always', 'init': True, - 'depends_on' : [ - 'db', - ], + 'depends_on': { + 'db': { + 'condition': 'service_healthy', + }, + }, 'volumes' : [ 'api_root:' + volumes['api_root'], ], @@ -151,9 +161,11 @@ 'backend', ], 'restart': 'always', - 'depends_on': [ - 'db', - ], + 'depends_on': { + 'db': { + 'condition': 'service_healthy', + }, + }, 'volumes': [ 'grafana_storage' + ':' + volumes['grafana_storage'], ### NOTE: Mount with the 'z' option for SELinux.