c08b09dc9f
Assisted-by: Codex
49 lines
1.7 KiB
Python
49 lines
1.7 KiB
Python
"""Slug / preflight / subnet helpers for the smolmachines backend
|
|
(PRD 0023). Kept in its own module so the renderers can be
|
|
unit-tested without importing the docker subprocess paths."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import shutil
|
|
|
|
from ...log import die
|
|
|
|
|
|
def smolmachines_preflight() -> None:
|
|
"""Ensure `smolvm` is on PATH before the launch flow runs.
|
|
Called from `_resolve_plan`; gives the operator a clear
|
|
install pointer rather than a cryptic FileNotFoundError
|
|
later. `gvproxy` is no longer required — see the PRD's design
|
|
pivot section."""
|
|
if shutil.which("smolvm") is not None:
|
|
return
|
|
die(
|
|
"BOT_BOTTLE_BACKEND=smolmachines requires `smolvm` on "
|
|
"PATH. Install with: "
|
|
"curl -sSL https://smolmachines.com/install.sh | sh"
|
|
)
|
|
|
|
|
|
def smolmachines_bundle_subnet(slug: str) -> tuple[str, str, str]:
|
|
"""Derive a per-bottle docker subnet + gateway IP + bundle IP
|
|
from the slug.
|
|
|
|
Returns `(subnet_cidr, gateway_ip, bundle_ip)`. The third
|
|
octet comes from SHA-256 of the slug mod 254 (skipping 17 to
|
|
avoid the docker-default bridge), so parallel bottles get
|
|
distinct /24s and `resume` reuses the same /24. The bundle
|
|
container always lands at `.2`; gateway is `.1`; the smolvm
|
|
Smolfile's `allow_cidrs` is `<bundle_ip>/32`."""
|
|
digest = hashlib.sha256(slug.encode("utf-8")).digest()
|
|
octet = (digest[0] % 254) + 1
|
|
# Skip the docker-default bridge to dodge the most common
|
|
# collision (operators with `docker0` at 172.17.x.x or a
|
|
# 192.168.17.x VPN client).
|
|
if octet == 17:
|
|
octet = 18
|
|
subnet = f"192.168.{octet}.0/24"
|
|
gateway = f"192.168.{octet}.1"
|
|
bundle_ip = f"192.168.{octet}.2"
|
|
return subnet, gateway, bundle_ip
|