The operator's call: a node-scoped system seat family (node-nfs-share, node-smb-share, …) defined by the control plane, one per protocol as package registries are (ADR 0109), so several modules occupy it and a machine may hold both.
4.2 KiB
status, opened, located-in, fixed-by, amended-design
| status | opened | located-in | fixed-by | amended-design | ||
|---|---|---|---|---|---|---|
| open | 2026-09-30 |
|
169 — A machine shares its files, and the mesh does not know
What was observed
ace serves the operator's media library to the home network with two host services no module declares and HAL never managed either:
/etc/exports: /storage/media 192.168.1.0/24(rw,sync,root_squash,…) nfs-server active, :2049
/etc/samba/smb.conf: [media] path = /storage/media/ valid users = media smb active, :139/:445
Two LAN clients were connected at survey (2026-09-30). The library itself is operator data (ADR 0051: ~40 TB on ZFS, the mesh owns nothing about it — issue 153 is about modules reaching it in place).
Under the mesh as it stands, this arrangement has no expression and one failure mode:
- Nothing declares the listens. At
converge acethe filter is the sum of what modules listen on (ADR 0045); 2049 and 445 are nobody's, so the shares close — silently, for the two clients that mount them. - Nothing owns the configuration.
/etc/exportsandsmb.confare hand-written files on one machine; a second machine sharing a directory would be written by hand again. - Nothing can consume it. A module on another node that wanted the library (a player, an
indexer, a backup) has no
requiresto state and no binding to read; it would mount by a hand-typed host and path. - The clients are LAN devices, so this also meets issue 154 (no reach for the machine's own network).
The proposal (the operator's, 2026-09-30)
File sharing is a core seat — a role each machine has, defined by the control plane — and, as with package registries (ADR 0109), one seat per protocol, so several modules occupy the family:
| seat | scope | delivers | held by |
|---|---|---|---|
node-nfs-share |
node | nfs-share |
an nfs module |
node-smb-share |
node | smb-share |
a samba module |
… (node-webdav-share) |
node | … | whatever comes next |
Named for their scope (ADR 0121), one holder per node (ADR 0110), each carrying its protocol (ADR 0129). A machine may hold both — nfs and samba on ace — and one module may hold several (0109: "gitea may hold several seats at once"). Adding a protocol is adding a seat and a provision, not widening one.
The holder module:
- declares the exported paths as
accesses(ADR 0051: it owns nothing about them — never creates, chowns or removes), and which paths as the assignment's settings (ADR 0046/0112); - writes the share configuration (
/etc/exports,smb.conf) as mesh-managed files and drives the units, likednsmasq/sshddo for theirs; - declares its endpoints (
nfs2049/tcp;smb445/tcp, …) so the reach — internal, or the LAN once 154 has an answer — is the assignment's, and converge keeps them open; - provides the seat's provision, serving the export path(s), so a consumer on another node
requires nfs-share(orsmb-share) and reads${bound:nfs-share:at}and the path from its binding instead of a hand-typed mount — a pair credential where the protocol has one (a Samba user), none forsec=sysNFS.
What it would settle: ace's library becomes reachable from the mesh by declaration, the two host services get an owner, converge stops being a trap for them, and a media module on another machine (or a backup on novox) can mount the library the way it binds a database today.
Open questions for the decision
- Whether an NFS export over the overlay is an
internalreach of the same endpoint or a second export line — NFS authorises by client address, so the mesh range and the LAN range are two entries in one file. - How a consumer's binding expresses a path to mount (today bindings carry
at,port,asand whatever the providerserves), and whether one share can serve several paths. - Whether the seat should exist before its first module (a system seat is a decision, ADR 0110) — the decision that adds the two seats can be the one that accepts this proposal.