Add meta-framework spec, pydantic schemas, profile/extension YAML, extension registry, ext.compose-ssh backend, SandboxManager with State Hub events, CLI commands, integration docs, capability registry entry, and compose-e2e runbook. Nine unit tests pass. T10 remote smoke test remains for operator.
28 lines
No EOL
906 B
Python
28 lines
No EOL
906 B
Python
"""Host placement resolution from profile policy and environment."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
from sandboxer.models import Profile
|
|
|
|
|
|
def resolve_host(profile: Profile, *, override: str | None = None) -> str:
|
|
if override:
|
|
return override
|
|
env_host = os.environ.get("SANDBOXER_HOST")
|
|
if env_host:
|
|
return env_host
|
|
for candidate in [*profile.placement.prefer, *profile.placement.fallback]:
|
|
mapped = os.environ.get(f"SANDBOXER_HOST_{candidate.upper()}")
|
|
if mapped:
|
|
return mapped
|
|
if candidate in os.environ:
|
|
return os.environ[candidate]
|
|
if profile.placement.prefer:
|
|
return profile.placement.prefer[0]
|
|
if profile.placement.fallback:
|
|
return profile.placement.fallback[0]
|
|
raise ValueError(
|
|
"No host resolved. Set SANDBOXER_HOST or profile placement hosts in environment."
|
|
) |