Files
headquarter/apps/api/src/services/shared/readiness_probe.py
T
alex 37ccaa4fdc refactor: organize API routers and services into subpackages
Service organization (19 files moved into 6 subpackages):
- services/instance/ — event_bus, health_monitor, lifecycle_hooks
- services/config/ — config_profile_resolver
- services/git/ — clone, git_operations, git_service
- services/build/ — docker_build, manifest_compiler
- services/terminal/ — terminal_manager, terminal_session
- services/shared/ — correlation, file_service, notification_service,
  permission_fixer, readiness_probe, ssh_keys, tunnel, workspace_manager

API router organization (16 files moved into 6 subpackages):
- api/tool/ — tool_instances, tool_types, tool_definitions,
  tool_types_validation, sessions (extracted from tool_instances)
- api/config/ — config_profiles, user_config
- api/workspace/ — workspaces, workspace_files, workspace_git,
  workspace_instances
- api/user/ — users, auth, ssh_keys
- api/project/ — projects, git_repositories
- api/system/ — health, events, notifications, dashboard, terminal,
  instance_proxy

Updated main.py imports and all __init__.py re-exports.
Sessions router extracted from tool_instances.py into api/tool/sessions.py.

Quality gates: py_compile passed, ruff passed.
2026-06-04 12:24:14 +02:00

67 lines
2.1 KiB
Python

"""Readiness probe service for checking if containers are ready."""
import asyncio
import logging
import subprocess
logger = logging.getLogger(__name__)
async def execute_probe(
container_id: str,
command: str,
timeout: int = 30,
interval: int = 2,
) -> tuple[bool, list[str]]:
"""Execute a readiness probe command inside a container.
Args:
container_id: Docker container ID or name
command: Command to execute inside the container
timeout: Maximum total time to wait (seconds)
interval: Time between retries (seconds)
Returns:
Tuple of (success, logs)
"""
logs = []
start_time = asyncio.get_event_loop().time()
attempt = 0
while True:
attempt += 1
elapsed = asyncio.get_event_loop().time() - start_time
if elapsed >= timeout:
logs.append(f"Probe timed out after {timeout}s ({attempt} attempts)")
return False, logs
try:
logger.debug("Probe attempt %d: %s", attempt, command)
# Execute command inside container
result = subprocess.run(
["docker", "exec", container_id, "sh", "-c", command],
capture_output=True,
text=True,
timeout=interval, # Each attempt has its own timeout
)
if result.returncode == 0:
logs.append(f"Attempt {attempt}: Success")
if result.stdout:
logs.append(f"Output: {result.stdout.strip()}")
return True, logs
else:
logs.append(f"Attempt {attempt}: Failed (exit code {result.returncode})")
if result.stderr:
logs.append(f"Stderr: {result.stderr.strip()[:200]}")
except subprocess.TimeoutExpired:
logs.append(f"Attempt {attempt}: Command timed out")
except Exception as exc:
logs.append(f"Attempt {attempt}: Error - {exc}")
# Wait before next attempt
await asyncio.sleep(interval)