028 — two things want one port, and nothing says so until the machine
Found by fixing 027 and pushing again. The declaration is now accepted and the database container still cannot start: the mesh's own store holds 5432 on that machine, and the module publishes 5432. Nothing catches it because the substrate is not a module. It arrives from the bundle before there is a mesh to ask, so the control plane has never heard of the store and does not know it holds a port. Resolution can compare modules with each other and cannot compare one against what the mesh is built on. Nor does it compare modules with each other. A port is exclusive on a machine in exactly the way a claim is, and the mesh has a mechanism for that which ports do not use. It has been met before: the end-to-end test that exercises a real database publishes 5433 rather than 5432, inline, with nothing saying why. That is how a constraint becomes folklore. The open question is bigger than the bug. Whether a module should publish to the machine at all decides how a consumer reaches it, and changes what `serves` means.
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
---
|
||||
status: located
|
||||
opened: 2026-09-01
|
||||
located-in: [mesh-control]
|
||||
fixed-by:
|
||||
amended-design:
|
||||
---
|
||||
|
||||
# 028 — Two things want one port, and nothing says so until the machine
|
||||
|
||||
## Symptom
|
||||
|
||||
The database module cannot start on a machine that runs the control plane:
|
||||
|
||||
```
|
||||
Bind for 127.0.0.1:5432 failed: port is already allocated
|
||||
```
|
||||
|
||||
The mesh keeps its own store on that machine, from the bundle, and it holds 5432. The module
|
||||
publishes 5432 too. Everything up to the machine is content: it resolves, it composes, it is
|
||||
pushed, and it is applied — the container is simply the one resource that fails.
|
||||
|
||||
## Why nothing catches it
|
||||
|
||||
**The substrate is not a module.** It arrives from the bundle a host carries, before there is a
|
||||
mesh to ask. So the control plane has never heard of `mesh-store` and does not know it holds a
|
||||
port. Resolution can compare modules against each other and cannot compare a module against the
|
||||
thing the mesh is built on.
|
||||
|
||||
**And nothing compares modules against each other either.** A port is exclusive on a machine in
|
||||
exactly the way a claim is — one seat, one display server, one artifact store — and the mesh has a
|
||||
mechanism for that, which ports do not use. Two modules both publishing 5432 would meet the same
|
||||
wall, one machine later.
|
||||
|
||||
## It has been met before, and worked around
|
||||
|
||||
The end-to-end test that exercises a real database publishes `5433:5432` rather than `5432:5432`.
|
||||
The workaround is right there, inline, with no note saying why — which is how a constraint becomes
|
||||
folklore.
|
||||
|
||||
## What a fix has to settle
|
||||
|
||||
- **Whether a module should publish to the machine at all.** Consumers reach a provider by the
|
||||
machine's address and the port it *serves*, so publishing is what makes that true. An alternative
|
||||
is that they reach it on the module's own network by name, and nothing is published — which
|
||||
changes what `serves` means and is a larger decision than it looks.
|
||||
- **Where the substrate's ports are written down.** Whatever compares them needs to know what the
|
||||
bundle holds. The bundle is a list of pinned references; what those containers bind is not in it.
|
||||
- **What a refusal should say.** *5432 is held by the mesh's own store on this machine* is a useful
|
||||
sentence. *Port is already allocated*, arriving from a container runtime three layers down, is
|
||||
not.
|
||||
|
||||
## Not the same as a firewall rule
|
||||
|
||||
`listens` already says which ports a module accepts on, and filtering is computed from it. That is
|
||||
about what may reach a port from elsewhere. This is about two things on one machine wanting to own
|
||||
the same one, which `listens` does not model and could not answer.
|
||||
Reference in New Issue
Block a user