mesh/delivery checking
mesh/merge-gate out of date: judged against trunk 1826b68a22b5, the trunk is now 404b4409e70e; judged again on a recheck or when it is merged
mesh/repo-check out of date: judged against trunk 1826b68a22b5, the trunk is now 404b4409e70e; judged again on a recheck or when it is merged
nfs-server's exports and adopt now say the local-network grant, and that sharenfs is cleared only once the mesh's export covers every client the property exported to.
103 lines
6.6 KiB
Go
103 lines
6.6 KiB
Go
package catalogue
|
|
|
|
// A machine's shares, and the shares a machine mounts (novox/hq ADR 0263).
|
|
//
|
|
// **Two roles, one per side of the wire.** A machine that shares a directory with the mesh does it
|
|
// through the holder of `node-nfs-server`: it writes the machine's export file, runs the NFS service,
|
|
// opens its port to the private network only, and provides each share as the provision `nfs-share`. A
|
|
// machine that wants the files gets them through the holder of `node-mounts`: it writes a mount unit and
|
|
// an automount unit per share, so nothing mounts at boot and nothing can fail a boot, and it says a
|
|
// device that comes and goes is absent rather than failed.
|
|
//
|
|
// **One holder per machine on each side.** Two modules writing one machine's export file, or two writing
|
|
// mount units for one mount point, is the conflict a seat exists to refuse. Both seats deliver nothing:
|
|
// `nfs-share` is provided at the mesh's scope, by the module holding `node-nfs-server` on the machine that
|
|
// shares, and a seat at a node's scope cannot be the answer for a provision at the mesh's.
|
|
//
|
|
// **The data is the operator's** (ADR 0051). Neither holder creates, chowns or removes anything under a
|
|
// shared path; the export maps every client to the path's owner, so no client acts as another account on
|
|
// the server. Their verbs read, and the ones that act take over what a person wrote by hand only on a
|
|
// person's word: a dataset's export property, an fstab line.
|
|
|
|
// NFSServerSeat is the role of the machine that shares directories over NFS (novox/hq ADR 0263).
|
|
const NFSServerSeat = "node-nfs-server"
|
|
|
|
// MountsSeat is the role that mounts a machine's shares and occasional sources (novox/hq ADR 0263).
|
|
const MountsSeat = "node-mounts"
|
|
|
|
// nfsServerVerbs is the contract every holder of node-nfs-server serves (novox/hq ADR 0263).
|
|
func nfsServerVerbs() []Verb {
|
|
return []Verb{
|
|
{Name: "exports", Description: "Every share this machine exports: its name, its path, read-write or " +
|
|
"read-only, the owner every client is mapped to (uid and gid), each node it is exported to with that " +
|
|
"node's private address and access (only the nodes the server grants it to and that ask for it), " +
|
|
"the subnets of this machine's local network it is exported to when the server grants it " +
|
|
"local-network (novox/hq ADR 0341), what is granted and not asked for or asked for and not " +
|
|
"granted, and whether the kernel holds it now. Also the exports found that are not the mesh's: a " +
|
|
"dataset's sharenfs property, a line in /etc/exports.",
|
|
Input: schema(map[string]string{}, nil),
|
|
Replaces: []string{"exportfs -v", "cat /etc/exports", "zfs get sharenfs"}},
|
|
{Name: "clients", Description: "Which machines have mounted which share now, as the NFS server " +
|
|
"knows its clients.",
|
|
Input: schema(map[string]string{}, nil),
|
|
Replaces: []string{"ss -tn sport = :2049", "cat /proc/fs/nfsd/clients/*/info"}},
|
|
{Name: "test", Description: "Whether this machine exports one share for the mesh now, and whether its " +
|
|
"NFS service is up; with an address, also whether the share is exported to that address: a node's " +
|
|
"own private address, when the server grants it the share and the node asks for it. What a machine " +
|
|
"mounting the share asks before it mounts.",
|
|
Input: schema(map[string]string{
|
|
"share": "the share, by its name",
|
|
"address": "a node's private address, to ask whether the share is exported to it (optional)",
|
|
}, []string{"share"}),
|
|
Replaces: []string{"showmount -e"}},
|
|
{Name: "reload", Description: "Have the kernel read this machine's export files again now (exportfs " +
|
|
"-ra) and answer the shares as it then holds them. The module's own process writes its export " +
|
|
"file; this is for after a change made outside it. Changes no shared path.",
|
|
Input: schema(map[string]string{}, nil),
|
|
Replaces: []string{"exportfs -ra"}},
|
|
{Name: "adopt", Description: "Take over an export a person made by hand: clear a dataset's sharenfs " +
|
|
"property for a path the mesh's own export now serves — only when that export is live and covers " +
|
|
"every client the property exported to: for a property exporting to the local network, the " +
|
|
"mesh's local-network export of the path (novox/hq ADR 0341). Without confirm, says what it " +
|
|
"would do and changes nothing.",
|
|
Input: schema(map[string]string{
|
|
"path": "the shared path whose hand-made export is taken over",
|
|
"confirm": "\"true\": change it (needs why); anything else is a dry run",
|
|
"why": "why, for the record",
|
|
}, []string{"path"}, "confirm"),
|
|
Replaces: []string{"zfs set sharenfs=off"}},
|
|
}
|
|
}
|
|
|
|
// mountsVerbs is the contract every holder of node-mounts serves (novox/hq ADR 0263).
|
|
func mountsVerbs() []Verb {
|
|
return []Verb{
|
|
{Name: "list", Description: "Every mount point on this machine: its fstab line, the mesh's mount and " +
|
|
"automount units for it, its state (armed, mounted, absent, unreachable, failed) and since when, " +
|
|
"and which settings asked for it. A password in a mount's options is never shown.",
|
|
Input: schema(map[string]string{}, nil),
|
|
Replaces: []string{"cat /etc/fstab", "findmnt", "systemctl list-units --type=mount"}},
|
|
{Name: "test", Description: "Whether one share's or occasional source's server answers from this " +
|
|
"machine now, without touching its mount point.",
|
|
Input: schema(map[string]string{"name": "the share or source, by its name"}, []string{"name"}),
|
|
Replaces: []string{"showmount -e", "ping"}},
|
|
{Name: "mount", Description: "Mount one share or occasional source now, rather than at its first " +
|
|
"access.",
|
|
Input: schema(map[string]string{"name": "the share or source, by its name"}, []string{"name"}),
|
|
Replaces: []string{"mount"}},
|
|
{Name: "unmount", Description: "Release one share or occasional source now; its automount stays " +
|
|
"armed, so the next access mounts it again.",
|
|
Input: schema(map[string]string{"name": "the share or source, by its name"}, []string{"name"}),
|
|
Replaces: []string{"umount"}},
|
|
{Name: "adopt", Description: "Take over a mount a person wrote by hand: comment out the /etc/fstab " +
|
|
"line for a mount point the mesh's own units now serve, keeping a copy of the file — only when " +
|
|
"the mesh's automount for it is armed. Without confirm, says what it would do and changes nothing.",
|
|
Input: schema(map[string]string{
|
|
"mountpoint": "the mount point whose fstab line is taken over",
|
|
"confirm": "\"true\": change it (needs why); anything else is a dry run",
|
|
"why": "why, for the record",
|
|
}, []string{"mountpoint"}, "confirm"),
|
|
Replaces: []string{"sed -i /etc/fstab"}},
|
|
}
|
|
}
|