From e87022dc55d06c60510f6069769a444a2d15a200 Mon Sep 17 00:00:00 2001 From: Dmitrii Iurco Date: Sat, 30 May 2026 14:28:46 -0400 Subject: [PATCH] fix: cell-network name, install error surfacing, health history cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docker-compose.services.yml: change external network name from pic_cell-network to cell-network so store-service compose files can find it. The project-prefixed name was overriding the explicit name: cell-network fix in docker-compose.yml when both files were merged by make start. - service_store.py: normalize docker compose stderr into the error key in the 400 response so the Store page shows the actual failure reason instead of the generic fallback message. - app.py: skip health checks for email/calendar/files managers when those optional store services are not installed — prevents false Down alerts and unnecessary noise in health history. - Logs.jsx: remove Email/Calendar/Files columns from the health history table; they are optional store services, not core builtins that should always appear. Co-Authored-By: Claude Sonnet 4.6 --- api/app.py | 13 +++++++++++-- api/routes/service_store.py | 4 ++++ docker-compose.services.yml | 2 +- webui/src/pages/Logs.jsx | 5 +---- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/api/app.py b/api/app.py index bb6ebdd..d163fe1 100644 --- a/api/app.py +++ b/api/app.py @@ -519,9 +519,18 @@ def perform_health_check(): 'timestamp': datetime.utcnow().isoformat(), 'alerts': [] } - + + # email/calendar/files are optional store services — only check them when installed + _installed_store_ids = set(config_manager.get_installed_services()) + _OPTIONAL_STORE_MANAGERS = frozenset({'email_manager', 'calendar_manager', 'file_manager'}) + # Get health from each service for service_name in service_bus.list_services(): + if service_name in _OPTIONAL_STORE_MANAGERS: + # Map manager name to store service id (strip _manager suffix) + store_id = service_name.replace('_manager', '') + if store_id not in _installed_store_ids: + continue try: service = service_bus.get_service(service_name) if hasattr(service, 'health_check'): @@ -531,7 +540,7 @@ def perform_health_check(): result[service_name] = health except Exception as e: result[service_name] = {'error': str(e), 'status': 'offline'} - + # Health alerting logic — alert only when a service container is not running global service_alert_counters for service_name in service_bus.list_services(): diff --git a/api/routes/service_store.py b/api/routes/service_store.py index b17c3ad..dcbf4bc 100644 --- a/api/routes/service_store.py +++ b/api/routes/service_store.py @@ -62,6 +62,10 @@ def install_service(service_id: str): result = _ssm().install(service_id) if result.get('ok'): return jsonify(result) + # Normalize docker compose stderr into the error key so the frontend + # can display the actual failure reason rather than a generic message. + if not result.get('error') and result.get('stderr'): + result = {**result, 'error': result['stderr']} return jsonify(result), 400 except Exception as e: logger.error(f'install_service({service_id}): {e}') diff --git a/docker-compose.services.yml b/docker-compose.services.yml index f5772f5..0189ff2 100644 --- a/docker-compose.services.yml +++ b/docker-compose.services.yml @@ -3,4 +3,4 @@ services: {} networks: cell-network: external: true - name: pic_cell-network + name: cell-network diff --git a/webui/src/pages/Logs.jsx b/webui/src/pages/Logs.jsx index de8d5e9..7f3e080 100644 --- a/webui/src/pages/Logs.jsx +++ b/webui/src/pages/Logs.jsx @@ -392,7 +392,7 @@ function HealthHistoryTab() { - {['Timestamp','Network','WireGuard','Email','Calendar','Files','Routing','Vault','Alerts'].map(h => ( + {['Timestamp','Network','WireGuard','Routing','Vault','Alerts'].map(h => ( ))} @@ -403,9 +403,6 @@ function HealthHistoryTab() { - - -
{h}
{h.timestamp}