40 lines
1.4 KiB
Python
40 lines
1.4 KiB
Python
"""Readiness checks shared by HTTP and background process roles."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
from backup_tool.cli import build_alembic_config
|
|
from backup_tool.config import Settings
|
|
from backup_tool.db.engine import assert_schema_current, create_engine
|
|
|
|
|
|
class ReadinessError(RuntimeError):
|
|
"""A dependency needed by the selected role is unavailable."""
|
|
|
|
|
|
def _require_access(path: object, mode: int) -> None:
|
|
try:
|
|
candidate = path if isinstance(path, str) else str(path)
|
|
if not os.path.isdir(candidate) or not os.access(candidate, mode):
|
|
raise ReadinessError("required storage is unavailable")
|
|
except OSError as error:
|
|
raise ReadinessError("required storage is unavailable") from error
|
|
|
|
|
|
async def check_role_readiness(settings: Settings, role: str) -> None:
|
|
engine = create_engine(settings)
|
|
try:
|
|
await assert_schema_current(engine, build_alembic_config(settings))
|
|
except Exception as error:
|
|
raise ReadinessError("metadata is unavailable") from error
|
|
finally:
|
|
await engine.dispose()
|
|
if role == "scheduler":
|
|
return
|
|
_require_access(settings.data_dir, os.R_OK | os.W_OK | os.X_OK)
|
|
for root in settings.repository_roots + settings.restore_roots:
|
|
_require_access(root, os.R_OK | os.W_OK | os.X_OK)
|
|
for root in settings.local_source_roots:
|
|
_require_access(root, os.R_OK | os.X_OK)
|