feat(core): kind-scoped deployment identity (name, kind)
A deployment's identity becomes (name, kind), so a tool, service, and job can
share a name (a `backup` trio). Kind is structural — which per-kind store / dir —
not a derived discriminator threaded around.
- CastleConfig holds per-kind stores (services/jobs/tools/statics/references);
all_deployments()/deployments_named()/deployment(kind,name) replace the single
flat `deployments` dict. A construction-only `deployments` InitVar routes a flat
map into the stores by kind_for.
- Storage: deployments/<store>/<name>.yaml (per-kind dirs), with read-compat for
the old flat + services/+jobs/ layouts.
- Registry keyed by composite "<kind>/<name>" + name field; get()/all()/named()/put().
- Job units carry a -job marker (castle-<name>-job.{service,timer}); services and
everything else unchanged — so a service and a job can coexist.
- deploy/apply/lifecycle thread kind through unit naming, activate/deactivate,
is_active; caddyfile/tunnel/relations iterate via all_deployments/registry.all.
- Subdomain uniqueness validated across kinds (a service and a static can't share one).
182 core tests pass, incl. a new same-name-trio suite (round-trip, distinct units,
subdomain guard). API/CLI/UI updated in follow-up phases.
This commit is contained in:
@@ -157,7 +157,7 @@ def materialize_all(
|
||||
process until the next ``castle tls reconcile``)."""
|
||||
msgs = messages if messages is not None else []
|
||||
scope = set(only) if only is not None else None
|
||||
for name, dep in sorted(config.deployments.items()):
|
||||
for _kind, name, dep in config.all_deployments():
|
||||
if scope is not None and name not in scope:
|
||||
continue
|
||||
if _tls_of(dep) is None:
|
||||
@@ -188,7 +188,7 @@ def wait_for_wildcard(
|
||||
needs = [
|
||||
n
|
||||
for n in names
|
||||
if (dep := config.deployments.get(n)) is not None and _tls_of(dep) is not None
|
||||
if any(_tls_of(spec) is not None for _k, spec in config.deployments_named(n))
|
||||
]
|
||||
if not needs:
|
||||
return msgs
|
||||
@@ -227,7 +227,7 @@ def reconcile_tls(config: CastleConfig, messages: list[str] | None = None) -> li
|
||||
a no-op when nothing rotated. Invoked by ``castle tls reconcile`` and the Caddy
|
||||
``cert_obtained`` hook. Logs its own outcome (the hook's ``exec`` swallows it)."""
|
||||
msgs = messages if messages is not None else []
|
||||
for name, dep in sorted(config.deployments.items()):
|
||||
for _kind, name, dep in config.all_deployments():
|
||||
tls = _tls_of(dep)
|
||||
if tls is None:
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user