zfs_config also says what the module says before it leaves a node (Z17): the next load of the kernel module uses ZFS's defaults, the three units and /etc/hostid stay. Builds: design 42 zfs-owns-zfs §28, §30, §10, A-31, A-35
77 lines
2.6 KiB
Go
77 lines
2.6 KiB
Go
// The zfs module's Go bundle: the mesh's view of ZFS on a machine — its pools' health, layout, space,
|
|
// scrubs, I/O, cache and events, every dataset with its space and snapshots — and one act, taking a named
|
|
// snapshot of one dataset.
|
|
//
|
|
// One binary, four ways to run. With no argument it is the bundle the node's tool runner launches and
|
|
// speaks MCP to over stdio (novox/hq ADR 0188, ADR 0193), as the operator account. With `watch` and
|
|
// `events` it is one of the module's two long-running processes, run by the node-engine: the watch, which
|
|
// the health check zfs_health stands on (watch.go), and the event follower, as root, judged by its unit
|
|
// (follow.go). With `run` it is the scheduled run, as root by the node-engine's timer (run.go), and with `apply` the
|
|
// apply that converges the node to its config file (apply.go).
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) > 1 {
|
|
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM, os.Interrupt)
|
|
defer stop()
|
|
switch os.Args[1] {
|
|
case "watch":
|
|
(&Watch{M: Here(), Out: os.Stdout}).Loop(ctx)
|
|
case "run":
|
|
m := Here()
|
|
closeBus := m.JoinBus()
|
|
said, err := m.RunScheduled(ctx, ServedFile)
|
|
closeBus()
|
|
for _, w := range m.Warnings {
|
|
fmt.Fprintln(os.Stderr, "warning:", w)
|
|
}
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Println(said)
|
|
case "apply":
|
|
m := Here()
|
|
closeBus := m.JoinBus()
|
|
said, err := m.Apply(ctx)
|
|
closeBus()
|
|
for _, w := range m.Warnings {
|
|
fmt.Fprintln(os.Stderr, "warning:", w)
|
|
}
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Println(said)
|
|
case "events":
|
|
if err := Follower(ctx, os.Stdout); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
default:
|
|
fmt.Fprintf(os.Stderr, "zfs-tools: %q is not a way to run; with no argument it serves its tools, with watch it "+
|
|
"watches the pools, with events it follows ZFS's events, with run it runs the scheduled scrub, trim and snapshots, with apply it converges the node to its config file\n", os.Args[1])
|
|
os.Exit(2)
|
|
}
|
|
return
|
|
}
|
|
m := Here()
|
|
m.Emit = func(eventType string, body any) error { return stdio.Emit(eventType, body) }
|
|
m.States, m.Call, m.Ledger, m.Await, m.Log = toolStates{}, stdio.Ask, busLedger{}, (&eventHub{}).await, busStream{}
|
|
// An empty name serves as the module the runtime names (MESH_SERVED_MODULE): zfs.
|
|
if err := stdio.Serve("", Tools(m)); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|