fix: prevent failed containers from showing as running on dashboard

- Add final get_container_status check in start_tool_instance before
  writing status=running; mark as error and return logs if container stopped
- Treat restarting as error in HealthMonitor when DB status was already
  running, so crash loops are surfaced instead of preserved
- Disable auto-restart (restart: unless-stopped -> restart: no) for tool
  instances in manifest compiler, legacy dockerfile path, and built-in seeds

Quality gates:
- pytest tests/unit: 210 passed
- ruff: clean on changed files
- mypy: clean on changed files
This commit is contained in:
Developer
2026-06-14 21:52:02 +00:00
parent a4e6c46a47
commit 089d802f1d
25 changed files with 185 additions and 48 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/seeds
## role
Provides database seeding utilities for initializing built-in tool type configurations in the API application.
Provides database seeding utilities for initializing and synchronizing built-in data records in the API application.
## parent
index: apps/api/src/.pi-map.index.md
map: apps/api/src/.pi-map.md
+3 -3
View File
@@ -4,12 +4,12 @@ dir: apps/api/src/seeds
index: apps/api/src/seeds/.pi-map.index.md
## role
Provides database seeding utilities for initializing built-in tool type configurations in the API application.
Provides database seeding utilities for initializing and synchronizing built-in data records in the API application.
## files
- __init__.py | Marks the directory as a Python package for database seeding utilities.
- builtin_tool_types.py | Seeds built-in tool types (code-server, jupyter-notebook, opencode) into a database with upsert logic, creating or updating Docker Compose-based development environment templates. | exp: func:_table_exists(session, table_name: str) → bool, call:session.execute, call:text, call:result.scalar, func:seed_builtin_tool_types(), call:SessionLocal, call:_table_exists, call:logger.warning, call:session.scalar, call:select(ToolType).where, call:ToolType, call:tool_data.get, call:session.add, call:logger.info, call:session.commit | dep: logging, sqlalchemy, src.database, src.models
- builtin_tool_types.py | Seeds predefined built-in tool types (code-server, jupyter-notebook, opencode) into a database with upsert logic, creating them if missing or updating existing ones to match code changes. | exp: func:_table_exists(session, table_name: str) → bool, call:session.execute, call:text, call:result.scalar, func:seed_builtin_tool_types(), call:SessionLocal, call:_table_exists, call:logger.warning, call:session.scalar, call:select(ToolType).where, call:ToolType, call:tool_data.get, call:session.add, call:logger.info, call:session.commit | dep: logging, sqlalchemy, src.database, src.models
## arch
Simple procedural seeding script using SQLAlchemy upsert operations to populate reference data for containerized development environment templates.
Simple imperative seeding scripts with upsert pattern for idempotent data initialization, using direct database operations without abstraction layers.
## tags
tool, types, table, exists, builtin, call:tool, database, init
## symbols
+3 -3
View File
@@ -65,7 +65,7 @@ services:
- {{REPO_PATH}}:/config/workspace
ports:
- "8443:8443"
restart: unless-stopped""",
restart: 'no'""",
"default_port": 8443,
"required_variables": ["REPO_PATH", "TOOL_NAME"],
},
@@ -87,7 +87,7 @@ services:
- {{REPO_PATH}}:/home/jovyan/work
ports:
- "8888:8888"
restart: unless-stopped""",
restart: 'no'""",
"required_variables": ["REPO_PATH", "TOOL_NAME"],
},
{
@@ -122,7 +122,7 @@ services:
exec tail -f /dev/null"
stdin_open: true
tty: true
restart: unless-stopped""",
restart: 'no'""",
"required_variables": ["REPO_PATH", "TOOL_NAME"],
},
]