Files
computer-playbook/utils/env/handlers/passthrough.py
kevinveenbirkenbachandClaude Opus 5.5 d2b33a3b2a fix(compose): keep dynamic addresses off the stack's static IPs
compose/cache.shared.override.yml attaches every worktree stack's
infinito service to the primary's network (infinito-nexus-core_default,
172.30.0.0/24) without an ipv4_address. The default network declared
no ip_range, so Docker IPAM handed out the lowest free address and the
worktree stacks took 172.30.0.2, .3, .8, .9 and, whenever the primary
container was down, .10, the primary's INFINITO_IP4. The primary's
`make compose-up` then failed with "Address already in use", and with
it `make quality-high` on main.

The default network now declares ip_range: ${INFINITO_IP_RANGE}, the
upper half of INFINITO_SUBNET. Every static address of the stack (.1,
.4 to .6, .10, .53) sits in the lower half, so a container without a
static address can no longer take one.

INFINITO_IP_RANGE is derived from the final INFINITO_SUBNET after
custom.env is applied, because a worktree pins its subnet there and
`make dotenv-force` regenerates without it in the environment. Existing
worktrees therefore get their own slot's range without a new pin.

A lint checks that every static IP in default.env and every
172.30.${slot}.N pin in scripts/system/worktree/up.sh lies below the
pool.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 21:44:16 +02:00

159 lines
4.9 KiB
Python

