feat(api): kind-scoped deployment resolution
Resolve deployments by (name, kind) via the core per-kind stores / registry.get:
- get_service resolves a service-or-static; get_job a job; get_component returns
the first kind for a name (the /services|/jobs|/tools/{name} endpoints are the
unambiguous addresses). _save_deployment stores into the kind store, preferring
the existing same-named deployment on a partial patch (can't derive kind from a
partial payload). delete/set-enabled act across a name's kinds.
- All iterate-all loops use registry.all(); lookups use registry.get/named.
- services.py/logs.py resolve the managed deployment and use kind-aware unit names.
- mqtt registry (de)serialization keyed by composite "<kind>/<name>".
API + core suites green (85 + 182).
This commit is contained in:
@@ -8,6 +8,8 @@ from collections.abc import AsyncGenerator
|
||||
from fastapi import APIRouter, HTTPException, Query, status
|
||||
from starlette.responses import StreamingResponse
|
||||
|
||||
from castle_core.generators.systemd import unit_name
|
||||
|
||||
from castle_api.config import get_castle_root
|
||||
|
||||
router = APIRouter(prefix="/logs", tags=["logs"])
|
||||
@@ -27,20 +29,24 @@ async def get_logs(
|
||||
from castle_core.config import load_config
|
||||
|
||||
config = load_config(root)
|
||||
dep = config.deployments.get(name)
|
||||
is_managed = dep is not None and getattr(dep, "manage", None) is not None
|
||||
if not is_managed:
|
||||
# A name may span kinds — the managed (systemd) one owns the journal.
|
||||
dep_kind = next(
|
||||
((k, s) for k, s in config.deployments_named(name) if getattr(s, "manage", None)),
|
||||
None,
|
||||
)
|
||||
if dep_kind is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"'{name}' is not a managed service",
|
||||
)
|
||||
kind, _spec = dep_kind
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Castle root not available",
|
||||
)
|
||||
|
||||
unit = f"{UNIT_PREFIX}{name}.service"
|
||||
unit = unit_name(name, kind)
|
||||
|
||||
if follow:
|
||||
return StreamingResponse(
|
||||
|
||||
Reference in New Issue
Block a user