pub struct MeshPort {
pub name: Option<String>,
pub number: Option<u16>,
}Expand description
One port a workload listens on, as its manifest declares it (R844-F17).
Before this, expose.mesh.ports was an array of bare numbers and a port
name was unwritable anywhere in the workspace — names were real at every
tier below the manifest (kamaji’s allocator resolves name -> port, a
service record publishes {"http": 8080, "wss": 8443}, the sibling wire
carries named_ports, PORT_<NAME> reaches the process) and synthesised
from nothing at the top by crate::MeshExpose’s number list. This is the
declaration surface that had to exist for any of that to be stated rather
than guessed.
§Three spellings, one type
ports = [8080] # a number, unnamed
ports = ["http", "wss"] # names; the supervisor picks the numbers
ports = [{ name = "https", port = 443 }] # both statedThey mix freely in one array (ports = [{ name = "http", port = 8080 }, "metrics"]), because the two facts are independent: a container’s ports are
fixed by its image and still want names, while a native workload’s numbers
are the allocator’s to choose and only the names are the author’s.
§What each spelling means downstream
- A number is a request to listen there. On a container backend that is
simply the container-side port. On the published (fleet) tier a number
outside
kamaji::ports::WORLD_FIXED_PORTSis refused at bring-up rather than honoured (R844-F14) — a stale pin is how one workload lands on the port a co-tenant already holds. - A name is what a consumer asks for:
ServiceRecord::port("wss"), the ingress planner resolving which listener a hostname fronts, thePORT_<NAME>variable the process reads. A workload declaring several ports and naming none has nothing calledhttp, and the front door refuses to resolve rather than publish a hostname at whichever listener sorted first (kamaji::name_anonymous_ports). Naming them is how you answer that question instead of being asked it.
§Wire shapes
Human-readable formats (TOML/JSON) accept all three spellings and
round-trip back to the most compact faithful one. The binary wire (postcard,
behind the kamaji UDS) carries the plain two-Option struct: untagged
needs deserialize_any, which postcard refuses — the same split
ImageRef makes, and for the same reason (R590-B3).
Deliberately NOT Default: the all-None value is the one shape no accepted
spelling produces and validate::shape rejects, so a ..Default::default()
would hand a caller exactly the invalid port.
Fields§
§name: Option<String>The name this port is known by — http, wss, metrics. None when
the manifest wrote a bare number; kamaji::name_anonymous_ports then
decides what to call it, which is deliberately not http when there
is more than one.
number: Option<u16>The port number, when the manifest states one. None means the
supervisor allocates it and tells the workload via PORT_<NAME>.
Implementations§
Trait Implementations§
Source§impl<'de> Deserialize<'de> for MeshPort
impl<'de> Deserialize<'de> for MeshPort
Source§fn deserialize<D>(de: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(de: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
impl Eq for MeshPort
impl StructuralPartialEq for MeshPort
Auto Trait Implementations§
impl Freeze for MeshPort
impl RefUnwindSafe for MeshPort
impl Send for MeshPort
impl Sync for MeshPort
impl Unpin for MeshPort
impl UnsafeUnpin for MeshPort
impl UnwindSafe for MeshPort
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.