"""Static-env passthrough: copy every declared key from default.env
with caller-env-wins (setdefault) semantics. Comments come from
``ctx.static_comments`` (parsed from default.env)."""
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from utils.env.builder import BuildContext, EnvBuilder
STATIC_KEYS = (
"INFINITO_SRC_DIR",
"INFINITO_VENV_DIR",
"INFINITO_ANSIBLE_COLLECTIONS_SOURCE",
"INFINITO_BIND_IP",
"INFINITO_BUILD",
"INFINITO_SUBNET",
"INFINITO_GATEWAY",
"INFINITO_DISTRO",
"INFINITO_DNS_DOMAIN",
"INFINITO_DNS_HOSTS_FILE",
"INFINITO_DNS_IP",
"INFINITO_DOMAIN",
"INFINITO_TOR_SOCKS_PORT",
"INFINITO_CONTAINER",
"INFINITO_CONTAINER_CA_ENABLED",
"INFINITO_RUNNING_ON_ACT",
"INFINITO_RUNNING_ON_GITHUB",
"INFINITO_IS_WSL2",
"INFINITO_PULL_POLICY",
"INFINITO_MEM_LIMIT",
"INFINITO_MEMSWAP_LIMIT",
"INFINITO_CPUS",
"INFINITO_WAIT_HEALTH_TIMEOUT_S",
"INFINITO_DOCKER_VOLUME",
"INFINITO_DOCKER_MOUNT",
"INFINITO_IP4",
"INFINITO_IP6",
"INFINITO_IP_RANGE",
"INFINITO_PARENT_IMAGE_OWNER",
"INFINITO_PARENT_IMAGE_TAG",
"INFINITO_PARENT_IMAGE_VARIANT",
"INFINITO_KEEP_SWARM_NODES",
"INFINITO_SWARM_TEST_LABEL",
"INFINITO_SWARM_MESHES",
"INFINITO_SWARM_VPN",
"INFINITO_VPN",
"INFINITO_SWARM_MGR_NAME",
"INFINITO_SWARM_STEP_TIMEOUT_MINUTES",
"INFINITO_SWARM_TEARDOWN_RESERVE_SECONDS",
"INFINITO_SWARM_WRK1_NAME",
"INFINITO_SWARM_WRK2_NAME",
"INFINITO_SWARM_NFS_NAME",
"INFINITO_SWARM_NODE_PIDS_LIMIT",
"INFINITO_SWARM_BACKUP_NAME",
"INFINITO_SWARM_BACKUP_KEY",
"INFINITO_SWARM_BACKUP_IP",
"INFINITO_SWARM_LAB_NET_NAME",
"INFINITO_SWARM_LAB_SUBNET",
"INFINITO_SWARM_MGR_IP",
"INFINITO_SWARM_NFS_IP",
"INFINITO_SWARM_NFS_MINOR_VERSIONS",
"INFINITO_SWARM_WRK1_IP",
"INFINITO_SWARM_WRK2_IP",
"INFINITO_NODE_SRC_DIR",
"INFINITO_DOCKER_CLI_INSTALL_SCRIPT",
"INFINITO_DOCKER_FILESYSTEM",
"INFINITO_DOCKER_FILESYSTEM_ALLOWED",
"INFINITO_DOCKER_FILESYSTEM_ENFORCED",
"INFINITO_DOCKER_FILESYSTEM_PICK",
"INFINITO_DOCKER_FILESYSTEM_REQUIRED",
"INFINITO_PACKAGE_INSTALL_SCRIPT",
"INFINITO_PYTHON_INSTALL_SCRIPT",
"INFINITO_FILESYSTEM_INSTALL_SCRIPT",
"INFINITO_INTERPRETERS_INSTALL_SCRIPT",
"INFINITO_ALIAS_REPOSITORY",
"INFINITO_APT_UBUNTU_MIRRORS",
"INFINITO_FORK_REPOSITORY_NAME",
"INFINITO_API_ANTHROPIC_KEY",
"INFINITO_API_OPENAI_KEY",
"INFINITO_API_OPENROUTER_KEY",
"INFINITO_PLAYWRIGHT_KEEP",
"INFINITO_INVENTORY_EXTRA_VARS",
"INFINITO_PUBLISH_PORTS",
"INFINITO_SKILLS_REPOSITORY",
"INFINITO_SKIP_COMPILE",
"INFINITO_MAIL_PRODUCTION_HOST",
"INFINITO_MAIL_PRODUCTION_RESOLVER",
"INFINITO_TEST_PATTERN",
"INFINITO_TEST_RUNNER",
"INFINITO_WORKSPACE_TRACKS",
"INFINITO_LINT_RUNNER",
"INFINITO_APP_DISCOVERY_RUNNER",
"INFINITO_DEPLOY_MODE",
"INFINITO_DISCOVERY_SEED",
"INFINITO_DISCOVERY_SORT",
"INFINITO_LIFECYCLES",
"INFINITO_MODES",
"INFINITO_REQUIRED_STORAGE",
"INFINITO_BUILDKIT_ENABLED",
"INFINITO_DEBUG",
"INFINITO_WHITELIST",
"INFINITO_BLACKLIST",
"INFINITO_PRIORITY",
"INFINITO_CI_CHUNK",
"INFINITO_CI_CHUNK_SIZE",
"INFINITO_CI_CONCURRENCY",
"INFINITO_CI_DISTRO_BUDGET_SECONDS",
"INFINITO_CI_JOB_LIMIT",
"INFINITO_CI_MAX_CHUNKS",
"INFINITO_CI_OFFSET",
"INFINITO_CI_QUEUE_HOURS",
"INFINITO_CI_SWEEP",
"INFINITO_LIMIT_HOST",
"INFINITO_RUN_FLAGS",
"INFINITO_WORKER_ENABLED",
"INFINITO_INVENTORY_VARS_FILE",
"INFINITO_PRESERVE_DOCKER_CACHE",
"INFINITO_RECOVER_DRILL",
"INFINITO_REPO_ROOT",
"INFINITO_RESCUE_DIAGNOSTICS_BASE",
"INFINITO_RUNNER_PREFIX",
"INFINITO_TIMEOUT_MULTIPLIER",
"INFINITO_TOR",
"INFINITO_INSTANCE",
"INFINITO_GIT_COMMON_DIR",
"INFINITO_CACHE_NETWORK",
"INFINITO_CACHE_STACK",
"INFINITO_GHCR_MIRROR",
"INFINITO_CACHE_REGISTRY_HOST_PATH",
"INFINITO_CACHE_REGISTRY_CA_HOST_PATH",
"INFINITO_CACHE_REGISTRY_IP",
"INFINITO_CACHE_PACKAGE_HOST_PATH",
"INFINITO_CACHE_PACKAGE_PORT",
"INFINITO_CACHE_PACKAGE_FRONTEND_CA_DIR",
"INFINITO_CACHE_PACKAGE_FRONTEND_CA_FILE",
"INFINITO_CACHE_PACKAGE_FRONTEND_CERTS_DIR",
"INFINITO_CACHE_PACKAGE_FRONTEND_IP",
"INFINITO_CACHE_PACKAGE_FRONTEND_INIT_IMAGE",
"INFINITO_CACHE_PACKAGE_IP",
"INFINITO_CACHE_PACKAGE_MAX_AGE_MIN",
"INFINITO_CACHE_PACKAGE_METADATA_MAX_AGE_MIN",
"INFINITO_CACHE_PACKAGE_NPMRC",
"INFINITO_CACHE_PACKAGE_PIP_CONF",
"INFINITO_CACHE_REGISTRY_PROXY_CONF",
"INFINITO_IMAGE_TAG",
"INFINITO_VARS_PAYLOAD",
"INFINITO_APP_VARIANTS",
)
def apply(eb: EnvBuilder, ctx: BuildContext) -> None:
for key in STATIC_KEYS:
if key in ctx.static:
eb.setdefault(
key, ctx.static[key], comment=ctx.static_comments.get(key, "")
)