feat: connectivity redesign phase 5 — one container per connection instance
Unit Tests / test (push) Successful in 13m5s
Unit Tests / test (push) Successful in 13m5s
instanceable rendering, per-instance up/down on create/delete, store-service-installed gate, per-instance health Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,13 @@ _RESERVED_CONTAINER_NAMES = frozenset({
|
||||
'cell-dnsmasq', 'cell-wireguard', 'cell-chrony',
|
||||
})
|
||||
_CONTAINER_NAME_RE = re.compile(r'^cell-[a-z0-9][a-z0-9-]{0,30}$')
|
||||
# Instanceable services template their container name with the connection's
|
||||
# short id, e.g. "cell-wgext-${INSTANCE_ID}". The literal prefix is validated;
|
||||
# ${INSTANCE_ID} is substituted at up-time with a hex token that itself matches
|
||||
# the per-instance naming rules.
|
||||
_INSTANCEABLE_CONTAINER_NAME_RE = re.compile(
|
||||
r'^cell-[a-z0-9][a-z0-9-]{0,22}-\$\{INSTANCE_ID\}$'
|
||||
)
|
||||
_ENV_VALUE_RE = re.compile(r'^[A-Za-z0-9._@:/+\-]{0,256}$')
|
||||
_HOOK_BINARY_RE = re.compile(r'^[a-z][a-z0-9_-]{0,31}$')
|
||||
_CAP_NAME_RE = re.compile(r'^[A-Z_]+$')
|
||||
@@ -93,7 +100,15 @@ def validate_manifest(manifest: dict) -> tuple:
|
||||
# container_name structural check
|
||||
cname = manifest.get('container_name')
|
||||
if cname is not None:
|
||||
if not _CONTAINER_NAME_RE.match(cname):
|
||||
instanceable = bool(manifest.get('instanceable'))
|
||||
if instanceable:
|
||||
if not _INSTANCEABLE_CONTAINER_NAME_RE.match(cname):
|
||||
errors.append(
|
||||
'instanceable container_name must match '
|
||||
"^cell-[a-z0-9][a-z0-9-]{0,22}-${INSTANCE_ID}$, "
|
||||
f'got: {cname!r}'
|
||||
)
|
||||
elif not _CONTAINER_NAME_RE.match(cname):
|
||||
errors.append(
|
||||
f'container_name must match ^cell-[a-z0-9][a-z0-9-]{{0,30}}$, got: {cname!r}'
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user