2.1 KiB
ctrl/ports.sh
Why each environment gets a port block
New versions of a system mean new clusters on ONE machine, not new machines. Cluster name, kubectl context, registry container and image tag already derive from the directory name, so two copies never collide there, but host ports are a single shared namespace and would.
The block is derived from the directory name: stateless, stable, and requiring no coordination between copies that know nothing about each other.
base = 20000 + (hash(slug) % 200) * 10
+0 HTTP +1 HTTPS +2 TILT +3 REGISTRY (+4..9 reserved)
20000+ deliberately avoids the ports something is already likely to hold: 80, 443, 3000, 5432, 8000, 8080.
Derivation is a default, not a decision. On first use the resolved block is written into ctrl/.env, so it becomes pinned, visible and editable rather than a number that appears from nowhere. Anything already in ctrl/.env wins.
active
The resolved facts a consumer outside bash needs, machine-readable:
CLUSTER KUBECONTEXT HTTP HTTPS TILT REGISTRY MANIFESTS_DIR
Identity and ports together, because they are one fact set: both derive from the directory name so that copies never collide. A consumer needs all of them or none, and fetching them separately is how two end up disagreeing. MANIFESTS_DIR rides along because the one consumer that needs the addressing is the one that needs to know what to deploy.
Space-separated, so MANIFESTS_DIR must not contain spaces. Everything else in rig already assumes that of paths; kind, docker and kubectl all do.
derive answers a DIFFERENT question (what the directory name alone implies) and deliberately ignores ctrl/.env. Configuring anything from it would silently contradict the rule that "anything already in ctrl/.env wins". active is what anything downstream should read.
Why this exists at all: the cluster name is not the bare directory name. default_cluster_name() lowercases it and replaces every character outside [a-z0-9-], because it has to be a DNS label. Re-deriving that in another language is how a copy in My_Project/ ends up guarding the wrong context.